ar-design 0.3.86 → 0.3.88

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.
@@ -1,61 +1,113 @@
1
1
  .ar-layout {
2
2
  display: flex;
3
3
  flex-direction: row;
4
- }
5
4
 
6
- .ar-layout > aside.ar-aside {
7
- position: sticky;
8
- top: 0;
9
- background-color: var(--gray-100);
10
- height: 100vh;
11
- box-sizing: border-box;
12
- }
13
- .ar-layout > aside.ar-aside.left {
14
- position: sticky;
15
- top: 0;
16
- display: flex;
17
- flex-direction: column;
18
- border-right: solid 1px var(--gray-200);
19
- }
20
- .ar-layout > aside.ar-aside.left > .logo {
21
- display: flex;
22
- align-items: center;
23
- }
24
- .ar-layout > aside.ar-aside.left > footer {
25
- position: fixed;
26
- bottom: 1rem;
27
- }
5
+ > aside.ar-aside {
6
+ position: sticky;
7
+ top: 0;
8
+ background-color: var(--gray-100);
9
+ height: 100vh;
10
+ box-sizing: border-box;
11
+ }
28
12
 
29
- .ar-layout > aside.ar-aside.right {
30
- }
13
+ > aside.ar-aside.left {
14
+ position: sticky;
15
+ top: 0;
16
+ display: flex;
17
+ flex-direction: column;
18
+ min-width: 280px;
19
+ max-width: 280px;
20
+ border-right: solid 1px var(--gray-200);
21
+ user-select: none;
22
+ transition: all 250ms ease-in-out;
23
+ z-index: 11;
31
24
 
32
- .ar-layout > main {
33
- display: flex;
34
- flex-direction: column;
35
- }
36
- .ar-layout > main > header {
37
- display: flex;
38
- align-items: center;
39
- position: sticky;
40
- top: 0;
41
- background-color: rgba(var(--white-rgb), 0.5);
42
- backdrop-filter: blur(5px);
43
- box-shadow: 0 10px 10px -15px rgba(var(--black-rgb), 0.25);
44
- z-index: 10;
45
- }
46
- .ar-layout > main > header > .actions {
47
- margin-left: auto;
48
- }
25
+ &.un-locked {
26
+ position: absolute;
27
+ min-width: 4.85rem;
28
+ max-width: 4.85rem;
49
29
 
50
- .ar-layout > main > section {
51
- width: 100%;
52
- height: fit-content;
53
- margin-left: auto;
54
- margin-right: auto;
55
- padding: 2.5rem;
56
- }
57
- .ar-layout > main > section.full-width {
58
- width: 100%;
30
+ &:hover {
31
+ min-width: 280px;
32
+ max-width: 280px;
33
+ }
34
+ }
35
+
36
+ > .button {
37
+ display: flex;
38
+ justify-content: center;
39
+ align-items: center;
40
+ position: absolute;
41
+ top: calc(2.5rem - (1.75rem / 2));
42
+ right: -0.875rem;
43
+ background-color: var(--white);
44
+ width: 1.75rem;
45
+ height: 1.75rem;
46
+ border-radius: var(--border-radius-lg);
47
+ color: var(--gray-400);
48
+ cursor: pointer;
49
+ box-shadow: 0 0 10px -5px rgba(var(--black-rgb), 0.25);
50
+ z-index: 1;
51
+ }
52
+
53
+ > .logo {
54
+ display: flex;
55
+ justify-content: center;
56
+ align-items: center;
57
+ position: relative;
58
+ width: 100%;
59
+ height: 5rem;
60
+
61
+ &::after {
62
+ position: absolute;
63
+ top: 100%;
64
+ content: "";
65
+ background-color: rgba(var(--black-rgb), 0.1);
66
+ width: 100%;
67
+ height: 1px;
68
+ }
69
+ }
70
+
71
+ > footer {
72
+ position: fixed;
73
+ bottom: 1rem;
74
+ }
75
+ }
76
+
77
+ > aside.ar-aside.right {
78
+ }
79
+
80
+ > main {
81
+ display: flex;
82
+ flex-direction: column;
83
+
84
+ > header {
85
+ display: flex;
86
+ align-items: center;
87
+ position: sticky;
88
+ top: 0;
89
+ background-color: rgba(var(--white-rgb), 0.5);
90
+ backdrop-filter: blur(5px);
91
+ box-shadow: 0 10px 10px -15px rgba(var(--black-rgb), 0.25);
92
+ z-index: 10;
93
+
94
+ > .actions {
95
+ margin-left: auto;
96
+ }
97
+ }
98
+
99
+ > section {
100
+ width: 100%;
101
+ height: fit-content;
102
+ margin-left: auto;
103
+ margin-right: auto;
104
+ padding: 2.5rem;
105
+
106
+ &.full-width {
107
+ width: 100%;
108
+ }
109
+ }
110
+ }
59
111
  }
60
112
 
61
113
  /* Media Queries */
@@ -1,21 +1,5 @@
1
1
  /* Large (Tablet Yatay & Büyük Tablet) */
