funuicss 2.7.9 → 2.7.11
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/css/fun.css +238 -25
- package/index.d.ts +1 -0
- package/index.js +3 -1
- package/index.tsx +2 -1
- package/package.json +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/ui/ScrollInView/ScrollInView.js +1 -1
- package/ui/ScrollInView/ScrollInView.tsx +1 -1
- package/ui/accordion/Accordion.d.ts +16 -2
- package/ui/accordion/Accordion.js +8 -8
- package/ui/accordion/Accordion.tsx +24 -17
- package/ui/avatar/Avatar.js +5 -4
- package/ui/avatar/Avatar.tsx +3 -1
- package/ui/button/Button.d.ts +1 -1
- package/ui/button/Button.js +1 -1
- package/ui/button/Button.tsx +3 -2
- package/ui/calendar/ActivityCard.d.ts +8 -0
- package/ui/calendar/ActivityCard.js +18 -0
- package/ui/calendar/ActivityCard.tsx +27 -0
- package/ui/calendar/Calendar.d.ts +5 -2
- package/ui/calendar/Calendar.js +119 -84
- package/ui/calendar/Calendar.tsx +211 -161
- package/ui/datepicker/DatePicker.js +4 -3
- package/ui/datepicker/DatePicker.tsx +8 -3
- package/ui/drop/Dropdown.js +17 -17
- package/ui/drop/Dropdown.tsx +31 -29
- package/ui/vista/Vista.d.ts +28 -0
- package/ui/vista/Vista.js +66 -0
- package/ui/vista/Vista.tsx +145 -0
|
@@ -46,7 +46,7 @@ var animationVariants = {
|
|
|
46
46
|
'slide-right': { hidden: { x: -20, opacity: 0 }, visible: { x: 0, opacity: 1 } },
|
|
47
47
|
};
|
|
48
48
|
var ScrollInView = function (_a) {
|
|
49
|
-
var children = _a.children, _b = _a.animationType, animationType = _b === void 0 ? 'fade-up' : _b, _c = _a.delay, delay = _c === void 0 ? 0 : _c, _d = _a.duration, duration = _d === void 0 ? 0.6 : _d, _e = _a.threshold, threshold = _e === void 0 ? 0.2 : _e, _f = _a.once, once = _f === void 0 ?
|
|
49
|
+
var children = _a.children, _b = _a.animationType, animationType = _b === void 0 ? 'fade-up' : _b, _c = _a.delay, delay = _c === void 0 ? 0 : _c, _d = _a.duration, duration = _d === void 0 ? 0.6 : _d, _e = _a.threshold, threshold = _e === void 0 ? 0.2 : _e, _f = _a.once, once = _f === void 0 ? true : _f, _g = _a.className, className = _g === void 0 ? '' : _g;
|
|
50
50
|
var controls = (0, framer_motion_1.useAnimation)();
|
|
51
51
|
var _h = (0, react_intersection_observer_1.useInView)({
|
|
52
52
|
threshold: threshold,
|
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
|
|
2
|
+
export type AccordionItemProps = {
|
|
3
|
+
title: string;
|
|
4
|
+
content: React.ReactNode;
|
|
5
|
+
isOpen?: boolean;
|
|
6
|
+
onToggle?: () => void;
|
|
7
|
+
index?: number;
|
|
8
|
+
icon?: React.ReactNode;
|
|
9
|
+
itemClass?: string;
|
|
10
|
+
titleClass?: string;
|
|
11
|
+
iconClass?: string;
|
|
12
|
+
contentClass?: string;
|
|
13
|
+
activeClass?: string;
|
|
14
|
+
};
|
|
15
|
+
export declare const AccordionItem: React.FC<AccordionItemProps>;
|
|
16
|
+
export type AccordionProps = {
|
|
3
17
|
items: {
|
|
4
18
|
title: string;
|
|
5
19
|
content: React.ReactNode;
|
|
@@ -12,6 +26,6 @@ interface AccordionProps {
|
|
|
12
26
|
iconClass?: string;
|
|
13
27
|
contentClass?: string;
|
|
14
28
|
activeClass?: string;
|
|
15
|
-
}
|
|
29
|
+
};
|
|
16
30
|
declare const Accordion: React.FC<AccordionProps>;
|
|
17
31
|
export default Accordion;
|
|
@@ -46,26 +46,26 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
46
46
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
47
47
|
};
|
|
48
48
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
|
+
exports.AccordionItem = void 0;
|
|
49
50
|
var react_1 = __importStar(require("react"));
|
|
50
51
|
var pi_1 = require("react-icons/pi");
|
|
51
52
|
var RowFlex_1 = __importDefault(require("../specials/RowFlex"));
|
|
52
53
|
var AccordionItem = function (_a) {
|
|
53
54
|
var icon = _a.icon, title = _a.title, content = _a.content, isOpen = _a.isOpen, onToggle = _a.onToggle, _b = _a.itemClass, itemClass = _b === void 0 ? '' : _b, _c = _a.titleClass, titleClass = _c === void 0 ? '' : _c, _d = _a.iconClass, iconClass = _d === void 0 ? '' : _d, _e = _a.contentClass, contentClass = _e === void 0 ? '' : _e, _f = _a.activeClass, activeClass = _f === void 0 ? '' : _f;
|
|
54
55
|
return (react_1.default.createElement("div", { className: "accordion-item ".concat(itemClass, " ").concat(isOpen ? activeClass : '') },
|
|
55
|
-
react_1.default.createElement("div", { className: "accordion-header ".concat(titleClass), onClick: onToggle },
|
|
56
|
-
react_1.default.createElement(RowFlex_1.default, { alignItems:
|
|
56
|
+
react_1.default.createElement("div", { className: "accordion-header ".concat(titleClass), onClick: onToggle, role: "button", "aria-expanded": isOpen },
|
|
57
|
+
react_1.default.createElement(RowFlex_1.default, { alignItems: "center", gap: 0.6 },
|
|
57
58
|
icon && react_1.default.createElement("div", { style: { lineHeight: 0 } }, icon),
|
|
58
|
-
react_1.default.createElement("div", { className:
|
|
59
|
-
react_1.default.createElement("div", { style: { lineHeight: 0 }, className: "".concat(iconClass, " ").concat(isOpen ?
|
|
59
|
+
react_1.default.createElement("div", { className: "col fit" }, title)),
|
|
60
|
+
react_1.default.createElement("div", { style: { lineHeight: 0 }, className: "".concat(iconClass, " ").concat(isOpen ? 'accordion-rotated' : '') },
|
|
60
61
|
react_1.default.createElement(pi_1.PiCaretDown, null))),
|
|
61
62
|
react_1.default.createElement("div", { className: "accordion-content ".concat(contentClass, " ").concat(isOpen ? 'open' : '') },
|
|
62
63
|
react_1.default.createElement("div", { className: "accordion-inner" }, content))));
|
|
63
64
|
};
|
|
65
|
+
exports.AccordionItem = AccordionItem;
|
|
64
66
|
var Accordion = function (_a) {
|
|
65
67
|
var _b;
|
|
66
|
-
var items = _a.items, _c = _a.allowMultiple, allowMultiple = _c === void 0 ? false : _c,
|
|
67
|
-
_d = _a.defaultOpenIndexes, // ❗ default is only one open
|
|
68
|
-
defaultOpenIndexes = _d === void 0 ? [] : _d, itemClass = _a.itemClass, titleClass = _a.titleClass, iconClass = _a.iconClass, contentClass = _a.contentClass, activeClass = _a.activeClass;
|
|
68
|
+
var items = _a.items, _c = _a.allowMultiple, allowMultiple = _c === void 0 ? false : _c, _d = _a.defaultOpenIndexes, defaultOpenIndexes = _d === void 0 ? [] : _d, itemClass = _a.itemClass, titleClass = _a.titleClass, iconClass = _a.iconClass, contentClass = _a.contentClass, activeClass = _a.activeClass;
|
|
69
69
|
var _e = (0, react_1.useState)(allowMultiple ? defaultOpenIndexes : [(_b = defaultOpenIndexes[0]) !== null && _b !== void 0 ? _b : -1]), openIndexes = _e[0], setOpenIndexes = _e[1];
|
|
70
70
|
var toggleIndex = function (index) {
|
|
71
71
|
if (allowMultiple) {
|
|
@@ -80,6 +80,6 @@ var Accordion = function (_a) {
|
|
|
80
80
|
setOpenIndexes(openIndexes.includes(index) ? [] : [index]);
|
|
81
81
|
}
|
|
82
82
|
};
|
|
83
|
-
return (react_1.default.createElement("div", { className: "accordion" }, items.map(function (item, index) { return (react_1.default.createElement(AccordionItem, { key: index, index: index, icon: item.icon, title: item.title, content: item.content, isOpen: openIndexes.includes(index), onToggle: function () { return toggleIndex(index); }, itemClass: itemClass, titleClass: titleClass, iconClass: iconClass, contentClass: contentClass, activeClass: activeClass })); })));
|
|
83
|
+
return (react_1.default.createElement("div", { className: "accordion" }, items.map(function (item, index) { return (react_1.default.createElement(exports.AccordionItem, { key: index, index: index, icon: item.icon, title: item.title, content: item.content, isOpen: openIndexes.includes(index), onToggle: function () { return toggleIndex(index); }, itemClass: itemClass, titleClass: titleClass, iconClass: iconClass, contentClass: contentClass, activeClass: activeClass })); })));
|
|
84
84
|
};
|
|
85
85
|
exports.default = Accordion;
|
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import React, { useState } from 'react';
|
|
3
|
-
import { PiCaretDown
|
|
3
|
+
import { PiCaretDown } from 'react-icons/pi';
|
|
4
4
|
import RowFlex from '../specials/RowFlex';
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
export type AccordionItemProps = {
|
|
7
7
|
title: string;
|
|
8
8
|
content: React.ReactNode;
|
|
9
9
|
isOpen?: boolean;
|
|
10
10
|
onToggle?: () => void;
|
|
11
11
|
index?: number;
|
|
12
12
|
icon?: React.ReactNode;
|
|
13
|
+
|
|
13
14
|
// Customization
|
|
14
15
|
itemClass?: string;
|
|
15
16
|
titleClass?: string;
|
|
16
17
|
iconClass?: string;
|
|
17
18
|
contentClass?: string;
|
|
18
19
|
activeClass?: string;
|
|
19
|
-
}
|
|
20
|
+
};
|
|
20
21
|
|
|
21
|
-
const AccordionItem: React.FC<AccordionItemProps> = ({
|
|
22
|
+
export const AccordionItem: React.FC<AccordionItemProps> = ({
|
|
22
23
|
icon,
|
|
23
24
|
title,
|
|
24
25
|
content,
|
|
@@ -32,14 +33,20 @@ const AccordionItem: React.FC<AccordionItemProps> = ({
|
|
|
32
33
|
}) => {
|
|
33
34
|
return (
|
|
34
35
|
<div className={`accordion-item ${itemClass} ${isOpen ? activeClass : ''}`}>
|
|
35
|
-
<div
|
|
36
|
-
|
|
37
|
-
{
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
36
|
+
<div
|
|
37
|
+
className={`accordion-header ${titleClass}`}
|
|
38
|
+
onClick={onToggle}
|
|
39
|
+
role="button"
|
|
40
|
+
aria-expanded={isOpen}
|
|
41
|
+
>
|
|
42
|
+
<RowFlex alignItems="center" gap={0.6}>
|
|
43
|
+
{icon && <div style={{ lineHeight: 0 }}>{icon}</div>}
|
|
44
|
+
<div className="col fit">{title}</div>
|
|
45
|
+
</RowFlex>
|
|
46
|
+
<div
|
|
47
|
+
style={{ lineHeight: 0 }}
|
|
48
|
+
className={`${iconClass} ${isOpen ? 'accordion-rotated' : ''}`}
|
|
49
|
+
>
|
|
43
50
|
<PiCaretDown />
|
|
44
51
|
</div>
|
|
45
52
|
</div>
|
|
@@ -50,14 +57,14 @@ const AccordionItem: React.FC<AccordionItemProps> = ({
|
|
|
50
57
|
);
|
|
51
58
|
};
|
|
52
59
|
|
|
53
|
-
|
|
60
|
+
export type AccordionProps = {
|
|
54
61
|
items: {
|
|
55
62
|
title: string;
|
|
56
63
|
content: React.ReactNode;
|
|
57
64
|
icon?: React.ReactNode;
|
|
58
65
|
}[];
|
|
59
|
-
allowMultiple?: boolean;
|
|
60
|
-
defaultOpenIndexes?: number[];
|
|
66
|
+
allowMultiple?: boolean;
|
|
67
|
+
defaultOpenIndexes?: number[];
|
|
61
68
|
|
|
62
69
|
// Custom styles
|
|
63
70
|
itemClass?: string;
|
|
@@ -65,11 +72,11 @@ interface AccordionProps {
|
|
|
65
72
|
iconClass?: string;
|
|
66
73
|
contentClass?: string;
|
|
67
74
|
activeClass?: string;
|
|
68
|
-
}
|
|
75
|
+
};
|
|
69
76
|
|
|
70
77
|
const Accordion: React.FC<AccordionProps> = ({
|
|
71
78
|
items,
|
|
72
|
-
allowMultiple = false,
|
|
79
|
+
allowMultiple = false,
|
|
73
80
|
defaultOpenIndexes = [],
|
|
74
81
|
itemClass,
|
|
75
82
|
titleClass,
|
package/ui/avatar/Avatar.js
CHANGED
|
@@ -60,8 +60,9 @@ exports.default = Avatar;
|
|
|
60
60
|
var React = __importStar(require("react"));
|
|
61
61
|
function Avatar(_a) {
|
|
62
62
|
var funcss = _a.funcss, children = _a.children, _b = _a.size, size = _b === void 0 ? 2 : _b, _c = _a.bordered, bordered = _c === void 0 ? true : _c, bg = _a.bg, content = _a.content, color = _a.color, onClick = _a.onClick, rest = __rest(_a, ["funcss", "children", "size", "bordered", "bg", "content", "color", "onClick"]);
|
|
63
|
-
return (React.createElement("div",
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
return (React.createElement("div", null,
|
|
64
|
+
React.createElement("div", __assign({ className: "\n animated \n pointer\n fade-in \n avatar \n ".concat(funcss || '', " \n ").concat(bg || 'lighter', " \n ").concat(bordered ? 'border' : '', "\n ").concat(color ? "text-".concat(color) : '', "\n "), style: {
|
|
65
|
+
width: "".concat(size, "rem"),
|
|
66
|
+
height: "".concat(size, "rem"),
|
|
67
|
+
}, onClick: onClick }, rest), content || children)));
|
|
67
68
|
}
|
package/ui/avatar/Avatar.tsx
CHANGED
|
@@ -26,7 +26,8 @@ export default function Avatar({
|
|
|
26
26
|
...rest
|
|
27
27
|
}: AvatarProps) {
|
|
28
28
|
return (
|
|
29
|
-
|
|
29
|
+
<div>
|
|
30
|
+
<div
|
|
30
31
|
className={`
|
|
31
32
|
animated
|
|
32
33
|
pointer
|
|
@@ -46,5 +47,6 @@ export default function Avatar({
|
|
|
46
47
|
>
|
|
47
48
|
{content || children}
|
|
48
49
|
</div>
|
|
50
|
+
</div>
|
|
49
51
|
);
|
|
50
52
|
}
|
package/ui/button/Button.d.ts
CHANGED
|
@@ -33,7 +33,7 @@ interface ButtonProps {
|
|
|
33
33
|
status?: 'success' | 'warning' | 'info' | 'danger';
|
|
34
34
|
children?: React.ReactNode;
|
|
35
35
|
style?: React.CSSProperties;
|
|
36
|
-
onClick?: () => void;
|
|
36
|
+
onClick?: (...args: unknown[]) => void;
|
|
37
37
|
}
|
|
38
38
|
export default function Button({ color, bg, funcss, startIcon, endIcon, text, rounded, raised, height, width, float, hoverUp, fullWidth, outlined, small, hoverless, smaller, big, bigger, jumbo, flat, hoverNone, fillAnimation, fillDirection, fillTextColor, outlineSize, isLoading, status, children, bold, style, onClick, ...rest }: ButtonProps): React.JSX.Element;
|
|
39
39
|
export {};
|
package/ui/button/Button.js
CHANGED
|
@@ -75,7 +75,7 @@ function Button(_a) {
|
|
|
75
75
|
}
|
|
76
76
|
var classNames = [
|
|
77
77
|
'button',
|
|
78
|
-
"text-".concat(bg ? color ? color : !hasNumber(bg) && !outlined ? "white" : hasNumberAbove(bg) && !outlined ? "white" : removeNumbers(bg) :
|
|
78
|
+
"text-".concat(bg ? color ? color : !hasNumber(bg) && !outlined ? "white" : hasNumberAbove(bg) && !outlined ? "white" : removeNumbers(bg) : color),
|
|
79
79
|
funcss || '',
|
|
80
80
|
rounded ? 'roundBtn' : '',
|
|
81
81
|
hoverless ? 'hoverless' : '',
|
package/ui/button/Button.tsx
CHANGED
|
@@ -37,7 +37,8 @@ interface ButtonProps {
|
|
|
37
37
|
status?: 'success' | 'warning' | 'info' | 'danger'
|
|
38
38
|
children?:React.ReactNode,
|
|
39
39
|
style?:React.CSSProperties ,
|
|
40
|
-
onClick?: () => void
|
|
40
|
+
onClick?: (...args: unknown[]) => void;
|
|
41
|
+
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
export default function Button({
|
|
@@ -91,7 +92,7 @@ function hasNumber(text:any) {
|
|
|
91
92
|
|
|
92
93
|
const classNames = [
|
|
93
94
|
'button',
|
|
94
|
-
`text-${bg ? color ? color : !hasNumber(bg) && !outlined ? "white" : hasNumberAbove(bg) && !outlined ? "white" : removeNumbers(bg) :
|
|
95
|
+
`text-${bg ? color ? color : !hasNumber(bg) && !outlined ? "white" : hasNumberAbove(bg) && !outlined ? "white" : removeNumbers(bg) : color}`,
|
|
95
96
|
funcss || '',
|
|
96
97
|
rounded ? 'roundBtn' : '',
|
|
97
98
|
hoverless ? 'hoverless' : '',
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
var react_1 = __importDefault(require("react"));
|
|
8
|
+
var Text_1 = __importDefault(require("../text/Text"));
|
|
9
|
+
var ActivityCard = function (_a) {
|
|
10
|
+
var activity = _a.activity, onClick = _a.onClick;
|
|
11
|
+
return (react_1.default.createElement("div", { className: "activity-tag animated slide-up ".concat(activity.funcss || ''), style: { backgroundColor: activity.color || '' }, onClick: function (e) {
|
|
12
|
+
e.stopPropagation();
|
|
13
|
+
onClick === null || onClick === void 0 ? void 0 : onClick(activity);
|
|
14
|
+
} },
|
|
15
|
+
react_1.default.createElement(Text_1.default, { text: activity.title, size: "xs", block: true, truncate: 2 }),
|
|
16
|
+
activity.footer && react_1.default.createElement("div", null, activity.footer)));
|
|
17
|
+
};
|
|
18
|
+
exports.default = ActivityCard;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Activity } from './Calendar';
|
|
4
|
+
import Text from '../text/Text';
|
|
5
|
+
|
|
6
|
+
type ActivityCardProps = {
|
|
7
|
+
activity: Activity;
|
|
8
|
+
onClick?: (activity: Activity) => void;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const ActivityCard: React.FC<ActivityCardProps> = ({ activity, onClick }) => {
|
|
12
|
+
return (
|
|
13
|
+
<div
|
|
14
|
+
className={`activity-tag animated slide-up ${activity.funcss || ''}`}
|
|
15
|
+
style={{ backgroundColor: activity.color || '' }}
|
|
16
|
+
onClick={(e) => {
|
|
17
|
+
e.stopPropagation();
|
|
18
|
+
onClick?.(activity);
|
|
19
|
+
}}
|
|
20
|
+
>
|
|
21
|
+
<Text text={activity.title} size="xs" block truncate={2} />
|
|
22
|
+
{activity.footer && <div>{activity.footer}</div>}
|
|
23
|
+
</div>
|
|
24
|
+
);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export default ActivityCard;
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
|
|
2
|
+
export type Activity = {
|
|
3
3
|
id: string;
|
|
4
4
|
title: string;
|
|
5
5
|
date: Date;
|
|
6
6
|
color?: string;
|
|
7
|
-
|
|
7
|
+
funcss?: string;
|
|
8
|
+
data?: any;
|
|
9
|
+
footer?: React.ReactNode;
|
|
10
|
+
};
|
|
8
11
|
interface CalendarProps {
|
|
9
12
|
activities: Activity[];
|
|
10
13
|
onAdd?: (date: Date) => void;
|
package/ui/calendar/Calendar.js
CHANGED
|
@@ -48,6 +48,10 @@ var RowFlex_1 = __importDefault(require("../specials/RowFlex"));
|
|
|
48
48
|
var Input_1 = __importDefault(require("../input/Input"));
|
|
49
49
|
var Button_1 = __importDefault(require("../button/Button"));
|
|
50
50
|
var Text_1 = __importDefault(require("../text/Text"));
|
|
51
|
+
var ActivityCard_1 = __importDefault(require("./ActivityCard"));
|
|
52
|
+
var View_1 = __importDefault(require("../view/View"));
|
|
53
|
+
var Dropdown_1 = __importDefault(require("../drop/Dropdown"));
|
|
54
|
+
var hi_1 = require("react-icons/hi");
|
|
51
55
|
dayjs_1.default.extend(isSameOrAfter_1.default);
|
|
52
56
|
dayjs_1.default.extend(isSameOrBefore_1.default);
|
|
53
57
|
var Calendar = function (_a) {
|
|
@@ -55,50 +59,64 @@ var Calendar = function (_a) {
|
|
|
55
59
|
var _e = (0, react_1.useState)((0, dayjs_1.default)()), currentMonth = _e[0], setCurrentMonth = _e[1];
|
|
56
60
|
var _f = (0, react_1.useState)(null), hoveredDate = _f[0], setHoveredDate = _f[1];
|
|
57
61
|
var _g = (0, react_1.useState)(null), selectedDate = _g[0], setSelectedDate = _g[1];
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
var firstDay = startOfMonth.day();
|
|
64
|
-
var daysBefore = (firstDay - weekStart + 7) % 7;
|
|
65
|
-
var daysInMonth = currentMonth.daysInMonth();
|
|
66
|
-
var totalDays = Math.ceil((daysBefore + daysInMonth) / 7) * 7;
|
|
62
|
+
var _h = (0, react_1.useState)(false), showMoreActivities = _h[0], setShowMoreActivities = _h[1];
|
|
63
|
+
// ✅ NEW: View mode state
|
|
64
|
+
var _j = (0, react_1.useState)('month'), viewMode = _j[0], setViewMode = _j[1];
|
|
65
|
+
var startOfWeek = currentMonth.startOf('week').add(weekStart, 'day');
|
|
66
|
+
var _k = (0, react_1.useMemo)(function () {
|
|
67
67
|
var days = [];
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
var
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
68
|
+
if (viewMode === 'month') {
|
|
69
|
+
var startOfMonth = currentMonth.startOf('month');
|
|
70
|
+
var endOfMonth = currentMonth.endOf('month');
|
|
71
|
+
var firstDay = startOfMonth.day();
|
|
72
|
+
var daysBefore = (firstDay - weekStart + 7) % 7;
|
|
73
|
+
var daysInMonth = currentMonth.daysInMonth();
|
|
74
|
+
var totalDays = Math.ceil((daysBefore + daysInMonth) / 7) * 7;
|
|
75
|
+
for (var i = daysBefore - 1; i >= 0; i--) {
|
|
76
|
+
var date = startOfMonth.subtract(i + 1, 'day');
|
|
77
|
+
days.push(showAdjacentMonths ? date : null);
|
|
78
|
+
}
|
|
79
|
+
for (var i = 0; i < daysInMonth; i++) {
|
|
80
|
+
days.push(startOfMonth.add(i, 'day'));
|
|
81
|
+
}
|
|
82
|
+
var remaining = totalDays - days.length;
|
|
83
|
+
for (var i = 0; i < remaining; i++) {
|
|
84
|
+
var date = endOfMonth.add(i + 1, 'day');
|
|
85
|
+
days.push(showAdjacentMonths ? date : null);
|
|
86
|
+
}
|
|
76
87
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
88
|
+
else {
|
|
89
|
+
// ✅ Week View: only 7 days
|
|
90
|
+
for (var i = 0; i < 7; i++) {
|
|
91
|
+
days.push(startOfWeek.add(i, 'day'));
|
|
92
|
+
}
|
|
82
93
|
}
|
|
83
|
-
// Group activities by date
|
|
84
94
|
var monthActivities = {};
|
|
85
95
|
activities.forEach(function (activity) {
|
|
86
96
|
var date = (0, dayjs_1.default)(activity.date);
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
97
|
+
var key = date.format('YYYY-MM-DD');
|
|
98
|
+
if (viewMode === 'month' &&
|
|
99
|
+
(date.isSame(currentMonth, 'month') || (showAdjacentMonths &&
|
|
100
|
+
(date.isBefore(currentMonth.endOf('month')) && date.isAfter(currentMonth.startOf('month')))))) {
|
|
101
|
+
if (!monthActivities[key])
|
|
102
|
+
monthActivities[key] = [];
|
|
103
|
+
monthActivities[key].push(activity);
|
|
104
|
+
}
|
|
105
|
+
if (viewMode === 'week' && date.isSame(startOfWeek, 'week')) {
|
|
90
106
|
if (!monthActivities[key])
|
|
91
107
|
monthActivities[key] = [];
|
|
92
108
|
monthActivities[key].push(activity);
|
|
93
109
|
}
|
|
94
110
|
});
|
|
95
111
|
return { days: days, monthActivities: monthActivities };
|
|
96
|
-
}, [currentMonth, activities, weekStart, showAdjacentMonths]), days =
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
112
|
+
}, [currentMonth, activities, viewMode, weekStart, showAdjacentMonths]), days = _k.days, monthActivities = _k.monthActivities;
|
|
113
|
+
var prevPeriod = function () {
|
|
114
|
+
return setCurrentMonth(currentMonth.subtract(1, viewMode === 'month' ? 'month' : 'week'));
|
|
115
|
+
};
|
|
116
|
+
var nextPeriod = function () {
|
|
117
|
+
return setCurrentMonth(currentMonth.add(1, viewMode === 'month' ? 'month' : 'week'));
|
|
118
|
+
};
|
|
100
119
|
var goToToday = function () { return setCurrentMonth((0, dayjs_1.default)()); };
|
|
101
|
-
// Date handlers
|
|
102
120
|
var handleDateClick = function (date) {
|
|
103
121
|
if (isDateDisabled(date))
|
|
104
122
|
return;
|
|
@@ -111,15 +129,12 @@ var Calendar = function (_a) {
|
|
|
111
129
|
return;
|
|
112
130
|
onAdd === null || onAdd === void 0 ? void 0 : onAdd(date.toDate());
|
|
113
131
|
};
|
|
114
|
-
// Utility functions
|
|
115
132
|
var isDateDisabled = function (date) {
|
|
116
|
-
return (
|
|
117
|
-
(maxDate && date.isAfter((0, dayjs_1.default)(maxDate), 'day'))
|
|
133
|
+
return (minDate && date.isBefore((0, dayjs_1.default)(minDate), 'day')) ||
|
|
134
|
+
(maxDate && date.isAfter((0, dayjs_1.default)(maxDate), 'day'));
|
|
118
135
|
};
|
|
119
136
|
var isToday = function (date) { return date.isSame((0, dayjs_1.default)(), 'day'); };
|
|
120
137
|
var isSelected = function (date) { return selectedDate && date.isSame(selectedDate, 'day'); };
|
|
121
|
-
var isCurrentMonth = function (date) { return date.isSame(currentMonth, 'month'); };
|
|
122
|
-
// Weekday headers
|
|
123
138
|
var weekdays = (0, react_1.useMemo)(function () {
|
|
124
139
|
var days = [];
|
|
125
140
|
for (var i = 0; i < 7; i++) {
|
|
@@ -128,69 +143,89 @@ var Calendar = function (_a) {
|
|
|
128
143
|
}
|
|
129
144
|
return days;
|
|
130
145
|
}, [weekStart]);
|
|
146
|
+
var _l = (0, react_1.useState)(false), isMobile = _l[0], setIsMobile = _l[1];
|
|
147
|
+
(0, react_1.useEffect)(function () {
|
|
148
|
+
var updateViewMode = function () {
|
|
149
|
+
var small = window.innerWidth < 768;
|
|
150
|
+
setIsMobile(small);
|
|
151
|
+
setViewMode(small ? 'week' : 'month');
|
|
152
|
+
};
|
|
153
|
+
updateViewMode(); // initial check
|
|
154
|
+
window.addEventListener('resize', updateViewMode);
|
|
155
|
+
return function () { return window.removeEventListener('resize', updateViewMode); };
|
|
156
|
+
}, []);
|
|
131
157
|
return (react_1.default.createElement("div", { className: "calendar ".concat(funcss) },
|
|
132
158
|
react_1.default.createElement("div", { className: "calendar-header" },
|
|
133
|
-
react_1.default.createElement(Avatar_1.default, { funcss:
|
|
159
|
+
react_1.default.createElement(Avatar_1.default, { funcss: "border", onClick: prevPeriod },
|
|
134
160
|
react_1.default.createElement(pi_1.PiCaretLeft, null)),
|
|
135
161
|
react_1.default.createElement("div", { className: "calendar-title" },
|
|
136
|
-
react_1.default.createElement(
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
};
|
|
163
|
-
}) }),
|
|
164
|
-
react_1.default.createElement(Button_1.default, { bg: 'lighter border', onClick: goToToday }, "Today")),
|
|
165
|
-
react_1.default.createElement(Avatar_1.default, { funcss: 'border', onClick: nextMonth, "aria-label": "Next month" },
|
|
162
|
+
react_1.default.createElement(RowFlex_1.default, { gap: 1, align: "center" },
|
|
163
|
+
react_1.default.createElement(Input_1.default, { type: "text", select: true, value: currentMonth.month().toString(), onChange: function (e) {
|
|
164
|
+
return setCurrentMonth(currentMonth.month(parseInt(e.target.value)));
|
|
165
|
+
}, options: Array.from({ length: 12 }, function (_, i) { return ({
|
|
166
|
+
value: i.toString(),
|
|
167
|
+
text: (0, dayjs_1.default)().month(i).format('MMMM'),
|
|
168
|
+
}); }), borderless: true, funcss: "round-edge" }),
|
|
169
|
+
react_1.default.createElement(Input_1.default, { type: "text", select: true, value: currentMonth.year().toString(), onChange: function (e) {
|
|
170
|
+
return setCurrentMonth(currentMonth.year(parseInt(e.target.value)));
|
|
171
|
+
}, options: Array.from({ length: 21 }, function (_, i) {
|
|
172
|
+
var year = (0, dayjs_1.default)().year() - 10 + i;
|
|
173
|
+
return { value: year.toString(), text: year.toString() };
|
|
174
|
+
}), borderless: true, funcss: "round-edge" }),
|
|
175
|
+
react_1.default.createElement(Dropdown_1.default, { direction: "dropdown", position: 'right', openOnHover: false, button: react_1.default.createElement(Avatar_1.default, null,
|
|
176
|
+
react_1.default.createElement(hi_1.HiOutlineDotsVertical, null)), items: [
|
|
177
|
+
{
|
|
178
|
+
label: react_1.default.createElement("span", { className: "text-sm" }, "Today"),
|
|
179
|
+
onClick: function () { return goToToday(); },
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
label: react_1.default.createElement("div", { className: "text-sm", onClick: function () {
|
|
183
|
+
return setViewMode(viewMode === 'month' ? 'week' : 'month');
|
|
184
|
+
} }, viewMode === 'month' ? 'Switch to Week' : 'Switch to Month'),
|
|
185
|
+
},
|
|
186
|
+
] }))),
|
|
187
|
+
react_1.default.createElement(Avatar_1.default, { funcss: "border", onClick: nextPeriod },
|
|
166
188
|
react_1.default.createElement(pi_1.PiCaretRight, null))),
|
|
167
189
|
react_1.default.createElement("div", { className: "calendar-weekdays" }, weekdays.map(function (d, i) { return (react_1.default.createElement("div", { key: i, className: "weekday-header" }, d)); })),
|
|
168
190
|
react_1.default.createElement("div", { className: "calendar-grid" }, days.map(function (date, index) {
|
|
169
|
-
if (!date)
|
|
191
|
+
if (!date || (viewMode === 'month' && !date.isSame(currentMonth, 'month'))) {
|
|
170
192
|
return react_1.default.createElement("div", { key: index, className: "calendar-cell empty" });
|
|
193
|
+
}
|
|
171
194
|
var key = date.format('YYYY-MM-DD');
|
|
172
195
|
var activitiesToday = monthActivities[key] || [];
|
|
173
196
|
var disabled = isDateDisabled(date);
|
|
174
197
|
var today = isToday(date);
|
|
175
198
|
var selected = isSelected(date);
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
react_1.default.createElement("div", { className: "
|
|
179
|
-
react_1.default.createElement(
|
|
180
|
-
react_1.default.createElement(Text_1.default, { text: date.date(), color: today ? 'primary' : '', size: 'xl' }),
|
|
181
|
-
today && react_1.default.createElement(pi_1.PiChecks, { className: "text-success" }))),
|
|
182
|
-
react_1.default.createElement("div", { className: "activities" },
|
|
183
|
-
activitiesToday.slice(0, 2).map(function (activity) { return (react_1.default.createElement("div", { key: activity.id, className: "activity-tag", style: { backgroundColor: activity.color || '#e0e0e0' }, onClick: function (e) {
|
|
184
|
-
e.stopPropagation();
|
|
199
|
+
return (react_1.default.createElement("div", { key: key, className: "calendar-cell hoverable ".concat(disabled ? 'disabled' : '', " ").concat(today ? 'today' : '', " ").concat(selected ? 'selected' : ''), onClick: function () { return handleDateClick(date); }, onMouseEnter: function () { return setHoveredDate(key); }, onMouseLeave: function () { return setHoveredDate(null); } },
|
|
200
|
+
react_1.default.createElement("div", { className: "day-number ".concat(today ? 'today' : '') }, date.date()),
|
|
201
|
+
!isMobile && (react_1.default.createElement("div", { className: "activities " },
|
|
202
|
+
activitiesToday.slice(0, showMoreActivities ? activitiesToday.length : 3).map(function (activity) { return (react_1.default.createElement(ActivityCard_1.default, { activity: activity, onClick: function (e) {
|
|
185
203
|
onActivityClick === null || onActivityClick === void 0 ? void 0 : onActivityClick(activity);
|
|
186
|
-
} }
|
|
187
|
-
activitiesToday.length >
|
|
204
|
+
} })); }),
|
|
205
|
+
activitiesToday.length > 3 && (react_1.default.createElement(Button_1.default, { smaller: true, funcss: 'p-0', color: "primary", onClick: function () { return setShowMoreActivities(!showMoreActivities); } }, showMoreActivities ? 'Show Less' : react_1.default.createElement(react_1.default.Fragment, null,
|
|
188
206
|
"+",
|
|
189
|
-
activitiesToday.length -
|
|
190
|
-
" more"))),
|
|
191
|
-
hoveredDate === key && !disabled && (react_1.default.createElement("div", { className: "add-icon", onClick: function (e) { return handleAdd(e, date); }
|
|
192
|
-
react_1.default.createElement(Circle_1.default, {
|
|
207
|
+
activitiesToday.length - 3,
|
|
208
|
+
" more"))))),
|
|
209
|
+
hoveredDate === key && !disabled && (react_1.default.createElement("div", { className: "add-icon hide-small", onClick: function (e) { return handleAdd(e, date); } },
|
|
210
|
+
react_1.default.createElement(Circle_1.default, { bg: 'primary' },
|
|
193
211
|
react_1.default.createElement(pi_1.PiPlus, null))))));
|
|
194
|
-
}))
|
|
212
|
+
})),
|
|
213
|
+
isMobile && selectedDate && (react_1.default.createElement("div", { className: "calendar-activities-mobile p-1" },
|
|
214
|
+
react_1.default.createElement(RowFlex_1.default, { gap: 0.5, justify: "space-between", align: "center", className: "mt-3 mb-2" },
|
|
215
|
+
react_1.default.createElement(Text_1.default, { text: (0, dayjs_1.default)(selectedDate).format('dddd, MMMM D'), weight: 600, funcss: "mb-2" }),
|
|
216
|
+
react_1.default.createElement("div", { onClick: function (e) { return handleAdd(e, (0, dayjs_1.default)(selectedDate)); } },
|
|
217
|
+
react_1.default.createElement(Circle_1.default, { bg: "primary" },
|
|
218
|
+
react_1.default.createElement(pi_1.PiPlus, null)))),
|
|
219
|
+
(monthActivities[(0, dayjs_1.default)(selectedDate).format('YYYY-MM-DD')] || []).map(function (activity) { return (react_1.default.createElement(ActivityCard_1.default, { activity: activity, onClick: function (e) {
|
|
220
|
+
onActivityClick === null || onActivityClick === void 0 ? void 0 : onActivityClick(activity);
|
|
221
|
+
} })); }),
|
|
222
|
+
(monthActivities[(0, dayjs_1.default)(selectedDate).format('YYYY-MM-DD')] || []).length === 0 && (react_1.default.createElement(View_1.default, { funcss: 'mt-2 text-center' },
|
|
223
|
+
react_1.default.createElement("div", null,
|
|
224
|
+
" ",
|
|
225
|
+
react_1.default.createElement(pi_1.PiEmpty, { size: 30 })),
|
|
226
|
+
react_1.default.createElement(Text_1.default, { text: "No activities for this day.", size: "sm", opacity: 2 }),
|
|
227
|
+
react_1.default.createElement("div", { className: "mt-2" },
|
|
228
|
+
react_1.default.createElement("span", { onClick: function (e) { return handleAdd(e, (0, dayjs_1.default)(selectedDate)); } },
|
|
229
|
+
react_1.default.createElement(Button_1.default, { small: true, bg: 'lighter', startIcon: react_1.default.createElement(pi_1.PiPlus, null) }, "Add Activity")))))))));
|
|
195
230
|
};
|
|
196
231
|
exports.default = Calendar;
|