pesona-ui 1.0.1
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/README.md +50 -0
- package/dist/index.cjs.js +195 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.esm.js +183 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/styles/pesona-ui.css +1 -0
- package/dist/types/components/Badge/Badge.d.ts +8 -0
- package/dist/types/components/Badge/index.d.ts +1 -0
- package/dist/types/components/Button/Button.d.ts +5 -0
- package/dist/types/components/Button/index.d.ts +1 -0
- package/dist/types/components/Card/Card.d.ts +26 -0
- package/dist/types/components/Card/index.d.ts +1 -0
- package/dist/types/components/Dropdown/Dropdown.d.ts +25 -0
- package/dist/types/components/Dropdown/DropdownMenu.d.ts +16 -0
- package/dist/types/components/Dropdown/index.d.ts +2 -0
- package/dist/types/components/Spinner/Spinner.d.ts +4 -0
- package/dist/types/components/Spinner/index.d.ts +1 -0
- package/dist/types/components/index.d.ts +5 -0
- package/dist/types/hooks/useOutsideClick.d.ts +12 -0
- package/dist/types/index.d.ts +1 -0
- package/package.json +57 -0
package/README.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# React + TypeScript + Vite
|
|
2
|
+
|
|
3
|
+
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
|
4
|
+
|
|
5
|
+
Currently, two official plugins are available:
|
|
6
|
+
|
|
7
|
+
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
|
|
8
|
+
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
|
|
9
|
+
|
|
10
|
+
## Expanding the ESLint configuration
|
|
11
|
+
|
|
12
|
+
If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:
|
|
13
|
+
|
|
14
|
+
- Configure the top-level `parserOptions` property like this:
|
|
15
|
+
|
|
16
|
+
```js
|
|
17
|
+
export default tseslint.config({
|
|
18
|
+
languageOptions: {
|
|
19
|
+
// other options...
|
|
20
|
+
parserOptions: {
|
|
21
|
+
project: ['./tsconfig.node.json', './tsconfig.app.json'],
|
|
22
|
+
tsconfigRootDir: import.meta.dirname,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
})
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
- Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked`
|
|
29
|
+
- Optionally add `...tseslint.configs.stylisticTypeChecked`
|
|
30
|
+
- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config:
|
|
31
|
+
|
|
32
|
+
```js
|
|
33
|
+
// eslint.config.js
|
|
34
|
+
import react from 'eslint-plugin-react'
|
|
35
|
+
|
|
36
|
+
export default tseslint.config({
|
|
37
|
+
// Set the react version
|
|
38
|
+
settings: { react: { version: '18.3' } },
|
|
39
|
+
plugins: {
|
|
40
|
+
// Add the react plugin
|
|
41
|
+
react,
|
|
42
|
+
},
|
|
43
|
+
rules: {
|
|
44
|
+
// other rules...
|
|
45
|
+
// Enable its recommended rules
|
|
46
|
+
...react.configs.recommended.rules,
|
|
47
|
+
...react.configs['jsx-runtime'].rules,
|
|
48
|
+
},
|
|
49
|
+
})
|
|
50
|
+
```
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
var ReactDOM = require('react-dom');
|
|
5
|
+
|
|
6
|
+
const Button = ({ type = 'button', className, children, ...rest }) => {
|
|
7
|
+
return (React.createElement("button", { type: type === 'submit' ? 'submit' : 'button', className: className, ...rest }, children));
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const CardHeader = ({ children, className }) => (React.createElement("div", { className: `card-header ${className}` }, children));
|
|
11
|
+
const CardBody = ({ children, className = '', ...rest }) => (React.createElement("div", { className: `card-body ${className}`, ...rest }, children));
|
|
12
|
+
const CardFooter = ({ children, className = '' }) => (React.createElement("div", { className: `card-footer ${className}` }, children));
|
|
13
|
+
const Card = ({ children, className = '', ...rest }) => (React.createElement("div", { className: `card ${className}`, ...rest }, children));
|
|
14
|
+
|
|
15
|
+
const Spinner = () => {
|
|
16
|
+
return (React.createElement("div", { className: "spinner" },
|
|
17
|
+
React.createElement("svg", { className: "spinner-icon", width: "30px", height: "30px", viewBox: "0 0 66 66", xmlns: "http://www.w3.org/2000/svg" },
|
|
18
|
+
React.createElement("circle", { className: "path", fill: "none", strokeWidth: "6", strokeLinecap: "round", cx: "33", cy: "33", r: "30" }))));
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Hook untuk mendeteksi klik di luar elemen yang diberikan
|
|
23
|
+
* @param refs Array of refs dari elemen yang akan dimonitor
|
|
24
|
+
* @param handler Fungsi yang akan dipanggil ketika klik terjadi di luar elemen
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* const ref = useRef<HTMLDivElement>(null);
|
|
28
|
+
* useOutsideClick([ref], () => {});
|
|
29
|
+
*/
|
|
30
|
+
const useOutsideClick = (refs, handler) => {
|
|
31
|
+
React.useEffect(() => {
|
|
32
|
+
// Cek apakah refs valid
|
|
33
|
+
if (!Array.isArray(refs) || refs.length === 0) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const handleClickOutside = (event) => {
|
|
37
|
+
// Cek apakah klik terjadi di luar semua refs yang diberikan
|
|
38
|
+
const isOutside = refs.every((ref) => {
|
|
39
|
+
return ref.current && !ref.current.contains(event.target);
|
|
40
|
+
});
|
|
41
|
+
if (isOutside) {
|
|
42
|
+
handler();
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
// Menambahkan event listener
|
|
46
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
47
|
+
// Cleanup event listener
|
|
48
|
+
return () => {
|
|
49
|
+
document.removeEventListener('mousedown', handleClickOutside);
|
|
50
|
+
};
|
|
51
|
+
}, [refs, handler]);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const DropdownMenu = ({ children, items, position = 'bottom-left', className = '', }) => {
|
|
55
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
56
|
+
const [menuPosition, setMenuPosition] = React.useState({ top: 0, left: 0 });
|
|
57
|
+
const triggerRef = React.useRef(null);
|
|
58
|
+
const menuRef = React.useRef(null);
|
|
59
|
+
useOutsideClick([triggerRef, menuRef], () => {
|
|
60
|
+
setIsOpen(false);
|
|
61
|
+
});
|
|
62
|
+
React.useEffect(() => {
|
|
63
|
+
if (isOpen && triggerRef.current && menuRef.current) {
|
|
64
|
+
const triggerRect = triggerRef.current.getBoundingClientRect();
|
|
65
|
+
const menuRect = menuRef.current.getBoundingClientRect();
|
|
66
|
+
const { scrollX, scrollY } = window;
|
|
67
|
+
let top = 0;
|
|
68
|
+
let left = 0;
|
|
69
|
+
switch (position) {
|
|
70
|
+
case 'bottom-left':
|
|
71
|
+
top = triggerRect.bottom;
|
|
72
|
+
left = triggerRect.left;
|
|
73
|
+
break;
|
|
74
|
+
case 'bottom-right':
|
|
75
|
+
top = triggerRect.bottom;
|
|
76
|
+
left = triggerRect.right - menuRect.width;
|
|
77
|
+
break;
|
|
78
|
+
case 'top-left':
|
|
79
|
+
top = triggerRect.top - menuRect.height;
|
|
80
|
+
left = triggerRect.left;
|
|
81
|
+
break;
|
|
82
|
+
case 'top-right':
|
|
83
|
+
top = triggerRect.top - menuRect.height;
|
|
84
|
+
left = triggerRect.right - menuRect.width;
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
setMenuPosition({
|
|
88
|
+
top: Math.round(top + scrollY),
|
|
89
|
+
left: Math.round(left + scrollX),
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}, [isOpen, position]);
|
|
93
|
+
return (React.createElement(React.Fragment, null,
|
|
94
|
+
React.createElement("div", { ref: triggerRef, onClick: () => setIsOpen(!isOpen) }, children),
|
|
95
|
+
isOpen &&
|
|
96
|
+
ReactDOM.createPortal(React.createElement("div", { ref: menuRef, style: {
|
|
97
|
+
position: 'absolute',
|
|
98
|
+
top: `${menuPosition.top}px`,
|
|
99
|
+
left: `${menuPosition.left}px`,
|
|
100
|
+
}, className: `dropdown-menu ${position} ${className}` }, items.map((item, index) => (React.createElement("div", { key: index, className: `dropdown-menu-item ${item.className}`, onClick: () => {
|
|
101
|
+
item.onClick();
|
|
102
|
+
setIsOpen(false);
|
|
103
|
+
} },
|
|
104
|
+
item.icon && item.icon,
|
|
105
|
+
" ",
|
|
106
|
+
item.label)))), document.body)));
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const Dropdown = ({ children, className = '', position = 'bottom-left' }) => {
|
|
110
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
111
|
+
const dropdownRef = React.useRef(null);
|
|
112
|
+
const contentRef = React.useRef(null);
|
|
113
|
+
const dropdownId = React.useRef(`dropdown-${Math.random().toString(36).substr(2, 9)}`);
|
|
114
|
+
const toggleDropdown = () => {
|
|
115
|
+
setIsOpen(!isOpen);
|
|
116
|
+
};
|
|
117
|
+
useOutsideClick([dropdownRef, contentRef], () => {
|
|
118
|
+
setIsOpen(false);
|
|
119
|
+
});
|
|
120
|
+
return (React.createElement("div", { className: `dropdown ${className}`, ref: dropdownRef, id: dropdownId.current }, React.Children.map(children, (child) => {
|
|
121
|
+
if (React.isValidElement(child)) {
|
|
122
|
+
return React.cloneElement(child, {
|
|
123
|
+
toggleDropdown,
|
|
124
|
+
isOpen,
|
|
125
|
+
position,
|
|
126
|
+
contentRef,
|
|
127
|
+
dropdownId: dropdownId.current,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
return child;
|
|
131
|
+
})));
|
|
132
|
+
};
|
|
133
|
+
const DropdownToggle = ({ children, className = '', toggleDropdown, dropdownId, }) => (React.createElement("div", { className: `dropdown-toggle ${className}`, onClick: toggleDropdown, "data-dropdown-id": dropdownId }, children));
|
|
134
|
+
const DropdownContent = ({ children, className = '', isOpen = false, position = 'bottom-left', contentRef, dropdownId, }) => {
|
|
135
|
+
const [menuPosition, setMenuPosition] = React.useState({ top: 0, left: 0 });
|
|
136
|
+
React.useEffect(() => {
|
|
137
|
+
if (isOpen && contentRef?.current) {
|
|
138
|
+
const triggerElement = document.querySelector(`[data-dropdown-id="${dropdownId}"]`);
|
|
139
|
+
if (triggerElement) {
|
|
140
|
+
const triggerRect = triggerElement.getBoundingClientRect();
|
|
141
|
+
const menuRect = contentRef.current.getBoundingClientRect();
|
|
142
|
+
const { scrollX, scrollY } = window;
|
|
143
|
+
let top = 0;
|
|
144
|
+
let left = 0;
|
|
145
|
+
switch (position) {
|
|
146
|
+
case 'bottom-left':
|
|
147
|
+
top = triggerRect.bottom;
|
|
148
|
+
left = triggerRect.left;
|
|
149
|
+
break;
|
|
150
|
+
case 'bottom-right':
|
|
151
|
+
top = triggerRect.bottom;
|
|
152
|
+
left = triggerRect.right - menuRect.width;
|
|
153
|
+
break;
|
|
154
|
+
case 'top-left':
|
|
155
|
+
top = triggerRect.top - menuRect.height;
|
|
156
|
+
left = triggerRect.left;
|
|
157
|
+
break;
|
|
158
|
+
case 'top-right':
|
|
159
|
+
top = triggerRect.top - menuRect.height;
|
|
160
|
+
left = triggerRect.right - menuRect.width;
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
// Add window scroll offset
|
|
164
|
+
setMenuPosition({
|
|
165
|
+
top: Math.round(top + scrollY),
|
|
166
|
+
left: Math.round(left + scrollX),
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}, [isOpen, position, contentRef, dropdownId]);
|
|
171
|
+
if (!isOpen)
|
|
172
|
+
return null;
|
|
173
|
+
return ReactDOM.createPortal(React.createElement("div", { ref: contentRef, style: {
|
|
174
|
+
position: 'absolute',
|
|
175
|
+
top: `${menuPosition.top}px`,
|
|
176
|
+
left: `${menuPosition.left}px`,
|
|
177
|
+
}, className: `dropdown-content ${position} ${className}` }, children), document.body);
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
const Badge = ({ className, text }) => {
|
|
181
|
+
return React.createElement("span", { className: className }, text);
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
exports.Badge = Badge;
|
|
185
|
+
exports.Button = Button;
|
|
186
|
+
exports.Card = Card;
|
|
187
|
+
exports.CardBody = CardBody;
|
|
188
|
+
exports.CardFooter = CardFooter;
|
|
189
|
+
exports.CardHeader = CardHeader;
|
|
190
|
+
exports.Dropdown = Dropdown;
|
|
191
|
+
exports.DropdownContent = DropdownContent;
|
|
192
|
+
exports.DropdownMenu = DropdownMenu;
|
|
193
|
+
exports.DropdownToggle = DropdownToggle;
|
|
194
|
+
exports.Spinner = Spinner;
|
|
195
|
+
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import React, { useEffect, useState, useRef } from 'react';
|
|
2
|
+
import ReactDOM, { createPortal } from 'react-dom';
|
|
3
|
+
|
|
4
|
+
const Button = ({ type = 'button', className, children, ...rest }) => {
|
|
5
|
+
return (React.createElement("button", { type: type === 'submit' ? 'submit' : 'button', className: className, ...rest }, children));
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const CardHeader = ({ children, className }) => (React.createElement("div", { className: `card-header ${className}` }, children));
|
|
9
|
+
const CardBody = ({ children, className = '', ...rest }) => (React.createElement("div", { className: `card-body ${className}`, ...rest }, children));
|
|
10
|
+
const CardFooter = ({ children, className = '' }) => (React.createElement("div", { className: `card-footer ${className}` }, children));
|
|
11
|
+
const Card = ({ children, className = '', ...rest }) => (React.createElement("div", { className: `card ${className}`, ...rest }, children));
|
|
12
|
+
|
|
13
|
+
const Spinner = () => {
|
|
14
|
+
return (React.createElement("div", { className: "spinner" },
|
|
15
|
+
React.createElement("svg", { className: "spinner-icon", width: "30px", height: "30px", viewBox: "0 0 66 66", xmlns: "http://www.w3.org/2000/svg" },
|
|
16
|
+
React.createElement("circle", { className: "path", fill: "none", strokeWidth: "6", strokeLinecap: "round", cx: "33", cy: "33", r: "30" }))));
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Hook untuk mendeteksi klik di luar elemen yang diberikan
|
|
21
|
+
* @param refs Array of refs dari elemen yang akan dimonitor
|
|
22
|
+
* @param handler Fungsi yang akan dipanggil ketika klik terjadi di luar elemen
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* const ref = useRef<HTMLDivElement>(null);
|
|
26
|
+
* useOutsideClick([ref], () => {});
|
|
27
|
+
*/
|
|
28
|
+
const useOutsideClick = (refs, handler) => {
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
// Cek apakah refs valid
|
|
31
|
+
if (!Array.isArray(refs) || refs.length === 0) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const handleClickOutside = (event) => {
|
|
35
|
+
// Cek apakah klik terjadi di luar semua refs yang diberikan
|
|
36
|
+
const isOutside = refs.every((ref) => {
|
|
37
|
+
return ref.current && !ref.current.contains(event.target);
|
|
38
|
+
});
|
|
39
|
+
if (isOutside) {
|
|
40
|
+
handler();
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
// Menambahkan event listener
|
|
44
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
45
|
+
// Cleanup event listener
|
|
46
|
+
return () => {
|
|
47
|
+
document.removeEventListener('mousedown', handleClickOutside);
|
|
48
|
+
};
|
|
49
|
+
}, [refs, handler]);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const DropdownMenu = ({ children, items, position = 'bottom-left', className = '', }) => {
|
|
53
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
54
|
+
const [menuPosition, setMenuPosition] = useState({ top: 0, left: 0 });
|
|
55
|
+
const triggerRef = useRef(null);
|
|
56
|
+
const menuRef = useRef(null);
|
|
57
|
+
useOutsideClick([triggerRef, menuRef], () => {
|
|
58
|
+
setIsOpen(false);
|
|
59
|
+
});
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
if (isOpen && triggerRef.current && menuRef.current) {
|
|
62
|
+
const triggerRect = triggerRef.current.getBoundingClientRect();
|
|
63
|
+
const menuRect = menuRef.current.getBoundingClientRect();
|
|
64
|
+
const { scrollX, scrollY } = window;
|
|
65
|
+
let top = 0;
|
|
66
|
+
let left = 0;
|
|
67
|
+
switch (position) {
|
|
68
|
+
case 'bottom-left':
|
|
69
|
+
top = triggerRect.bottom;
|
|
70
|
+
left = triggerRect.left;
|
|
71
|
+
break;
|
|
72
|
+
case 'bottom-right':
|
|
73
|
+
top = triggerRect.bottom;
|
|
74
|
+
left = triggerRect.right - menuRect.width;
|
|
75
|
+
break;
|
|
76
|
+
case 'top-left':
|
|
77
|
+
top = triggerRect.top - menuRect.height;
|
|
78
|
+
left = triggerRect.left;
|
|
79
|
+
break;
|
|
80
|
+
case 'top-right':
|
|
81
|
+
top = triggerRect.top - menuRect.height;
|
|
82
|
+
left = triggerRect.right - menuRect.width;
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
setMenuPosition({
|
|
86
|
+
top: Math.round(top + scrollY),
|
|
87
|
+
left: Math.round(left + scrollX),
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}, [isOpen, position]);
|
|
91
|
+
return (React.createElement(React.Fragment, null,
|
|
92
|
+
React.createElement("div", { ref: triggerRef, onClick: () => setIsOpen(!isOpen) }, children),
|
|
93
|
+
isOpen &&
|
|
94
|
+
ReactDOM.createPortal(React.createElement("div", { ref: menuRef, style: {
|
|
95
|
+
position: 'absolute',
|
|
96
|
+
top: `${menuPosition.top}px`,
|
|
97
|
+
left: `${menuPosition.left}px`,
|
|
98
|
+
}, className: `dropdown-menu ${position} ${className}` }, items.map((item, index) => (React.createElement("div", { key: index, className: `dropdown-menu-item ${item.className}`, onClick: () => {
|
|
99
|
+
item.onClick();
|
|
100
|
+
setIsOpen(false);
|
|
101
|
+
} },
|
|
102
|
+
item.icon && item.icon,
|
|
103
|
+
" ",
|
|
104
|
+
item.label)))), document.body)));
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const Dropdown = ({ children, className = '', position = 'bottom-left' }) => {
|
|
108
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
109
|
+
const dropdownRef = useRef(null);
|
|
110
|
+
const contentRef = useRef(null);
|
|
111
|
+
const dropdownId = useRef(`dropdown-${Math.random().toString(36).substr(2, 9)}`);
|
|
112
|
+
const toggleDropdown = () => {
|
|
113
|
+
setIsOpen(!isOpen);
|
|
114
|
+
};
|
|
115
|
+
useOutsideClick([dropdownRef, contentRef], () => {
|
|
116
|
+
setIsOpen(false);
|
|
117
|
+
});
|
|
118
|
+
return (React.createElement("div", { className: `dropdown ${className}`, ref: dropdownRef, id: dropdownId.current }, React.Children.map(children, (child) => {
|
|
119
|
+
if (React.isValidElement(child)) {
|
|
120
|
+
return React.cloneElement(child, {
|
|
121
|
+
toggleDropdown,
|
|
122
|
+
isOpen,
|
|
123
|
+
position,
|
|
124
|
+
contentRef,
|
|
125
|
+
dropdownId: dropdownId.current,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
return child;
|
|
129
|
+
})));
|
|
130
|
+
};
|
|
131
|
+
const DropdownToggle = ({ children, className = '', toggleDropdown, dropdownId, }) => (React.createElement("div", { className: `dropdown-toggle ${className}`, onClick: toggleDropdown, "data-dropdown-id": dropdownId }, children));
|
|
132
|
+
const DropdownContent = ({ children, className = '', isOpen = false, position = 'bottom-left', contentRef, dropdownId, }) => {
|
|
133
|
+
const [menuPosition, setMenuPosition] = useState({ top: 0, left: 0 });
|
|
134
|
+
useEffect(() => {
|
|
135
|
+
if (isOpen && contentRef?.current) {
|
|
136
|
+
const triggerElement = document.querySelector(`[data-dropdown-id="${dropdownId}"]`);
|
|
137
|
+
if (triggerElement) {
|
|
138
|
+
const triggerRect = triggerElement.getBoundingClientRect();
|
|
139
|
+
const menuRect = contentRef.current.getBoundingClientRect();
|
|
140
|
+
const { scrollX, scrollY } = window;
|
|
141
|
+
let top = 0;
|
|
142
|
+
let left = 0;
|
|
143
|
+
switch (position) {
|
|
144
|
+
case 'bottom-left':
|
|
145
|
+
top = triggerRect.bottom;
|
|
146
|
+
left = triggerRect.left;
|
|
147
|
+
break;
|
|
148
|
+
case 'bottom-right':
|
|
149
|
+
top = triggerRect.bottom;
|
|
150
|
+
left = triggerRect.right - menuRect.width;
|
|
151
|
+
break;
|
|
152
|
+
case 'top-left':
|
|
153
|
+
top = triggerRect.top - menuRect.height;
|
|
154
|
+
left = triggerRect.left;
|
|
155
|
+
break;
|
|
156
|
+
case 'top-right':
|
|
157
|
+
top = triggerRect.top - menuRect.height;
|
|
158
|
+
left = triggerRect.right - menuRect.width;
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
// Add window scroll offset
|
|
162
|
+
setMenuPosition({
|
|
163
|
+
top: Math.round(top + scrollY),
|
|
164
|
+
left: Math.round(left + scrollX),
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}, [isOpen, position, contentRef, dropdownId]);
|
|
169
|
+
if (!isOpen)
|
|
170
|
+
return null;
|
|
171
|
+
return createPortal(React.createElement("div", { ref: contentRef, style: {
|
|
172
|
+
position: 'absolute',
|
|
173
|
+
top: `${menuPosition.top}px`,
|
|
174
|
+
left: `${menuPosition.left}px`,
|
|
175
|
+
}, className: `dropdown-content ${position} ${className}` }, children), document.body);
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
const Badge = ({ className, text }) => {
|
|
179
|
+
return React.createElement("span", { className: className }, text);
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
export { Badge, Button, Card, CardBody, CardFooter, CardHeader, Dropdown, DropdownContent, DropdownMenu, DropdownToggle, Spinner };
|
|
183
|
+
//# sourceMappingURL=index.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
button:disabled,button[disabled]{background:transparent!important;color:var(--font-color-secondary)!important;cursor:not-allowed;pointer-events:none}.Button_btn__W6oxS{align-items:center;background:none;border:1px solid transparent;border-radius:4px;color:var(--black-white);display:inline-flex;gap:5px;height:32px;justify-content:center;line-height:1;padding:0 12px;position:relative;touch-action:manipulation;white-space:nowrap}.Button_btn__W6oxS .Button_icon__OeKUC,.Button_btn__W6oxS svg{pointer-events:none}.Button_btn__W6oxS svg{height:14px;margin-top:0;width:14px}.Button_btn__W6oxS:hover{text-decoration:none}.Button_btn__W6oxS:active,.Button_btn__W6oxS:focus{box-shadow:inset 0 3px 5px rgba(0,0,0,.15)}.Button_btn__W6oxS.Button_active__BWfrx{background-color:var(--primary-bg);box-shadow:inset 0 3px 5px rgba(0,0,0,.1)}.Button_btn__W6oxS.Button_btn-default__Cucka{border-color:var(--border-color);color:var(--font-color)}.Button_btn__W6oxS.Button_btn-default__Cucka:hover{background-color:var(--primary-bg)}.Button_btn__W6oxS.Button_btn-danger__nwxfa,.Button_btn__W6oxS.Button_btn-info__kXW9e,.Button_btn__W6oxS.Button_btn-primary__Y1iy-,.Button_btn__W6oxS.Button_btn-success__DK393,.Button_btn__W6oxS.Button_btn-warning__MlDsD{color:#fff}.Button_btn__W6oxS.Button_btn-danger__nwxfa.Button_btn-primary__Y1iy-,.Button_btn__W6oxS.Button_btn-info__kXW9e.Button_btn-primary__Y1iy-,.Button_btn__W6oxS.Button_btn-primary__Y1iy-.Button_btn-primary__Y1iy-,.Button_btn__W6oxS.Button_btn-success__DK393.Button_btn-primary__Y1iy-,.Button_btn__W6oxS.Button_btn-warning__MlDsD.Button_btn-primary__Y1iy-{background-color:#1668dc;border-color:#0f4796}.Button_btn__W6oxS.Button_btn-danger__nwxfa.Button_btn-primary__Y1iy-:hover,.Button_btn__W6oxS.Button_btn-info__kXW9e.Button_btn-primary__Y1iy-:hover,.Button_btn__W6oxS.Button_btn-primary__Y1iy-.Button_btn-primary__Y1iy-:hover,.Button_btn__W6oxS.Button_btn-success__DK393.Button_btn-primary__Y1iy-:hover,.Button_btn__W6oxS.Button_btn-warning__MlDsD.Button_btn-primary__Y1iy-:hover{background-color:#0d3c7f}.Button_btn__W6oxS.Button_btn-danger__nwxfa.Button_btn-success__DK393,.Button_btn__W6oxS.Button_btn-info__kXW9e.Button_btn-success__DK393,.Button_btn__W6oxS.Button_btn-primary__Y1iy-.Button_btn-success__DK393,.Button_btn__W6oxS.Button_btn-success__DK393.Button_btn-success__DK393,.Button_btn__W6oxS.Button_btn-warning__MlDsD.Button_btn-success__DK393{background-color:#66bf60;border-color:#42963c}.Button_btn__W6oxS.Button_btn-danger__nwxfa.Button_btn-success__DK393:hover,.Button_btn__W6oxS.Button_btn-info__kXW9e.Button_btn-success__DK393:hover,.Button_btn__W6oxS.Button_btn-primary__Y1iy-.Button_btn-success__DK393:hover,.Button_btn__W6oxS.Button_btn-success__DK393.Button_btn-success__DK393:hover,.Button_btn__W6oxS.Button_btn-warning__MlDsD.Button_btn-success__DK393:hover{background-color:#3a8435}.Button_btn__W6oxS.Button_btn-danger__nwxfa.Button_btn-info__kXW9e,.Button_btn__W6oxS.Button_btn-info__kXW9e.Button_btn-info__kXW9e,.Button_btn__W6oxS.Button_btn-primary__Y1iy-.Button_btn-info__kXW9e,.Button_btn__W6oxS.Button_btn-success__DK393.Button_btn-info__kXW9e,.Button_btn__W6oxS.Button_btn-warning__MlDsD.Button_btn-info__kXW9e{background-color:#67c2ec;border-color:#23a7e4}.Button_btn__W6oxS.Button_btn-danger__nwxfa.Button_btn-info__kXW9e:hover,.Button_btn__W6oxS.Button_btn-info__kXW9e.Button_btn-info__kXW9e:hover,.Button_btn__W6oxS.Button_btn-primary__Y1iy-.Button_btn-info__kXW9e:hover,.Button_btn__W6oxS.Button_btn-success__DK393.Button_btn-info__kXW9e:hover,.Button_btn__W6oxS.Button_btn-warning__MlDsD.Button_btn-info__kXW9e:hover{background-color:#1a98d3}.Button_btn__W6oxS.Button_btn-danger__nwxfa.Button_btn-warning__MlDsD,.Button_btn__W6oxS.Button_btn-info__kXW9e.Button_btn-warning__MlDsD,.Button_btn__W6oxS.Button_btn-primary__Y1iy-.Button_btn-warning__MlDsD,.Button_btn__W6oxS.Button_btn-success__DK393.Button_btn-warning__MlDsD,.Button_btn__W6oxS.Button_btn-warning__MlDsD.Button_btn-warning__MlDsD{background-color:#fd9a17;border-color:#c67102}.Button_btn__W6oxS.Button_btn-danger__nwxfa.Button_btn-warning__MlDsD:hover,.Button_btn__W6oxS.Button_btn-info__kXW9e.Button_btn-warning__MlDsD:hover,.Button_btn__W6oxS.Button_btn-primary__Y1iy-.Button_btn-warning__MlDsD:hover,.Button_btn__W6oxS.Button_btn-success__DK393.Button_btn-warning__MlDsD:hover,.Button_btn__W6oxS.Button_btn-warning__MlDsD.Button_btn-warning__MlDsD:hover{background-color:#ad6301}.Button_btn__W6oxS.Button_btn-danger__nwxfa.Button_btn-danger__nwxfa,.Button_btn__W6oxS.Button_btn-info__kXW9e.Button_btn-danger__nwxfa,.Button_btn__W6oxS.Button_btn-primary__Y1iy-.Button_btn-danger__nwxfa,.Button_btn__W6oxS.Button_btn-success__DK393.Button_btn-danger__nwxfa,.Button_btn__W6oxS.Button_btn-warning__MlDsD.Button_btn-danger__nwxfa{background-color:#f15554;border-color:#e61413}.Button_btn__W6oxS.Button_btn-danger__nwxfa.Button_btn-danger__nwxfa:hover,.Button_btn__W6oxS.Button_btn-info__kXW9e.Button_btn-danger__nwxfa:hover,.Button_btn__W6oxS.Button_btn-primary__Y1iy-.Button_btn-danger__nwxfa:hover,.Button_btn__W6oxS.Button_btn-success__DK393.Button_btn-danger__nwxfa:hover,.Button_btn__W6oxS.Button_btn-warning__MlDsD.Button_btn-danger__nwxfa:hover{background-color:#ce1211}.Button_btn__W6oxS.Button_btn-link__nXTLn{background-color:transparent;border-color:transparent;color:var(--link-color)}.Button_btn__W6oxS.Button_btn-block__44OZY{display:block;width:100%}.Button_btn__W6oxS.Button_btn-lg__nTi1W{height:36px}.Button_btn__W6oxS.Button_btn-sm__NGixt{height:28px}.Button_btn__W6oxS.Button_btn-rounded__s5DPa{border-radius:50%!important;font-size:14px;height:35px;padding:0;text-align:center;width:35px}.Button_btn__W6oxS.Button_btn-round__e7AKL{border-radius:30px}.Button_btn__W6oxS.Button_btn-ripple__U47i5{overflow:hidden}.Button_btn__W6oxS.Button_btn-ripple__U47i5:before{background:#fff;border-radius:50%;content:"";height:0;left:0;opacity:.5;position:absolute;top:0;transform:translate(-50%,-50%);transition:width .5s,height .5s;width:0}.Button_btn__W6oxS.Button_btn-ripple__U47i5:hover:before{height:300px;width:300px}.Button_btn__W6oxS.Button_loading__f5mmD svg{animation:Button_spin__cK5ia 1s linear infinite;transform-origin:center}.Button_btn-icon__UqlIV{align-items:center;background:transparent;border:none;border-radius:50%;color:var(--black-white);display:flex;font-size:1.3em;height:35px;justify-content:center;line-height:1;width:35px}.Button_btn-icon__UqlIV .Button_icon__OeKUC{height:auto;width:100%}.Button_btn-icon__UqlIV:hover.Button_btn-default__Cucka{background-color:#fff}.Button_btn-icon__UqlIV:hover.Button_btn-primary__Y1iy-{background-color:#68a0f0}.Button_btn-icon__UqlIV:hover.Button_btn-success__DK393{background-color:#acdca9}.Button_btn-icon__UqlIV:hover.Button_btn-info__kXW9e{background-color:#c2e6f7}.Button_btn-icon__UqlIV:hover.Button_btn-warning__MlDsD{background-color:#fec67c}.Button_btn-icon__UqlIV:hover.Button_btn-danger__nwxfa{background-color:#f9b3b2}.Button_btn-icon__UqlIV.Button_btn-rounded__s5DPa .Button_icon__OeKUC{border-radius:50%}.Button_btn-toolbar__qgbHo{margin-left:-5px}.Button_btn-toolbar__qgbHo>.Button_btn-group__ByOF5,.Button_btn-toolbar__qgbHo>.Button_btn__W6oxS,.Button_btn-toolbar__qgbHo>.Button_input-group__tjkJ3{margin-left:5px}.Button_btn-group-vertical__hbV6F,.Button_btn-group__ByOF5{position:relative}.Button_btn-group-vertical__hbV6F>label,.Button_btn-group__ByOF5>label{margin-bottom:0}.Button_btn-group-vertical__hbV6F>.Button_auto__NAlwq,.Button_btn-group__ByOF5>.Button_auto__NAlwq{flex:1 1 auto;position:relative}.Button_btn-group-vertical__hbV6F>.Button_active__BWfrx,.Button_btn-group__ByOF5>.Button_active__BWfrx{background-color:var(--link-active-color);border-color:var(--link-active-color);color:var(--white-black)}.Button_btn-group-vertical__hbV6F>.Button_active__BWfrx:hover,.Button_btn-group__ByOF5>.Button_active__BWfrx:hover{background-color:var(--link-active-color)}.Button_btn-group__ByOF5{align-items:center;display:flex}.Button_btn-group__ByOF5>.Button_btn__W6oxS:first-child:not(:last-child):not(.Button_dropdown-toggle__H1XIw){border-bottom-right-radius:0;border-top-right-radius:0;margin-left:0}.Button_btn-group__ByOF5>.Button_btn__W6oxS:not(:first-child):not(:last-child):not(.Button_dropdown-toggle__H1XIw){border-radius:0}.Button_btn-group__ByOF5>.Button_btn__W6oxS:last-child:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.Button_btn-group__ByOF5 .Button_btn-group__ByOF5+.Button_btn-group__ByOF5,.Button_btn-group__ByOF5 .Button_btn-group__ByOF5+.Button_btn__W6oxS,.Button_btn-group__ByOF5 .Button_btn__W6oxS+.Button_btn-group__ByOF5,.Button_btn-group__ByOF5 .Button_btn__W6oxS+.Button_btn__W6oxS{margin-left:-1px}.Button_btn-group-vertical__hbV6F{display:inline-flex;flex-direction:column}.Button_btn-group-vertical__hbV6F>.Button_btn__W6oxS{min-width:150px}.Button_btn-group-vertical__hbV6F>.Button_btn__W6oxS:first-child:not(:last-child){border-radius:4px 4px 0 0}.Button_btn-group-vertical__hbV6F>.Button_btn__W6oxS:not(:first-child):not(:last-child){border-radius:0}.Button_btn-group-vertical__hbV6F>.Button_btn__W6oxS:last-child:not(:first-child){border-radius:0 0 4px 4px}.Button_btn-group-vertical__hbV6F .Button_btn-group__ByOF5+.Button_btn-group__ByOF5,.Button_btn-group-vertical__hbV6F .Button_btn-group__ByOF5+.Button_btn__W6oxS,.Button_btn-group-vertical__hbV6F .Button_btn__W6oxS+.Button_btn-group__ByOF5,.Button_btn-group-vertical__hbV6F .Button_btn__W6oxS+.Button_btn__W6oxS{margin-left:0;margin-top:-1px}[data-toggle=buttons]>.Button_btn-group__ByOF5>.Button_btn__W6oxS input[type=checkbox],[data-toggle=buttons]>.Button_btn-group__ByOF5>.Button_btn__W6oxS input[type=radio],[data-toggle=buttons]>.Button_btn__W6oxS input[type=checkbox],[data-toggle=buttons]>.Button_btn__W6oxS input[type=radio]{clip:rect(0,0,0,0);pointer-events:none;position:absolute}input[type=checkbox],input[type=radio]{line-height:normal}@keyframes Button_spin__cK5ia{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.Card_card__9VbVP{background-color:var(--secondary-bg);border:1px solid var(--border-color);border-radius:4px;display:flex;flex-direction:column;position:relative;width:100%}.Card_card__9VbVP .Card_card-header__hfkqU{align-items:center;border-bottom:1px solid var(--border-color);border-radius:4px 4px 0 0;display:flex;justify-content:space-between;min-height:50px;padding:0 20px}.Card_card__9VbVP .Card_card-header__hfkqU .Card_card-header-title__vSeAf{align-items:center;display:flex;font-weight:500;gap:10px;line-height:1}.Card_card__9VbVP .Card_card-header__hfkqU .Card_card-header-title__vSeAf svg.Card_icon__u40Sx{fill:rgba(84,90,109,.2);height:16px;margin-right:0;margin-top:-2px;width:16px}.Card_card__9VbVP .Card_card-header__hfkqU .Card_card-header-title__vSeAf span{font-weight:500}.Card_card__9VbVP .Card_card-header__hfkqU .Card_tools__SLGqz{align-items:center;display:flex;gap:10px;position:relative}.Card_card__9VbVP .Card_card-header__hfkqU .Card_tools__SLGqz .Card_icon__u40Sx{border-radius:50%;cursor:pointer;height:25px;padding:3px;width:25px}.Card_card__9VbVP .Card_card-header__hfkqU .Card_tools__SLGqz .Card_icon__u40Sx:hover{background:var(--hover-bg)}.Card_card__9VbVP .Card_card-header__hfkqU .Card_tools__SLGqz .Card_icon__u40Sx:focus{background:var(--hover-bg);outline:none}.Card_card__9VbVP .Card_card-header__hfkqU.Card_sm__6lW1T{min-height:40px}.Card_card__9VbVP .Card_card-body__tkhoz{height:100%;padding:20px;width:100%}.Card_card__9VbVP .Card_card-footer__-aFRf{align-items:center;border-top:1px solid var(--border-color);display:flex;justify-content:space-between;min-height:50px;padding:5px 20px;position:relative}.Card_card__9VbVP .Card_card-footer__-aFRf button{margin-bottom:0}.Card_card__9VbVP.Card_card-h-left__TFJ5-{flex-direction:row}.Card_card__9VbVP.Card_card-h-left__TFJ5->.Card_card-header__hfkqU{align-items:start;background:var(--hover-bg);padding:0}.Card_card__9VbVP.Card_card-h-right__RzmaC{flex-direction:row-reverse}.Card_card__9VbVP.Card_card-h-right__RzmaC>.Card_card-header__hfkqU{align-items:start;background:var(--hover-bg);padding:0}.Card_modul-child-items__VrKPt{margin-left:20px}.Card_modul-child-items__VrKPt>:before{border-left:1px dashed var(--border-color);content:"";height:100%;left:-20px;position:absolute;top:0;width:1px}.Card_modul-child-items__VrKPt>:after{border-top:1px dashed var(--border-color);content:"";height:1px;left:-20px;position:absolute;top:50%;transform:translateY(-50%);width:20px}@media (max-width:992px){.Card_card__9VbVP .Card_card-footer__-aFRf,.Card_card__9VbVP .Card_card-footer__-aFRf .Card_pagination-toolbar__mpIGN,.Card_card__9VbVP .Card_card-header__hfkqU{flex-direction:column;gap:10px;justify-content:center;padding:15px 20px}.Card_card__9VbVP .Card_card-footer__-aFRf .Card_pagination-toolbar__mpIGN>div,.Card_card__9VbVP .Card_card-footer__-aFRf>div,.Card_card__9VbVP .Card_card-header__hfkqU>div{margin:0!important}.Card_card__9VbVP .Card_card-body__tkhoz{overflow-y:auto}}.spinner_spinner__kDIER{display:inline-block;margin-bottom:5px;margin-right:5px}.spinner_spinner__kDIER .spinner_spinner-icon__QlzMR{animation:spinner_rotator__eQjVe 1.4s linear infinite}@keyframes spinner_rotator__eQjVe{0%{transform:rotate(0deg)}to{transform:rotate(270deg)}}.spinner_spinner__kDIER .spinner_path__G-87M{stroke-dasharray:187;stroke-dashoffset:0;animation:spinner_dash__1HpcO 1.4s ease-in-out infinite,spinner_colors__Cp8ST 5.6s ease-in-out infinite;transform-origin:center}@keyframes spinner_colors__Cp8ST{0%{stroke:#4285f4}25%{stroke:#de3e35}50%{stroke:#f7c223}75%{stroke:#1b9a59}to{stroke:#4285f4}}@keyframes spinner_dash__1HpcO{0%{stroke-dashoffset:187}50%{stroke-dashoffset:46.75;transform:rotate(135deg)}to{stroke-dashoffset:187;transform:rotate(450deg)}}.DropdownMenu_dropdown-menu__3VCoD{background-clip:padding-box;background:var(--secondary-bg);border:1px solid var(--border-color);border-radius:3px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.18);box-shadow:0 6px 12px rgba(0,0,0,.18);min-width:160px;z-index:1001}.DropdownMenu_dropdown-menu-item__0cGSf{cursor:pointer;padding:8px 16px}.DropdownMenu_dropdown-menu-item__0cGSf:last-child{border-bottom:none}.DropdownMenu_dropdown-menu-item__0cGSf:hover{background:var(--hover-bg)}.DropdownMenu_dropdown-menu-item__0cGSf .DropdownMenu_icon__s1oRM,.DropdownMenu_dropdown-menu-item__0cGSf svg{fill:rgba(84,90,109,.2);height:16px;margin-right:10px;margin-top:-2px;width:16px}.Dropdown_dropdown__pt4zU{display:inline-block;position:relative}.Dropdown_dropdown__pt4zU .Dropdown_dropdown-toggle__CCe-U{cursor:pointer;user-select:none}.Dropdown_dropdown__pt4zU .Dropdown_dropdown-toggle__CCe-U svg.Dropdown_icon__aIftF{fill:rgba(84,90,109,.2);height:16px;width:16px}.Dropdown_dropdown-content__qnIAG{background-clip:padding-box;background:var(--secondary-bg);border:1px solid var(--border-color);border-radius:3px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.18);box-shadow:0 6px 12px rgba(0,0,0,.18);min-width:160px;z-index:1001}.Dropdown_dropdown-content__qnIAG.Dropdown_bottom-left__cuUsU,.Dropdown_dropdown-content__qnIAG.Dropdown_bottom-right__HpnxP{margin-top:4px}.Dropdown_dropdown-content__qnIAG.Dropdown_top-left__DHElR,.Dropdown_dropdown-content__qnIAG.Dropdown_top-right__wp9Jq{margin-bottom:4px}@media (max-width:768px){.Dropdown_dropdown-content__qnIAG{left:50%!important;max-width:320px;min-width:calc(100% - 32px);position:fixed!important;transform:translateX(-50%)}.Dropdown_dropdown-content__qnIAG.Dropdown_bottom-left__cuUsU,.Dropdown_dropdown-content__qnIAG.Dropdown_bottom-right__HpnxP,.Dropdown_dropdown-content__qnIAG.Dropdown_top-left__DHElR,.Dropdown_dropdown-content__qnIAG.Dropdown_top-right__wp9Jq{top:50%!important;transform:translate(-50%,-50%)}}.Badge_badge__V11MP{border-radius:3px;display:inline-block;font-size:12px;font-weight:500;line-height:1;padding:5px 10px;text-align:center;vertical-align:baseline;white-space:nowrap}.Badge_badge__V11MP.Badge_badge-primary__kbIbZ{background-color:#96bdf5;color:#082651}.Badge_badge__V11MP.Badge_badge-success__p3xRL{background-color:#cfebcd;color:#2a6026}.Badge_badge__V11MP.Badge_badge-info__rrciq{background-color:#d8effa;color:#1578a5}.Badge_badge__V11MP.Badge_badge-warning__D7uFZ{background-color:#fedcaf;color:#7a4601}.Badge_badge__V11MP.Badge_badge-danger__3j-yd{background-color:#fde2e1;color:#9f0e0d}.Badge_badge__V11MP.Badge_badge-light__eXhHT{background-color:#f1f1f1;color:#000}.Badge_badge__V11MP.Badge_badge-dark__ILThB{background-color:#4d4d4d;color:#b3b3b3}.Badge_badge__V11MP.Badge_rounded-pill__9bkwJ{border-radius:30px}.Badge_badge__V11MP.Badge_badge-notif__SH-r9{border-radius:50px;font-size:10px;font-weight:600;padding:5px;pointer-events:none;position:absolute;right:-10px;top:-10px}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Badge } from "./Badge";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Button } from "./Button";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import "./Card.scss";
|
|
3
|
+
interface CardHeaderProps {
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
className?: string;
|
|
6
|
+
}
|
|
7
|
+
declare const CardHeader: React.FC<CardHeaderProps>;
|
|
8
|
+
interface CardBodyProps {
|
|
9
|
+
children: React.ReactNode;
|
|
10
|
+
className?: string;
|
|
11
|
+
onDrop?: (e: React.DragEvent<HTMLDivElement>) => void;
|
|
12
|
+
onDragOver?: (e: React.DragEvent<HTMLDivElement>) => void;
|
|
13
|
+
style?: React.CSSProperties;
|
|
14
|
+
}
|
|
15
|
+
declare const CardBody: React.FC<CardBodyProps>;
|
|
16
|
+
interface CardFooterProps {
|
|
17
|
+
children: React.ReactNode;
|
|
18
|
+
className?: string;
|
|
19
|
+
}
|
|
20
|
+
declare const CardFooter: React.FC<CardFooterProps>;
|
|
21
|
+
interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
22
|
+
children: React.ReactNode;
|
|
23
|
+
className?: string;
|
|
24
|
+
}
|
|
25
|
+
declare const Card: React.FC<CardProps>;
|
|
26
|
+
export { Card, CardHeader, CardBody, CardFooter };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Card, CardHeader, CardBody, CardFooter } from "./Card";
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
import './Dropdown.scss';
|
|
3
|
+
interface DropdownProps {
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
className?: string;
|
|
6
|
+
position?: 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right';
|
|
7
|
+
}
|
|
8
|
+
interface DropdownToggleProps {
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
className?: string;
|
|
11
|
+
toggleDropdown?: () => void;
|
|
12
|
+
dropdownId?: string;
|
|
13
|
+
}
|
|
14
|
+
interface DropdownContentProps {
|
|
15
|
+
children: ReactNode;
|
|
16
|
+
className?: string;
|
|
17
|
+
isOpen?: boolean;
|
|
18
|
+
position?: 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right';
|
|
19
|
+
contentRef?: React.RefObject<HTMLDivElement>;
|
|
20
|
+
dropdownId?: string;
|
|
21
|
+
}
|
|
22
|
+
declare const Dropdown: React.FC<DropdownProps>;
|
|
23
|
+
declare const DropdownToggle: React.FC<DropdownToggleProps>;
|
|
24
|
+
declare const DropdownContent: React.FC<DropdownContentProps>;
|
|
25
|
+
export { Dropdown, DropdownToggle, DropdownContent };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
import './DropdownMenu.scss';
|
|
3
|
+
interface DropdownMenuItem {
|
|
4
|
+
icon?: ReactNode;
|
|
5
|
+
label: string;
|
|
6
|
+
className?: string;
|
|
7
|
+
onClick: () => void;
|
|
8
|
+
}
|
|
9
|
+
interface DropdownMenuProps {
|
|
10
|
+
children: ReactNode;
|
|
11
|
+
items: DropdownMenuItem[];
|
|
12
|
+
position?: 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right';
|
|
13
|
+
className?: string;
|
|
14
|
+
}
|
|
15
|
+
declare const DropdownMenu: React.FC<DropdownMenuProps>;
|
|
16
|
+
export { DropdownMenu };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Spinner } from "./Spinner";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Hook untuk mendeteksi klik di luar elemen yang diberikan
|
|
4
|
+
* @param refs Array of refs dari elemen yang akan dimonitor
|
|
5
|
+
* @param handler Fungsi yang akan dipanggil ketika klik terjadi di luar elemen
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* const ref = useRef<HTMLDivElement>(null);
|
|
9
|
+
* useOutsideClick([ref], () => {});
|
|
10
|
+
*/
|
|
11
|
+
declare const useOutsideClick: (refs: RefObject<HTMLElement>[], handler: () => void) => void;
|
|
12
|
+
export default useOutsideClick;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './components';
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "module",
|
|
3
|
+
"name": "pesona-ui",
|
|
4
|
+
"version": "1.0.1",
|
|
5
|
+
"description": "PesonaUI - A reusable React component library built with TypeScript and SCSS",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"react",
|
|
8
|
+
"ui",
|
|
9
|
+
"component-library",
|
|
10
|
+
"typescript",
|
|
11
|
+
"scss"
|
|
12
|
+
],
|
|
13
|
+
"author": "MASRIADI",
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"main": "dist/index.cjs.js",
|
|
16
|
+
"module": "dist/index.esm.js",
|
|
17
|
+
"types": "dist/types/index.d.ts",
|
|
18
|
+
"files": [
|
|
19
|
+
"dist"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "rollup -c",
|
|
23
|
+
"start-demo": "vite demo",
|
|
24
|
+
"prepublishOnly": "yarn build"
|
|
25
|
+
},
|
|
26
|
+
"peerDependencies": {
|
|
27
|
+
"react": "^18.0.0",
|
|
28
|
+
"react-dom": "^18.0.0"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@eslint/js": "^9.17.0",
|
|
32
|
+
"@rollup/plugin-commonjs": "^28.0.2",
|
|
33
|
+
"@rollup/plugin-node-resolve": "^16.0.0",
|
|
34
|
+
"@types/node": "^22.12.0",
|
|
35
|
+
"@types/react": "^18.3.18",
|
|
36
|
+
"@types/react-dom": "^18.3.5",
|
|
37
|
+
"@vitejs/plugin-react": "^4.3.4",
|
|
38
|
+
"eslint": "^9.17.0",
|
|
39
|
+
"eslint-plugin-react-hooks": "^5.0.0",
|
|
40
|
+
"eslint-plugin-react-refresh": "^0.4.16",
|
|
41
|
+
"globals": "^15.14.0",
|
|
42
|
+
"postcss": "^8.4.49",
|
|
43
|
+
"rollup": "^4.29.1",
|
|
44
|
+
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
45
|
+
"rollup-plugin-postcss": "^4.0.2",
|
|
46
|
+
"rollup-plugin-scss": "^4.0.1",
|
|
47
|
+
"rollup-plugin-typescript2": "^0.36.0",
|
|
48
|
+
"sass": "^1.83.0",
|
|
49
|
+
"typescript": "~5.6.2",
|
|
50
|
+
"typescript-eslint": "^8.18.2",
|
|
51
|
+
"vite": "^6.0.5"
|
|
52
|
+
},
|
|
53
|
+
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e",
|
|
54
|
+
"dependencies": {
|
|
55
|
+
"rollup-plugin-sass": "^1.14.0"
|
|
56
|
+
}
|
|
57
|
+
}
|