2
2
  @media (min-width: 768px) and (max-width: 991px) {
3
- .ar-layout > aside.ar-aside.left {
4
- min-width: 3.85rem;
5
- max-width: 3.85rem;
6
- padding: 0 1rem;
7
- overflow: hidden;
8
- }
9
- .ar-layout > aside.ar-aside.left:hover {
10
- min-width: 280px;
11
- max-width: 280px;
12
- }
13
- .ar-layout > aside.ar-aside.left > .logo {
14
- visibility: hidden;
15
- opacity: 0;
16
- height: 5rem;
17
- margin-bottom: 1rem;
18
- }
19
3
  .ar-layout > aside.ar-aside.right {
20
4
  width: 100%;
21
5
  }
@@ -1,22 +1,5 @@
1
1
  /* Medium (Tablet Dikey & Büyük Telefonlar) */
2
2
  @media (min-width: 576px) and (max-width: 767px) {
3
- .ar-layout > aside.ar-aside.left {
4
- min-width: 3.85rem;
5
- max-width: 3.85rem;
6
- padding: 0 1rem;
7
- overflow: hidden;
8
- }
9
- .ar-layout > aside.ar-aside.left:hover {
10
- min-width: 280px;
11
- max-width: 280px;
12
- }
13
- .ar-layout > aside.ar-aside.left > .logo {
14
- visibility: hidden;
15
- opacity: 0;
16
- height: 5rem;
17
- margin-bottom: 1rem;
18
- }
19
-
20
3
  .ar-layout > aside.ar-aside.right {
21
4
  width: 100%;
22
5
  }
@@ -1,22 +1,5 @@
1
1
  /* Small (Küçük Telefonlar) */
2
2
  @media (max-width: 575px) {
3
- .ar-layout > aside.ar-aside.left {
4
- min-width: 3.85rem;
5
- max-width: 3.85rem;
6
- padding: 0 1rem;
7
- overflow: hidden;
8
- }
9
- .ar-layout > aside.ar-aside.left:hover {
10
- min-width: 280px;
11
- max-width: 280px;
12
- }
13
- .ar-layout > aside.ar-aside.left > .logo {
14
- visibility: hidden;
15
- opacity: 0;
16
- height: 5rem;
17
- margin-bottom: 1rem;
18
- }
19
-
20
3
  .ar-layout > aside.ar-aside.right {
21
4
  width: 100%;
22
5
  }
@@ -1,15 +1,5 @@
1
1
  /* X-Large (Standart Laptop & Küçük Desktop) */
2
2
  @media (min-width: 992px) and (max-width: 1199px) {
3
- .ar-layout > aside.ar-aside.left {
4
- min-width: 280px;
5
- max-width: 280px;
6
- padding: 0 1rem;
7
- }
8
- .ar-layout > aside.ar-aside.left > .logo {
9
- height: 5rem;
10
- margin-bottom: 1rem;
11
- }
12
-
13
3
  .ar-layout > aside.ar-aside.right {
14
4
  width: 100%;
15
5
  }
@@ -1,19 +1,3 @@
1
1
  /* X-Small (Ekstra Küçük Telefonlar, Saat vb.) */
2
2
  @media (max-width: 320px) {
3
- .ar-layout > aside.ar-aside.left {
4
- min-width: 3.7rem;
5
- max-width: 3.7rem;
6
- padding: 0 1rem;
7
- overflow: hidden;
8
- }
9
- .ar-layout > aside.ar-aside.left:hover {
10
- min-width: 280px;
11
- max-width: 280px;
12
- }
13
- .ar-layout > aside.ar-aside.left > .logo {
14
- visibility: hidden;
15
- opacity: 0;
16
- height: 5rem;
17
- margin-bottom: 1rem;
18
- }
19
3
  }
@@ -1,15 +1,5 @@
1
1
  /* XX-Large (Laptop & Büyük Desktop Ekranlar) */
2
2
  @media (min-width: 1200px) and (max-width: 1399px) {
3
- .ar-layout > aside.ar-aside.left {
4
- min-width: 280px;
5
- max-width: 280px;
6
- padding: 0 1rem;
7
- }
8
- .ar-layout > aside.ar-aside.left > .logo {
9
- height: 5rem;
10
- margin-bottom: 1rem;
11
- }
12
-
13
3
  .ar-layout > aside.ar-aside.right {
14
4
  width: 100%;
15
5
  }
@@ -1,16 +1,6 @@
1
1
  /* XXX-Large (Büyük Ekranlar: TV, Ultra Geniş Monitörler) */
2
2
 
3
3
  @media (min-width: 1400px) {
4
- .ar-layout > aside.ar-aside.left {
5
- min-width: 280px;
6
- max-width: 280px;
7
- padding: 0 1rem;
8
- }
9
- .ar-layout > aside.ar-aside.left > .logo {
10
- height: 5rem;
11
- margin-bottom: 1rem;
12
- }
13
-
14
4
  .ar-layout > aside.ar-aside.right {
15
5
  width: 100%;
16
6
  }
@@ -1,123 +1,145 @@
1
- .ar-menu > {
1
+ .ar-menu {
2
+ width: 100%;
2
3
  padding: 0 0.25rem;
3
4
  font-family: var(--system);
4
- }
5
- .ar-menu > ul {
6
- display: flex;
7
- flex-direction: column;
8
- list-style: none;
9
- }
10
- .ar-menu > ul li ul {
11
- display: grid;
12
- grid-template-rows: 0fr;
13
- list-style: none;
14
- }
15
5
 
16
- .ar-menu > ul li .item-render {
17
- position: relative;
18
- display: flex;
19
- flex-direction: row;
20
- align-items: center;
21
- text-wrap: nowrap;
22
- cursor: pointer;
23
- }
24
- .ar-menu > ul li .item-render > hr {
25
- width: 100%;
26
- border: none;
27
- border-bottom: solid 1px currentColor;
28
- margin: 0.5rem 0;
29
- }
30
- .ar-menu > ul li .item-render a {
31
- display: block;
32
- width: 100%;
33
- height: 2rem;
34
- color: inherit;
35
- text-decoration: none;
36
- line-height: 2rem;
37
- }
38
- .ar-menu > ul li .item-render > span:first-child {
39
- display: flex;
40
- justify-content: center;
41
- align-items: center;
42
- min-width: 2rem;
43
- min-height: 2rem;
44
- margin-right: 0.75rem;
45
- border-radius: var(--border-radius-pill);
46
- }
47
- .ar-menu > ul li .item-render > span:first-child svg {
48
- color: var(--light);
49
- }
50
- .ar-menu > ul li .item-render > span:first-child > .no-icon::before {
51
- display: inline-block;
52
- content: "";
53
- width: 0.75rem;
54
- height: 0.75rem;
55
- border: dashed 2px transparent;
56
- border-top-color: var(--light);
57
- border-right-color: var(--light);
58
- border-left-color: rgba(var(--black-rgb), 0.1);
59
- border-bottom-color: rgba(var(--black-rgb), 0.1);
60
- transform-origin: center;
61
- transform: rotate(45deg);
62
- }
63
- .ar-menu > ul li .item-render > .angel-down {
64
- position: absolute;
65
- top: calc(var(--input-height) / 2);
66
- transform: translateY(-50%);
67
- right: 0.5rem;
68
- width: 0.75rem;
69
- margin-left: auto;
70
- height: 0.75rem;
71
- cursor: pointer;
72
- }
73
- .ar-menu > ul li .item-render > .angel-down::before {
74
- display: inline-block;
75
- content: "";
76
- position: absolute;
77
- width: 100%;
78
- height: 100%;
79
- border: 1px transparent;
80
- border-top-style: solid;
81
- border-right-style: solid;
82
- border-bottom-style: dashed;
83
- border-left-style: dashed;
84
- border-top-color: rgba(var(--black-rgb), 0.5);
85
- border-right-color: rgba(var(--black-rgb), 0.5);
86
- border-left-color: rgba(var(--black-rgb), 0.1);
87
- border-bottom-color: rgba(var(--black-rgb), 0.1);
88
- transform-origin: center;
89
- transform: rotate(45deg);
90
- transition: transform 250ms ease-in-out;
91
- }
92
- .ar-menu > ul li .item-render > .angel-down.opened::before {
93
- transform: rotate(135deg);
94
- }
6
+ > ul {
7
+ display: flex;
8
+ flex-direction: column;
9
+ padding: 0;
10
+ margin: 0;
11
+ list-style: none;
95
12
 
96
- .ar-menu > ul li.divider {
97
- color: var(--black);
98
- }
13
+ li {
14
+ list-style: none;
99
15
 
100
- .ar-menu > ul li.selected {
101
- color: var(--primary);
102
- }
103
- .ar-menu > ul li.selected .item-render > span:first-child {
104
- background-color: var(--primary);
105
- box-shadow: 0 0 0 5px rgba(var(--primary-rgb), 0.1);
106
- color: var(--white) !important;
107
- }
108
- .ar-menu > ul li.selected .item-render > span:first-child > .no-icon::before {
109
- display: inline-block;
110
- content: "";
111
- width: 0.75rem;
112
- height: 0.75rem;
113
- border: solid 2px transparent;
114
- border-top-color: var(--light);
115
- border-right-color: var(--light);
116
- border-left-color: rgba(var(--black-rgb), 0.1);
117
- border-bottom-color: rgba(var(--black-rgb), 0.1);
118
- transform-origin: center;
119
- transform: rotate(45deg);
120
- }
16
+ > ul.submenu {
17
+ display: grid;
18
+ grid-template-rows: 0fr;
19
+ margin-left: 1.5rem;
20
+ opacity: 0;
21
+ transform: translateY(-4px);
22
+ transition: grid-template-rows 250ms ease, opacity 200ms ease, transform 200ms ease;
23
+ overflow: hidden;
24
+
25
+ > .submenu-inner {
26
+ display: flex;
27
+ flex-direction: column;
28
+ overflow: hidden;
29
+ }
30
+
31
+ &.opened {
32
+ grid-template-rows: 1fr;
33
+ opacity: 1;
34
+ transform: translateY(0);
35
+ }
36
+ }
37
+
38
+ .item-render {
39
+ position: relative;
40
+ display: flex;
41
+ align-items: center;
42
+ gap: 0.5rem;
43
+ padding: 0.3rem;
44
+ white-space: nowrap;
45
+ cursor: pointer;
46
+
47
+ &.align-center {
48
+ justify-content: center;
49
+ }
50
+
51
+ &.align-left {
52
+ justify-content: flex-start;
53
+ }
54
+
55
+ > hr {
56
+ width: 100%;
57
+ border: none;
58
+ border-bottom: 1px solid currentColor;
59
+ margin: 0.5rem 0;
60
+ }
61
+
62
+ > .icon {
63
+ display: flex;
64
+ justify-content: center;
65
+ align-items: center;
66
+ min-width: 2rem;
67
+ min-height: 2rem;
68
+ border-radius: var(--border-radius-pill);
69
+
70
+ svg {
71
+ color: var(--light);
72
+ }
121
73
 
122
- /* Core Css */
123
- @import url("./core/open-or-close.css");
74
+ > .no-icon::before {
75
+ display: inline-block;
76
+ content: "";
77
+ width: 0.75rem;
78
+ height: 0.75rem;
79
+ border: dashed 2px transparent;
80
+ border-top-color: var(--light);
81
+ border-right-color: var(--light);
82
+ border-left-color: rgba(var(--black-rgb), 0.1);
83
+ border-bottom-color: rgba(var(--black-rgb), 0.1);
84
+ transform: rotate(45deg);
85
+ }
86
+ }
87
+
88
+ > .angel-down {
89
+ position: absolute;
90
+ right: 0.5rem;
91
+ width: 0.75rem;
92
+ height: 0.75rem;
93
+
94
+ &::before {
95
+ content: "";
96
+ position: absolute;
97
+ width: 100%;
98
+ height: 100%;
99
+ border: 1px transparent;
100
+ border-top-style: solid;
101
+ border-right-style: solid;
102
+ border-bottom-style: dashed;
103
+ border-left-style: dashed;
104
+ border-top-color: rgba(var(--black-rgb), 0.5);
105
+ border-right-color: rgba(var(--black-rgb), 0.5);
106
+ border-left-color: rgba(var(--black-rgb), 0.1);
107
+ border-bottom-color: rgba(var(--black-rgb), 0.1);
108
+ transform: rotate(45deg);
109
+ transition: transform 200ms ease-in-out;
110
+ }
111
+
112
+ &.opened::before {
113
+ transform: rotate(135deg);
114
+ }
115
+ }
116
+ }
117
+
118
+ &.divider {
119
+ color: var(--black);
120
+ }
121
+
122
+ &.selected {
123
+ color: var(--selected-icon-bg-color);
124
+
125
+ .icon {
126
+ background-color: var(--selected-icon-bg-color);
127
+ box-shadow: 0 0 0 5px var(--selected-icon-bg-color-rgb);
128
+ color: var(--white);
129
+
130
+ svg {
131
+ color: var(--white);
132
+ }
133
+ }
134
+
135
+ .no-icon::before {
136
+ border: solid 2px transparent;
137
+ border-top-color: var(--light);
138
+ border-right-color: var(--light);
139
+ border-left-color: rgba(var(--black-rgb), 0.1);
140
+ border-bottom-color: rgba(var(--black-rgb), 0.1);
141
+ }
142
+ }
143
+ }
144
+ }
145
+ }
@@ -721,7 +721,7 @@ const Table = forwardRef(({ children, trackBy, title, description, data, columns
721
721
  handleFilterPopupContent(c, dataType, cIndex);
722
722
  } },
723
723
  React.createElement(Button, { variant: "borderless", icon: {
724
- element: (React.createElement(ARIcon, { viewBox: "0 0 16 16", size: 24, icon: "Filter", fill: "var(--dark)", strokeWidth: 0 })),
724
+ element: React.createElement(ARIcon, { size: 24, icon: "Filter", fill: "var(--dark)", strokeWidth: 0 }),
725
725
  } }))))));
726
726
  })))),
