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.
@@ -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 ? false : _f, _g = _a.className, className = _g === void 0 ? '' : _g;
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,
@@ -29,7 +29,7 @@ const ScrollInView: React.FC<ScrollInViewProps> = ({
29
29
  delay = 0,
30
30
  duration = 0.6,
31
31
  threshold = 0.2,
32
- once = false,
32
+ once = true,
33
33
  className = '',
34
34
  }) => {
35
35
  const controls = useAnimation();
@@ -1,5 +1,19 @@
1
1
  import React from 'react';
2
- interface AccordionProps {
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: 'center', gap: 0.6 },
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: 'col fit' }, title)),
59
- react_1.default.createElement("div", { style: { lineHeight: 0 }, className: "".concat(iconClass, " ").concat(isOpen ? "accordion-rotated" : "") },
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, // default is only one open
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, PiCaretUp } from 'react-icons/pi';
3
+ import { PiCaretDown } from 'react-icons/pi';
4
4
  import RowFlex from '../specials/RowFlex';
5
5
 
6
- interface AccordionItemProps {
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 className={`accordion-header ${titleClass}`} onClick={onToggle}>
36
- <RowFlex alignItems='center' gap={0.6}>
37
- {
38
- icon && <div style={{lineHeight:0}}>{icon}</div>
39
- }
40
- <div className='col fit'>{title}</div>
41
- </RowFlex>
42
- <div style={{lineHeight:0}} className={`${iconClass} ${isOpen ? "accordion-rotated" : ""}`}>
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
- interface AccordionProps {
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; // ✅ NEW
60
- defaultOpenIndexes?: number[]; // optional
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, // ❗ default is only one open
79
+ allowMultiple = false,
73
80
  defaultOpenIndexes = [],
74
81
  itemClass,
75
82
  titleClass,
@@ -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", __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: {
64
- width: "".concat(size, "rem"),
65
- height: "".concat(size, "rem"),
66
- }, onClick: onClick }, rest), content || children));
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
  }
@@ -26,7 +26,8 @@ export default function Avatar({
26
26
  ...rest
27
27
  }: AvatarProps) {
28
28
  return (
29
- <div
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
  }
@@ -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 {};
@@ -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) : 'base'),
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' : '',
@@ -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) : 'base'}`,
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,8 @@
1
+ import React from 'react';
2
+ import { Activity } from './Calendar';
3
+ type ActivityCardProps = {
4
+ activity: Activity;
5
+ onClick?: (activity: Activity) => void;
6
+ };
7
+ declare const ActivityCard: React.FC<ActivityCardProps>;
8
+ export default ActivityCard;
@@ -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
- interface Activity {
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;
@@ -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
- // Memoized calculations
59
- var _h = (0, react_1.useMemo)(function () {
60
- var startOfMonth = currentMonth.startOf('month');
61
- var endOfMonth = currentMonth.endOf('month');
62
- // Calculate days grid
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
- // Previous month days
69
- for (var i = daysBefore - 1; i >= 0; i--) {
70
- var date = startOfMonth.subtract(i + 1, 'day');
71
- days.push(showAdjacentMonths ? date : null);
72
- }
73
- // Current month days
74
- for (var i = 0; i < daysInMonth; i++) {
75
- days.push(startOfMonth.add(i, 'day'));
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
- // Next month days
78
- var remaining = totalDays - days.length;
79
- for (var i = 0; i < remaining; i++) {
80
- var date = endOfMonth.add(i + 1, 'day');
81
- days.push(showAdjacentMonths ? date : null);
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
- if (date.isSame(currentMonth, 'month') ||
88
- (showAdjacentMonths && (date.isBefore(endOfMonth) && date.isAfter(startOfMonth)))) {
89
- var key = date.format('YYYY-MM-DD');
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 = _h.days, monthActivities = _h.monthActivities;
97
- // Navigation handlers
98
- var prevMonth = function () { return setCurrentMonth(currentMonth.subtract(1, 'month')); };
99
- var nextMonth = function () { return setCurrentMonth(currentMonth.add(1, 'month')); };
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 ((minDate && date.isBefore((0, dayjs_1.default)(minDate), 'day')) ||
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: 'border', onClick: prevMonth, "aria-label": "Previous month" },
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(Input_1.default, { value: currentMonth.month(), onChange: function (e) {
137
- var newMonth = currentMonth.month(parseInt(e.target.value));
138
- setCurrentMonth(newMonth);
139
- }, type: "text", label: "Select Month", borderless: true, fullWidth: true, funcss: 'round-edge', select: true, options: [
140
- { value: "", text: "-- Select month --" },
141
- { value: "0", text: "January" },
142
- { value: "1", text: "February" },
143
- { value: "2", text: "March" },
144
- { value: "3", text: "April" },
145
- { value: "4", text: "May" },
146
- { value: "5", text: "June" },
147
- { value: "6", text: "July" },
148
- { value: "7", text: "August" },
149
- { value: "8", text: "September" },
150
- { value: "9", text: "October" },
151
- { value: "10", text: "November" },
152
- { value: "11", text: "December" }
153
- ] }),
154
- react_1.default.createElement(Input_1.default, { type: "text", label: "Select Year", funcss: 'round-edge', fullWidth: true, borderless: true, select: true, value: currentMonth.year().toString(), onChange: function (e) {
155
- var newYear = currentMonth.year(parseInt(e.target.value));
156
- setCurrentMonth(newYear);
157
- }, options: Array.from({ length: 21 }, function (_, i) {
158
- var year = (0, dayjs_1.default)().year() - 10 + i;
159
- return {
160
- value: year.toString(),
161
- text: year.toString(),
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
- var currentMonth = isCurrentMonth(date);
177
- return (react_1.default.createElement("div", { key: key, className: "calendar-cell ".concat(!currentMonth ? 'adjacent-month' : '', " ").concat(disabled ? 'disabled' : '', " ").concat(today ? 'today' : '', " ").concat(selected ? 'selected' : ''), onClick: function () { return handleDateClick(date); }, onMouseEnter: function () { return setHoveredDate(key); }, onMouseLeave: function () { return setHoveredDate(null); }, "aria-disabled": disabled, "aria-label": date.format('MMMM D, YYYY'), role: "button", tabIndex: 0 },
178
- react_1.default.createElement("div", { className: "day-number" },
179
- react_1.default.createElement(RowFlex_1.default, { justify: 'space-between', align: 'center', gap: 0.5 },
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
- } }, renderActivity ? renderActivity(activity) : activity.title)); }),
187
- activitiesToday.length > 2 && (react_1.default.createElement("div", { className: "activity-more" },
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 - 2,
190
- " more"))),
191
- hoveredDate === key && !disabled && (react_1.default.createElement("div", { className: "add-icon", onClick: function (e) { return handleAdd(e, date); }, "aria-label": "Add event on ".concat(date.format('MMMM D')) },
192
- react_1.default.createElement(Circle_1.default, { hoverable: true, funcss: 'card bg' },
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;