diff --git a/library/src/components/Button.tsx b/library/src/components/Button.tsx index 06dc8f2b..3cd0bfa6 100644 --- a/library/src/components/Button.tsx +++ b/library/src/components/Button.tsx @@ -1,5 +1,11 @@ import type React from "react" -import { type CSSProperties, forwardRef, type HTMLProps, useMemo } from "react" +import { + type CSSProperties, + forwardRef, + type HTMLProps, + useMemo, + useRef, +} from "react" import { twJoin, twMerge } from "tailwind-merge" import { LoadingSpinner } from "./LoadingSpinner" @@ -204,6 +210,10 @@ export const LoadingButton = ({ loadingSpinnerClassName, ...props }: ButtonProps & { loading: boolean; loadingSpinnerClassName?: string }) => { + const ref = useRef(null) + + const height = ref.current?.clientHeight ?? 0 + return ( ) } diff --git a/library/src/components/inputs/Select.tsx b/library/src/components/inputs/Select.tsx index 27b8c8a7..82c92393 100644 --- a/library/src/components/inputs/Select.tsx +++ b/library/src/components/inputs/Select.tsx @@ -164,6 +164,7 @@ function useClassNamesConfig( provided.isDisabled ? "bg-disabled text-disabled-text" : undefined, + provided.data.isFixed ? "pr-1" : undefined, ), "text-ellipsis whitespace-nowrap", classNamesConfig?.multiValue?.(provided), diff --git a/library/src/components/timetable/TimeTable.tsx b/library/src/components/timetable/TimeTable.tsx index c53785b6..c89dbdee 100644 --- a/library/src/components/timetable/TimeTable.tsx +++ b/library/src/components/timetable/TimeTable.tsx @@ -36,7 +36,7 @@ import { } from "./TimeTableSelectionStore" import { useGroupRows } from "./useGoupRows" import { twMerge } from "tailwind-merge" -import { getStartAndEndSlot } from "./timeTableUtils" +import { getStartAndEndSlot, getTimeSlotMinutes } from "./timeTableUtils" import { flushSync } from "react-dom" export interface TimeSlotBooking { @@ -205,6 +205,8 @@ const nowbarUpdateIntervall = 1000 * 60 // 1 minute * Each column in the table is actually 2 columns. 1 fixed size one, and 1 dynamic sized on. Like that I can simulate min-width on the columns, which else is not allowed. * * The index exports a memoized version of the LPTimeTable, which is used by the parent component. + * + * @emits allGroupsRendered (exported, string: timetable-allgroupsrendered) - when all groups are rendered */ export default function LPTimeTable< G extends TimeTableGroup, @@ -270,7 +272,7 @@ const LPTimeTableImpl = ({ // biome-ignore lint/correctness/useExhaustiveDependencies: just remove the message is props change useEffect(() => { setMessage?.(undefined) // clear the message on time frame change - }, [viewType, startDate, endDate, setMessage, timeStepsMinutes]) + }, [startDate, endDate, setMessage, timeStepsMinutes]) const tableRef = useRef(null) const tableHeaderRef = useRef(null) @@ -316,7 +318,7 @@ const LPTimeTableImpl = ({ itemsWithSameStartAndEnd, slotsArray, timeFrameDay, - timeSlotMinutes, + viewType: currViewType, } = useGroupRows(entries) if (!slotsArray || slotsArray.length === 0) { @@ -401,18 +403,10 @@ const LPTimeTableImpl = ({ tableHeaderRef, tableBodyRef, timeFrameDay, - timeSlotMinutes, - viewType, + currViewType, setMessage, ) - }, [ - slotsArray, - nowOverwrite, - timeFrameDay, - timeSlotMinutes, - viewType, - setMessage, - ]) + }, [slotsArray, nowOverwrite, timeFrameDay, currViewType, setMessage]) // initial run, and start interval to move the now bar useEffect(() => { @@ -439,11 +433,10 @@ const LPTimeTableImpl = ({ tableHeaderRef, tableBodyRef, timeFrameDay, - timeSlotMinutes, - viewType, + currViewType, setMessage, ) - }, [setMessage, slotsArray, timeFrameDay, timeSlotMinutes, viewType]) + }, [setMessage, slotsArray, timeFrameDay, currViewType]) useResizeObserver({ ref: tableBodyRef, @@ -507,12 +500,11 @@ const LPTimeTableImpl = ({ > slotsArray={slotsArray} - timeSlotMinutes={timeSlotMinutes} columnWidth={columnWidth} groupHeaderColumnWidth={groupHeaderColumnWidth} startDate={startDate} endDate={endDate} - viewType={viewType} + viewType={currViewType} timeFrameDay={timeFrameDay} showTimeSlotHeader={ showTimeSlotHeader === undefined || @@ -539,9 +531,8 @@ const LPTimeTableImpl = ({ } headerRef={tableHeaderRef} slotsArray={slotsArray} - timeSlotMinutes={timeSlotMinutes} timeFrameDay={timeFrameDay} - viewType={viewType} + viewType={currViewType} /> @@ -568,7 +559,6 @@ function moveNowBar( tableHeaderRef: MutableRefObject, tableBodyRef: MutableRefObject, timeFrameDay: TimeFrameDay, - timeSlotMinutes: number, viewType: TimeTableViewType, setMessage?: (message: TimeTableMessage) => void, ) { @@ -623,7 +613,6 @@ function moveNowBar( nowItem, slotsArray, timeFrameDay, - timeSlotMinutes, viewType, ) if (startAndEndSlot.status !== "in") { @@ -684,19 +673,13 @@ function moveNowBar( nowBarRef.current = nowBar } - let currentTimeSlot = slotsArray[startSlot] - if (viewType !== "hours") { - currentTimeSlot = currentTimeSlot - .add(timeFrameDay.startHour, "hour") - .add(timeFrameDay.startMinute, "minute") - } - - const diffNowDays = now.diff(currentTimeSlot, "days") - let diffNow = now.diff(currentTimeSlot, "minutes") - if (diffNowDays > 0) { - const dDay = 24 * 60 - timeFrameDay.oneDayMinutes - diffNow = diffNow - dDay * diffNowDays - } + const currentTimeSlot = slotsArray[startSlot] + const timeSlotMinutes = getTimeSlotMinutes( + currentTimeSlot, + timeFrameDay, + viewType, + ) + const diffNow = now.diff(currentTimeSlot, "minutes") const diffPerc = diffNow / timeSlotMinutes nowBar.style.left = `${diffPerc * 100}%` @@ -727,6 +710,7 @@ function moveNowBar( console.error("unable to find header date row") return } + const headerDateCells = headerDateRow.children for (const headerDateCell of headerDateCells) { headerDateCell.classList.remove("text-text-subtle") diff --git a/library/src/components/timetable/TimeTableConfigStore.ts b/library/src/components/timetable/TimeTableConfigStore.ts index 8b993534..257d7afd 100644 --- a/library/src/components/timetable/TimeTableConfigStore.ts +++ b/library/src/components/timetable/TimeTableConfigStore.ts @@ -8,9 +8,8 @@ export type TimeTableConfig = { basicProperties: { timeFrameDay: TimeFrameDay slotsArray: readonly Dayjs[] - timeSlotMinutes: number // length of 1 slot in minutes (for example if the day starts at 8, and ends at 16, and the time slot is a week, that this means (16-8)*60*7 minutes) + viewType: TimeTableViewType } - viewType: TimeTableViewType disableWeekendInteractions: boolean hideOutOfRangeMarkers: boolean timeSlotSelectionDisabled: boolean @@ -73,7 +72,6 @@ export function initAndUpdateTimeTableConfigStore( timeTableConfigStore[ident] = proxy>({ basicProperties, - viewType, propTimeSlotMinutes, @@ -107,7 +105,7 @@ export function initAndUpdateTimeTableConfigStore( timeTableConfigStore[ident].endDate !== endDateString || timeTableConfigStore[ident].propTimeSlotMinutes !== propTimeSlotMinutes || - timeTableConfigStore[ident].viewType !== viewType + timeTableConfigStore[ident].basicProperties.viewType !== viewType ) { const basicProperties = calculateTimeSlotPropertiesForView( startDate, @@ -134,7 +132,7 @@ export function initAndUpdateTimeTableConfigStore( timeTableConfigStore[ident].propTimeSlotMinutes !== propTimeSlotMinutes, "view type updated", - timeTableConfigStore[ident].viewType !== viewType, + timeTableConfigStore[ident].basicProperties.viewType !== viewType, ) clearTimeSlotSelection(ident, true) @@ -156,12 +154,10 @@ export function initAndUpdateTimeTableConfigStore( }*/ timeTableConfigStore[ident].basicProperties = basicProperties - timeTableConfigStore[ident].viewType = viewType timeTableConfigStore[ident].propTimeSlotMinutes = propTimeSlotMinutes timeTableConfigStore[ident].startDate = startDateString timeTableConfigStore[ident].endDate = endDateString timeTableConfigStore[ident].propTimeSlotMinutes = propTimeSlotMinutes - timeTableConfigStore[ident].viewType = viewType } if (isCellDisabled !== timeTableConfigStore[ident].isCellDisabled) { @@ -246,14 +242,6 @@ export function useTTCTimeSlotSelectionDisabled(ident: string) { return timeSlotSelectionDisabled } -/** - * returns the view type and a setter for it - */ -export function useTTCViewType(ident: string) { - const viewType = useSnapshot(timeTableConfigStore[ident]).viewType - return viewType -} - //#endregion //#region utilities diff --git a/library/src/components/timetable/TimeTableHeader.tsx b/library/src/components/timetable/TimeTableHeader.tsx index 1c358916..1c305525 100644 --- a/library/src/components/timetable/TimeTableHeader.tsx +++ b/library/src/components/timetable/TimeTableHeader.tsx @@ -23,6 +23,7 @@ import type { } from "./TimeTable" import type { TimeFrameDay } from "./TimeTableConfigStore" import useResizeObserver, { type ObservedSize } from "use-resize-observer" +import { getTimeSlotMinutes } from "./timeTableUtils" const headerTimeSlotFormat: { [viewType in TimeTableViewType]: string } = { hours: "HH:mm", @@ -88,7 +89,6 @@ type TimeTableHeaderProps< I extends TimeSlotBooking, > = { slotsArray: readonly Dayjs[] - timeSlotMinutes: number groupHeaderColumnWidth: number | string columnWidth: number | string startDate: Dayjs @@ -120,7 +120,6 @@ export const LPTimeTableHeader = function TimeTableHeader< I extends TimeSlotBooking, >({ slotsArray, - timeSlotMinutes, groupHeaderColumnWidth, columnWidth, startDate, @@ -311,6 +310,11 @@ export const LPTimeTableHeader = function TimeTableHeader< const isLastOfDay = i === slotsArray.length - 1 || !slotsArray[i + 1].isSame(slot, "day") + const timeSlotMinutes = getTimeSlotMinutes( + slotsArray[i], + timeFrameDay, + viewType, + ) return ( ) { const storeIdent = useTimeTableIdent() @@ -107,7 +107,6 @@ export default function TimeTableRows< const groupRowsRendered = useRef(new Array(entries.length)) const slotsArrayCurrent = useRef(slotsArray) - const timeSlotMinutesCurrent = useRef(timeSlotMinutes) const viewTypeCurrent = useRef(viewType) const timeFrameDayCurrent = useRef(timeFrameDay) @@ -121,14 +120,12 @@ export default function TimeTableRows< if ( slotsArrayCurrent.current !== slotsArray || - timeSlotMinutesCurrent.current !== timeSlotMinutes || viewTypeCurrent.current !== viewType || timeFrameDayCurrent.current !== timeFrameDay ) { // reset the rendered cells renderedCells.current.clear() slotsArrayCurrent.current = slotsArray - timeSlotMinutesCurrent.current = timeSlotMinutes viewTypeCurrent.current = viewType timeFrameDayCurrent.current = timeFrameDay setGroupRowsRenderedIdx(0) @@ -237,6 +234,7 @@ export default function TimeTableRows< console.info("TimeTable - all group rows updated") return } + // determine when new ones start let newOne = -1 const keys = Object.keys(currentGroupRows) @@ -276,8 +274,8 @@ export default function TimeTableRows< return ret }) currentGroupRows.current = groupRows - //rateLimiterRendering(() => window.setTimeout(renderBatch, 0)) - }, [groupRows]) + rateLimiterRendering(renderBatch) + }, [groupRows, rateLimiterRendering]) //useEffect(handleIntersections, []) // handle intersection observer, create new observer if the intersectionContainerRef changes @@ -323,6 +321,26 @@ export default function TimeTableRows< let start = groupRowsRenderedIdx + // removal of too many rendered elements + for ( + let g = entries.length; + g < groupRowsRendered.current.length; + g++ + ) { + if (groupRowsRendered.current[g]) { + console.log("REMOVING ", g, groupRowsRendered.current) + delete groupRowsRendered.current[g] + delete refCollection.current[g] + renderedCells.current.delete(g) + if (renderCells.current[0] >= g) { + renderCells.current[0] = g - 2 > 0 ? g - 2 : 0 + } + if (renderCells.current[1] >= g) { + renderCells.current[1] = g - 1 > 0 ? g - 1 : 0 + } + } + } + // get the group entries which required rendering let startRender = -1 for ( @@ -371,7 +389,7 @@ export default function TimeTableRows< end = groupRowKeys.length } - for (let g = start; g < end && g < groupRowKeys.length; g++) { + for (let g = start; g < end; g++) { const groupEntry = entries[g] if (!groupEntry) { console.warn( @@ -417,7 +435,6 @@ export default function TimeTableRows< mref={mref} slotsArray={slotsArray} timeFrameDay={timeFrameDay} - timeSlotsMinutes={timeSlotMinutes} viewType={viewType} /> ) @@ -453,7 +470,6 @@ export default function TimeTableRows< placeHolderHeight, slotsArray, timeFrameDay, - timeSlotMinutes, viewType, ]) @@ -464,18 +480,18 @@ export default function TimeTableRows< if (groupRowsRenderedIdx < entries.length) { rateLimiterRendering(renderBatch) } else { - console.info( - "TimeTable - all group rows rendered", - groupRowsRenderedIdx, - entries.length, - ) if (!allPlaceholderRendered.current) { + console.info( + "TimeTable - all group rows rendered", + groupRowsRenderedIdx, + entries.length, + ) allPlaceholderRendered.current = true + window.dispatchEvent(new Event(allGroupsRenderedEvent)) // we need to render all placeholders rateLimiterIntersection(handleIntersections) } } - return groupRowsRendered.current } @@ -494,7 +510,6 @@ function TableCell({ slotsArray, timeFrameDay, viewType, - timeSlotMinutes, }: { timeSlotNumber: number group: G @@ -506,7 +521,6 @@ function TableCell({ onTimeSlotItemClick: ((group: G, item: I) => void) | undefined slotsArray: readonly Dayjs[] timeFrameDay: TimeFrameDay - timeSlotMinutes: number viewType: TimeTableViewType }) { const storeIdent = useTimeTableIdent() @@ -536,6 +550,8 @@ function TableCell({ ? timeSlotAfter.day() !== timeSlot.day() : true + const timeSlotMinutes = getTimeSlotMinutes(timeSlot, timeFrameDay, viewType) + const cellDisabled = isCellDisabled?.( group, @@ -630,6 +646,7 @@ function TableCell({ currentLeft, slotsArray, bookingItemsBeginningInCell, + width, ) } @@ -854,7 +871,6 @@ type GroupRowsProps = { mref: React.MutableRefObject slotsArray: readonly Dayjs[] timeFrameDay: TimeFrameDay - timeSlotsMinutes: number viewType: TimeTableViewType } @@ -871,7 +887,6 @@ function GroupRows({ placeHolderHeight, slotsArray, timeFrameDay, - timeSlotsMinutes, viewType, mref, }: GroupRowsProps) { @@ -971,17 +986,22 @@ function GroupRows({ timeSlotNumber < slotsArray.length; timeSlotNumber++ ) { + const timeSlotMinutes = getTimeSlotMinutes( + slotsArray[timeSlotNumber], + timeFrameDay, + viewType, + ) tds.push( key={timeSlotNumber} group={group} groupNumber={groupNumber} timeSlotNumber={timeSlotNumber} - timeSlotMinutes={timeSlotsMinutes} viewType={viewType} slotsArray={slotsArray} selectedTimeSlots={selectedTimeSlots ?? undefined} placeHolderHeight={placeHolderHeight} + timeSlotMinutes={timeSlotMinutes} />, ) } @@ -991,11 +1011,11 @@ function GroupRows({ groupNumber, timeSlotSelectionDisabled, slotsArray, - timeSlotsMinutes, viewType, selectedTimeSlots, renderCells, placeHolderHeight, + timeFrameDay, ]) const normalRows = useMemo(() => { @@ -1033,7 +1053,6 @@ function GroupRows({ slotsArray={slotsArray} timeFrameDay={timeFrameDay} viewType={viewType} - timeSlotMinutes={timeSlotsMinutes} />, ) } @@ -1052,7 +1071,6 @@ function GroupRows({ selectedTimeSlotItem, onTimeSlotItemClick, renderCells, - timeSlotsMinutes, ]) if (!renderCells) { diff --git a/library/src/components/timetable/TimeTableSelectionStore.ts b/library/src/components/timetable/TimeTableSelectionStore.ts index b78349c9..d17d9b9c 100644 --- a/library/src/components/timetable/TimeTableSelectionStore.ts +++ b/library/src/components/timetable/TimeTableSelectionStore.ts @@ -2,6 +2,7 @@ import { proxy, snapshot, useSnapshot } from "valtio" import type { TimeTableGroup } from "./TimeTable" import { getTTCBasicProperties } from "./TimeTableConfigStore" import type { Dayjs } from "dayjs" +import { getTimeSlotMinutes } from "./timeTableUtils" export type onTimeRangeSelectedType = | React.Dispatch< @@ -154,7 +155,6 @@ function setTimeSlotSelectionByDateRange( const basicConfig = getTTCBasicProperties(ident) const slotsArray = basicConfig.slotsArray - const timeSlotMinutes = basicConfig.timeSlotMinutes // find the time range in the slots array const newSlots: number[] = [] @@ -163,6 +163,13 @@ function setTimeSlotSelectionByDateRange( if (!newSlots.length && slot.isSame(startDate)) { newSlots.push(i) } + + const timeSlotMinutes = getTimeSlotMinutes( + slot, + basicConfig.timeFrameDay, + basicConfig.viewType, + ) + const slotEnd = slot.add(timeSlotMinutes, "minutes") if ( newSlots.length && @@ -363,8 +370,13 @@ function notifyOnTimeRangeSelected( const basicProps = getTTCBasicProperties(ident) const startDate = basicProps.slotsArray[firstSlot] + const timeSlotMinutes = getTimeSlotMinutes( + basicProps.slotsArray[lastSlot], + basicProps.timeFrameDay, + basicProps.viewType, + ) const endDate = basicProps.slotsArray[lastSlot].add( - basicProps.timeSlotMinutes, + timeSlotMinutes, "minutes", ) store.onTimeRangeSelected({ group, startDate, endDate }) diff --git a/library/src/components/timetable/index.ts b/library/src/components/timetable/index.ts index 972b0fbf..143976af 100644 --- a/library/src/components/timetable/index.ts +++ b/library/src/components/timetable/index.ts @@ -18,10 +18,15 @@ export type { TimeTableItemProps } from "./ItemWrapper" export type { TimeTablePlaceholderItemProps } from "./PlaceholderItem" import type { TimeFrameDay as _TimeFrameDay } from "./TimeTableConfigStore" -import { getLeftAndWidth, getStartAndEndSlot } from "./timeTableUtils" +import { + getLeftAndWidth, + getStartAndEndSlot, + getTimeSlotMinutes, +} from "./timeTableUtils" export const timeTableUtils = { getLeftAndWidth, getStartAndEndSlot, + getTimeSlotMinutes, } //const memoized = React.memo(TimeTable) as typeof TimeTable @@ -60,3 +65,6 @@ export namespace TimeTableTypes { I extends TimeSlotBooking, > = LPTimeTableProps } + +/** Evnts */ +export { allGroupsRenderedEvent } from "./TimeTableRows" diff --git a/library/src/components/timetable/timeTableUtils.ts b/library/src/components/timetable/timeTableUtils.ts index 0d4765c0..72812382 100644 --- a/library/src/components/timetable/timeTableUtils.ts +++ b/library/src/components/timetable/timeTableUtils.ts @@ -4,6 +4,7 @@ dayjs.extend(isoWeek) import type { TimeSlotBooking, TimeTableViewType } from "./TimeTable" import type { TimeTableMessage } from "./TimeTableMessageContext" import type { TimeFrameDay } from "./TimeTableConfigStore" +import { assertUnreachable } from "../../utils/assertUnreachable" export function isOverlapping( item: TimeSlotBooking, @@ -210,7 +211,7 @@ export function calculateTimeSlotPropertiesForView( ): { timeFrameDay: TimeFrameDay slotsArray: Dayjs[] - timeSlotMinutes: number + viewType: TimeTableViewType } { const startHour = startDate.hour() const startMinute = startDate.minute() @@ -236,7 +237,7 @@ export function calculateTimeSlotPropertiesForView( oneDayMinutes: 0, }, slotsArray: [], - timeSlotMinutes: 0, + viewType, } } @@ -247,7 +248,7 @@ export function calculateTimeSlotPropertiesForView( timeStepsMinute, setMessage, ) - return Object.freeze(res) + return Object.freeze({ ...res, viewType }) } // get the actual end time fitting to the time slots @@ -329,12 +330,27 @@ export function calculateTimeSlotPropertiesForView( .startOf("day") .add(1, unit) .diff(dayjs().startOf("day"), "days") - const timeSlotMinutes = unitDays * oneDayMinutes + //const timeSlotMinutes = unitDays * oneDayMinutes + let timeSlotMinutes = timeStepsMinute + switch (viewType) { + case "days": { + timeSlotMinutes = oneDayMinutes + break + } + case "weeks": { + timeSlotMinutes = 6 * 24 * 60 + oneDayMinutes + break + } + case "months": { + timeSlotMinutes = 29 * 24 * 60 + oneDayMinutes + break + } + } return Object.freeze({ timeFrameDay, slotsArray, - timeSlotMinutes, + viewType, }) } @@ -345,6 +361,9 @@ export function calculateTimeSlotPropertiesForView( * @param endSlot * @param slotsArray * @param timeSteps + * @param timeFrameDay + * @param viewType + * @param timeSlotMinutes */ export function getLeftAndWidth( item: TimeSlotBooking, @@ -391,20 +410,22 @@ export function getLeftAndWidth( ) itemModEnd = itemModStart } else { - let timeFrameEndEnd = slotsArray[slotsArray.length - 1].add( - timeSlotMinutes, + const timeSlotMinutesLastTS = getTimeSlotMinutes( + slotsArray[slotsArray.length - 1], + timeFrameDay, + viewType, + ) + const timeFrameEndEnd = slotsArray[slotsArray.length - 1].add( + timeSlotMinutesLastTS, "minutes", ) - if (viewType !== "hours") { - timeFrameEndEnd = timeFrameEndEnd - .add(1, viewType) - .subtract(1, "day") - } + if (itemModEnd.isAfter(timeFrameEndEnd)) { itemModEnd = timeFrameEndEnd } else if (item.endDate.hour() === 0 && item.endDate.minute() === 0) { - //itemModEnd = itemModEnd.subtract(1, "minute") - itemModEnd = timeFrameEndEnd + //itemModEnd = itemModEnd.subtract(1, "second") // this is a hack to make the end time of the day inclusive + //console.log("HACK APPLIED", itemModEnd) + //itemModEnd = timeFrameEndEnd //.startOf("day") //.add(timeFrameDay.endHour, "hour") //.add(timeFrameDay.endMinute, "minutes") @@ -414,6 +435,7 @@ export function getLeftAndWidth( item.endDate.minute() > timeFrameDay.endMinute) ) { if (timeFrameDay.endHour !== 0 && timeFrameDay.endMinute !== 0) { + console.log("WARG", item, itemModEnd, timeFrameDay) itemModEnd = itemModEnd .startOf("day") .add(timeFrameDay.endHour, "hour") @@ -422,19 +444,9 @@ export function getLeftAndWidth( } } - const dTimeDay = 24 * 60 - timeFrameDay.oneDayMinutes + const slotStart = slotsArray[startSlot] - let slotStart = slotsArray[startSlot] - if (viewType !== "hours") { - slotStart = slotStart - .add(timeFrameDay.startHour, "hour") - .add(timeFrameDay.startMinute, "minutes") - } - const dstartDays = itemModStart.diff(slotStart, "day") - let dstartMin = itemModStart.diff(slotStart, "minute") - if (dstartDays > 0) { - dstartMin -= dstartDays * dTimeDay - } + const dstartMin = itemModStart.diff(slotStart, "minute") let left = dstartMin / timeSlotMinutes if (left < 0) { console.error( @@ -450,11 +462,7 @@ export function getLeftAndWidth( left = 0 } - const timeSpanDays = itemModEnd.diff(itemModStart, "day") - let timeSpanMin = itemModEnd.diff(itemModStart, "minute") - if (timeSpanDays > 0) { - timeSpanMin -= timeSpanDays * dTimeDay - } + const timeSpanMin = itemModEnd.diff(itemModStart, "minute") const width = timeSpanMin / timeSlotMinutes /*let dmin = itemModEnd.diff(slotsArray[endSlot], "minute") @@ -486,8 +494,6 @@ export function getLeftAndWidth( slotsArray, timeSlotMinutes, timeSpanMin, - timeSpanDays, - dTimeDay, itemModStart, itemModEnd, ) @@ -506,7 +512,6 @@ export function getStartAndEndSlot( item: TimeSlotBooking, slotsArray: readonly Dayjs[], timeFrameDay: TimeFrameDay, - timeSlotMinutes: number, viewType: TimeTableViewType, ): { startSlot: number @@ -519,16 +524,36 @@ export function getStartAndEndSlot( .add(timeFrameDay.startHour, "hours") .add(timeFrameDay.startMinute, "minutes") } - let timeFrameEnd = slotsArray[slotsArray.length - 1].add( - timeSlotMinutes, - "minutes", - ) - //.startOf("day") - //.add(timeFrameDay.endHour, "hours") - //.add(timeFrameDay.endMinute, "minutes") - if (viewType !== "hours") { - timeFrameEnd = timeFrameEnd.add(1, viewType).subtract(1, "day") + let timeFrameEnd = slotsArray[slotsArray.length - 1] + switch (viewType) { + case "hours": + timeFrameEnd = timeFrameEnd.add(1, "hour") + break + case "days": + timeFrameEnd = timeFrameEnd.add( + timeFrameDay.oneDayMinutes, + "minutes", + ) + break + case "weeks": + timeFrameEnd = timeFrameEnd + .add(6, "days") + .add(timeFrameDay.oneDayMinutes, "minutes") + break + case "months": + timeFrameEnd = timeFrameEnd + .add(1, "month") + .subtract(1, "day") + .add(timeFrameDay.oneDayMinutes, "minutes") + break + case "years": + timeFrameEnd = timeFrameEnd + .add(1, "year") + .subtract(1, "day") + .add(timeFrameDay.oneDayMinutes, "minutes") + break } + if ( item.endDate.isBefore(timeFrameStart) || item.endDate.isSame(timeFrameStart) @@ -605,7 +630,7 @@ export function getStartAndEndSlot( let endSlotEnd = slotsArray[endSlot] if (viewType === "hours") { - endSlotEnd = endSlotEnd.add(timeSlotMinutes, "minutes") + endSlotEnd = endSlotEnd.add(60, "minutes") } else { endSlotEnd = endSlotEnd .add(timeFrameDay.endHour, "hours") @@ -619,3 +644,33 @@ export function getStartAndEndSlot( return { startSlot, endSlot, status: "in" } } + +export function getTimeSlotMinutes( + slotStart: Dayjs, + timeFrameDay: TimeFrameDay, + viewType: TimeTableViewType, +) { + switch (viewType) { + case "hours": + return 60 + case "days": + return timeFrameDay.oneDayMinutes + case "weeks": + return 6 * 24 * 60 + timeFrameDay.oneDayMinutes + case "months": + return slotStart + .add(1, "month") + .subtract(1, "day") + .add(timeFrameDay.oneDayMinutes, "minutes") + .diff(slotStart, "minutes") + case "years": + return slotStart + .add(1, "year") + .subtract(1, "day") + .add(timeFrameDay.oneDayMinutes, "minutes") + .diff(slotStart, "minutes") + + default: + assertUnreachable(viewType) + } +} diff --git a/library/src/components/timetable/useGoupRows.ts b/library/src/components/timetable/useGoupRows.ts index d37a8fe5..f31548c7 100644 --- a/library/src/components/timetable/useGoupRows.ts +++ b/library/src/components/timetable/useGoupRows.ts @@ -8,7 +8,6 @@ import type { import { getTTCBasicProperties, type TimeFrameDay, - useTTCViewType, } from "./TimeTableConfigStore" import { useTimeTableIdent } from "./TimeTableIdentContext" import { getStartAndEndSlot, isOverlapping } from "./timeTableUtils" @@ -31,9 +30,8 @@ export function useGroupRows< I extends TimeSlotBooking, >(entries: TimeTableEntry[]) { const storeIdent = useTimeTableIdent() - const { timeFrameDay, slotsArray, timeSlotMinutes } = + const { timeFrameDay, slotsArray, viewType } = getTTCBasicProperties(storeIdent) - const viewType = useTTCViewType(storeIdent) const currentEntries = useRef[]>() @@ -49,7 +47,7 @@ export function useGroupRows< const currentTimeSlots = useRef(slotsArray) const currentTimeFrameDay = useRef(timeFrameDay) - const currentTimeSlotMinutes = useRef(timeSlotMinutes) + const currentViewType = useRef(viewType) const [calcBatch, setCalcBatch] = useState(-1) @@ -57,7 +55,8 @@ export function useGroupRows< const requireNewGroupRows = currentTimeSlots.current !== slotsArray || currentTimeFrameDay.current !== timeFrameDay || - currentTimeSlotMinutes.current !== timeSlotMinutes + currentViewType.current !== viewType || + currentEntries.current !== entries const clearGroupRows = useCallback(() => { groupRowsState.current = {} @@ -140,7 +139,6 @@ export function useGroupRows< entry.items, slotsArray, timeFrameDay, - timeSlotMinutes, viewType, ) @@ -182,7 +180,7 @@ export function useGroupRows< groupRowsState.current = updatedGroupRows // we need to rerender the component to update the group rows setCalcBatch((prev) => (prev > 10 ? prev - 1 : prev + 1)) - }, [slotsArray, timeFrameDay, timeSlotMinutes, viewType]) + }, [slotsArray, timeFrameDay, viewType]) const rateLimiterCalc = useIdleRateLimitHelper(renderIdleTimeout) @@ -190,7 +188,7 @@ export function useGroupRows< currentEntries.current = entries currentTimeSlots.current = slotsArray currentTimeFrameDay.current = timeFrameDay - currentTimeSlotMinutes.current = timeSlotMinutes + currentViewType.current = viewType clearGroupRows() rateLimiterCalc(calculateGroupRows) } @@ -256,7 +254,7 @@ export function useGroupRows< itemsOutsideOfDayRange: itemsOutsideOfDayRange.current, itemsWithSameStartAndEnd: itemsWithSameStartAndEnd.current, // those three are cached for consistency to render with the correct data even through the data might have been updated in between - timeSlotMinutes: currentTimeSlotMinutes.current, + viewType: currentViewType.current, timeFrameDay: currentTimeFrameDay.current, slotsArray: currentTimeSlots.current, // @@ -272,7 +270,6 @@ function getGroupItemStack( groupItems: I[], slotsArray: readonly Dayjs[], timeFrameDay: TimeFrameDay, - timeSlotMinutes: number, viewType: TimeTableViewType, ) { const itemRows: ItemRowEntry[][] = [] @@ -293,7 +290,6 @@ function getGroupItemStack( item, slotsArray, timeFrameDay, - timeSlotMinutes, viewType, ) diff --git a/package-lock.json b/package-lock.json index 24479572..fe809066 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "Apache-2.0", "dependencies": { "@atlaskit/empty-state": "^7.12.3", - "@atlaskit/icon": "^22.26.0", + "@atlaskit/icon": "^22.28.0", "@emotion/css": "^11.13.5", "@hello-pangea/dnd": "^17.0.0", "@radix-ui/react-accordion": "^1.2.1", @@ -51,7 +51,7 @@ "@atlaskit/css-reset": "^6.11.2", "@atlaskit/lozenge": "^11.12.2", "@atlaskit/pagination": "^14.10.0", - "@atlaskit/side-navigation": "^3.6.3", + "@atlaskit/side-navigation": "^3.6.4", "@atlaskit/table-tree": "^10.0.6", "@atlaskit/tag": "^12.6.6", "@atlaskit/tag-group": "^11.0.0", @@ -66,7 +66,7 @@ "@formatjs/cli": "^6.3.11", "@monaco-editor/react": "^4.6.0", "@total-typescript/ts-reset": "^0.6.1", - "@types/node": "^22.10.0", + "@types/node": "^22.10.1", "@types/react": "^18.3.12", "@types/react-dom": "^18.3.1", "@typescript-eslint/eslint-plugin": "^8.16.0", @@ -84,7 +84,7 @@ "react-dom": "^18.3.1", "rollup": "4.21", "rollup-plugin-polyfill-node": "^0.13.0", - "stylelint": "^16.10.0", + "stylelint": "^16.11.0", "stylelint-config-standard": "^36.0.1", "stylelint-config-tailwindcss": "^0.0.7", "stylelint-order": "^6.0.4", @@ -92,7 +92,7 @@ "tailwindcss": "^3.4.15", "typescript": "^5.7.2", "typescript-plugin-css-modules": "^5.1.0", - "vite": "^6.0.1", + "vite": "^6.0.2", "vite-plugin-dts": "^4.3.0", "vitest": "^2.1.6" }, @@ -169,12 +169,12 @@ } }, "node_modules/@atlaskit/app-provider": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@atlaskit/app-provider/-/app-provider-1.4.2.tgz", - "integrity": "sha512-CtkObk1aqAGdn1eMC4INzeqkJsq0r9KtmCCtNwk08m84w2Jx+c/zr1+lJ9bJLzG3ozkWb7s0TeCOkT4j1iuwJw==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@atlaskit/app-provider/-/app-provider-1.4.3.tgz", + "integrity": "sha512-D1/qY2ZgCVLBgtjRmUO+wlICibvYGI0rEGp+5g4e2Z4KDEq9TRz0P2ibDDedZv8paM0eo7PstrmWA3J2xmE5RQ==", "license": "Apache-2.0", "dependencies": { - "@atlaskit/tokens": "^2.2.0", + "@atlaskit/tokens": "^2.4.0", "@babel/runtime": "^7.0.0", "bind-event-listener": "^3.0.0" }, @@ -211,21 +211,21 @@ } }, "node_modules/@atlaskit/button": { - "version": "20.3.2", - "resolved": "https://registry.npmjs.org/@atlaskit/button/-/button-20.3.2.tgz", - "integrity": "sha512-LuV9GbG5HQLu6n2ObX+UKsBzuhA4NnAUD1OdxvN1Bvac9jfLL7dDAaI+wsmx7n8wq1W/eTrPO/t/rAwUAQamew==", + "version": "20.3.3", + "resolved": "https://registry.npmjs.org/@atlaskit/button/-/button-20.3.3.tgz", + "integrity": "sha512-iW5OoZkfW2WRzHqplZvHjgrDhJSvfQZ3GttKu+96hzNqFLItvjCiMn3nT/uJlwa/4MtiWlPFnDcdcKwOOJjPBg==", "license": "Apache-2.0", "dependencies": { "@atlaskit/analytics-next": "^10.1.0", "@atlaskit/ds-lib": "^3.2.0", - "@atlaskit/focus-ring": "^1.7.0", - "@atlaskit/icon": "^22.24.0", + "@atlaskit/focus-ring": "^2.0.0", + "@atlaskit/icon": "^22.26.0", "@atlaskit/interaction-context": "^2.1.0", "@atlaskit/platform-feature-flags": "^0.3.0", - "@atlaskit/primitives": "^13.2.0", + "@atlaskit/primitives": "^13.3.0", "@atlaskit/spinner": "^16.3.0", "@atlaskit/theme": "^14.0.0", - "@atlaskit/tokens": "^2.2.0", + "@atlaskit/tokens": "^2.3.0", "@atlaskit/tooltip": "^18.9.0", "@atlaskit/visually-hidden": "^1.5.0", "@babel/runtime": "^7.0.0", @@ -295,9 +295,9 @@ } }, "node_modules/@atlaskit/ds-lib": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@atlaskit/ds-lib/-/ds-lib-3.2.2.tgz", - "integrity": "sha512-nZrUJtrNLbxk+UW/woJWkM4ocQTx51eDXhy/1D2ttHvP3vCHehhbC6/f8JxkKwXY98jinjC4utYqAWnIGA15xg==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@atlaskit/ds-lib/-/ds-lib-3.3.0.tgz", + "integrity": "sha512-8bgJRFvL4C9dOc3XQ0nJLze4OSXtfemmE2os2h/T80hSdQO57hPMnXB22Pl6nT/6nEP7kZ4kAH6hDuJ3vBUNPA==", "license": "Apache-2.0", "dependencies": { "@atlaskit/platform-feature-flags": "^0.3.0", @@ -329,12 +329,12 @@ } }, "node_modules/@atlaskit/focus-ring": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@atlaskit/focus-ring/-/focus-ring-1.7.0.tgz", - "integrity": "sha512-k+Ix8mat1MiB3Pn35NcNQetQSPG4oxAW/TZlJ1yaawRqvS14ymfWRP+5Rh+A3vSYHAoWBamytbd+jd4A5j33yA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@atlaskit/focus-ring/-/focus-ring-2.0.0.tgz", + "integrity": "sha512-EjCPbwGotrIhOHKAvWiRTcCEeorzhvS2c0t3BD6I4qdOnJzdUATp6YmAn8yAhT1tYIEHg3SKthf/RzwIQWMTKw==", "license": "Apache-2.0", "dependencies": { - "@atlaskit/tokens": "^2.0.0", + "@atlaskit/tokens": "^2.3.0", "@babel/runtime": "^7.0.0", "@compiled/react": "^0.18.1", "@emotion/react": "^11.7.1" @@ -359,13 +359,13 @@ } }, "node_modules/@atlaskit/icon": { - "version": "22.26.0", - "resolved": "https://registry.npmjs.org/@atlaskit/icon/-/icon-22.26.0.tgz", - "integrity": "sha512-uOh011NZMp5F9ueUTM9TVqWPdnO45ZfMM7e4jpYZCmT77TkyBl1pqVmMgrBertczBcyOp/bh8K3PV93NQLtFjA==", + "version": "22.28.0", + "resolved": "https://registry.npmjs.org/@atlaskit/icon/-/icon-22.28.0.tgz", + "integrity": "sha512-ugCFHgSnu4oT0Oh/E1gMizlkXo5CcWl4FuZ84TmnpEn0Nj4RkPNBmT6lM1K8kvy3OkKNdJBmVDjc5ccx9+nYmA==", "license": "Apache-2.0", "dependencies": { "@atlaskit/platform-feature-flags": "^0.3.0", - "@atlaskit/tokens": "^2.3.0", + "@atlaskit/tokens": "^2.4.0", "@babel/runtime": "^7.0.0", "@emotion/react": "^11.7.1" }, @@ -440,20 +440,20 @@ } }, "node_modules/@atlaskit/menu": { - "version": "2.13.4", - "resolved": "https://registry.npmjs.org/@atlaskit/menu/-/menu-2.13.4.tgz", - "integrity": "sha512-WBBK3leJfvBRFeY9rgPQ8IYb/bX0ee8xSsBaq24z5Gaqpj9VAnYfiacsVkoW0CfITtlBIAEVYHLcJczsAwypbQ==", + "version": "2.13.6", + "resolved": "https://registry.npmjs.org/@atlaskit/menu/-/menu-2.13.6.tgz", + "integrity": "sha512-PXB49LivJ/KT082PhpWtdlyRUPelkLv94lPseQylRPEOlFIbddmX4+kMA5nJ7E/0Hp8cZQbIBkVr59+4D75Csw==", "dev": true, "license": "Apache-2.0", "dependencies": { "@atlaskit/app-provider": "^1.4.0", - "@atlaskit/ds-lib": "^3.2.0", - "@atlaskit/focus-ring": "^1.7.0", + "@atlaskit/ds-lib": "^3.3.0", + "@atlaskit/focus-ring": "^2.0.0", "@atlaskit/interaction-context": "^2.1.0", "@atlaskit/platform-feature-flags": "^0.3.0", - "@atlaskit/primitives": "^13.2.0", + "@atlaskit/primitives": "^13.3.0", "@atlaskit/theme": "^14.0.0", - "@atlaskit/tokens": "^2.3.0", + "@atlaskit/tokens": "^2.4.0", "@babel/runtime": "^7.0.0", "@emotion/react": "^11.7.1" }, @@ -523,22 +523,22 @@ } }, "node_modules/@atlaskit/popup": { - "version": "1.29.4", - "resolved": "https://registry.npmjs.org/@atlaskit/popup/-/popup-1.29.4.tgz", - "integrity": "sha512-KaChYn0tRtVZmhaXARQogBjZadjh4iWg36lVlQZ0rifvtRLA/49cXC8IKriIrC/6XIePy3oECWk+TIphahewOQ==", + "version": "1.29.5", + "resolved": "https://registry.npmjs.org/@atlaskit/popup/-/popup-1.29.5.tgz", + "integrity": "sha512-yYSw365KPr92s0tgmlBtoMDeQtrjQuSDxSTEsrKCP8eKjG2x01+NNO5YCeheNGyqtph/Q734B8jbQVWR8X6buQ==", "dev": true, "license": "Apache-2.0", "dependencies": { "@atlaskit/css": "^0.6.0", "@atlaskit/ds-lib": "^3.2.0", - "@atlaskit/focus-ring": "^1.7.0", + "@atlaskit/focus-ring": "^2.0.0", "@atlaskit/layering": "^0.8.0", "@atlaskit/platform-feature-flags": "^0.3.0", "@atlaskit/popper": "^6.3.0", "@atlaskit/portal": "^4.9.0", - "@atlaskit/primitives": "^13.2.0", + "@atlaskit/primitives": "^13.3.0", "@atlaskit/theme": "^14.0.0", - "@atlaskit/tokens": "^2.2.0", + "@atlaskit/tokens": "^2.3.0", "@babel/runtime": "^7.0.0", "@emotion/react": "^11.7.1", "bind-event-listener": "^3.0.0", @@ -567,9 +567,9 @@ } }, "node_modules/@atlaskit/primitives": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/@atlaskit/primitives/-/primitives-13.2.0.tgz", - "integrity": "sha512-BkWXoQuWTGPPCnChgOJa85gMtN6PKURAKq4Lqz/X9QTGXfx3VLLoxeonddb7DtF6p7lML6YjvN5jP5hFApqqBw==", + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/@atlaskit/primitives/-/primitives-13.3.0.tgz", + "integrity": "sha512-5/NeDaRjXw7PPdvUaVHOlICJL7TMbjnZ6fwIwEanK1vY/mJtmFZ8aa4nA88LqAA4ty3mte+WBSmL40in5XJkZA==", "license": "Apache-2.0", "dependencies": { "@atlaskit/analytics-next": "^10.1.0", @@ -578,7 +578,7 @@ "@atlaskit/ds-lib": "^3.2.0", "@atlaskit/interaction-context": "^2.1.0", "@atlaskit/platform-feature-flags": "^0.3.0", - "@atlaskit/tokens": "^2.2.0", + "@atlaskit/tokens": "^2.3.0", "@atlaskit/visually-hidden": "^1.5.0", "@babel/runtime": "^7.0.0", "@compiled/react": "^0.18.1", @@ -592,20 +592,20 @@ } }, "node_modules/@atlaskit/side-navigation": { - "version": "3.6.3", - "resolved": "https://registry.npmjs.org/@atlaskit/side-navigation/-/side-navigation-3.6.3.tgz", - "integrity": "sha512-nplD6KdM/628U8Ema3PSIHUhFjxypgSW58nlQbyAU9nbFmXBA78LEjm5YTyo50Kw7lNhsls6w+f/ELvZ22yTfg==", + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/@atlaskit/side-navigation/-/side-navigation-3.6.4.tgz", + "integrity": "sha512-mwUP4cpx/SAgOngNLsmIM5cOBPCnU0QQh2N+Kelr3gZ1UdsLd4Nt0Nw1QC7cwTLP+/PIH9rFddTbWOqVdPNueA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@atlaskit/ds-lib": "^3.2.0", - "@atlaskit/icon": "^22.26.0", + "@atlaskit/ds-lib": "^3.3.0", + "@atlaskit/icon": "^22.28.0", "@atlaskit/menu": "^2.13.0", "@atlaskit/motion": "^1.9.0", "@atlaskit/platform-feature-flags": "^0.3.0", - "@atlaskit/primitives": "^13.2.0", + "@atlaskit/primitives": "^13.3.0", "@atlaskit/theme": "^14.0.0", - "@atlaskit/tokens": "^2.3.0", + "@atlaskit/tokens": "^2.4.0", "@babel/runtime": "^7.0.0", "@emotion/react": "^11.7.1" }, @@ -739,12 +739,12 @@ } }, "node_modules/@atlaskit/tokens": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@atlaskit/tokens/-/tokens-2.3.0.tgz", - "integrity": "sha512-trtYLU1TQ2HPK0Ej3pJ8vLPz+madd55cRbxqm9tE9TjtHtsA2aiLN79Ab1fXnQ+zFX2FGIDcJf81iz9/OexuZQ==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@atlaskit/tokens/-/tokens-2.4.0.tgz", + "integrity": "sha512-GfDX+1j4WJLBOMaBib/Gaa73FaDsNReHCy5qxaoYnNyVQJC0LWtiFT15l4VaIyDhtI3Vl+WWsdkUWDu10Mksag==", "license": "Apache-2.0", "dependencies": { - "@atlaskit/ds-lib": "^3.2.0", + "@atlaskit/ds-lib": "^3.3.0", "@atlaskit/platform-feature-flags": "^0.3.0", "@babel/runtime": "^7.0.0", "@babel/traverse": "^7.23.2", @@ -1158,9 +1158,9 @@ } }, "node_modules/@csstools/media-query-list-parser": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-3.0.1.tgz", - "integrity": "sha512-HNo8gGD02kHmcbX6PvCoUuOQvn4szyB9ca63vZHKX5A81QytgDG4oxG4IaEfHTlEZSZ6MjPEMWIVU+zF2PZcgw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.2.tgz", + "integrity": "sha512-EUos465uvVvMJehckATTlNqGj4UJWkTmdWuDMjqvSUkjGpmOyFZBVwb4knxCm/k2GMTXY+c/5RkdndzFYWeX5A==", "dev": true, "funding": [ { @@ -1177,14 +1177,14 @@ "node": ">=18" }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.1", - "@csstools/css-tokenizer": "^3.0.1" + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" } }, "node_modules/@csstools/selector-specificity": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-4.0.0.tgz", - "integrity": "sha512-189nelqtPd8++phaHNwYovKZI0FOzH1vQEE3QhHHkNIGrg5fSs9CbYP3RvfEH5geztnIA9Jwq91wyOIwAW5JIQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", + "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", "dev": true, "funding": [ { @@ -1201,7 +1201,7 @@ "node": ">=18" }, "peerDependencies": { - "postcss-selector-parser": "^6.1.0" + "postcss-selector-parser": "^7.0.0" } }, "node_modules/@dual-bundle/import-meta-resolve": { @@ -1898,9 +1898,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.15.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.15.0.tgz", - "integrity": "sha512-tMTqrY+EzbXmKJR5ToI8lxu7jaN5EdmrBFJpQk5JmSlyLsx6o4t27r883K5xsLuCYCpfKBCGswMSWXsM+jB7lg==", + "version": "9.16.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.16.0.tgz", + "integrity": "sha512-tw2HxzQkrbeuvyj1tG2Yqq+0H9wGoI2IMk4EOsQeX+vmd75FtJAzf+gTA69WF+baUKRYQ3x2kbLE08js5OsTVg==", "dev": true, "license": "MIT", "peer": true, @@ -3925,9 +3925,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.27.4.tgz", - "integrity": "sha512-NBI2/i2hT9Q+HySSHTBh52da7isru4aAAo6qC3I7QFVsuhxi2gM8t/EI9EVcILiHLj1vfi+VGGPaLOUENn7pmw==", + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.28.0.tgz", + "integrity": "sha512-lA1zZB3bFx5oxu9fYud4+g1mt+lYXCoch0M0V/xhqLoGatbzVse0wlSQ1UYOWKpuSu3gyN4qEc0Dxf/DII1bhQ==", "cpu": [ "arm64" ], @@ -3939,9 +3939,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.27.4.tgz", - "integrity": "sha512-wYcC5ycW2zvqtDYrE7deary2P2UFmSh85PUpAx+dwTCO9uw3sgzD6Gv9n5X4vLaQKsrfTSZZ7Z7uynQozPVvWA==", + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.28.0.tgz", + "integrity": "sha512-aI2plavbUDjCQB/sRbeUZWX9qp12GfYkYSJOrdYTL/C5D53bsE2/nBPuoiJKoWp5SN78v2Vr8ZPnB+/VbQ2pFA==", "cpu": [ "x64" ], @@ -4622,9 +4622,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.10.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", - "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", + "version": "22.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz", + "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5519,9 +5519,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001684", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001684.tgz", - "integrity": "sha512-G1LRwLIQjBQoyq0ZJGqGIJUXzJ8irpbjHLpVRXDvBEScFJ9b17sgK6vlx0GAJFE21okD7zXl08rRRUfq6HdoEQ==", + "version": "1.0.30001685", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001685.tgz", + "integrity": "sha512-e/kJN1EMyHQzgcMEEgoo+YTCO1NGCmIYHk5Qk8jT6AazWemS5QFKJ5ShCJlH3GZrNIdZofcNCEwZqbMjjKzmnA==", "dev": true, "funding": [ { @@ -6084,9 +6084,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.65", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.65.tgz", - "integrity": "sha512-PWVzBjghx7/wop6n22vS2MLU8tKGd4Q91aCEGhG/TYmW6PP5OcSXcdnxTe1NNt0T66N8D6jxh4kC8UsdzOGaIw==", + "version": "1.5.67", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.67.tgz", + "integrity": "sha512-nz88NNBsD7kQSAGGJyp8hS6xSPtWwqNogA0mjtc2nUYeEf3nURK9qpV18TuBdDmEDgVWotS8Wkzf+V52dSQ/LQ==", "dev": true, "license": "ISC" }, @@ -6213,9 +6213,9 @@ } }, "node_modules/eslint": { - "version": "9.15.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.15.0.tgz", - "integrity": "sha512-7CrWySmIibCgT1Os28lUU6upBshZ+GxybLOrmRzi08kS8MBuO8QA7pXEgYgY5W8vK3e74xv0lpjo9DbaGU9Rkw==", + "version": "9.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.16.0.tgz", + "integrity": "sha512-whp8mSQI4C8VXd+fLgSM0lh3UlmcFtVwUQjyKCFfsp+2ItAIYhlq/hqGahGqHE6cv9unM41VlqKk2VtKYR2TaA==", "dev": true, "license": "MIT", "peer": true, @@ -6225,7 +6225,7 @@ "@eslint/config-array": "^0.19.0", "@eslint/core": "^0.9.0", "@eslint/eslintrc": "^3.2.0", - "@eslint/js": "9.15.0", + "@eslint/js": "9.16.0", "@eslint/plugin-kit": "^0.2.3", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -7570,9 +7570,9 @@ } }, "node_modules/known-css-properties": { - "version": "0.34.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.34.0.tgz", - "integrity": "sha512-tBECoUqNFbyAY4RrbqsBQqDFpGXAEbdD5QKr8kACx3+rnArmuuR22nKQWKazvp07N9yjTyDZaw/20UIH8tL9DQ==", + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.35.0.tgz", + "integrity": "sha512-a/RAk2BfKk+WFGhhOCAYqSiFLc34k8Mt/6NWRI4joER0EYUzXIcFivjjnoD3+XU1DggLn/tZc3DOAgke7l8a4A==", "dev": true, "license": "MIT" }, @@ -9104,20 +9104,6 @@ "postcss": "^8.1.0" } }, - "node_modules/postcss-modules-local-by-default/node_modules/postcss-selector-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", - "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/postcss-modules-scope": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", @@ -9134,20 +9120,6 @@ "postcss": "^8.1.0" } }, - "node_modules/postcss-modules-scope/node_modules/postcss-selector-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", - "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/postcss-nested": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", @@ -9174,6 +9146,20 @@ "postcss": "^8.2.14" } }, + "node_modules/postcss-nested/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss-resolve-nested-selector": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.6.tgz", @@ -9209,9 +9195,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", "dev": true, "license": "MIT", "dependencies": { @@ -10500,9 +10486,9 @@ } }, "node_modules/stylelint": { - "version": "16.10.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.10.0.tgz", - "integrity": "sha512-z/8X2rZ52dt2c0stVwI9QL2AFJhLhbPkyfpDFcizs200V/g7v+UYY6SNcB9hKOLcDDX/yGLDsY/pX08sLkz9xQ==", + "version": "16.11.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.11.0.tgz", + "integrity": "sha512-zrl4IrKmjJQ+h9FoMp69UMCq5SxeHk0URhxUBj4d3ISzo/DplOFBJZc7t7Dr6otB+1bfbbKNLOmCDpzKSlW+Nw==", "dev": true, "funding": [ { @@ -10516,16 +10502,16 @@ ], "license": "MIT", "dependencies": { - "@csstools/css-parser-algorithms": "^3.0.1", - "@csstools/css-tokenizer": "^3.0.1", - "@csstools/media-query-list-parser": "^3.0.1", - "@csstools/selector-specificity": "^4.0.0", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "@csstools/media-query-list-parser": "^4.0.2", + "@csstools/selector-specificity": "^5.0.0", "@dual-bundle/import-meta-resolve": "^4.1.0", "balanced-match": "^2.0.0", "colord": "^2.9.3", "cosmiconfig": "^9.0.0", "css-functions-list": "^3.2.3", - "css-tree": "^3.0.0", + "css-tree": "^3.0.1", "debug": "^4.3.7", "fast-glob": "^3.3.2", "fastest-levenshtein": "^1.0.16", @@ -10537,16 +10523,16 @@ "ignore": "^6.0.2", "imurmurhash": "^0.1.4", "is-plain-object": "^5.0.0", - "known-css-properties": "^0.34.0", + "known-css-properties": "^0.35.0", "mathml-tag-names": "^2.1.3", "meow": "^13.2.0", "micromatch": "^4.0.8", "normalize-path": "^3.0.0", - "picocolors": "^1.0.1", - "postcss": "^8.4.47", + "picocolors": "^1.1.1", + "postcss": "^8.4.49", "postcss-resolve-nested-selector": "^0.1.6", "postcss-safe-parser": "^7.0.1", - "postcss-selector-parser": "^6.1.2", + "postcss-selector-parser": "^7.0.0", "postcss-value-parser": "^4.2.0", "resolve-from": "^5.0.0", "string-width": "^4.2.3", @@ -10977,6 +10963,20 @@ "node": ">=14.0.0" } }, + "node_modules/tailwindcss/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", @@ -11074,9 +11074,9 @@ } }, "node_modules/ts-api-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.2.tgz", - "integrity": "sha512-ZF5gQIQa/UmzfvxbHZI3JXN0/Jt+vnAfAviNRAMc491laiK6YCLpCW9ft8oaCRFOTxCZtUTE6XB0ZQAe3olntw==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", + "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", "dev": true, "license": "MIT", "engines": { @@ -11129,9 +11129,9 @@ } }, "node_modules/type-fest": { - "version": "4.29.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.29.0.tgz", - "integrity": "sha512-RPYt6dKyemXJe7I6oNstcH24myUGSReicxcHTvCLgzm4e0n8y05dGvcGB15/SoPRBmhlMthWQ9pvKyL81ko8nQ==", + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.29.1.tgz", + "integrity": "sha512-Y1zUveI92UYM/vo1EFlQSsNf74+hfKH+7saZJslF0Fw92FRaiTAnHPIvo9d7SLxXt/gAYqA4RXyDTioMQCCp0A==", "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=16" @@ -11490,9 +11490,9 @@ } }, "node_modules/vite": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.1.tgz", - "integrity": "sha512-Ldn6gorLGr4mCdFnmeAOLweJxZ34HjKnDm4HGo6P66IEqTxQb36VEdFJQENKxWjupNfoIjvRUnswjn1hpYEpjQ==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.2.tgz", + "integrity": "sha512-XdQ+VsY2tJpBsKGs0wf3U/+azx8BBpYRHFAyKm5VeEZNOJZRB63q7Sc8Iup3k0TrN3KO6QgyzFf+opSbfY1y0g==", "dev": true, "license": "MIT", "dependencies": { @@ -11615,9 +11615,9 @@ } }, "node_modules/vite/node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.27.4.tgz", - "integrity": "sha512-2Y3JT6f5MrQkICUyRVCw4oa0sutfAsgaSsb0Lmmy1Wi2y7X5vT9Euqw4gOsCyy0YfKURBg35nhUKZS4mDcfULw==", + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.28.0.tgz", + "integrity": "sha512-wLJuPLT6grGZsy34g4N1yRfYeouklTgPhH1gWXCYspenKYD0s3cR99ZevOGw5BexMNywkbV3UkjADisozBmpPQ==", "cpu": [ "arm" ], @@ -11629,9 +11629,9 @@ ] }, "node_modules/vite/node_modules/@rollup/rollup-android-arm64": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.27.4.tgz", - "integrity": "sha512-wzKRQXISyi9UdCVRqEd0H4cMpzvHYt1f/C3CoIjES6cG++RHKhrBj2+29nPF0IB5kpy9MS71vs07fvrNGAl/iA==", + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.28.0.tgz", + "integrity": "sha512-eiNkznlo0dLmVG/6wf+Ifi/v78G4d4QxRhuUl+s8EWZpDewgk7PX3ZyECUXU0Zq/Ca+8nU8cQpNC4Xgn2gFNDA==", "cpu": [ "arm64" ], @@ -11643,9 +11643,9 @@ ] }, "node_modules/vite/node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.27.4.tgz", - "integrity": "sha512-PlNiRQapift4LNS8DPUHuDX/IdXiLjf8mc5vdEmUR0fF/pyy2qWwzdLjB+iZquGr8LuN4LnUoSEvKRwjSVYz3Q==", + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.28.0.tgz", + "integrity": "sha512-lmKx9yHsppblnLQZOGxdO66gT77bvdBtr/0P+TPOseowE7D9AJoBw8ZDULRasXRWf1Z86/gcOdpBrV6VDUY36Q==", "cpu": [ "arm64" ], @@ -11657,9 +11657,9 @@ ] }, "node_modules/vite/node_modules/@rollup/rollup-darwin-x64": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.27.4.tgz", - "integrity": "sha512-o9bH2dbdgBDJaXWJCDTNDYa171ACUdzpxSZt+u/AAeQ20Nk5x+IhA+zsGmrQtpkLiumRJEYef68gcpn2ooXhSQ==", + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.28.0.tgz", + "integrity": "sha512-8hxgfReVs7k9Js1uAIhS6zq3I+wKQETInnWQtgzt8JfGx51R1N6DRVy3F4o0lQwumbErRz52YqwjfvuwRxGv1w==", "cpu": [ "x64" ], @@ -11671,9 +11671,9 @@ ] }, "node_modules/vite/node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.27.4.tgz", - "integrity": "sha512-9OwUnK/xKw6DyRlgx8UizeqRFOfi9mf5TYCw1uolDaJSbUmBxP85DE6T4ouCMoN6pXw8ZoTeZCSEfSaYo+/s1w==", + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.28.0.tgz", + "integrity": "sha512-WXveUPKtfqtaNvpf0iOb0M6xC64GzUX/OowbqfiCSXTdi/jLlOmH0Ba94/OkiY2yTGTwteo4/dsHRfh5bDCZ+w==", "cpu": [ "arm" ], @@ -11685,9 +11685,9 @@ ] }, "node_modules/vite/node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.27.4.tgz", - "integrity": "sha512-Vgdo4fpuphS9V24WOV+KwkCVJ72u7idTgQaBoLRD0UxBAWTF9GWurJO9YD9yh00BzbkhpeXtm6na+MvJU7Z73A==", + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.28.0.tgz", + "integrity": "sha512-yLc3O2NtOQR67lI79zsSc7lk31xjwcaocvdD1twL64PK1yNaIqCeWI9L5B4MFPAVGEVjH5k1oWSGuYX1Wutxpg==", "cpu": [ "arm" ], @@ -11699,9 +11699,9 @@ ] }, "node_modules/vite/node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.27.4.tgz", - "integrity": "sha512-pleyNgyd1kkBkw2kOqlBx+0atfIIkkExOTiifoODo6qKDSpnc6WzUY5RhHdmTdIJXBdSnh6JknnYTtmQyobrVg==", + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.28.0.tgz", + "integrity": "sha512-+P9G9hjEpHucHRXqesY+3X9hD2wh0iNnJXX/QhS/J5vTdG6VhNYMxJ2rJkQOxRUd17u5mbMLHM7yWGZdAASfcg==", "cpu": [ "arm64" ], @@ -11713,9 +11713,9 @@ ] }, "node_modules/vite/node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.27.4.tgz", - "integrity": "sha512-caluiUXvUuVyCHr5DxL8ohaaFFzPGmgmMvwmqAITMpV/Q+tPoaHZ/PWa3t8B2WyoRcIIuu1hkaW5KkeTDNSnMA==", + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.28.0.tgz", + "integrity": "sha512-1xsm2rCKSTpKzi5/ypT5wfc+4bOGa/9yI/eaOLW0oMs7qpC542APWhl4A37AENGZ6St6GBMWhCCMM6tXgTIplw==", "cpu": [ "arm64" ], @@ -11727,9 +11727,9 @@ ] }, "node_modules/vite/node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.27.4.tgz", - "integrity": "sha512-FScrpHrO60hARyHh7s1zHE97u0KlT/RECzCKAdmI+LEoC1eDh/RDji9JgFqyO+wPDb86Oa/sXkily1+oi4FzJQ==", + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.28.0.tgz", + "integrity": "sha512-zgWxMq8neVQeXL+ouSf6S7DoNeo6EPgi1eeqHXVKQxqPy1B2NvTbaOUWPn/7CfMKL7xvhV0/+fq/Z/J69g1WAQ==", "cpu": [ "ppc64" ], @@ -11741,9 +11741,9 @@ ] }, "node_modules/vite/node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.27.4.tgz", - "integrity": "sha512-qyyprhyGb7+RBfMPeww9FlHwKkCXdKHeGgSqmIXw9VSUtvyFZ6WZRtnxgbuz76FK7LyoN8t/eINRbPUcvXB5fw==", + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.28.0.tgz", + "integrity": "sha512-VEdVYacLniRxbRJLNtzwGt5vwS0ycYshofI7cWAfj7Vg5asqj+pt+Q6x4n+AONSZW/kVm+5nklde0qs2EUwU2g==", "cpu": [ "riscv64" ], @@ -11755,9 +11755,9 @@ ] }, "node_modules/vite/node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.27.4.tgz", - "integrity": "sha512-PFz+y2kb6tbh7m3A7nA9++eInGcDVZUACulf/KzDtovvdTizHpZaJty7Gp0lFwSQcrnebHOqxF1MaKZd7psVRg==", + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.28.0.tgz", + "integrity": "sha512-LQlP5t2hcDJh8HV8RELD9/xlYtEzJkm/aWGsauvdO2ulfl3QYRjqrKW+mGAIWP5kdNCBheqqqYIGElSRCaXfpw==", "cpu": [ "s390x" ], @@ -11769,9 +11769,9 @@ ] }, "node_modules/vite/node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.27.4.tgz", - "integrity": "sha512-Ni8mMtfo+o/G7DVtweXXV/Ol2TFf63KYjTtoZ5f078AUgJTmaIJnj4JFU7TK/9SVWTaSJGxPi5zMDgK4w+Ez7Q==", + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.28.0.tgz", + "integrity": "sha512-Nl4KIzteVEKE9BdAvYoTkW19pa7LR/RBrT6F1dJCV/3pbjwDcaOq+edkP0LXuJ9kflW/xOK414X78r+K84+msw==", "cpu": [ "x64" ], @@ -11783,9 +11783,9 @@ ] }, "node_modules/vite/node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.27.4.tgz", - "integrity": "sha512-5AeeAF1PB9TUzD+3cROzFTnAJAcVUGLuR8ng0E0WXGkYhp6RD6L+6szYVX+64Rs0r72019KHZS1ka1q+zU/wUw==", + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.28.0.tgz", + "integrity": "sha512-eKpJr4vBDOi4goT75MvW+0dXcNUqisK4jvibY9vDdlgLx+yekxSm55StsHbxUsRxSTt3JEQvlr3cGDkzcSP8bw==", "cpu": [ "x64" ], @@ -11797,9 +11797,9 @@ ] }, "node_modules/vite/node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.27.4.tgz", - "integrity": "sha512-yOpVsA4K5qVwu2CaS3hHxluWIK5HQTjNV4tWjQXluMiiiu4pJj4BN98CvxohNCpcjMeTXk/ZMJBRbgRg8HBB6A==", + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.28.0.tgz", + "integrity": "sha512-Vi+WR62xWGsE/Oj+mD0FNAPY2MEox3cfyG0zLpotZdehPFXwz6lypkGs5y38Jd/NVSbOD02aVad6q6QYF7i8Bg==", "cpu": [ "arm64" ], @@ -11811,9 +11811,9 @@ ] }, "node_modules/vite/node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.27.4.tgz", - "integrity": "sha512-KtwEJOaHAVJlxV92rNYiG9JQwQAdhBlrjNRp7P9L8Cb4Rer3in+0A+IPhJC9y68WAi9H0sX4AiG2NTsVlmqJeQ==", + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.28.0.tgz", + "integrity": "sha512-kN/Vpip8emMLn/eOza+4JwqDZBL6MPNpkdaEsgUtW1NYN3DZvZqSQrbKzJcTL6hd8YNmFTn7XGWMwccOcJBL0A==", "cpu": [ "ia32" ], @@ -11825,9 +11825,9 @@ ] }, "node_modules/vite/node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.27.4.tgz", - "integrity": "sha512-3j4jx1TppORdTAoBJRd+/wJRGCPC0ETWkXOecJ6PPZLj6SptXkrXcNqdj0oclbKML6FkQltdz7bBA3rUSirZug==", + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.28.0.tgz", + "integrity": "sha512-Bvno2/aZT6usSa7lRDL2+hMjVAGjuqaymF1ApZm31JXzniR/hvr14jpU+/z4X6Gt5BPlzosscyJZGUvguXIqeQ==", "cpu": [ "x64" ], @@ -11839,9 +11839,9 @@ ] }, "node_modules/vite/node_modules/rollup": { - "version": "4.27.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.27.4.tgz", - "integrity": "sha512-RLKxqHEMjh/RGLsDxAEsaLO3mWgyoU6x9w6n1ikAzet4B3gI2/3yP6PWY2p9QzRTh6MfEIXB3MwsOY0Iv3vNrw==", + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.28.0.tgz", + "integrity": "sha512-G9GOrmgWHBma4YfCcX8PjH0qhXSdH8B4HDE2o4/jaxj93S4DPCIDoLcXz99eWMji4hB29UFCEd7B2gwGJDR9cQ==", "dev": true, "license": "MIT", "dependencies": { @@ -11855,24 +11855,24 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.27.4", - "@rollup/rollup-android-arm64": "4.27.4", - "@rollup/rollup-darwin-arm64": "4.27.4", - "@rollup/rollup-darwin-x64": "4.27.4", - "@rollup/rollup-freebsd-arm64": "4.27.4", - "@rollup/rollup-freebsd-x64": "4.27.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.27.4", - "@rollup/rollup-linux-arm-musleabihf": "4.27.4", - "@rollup/rollup-linux-arm64-gnu": "4.27.4", - "@rollup/rollup-linux-arm64-musl": "4.27.4", - "@rollup/rollup-linux-powerpc64le-gnu": "4.27.4", - "@rollup/rollup-linux-riscv64-gnu": "4.27.4", - "@rollup/rollup-linux-s390x-gnu": "4.27.4", - "@rollup/rollup-linux-x64-gnu": "4.27.4", - "@rollup/rollup-linux-x64-musl": "4.27.4", - "@rollup/rollup-win32-arm64-msvc": "4.27.4", - "@rollup/rollup-win32-ia32-msvc": "4.27.4", - "@rollup/rollup-win32-x64-msvc": "4.27.4", + "@rollup/rollup-android-arm-eabi": "4.28.0", + "@rollup/rollup-android-arm64": "4.28.0", + "@rollup/rollup-darwin-arm64": "4.28.0", + "@rollup/rollup-darwin-x64": "4.28.0", + "@rollup/rollup-freebsd-arm64": "4.28.0", + "@rollup/rollup-freebsd-x64": "4.28.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.28.0", + "@rollup/rollup-linux-arm-musleabihf": "4.28.0", + "@rollup/rollup-linux-arm64-gnu": "4.28.0", + "@rollup/rollup-linux-arm64-musl": "4.28.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.28.0", + "@rollup/rollup-linux-riscv64-gnu": "4.28.0", + "@rollup/rollup-linux-s390x-gnu": "4.28.0", + "@rollup/rollup-linux-x64-gnu": "4.28.0", + "@rollup/rollup-linux-x64-musl": "4.28.0", + "@rollup/rollup-win32-arm64-msvc": "4.28.0", + "@rollup/rollup-win32-ia32-msvc": "4.28.0", + "@rollup/rollup-win32-x64-msvc": "4.28.0", "fsevents": "~2.3.2" } }, diff --git a/package.json b/package.json index 56a94660..e9d2701d 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ }, "dependencies": { "@atlaskit/empty-state": "^7.12.3", - "@atlaskit/icon": "^22.26.0", + "@atlaskit/icon": "^22.28.0", "@emotion/css": "^11.13.5", "@hello-pangea/dnd": "^17.0.0", "@radix-ui/react-accordion": "^1.2.1", @@ -118,7 +118,7 @@ "@atlaskit/css-reset": "^6.11.2", "@atlaskit/lozenge": "^11.12.2", "@atlaskit/pagination": "^14.10.0", - "@atlaskit/side-navigation": "^3.6.3", + "@atlaskit/side-navigation": "^3.6.4", "@atlaskit/table-tree": "^10.0.6", "@atlaskit/tag": "^12.6.6", "@atlaskit/tag-group": "^11.0.0", @@ -133,7 +133,7 @@ "@formatjs/cli": "^6.3.11", "@monaco-editor/react": "^4.6.0", "@total-typescript/ts-reset": "^0.6.1", - "@types/node": "^22.10.0", + "@types/node": "^22.10.1", "@types/react": "^18.3.12", "@types/react-dom": "^18.3.1", "@typescript-eslint/eslint-plugin": "^8.16.0", @@ -151,7 +151,7 @@ "react-dom": "^18.3.1", "rollup": "4.21", "rollup-plugin-polyfill-node": "^0.13.0", - "stylelint": "^16.10.0", + "stylelint": "^16.11.0", "stylelint-config-standard": "^36.0.1", "stylelint-config-tailwindcss": "^0.0.7", "stylelint-order": "^6.0.4", @@ -159,7 +159,7 @@ "tailwindcss": "^3.4.15", "typescript": "^5.7.2", "typescript-plugin-css-modules": "^5.1.0", - "vite": "^6.0.1", + "vite": "^6.0.2", "vite-plugin-dts": "^4.3.0", "vitest": "^2.1.6" }, diff --git a/showcase/public/showcase-sources.txt b/showcase/public/showcase-sources.txt index ac3d43b6..fdafadde 100644 --- a/showcase/public/showcase-sources.txt +++ b/showcase/public/showcase-sources.txt @@ -1573,6 +1573,7 @@ function ButtonShowcase(props: ShowcaseProps) { loading={isLoading} iconBefore={} iconAfter={} + className="h-6" > Icon Loading Button @@ -6366,7 +6367,7 @@ function SelectShowcase(props: ShowcaseProps) { }} isMulti options={options} - value={options[4]} + defaultValue={options[4]} /** adding some custom classnames to the styling */ classNames={{ control: () => "bg-warning", @@ -7689,6 +7690,7 @@ import ChevronDownIcon from "@atlaskit/icon/glyph/chevron-down" import { useTranslation } from "@linked-planet/ui-kit-ts/localization/LocaleContext" import type { TranslatedTimeTableMessages } from "@linked-planet/ui-kit-ts/components/timetable/TimeTableMessageContext" import type { TimeTableTypes } from "@linked-planet/ui-kit-ts/components/timetable" +import { allGroupsRenderedEvent } from "@linked-planet/ui-kit-ts/components/timetable/TimeTableRows" //import "@linked-planet/ui-kit-ts/dist/style.css" //-> this is not necessary in this setup, but in the real library usage @@ -8109,6 +8111,9 @@ function TestCustomHeaderRowTimeSlot< entries, tableCellRef, }: TimeTableTypes.CustomHeaderRowTimeSlotProps) { + if (!entries || !entries[1]) { + return null + } const groupItems = entries[1].items if (!groupItems.length) { return null @@ -8126,7 +8131,6 @@ function TestCustomHeaderRowTimeSlot< item, slotsArray, timeFrameOfDay, - timeSlotMinutes, viewType, ) if (slotsArray[startAndEnd.startSlot] === timeSlot) { @@ -8184,6 +8188,9 @@ function CustomHeaderRowHeader< viewType, entries, }: TimeTableTypes.CustomHeaderRowHeaderProps) { + if (!entries || !entries[1]) { + return <> + } return (
{entries[1].group.title} has {entries.length} entries @@ -8191,6 +8198,10 @@ function CustomHeaderRowHeader< ) } +window.addEventListener(allGroupsRenderedEvent, () => { + console.info("All groups rendered") +}) + function Example() { //#region timetable @@ -8582,6 +8593,25 @@ function Example() { > Create New Item + +
} iconAfter={} + className="h-6" > Icon Loading Button diff --git a/showcase/src/components/showcase/wrapper/SelectShowcase.tsx b/showcase/src/components/showcase/wrapper/SelectShowcase.tsx index 60dc2693..443c6fc4 100644 --- a/showcase/src/components/showcase/wrapper/SelectShowcase.tsx +++ b/showcase/src/components/showcase/wrapper/SelectShowcase.tsx @@ -298,7 +298,7 @@ function SelectShowcase(props: ShowcaseProps) { }} isMulti options={options} - value={options[4]} + defaultValue={options[4]} /** adding some custom classnames to the styling */ classNames={{ control: () => "bg-warning", diff --git a/showcase/src/components/showcase/wrapper/TimeTableShowcase.tsx b/showcase/src/components/showcase/wrapper/TimeTableShowcase.tsx index aef127ee..712bb3fa 100644 --- a/showcase/src/components/showcase/wrapper/TimeTableShowcase.tsx +++ b/showcase/src/components/showcase/wrapper/TimeTableShowcase.tsx @@ -15,6 +15,7 @@ import ChevronDownIcon from "@atlaskit/icon/glyph/chevron-down" import { useTranslation } from "@linked-planet/ui-kit-ts/localization/LocaleContext" import type { TranslatedTimeTableMessages } from "@linked-planet/ui-kit-ts/components/timetable/TimeTableMessageContext" import type { TimeTableTypes } from "@linked-planet/ui-kit-ts/components/timetable" +import { allGroupsRenderedEvent } from "@linked-planet/ui-kit-ts/components/timetable/TimeTableRows" //import "@linked-planet/ui-kit-ts/dist/style.css" //-> this is not necessary in this setup, but in the real library usage @@ -435,6 +436,9 @@ function TestCustomHeaderRowTimeSlot< entries, tableCellRef, }: TimeTableTypes.CustomHeaderRowTimeSlotProps) { + if (!entries || !entries[1]) { + return null + } const groupItems = entries[1].items if (!groupItems.length) { return null @@ -452,7 +456,6 @@ function TestCustomHeaderRowTimeSlot< item, slotsArray, timeFrameOfDay, - timeSlotMinutes, viewType, ) if (slotsArray[startAndEnd.startSlot] === timeSlot) { @@ -510,13 +513,20 @@ function CustomHeaderRowHeader< viewType, entries, }: TimeTableTypes.CustomHeaderRowHeaderProps) { + if (!entries || !entries[1]) { + return <> + } return (
- {entries[1].group.title} has {entries.length} entries + {entries[1].group.title} has {entries[1].items.length} entries
) } +window.addEventListener(allGroupsRenderedEvent, () => { + console.info("All groups rendered") +}) + function Example() { //#region timetable @@ -908,6 +918,25 @@ function Example() { > Create New Item + +