727
727
  React.createElement("tbody", { ref: _tBody }, renderTBody))),
@@ -25,6 +25,10 @@ class Icon {
25
25
  React.createElement("path", { d: "M9 6a3 3 0 1 0 0-6 3 3 0 0 0 0 6M7 3a2 2 0 1 1 4 0 2 2 0 0 1-4 0" })));
26
26
  case "CheckAll":
27
27
  return (React.createElement("path", { d: "M8.97 4.97a.75.75 0 0 1 1.07 1.05l-3.99 4.99a.75.75 0 0 1-1.08.02L2.324 8.384a.75.75 0 1 1 1.06-1.06l2.094 2.093L8.95 4.992zm-.92 5.14.92.92a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 1 0-1.091-1.028L9.477 9.417l-.485-.486z" }));
28
+ case "ChevronBarLeft":
29
+ return (React.createElement("path", { d: "M11.854 3.646a.5.5 0 0 1 0 .708L8.207 8l3.647 3.646a.5.5 0 0 1-.708.708l-4-4a.5.5 0 0 1 0-.708l4-4a.5.5 0 0 1 .708 0M4.5 1a.5.5 0 0 0-.5.5v13a.5.5 0 0 0 1 0v-13a.5.5 0 0 0-.5-.5", fillRule: "evenodd", stroke: this._stroke, strokeWidth: this._strokeWidth, strokeMiterlimit: "10", strokeLinecap: "round", strokeLinejoin: "round" }));
30
+ case "ChevronBarRight":
31
+ return (React.createElement("path", { d: "M4.146 3.646a.5.5 0 0 0 0 .708L7.793 8l-3.647 3.646a.5.5 0 0 0 .708.708l4-4a.5.5 0 0 0 0-.708l-4-4a.5.5 0 0 0-.708 0M11.5 1a.5.5 0 0 1 .5.5v13a.5.5 0 0 1-1 0v-13a.5.5 0 0 1 .5-.5", fillRule: "evenodd", stroke: this._stroke, strokeWidth: this._strokeWidth, strokeMiterlimit: "10", strokeLinecap: "round", strokeLinejoin: "round" }));
28
32
  case "ChevronDown":
