@koobiq/react-components 0.0.1-beta.25 → 0.0.1-beta.26
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/dist/components/Calendar/Calendar.d.ts +2 -0
- package/dist/components/Calendar/Calendar.js +41 -0
- package/dist/components/Calendar/Calendar.module.css.js +14 -0
- package/dist/components/Calendar/components/CalendarCell/CalendarCell.d.ts +7 -0
- package/dist/components/Calendar/components/CalendarCell/CalendarCell.js +49 -0
- package/dist/components/Calendar/components/CalendarCell/CalendarCell.module.css.js +29 -0
- package/dist/components/Calendar/components/CalendarCell/index.d.ts +1 -0
- package/dist/components/Calendar/components/CalendarGrid/CalendarGrid.d.ts +6 -0
- package/dist/components/Calendar/components/CalendarGrid/CalendarGrid.js +28 -0
- package/dist/components/Calendar/components/CalendarGrid/CalendarGrid.module.css.js +14 -0
- package/dist/components/Calendar/components/CalendarGrid/index.d.ts +1 -0
- package/dist/components/Calendar/components/CalendarHeader/CalendarHeader.d.ts +8 -0
- package/dist/components/Calendar/components/CalendarHeader/CalendarHeader.js +54 -0
- package/dist/components/Calendar/components/CalendarHeader/CalendarHeader.module.css.js +11 -0
- package/dist/components/Calendar/components/CalendarHeader/index.d.ts +1 -0
- package/dist/components/Calendar/components/CalendarMonthDropdown/CalendarMonthDropdown.d.ts +6 -0
- package/dist/components/Calendar/components/CalendarMonthDropdown/CalendarMonthDropdown.js +101 -0
- package/dist/components/Calendar/components/CalendarMonthDropdown/index.d.ts +1 -0
- package/dist/components/Calendar/components/CalendarYearDropdown/CalendarYearDropdown.d.ts +6 -0
- package/dist/components/Calendar/components/CalendarYearDropdown/CalendarYearDropdown.js +76 -0
- package/dist/components/Calendar/components/CalendarYearDropdown/index.d.ts +1 -0
- package/dist/components/Calendar/components/index.d.ts +2 -0
- package/dist/components/Calendar/index.d.ts +2 -0
- package/dist/components/Calendar/intl.json.js +7 -0
- package/dist/components/Calendar/types.d.ts +49 -0
- package/dist/components/Menu/Menu.js +3 -2
- package/dist/components/Menu/components/MenuInner/MenuInner.d.ts +4 -1
- package/dist/components/Menu/components/MenuInner/MenuInner.js +7 -6
- package/dist/components/Menu/types.d.ts +4 -3
- package/dist/components/Popover/Popover.js +2 -1
- package/dist/components/Popover/types.d.ts +6 -1
- package/dist/components/Provider/Provider.d.ts +2 -0
- package/dist/components/Provider/Provider.js +3 -1
- package/dist/components/Table/Table.js +2 -2
- package/dist/components/Table/Table.module.css.js +6 -47
- package/dist/components/Table/components/TableCell/TableCell.js +2 -2
- package/dist/components/Table/components/TableCell/TableCell.module.css.js +27 -0
- package/dist/components/Table/components/TableCheckboxCell/TableCheckboxCell.js +2 -2
- package/dist/components/Table/components/TableColumnHeader/TableColumnHeader.js +3 -3
- package/dist/components/Table/components/TableColumnHeader/TableColumnHeader.module.css.js +27 -0
- package/dist/components/Table/components/TableRow/TableRow.js +2 -2
- package/dist/components/Table/components/TableRow/TableRow.module.css.js +23 -0
- package/dist/components/Table/components/TableRowGroup/TableRowGroup.js +1 -3
- package/dist/components/Table/components/TableSelectAllCell/TableSelectAllCell.js +2 -2
- package/dist/components/Toggle/Toggle.d.ts +14 -7
- package/dist/components/Toggle/Toggle.js +72 -11
- package/dist/components/Toggle/Toggle.module.css.js +6 -6
- package/dist/components/Toggle/types.d.ts +66 -2
- package/dist/components/index.d.ts +1 -0
- package/dist/index.js +4 -1
- package/dist/style.css +197 -61
- package/dist/utils/capitalizeFirstLetter/capitalizeFirstLetter.d.ts +2 -0
- package/dist/utils/capitalizeFirstLetter/capitalizeFirstLetter.js +6 -0
- package/dist/utils/capitalizeFirstLetter/index.d.ts +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/package.json +5 -5
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
3
|
+
import { forwardRef } from "react";
|
|
4
|
+
import { mergeProps, clsx } from "@koobiq/react-core";
|
|
5
|
+
import { useLocale, useCalendarState, createCalendar, useCalendar } from "@koobiq/react-primitives";
|
|
6
|
+
import { utilClasses } from "../../styles/utility.js";
|
|
7
|
+
import s from "./Calendar.module.css.js";
|
|
8
|
+
import { CalendarHeader } from "./components/CalendarHeader/CalendarHeader.js";
|
|
9
|
+
import { CalendarGrid } from "./components/CalendarGrid/CalendarGrid.js";
|
|
10
|
+
const textNormal = utilClasses.typography["text-normal"];
|
|
11
|
+
function CalendarRender(props, ref) {
|
|
12
|
+
const { locale } = useLocale();
|
|
13
|
+
const state = useCalendarState({
|
|
14
|
+
createCalendar,
|
|
15
|
+
...props,
|
|
16
|
+
locale
|
|
17
|
+
});
|
|
18
|
+
const { calendarProps, prevButtonProps, nextButtonProps } = useCalendar(
|
|
19
|
+
props,
|
|
20
|
+
state
|
|
21
|
+
);
|
|
22
|
+
const rootProps = mergeProps(
|
|
23
|
+
{ className: clsx(s.base, textNormal, props.className), ref },
|
|
24
|
+
calendarProps
|
|
25
|
+
);
|
|
26
|
+
return /* @__PURE__ */ jsxs("div", { ...rootProps, children: [
|
|
27
|
+
/* @__PURE__ */ jsx(
|
|
28
|
+
CalendarHeader,
|
|
29
|
+
{
|
|
30
|
+
state,
|
|
31
|
+
prevButtonProps,
|
|
32
|
+
nextButtonProps
|
|
33
|
+
}
|
|
34
|
+
),
|
|
35
|
+
/* @__PURE__ */ jsx(CalendarGrid, { state })
|
|
36
|
+
] });
|
|
37
|
+
}
|
|
38
|
+
const Calendar = forwardRef(CalendarRender);
|
|
39
|
+
export {
|
|
40
|
+
Calendar
|
|
41
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CalendarState, AriaCalendarCellProps } from '@koobiq/react-primitives';
|
|
2
|
+
type CalendarCellProps = {
|
|
3
|
+
state: CalendarState;
|
|
4
|
+
date: AriaCalendarCellProps['date'];
|
|
5
|
+
};
|
|
6
|
+
export declare function CalendarCell({ state, date }: CalendarCellProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useRef } from "react";
|
|
4
|
+
import { useHover, useFocusRing, clsx, mergeProps } from "@koobiq/react-core";
|
|
5
|
+
import { today, useCalendarCell } from "@koobiq/react-primitives";
|
|
6
|
+
import { utilClasses } from "../../../../styles/utility.js";
|
|
7
|
+
import s from "./CalendarCell.module.css.js";
|
|
8
|
+
const textNormalMedium = utilClasses.typography["text-normal-medium"];
|
|
9
|
+
function CalendarCell({ state, date }) {
|
|
10
|
+
const ref = useRef(null);
|
|
11
|
+
const isToday = date.compare(today(state.timeZone)) === 0;
|
|
12
|
+
const {
|
|
13
|
+
cellProps,
|
|
14
|
+
isSelected,
|
|
15
|
+
isDisabled,
|
|
16
|
+
isPressed,
|
|
17
|
+
buttonProps,
|
|
18
|
+
isUnavailable,
|
|
19
|
+
formattedDate,
|
|
20
|
+
isOutsideVisibleRange
|
|
21
|
+
} = useCalendarCell({ date }, state, ref);
|
|
22
|
+
const { hoverProps, isHovered } = useHover({
|
|
23
|
+
isDisabled: isDisabled || isUnavailable
|
|
24
|
+
});
|
|
25
|
+
const { focusProps, isFocusVisible } = useFocusRing({});
|
|
26
|
+
return /* @__PURE__ */ jsx("td", { ...cellProps, children: /* @__PURE__ */ jsx(
|
|
27
|
+
"div",
|
|
28
|
+
{
|
|
29
|
+
...mergeProps(hoverProps, focusProps, buttonProps),
|
|
30
|
+
ref,
|
|
31
|
+
className: clsx(
|
|
32
|
+
s.base,
|
|
33
|
+
isToday && s.today,
|
|
34
|
+
isPressed && s.pressed,
|
|
35
|
+
isHovered && s.hovered,
|
|
36
|
+
isDisabled && s.disabled,
|
|
37
|
+
isSelected && s.selected,
|
|
38
|
+
isUnavailable && s.unavailable,
|
|
39
|
+
isSelected && textNormalMedium,
|
|
40
|
+
isFocusVisible && s.focusVisible
|
|
41
|
+
),
|
|
42
|
+
hidden: isOutsideVisibleRange,
|
|
43
|
+
children: formattedDate
|
|
44
|
+
}
|
|
45
|
+
) });
|
|
46
|
+
}
|
|
47
|
+
export {
|
|
48
|
+
CalendarCell
|
|
49
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const base = "kbq-calendarcell-dc4d6e";
|
|
2
|
+
const today = "kbq-calendarcell-today-04de99";
|
|
3
|
+
const hovered = "kbq-calendarcell-hovered-c94a4e";
|
|
4
|
+
const pressed = "kbq-calendarcell-pressed-a65ee0";
|
|
5
|
+
const focusVisible = "kbq-calendarcell-focusVisible-d92d99";
|
|
6
|
+
const selected = "kbq-calendarcell-selected-62a719";
|
|
7
|
+
const disabled = "kbq-calendarcell-disabled-a2a975";
|
|
8
|
+
const unavailable = "kbq-calendarcell-unavailable-a606f4";
|
|
9
|
+
const s = {
|
|
10
|
+
base,
|
|
11
|
+
today,
|
|
12
|
+
hovered,
|
|
13
|
+
pressed,
|
|
14
|
+
focusVisible,
|
|
15
|
+
selected,
|
|
16
|
+
disabled,
|
|
17
|
+
unavailable
|
|
18
|
+
};
|
|
19
|
+
export {
|
|
20
|
+
base,
|
|
21
|
+
s as default,
|
|
22
|
+
disabled,
|
|
23
|
+
focusVisible,
|
|
24
|
+
hovered,
|
|
25
|
+
pressed,
|
|
26
|
+
selected,
|
|
27
|
+
today,
|
|
28
|
+
unavailable
|
|
29
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './CalendarCell';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type AriaCalendarGridProps, type CalendarState } from '@koobiq/react-primitives';
|
|
2
|
+
type CalendarGridProps = {
|
|
3
|
+
state: CalendarState;
|
|
4
|
+
} & AriaCalendarGridProps;
|
|
5
|
+
export declare function CalendarGrid({ state, ...props }: CalendarGridProps): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
3
|
+
import { clsx } from "@koobiq/react-core";
|
|
4
|
+
import { useLocale, useCalendarGrid, getWeeksInMonth } from "@koobiq/react-primitives";
|
|
5
|
+
import { utilClasses } from "../../../../styles/utility.js";
|
|
6
|
+
import s from "./CalendarGrid.module.css.js";
|
|
7
|
+
import { CalendarCell } from "../CalendarCell/CalendarCell.js";
|
|
8
|
+
const textNormal = utilClasses.typography["text-normal"];
|
|
9
|
+
function CalendarGrid({ state, ...props }) {
|
|
10
|
+
const { locale } = useLocale();
|
|
11
|
+
const { gridProps, headerProps, weekDays } = useCalendarGrid(
|
|
12
|
+
{ ...props, weekdayStyle: "short" },
|
|
13
|
+
state
|
|
14
|
+
);
|
|
15
|
+
const weeksInMonth = getWeeksInMonth(state.visibleRange.start, locale);
|
|
16
|
+
return /* @__PURE__ */ jsxs("table", { ...gridProps, className: clsx(s.base, textNormal), children: [
|
|
17
|
+
/* @__PURE__ */ jsxs("thead", { ...headerProps, children: [
|
|
18
|
+
/* @__PURE__ */ jsx("tr", { children: weekDays.map((day, i) => /* @__PURE__ */ jsx("th", { className: clsx(s.weekDay, textNormal), children: day }, i)) }),
|
|
19
|
+
/* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("th", { colSpan: 7, className: s.divider }) })
|
|
20
|
+
] }),
|
|
21
|
+
/* @__PURE__ */ jsx("tbody", { children: [...new Array(weeksInMonth).keys()].map((weekIndex) => /* @__PURE__ */ jsx("tr", { children: state.getDatesInWeek(weekIndex).map(
|
|
22
|
+
(date, i) => date ? /* @__PURE__ */ jsx(CalendarCell, { state, date }, i) : /* @__PURE__ */ jsx("td", {}, i)
|
|
23
|
+
) }, weekIndex)) })
|
|
24
|
+
] });
|
|
25
|
+
}
|
|
26
|
+
export {
|
|
27
|
+
CalendarGrid
|
|
28
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const base = "kbq-calendargrid-1a43cf";
|
|
2
|
+
const weekDay = "kbq-calendargrid-weekDay-94b083";
|
|
3
|
+
const divider = "kbq-calendargrid-divider-3ec061";
|
|
4
|
+
const s = {
|
|
5
|
+
base,
|
|
6
|
+
weekDay,
|
|
7
|
+
divider
|
|
8
|
+
};
|
|
9
|
+
export {
|
|
10
|
+
base,
|
|
11
|
+
s as default,
|
|
12
|
+
divider,
|
|
13
|
+
weekDay
|
|
14
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './CalendarGrid';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type CalendarState, type CalendarAria } from '@koobiq/react-primitives';
|
|
2
|
+
type CalendarHeaderProps = {
|
|
3
|
+
prevButtonProps: CalendarAria['prevButtonProps'];
|
|
4
|
+
nextButtonProps: CalendarAria['nextButtonProps'];
|
|
5
|
+
state: CalendarState;
|
|
6
|
+
};
|
|
7
|
+
export declare const CalendarHeader: (props: CalendarHeaderProps) => import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
3
|
+
import { IconChevronLeft16, IconCircleXs16, IconChevronRight16 } from "@koobiq/react-icons";
|
|
4
|
+
import { useLocalizedStringFormatter, today } from "@koobiq/react-primitives";
|
|
5
|
+
import intlMessages from "../../intl.json.js";
|
|
6
|
+
import s from "./CalendarHeader.module.css.js";
|
|
7
|
+
import { CalendarMonthDropdown } from "../CalendarMonthDropdown/CalendarMonthDropdown.js";
|
|
8
|
+
import { CalendarYearDropdown } from "../CalendarYearDropdown/CalendarYearDropdown.js";
|
|
9
|
+
import { Button } from "../../../Button/Button.js";
|
|
10
|
+
const CalendarHeader = (props) => {
|
|
11
|
+
const { prevButtonProps, nextButtonProps, state } = props;
|
|
12
|
+
const stringFormatter = useLocalizedStringFormatter(intlMessages);
|
|
13
|
+
return /* @__PURE__ */ jsxs("div", { className: s.base, children: [
|
|
14
|
+
/* @__PURE__ */ jsx(CalendarMonthDropdown, { state }),
|
|
15
|
+
/* @__PURE__ */ jsx(CalendarYearDropdown, { state }),
|
|
16
|
+
/* @__PURE__ */ jsxs("div", { className: s.actions, children: [
|
|
17
|
+
/* @__PURE__ */ jsx(
|
|
18
|
+
Button,
|
|
19
|
+
{
|
|
20
|
+
...prevButtonProps,
|
|
21
|
+
variant: "contrast-transparent",
|
|
22
|
+
startIcon: /* @__PURE__ */ jsx(IconChevronLeft16, {}),
|
|
23
|
+
onlyIcon: true
|
|
24
|
+
}
|
|
25
|
+
),
|
|
26
|
+
/* @__PURE__ */ jsx(
|
|
27
|
+
Button,
|
|
28
|
+
{
|
|
29
|
+
"aria-label": stringFormatter.format("today"),
|
|
30
|
+
onPress: () => {
|
|
31
|
+
const date = today(state.timeZone);
|
|
32
|
+
state.setFocusedDate(date);
|
|
33
|
+
},
|
|
34
|
+
isDisabled: state.isDisabled,
|
|
35
|
+
variant: "contrast-transparent",
|
|
36
|
+
startIcon: /* @__PURE__ */ jsx(IconCircleXs16, {}),
|
|
37
|
+
onlyIcon: true
|
|
38
|
+
}
|
|
39
|
+
),
|
|
40
|
+
/* @__PURE__ */ jsx(
|
|
41
|
+
Button,
|
|
42
|
+
{
|
|
43
|
+
...nextButtonProps,
|
|
44
|
+
variant: "contrast-transparent",
|
|
45
|
+
startIcon: /* @__PURE__ */ jsx(IconChevronRight16, {}),
|
|
46
|
+
onlyIcon: true
|
|
47
|
+
}
|
|
48
|
+
)
|
|
49
|
+
] })
|
|
50
|
+
] });
|
|
51
|
+
};
|
|
52
|
+
export {
|
|
53
|
+
CalendarHeader
|
|
54
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './CalendarHeader';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type CalendarState } from '@koobiq/react-primitives';
|
|
2
|
+
type CalendarMonthDropdownProps = {
|
|
3
|
+
state: CalendarState;
|
|
4
|
+
};
|
|
5
|
+
export declare function CalendarMonthDropdown({ state }: CalendarMonthDropdownProps): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export {};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useRef, useEffect } from "react";
|
|
4
|
+
import { useBoolean, clsx } from "@koobiq/react-core";
|
|
5
|
+
import { IconChevronDown16 } from "@koobiq/react-icons";
|
|
6
|
+
import { useDateFormatter } from "@koobiq/react-primitives";
|
|
7
|
+
import s from "../../Calendar.module.css.js";
|
|
8
|
+
import { Menu } from "../../../Menu/Menu.js";
|
|
9
|
+
import { capitalizeFirstLetter } from "../../../../utils/capitalizeFirstLetter/capitalizeFirstLetter.js";
|
|
10
|
+
import { Button } from "../../../Button/Button.js";
|
|
11
|
+
function CalendarMonthDropdown({ state }) {
|
|
12
|
+
const months = [];
|
|
13
|
+
const disabledKeys = /* @__PURE__ */ new Set();
|
|
14
|
+
const [isOpen, { on, off }] = useBoolean();
|
|
15
|
+
const longFormatter = useDateFormatter({
|
|
16
|
+
month: "long",
|
|
17
|
+
timeZone: state.timeZone
|
|
18
|
+
});
|
|
19
|
+
const shortFormatter = useDateFormatter({
|
|
20
|
+
month: "short",
|
|
21
|
+
timeZone: state.timeZone
|
|
22
|
+
});
|
|
23
|
+
const selectedMonthName = shortFormatter.format(
|
|
24
|
+
state.focusedDate.toDate(state.timeZone)
|
|
25
|
+
);
|
|
26
|
+
const menuRef = useRef(null);
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
if (!menuRef.current || !state.focusedDate.month) return;
|
|
29
|
+
const container = menuRef.current;
|
|
30
|
+
const selectedEl = container.querySelector(
|
|
31
|
+
`[data-key="${state.focusedDate.month}"]`
|
|
32
|
+
);
|
|
33
|
+
if (selectedEl instanceof HTMLElement) {
|
|
34
|
+
const containerHeight = container.offsetHeight;
|
|
35
|
+
const elementTop = selectedEl.offsetTop;
|
|
36
|
+
const elementHeight = selectedEl.offsetHeight;
|
|
37
|
+
container.scrollTop = elementTop - containerHeight / 2 + elementHeight / 2;
|
|
38
|
+
}
|
|
39
|
+
}, [state.focusedDate.month, isOpen]);
|
|
40
|
+
const numMonths = state.focusedDate.calendar.getMonthsInYear(
|
|
41
|
+
state.focusedDate
|
|
42
|
+
);
|
|
43
|
+
const minDate = state.minValue;
|
|
44
|
+
const maxDate = state.maxValue;
|
|
45
|
+
for (let i = 1; i <= numMonths; i++) {
|
|
46
|
+
const date = state.focusedDate.set({ month: i });
|
|
47
|
+
const isBeforeMin = minDate && date.compare(minDate) < 0;
|
|
48
|
+
const isAfterMax = maxDate && date.compare(maxDate) > 0;
|
|
49
|
+
if (isBeforeMin || isAfterMax) {
|
|
50
|
+
disabledKeys.add(i);
|
|
51
|
+
}
|
|
52
|
+
months.push({
|
|
53
|
+
id: i,
|
|
54
|
+
name: longFormatter.format(date.toDate(state.timeZone))
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
return /* @__PURE__ */ jsx(
|
|
58
|
+
Menu,
|
|
59
|
+
{
|
|
60
|
+
control: (props) => /* @__PURE__ */ jsx(
|
|
61
|
+
Button,
|
|
62
|
+
{
|
|
63
|
+
...props,
|
|
64
|
+
className: clsx(isOpen && s.open),
|
|
65
|
+
variant: "contrast-transparent",
|
|
66
|
+
isDisabled: state.isDisabled,
|
|
67
|
+
endIcon: /* @__PURE__ */ jsx(IconChevronDown16, {}),
|
|
68
|
+
children: capitalizeFirstLetter(selectedMonthName).replace(/\.$/, "")
|
|
69
|
+
}
|
|
70
|
+
),
|
|
71
|
+
className: s.popover,
|
|
72
|
+
slotProps: {
|
|
73
|
+
list: {
|
|
74
|
+
ref: menuRef
|
|
75
|
+
},
|
|
76
|
+
popover: {
|
|
77
|
+
maxBlockSize: 265,
|
|
78
|
+
slotProps: {
|
|
79
|
+
transition: {
|
|
80
|
+
onEnter: on,
|
|
81
|
+
onExited: off
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
items: months,
|
|
87
|
+
disabledKeys,
|
|
88
|
+
selectionMode: "single",
|
|
89
|
+
selectedKeys: /* @__PURE__ */ new Set([state.focusedDate.month]),
|
|
90
|
+
onSelectionChange: (keys) => {
|
|
91
|
+
const value = Array.from(keys)[0];
|
|
92
|
+
const date = state.focusedDate.set({ month: +value });
|
|
93
|
+
state.setFocusedDate(date);
|
|
94
|
+
},
|
|
95
|
+
children: (item) => /* @__PURE__ */ jsx(Menu.Item, { children: capitalizeFirstLetter(item.name) })
|
|
96
|
+
}
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
export {
|
|
100
|
+
CalendarMonthDropdown
|
|
101
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './CalendarMonthDropdown';
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useRef, useEffect } from "react";
|
|
4
|
+
import { useBoolean, clsx } from "@koobiq/react-core";
|
|
5
|
+
import { IconChevronDown16 } from "@koobiq/react-icons";
|
|
6
|
+
import "@koobiq/react-primitives";
|
|
7
|
+
import s from "../../Calendar.module.css.js";
|
|
8
|
+
import { Menu } from "../../../Menu/Menu.js";
|
|
9
|
+
import { Button } from "../../../Button/Button.js";
|
|
10
|
+
function CalendarYearDropdown({ state }) {
|
|
11
|
+
const years = [];
|
|
12
|
+
const [isOpen, { on, off }] = useBoolean();
|
|
13
|
+
const menuRef = useRef(null);
|
|
14
|
+
const minYear = state.minValue?.year ?? state.focusedDate.year - 20;
|
|
15
|
+
const maxYear = state.maxValue?.year ?? state.focusedDate.year + 20;
|
|
16
|
+
for (let y = minYear; y <= maxYear; y++) {
|
|
17
|
+
years.push({ id: y });
|
|
18
|
+
}
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (!menuRef.current || !state.focusedDate.year) return;
|
|
21
|
+
const container = menuRef.current;
|
|
22
|
+
const selectedEl = container.querySelector(
|
|
23
|
+
`[data-key="${state.focusedDate.year}"]`
|
|
24
|
+
);
|
|
25
|
+
if (selectedEl instanceof HTMLElement) {
|
|
26
|
+
const containerHeight = container.offsetHeight;
|
|
27
|
+
const elementTop = selectedEl.offsetTop;
|
|
28
|
+
const elementHeight = selectedEl.offsetHeight;
|
|
29
|
+
container.scrollTop = elementTop - containerHeight / 2 + elementHeight / 2;
|
|
30
|
+
}
|
|
31
|
+
}, [state.focusedDate.year, isOpen]);
|
|
32
|
+
const selectedYearName = years.find(({ id }) => id === state.focusedDate.year)?.id ?? "";
|
|
33
|
+
return /* @__PURE__ */ jsx(
|
|
34
|
+
Menu,
|
|
35
|
+
{
|
|
36
|
+
slotProps: {
|
|
37
|
+
list: {
|
|
38
|
+
ref: menuRef
|
|
39
|
+
},
|
|
40
|
+
popover: {
|
|
41
|
+
maxBlockSize: 265,
|
|
42
|
+
slotProps: {
|
|
43
|
+
transition: {
|
|
44
|
+
onEnter: on,
|
|
45
|
+
onExited: off
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
control: (props) => /* @__PURE__ */ jsx(
|
|
51
|
+
Button,
|
|
52
|
+
{
|
|
53
|
+
...props,
|
|
54
|
+
className: clsx(isOpen && s.open),
|
|
55
|
+
variant: "contrast-transparent",
|
|
56
|
+
endIcon: /* @__PURE__ */ jsx(IconChevronDown16, {}),
|
|
57
|
+
isDisabled: state.isDisabled,
|
|
58
|
+
children: selectedYearName
|
|
59
|
+
}
|
|
60
|
+
),
|
|
61
|
+
className: s.popover,
|
|
62
|
+
items: years,
|
|
63
|
+
selectionMode: "single",
|
|
64
|
+
selectedKeys: /* @__PURE__ */ new Set([state.focusedDate.year]),
|
|
65
|
+
onSelectionChange: (keys) => {
|
|
66
|
+
const value = Array.from(keys)[0];
|
|
67
|
+
const date = state.focusedDate.set({ year: +value });
|
|
68
|
+
state.setFocusedDate(date);
|
|
69
|
+
},
|
|
70
|
+
children: (item) => /* @__PURE__ */ jsx(Menu.Item, { textValue: String(item.id), children: item.id })
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
export {
|
|
75
|
+
CalendarYearDropdown
|
|
76
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './CalendarYearDropdown';
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { ComponentRef, ReactElement, Ref } from 'react';
|
|
2
|
+
import type { AriaCalendarProps, DateValue } from '@koobiq/react-primitives';
|
|
3
|
+
type CalendarPropMinValue<T extends DateValue> = AriaCalendarProps<T>['minValue'];
|
|
4
|
+
type CalendarPropMaxValue<T extends DateValue> = AriaCalendarProps<T>['maxValue'];
|
|
5
|
+
type CalendarPropValue<T extends DateValue> = AriaCalendarProps<T>['value'];
|
|
6
|
+
type CalendarPropDefaultValue<T extends DateValue> = AriaCalendarProps<T>['defaultValue'];
|
|
7
|
+
type CalendarPropOnChange<T extends DateValue> = AriaCalendarProps<T>['onChange'];
|
|
8
|
+
type CalendarPropIsDisabled<T extends DateValue> = AriaCalendarProps<T>['isDisabled'];
|
|
9
|
+
type CalendarPropFirstDayOfWeek<T extends DateValue> = AriaCalendarProps<T>['firstDayOfWeek'];
|
|
10
|
+
type CalendarPropIsDateUnavailable<T extends DateValue> = AriaCalendarProps<T>['isDateUnavailable'];
|
|
11
|
+
type CalendarPropFocusedValue<T extends DateValue> = AriaCalendarProps<T>['focusedValue'];
|
|
12
|
+
type CalendarPropDefaultFocusedValue<T extends DateValue> = AriaCalendarProps<T>['defaultFocusedValue'];
|
|
13
|
+
type CalendarPropOnFocusChange<T extends DateValue> = AriaCalendarProps<T>['onFocusChange'];
|
|
14
|
+
export type CalendarProps<T extends DateValue> = {
|
|
15
|
+
/** Ref to the root container. */
|
|
16
|
+
ref?: Ref<HTMLDivElement>;
|
|
17
|
+
/** Additional CSS-classes. */
|
|
18
|
+
className?: string;
|
|
19
|
+
/** The minimum allowed date that a user may select. */
|
|
20
|
+
minValue?: CalendarPropMinValue<T>;
|
|
21
|
+
/** The maximum allowed date that a user may select. */
|
|
22
|
+
maxValue?: CalendarPropMaxValue<T>;
|
|
23
|
+
/** The current value (controlled). */
|
|
24
|
+
value?: CalendarPropValue<T>;
|
|
25
|
+
/** The default value (uncontrolled). */
|
|
26
|
+
defaultValue?: CalendarPropDefaultValue<T>;
|
|
27
|
+
/** Handler that is called when the value changes. */
|
|
28
|
+
onChange?: CalendarPropOnChange<T>;
|
|
29
|
+
/**
|
|
30
|
+
* Whether the calendar is disabled.
|
|
31
|
+
* @default false
|
|
32
|
+
*/
|
|
33
|
+
isDisabled?: CalendarPropIsDisabled<T>;
|
|
34
|
+
/**
|
|
35
|
+
* The day that starts the week.
|
|
36
|
+
*/
|
|
37
|
+
firstDayOfWeek?: CalendarPropFirstDayOfWeek<T>;
|
|
38
|
+
/** Callback that is called for each date of the calendar. If it returns true, then the date is unavailable. */
|
|
39
|
+
isDateUnavailable?: CalendarPropIsDateUnavailable<T>;
|
|
40
|
+
/** Controls the currently focused date within the calendar. */
|
|
41
|
+
focusedValue?: CalendarPropFocusedValue<T>;
|
|
42
|
+
/** The date that is focused when the calendar first mounts (uncountrolled). */
|
|
43
|
+
defaultFocusedValue?: CalendarPropDefaultFocusedValue<T>;
|
|
44
|
+
/** Handler that is called when the focused date changes. */
|
|
45
|
+
onFocusChange?: CalendarPropOnFocusChange<T>;
|
|
46
|
+
};
|
|
47
|
+
export type CalendarComponentProp = <T extends DateValue>(props: CalendarProps<T>) => ReactElement | null;
|
|
48
|
+
export type CalendarRef = ComponentRef<'div'>;
|
|
49
|
+
export {};
|
|
@@ -21,7 +21,7 @@ function MenuRender(props, ref) {
|
|
|
21
21
|
anchorRef,
|
|
22
22
|
className,
|
|
23
23
|
slotProps,
|
|
24
|
-
...
|
|
24
|
+
...other
|
|
25
25
|
} = props;
|
|
26
26
|
const state = useMenuTriggerState({ ...props, isOpen: open });
|
|
27
27
|
const domRef = useDOMRef(ref);
|
|
@@ -45,12 +45,13 @@ function MenuRender(props, ref) {
|
|
|
45
45
|
},
|
|
46
46
|
slotProps?.popover
|
|
47
47
|
);
|
|
48
|
+
const listProps = mergeProps(menuProps, other, slotProps?.list);
|
|
48
49
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
49
50
|
control?.({
|
|
50
51
|
ref: controlRef,
|
|
51
52
|
...menuTriggerProps
|
|
52
53
|
}),
|
|
53
|
-
/* @__PURE__ */ jsx(PopoverInner, { type: "menu", placement, ...popoverProps, children: /* @__PURE__ */ jsx(MenuInner, { ...
|
|
54
|
+
/* @__PURE__ */ jsx(PopoverInner, { type: "menu", placement, ...popoverProps, children: /* @__PURE__ */ jsx(MenuInner, { ...listProps }) })
|
|
54
55
|
] });
|
|
55
56
|
}
|
|
56
57
|
const MenuComponent = forwardRef(MenuRender);
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import type { ComponentRef, ReactElement } from 'react';
|
|
1
2
|
import type { AriaMenuOptions } from '@koobiq/react-primitives';
|
|
2
3
|
export type MenuInnerProps<T> = AriaMenuOptions<T>;
|
|
3
|
-
export
|
|
4
|
+
export type MenuInnerComponentProp = <T extends object>(props: MenuInnerProps<T>) => ReactElement | null;
|
|
5
|
+
export type MenuInnerRef = ComponentRef<'ul'>;
|
|
6
|
+
export declare const MenuInner: MenuInnerComponentProp;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
4
|
-
import { clsx } from "@koobiq/react-core";
|
|
3
|
+
import { forwardRef } from "react";
|
|
4
|
+
import { useDOMRef, clsx } from "@koobiq/react-core";
|
|
5
5
|
import { useTreeState, useMenu } from "@koobiq/react-primitives";
|
|
6
6
|
import { utilClasses } from "../../../../styles/utility.js";
|
|
7
7
|
import s from "./MenuInner.module.css.js";
|
|
@@ -10,10 +10,10 @@ import { Divider } from "../../../Divider/Divider.js";
|
|
|
10
10
|
import { MenuHeader } from "../MenuHeader/MenuHeader.js";
|
|
11
11
|
import { MenuItem } from "../MenuItem/MenuItem.js";
|
|
12
12
|
const { list } = utilClasses;
|
|
13
|
-
function
|
|
13
|
+
function MenuInnerRender(props, ref) {
|
|
14
14
|
const state = useTreeState(props);
|
|
15
|
-
const
|
|
16
|
-
const { menuProps } = useMenu(props, state,
|
|
15
|
+
const domRef = useDOMRef(ref);
|
|
16
|
+
const { menuProps } = useMenu(props, state, domRef);
|
|
17
17
|
const multiple = props.selectionMode === "multiple";
|
|
18
18
|
const renderItems = (treeState) => [...treeState.collection].map((item) => {
|
|
19
19
|
switch (item.type) {
|
|
@@ -35,11 +35,12 @@ function MenuInner(props) {
|
|
|
35
35
|
...menuProps,
|
|
36
36
|
className: clsx(s.base, list),
|
|
37
37
|
...multiple && { "aria-multiselectable": true },
|
|
38
|
-
ref,
|
|
38
|
+
ref: domRef,
|
|
39
39
|
children: renderItems(state)
|
|
40
40
|
}
|
|
41
41
|
);
|
|
42
42
|
}
|
|
43
|
+
const MenuInner = forwardRef(MenuInnerRender);
|
|
43
44
|
export {
|
|
44
45
|
MenuInner
|
|
45
46
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { ComponentRef, CSSProperties, ReactElement, Ref, RefObject } from 'react';
|
|
1
|
+
import type { ComponentPropsWithRef, ComponentRef, CSSProperties, ReactElement, Ref, RefObject } from 'react';
|
|
2
2
|
import type { ButtonOptions, AriaMenuProps } from '@koobiq/react-primitives';
|
|
3
|
-
import type {
|
|
3
|
+
import type { PopoverBaseProps, PopoverPropPlacement } from '../Popover';
|
|
4
4
|
export type MenuPropControl = (props: ButtonOptions & {
|
|
5
5
|
ref?: Ref<HTMLButtonElement>;
|
|
6
6
|
}) => ReactElement;
|
|
@@ -55,7 +55,8 @@ export type MenuProps<T extends object> = {
|
|
|
55
55
|
ref?: Ref<HTMLDivElement>;
|
|
56
56
|
/** The props used for each slot inside. */
|
|
57
57
|
slotProps?: {
|
|
58
|
-
popover?:
|
|
58
|
+
popover?: PopoverBaseProps;
|
|
59
|
+
list?: ComponentPropsWithRef<'ul'>;
|
|
59
60
|
};
|
|
60
61
|
};
|
|
61
62
|
export type MenuComponentProps = <T extends object>(props: MenuProps<T>) => ReactElement | null;
|