29
33
  return (React.createElement("path", { fillRule: "evenodd", d: "M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708" }));
30
34
  case "ChevronUp":
@@ -1,7 +1,6 @@
1
1
  import React from "react";
2
2
  import { Icons } from "../../libs/types";
3
3
  export declare const ARIcon: React.FC<{
4
- viewBox?: string;
5
4
  size?: string | number | undefined;
6
5
  icon: Icons;
7
6
  fill?: string;
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import Icon from "./Compiler";
3
- export const ARIcon = ({ viewBox, size = 16, icon, fill = "var(--dark)", stroke = "var(--dark)", strokeWidth = 1, style }) => {
3
+ export const ARIcon = ({ size = 16, icon, fill = "var(--dark)", stroke = "var(--dark)", strokeWidth = 1, style }) => {
4
4
  const { Compiler } = new Icon(stroke, strokeWidth);
5
- return (React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: viewBox ?? `0 0 16 16`, fill: fill, width: size, height: size, style: style }, Compiler(icon)));
5
+ return (React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 16 16", fill: fill, width: size, height: size, style: style }, Compiler(icon)));
6
6
  };
@@ -5,9 +5,12 @@ export interface ILayoutProps extends IChildren {
5
5
  export interface IHeaderProps {
6
6
  actions?: React.ReactNode;
7
7
  }
8
- export interface ILSiderProps {
9
- image?: React.ReactElement<SVGElement | HTMLImageElement>;
10
- text?: string | React.JSX.Element;
8
+ export interface ILSiderProps extends React.HTMLAttributes<HTMLElement> {
9
+ logo?: {
10
+ default: React.ReactElement<SVGElement | HTMLImageElement>;
11
+ mini: React.ReactElement<SVGElement | HTMLImageElement>;
12
+ onClick?: () => void;
13
+ };
11
14
  footer?: string;
12
15
  }
13
16
  export interface IMainProps extends IChildren {
@@ -1,18 +1,50 @@
1
1
  "use client";
2
- import React from "react";
2
+ import React, { useEffect, useState } from "react";
3
3
  import { useLayout } from "../../libs/core/application/hooks";
4
- import Title from "../data-display/typography/title/Title";
5
4
  import Paragraph from "../data-display/typography/paragraph/Paragraph";
6
- const LSider = ({ image, text, footer }) => {
5
+ import { ARIcon } from "../icons";
6
+ import { DispatchEvent, SessionStorage } from "../../libs/infrastructure/shared/Enums";
7
+ const LSider = ({ logo, footer, ...attributes }) => {
8
+ // states
9
+ const [isLocked, setIsLocked] = useState(true);
10
+ const [isLockedSessionStorage, setIsLockedSessionStorage] = useState(true);
11
+ // variables
12
+ const _className = ["ar-aside", "left", isLocked ? "locked" : "un-locked"];
13
+ if (attributes.className)
14
+ _className.push(attributes.className);
7
15
  // hooks
8
16
  const { config } = useLayout();
9
17
  const sider = config.layout.sider.left;
10
18
  if (!sider?.active)
11
19
  return null;
12
- return (React.createElement("aside", { className: "ar-aside left" },
13
- React.createElement("div", { className: "logo" },
14
- image,
15
- React.createElement(Title, { Level: "h4", align: "center" }, text)),
20
+ // useEffects
21
+ useEffect(() => {
22
+ const onStorageChange = () => {
23
+ setIsLockedSessionStorage(JSON.parse(sessionStorage.getItem(SessionStorage.MenuIsLocked) ?? "true"));
24
+ };
25
+ window.addEventListener(DispatchEvent.MenuLock, onStorageChange);
26
+ window.addEventListener("storage", onStorageChange);
27
+ return () => {
28
+ window.removeEventListener(DispatchEvent.MenuLock, onStorageChange);
29
+ window.removeEventListener("storage", onStorageChange);
30
+ };
31
+ }, []);
32
+ return (React.createElement("aside", { ...attributes, className: _className.map((c) => c).join(" "), onMouseOver: () => {
33
+ sessionStorage.setItem(SessionStorage.MenuIsLocked, String(true));
34
+ window.dispatchEvent(new Event(DispatchEvent.MenuLock));
35
+ }, onMouseLeave: () => {
36
+ sessionStorage.setItem(SessionStorage.MenuIsLocked, String(isLocked));
37
+ window.dispatchEvent(new Event(DispatchEvent.MenuLock));
38
+ } },
39
+ React.createElement("span", { className: "button", role: "button", onClick: () => setIsLocked((prev) => !prev) },
40
+ React.createElement(ARIcon, { size: 20, strokeWidth: 0, fill: "currentColor", icon: isLocked ? "ChevronBarLeft" : "ChevronBarRight" })),
41
+ React.createElement("div", { className: "logo", onClick: () => {
42
+ if (!logo?.onClick)
43
+ return;
44
+ logo?.onClick();
45
+ sessionStorage.setItem(SessionStorage.SelectedMenuItem, "null");
46
+ window.dispatchEvent(new Event(DispatchEvent.SelectedMenuItem));
47
+ } }, isLockedSessionStorage ? logo?.default : logo?.mini),
16
48
  React.createElement("div", null, sider.element),
17
49
  footer && (React.createElement("footer", null,
18
50
  React.createElement(Paragraph, { size: "small" }, footer)))));
@@ -3,5 +3,12 @@ import { MenuItemVariants, MenuProps } from "../../../libs/types";
3
3
  interface IProps extends React.HTMLAttributes<HTMLElement> {
4
4
  data: MenuProps[];
5
5
  variant?: MenuItemVariants;
6
+ config?: {
7
+ icon?: {
8
+ selectedColor: string;
9
+ selectedBackgroundColor: string;
10
+ selectedBackgroundBorderColor: string;
11
+ };
12
+ };
6
13
  }
7
14
  export default IProps;
@@ -1,72 +1,90 @@
1
1
  "use client";
2
2
  import React, { useEffect, useState } from "react";
3
3
  import "../../../assets/css/components/navigation/menu/styles.css";
4
- import SubMenu from "./SubMenu";
5
- const Menu = ({ data, variant = "vertical", ...attributes }) => {
4
+ import { DispatchEvent, SessionStorage } from "../../../libs/infrastructure/shared/Enums";
5
+ const Menu = ({ data, variant = "vertical", config, ...attributes }) => {
6
6
  // states
7
- const [selectedMenu, setSelectedMenu] = useState([]);
8
- const [selectedItem, setSelectedItem] = useState(null);
9
- // variables
10
- const sessionStorageKey = "selected-menu-item";
7
+ const [openMenus, setOpenMenus] = useState([]);
8
+ const [selectedKey, setSelectedKey] = useState(null);
9
+ const [isMenuLocked, setIsMenuLocked] = useState(true);
11
10
  // methods
12
- const handleClick = (event, item, setSelectedItem) => {
13
- event.stopPropagation();
14
- const target = event.currentTarget;
15
- const childNodes = Array.from(target.childNodes);
16
- const ul = childNodes.filter((child) => child instanceof HTMLUListElement); // alt menü UL
17
- const div = childNodes.filter((child) => child instanceof HTMLDivElement); // item render div
18
- if (ul.length > 0) {
19
- // Alt menüyü aç/kapa.
20
- const span = div[0].querySelector(".angel-down");
21
- span?.classList.toggle("opened");
22
- ul[0].classList.toggle("opened");
11
+ const handleItemClick = (item) => {
12
+ if (!isMenuLocked && item.type === "group")
13
+ return;
14
+ if (item.type === "group") {
15
+ const parents = findPath(item.key, data) ?? [];
16
+ setOpenMenus((prev) => {
17
+ const isOpen = prev.includes(item.key);
18
+ if (isOpen)
19
+ return prev.filter((k) => k !== item.key);
20
+ return [...parents, item.key];
21
+ });
22
+ return;
23
23
  }
24
- else {
25
- const selectedItems = document.querySelectorAll(".selected");
26
- selectedItems.forEach((el) => el.classList.remove("selected"));
27
- if (!target.classList.contains("divider")) {
28
- target.classList.add("selected");
29
- // SessionStorage'a kaydeder.
30
- setSelectedItem(item);
31
- sessionStorage.setItem(sessionStorageKey, JSON.stringify(item));
32
- }
24
+ if (item.type !== "divider") {
25
+ setSelectedKey(item.key);
26
+ sessionStorage.setItem(SessionStorage.SelectedMenuItem, String(item.key));
33
27
  }
34
28
  };
35
- const openParentMenusDOM = (li) => {
36
- if (!li)
37
- return;
38
- let parent = li.parentElement; // ul
39
- while (parent && parent.tagName === "DIV") {
40
- const parentLi = parent.closest("li");
41
- if (parentLi) {
42
- const ul = parentLi.querySelector("ul");
43
- const span = parentLi.querySelector(".angel-down");
44
- ul?.classList.add("opened");
45
- span?.classList.add("opened");
29
+ const findPath = (key, items, path = []) => {
30
+ for (const item of items) {
31
+ if (item.key === key)
32
+ return path;
33
+ if (item.submenu) {
34
+ const result = findPath(key, item.submenu, [...path, item.key]);
35
+ if (result)
36
+ return result;
46
37
  }
47
- parent = parentLi?.parentElement || null;
48
38
  }
39
+ return null;
49
40
  };
50
41
  // useEffects
51
42
  useEffect(() => {
52
- if (data.length === 0)
43
+ if (!data.length)
53
44
  return;
54
- const stored = JSON.parse(sessionStorage.getItem(sessionStorageKey) ?? "{}");
55
- const _menuItem = (Object.keys(stored).length > 0 ? stored : data[0]);
56
- setSelectedItem(_menuItem);
57
- // DOM üzerinde seçili li elementini bul ve üst menüleri aç
58
- const li = document.querySelector(`li[data-menu-id="ar-menu-${_menuItem.key}"]`);
59
- openParentMenusDOM(li);
45
+ const selectedMenuItem = sessionStorage.getItem(SessionStorage.SelectedMenuItem) ?? "";
46
+ setSelectedKey(selectedMenuItem);
47
+ const parents = findPath(selectedMenuItem, data);
48
+ if (parents)
49
+ setOpenMenus(parents);
60
50
  }, [data]);
51
+ useEffect(() => {
52
+ const onStorageChangeSelectedMenuItem = () => {
53
+ setSelectedKey(JSON.parse(sessionStorage.getItem(SessionStorage.SelectedMenuItem) ?? ""));
54
+ };
55
+ const onStorageChangeMenuLock = () => {
56
+ setIsMenuLocked(JSON.parse(sessionStorage.getItem(SessionStorage.MenuIsLocked) ?? "true"));
57
+ };
58
+ window.addEventListener(DispatchEvent.SelectedMenuItem, onStorageChangeSelectedMenuItem);
59
+ window.addEventListener(DispatchEvent.MenuLock, onStorageChangeMenuLock);
60
+ const styles = document.createElement("style");
61
+ styles.innerHTML = `
62
+ :root {
63
+ --selected-icon-color: ${config?.icon?.selectedColor};
64
+ --selected-icon-bg-color: ${config?.icon?.selectedBackgroundColor};
65
+ --selected-icon-bg-color-rgb: ${config?.icon?.selectedBackgroundBorderColor};
66
+ }
67
+ `;
68
+ document.head.appendChild(styles);
69
+ return () => {
70
+ window.removeEventListener(DispatchEvent.SelectedMenuItem, onStorageChangeSelectedMenuItem);
71
+ window.removeEventListener(DispatchEvent.MenuLock, onStorageChangeMenuLock);
72
+ };
73
+ }, []);
74
+ console.log(selectedKey);
61
75
  return (React.createElement("nav", { className: "ar-menu", ...attributes },
62
- React.createElement("ul", null, data.map((item, index) => {
63
- return (React.createElement("li", { key: index, "data-menu-id": `ar-menu-${item.key}`, className: `${item.type === "divider" ? "divider" : ""} ${selectedItem?.key === item.key ? "selected" : ""}`, onClick: (event) => handleClick(event, item, setSelectedItem) },
64
- React.createElement("div", { className: "item-render" },
65
- item.type !== "divider" && React.createElement("span", null, item.icon ? item.icon : React.createElement("span", { className: "no-icon" })),
66
- item.type === "divider" ? React.createElement("hr", null) : React.createElement("span", { className: "item" }, item.render),
67
- item.type === "group" && React.createElement("span", { className: "angel-down" })),
68
- item.submenu && (React.createElement(SubMenu, { items: item.submenu, variant: variant, setSelectedMenu: setSelectedMenu, selectedMenu: selectedMenu, setSelectedItem: setSelectedItem, selectedItem: selectedItem, handleClick: handleClick }))));
69
- }))));
76
+ React.createElement("ul", null, data.map((item) => (React.createElement(MenuItem, { key: item.key, item: item, openMenus: openMenus, selectedKey: selectedKey, isMenuLocked: isMenuLocked, onClick: handleItemClick }))))));
77
+ };
78
+ const MenuItem = ({ item, openMenus, selectedKey, isMenuLocked, onClick }) => {
79
+ const isOpen = openMenus.includes(item.key);
80
+ const isSelected = selectedKey === item.key && item.type !== "group";
81
+ return (React.createElement("li", { "data-menu-id": `ar-menu-${item.key}`, className: `${item.type === "divider" ? "divider" : ""} ${isSelected ? "selected" : ""}` },
82
+ React.createElement("div", { className: `item-render ${isMenuLocked ? "align-left" : "align-center"}`, onClick: () => onClick(item) },
83
+ item.type !== "divider" && React.createElement("span", { className: "icon" }, item.icon ?? React.createElement("span", { className: "no-icon" })),
84
+ isMenuLocked && (item.type === "divider" ? React.createElement("hr", null) : React.createElement("span", { className: "item" }, item.render)),
85
+ isMenuLocked && item.type === "group" && React.createElement("span", { className: `angel-down ${isOpen ? "opened" : ""}` })),
86
+ item.submenu && isMenuLocked && (React.createElement("ul", { className: `submenu ${isOpen ? "opened" : ""}` },
87
+ React.createElement("div", { className: "submenu-inner" }, item.submenu.map((sub) => (React.createElement(MenuItem, { key: sub.key, item: sub, openMenus: openMenus, selectedKey: selectedKey, isMenuLocked: isMenuLocked, onClick: onClick }))))))));
70
88
  };
71
89
  Menu.displayName = "Menu";
72
90
  export default Menu;
@@ -8,3 +8,11 @@ export declare enum FilterOperator {
8
8
  Blank = 7,
9
9
  NotBlank = 8
10
10
  }
11
+ export declare enum SessionStorage {
12
+ SelectedMenuItem = "selected-menu-item",
13
+ MenuIsLocked = "is-menu-locked"
14
+ }
15
+ export declare enum DispatchEvent {
16
+ SelectedMenuItem = "selectedMenuItem",
17
+ MenuLock = "menuLock"
18
+ }
@@ -9,3 +9,13 @@ export var FilterOperator;
9
9
  FilterOperator[FilterOperator["Blank"] = 7] = "Blank";
10
10
  FilterOperator[FilterOperator["NotBlank"] = 8] = "NotBlank";
11
11
  })(FilterOperator || (FilterOperator = {}));
12
+ export var SessionStorage;
13
+ (function (SessionStorage) {
14
+ SessionStorage["SelectedMenuItem"] = "selected-menu-item";
15
+ SessionStorage["MenuIsLocked"] = "is-menu-locked";
16
+ })(SessionStorage || (SessionStorage = {}));
17
+ export var DispatchEvent;
18
+ (function (DispatchEvent) {
19
+ DispatchEvent["SelectedMenuItem"] = "selectedMenuItem";
20
+ DispatchEvent["MenuLock"] = "menuLock";
21
+ })(DispatchEvent || (DispatchEvent = {}));
@@ -85,7 +85,7 @@ export type Errors<TData> = Partial<{
85
85
  }>;
86
86
  export type MimeTypes = "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";
87
87
  export type FileCategory = "image" | "document" | "spreadsheet" | "presentation" | "archive" | "text" | "video" | "audio" | "json" | "xml" | "binary" | "other";
88
- export type Icons = "Add" | "ArrowLeft" | "ArrowRight" | "Bold" | "BulletList" | "CameraReels" | "CheckAll" | "ChevronDown" | "ChevronUp" | "CloseCircle" | "CloseSquare" | "CloudUpload-Fill" | "Dash" | "Document" | "Download" | "ExclamationCircle" | "ExclamationDiamond-Fill" | "Eye-Fill" | "File" | "FileEarmark-Fill" | "FileTypeCsv" | "FileTypeDoc" | "FileTypeDocx" | "FileTypeHtml" | "FileTypeJson" | "FileTypePdf" | "FileTypePptx" | "FileTypeTxt" | "FileTypeXls" | "FileTypeXlsx" | "FileTypeXml" | "FileTypeZip" | "Filter" | "Floppy-Fill" | "Folder" | "Front" | "GripVertical" | "Import" | "Inbox-Fill" | "Information-Circle-Fill" | "Italic" | "NumberList" | "Strikethrough" | "TextAlingCenter" | "TextAlingLeft" | "TextAlingRight" | "TickCircle" | "Trash-Fill" | "Underline" | "Upload" | "Warning" | "XCircle-Fill";
88
+ export type Icons = "Add" | "ArrowLeft" | "ArrowRight" | "Bold" | "BulletList" | "CameraReels" | "CheckAll" | "ChevronBarLeft" | "ChevronBarRight" | "ChevronDown" | "ChevronUp" | "CloseCircle" | "CloseSquare" | "CloudUpload-Fill" | "Dash" | "Document" | "Download" | "ExclamationCircle" | "ExclamationDiamond-Fill" | "Eye-Fill" | "File" | "FileEarmark-Fill" | "FileTypeCsv" | "FileTypeDoc" | "FileTypeDocx" | "FileTypeHtml" | "FileTypeJson" | "FileTypePdf" | "FileTypePptx" | "FileTypeTxt" | "FileTypeXls" | "FileTypeXlsx" | "FileTypeXml" | "FileTypeZip" | "Filter" | "Floppy-Fill" | "Folder" | "Front" | "GripVertical" | "Import" | "Inbox-Fill" | "Information-Circle-Fill" | "Italic" | "NumberList" | "Strikethrough" | "TextAlingCenter" | "TextAlingLeft" | "TextAlingRight" | "TickCircle" | "Trash-Fill" | "Underline" | "Upload" | "Warning" | "XCircle-Fill";
89
89
  export type PieChartDataType = {
90
90
  value: number;
91
91
  text: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ar-design",
3
- "version": "0.3.86",
3
+ "version": "0.3.88",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -1,12 +0,0 @@
1
- import React from "react";
2
- import { MenuItemVariants, MenuProps } from "../../../libs/types";
3
- declare const SubMenu: ({ items, variant, setSelectedMenu, selectedMenu, setSelectedItem, selectedItem, handleClick, }: {
4
- items: MenuProps[];
5
- variant: MenuItemVariants;
6
- setSelectedMenu: React.Dispatch<React.SetStateAction<MenuProps[]>>;
7
- selectedMenu: MenuProps[];
8
- setSelectedItem: React.Dispatch<React.SetStateAction<MenuProps | null>>;
9
- selectedItem: MenuProps | null;
10
- handleClick: (event: React.MouseEvent<HTMLLIElement, MouseEvent>, item: MenuProps, setSelectedItem: React.Dispatch<React.SetStateAction<MenuProps | null>>) => void;
11
- }) => React.JSX.Element | null;
12
- export default SubMenu;
@@ -1,15 +0,0 @@
1
- import React from "react";
2
- const SubMenu = ({ items, variant, setSelectedMenu, selectedMenu, setSelectedItem, selectedItem, handleClick, }) => {
3
- if (!items)
4
- return null;
5
- return (React.createElement("ul", null,
6
- React.createElement("div", null, items.map((item, index) => {
7
- return (React.createElement("li", { key: index, "data-menu-id": `ar-menu-${item.key}`, className: `${item.type === "divider" ? "divider" : ""} ${selectedItem?.key === item.key ? "selected" : ""}`, onClick: (event) => handleClick(event, item, setSelectedItem) },
8
- React.createElement("div", { className: "item-render" },
9
- item.type !== "divider" && React.createElement("span", null, item.icon ? item.icon : React.createElement("span", { className: "no-icon" })),
10
- item.type === "divider" ? React.createElement("hr", null) : React.createElement("span", { className: "item" }, item.render),
11
- item.type === "group" && React.createElement("span", { className: "angel-down" })),
12
- item.submenu && (React.createElement(SubMenu, { items: item.submenu, variant: variant, setSelectedMenu: setSelectedMenu, selectedMenu: selectedMenu, setSelectedItem: setSelectedItem, selectedItem: selectedItem, handleClick: handleClick }))));
13
- }))));
14
- };
15
- export default SubMenu;