@ahrowe/ui 0.42.0 → 0.43.0
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/CHANGELOG.md +934 -0
- package/README.md +11 -10
- package/dist/cjs-types/common/accordion/accordion.types.d.ts +17 -2
- package/dist/cjs-types/common/actionButtons/actionButtons.types.d.ts +7 -1
- package/dist/cjs-types/common/actionIcon/actionIcon.d.ts +1 -1
- package/dist/cjs-types/common/actionIcon/actionIcon.types.d.ts +7 -9
- package/dist/cjs-types/common/alert/alert.types.d.ts +6 -8
- package/dist/cjs-types/common/animatedLogo/animatedLogo.types.d.ts +3 -2
- package/dist/cjs-types/common/badge/badge.types.d.ts +10 -6
- package/dist/cjs-types/common/button/button.types.d.ts +14 -4
- package/dist/cjs-types/common/calendar/calendar.types.d.ts +25 -10
- package/dist/cjs-types/common/calendar/components/agendaList/agendaList.d.ts +1 -1
- package/dist/cjs-types/common/calendar/components/agendaList/agendaList.types.d.ts +3 -0
- package/dist/cjs-types/common/calendar/components/calendarHeader/calendarHeader.d.ts +1 -1
- package/dist/cjs-types/common/calendar/components/calendarHeader/calendarHeader.types.d.ts +2 -0
- package/dist/cjs-types/common/calendar/components/compactMonth/compactMonth.d.ts +1 -1
- package/dist/cjs-types/common/calendar/components/monthView/monthView.d.ts +1 -1
- package/dist/cjs-types/common/calendar/components/monthView/monthView.types.d.ts +3 -2
- package/dist/cjs-types/common/calendar/components/timeGrid/timeGrid.d.ts +1 -1
- package/dist/cjs-types/common/calendar/components/timeGrid/timeGrid.types.d.ts +9 -1
- package/dist/cjs-types/common/calendar/dates.d.ts +21 -5
- package/dist/cjs-types/common/calendar/format.d.ts +3 -2
- package/dist/cjs-types/common/calendar/layout.d.ts +5 -0
- package/dist/cjs-types/common/calendar/useNow.d.ts +4 -0
- package/dist/cjs-types/common/calendar/view.types.d.ts +9 -2
- package/dist/cjs-types/common/card/card.types.d.ts +16 -2
- package/dist/cjs-types/common/chip/chip.types.d.ts +10 -5
- package/dist/cjs-types/common/copyButton/copyButton.types.d.ts +5 -4
- package/dist/cjs-types/common/fab/components/fabBase/fabBase.d.ts +1 -1
- package/dist/cjs-types/common/fab/components/fabBase/fabBase.types.d.ts +2 -1
- package/dist/cjs-types/common/progressBar/progressBar.d.ts +0 -1
- package/dist/cjs-types/common/progressBar/progressBar.types.d.ts +3 -1
- package/dist/cjs-types/common/splitButton/splitButton.types.d.ts +4 -1
- package/dist/cjs-types/common/styles/tone.d.ts +11 -0
- package/dist/cjs-types/common/themeProvider/color.types.d.ts +20 -0
- package/dist/cjs-types/common/themeProvider/index.d.ts +2 -0
- package/dist/cjs-types/common/themeProvider/theme.types.d.ts +3 -6
- package/dist/cjs-types/common/timeline/timeline.types.d.ts +3 -10
- package/dist/cjs-types/common/toast/index.d.ts +1 -1
- package/dist/cjs-types/common/toast/toast.types.d.ts +7 -3
- package/dist/cjs-types/common/types/actions.types.d.ts +1 -1
- package/dist/cjs-types/common/utils/dismissClick.d.ts +4 -0
- package/dist/cjs-types/common/utils/isDev.d.ts +1 -0
- package/dist/esm/common/accordion/accordion.mjs +1 -1
- package/dist/esm/common/accordion/accordion.mjs.map +1 -1
- package/dist/esm/common/accordion/accordion.module.mjs +1 -1
- package/dist/esm/common/accordion/accordion.module.mjs.map +1 -1
- package/dist/esm/common/accordion/accordion.types.mjs +1 -1
- package/dist/esm/common/accordion/accordion.types.mjs.map +1 -1
- package/dist/esm/common/actionButtons/actionButtons.mjs +1 -1
- package/dist/esm/common/actionButtons/actionButtons.mjs.map +1 -1
- package/dist/esm/common/actionIcon/actionIcon.mjs +1 -1
- package/dist/esm/common/actionIcon/actionIcon.mjs.map +1 -1
- package/dist/esm/common/actionIcon/actionIcon.module.mjs +1 -1
- package/dist/esm/common/actionIcon/actionIcon.module.mjs.map +1 -1
- package/dist/esm/common/alert/alert.mjs +1 -1
- package/dist/esm/common/alert/alert.mjs.map +1 -1
- package/dist/esm/common/alert/alert.module.mjs +1 -1
- package/dist/esm/common/alert/alert.module.mjs.map +1 -1
- package/dist/esm/common/animatedLogo/animatedLogo.mjs +1 -1
- package/dist/esm/common/animatedLogo/animatedLogo.mjs.map +1 -1
- package/dist/esm/common/avatar/avatar.mjs +1 -1
- package/dist/esm/common/avatar/avatar.mjs.map +1 -1
- package/dist/esm/common/badge/badge.mjs +1 -1
- package/dist/esm/common/badge/badge.mjs.map +1 -1
- package/dist/esm/common/badge/badge.module.mjs +1 -1
- package/dist/esm/common/badge/badge.module.mjs.map +1 -1
- package/dist/esm/common/badge/badge.types.mjs +1 -1
- package/dist/esm/common/badge/badge.types.mjs.map +1 -1
- package/dist/esm/common/bodyEnd/bodyEnd.mjs +1 -1
- package/dist/esm/common/bodyEnd/bodyEnd.mjs.map +1 -1
- package/dist/esm/common/breadcrumb/breadcrumb.mjs +1 -1
- package/dist/esm/common/breadcrumb/breadcrumb.mjs.map +1 -1
- package/dist/esm/common/breadcrumb/breadcrumb.module.mjs.map +1 -1
- package/dist/esm/common/button/button.mjs +1 -1
- package/dist/esm/common/button/button.mjs.map +1 -1
- package/dist/esm/common/button/button.module.mjs +1 -1
- package/dist/esm/common/button/button.module.mjs.map +1 -1
- package/dist/esm/common/button/button.types.mjs +1 -1
- package/dist/esm/common/button/button.types.mjs.map +1 -1
- package/dist/esm/common/calendar/calendar.mjs +1 -1
- package/dist/esm/common/calendar/calendar.mjs.map +1 -1
- package/dist/esm/common/calendar/calendar.module.mjs.map +1 -1
- package/dist/esm/common/calendar/calendar.types.mjs.map +1 -1
- package/dist/esm/common/calendar/components/agendaList/agendaList.mjs +1 -1
- package/dist/esm/common/calendar/components/agendaList/agendaList.mjs.map +1 -1
- package/dist/esm/common/calendar/components/agendaList/agendaList.module.mjs.map +1 -1
- package/dist/esm/common/calendar/components/calendarHeader/calendarHeader.mjs +1 -1
- package/dist/esm/common/calendar/components/calendarHeader/calendarHeader.mjs.map +1 -1
- package/dist/esm/common/calendar/components/calendarHeader/calendarHeader.module.mjs +1 -1
- package/dist/esm/common/calendar/components/calendarHeader/calendarHeader.module.mjs.map +1 -1
- package/dist/esm/common/calendar/components/compactMonth/compactMonth.mjs +1 -1
- package/dist/esm/common/calendar/components/compactMonth/compactMonth.mjs.map +1 -1
- package/dist/esm/common/calendar/components/compactMonth/compactMonth.module.mjs +1 -1
- package/dist/esm/common/calendar/components/compactMonth/compactMonth.module.mjs.map +1 -1
- package/dist/esm/common/calendar/components/monthView/monthView.mjs +1 -1
- package/dist/esm/common/calendar/components/monthView/monthView.mjs.map +1 -1
- package/dist/esm/common/calendar/components/monthView/monthView.module.mjs +1 -1
- package/dist/esm/common/calendar/components/monthView/monthView.module.mjs.map +1 -1
- package/dist/esm/common/calendar/components/timeGrid/timeGrid.mjs +1 -1
- package/dist/esm/common/calendar/components/timeGrid/timeGrid.mjs.map +1 -1
- package/dist/esm/common/calendar/components/timeGrid/timeGrid.module.mjs +1 -1
- package/dist/esm/common/calendar/components/timeGrid/timeGrid.module.mjs.map +1 -1
- package/dist/esm/common/calendar/dates.mjs +1 -1
- package/dist/esm/common/calendar/dates.mjs.map +1 -1
- package/dist/esm/common/calendar/format.mjs +1 -1
- package/dist/esm/common/calendar/format.mjs.map +1 -1
- package/dist/esm/common/calendar/layout.mjs +1 -1
- package/dist/esm/common/calendar/layout.mjs.map +1 -1
- package/dist/esm/common/calendar/useNow.mjs +2 -0
- package/dist/esm/common/calendar/useNow.mjs.map +1 -0
- package/dist/esm/common/card/Card.mjs +1 -1
- package/dist/esm/common/card/Card.mjs.map +1 -1
- package/dist/esm/common/card/CardActions.mjs +1 -1
- package/dist/esm/common/card/CardActions.mjs.map +1 -1
- package/dist/esm/common/card/CardHeader.mjs.map +1 -1
- package/dist/esm/common/card/card.module.mjs +1 -1
- package/dist/esm/common/card/card.module.mjs.map +1 -1
- package/dist/esm/common/card/card.types.mjs +1 -1
- package/dist/esm/common/card/card.types.mjs.map +1 -1
- package/dist/esm/common/carousel/carousel.mjs +1 -1
- package/dist/esm/common/carousel/carousel.mjs.map +1 -1
- package/dist/esm/common/carousel/carousel.module.mjs.map +1 -1
- package/dist/esm/common/chip/chip.mjs +1 -1
- package/dist/esm/common/chip/chip.mjs.map +1 -1
- package/dist/esm/common/chip/chip.module.mjs +1 -1
- package/dist/esm/common/chip/chip.module.mjs.map +1 -1
- package/dist/esm/common/chip/chip.types.mjs +1 -1
- package/dist/esm/common/chip/chip.types.mjs.map +1 -1
- package/dist/esm/common/colorPicker/colorPicker.mjs +1 -1
- package/dist/esm/common/colorPicker/colorPicker.mjs.map +1 -1
- package/dist/esm/common/colorPicker/colorPicker.module.mjs.map +1 -1
- package/dist/esm/common/confirmModal/confirmModal.mjs +1 -1
- package/dist/esm/common/confirmModal/confirmModal.mjs.map +1 -1
- package/dist/esm/common/copyButton/copyButton.mjs +1 -1
- package/dist/esm/common/copyButton/copyButton.mjs.map +1 -1
- package/dist/esm/common/copyButton/copyButton.module.mjs +1 -1
- package/dist/esm/common/copyButton/copyButton.module.mjs.map +1 -1
- package/dist/esm/common/errorBoundary/errorBoundary.mjs +2 -2
- package/dist/esm/common/errorBoundary/errorBoundary.mjs.map +1 -1
- package/dist/esm/common/fab/components/fabBase/fabBase.mjs +1 -1
- package/dist/esm/common/fab/components/fabBase/fabBase.mjs.map +1 -1
- package/dist/esm/common/fab/fab.mjs +1 -1
- package/dist/esm/common/fab/fab.mjs.map +1 -1
- package/dist/esm/common/flip/flip.mjs +1 -1
- package/dist/esm/common/flip/flip.mjs.map +1 -1
- package/dist/esm/common/klipyPicker/klipyPicker.mjs +1 -1
- package/dist/esm/common/klipyPicker/klipyPicker.mjs.map +1 -1
- package/dist/esm/common/modal/modal.mjs +1 -1
- package/dist/esm/common/modal/modal.mjs.map +1 -1
- package/dist/esm/common/modal/modal.module.mjs.map +1 -1
- package/dist/esm/common/numberInput/numberInput.mjs +1 -1
- package/dist/esm/common/numberInput/numberInput.mjs.map +1 -1
- package/dist/esm/common/numberInput/numberInput.module.mjs.map +1 -1
- package/dist/esm/common/popover/popover.mjs +1 -1
- package/dist/esm/common/popover/popover.mjs.map +1 -1
- package/dist/esm/common/progressBar/progressBar.mjs +1 -1
- package/dist/esm/common/progressBar/progressBar.mjs.map +1 -1
- package/dist/esm/common/progressBar/progressBar.module.mjs +1 -1
- package/dist/esm/common/progressBar/progressBar.module.mjs.map +1 -1
- package/dist/esm/common/roomDrawer/roomDrawer.mjs +1 -1
- package/dist/esm/common/roomDrawer/roomDrawer.mjs.map +1 -1
- package/dist/esm/common/roomDrawer/roomDrawer.module.mjs.map +1 -1
- package/dist/esm/common/sectionHeader/sectionHeader.mjs.map +1 -1
- package/dist/esm/common/splitButton/splitButton.mjs +1 -1
- package/dist/esm/common/splitButton/splitButton.mjs.map +1 -1
- package/dist/esm/common/styles/tone.mjs +4 -0
- package/dist/esm/common/styles/tone.mjs.map +1 -0
- package/dist/esm/common/styles/tone.module.mjs +2 -0
- package/dist/esm/common/styles/tone.module.mjs.map +1 -0
- package/dist/esm/common/themeProvider/color.types.mjs +2 -0
- package/dist/esm/common/themeProvider/color.types.mjs.map +1 -0
- package/dist/esm/common/themeProvider/defaultTheme.mjs +1 -1
- package/dist/esm/common/themeProvider/defaultTheme.mjs.map +1 -1
- package/dist/esm/common/tilt/tilt.mjs +1 -1
- package/dist/esm/common/tilt/tilt.mjs.map +1 -1
- package/dist/esm/common/timeInput/timeInput.mjs +1 -1
- package/dist/esm/common/timeInput/timeInput.mjs.map +1 -1
- package/dist/esm/common/timeline/timeline.mjs +1 -1
- package/dist/esm/common/timeline/timeline.mjs.map +1 -1
- package/dist/esm/common/timeline/timeline.module.mjs +1 -1
- package/dist/esm/common/timeline/timeline.module.mjs.map +1 -1
- package/dist/esm/common/timeline/timeline.types.mjs +1 -1
- package/dist/esm/common/timeline/timeline.types.mjs.map +1 -1
- package/dist/esm/common/timer/timer.mjs +1 -1
- package/dist/esm/common/timer/timer.mjs.map +1 -1
- package/dist/esm/common/timer/timer.module.mjs +1 -1
- package/dist/esm/common/timer/timer.module.mjs.map +1 -1
- package/dist/esm/common/toast/toast.mjs +1 -1
- package/dist/esm/common/toast/toast.mjs.map +1 -1
- package/dist/esm/common/toast/toast.module.mjs +1 -1
- package/dist/esm/common/toast/toast.module.mjs.map +1 -1
- package/dist/esm/common/toast/toastHost.mjs +1 -1
- package/dist/esm/common/toast/toastHost.mjs.map +1 -1
- package/dist/esm/common/utils/dismissClick.mjs +2 -0
- package/dist/esm/common/utils/dismissClick.mjs.map +1 -0
- package/dist/esm/common/utils/isDev.mjs +2 -0
- package/dist/esm/common/utils/isDev.mjs.map +1 -0
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/services/formValidation/FormValidatorGroupWithForm.mjs +1 -1
- package/dist/esm/services/formValidation/FormValidatorGroupWithForm.mjs.map +1 -1
- package/dist/index.cjs +5 -3
- package/dist/index.cjs.map +1 -1
- package/dist/style.css +1 -1
- package/dist/types/common/accordion/accordion.types.d.ts +17 -2
- package/dist/types/common/actionButtons/actionButtons.types.d.ts +7 -1
- package/dist/types/common/actionIcon/actionIcon.d.ts +1 -1
- package/dist/types/common/actionIcon/actionIcon.types.d.ts +7 -9
- package/dist/types/common/alert/alert.types.d.ts +6 -8
- package/dist/types/common/animatedLogo/animatedLogo.types.d.ts +3 -2
- package/dist/types/common/badge/badge.types.d.ts +10 -6
- package/dist/types/common/button/button.types.d.ts +14 -4
- package/dist/types/common/calendar/calendar.types.d.ts +25 -10
- package/dist/types/common/calendar/components/agendaList/agendaList.d.ts +1 -1
- package/dist/types/common/calendar/components/agendaList/agendaList.types.d.ts +3 -0
- package/dist/types/common/calendar/components/calendarHeader/calendarHeader.d.ts +1 -1
- package/dist/types/common/calendar/components/calendarHeader/calendarHeader.types.d.ts +2 -0
- package/dist/types/common/calendar/components/compactMonth/compactMonth.d.ts +1 -1
- package/dist/types/common/calendar/components/monthView/monthView.d.ts +1 -1
- package/dist/types/common/calendar/components/monthView/monthView.types.d.ts +3 -2
- package/dist/types/common/calendar/components/timeGrid/timeGrid.d.ts +1 -1
- package/dist/types/common/calendar/components/timeGrid/timeGrid.types.d.ts +9 -1
- package/dist/types/common/calendar/dates.d.ts +21 -5
- package/dist/types/common/calendar/format.d.ts +3 -2
- package/dist/types/common/calendar/layout.d.ts +5 -0
- package/dist/types/common/calendar/useNow.d.ts +4 -0
- package/dist/types/common/calendar/view.types.d.ts +9 -2
- package/dist/types/common/card/card.types.d.ts +16 -2
- package/dist/types/common/chip/chip.types.d.ts +10 -5
- package/dist/types/common/copyButton/copyButton.types.d.ts +5 -4
- package/dist/types/common/fab/components/fabBase/fabBase.d.ts +1 -1
- package/dist/types/common/fab/components/fabBase/fabBase.types.d.ts +2 -1
- package/dist/types/common/progressBar/progressBar.d.ts +0 -1
- package/dist/types/common/progressBar/progressBar.types.d.ts +3 -1
- package/dist/types/common/splitButton/splitButton.types.d.ts +4 -1
- package/dist/types/common/styles/tone.d.ts +11 -0
- package/dist/types/common/themeProvider/color.types.d.ts +20 -0
- package/dist/types/common/themeProvider/index.d.ts +2 -0
- package/dist/types/common/themeProvider/theme.types.d.ts +3 -6
- package/dist/types/common/timeline/timeline.types.d.ts +3 -10
- package/dist/types/common/toast/index.d.ts +1 -1
- package/dist/types/common/toast/toast.types.d.ts +7 -3
- package/dist/types/common/types/actions.types.d.ts +1 -1
- package/dist/types/common/utils/dismissClick.d.ts +4 -0
- package/dist/types/common/utils/isDev.d.ts +1 -0
- package/docs/Accordion.md +74 -5
- package/docs/ActionButtons.md +6 -3
- package/docs/ActionIcon.md +39 -14
- package/docs/Alert.md +27 -17
- package/docs/AnimatedLogo.md +1 -1
- package/docs/Badge.md +24 -7
- package/docs/Button.md +98 -40
- package/docs/ButtonGroup.md +18 -18
- package/docs/CLAUDE.md +21 -11
- package/docs/Calendar.md +35 -17
- package/docs/Card.md +53 -14
- package/docs/Chip.md +24 -9
- package/docs/ConfigProvider.md +3 -3
- package/docs/CopyButton.md +6 -5
- package/docs/ProgressBar.md +7 -4
- package/docs/SectionHeader.md +1 -1
- package/docs/SplitButton.md +6 -5
- package/docs/ThemeColor.md +103 -0
- package/docs/ThemeProvider.md +5 -5
- package/docs/Timeline.md +18 -9
- package/docs/Toast.md +25 -11
- package/package.json +3 -2
- package/dist/esm/common/accordion/accordion.plain.module.mjs +0 -2
- package/dist/esm/common/accordion/accordion.plain.module.mjs.map +0 -1
- package/dist/esm/common/accordion/accordion.primary.module.mjs +0 -2
- package/dist/esm/common/accordion/accordion.primary.module.mjs.map +0 -1
- package/dist/esm/common/alert/alert.types.mjs +0 -2
- package/dist/esm/common/alert/alert.types.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.mjs","names":[],"sources":["../../../../package/common/calendar/layout.ts"],"sourcesContent":["import type { CalendarEvent } from './calendar.types';\nimport { addDays, dayDiff, MINUTES_PER_DAY, minutesOfDay, startOfDay } from './dates';\n\nconst DAY_MS = 86_400_000;\n\n/**\n * Below this an event has no room for a line of text at the default hour height. It is drawn as a\n * bar of its real length with its label beneath, and packed with room for that label.\n */\nexport const BRIEF_EVENT_MINUTES = 15;\n/** The label's line (`--label` in timeGrid.module.pcss) at the default 48px hour: 15px. */\nconst BRIEF_LABEL_MINUTES = 20;\n\n/** `end`, clamped so an event that ends before it starts is treated as having no length. */\nexport function eventEnd(event: CalendarEvent): Date {\n return event.end < event.start ? event.start : event.end;\n}\n\n/** Drawn in the all-day row rather than the time grid. */\nexport function isAllDayLike(event: CalendarEvent): boolean {\n return Boolean(event.allDay) || eventEnd(event).getTime() - event.start.getTime() >= DAY_MS;\n}\n\n/** First and last day (both midnight, both inclusive) the event appears on. */\nexport function eventDays(event: CalendarEvent): { first: Date; last: Date } {\n const first = startOfDay(event.start);\n const end = eventEnd(event);\n if (event.allDay) {\n // `end` is exclusive, but an all-day event ending on its own start day still takes that day.\n const endDay = startOfDay(end);\n return { first, last: dayDiff(first, endDay) >= 1 ? addDays(endDay, -1) : first };\n }\n // One millisecond back, so a timed event ending at midnight does not appear on the next day.\n const last = end > event.start ? startOfDay(new Date(end.getTime() - 1)) : first;\n return { first, last };\n}\n\n/** All-day events first, then by start, then the longer first, so a day reads the same everywhere. */\nexport function compareEvents(a: CalendarEvent, b: CalendarEvent): number {\n const allDay = Number(isAllDayLike(b)) - Number(isAllDayLike(a));\n if (allDay !== 0) return allDay;\n const start = a.start.getTime() - b.start.getTime();\n if (start !== 0) return start;\n const length = eventEnd(b).getTime() - eventEnd(a).getTime();\n if (length !== 0) return length;\n return a.title.localeCompare(b.title);\n}\n\n/** The events on each of `dates`, sorted with `compareEvents`. */\nexport function eventsByDay<E extends CalendarEvent>(events: readonly E[], dates: readonly Date[]): E[][] {\n const result: E[][] = dates.map(() => []);\n for (const event of events) {\n const { first, last } = eventDays(event);\n dates.forEach((day, i) => {\n if (dayDiff(first, day) >= 0 && dayDiff(day, last) >= 0) result[i].push(event);\n });\n }\n for (const day of result) day.sort(compareEvents);\n return result;\n}\n\nexport interface TimedBox<E extends CalendarEvent = CalendarEvent> {\n event: E;\n /** Wall-clock minutes from the column's midnight. */\n top: number;\n bottom: number;\n /** Where the next event in its column may start: below the label of a brief event. */\n reach: number;\n /** Left edge, as a column of `columns`. */\n column: number;\n columns: number;\n /** Columns it can widen into to its right without covering another event. */\n span: number;\n continuesBefore: boolean;\n continuesAfter: boolean;\n}\n\n/**\n * Lays out one day column of the time grid: events that overlap share the width in columns, and\n * each one widens right into columns that are free for its whole height.\n *\n * Positions are wall-clock minutes, never milliseconds from midnight. Drawing and packing have\n * to agree on that: on a 25-hour day two events in the repeated hour occupy the same rows, and\n * packing them by real time would put them in one column, drawn over each other.\n */\nexport function packDay<E extends CalendarEvent>(events: readonly E[], day: Date): TimedBox<E>[] {\n const dayStart = startOfDay(day);\n const next = addDays(dayStart, 1);\n\n const boxes: TimedBox<E>[] = [];\n for (const event of events) {\n if (isAllDayLike(event)) continue;\n const { start } = event;\n const end = eventEnd(event);\n if (start >= next) continue;\n // A zero-length event at midnight belongs to the day it starts on.\n if (end <= dayStart && start < dayStart) continue;\n\n const continuesBefore = start < dayStart;\n const continuesAfter = end > next;\n const top = continuesBefore ? 0 : minutesOfDay(start);\n // Never upside down: on the day the clocks go back, an event can end on an earlier clock time.\n const bottom = Math.max(end >= next ? MINUTES_PER_DAY : minutesOfDay(end), top);\n const reach = bottom - top < BRIEF_EVENT_MINUTES ? Math.min(bottom + BRIEF_LABEL_MINUTES, MINUTES_PER_DAY) : bottom;\n boxes.push({ event, top, bottom, reach, column: 0, columns: 1, span: 1, continuesBefore, continuesAfter });\n }\n\n boxes.sort((a, b) => a.top - b.top || b.reach - a.reach);\n\n let cluster: TimedBox<E>[] = [];\n let clusterEnd = -1;\n for (const box of boxes) {\n if (cluster.length > 0 && box.top >= clusterEnd) {\n packCluster(cluster);\n cluster = [];\n }\n cluster.push(box);\n clusterEnd = Math.max(clusterEnd, box.reach);\n }\n if (cluster.length > 0) packCluster(cluster);\n\n return boxes;\n}\n\nfunction packCluster(cluster: TimedBox[]): void {\n const columnBottoms: number[] = [];\n for (const box of cluster) {\n let column = columnBottoms.findIndex((bottom) => bottom <= box.top);\n if (column === -1) column = columnBottoms.push(0) - 1;\n box.column = column;\n columnBottoms[column] = box.reach;\n }\n const columns = columnBottoms.length;\n for (const box of cluster) {\n box.columns = columns;\n let span = 1;\n for (let column = box.column + 1; column < columns; column++) {\n const blocked = cluster.some(\n (other) => other.column === column && other.top < box.reach && other.reach > box.top,\n );\n if (blocked) break;\n span++;\n }\n box.span = span;\n }\n}\n\nexport interface LaneBar<E extends CalendarEvent = CalendarEvent> {\n event: E;\n /** First column of the row it covers, 0-based. */\n start: number;\n /** Columns it covers within the row. */\n span: number;\n lane: number;\n /** It starts before its first column: in an earlier row, or on a hidden day. */\n continuesBefore: boolean;\n continuesAfter: boolean;\n}\n\n/**\n * Stacks the events of one row of days into lanes, as the month view and the all-day row draw\n * them: longer bars first, so a multi-day event keeps one lane across the week. `dates` are the\n * row's columns, so a hidden day between two of them is simply not drawn.\n */\nexport function packLanes<E extends CalendarEvent>(\n events: readonly E[],\n dates: readonly Date[],\n include: (event: E) => boolean = () => true,\n): LaneBar<E>[] {\n const bars: LaneBar<E>[] = [];\n for (const event of events) {\n if (!include(event)) continue;\n const { first, last } = eventDays(event);\n const start = dates.findIndex((day) => dayDiff(first, day) >= 0 && dayDiff(day, last) >= 0);\n if (start === -1) continue;\n let end = start;\n while (end + 1 < dates.length && dayDiff(dates[end + 1], last) >= 0) end++;\n bars.push({\n event,\n start,\n span: end - start + 1,\n lane: 0,\n continuesBefore: dayDiff(first, dates[start]) > 0,\n continuesAfter: dayDiff(dates[end], last) > 0,\n });\n }\n\n bars.sort((a, b) => a.start - b.start || b.span - a.span || compareEvents(a.event, b.event));\n\n const laneEnds: number[] = [];\n for (const bar of bars) {\n let lane = laneEnds.findIndex((end) => end <= bar.start);\n if (lane === -1) lane = laneEnds.push(0) - 1;\n bar.lane = lane;\n laneEnds[lane] = bar.start + bar.span;\n }\n return bars;\n}\n\nexport interface LimitedLanes<E extends CalendarEvent = CalendarEvent> {\n visible: LaneBar<E>[];\n /** Lane the `+N` buttons go in, on the days that have one. */\n moreLane: number;\n /** Events hidden on each day of the row. */\n hidden: number[];\n}\n\n/**\n * Fits the bars into `capacity` lanes. A day that needs more gives its last lane to a `+N`\n * button; a day that does not keeps every bar. Decided per day, so one crowded day does not\n * hide events on the quiet days next to it. A bar crossing into a crowded day's `+N` lane is\n * hidden along its whole length and counted on each day it covers.\n */\nexport function limitLanes<E extends CalendarEvent>(\n bars: LaneBar<E>[],\n days: number,\n capacity: number,\n): LimitedLanes<E> {\n const moreLane = Math.max(capacity - 1, 0);\n const lanesPerDay = Array.from({ length: days }, () => 0);\n for (const bar of bars) {\n for (let day = bar.start; day < bar.start + bar.span; day++) {\n lanesPerDay[day] = Math.max(lanesPerDay[day], bar.lane + 1);\n }\n }\n\n const hidden = Array.from({ length: days }, () => 0);\n const visible: LaneBar<E>[] = [];\n for (const bar of bars) {\n let fits = bar.lane < moreLane;\n if (!fits && bar.lane === moreLane) {\n fits = true;\n for (let day = bar.start; day < bar.start + bar.span; day++) {\n if (lanesPerDay[day] > capacity) fits = false;\n }\n }\n if (fits) {\n visible.push(bar);\n continue;\n }\n for (let day = bar.start; day < bar.start + bar.span; day++) hidden[day]++;\n }\n return { visible, moreLane, hidden };\n}\n"],"mappings":"uHAGA,IAAM,EAAS,MAQT,EAAsB,GAG5B,SAAgB,EAAS,EAA4B,CACnD,OAAO,EAAM,IAAM,EAAM,MAAQ,EAAM,MAAQ,EAAM,GACvD,CAGA,SAAgB,EAAa,EAA+B,CAC1D,MAAO,EAAQ,EAAM,QAAW,EAAS,CAAK,CAAC,CAAC,QAAQ,EAAI,EAAM,MAAM,QAAQ,GAAK,CACvF,CAGA,SAAgB,EAAU,EAAmD,CAC3E,IAAM,EAAQ,EAAW,EAAM,KAAK,EAC9B,EAAM,EAAS,CAAK,EAC1B,GAAI,EAAM,OAAQ,CAEhB,IAAM,EAAS,EAAW,CAAG,EAC7B,MAAO,CAAE,QAAO,KAAM,EAAQ,EAAO,CAAM,GAAK,EAAI,EAAQ,EAAQ,EAAE,EAAI,CAAM,CAClF,CAGA,MAAO,CAAE,QAAO,KADH,EAAM,EAAM,MAAQ,EAAW,IAAI,KAAK,EAAI,QAAQ,EAAI,CAAC,CAAC,EAAI,CACtD,CACvB,CAGA,SAAgB,EAAc,EAAkB,EAA0B,CACxE,IAAM,EAAS,OAAO,EAAa,CAAC,CAAC,EAAI,OAAO,EAAa,CAAC,CAAC,EAC/D,GAAI,IAAW,EAAG,OAAO,EACzB,IAAM,EAAQ,EAAE,MAAM,QAAQ,EAAI,EAAE,MAAM,QAAQ,EAClD,GAAI,IAAU,EAAG,OAAO,EACxB,IAAM,EAAS,EAAS,CAAC,CAAC,CAAC,QAAQ,EAAI,EAAS,CAAC,CAAC,CAAC,QAAQ,EAE3D,OADI,IAAW,EACR,EAAE,MAAM,cAAc,EAAE,KAAK,EADX,CAE3B,CAGA,SAAgB,EAAqC,EAAsB,EAA+B,CACxG,IAAM,EAAgB,EAAM,QAAU,CAAC,CAAC,EACxC,IAAK,IAAM,KAAS,EAAQ,CAC1B,GAAM,CAAE,QAAO,QAAS,EAAU,CAAK,EACvC,EAAM,SAAS,EAAK,IAAM,CACpB,EAAQ,EAAO,CAAG,GAAK,GAAK,EAAQ,EAAK,CAAI,GAAK,GAAG,EAAO,EAAE,CAAC,KAAK,CAAK,CAC/E,CAAC,CACH,CACA,IAAK,IAAM,KAAO,EAAQ,EAAI,KAAK,CAAa,EAChD,OAAO,CACT,CA0BA,SAAgB,EAAiC,EAAsB,EAA0B,CAC/F,IAAM,EAAW,EAAW,CAAG,EACzB,EAAO,EAAQ,EAAU,CAAC,EAE1B,EAAuB,CAAC,EAC9B,IAAK,IAAM,KAAS,EAAQ,CAC1B,GAAI,EAAa,CAAK,EAAG,SACzB,GAAM,CAAE,SAAU,EACZ,EAAM,EAAS,CAAK,EAG1B,GAFI,GAAS,GAET,GAAO,GAAY,EAAQ,EAAU,SAEzC,IAAM,EAAkB,EAAQ,EAC1B,EAAiB,EAAM,EACvB,EAAM,EAAkB,EAAI,EAAa,CAAK,EAE9C,EAAS,KAAK,IAAI,GAAO,EAAO,EAAkB,EAAa,CAAG,EAAG,CAAG,EACxE,EAAQ,EAAS,EAAA,GAA4B,KAAK,IAAI,EAAS,EAAqB,CAAe,EAAI,EAC7G,EAAM,KAAK,CAAE,QAAO,MAAK,SAAQ,QAAO,OAAQ,EAAG,QAAS,EAAG,KAAM,EAAG,kBAAiB,gBAAe,CAAC,CAC3G,CAEA,EAAM,MAAM,EAAG,IAAM,EAAE,IAAM,EAAE,KAAO,EAAE,MAAQ,EAAE,KAAK,EAEvD,IAAI,EAAyB,CAAC,EAC1B,EAAa,GACjB,IAAK,IAAM,KAAO,EACZ,EAAQ,OAAS,GAAK,EAAI,KAAO,IACnC,EAAY,CAAO,EACnB,EAAU,CAAC,GAEb,EAAQ,KAAK,CAAG,EAChB,EAAa,KAAK,IAAI,EAAY,EAAI,KAAK,EAI7C,OAFI,EAAQ,OAAS,GAAG,EAAY,CAAO,EAEpC,CACT,CAEA,SAAS,EAAY,EAA2B,CAC9C,IAAM,EAA0B,CAAC,EACjC,IAAK,IAAM,KAAO,EAAS,CACzB,IAAI,EAAS,EAAc,UAAW,GAAW,GAAU,EAAI,GAAG,EAC9D,IAAW,KAAI,EAAS,EAAc,KAAK,CAAC,EAAI,GACpD,EAAI,OAAS,EACb,EAAc,GAAU,EAAI,KAC9B,CACA,IAAM,EAAU,EAAc,OAC9B,IAAK,IAAM,KAAO,EAAS,CACzB,EAAI,QAAU,EACd,IAAI,EAAO,EACX,IAAK,IAAI,EAAS,EAAI,OAAS,EAAG,EAAS,GACzB,GAAQ,KACrB,GAAU,EAAM,SAAW,GAAU,EAAM,IAAM,EAAI,OAAS,EAAM,MAAQ,EAAI,GAE/E,EAJ8C,IAKlD,IAEF,EAAI,KAAO,CACb,CACF,CAmBA,SAAgB,EACd,EACA,EACA,MAAuC,GACzB,CACd,IAAM,EAAqB,CAAC,EAC5B,IAAK,IAAM,KAAS,EAAQ,CAC1B,GAAI,CAAC,EAAQ,CAAK,EAAG,SACrB,GAAM,CAAE,QAAO,QAAS,EAAU,CAAK,EACjC,EAAQ,EAAM,UAAW,GAAQ,EAAQ,EAAO,CAAG,GAAK,GAAK,EAAQ,EAAK,CAAI,GAAK,CAAC,EAC1F,GAAI,IAAU,GAAI,SAClB,IAAI,EAAM,EACV,KAAO,EAAM,EAAI,EAAM,QAAU,EAAQ,EAAM,EAAM,GAAI,CAAI,GAAK,GAAG,IACrE,EAAK,KAAK,CACR,QACA,QACA,KAAM,EAAM,EAAQ,EACpB,KAAM,EACN,gBAAiB,EAAQ,EAAO,EAAM,EAAM,EAAI,EAChD,eAAgB,EAAQ,EAAM,GAAM,CAAI,EAAI,CAC9C,CAAC,CACH,CAEA,EAAK,MAAM,EAAG,IAAM,EAAE,MAAQ,EAAE,OAAS,EAAE,KAAO,EAAE,MAAQ,EAAc,EAAE,MAAO,EAAE,KAAK,CAAC,EAE3F,IAAM,EAAqB,CAAC,EAC5B,IAAK,IAAM,KAAO,EAAM,CACtB,IAAI,EAAO,EAAS,UAAW,GAAQ,GAAO,EAAI,KAAK,EACnD,IAAS,KAAI,EAAO,EAAS,KAAK,CAAC,EAAI,GAC3C,EAAI,KAAO,EACX,EAAS,GAAQ,EAAI,MAAQ,EAAI,IACnC,CACA,OAAO,CACT,CAgBA,SAAgB,EACd,EACA,EACA,EACiB,CACjB,IAAM,EAAW,KAAK,IAAI,EAAW,EAAG,CAAC,EACnC,EAAc,MAAM,KAAK,CAAE,OAAQ,CAAK,MAAS,CAAC,EACxD,IAAK,IAAM,KAAO,EAChB,IAAK,IAAI,EAAM,EAAI,MAAO,EAAM,EAAI,MAAQ,EAAI,KAAM,IACpD,EAAY,GAAO,KAAK,IAAI,EAAY,GAAM,EAAI,KAAO,CAAC,EAI9D,IAAM,EAAS,MAAM,KAAK,CAAE,OAAQ,CAAK,MAAS,CAAC,EAC7C,EAAwB,CAAC,EAC/B,IAAK,IAAM,KAAO,EAAM,CACtB,IAAI,EAAO,EAAI,KAAO,EACtB,GAAI,CAAC,GAAQ,EAAI,OAAS,EAAU,CAClC,EAAO,GACP,IAAK,IAAI,EAAM,EAAI,MAAO,EAAM,EAAI,MAAQ,EAAI,KAAM,IAChD,EAAY,GAAO,IAAU,EAAO,GAE5C,CACA,GAAI,EAAM,CACR,EAAQ,KAAK,CAAG,EAChB,QACF,CACA,IAAK,IAAI,EAAM,EAAI,MAAO,EAAM,EAAI,MAAQ,EAAI,KAAM,IAAO,EAAO,EAAI,EAC1E,CACA,MAAO,CAAE,UAAS,WAAU,QAAO,CACrC"}
|
|
1
|
+
{"version":3,"file":"layout.mjs","names":[],"sources":["../../../../package/common/calendar/layout.ts"],"sourcesContent":["import type { CalendarEvent } from './calendar.types';\nimport { addDays, dayDiff, endAfter, MINUTES_PER_DAY, minutesOfDay, shiftDays, startOfDay } from './dates';\n\nconst DAY_MS = 86_400_000;\n\n/**\n * Below this an event has no room for a line of text at the default hour height. It is drawn as a\n * bar of its real length with its label beneath, and packed with room for that label.\n */\nexport const BRIEF_EVENT_MINUTES = 15;\n/** The label's line (`--label` in timeGrid.module.pcss) at the default 48px hour: 15px. */\nconst BRIEF_LABEL_MINUTES = 20;\n\n/** `end`, clamped so an event that ends before it starts is treated as having no length. */\nexport function eventEnd(event: CalendarEvent): Date {\n return event.end < event.start ? event.start : event.end;\n}\n\n/** `event` moved by `days` calendar days, keeping its clock times and its real length. */\nexport function moveByDays(event: CalendarEvent, days: number): { start: Date; end: Date } {\n const start = shiftDays(event.start, days);\n const length = (eventEnd(event).getTime() - event.start.getTime()) / 60_000;\n return { start, end: endAfter(start, shiftDays(eventEnd(event), days), length) };\n}\n\n/** Drawn in the all-day row rather than the time grid. */\nexport function isAllDayLike(event: CalendarEvent): boolean {\n return Boolean(event.allDay) || eventEnd(event).getTime() - event.start.getTime() >= DAY_MS;\n}\n\n/** First and last day (both midnight, both inclusive) the event appears on. */\nexport function eventDays(event: CalendarEvent): { first: Date; last: Date } {\n const first = startOfDay(event.start);\n const end = eventEnd(event);\n if (event.allDay) {\n // `end` is exclusive, but an all-day event ending on its own start day still takes that day.\n const endDay = startOfDay(end);\n return { first, last: dayDiff(first, endDay) >= 1 ? addDays(endDay, -1) : first };\n }\n // One millisecond back, so a timed event ending at midnight does not appear on the next day.\n const last = end > event.start ? startOfDay(new Date(end.getTime() - 1)) : first;\n return { first, last };\n}\n\n/** All-day events first, then by start, then the longer first, so a day reads the same everywhere. */\nexport function compareEvents(a: CalendarEvent, b: CalendarEvent): number {\n const allDay = Number(isAllDayLike(b)) - Number(isAllDayLike(a));\n if (allDay !== 0) return allDay;\n const start = a.start.getTime() - b.start.getTime();\n if (start !== 0) return start;\n const length = eventEnd(b).getTime() - eventEnd(a).getTime();\n if (length !== 0) return length;\n return a.title.localeCompare(b.title);\n}\n\n/** The events on each of `dates`, sorted with `compareEvents`. */\nexport function eventsByDay<E extends CalendarEvent>(events: readonly E[], dates: readonly Date[]): E[][] {\n const result: E[][] = dates.map(() => []);\n for (const event of events) {\n const { first, last } = eventDays(event);\n dates.forEach((day, i) => {\n if (dayDiff(first, day) >= 0 && dayDiff(day, last) >= 0) result[i].push(event);\n });\n }\n for (const day of result) day.sort(compareEvents);\n return result;\n}\n\nexport interface TimedBox<E extends CalendarEvent = CalendarEvent> {\n event: E;\n /** Wall-clock minutes from the column's midnight. */\n top: number;\n bottom: number;\n /** Where the next event in its column may start: below the label of a brief event. */\n reach: number;\n /** Left edge, as a column of `columns`. */\n column: number;\n columns: number;\n /** Columns it can widen into to its right without covering another event. */\n span: number;\n continuesBefore: boolean;\n continuesAfter: boolean;\n}\n\n/**\n * Lays out one day column of the time grid: events that overlap share the width in columns, and\n * each one widens right into columns that are free for its whole height.\n *\n * Positions are wall-clock minutes, never milliseconds from midnight. Drawing and packing have\n * to agree on that: on a 25-hour day two events in the repeated hour occupy the same rows, and\n * packing them by real time would put them in one column, drawn over each other.\n */\nexport function packDay<E extends CalendarEvent>(events: readonly E[], day: Date): TimedBox<E>[] {\n const dayStart = startOfDay(day);\n const next = addDays(dayStart, 1);\n\n const boxes: TimedBox<E>[] = [];\n for (const event of events) {\n if (isAllDayLike(event)) continue;\n const { start } = event;\n const end = eventEnd(event);\n if (start >= next) continue;\n // A zero-length event at midnight belongs to the day it starts on.\n if (end <= dayStart && start < dayStart) continue;\n\n const continuesBefore = start < dayStart;\n const continuesAfter = end > next;\n const top = continuesBefore ? 0 : minutesOfDay(start);\n // Never upside down: on the day the clocks go back, an event can end on an earlier clock time.\n const bottom = Math.max(end >= next ? MINUTES_PER_DAY : minutesOfDay(end), top);\n const reach = bottom - top < BRIEF_EVENT_MINUTES ? Math.min(bottom + BRIEF_LABEL_MINUTES, MINUTES_PER_DAY) : bottom;\n boxes.push({ event, top, bottom, reach, column: 0, columns: 1, span: 1, continuesBefore, continuesAfter });\n }\n\n boxes.sort((a, b) => a.top - b.top || b.reach - a.reach);\n\n let cluster: TimedBox<E>[] = [];\n let clusterEnd = -1;\n for (const box of boxes) {\n if (cluster.length > 0 && box.top >= clusterEnd) {\n packCluster(cluster);\n cluster = [];\n }\n cluster.push(box);\n clusterEnd = Math.max(clusterEnd, box.reach);\n }\n if (cluster.length > 0) packCluster(cluster);\n\n return boxes;\n}\n\nfunction packCluster(cluster: TimedBox[]): void {\n const columnBottoms: number[] = [];\n for (const box of cluster) {\n let column = columnBottoms.findIndex((bottom) => bottom <= box.top);\n if (column === -1) column = columnBottoms.push(0) - 1;\n box.column = column;\n columnBottoms[column] = box.reach;\n }\n const columns = columnBottoms.length;\n for (const box of cluster) {\n box.columns = columns;\n let span = 1;\n for (let column = box.column + 1; column < columns; column++) {\n const blocked = cluster.some(\n (other) => other.column === column && other.top < box.reach && other.reach > box.top,\n );\n if (blocked) break;\n span++;\n }\n box.span = span;\n }\n}\n\nexport interface LaneBar<E extends CalendarEvent = CalendarEvent> {\n event: E;\n /** First column of the row it covers, 0-based. */\n start: number;\n /** Columns it covers within the row. */\n span: number;\n lane: number;\n /** It starts before its first column: in an earlier row, or on a hidden day. */\n continuesBefore: boolean;\n continuesAfter: boolean;\n}\n\n/**\n * Stacks the events of one row of days into lanes, as the month view and the all-day row draw\n * them: longer bars first, so a multi-day event keeps one lane across the week. `dates` are the\n * row's columns, so a hidden day between two of them is simply not drawn.\n */\nexport function packLanes<E extends CalendarEvent>(\n events: readonly E[],\n dates: readonly Date[],\n include: (event: E) => boolean = () => true,\n): LaneBar<E>[] {\n const bars: LaneBar<E>[] = [];\n for (const event of events) {\n if (!include(event)) continue;\n const { first, last } = eventDays(event);\n const start = dates.findIndex((day) => dayDiff(first, day) >= 0 && dayDiff(day, last) >= 0);\n if (start === -1) continue;\n let end = start;\n while (end + 1 < dates.length && dayDiff(dates[end + 1], last) >= 0) end++;\n bars.push({\n event,\n start,\n span: end - start + 1,\n lane: 0,\n continuesBefore: dayDiff(first, dates[start]) > 0,\n continuesAfter: dayDiff(dates[end], last) > 0,\n });\n }\n\n bars.sort((a, b) => a.start - b.start || b.span - a.span || compareEvents(a.event, b.event));\n\n const laneEnds: number[] = [];\n for (const bar of bars) {\n let lane = laneEnds.findIndex((end) => end <= bar.start);\n if (lane === -1) lane = laneEnds.push(0) - 1;\n bar.lane = lane;\n laneEnds[lane] = bar.start + bar.span;\n }\n return bars;\n}\n\nexport interface LimitedLanes<E extends CalendarEvent = CalendarEvent> {\n visible: LaneBar<E>[];\n /** Lane the `+N` buttons go in, on the days that have one. */\n moreLane: number;\n /** Events hidden on each day of the row. */\n hidden: number[];\n}\n\n/**\n * Fits the bars into `capacity` lanes. A day that needs more gives its last lane to a `+N`\n * button; a day that does not keeps every bar. Decided per day, so one crowded day does not\n * hide events on the quiet days next to it. A bar crossing into a crowded day's `+N` lane is\n * hidden along its whole length and counted on each day it covers.\n */\nexport function limitLanes<E extends CalendarEvent>(\n bars: LaneBar<E>[],\n days: number,\n capacity: number,\n): LimitedLanes<E> {\n const moreLane = Math.max(capacity - 1, 0);\n const lanesPerDay = Array.from({ length: days }, () => 0);\n for (const bar of bars) {\n for (let day = bar.start; day < bar.start + bar.span; day++) {\n lanesPerDay[day] = Math.max(lanesPerDay[day], bar.lane + 1);\n }\n }\n\n const hidden = Array.from({ length: days }, () => 0);\n const visible: LaneBar<E>[] = [];\n for (const bar of bars) {\n let fits = bar.lane < moreLane;\n if (!fits && bar.lane === moreLane) {\n fits = true;\n for (let day = bar.start; day < bar.start + bar.span; day++) {\n if (lanesPerDay[day] > capacity) fits = false;\n }\n }\n if (fits) {\n visible.push(bar);\n continue;\n }\n for (let day = bar.start; day < bar.start + bar.span; day++) hidden[day]++;\n }\n return { visible, moreLane, hidden };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";import{isSameDay as e,startOfDay as t}from"./dates.mjs";import{useEffect as n,useState as r}from"react";function i(e){return e?t(new Date):new Date}function a(t){let[a,o]=r(()=>i(t));return n(()=>{let n;function r(){n=setTimeout(()=>{let n=i(t);o(r=>t&&e(r,n)?r:n),r()},6e4-Date.now()%6e4)}return r(),()=>clearTimeout(n)},[t]),a}function o(){return a(!1)}function s(){return a(!0)}export{o as useNow,s as useToday};
|
|
2
|
+
//# sourceMappingURL=useNow.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useNow.mjs","names":[],"sources":["../../../../package/common/calendar/useNow.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\nimport { isSameDay, startOfDay } from './dates';\n\nfunction read(day: boolean): Date {\n return day ? startOfDay(new Date()) : new Date();\n}\n\n/**\n * Checked on each minute boundary rather than once at midnight: a long timer is paused while the\n * device sleeps, and would mark the old day for hours after waking.\n */\nfunction useClock(day: boolean): Date {\n const [now, setNow] = useState(() => read(day));\n useEffect(() => {\n let timer: ReturnType<typeof setTimeout>;\n function schedule() {\n timer = setTimeout(\n () => {\n const next = read(day);\n // The same object while the day lasts, so nothing re-renders for it.\n setNow((previous) => (day && isSameDay(previous, next) ? previous : next));\n schedule();\n },\n 60_000 - (Date.now() % 60_000),\n );\n }\n schedule();\n return () => clearTimeout(timer);\n }, [day]);\n return now;\n}\n\n/** The current time, updated on each minute boundary: it carries the now-line through the day. */\nexport function useNow(): Date {\n return useClock(false);\n}\n\n/** Midnight of today, updated when the day changes: today's mark, for a calendar left open overnight. */\nexport function useToday(): Date {\n return useClock(true);\n}\n"],"mappings":"qHAIA,SAAS,EAAK,EAAoB,CAChC,OAAO,EAAM,EAAW,IAAI,IAAM,EAAI,IAAI,IAC5C,CAMA,SAAS,EAAS,EAAoB,CACpC,GAAM,CAAC,EAAK,GAAU,MAAe,EAAK,CAAG,CAAC,EAiB9C,OAhBA,MAAgB,CACd,IAAI,EACJ,SAAS,GAAW,CAClB,EAAQ,eACA,CACJ,IAAM,EAAO,EAAK,CAAG,EAErB,EAAQ,GAAc,GAAO,EAAU,EAAU,CAAI,EAAI,EAAW,CAAK,EACzE,EAAS,CACX,EACA,IAAU,KAAK,IAAI,EAAI,GACzB,CACF,CAEA,OADA,EAAS,MACI,aAAa,CAAK,CACjC,EAAG,CAAC,CAAG,CAAC,EACD,CACT,CAGA,SAAgB,GAAe,CAC7B,OAAO,EAAS,EAAK,CACvB,CAGA,SAAgB,GAAiB,CAC/B,OAAO,EAAS,EAAI,CACtB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{isSelfActivation as t}from"../utils/activationKey.mjs";import n from"../ripple/ripple.mjs";import
|
|
1
|
+
"use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{isSelfActivation as t}from"../utils/activationKey.mjs";import{ThemeColor as n}from"../themeProvider/color.types.mjs";import{toneProps as r,useToneCheck as i}from"../styles/tone.mjs";import a from"../ripple/ripple.mjs";import o from"../interactableDiv/index.mjs";import{CardStyleType as s}from"./card.types.mjs";import c from"./card.module.mjs";import{useRef as l}from"react";import u from"classnames";import{jsx as d}from"react/jsx-runtime";var f={elevated:c.cardStyleElevated,outlined:c.cardStyleOutlined,light:c.cardStyleLight};function p(p){let{className:m=void 0,children:h=null,styleType:g=s.Elevated,color:_=n.Neutral,onClick:v=void 0,tabIndex:y=null,hoverEffect:b=void 0,style:x=void 0,autoGap:S=!0,clip:C=!1,onKeyDown:w,classNames:T,styles:E,...D}=e(`Card`,p),O=!!v,k=r(_);i(`Card`,[_]);let A=l(null);function j(e){O&&t(e)&&A.current?.addRipple(),w?.(e)}return d(o,{...D,className:u(c.card,k.className,_===n.Neutral&&c.cardNeutral,f[g],C&&c.cardClip,O&&c.cardInteractable,(O&&b!==!1||b)&&c.cardHover,m,T?.root),onClick:v,onKeyDown:j,tabIndex:y??(O?0:null),style:{...k.style,...x,...E?.root},children:d(a,{ref:A,disabled:!O,className:u(c.cardPadding,S&&c.cardGaps,T?.content),style:{borderRadius:`inherit`,...E?.content},children:h})})}export{p as default};
|
|
2
2
|
//# sourceMappingURL=Card.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Card.mjs","names":[],"sources":["../../../../package/common/card/Card.tsx"],"sourcesContent":["import cx from 'classnames';\nimport React, { useRef } from 'react';\n\nimport { CardStyleType, type CardProps } from './card.types';\nimport styles from './card.module.pcss';\nimport InteractableDiv from '../interactableDiv';\nimport Ripple from '../ripple';\nimport type { RippleHandle } from '../ripple';\nimport { useComponentDefaults } from '../configProvider';\nimport { isSelfActivation } from '../utils/activationKey';\n\nconst CLASS_BY_STYLE: Record<CardStyleType, string> = {\n elevated: styles.cardStyleElevated,\n outlined: styles.cardStyleOutlined,\n
|
|
1
|
+
{"version":3,"file":"Card.mjs","names":[],"sources":["../../../../package/common/card/Card.tsx"],"sourcesContent":["import cx from 'classnames';\nimport React, { useRef } from 'react';\n\nimport { CardStyleType, type CardProps } from './card.types';\nimport styles from './card.module.pcss';\nimport InteractableDiv from '../interactableDiv';\nimport Ripple from '../ripple';\nimport type { RippleHandle } from '../ripple';\nimport { useComponentDefaults } from '../configProvider';\nimport { isSelfActivation } from '../utils/activationKey';\nimport { ThemeColor } from '../themeProvider/color.types';\nimport { toneProps, useToneCheck } from '../styles/tone';\n\nconst CLASS_BY_STYLE: Record<CardStyleType, string> = {\n elevated: styles.cardStyleElevated,\n outlined: styles.cardStyleOutlined,\n light: styles.cardStyleLight,\n};\n\nfunction Card(props: CardProps) {\n const {\n className = undefined,\n children = null,\n styleType = CardStyleType.Elevated,\n color = ThemeColor.Neutral,\n onClick = undefined,\n tabIndex = null,\n hoverEffect = undefined,\n style = undefined,\n autoGap = true,\n clip = false,\n onKeyDown: onKeyDownProp,\n classNames,\n styles: slotStyles,\n ...rest\n } = useComponentDefaults('Card', props);\n const isInteractable = !!onClick;\n const tone = toneProps(color);\n useToneCheck('Card', [color]);\n\n const rippleRef = useRef<RippleHandle>(null);\n\n // Keyboard activation calls onClick directly without dispatching a DOM click, so Ripple's own\n // listener never sees it.\n function handleKeyDown(event: React.KeyboardEvent<HTMLDivElement>) {\n if (isInteractable && isSelfActivation(event)) rippleRef.current?.addRipple();\n onKeyDownProp?.(event);\n }\n\n return (\n <InteractableDiv\n {...rest}\n className={cx(\n styles.card,\n tone.className,\n color === ThemeColor.Neutral && styles.cardNeutral,\n CLASS_BY_STYLE[styleType],\n clip && styles.cardClip,\n isInteractable && styles.cardInteractable,\n ((isInteractable && hoverEffect !== false) || hoverEffect) && styles.cardHover,\n className,\n classNames?.root,\n )}\n onClick={onClick}\n onKeyDown={handleKeyDown}\n tabIndex={tabIndex ?? (isInteractable ? 0 : null)}\n style={{ ...tone.style, ...style, ...slotStyles?.root }}\n >\n <Ripple\n ref={rippleRef}\n disabled={!isInteractable}\n className={cx(styles.cardPadding, autoGap && styles.cardGaps, classNames?.content)}\n style={{ borderRadius: 'inherit', ...slotStyles?.content }}\n >\n {children}\n </Ripple>\n </InteractableDiv>\n );\n}\n\nexport default Card;\n"],"mappings":"+hBAaA,IAAM,EAAgD,CACpD,SAAU,EAAO,kBACjB,SAAU,EAAO,kBACjB,MAAO,EAAO,cAChB,EAEA,SAAS,EAAK,EAAkB,CAC9B,GAAM,CACJ,YAAY,IAAA,GACZ,WAAW,KACX,YAAY,EAAc,SAC1B,QAAQ,EAAW,QACnB,UAAU,IAAA,GACV,WAAW,KACX,cAAc,IAAA,GACd,QAAQ,IAAA,GACR,UAAU,GACV,OAAO,GACP,UAAW,EACX,aACA,OAAQ,EACR,GAAG,GACD,EAAqB,OAAQ,CAAK,EAChC,EAAiB,CAAC,CAAC,EACnB,EAAO,EAAU,CAAK,EAC5B,EAAa,OAAQ,CAAC,CAAK,CAAC,EAE5B,IAAM,EAAY,EAAqB,IAAI,EAI3C,SAAS,EAAc,EAA4C,CAC7D,GAAkB,EAAiB,CAAK,GAAG,EAAU,SAAS,UAAU,EAC5E,IAAgB,CAAK,CACvB,CAEA,OACE,EAAC,EAAD,CACE,GAAI,EACJ,UAAW,EACT,EAAO,KACP,EAAK,UACL,IAAU,EAAW,SAAW,EAAO,YACvC,EAAe,GACf,GAAQ,EAAO,SACf,GAAkB,EAAO,kBACvB,GAAkB,IAAgB,IAAU,IAAgB,EAAO,UACrE,EACA,GAAY,IACd,EACS,UACT,UAAW,EACX,SAAU,IAAa,EAAiB,EAAI,MAC5C,MAAO,CAAE,GAAG,EAAK,MAAO,GAAG,EAAO,GAAG,GAAY,IAAK,EAEtD,SAAA,EAAC,EAAD,CACE,IAAK,EACL,SAAU,CAAC,EACX,UAAW,EAAG,EAAO,YAAa,GAAW,EAAO,SAAU,GAAY,OAAO,EACjF,MAAO,CAAE,aAAc,UAAW,GAAG,GAAY,OAAQ,EAExD,UACK,CAAA,CACO,CAAA,CAErB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import
|
|
1
|
+
"use client";import e from"../button/button.mjs";import t from"./card.module.mjs";import"react";import n from"classnames";import{jsx as r,jsxs as i}from"react/jsx-runtime";function a({className:a=``,actions:o=[],children:s=null}){return i(`div`,{className:n(t.cardActions,a),children:[o.map(({id:t,onClick:n,label:i,styleType:a,color:o})=>r(`div`,{children:r(e,{onClick:n,styleType:a,color:o,children:i})},t??i)),s]})}export{a as default};
|
|
2
2
|
//# sourceMappingURL=CardActions.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CardActions.mjs","names":[],"sources":["../../../../package/common/card/CardActions.tsx"],"sourcesContent":["import React from 'react';\nimport cx from 'classnames';\nimport Button from '../button';\
|
|
1
|
+
{"version":3,"file":"CardActions.mjs","names":[],"sources":["../../../../package/common/card/CardActions.tsx"],"sourcesContent":["import React from 'react';\nimport cx from 'classnames';\nimport Button from '../button';\n\nimport type { CardActionsProps } from './card.types';\nimport styles from './card.module.pcss';\n\nfunction CardActions({ className = '', actions = [], children = null }: CardActionsProps) {\n return (\n <div className={cx(styles.cardActions, className)}>\n {actions.map(({ id, onClick, label, styleType, color }) => (\n <div key={id ?? label}>\n <Button onClick={onClick} styleType={styleType} color={color}>\n {label}\n </Button>\n </div>\n ))}\n {children}\n </div>\n );\n}\n\nexport default CardActions;\n"],"mappings":"4KAOA,SAAS,EAAY,CAAE,YAAY,GAAI,UAAU,CAAC,EAAG,WAAW,MAA0B,CACxF,OACE,EAAC,MAAD,CAAK,UAAW,EAAG,EAAO,YAAa,CAAS,EAAhD,SAAA,CACG,EAAQ,KAAK,CAAE,KAAI,UAAS,QAAO,YAAW,WAC7C,EAAC,MAAD,CAAA,SACE,EAAC,EAAD,CAAiB,UAAoB,YAAkB,QACpD,SAAA,CACK,CAAA,CACL,EAJK,GAAM,CAIX,CACN,EACA,CACE,GAET"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CardHeader.mjs","names":[],"sources":["../../../../package/common/card/CardHeader.tsx"],"sourcesContent":["import React from 'react';\nimport cx from 'classnames';\n\nimport type { CardHeaderProps } from './card.types';\nimport styles from './card.module.pcss';\nimport ActionIcon from '../actionIcon';\n\nfunction CardHeader({\n className = '',\n title = '',\n subTitle = '',\n thumbnail = '',\n actions = undefined,\n}: CardHeaderProps) {\n const thumbnailUrl = typeof thumbnail === 'string' && thumbnail.startsWith('http') ? thumbnail : undefined;\n\n return (\n <div className={cx(styles.cardHeader, className)}>\n {thumbnail && (\n <div\n className={styles.cardHeaderThumbnail}\n style={thumbnailUrl ? { backgroundImage: `url(${thumbnailUrl})` } : {}}\n >\n {!thumbnailUrl && thumbnail}\n </div>\n )}\n <div className={styles.cardHeaderTitles}>\n <div className={styles.cardHeaderTitlesMainContainer}>\n <div className={styles.cardHeaderTitlesMain}>{title}</div>\n <div className={styles.cardHeaderActions}>\n {Array.isArray(actions)\n ? actions.map((action, index) => (\n <ActionIcon\n key={index}\n title={action.title}\n onClick={\n action.onClick\n ? (e: React.MouseEvent<
|
|
1
|
+
{"version":3,"file":"CardHeader.mjs","names":[],"sources":["../../../../package/common/card/CardHeader.tsx"],"sourcesContent":["import React from 'react';\nimport cx from 'classnames';\n\nimport type { CardHeaderProps } from './card.types';\nimport styles from './card.module.pcss';\nimport ActionIcon from '../actionIcon';\n\nfunction CardHeader({\n className = '',\n title = '',\n subTitle = '',\n thumbnail = '',\n actions = undefined,\n}: CardHeaderProps) {\n const thumbnailUrl = typeof thumbnail === 'string' && thumbnail.startsWith('http') ? thumbnail : undefined;\n\n return (\n <div className={cx(styles.cardHeader, className)}>\n {thumbnail && (\n <div\n className={styles.cardHeaderThumbnail}\n style={thumbnailUrl ? { backgroundImage: `url(${thumbnailUrl})` } : {}}\n >\n {!thumbnailUrl && thumbnail}\n </div>\n )}\n <div className={styles.cardHeaderTitles}>\n <div className={styles.cardHeaderTitlesMainContainer}>\n <div className={styles.cardHeaderTitlesMain}>{title}</div>\n <div className={styles.cardHeaderActions}>\n {Array.isArray(actions)\n ? actions.map((action, index) => (\n <ActionIcon\n key={index}\n title={action.title}\n onClick={\n action.onClick\n ? (e: React.MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation();\n action.onClick?.(e);\n }\n : undefined\n }\n icon={action.icon}\n />\n ))\n : actions}\n </div>\n </div>\n <div className={styles.cardHeaderTitlesSub}>{subTitle}</div>\n </div>\n </div>\n );\n}\n\nexport default CardHeader;\n"],"mappings":"oLAOA,SAAS,EAAW,CAClB,YAAY,GACZ,QAAQ,GACR,WAAW,GACX,YAAY,GACZ,UAAU,IAAA,IACQ,CAClB,IAAM,EAAe,OAAO,GAAc,UAAY,EAAU,WAAW,MAAM,EAAI,EAAY,IAAA,GAEjG,OACE,EAAC,MAAD,CAAK,UAAW,EAAG,EAAO,WAAY,CAAS,EAA/C,SAAA,CACG,GACC,EAAC,MAAD,CACE,UAAW,EAAO,oBAClB,MAAO,EAAe,CAAE,gBAAiB,OAAO,EAAa,EAAG,EAAI,CAAC,EAEpE,SAAA,CAAC,GAAgB,CACf,CAAA,EAEP,EAAC,MAAD,CAAK,UAAW,EAAO,iBAAvB,SAAA,CACE,EAAC,MAAD,CAAK,UAAW,EAAO,8BAAvB,SAAA,CACE,EAAC,MAAD,CAAK,UAAW,EAAO,qBAAuB,SAAA,CAAW,CAAA,EACzD,EAAC,MAAD,CAAK,UAAW,EAAO,kBACpB,SAAA,MAAM,QAAQ,CAAO,EAClB,EAAQ,KAAK,EAAQ,IACnB,EAAC,EAAD,CAEE,MAAO,EAAO,MACd,QACE,EAAO,QACF,GAA2C,CAC1C,EAAE,gBAAgB,EAClB,EAAO,UAAU,CAAC,CACpB,EACA,IAAA,GAEN,KAAM,EAAO,IACd,EAXM,CAWN,CACF,EACD,CACD,CAAA,CACF,CACL,CAAA,EAAA,EAAC,MAAD,CAAK,UAAW,EAAO,oBAAsB,SAAA,CAAc,CAAA,CACxD,CACF,CAAA,CAAA,GAET"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";var e=`card_w-6Ki`,t=`card-clip_eZ8-1`,n=`card-padding_X2-q-`,r=`card-gaps_jhYkx`,i=`card-style-elevated_exvMB`,a=`card-style-outlined_PxZZA`,o=`card-style-
|
|
1
|
+
"use client";var e=`card_w-6Ki`,t=`card-clip_eZ8-1`,n=`card-padding_X2-q-`,r=`card-gaps_jhYkx`,i=`card-style-elevated_exvMB`,a=`card-style-outlined_PxZZA`,o=`card-style-light_J5TME`,s=`card-neutral_AZL-v`,c=`card-interactable_az2lE`,l=`card-hover_fdS-X`,u=`cardHeader_HfIlm`,d=`cardHeader-thumbnail_rFw-N`,f=`cardHeader-actions_awD46`,p=`cardHeader-titles_CAUU3`,m=`cardHeader-titles-main_Z834V`,h=`cardHeader-titles-main-container_1j-od`,g=`cardHeader-titles-sub_2X08b`,_=`cardMedia_GZJQF`,v=`cardActions_uYu-0`,y={card:e,"card-clip":`card-clip_eZ8-1`,cardClip:t,"card-padding":`card-padding_X2-q-`,cardPadding:n,"card-gaps":`card-gaps_jhYkx`,cardGaps:r,"card-style-elevated":`card-style-elevated_exvMB`,cardStyleElevated:i,"card-style-outlined":`card-style-outlined_PxZZA`,cardStyleOutlined:a,"card-style-light":`card-style-light_J5TME`,cardStyleLight:o,"card-neutral":`card-neutral_AZL-v`,cardNeutral:s,"card-interactable":`card-interactable_az2lE`,cardInteractable:c,"card-hover":`card-hover_fdS-X`,cardHover:l,cardHeader:u,"cardHeader-thumbnail":`cardHeader-thumbnail_rFw-N`,cardHeaderThumbnail:d,"cardHeader-actions":`cardHeader-actions_awD46`,cardHeaderActions:f,"cardHeader-titles":`cardHeader-titles_CAUU3`,cardHeaderTitles:p,"cardHeader-titles-main":`cardHeader-titles-main_Z834V`,cardHeaderTitlesMain:m,"cardHeader-titles-main-container":`cardHeader-titles-main-container_1j-od`,cardHeaderTitlesMainContainer:h,"cardHeader-titles-sub":`cardHeader-titles-sub_2X08b`,cardHeaderTitlesSub:g,cardMedia:_,cardActions:v};export{e as card,v as cardActions,t as cardClip,r as cardGaps,u as cardHeader,f as cardHeaderActions,d as cardHeaderThumbnail,p as cardHeaderTitles,m as cardHeaderTitlesMain,h as cardHeaderTitlesMainContainer,g as cardHeaderTitlesSub,l as cardHover,c as cardInteractable,_ as cardMedia,s as cardNeutral,n as cardPadding,i as cardStyleElevated,o as cardStyleLight,a as cardStyleOutlined,y as default};
|
|
2
2
|
//# sourceMappingURL=card.module.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"card.module.mjs","names":[],"sources":["../../../../package/common/card/card.module.pcss"],"sourcesContent":[".card {\n border-radius: var(--default-border-radius);\n color: var(--text-color);\n border: 1px solid transparent;\n box-sizing: border-box;\n\n &-clip {\n overflow: hidden;\n }\n\n &-padding {\n padding: 1em;\n }\n\n &-gaps {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-s);\n }\n\n &-style {\n &-elevated {\n background: var(--background-card-elevated, var(--background-accent-light));\n box-shadow: var(--card-shadow);\n }\n\n &-outlined {\n background: var(--background-card-outlined, transparent);\n border-color: var(--
|
|
1
|
+
{"version":3,"file":"card.module.mjs","names":[],"sources":["../../../../package/common/card/card.module.pcss"],"sourcesContent":[".card {\n border-radius: var(--default-border-radius);\n color: var(--text-color);\n border: 1px solid transparent;\n box-sizing: border-box;\n\n &-clip {\n overflow: hidden;\n }\n\n &-padding {\n padding: 1em;\n }\n\n &-gaps {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-s);\n }\n\n &-style {\n &-elevated {\n background: var(--background-card-elevated, var(--background-accent-light));\n box-shadow: var(--card-shadow);\n }\n\n &-outlined {\n background: var(--background-card-outlined, transparent);\n border-color: var(--tone-outline);\n }\n\n &-light {\n background: var(--tone-light);\n }\n }\n\n /* A theme may give the Neutral card a surface of its own; any other colour's tint is the point. */\n &-neutral&-style-light {\n background: var(--background-card-filled, var(--tone-light));\n }\n\n &-interactable {\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n }\n\n &-hover {\n position: relative;\n transition:\n transform 0.15s ease,\n box-shadow 0.15s ease,\n filter 0.3s ease;\n\n /* A layer over the card's own surface, so a coloured card keeps its colour. Opacity, because\n Chromium does not interpolate a currentcolor mix. Paints under the later Ripple wrapper. */\n &::before {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background: currentcolor;\n opacity: 0;\n transition: opacity 0.15s ease;\n pointer-events: none;\n }\n\n &:hover {\n transform: translateY(-2px);\n\n &::before {\n opacity: 0.05;\n }\n }\n }\n}\n\n.cardHeader {\n display: flex;\n gap: 1em;\n align-items: center;\n\n &-thumbnail {\n display: flex;\n justify-content: center;\n align-items: center;\n width: 2.5em;\n height: 2.5em;\n background: rgb(0 0 0 / 8%);\n border-radius: 50%;\n overflow: hidden;\n background-size: cover;\n background-position: center;\n flex-shrink: 0;\n }\n\n &-actions {\n display: flex;\n gap: var(--spacing-s);\n flex-wrap: wrap;\n flex-shrink: 1;\n align-items: center;\n justify-content: flex-end;\n }\n\n &-titles {\n display: flex;\n flex-flow: column;\n flex: 1;\n gap: 0.25em;\n overflow: hidden;\n\n &-main {\n font-size: 1.125em;\n font-weight: 600;\n min-width: 3ch;\n flex-shrink: 100000;\n overflow: hidden;\n text-overflow: ellipsis;\n\n &-container {\n display: flex;\n align-items: center;\n gap: var(--spacing-m);\n justify-content: space-between;\n }\n }\n\n &-sub {\n font-weight: 300;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n }\n}\n\n/* Pulled out to the card's own edges, so these must stay twice and once .card-padding above. */\n.cardMedia {\n width: calc(100% + 2em);\n margin: 0 -1em;\n}\n\n.cardActions {\n display: flex;\n flex-wrap: wrap;\n gap: 0.5em;\n}\n\n/* The lift on hover is the only motion here; the shadow and border it transitions alongside stay. */\n@media (prefers-reduced-motion: reduce) {\n .card-hover:hover {\n transform: none;\n }\n}\n"],"mappings":""}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";var e=function(e){return e.Elevated=`elevated`,e.Outlined=`outlined`,e.
|
|
1
|
+
"use client";var e=function(e){return e.Elevated=`elevated`,e.Outlined=`outlined`,e.Light=`light`,e}({});export{e as CardStyleType};
|
|
2
2
|
//# sourceMappingURL=card.types.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"card.types.mjs","names":[],"sources":["../../../../package/common/card/card.types.ts"],"sourcesContent":["import type React from 'react';\nimport type { ReactNode } from 'react';\nimport type { ButtonStyleType } from '../button/button.types';\nimport type { HtmlProps, SlotClassNames, SlotStyles } from '../types/slots.types';\nimport type { IconAction } from '../types/actions.types';\n\nexport enum CardStyleType {\n Elevated = 'elevated',\n Outlined = 'outlined',\n
|
|
1
|
+
{"version":3,"file":"card.types.mjs","names":[],"sources":["../../../../package/common/card/card.types.ts"],"sourcesContent":["import type React from 'react';\nimport type { ReactNode } from 'react';\nimport type { ButtonProps, ButtonStyleType } from '../button/button.types';\nimport type { HtmlProps, SlotClassNames, SlotStyles } from '../types/slots.types';\nimport type { IconAction } from '../types/actions.types';\nimport type { ColorValue } from '../themeProvider/color.types';\n\n/**\n * The card's surface. `Outlined` and `Light` mean what they do on Button, Badge and Chip; `Elevated`\n * is a card's own. There is no `Filled`: body text on a solid colour reads badly.\n */\nexport enum CardStyleType {\n /** A raised surface with a shadow, always neutral. The default. */\n Elevated = 'elevated',\n /** A border in the colour, no fill. */\n Outlined = 'outlined',\n /** A flat tint of the colour, no border. */\n Light = 'light',\n}\n\n// `tabIndex` is omitted only because this component's version also accepts `null`.\nexport type CardSlots = 'root' | 'content';\n\nexport interface CardProps extends Omit<HtmlProps, 'tabIndex'> {\n className?: string | undefined;\n children?: ReactNode;\n styleType?: CardStyleType;\n /**\n * The border of an `Outlined` card and the tint of a `Light` one: a `ThemeColor` (default\n * `Neutral`) or any CSS colour. An `Elevated` card stays neutral.\n */\n color?: ColorValue;\n onClick?: () => void;\n tabIndex?: number | null;\n hoverEffect?: boolean;\n style?: React.CSSProperties;\n autoGap?: boolean;\n clip?: boolean;\n /** Ref to the root element. */\n ref?: React.Ref<HTMLDivElement>;\n /** Classes for the inner elements. See `CardSlots`. */\n classNames?: SlotClassNames<CardSlots>;\n /** Inline styles for the inner elements. See `CardSlots`. */\n styles?: SlotStyles<CardSlots>;\n}\n\nexport type CardHeaderAction = IconAction;\n\nexport interface CardHeaderProps {\n className?: string;\n title?: ReactNode;\n subTitle?: ReactNode;\n /** URL string → rendered as background-image. Any other ReactNode → rendered inside the thumbnail div. */\n thumbnail?: string | ReactNode;\n actions?: CardHeaderAction[] | ReactNode;\n}\n\nexport interface CardMediaProps {\n src?: string;\n alt?: string;\n}\n\nexport interface CardContentProps {\n children?: ReactNode;\n}\n\nexport interface CardAction {\n id?: string;\n label?: string;\n styleType?: ButtonStyleType;\n color?: ButtonProps['color'];\n onClick?: () => void;\n}\n\nexport interface CardActionsProps {\n className?: string;\n /** Renders a Button for each action object. Pass `children` for custom content instead. */\n actions?: CardAction[];\n children?: ReactNode;\n}\n"],"mappings":"aAWA,IAAY,EAAL,SAAA,EAAA,OAEL,GAAA,SAAA,WAEA,EAAA,SAAA,WAEA,EAAA,MAAA,SACF,EAAA,CAAA,CAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{useLabels as t}from"../configProvider/useLabels.mjs";import n
|
|
1
|
+
"use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{useLabels as t}from"../configProvider/useLabels.mjs";import{ButtonStyleType as n}from"../button/button.types.mjs";import r from"../actionIcon/actionIcon.mjs";import i from"../interactableDiv/index.mjs";import a from"./carousel.module.mjs";import o from"../styles/scrollFade.module.mjs";import s,{useEffect as ee,useLayoutEffect as c,useRef as l,useState as u}from"react";import d from"classnames";import{faChevronLeft as te,faChevronRight as ne}from"@fortawesome/free-solid-svg-icons";import{Fragment as re,jsx as f,jsxs as p}from"react/jsx-runtime";var m=`var(--background-accent)`,h=10,ie=.2,ae={previous:`Previous slide`,next:`Next slide`,slides:`Slides`,goToSlide:e=>`Go to slide ${e}`};function g(g){let{children:oe,currentIndex:y,defaultIndex:se=0,onChange:ce=()=>{},loop:le=!0,autoPlay:b=!1,autoPlayInterval:ue=4e3,pauseOnHover:de=!0,showArrows:fe=!0,showDots:pe=!0,swipeable:me=!0,lazyRender:he=!1,adaptiveHeight:x=!1,className:ge,style:_e,classNames:S,styles:C,labels:ve,...w}=e(`Carousel`,g),T=t(`Carousel`,ve,ae),E=s.useId(),D=s.Children.toArray(oe),O=D.length,k=le&&O>1,A=+!!k,j=k?[D[O-1],...D,D[0]]:D,M=y!==void 0,[ye,be]=u(()=>v(se,O,k)),N=v(M?y:ye,O,k),[P,F]=u(N+A),[xe,I]=u(!0),L=l(N),[Se,R]=u(!1),[Ce,z]=u(!1),[we,B]=u(!1),V=l(null),H=l(null),U=l(null),W=j.length>0?100/j.length:100;c(()=>{let e=L.current;if(L.current=N,e===N)return;let t=j.length-1,n=P;k&&P===0?n=O:k&&P===t&&(n=1);let r=k&&e===O-1&&N===0,i=k&&e===0&&N===O-1,a;a=r?n+1:i?n-1:N+A;let o=H.current;n!==P&&o&&(o.style.transition=`none`,o.style.transform=_(n,0,W),o.offsetWidth,o.style.transition=``),I(!0),F(a)},[N]);let[G,Te]=u(()=>({min:N+A-1,max:N+A+1})),Ee=Math.min(G.min,P-1),De=Math.max(G.max,P+1),[Oe,ke]=u(void 0);c(()=>{if(!x)return;let e=H.current?.children[P];if(!e)return;let t=()=>ke(e.offsetHeight);t();let n=new ResizeObserver(t);return n.observe(e),()=>n.disconnect()},[x,P,O]),c(()=>{let e=U.current,t=e?.children[N];e&&t&&(e.scrollLeft=t.offsetLeft-(e.clientWidth-t.offsetWidth)/2)},[N,O]);function K(e){let t=v(e,O,k);M||be(t),ce(t)}function q(){!k&&N>=O-1||K(N+1)}function J(){!k&&N<=0||K(N-1)}function Ae(e){e.target===e.currentTarget&&(Te({min:P-1,max:P+1}),k&&(P===0?(I(!1),F(O)):P===j.length-1&&(I(!1),F(1))))}let Y=b&&de,je=Se||Ce||we;ee(()=>{if(!b||O<=1||je)return;let e=setInterval(q,ue);return()=>clearInterval(e)},[b,ue,je,N,O]);let X=l(null);function Me(e){!me||O<=1||(X.current={startX:e.clientX,startY:e.clientY,width:V.current?.getBoundingClientRect().width||1,axisLocked:!1,active:!0,offsetPercent:0})}function Ne(e){let t=X.current;if(!t||!t.active)return;let n=e.clientX-t.startX,r=e.clientY-t.startY;if(!t.axisLocked){if(Math.abs(n)<h&&Math.abs(r)<h)return;if(Math.abs(r)>Math.abs(n)){t.active=!1;return}t.axisLocked=!0,e.currentTarget.setPointerCapture?.(e.pointerId),B(!0),I(!1)}t.offsetPercent=n/t.width*100,H.current&&(H.current.style.transform=_(P,t.offsetPercent,W))}function Pe(){let e=X.current;if(X.current=null,!e||!e.axisLocked){B(!1);return}I(!0),B(!1),H.current&&(H.current.style.transition=``,H.current.style.transform=_(P,0,W)),Math.abs(e.offsetPercent)>=ie*100&&(e.offsetPercent<0?q():J())}function Fe(e){e.defaultPrevented||H.current?.contains(e.target)||(e.key===`ArrowLeft`?(e.preventDefault(),J()):e.key===`ArrowRight`&&(e.preventDefault(),q()))}function Ie(e){let t=null;if(e.key===`ArrowLeft`?t=N-1:e.key===`ArrowRight`?t=N+1:e.key===`Home`?t=0:e.key===`End`&&(t=O-1),t===null)return;e.preventDefault();let n=v(t,O,k);K(n),(U.current?.children[n])?.focus()}let Le=pe&&O>1,Re=e=>`${E}-dot-${e}`,Z=e=>`${E}-slide-${e}`,ze=w[`aria-label`]!==void 0||w[`aria-labelledby`]!==void 0;function Be(e){return Le?{id:Z(e),role:`tabpanel`,"aria-labelledby":Re(e)}:{id:Z(e),role:`group`,"aria-roledescription":`slide`,"aria-label":`${e+1} of ${O}`}}let Q=!k&&N<=0,$=!k&&N>=O-1,Ve=_(P,0,W);return p(`div`,{...w,ref:V,role:ze?`region`:`group`,"aria-roledescription":`carousel`,className:d(a.carousel,x&&a.carouselAdaptive,S?.root,ge),style:{height:x?Oe:void 0,..._e,...C?.root},onMouseEnter:Y?()=>R(!0):void 0,onMouseLeave:Y?()=>R(!1):void 0,onFocus:Y?()=>z(!0):void 0,onBlur:Y?()=>z(!1):void 0,onKeyDown:Fe,children:[f(`div`,{ref:H,className:d(a.carouselTrack,x&&a.carouselTrackAdaptive,S?.track),style:{width:`${j.length*100}%`,transform:Ve,transition:xe?void 0:`none`,...C?.track},"aria-live":b?`off`:`polite`,onTransitionEnd:Ae,onPointerDown:Me,onPointerMove:Ne,onPointerUp:Pe,onPointerCancel:Pe,children:j.map((e,t)=>{let n=k&&(t===0||t===j.length-1),r=t-A,i=!n&&r===N,o=!he||t>=Ee&&t<=De;return f(`div`,{...n?{}:Be(r),className:d(a.carouselSlide,S?.slide),style:{width:`${100/j.length}%`,...C?.slide},inert:!i||void 0,children:o?e:null},`carousel-slide-${t}`)})}),fe&&O>1&&p(re,{children:[f(r,{styleType:n.Filled,color:m,icon:te,title:T.previous,"aria-label":T.previous,"aria-disabled":Q||void 0,onClick:()=>{Q||J()},className:d(a.carouselPrevButton,Q&&a.carouselButtonDisabled,S?.prevButton),style:C?.prevButton}),f(r,{styleType:n.Filled,color:m,icon:ne,title:T.next,"aria-label":T.next,"aria-disabled":$||void 0,onClick:()=>{$||q()},className:d(a.carouselNextButton,$&&a.carouselButtonDisabled,S?.nextButton),style:C?.nextButton})]}),Le&&f(`div`,{ref:U,role:`tablist`,"aria-label":T.slides,className:d(a.carouselDots,o.scrollFade,o.scrollFadeX,o.scrollFadeFadedStart,o.scrollFadeFadedEnd,S?.dots),style:C?.dots,onKeyDown:Ie,children:D.map((e,t)=>f(i,{id:Re(t),role:`tab`,"aria-label":T.goToSlide(t+1),"aria-selected":t===N,"aria-controls":Z(t),tabIndex:t===N?0:-1,onClick:()=>K(t),className:d(a.carouselDot,t===N&&a.carouselDotActive,S?.dot),style:C?.dot},`carousel-dot-${t}`))})]})}function _(e,t,n){return`translateX(calc(${-e*n}% + ${n/100*t}%))`}function v(e,t,n){return t===0?0:n?(e%t+t)%t:Math.max(0,Math.min(t-1,e))}export{g as default};
|
|
2
2
|
//# sourceMappingURL=carousel.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"carousel.mjs","names":[],"sources":["../../../../package/common/carousel/carousel.tsx"],"sourcesContent":["import React, { useEffect, useLayoutEffect, useRef, useState } from 'react';\nimport cx from 'classnames';\nimport { faChevronLeft, faChevronRight } from '@fortawesome/free-solid-svg-icons';\n\nimport ActionIcon from '../actionIcon';\nimport InteractableDiv from '../interactableDiv';\nimport { useComponentDefaults, useLabels } from '../configProvider';\nimport type { CarouselLabels, CarouselProps } from './carousel.types';\n\nimport styles from './carousel.module.pcss';\nimport fadeStyles from 'components/common/styles/scrollFade.module.pcss';\n\nconst AXIS_LOCK_THRESHOLD = 10;\nconst DRAG_COMMIT_RATIO = 0.2;\n\nconst DEFAULT_LABELS: Required<CarouselLabels> = {\n previous: 'Previous slide',\n next: 'Next slide',\n slides: 'Slides',\n goToSlide: (slide) => `Go to slide ${slide}`,\n};\n\nfunction Carousel(props: CarouselProps) {\n const {\n children,\n currentIndex,\n defaultIndex = 0,\n onChange = () => {},\n loop = true,\n autoPlay = false,\n autoPlayInterval = 4000,\n pauseOnHover = true,\n showArrows = true,\n showDots = true,\n swipeable = true,\n lazyRender = false,\n adaptiveHeight = false,\n className,\n style,\n classNames,\n styles: slotStyles,\n labels,\n ...rest\n } = useComponentDefaults('Carousel', props);\n const text = useLabels('Carousel', labels, DEFAULT_LABELS);\n\n const instanceId = React.useId();\n const slides = React.Children.toArray(children);\n const count = slides.length;\n const canLoop = loop && count > 1;\n const offset = canLoop ? 1 : 0;\n const extendedSlides = canLoop ? [slides[count - 1], ...slides, slides[0]] : slides;\n\n const isControlled = currentIndex !== undefined;\n const [internalIndex, setInternalIndex] = useState(() => clampIndex(defaultIndex, count, canLoop));\n const realIndex = clampIndex(isControlled ? currentIndex! : internalIndex, count, canLoop);\n\n const [displayIndex, setDisplayIndex] = useState(realIndex + offset);\n const [transitionEnabled, setTransitionEnabled] = useState(true);\n const prevRealIndexRef = useRef(realIndex);\n\n const [hovered, setHovered] = useState(false);\n const [focused, setFocused] = useState(false);\n const [dragging, setDragging] = useState(false);\n\n const containerRef = useRef<HTMLDivElement>(null);\n const trackRef = useRef<HTMLDivElement>(null);\n const dotsRef = useRef<HTMLDivElement>(null);\n\n const slideWidthPercent = extendedSlides.length > 0 ? 100 / extendedSlides.length : 100;\n\n useLayoutEffect(() => {\n const prevReal = prevRealIndexRef.current;\n prevRealIndexRef.current = realIndex;\n if (prevReal === realIndex) return;\n\n // A wrap parks the track on a clone until transitionEnd swaps it back, so a change arriving\n // before that has to animate from the normalised position rather than the clone.\n const lastExtendedIndex = extendedSlides.length - 1;\n let fromIndex = displayIndex;\n if (canLoop && displayIndex === 0) fromIndex = count;\n else if (canLoop && displayIndex === lastExtendedIndex) fromIndex = 1;\n\n const forwardWrap = canLoop && prevReal === count - 1 && realIndex === 0;\n const backwardWrap = canLoop && prevReal === 0 && realIndex === count - 1;\n\n let target: number;\n if (forwardWrap) target = fromIndex + 1;\n else if (backwardWrap) target = fromIndex - 1;\n else target = realIndex + offset;\n\n // Written straight to the node: the normalised position has to reach style recalculation on its\n // own, or it and the animated position collapse into one jump with no transition.\n const track = trackRef.current;\n if (fromIndex !== displayIndex && track) {\n track.style.transition = 'none';\n track.style.transform = buildTrackTransform(fromIndex, 0, slideWidthPercent);\n void track.offsetWidth;\n track.style.transition = '';\n }\n\n setTransitionEnabled(true);\n setDisplayIndex(target);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [realIndex]);\n\n // The window of slides `lazyRender` keeps mounted, as of the last settled position. Slides are\n // rendered for the union of this and the current window, so the ones a multi-step jump slides\n // past stay mounted until the transform transition ends instead of blanking out mid-flight.\n const [settledMountRange, setSettledMountRange] = useState(() => ({\n min: realIndex + offset - 1,\n max: realIndex + offset + 1,\n }));\n const mountMin = Math.min(settledMountRange.min, displayIndex - 1);\n const mountMax = Math.max(settledMountRange.max, displayIndex + 1);\n\n const [contentHeight, setContentHeight] = useState<number | undefined>(undefined);\n\n useLayoutEffect(() => {\n if (!adaptiveHeight) return;\n const slideElement = trackRef.current?.children[displayIndex] as HTMLElement | undefined;\n if (!slideElement) return;\n\n const update = () => setContentHeight(slideElement.offsetHeight);\n update();\n\n const observer = new ResizeObserver(update);\n observer.observe(slideElement);\n return () => observer.disconnect();\n }, [adaptiveHeight, displayIndex, count]);\n\n // Keeps the selected dot in view. Written as `scrollLeft` because `scrollIntoView` is free to\n // scroll the page along with it.\n useLayoutEffect(() => {\n const strip = dotsRef.current;\n const dot = strip?.children[realIndex] as HTMLElement | undefined;\n if (!strip || !dot) return;\n strip.scrollLeft = dot.offsetLeft - (strip.clientWidth - dot.offsetWidth) / 2;\n }, [realIndex, count]);\n\n function goToIndex(nextIndex: number) {\n const clamped = clampIndex(nextIndex, count, canLoop);\n if (!isControlled) setInternalIndex(clamped);\n onChange(clamped);\n }\n\n function goNext() {\n if (!canLoop && realIndex >= count - 1) return;\n goToIndex(realIndex + 1);\n }\n\n function goPrev() {\n if (!canLoop && realIndex <= 0) return;\n goToIndex(realIndex - 1);\n }\n\n function handleTrackTransitionEnd(event: React.TransitionEvent<HTMLDivElement>) {\n if (event.target !== event.currentTarget) return;\n setSettledMountRange({ min: displayIndex - 1, max: displayIndex + 1 });\n\n if (!canLoop) return;\n if (displayIndex === 0) {\n setTransitionEnabled(false);\n setDisplayIndex(count);\n } else if (displayIndex === extendedSlides.length - 1) {\n setTransitionEnabled(false);\n setDisplayIndex(1);\n }\n }\n\n // Hover and focus only ever pause the timer, so without one they are not worth tracking.\n const tracksPointerPause = autoPlay && pauseOnHover;\n const isPaused = hovered || focused || dragging;\n useEffect(() => {\n if (!autoPlay || count <= 1 || isPaused) return;\n const timer = setInterval(goNext, autoPlayInterval);\n return () => clearInterval(timer);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [autoPlay, autoPlayInterval, isPaused, realIndex, count]);\n\n // A drag follows the pointer through the node, not through state: a render per move event would\n // rebuild every slide and dot for something only the track's transform sees.\n const dragRef = useRef<{\n startX: number;\n startY: number;\n width: number;\n axisLocked: boolean;\n active: boolean;\n offsetPercent: number;\n } | null>(null);\n\n function handlePointerDown(event: React.PointerEvent<HTMLDivElement>) {\n if (!swipeable || count <= 1) return;\n dragRef.current = {\n startX: event.clientX,\n startY: event.clientY,\n // Measured once: measuring per move would force a layout between the transform writes.\n width: containerRef.current?.getBoundingClientRect().width || 1,\n axisLocked: false,\n active: true,\n offsetPercent: 0,\n };\n }\n\n function handlePointerMove(event: React.PointerEvent<HTMLDivElement>) {\n const drag = dragRef.current;\n if (!drag || !drag.active) return;\n\n const deltaX = event.clientX - drag.startX;\n const deltaY = event.clientY - drag.startY;\n\n if (!drag.axisLocked) {\n if (Math.abs(deltaX) < AXIS_LOCK_THRESHOLD && Math.abs(deltaY) < AXIS_LOCK_THRESHOLD) return;\n if (Math.abs(deltaY) > Math.abs(deltaX)) {\n drag.active = false;\n return;\n }\n drag.axisLocked = true;\n // Never on pointerdown: a captured pointer sends its `click` to the capture target too, so\n // capturing earlier would swallow every click meant for a button inside a slide.\n event.currentTarget.setPointerCapture?.(event.pointerId);\n setDragging(true);\n setTransitionEnabled(false);\n }\n\n drag.offsetPercent = (deltaX / drag.width) * 100;\n if (trackRef.current) {\n trackRef.current.style.transform = buildTrackTransform(displayIndex, drag.offsetPercent, slideWidthPercent);\n }\n }\n\n function handlePointerUp() {\n const drag = dragRef.current;\n dragRef.current = null;\n if (!drag || !drag.axisLocked) {\n setDragging(false);\n return;\n }\n\n setTransitionEnabled(true);\n setDragging(false);\n\n // React never saw the dragged transform, so it has to be handed back by hand, and always: a\n // drag that changes no index would otherwise strand the track off-screen. One that does change\n // it overwrites this in the same tick, and still animates on from where the pointer left off.\n if (trackRef.current) {\n trackRef.current.style.transition = '';\n trackRef.current.style.transform = buildTrackTransform(displayIndex, 0, slideWidthPercent);\n }\n\n if (Math.abs(drag.offsetPercent) >= DRAG_COMMIT_RATIO * 100) {\n if (drag.offsetPercent < 0) goNext();\n else goPrev();\n }\n }\n\n // Arrow keys belong to the carousel's own controls, never to the slides: a text field or a\n // scrollable region in a slide has to keep its own. `defaultPrevented` leaves the dots to their\n // own handling below.\n function handleKeyDown(event: React.KeyboardEvent<HTMLDivElement>) {\n if (event.defaultPrevented || trackRef.current?.contains(event.target as Node)) return;\n\n if (event.key === 'ArrowLeft') {\n event.preventDefault();\n goPrev();\n } else if (event.key === 'ArrowRight') {\n event.preventDefault();\n goNext();\n }\n }\n\n function handleDotsKeyDown(event: React.KeyboardEvent<HTMLDivElement>) {\n let next: number | null = null;\n if (event.key === 'ArrowLeft') next = realIndex - 1;\n else if (event.key === 'ArrowRight') next = realIndex + 1;\n else if (event.key === 'Home') next = 0;\n else if (event.key === 'End') next = count - 1;\n if (next === null) return;\n\n event.preventDefault();\n const clamped = clampIndex(next, count, canLoop);\n goToIndex(clamped);\n // The selected dot is the one holding the tab stop, so focus has to travel with the selection.\n (dotsRef.current?.children[clamped] as HTMLElement | undefined)?.focus();\n }\n\n // The dots are the APG tablist over the slides. Without them the slides describe themselves as\n // plain slides rather than as panels.\n const hasTabs = showDots && count > 1;\n const dotId = (index: number) => `${instanceId}-dot-${index}`;\n const slideId = (index: number) => `${instanceId}-slide-${index}`;\n\n // An unnamed landmark is worse than none, so the carousel is only a region once it has a name.\n const isNamed = rest['aria-label'] !== undefined || rest['aria-labelledby'] !== undefined;\n\n function slideSemantics(index: number) {\n if (hasTabs) {\n return { id: slideId(index), role: 'tabpanel', 'aria-labelledby': dotId(index) };\n }\n return {\n id: slideId(index),\n role: 'group',\n 'aria-roledescription': 'slide',\n 'aria-label': `${index + 1} of ${count}`,\n };\n }\n\n const isPrevDisabled = !canLoop && realIndex <= 0;\n const isNextDisabled = !canLoop && realIndex >= count - 1;\n\n const trackTransform = buildTrackTransform(displayIndex, 0, slideWidthPercent);\n\n return (\n <div\n {...rest}\n ref={containerRef}\n role={isNamed ? 'region' : 'group'}\n aria-roledescription='carousel'\n className={cx(styles.carousel, adaptiveHeight && styles.carouselAdaptive, classNames?.root, className)}\n style={{ height: adaptiveHeight ? contentHeight : undefined, ...style, ...slotStyles?.root }}\n onMouseEnter={tracksPointerPause ? () => setHovered(true) : undefined}\n onMouseLeave={tracksPointerPause ? () => setHovered(false) : undefined}\n onFocus={tracksPointerPause ? () => setFocused(true) : undefined}\n onBlur={tracksPointerPause ? () => setFocused(false) : undefined}\n onKeyDown={handleKeyDown}\n >\n <div\n ref={trackRef}\n className={cx(styles.carouselTrack, adaptiveHeight && styles.carouselTrackAdaptive, classNames?.track)}\n style={{\n width: `${extendedSlides.length * 100}%`,\n transform: trackTransform,\n transition: transitionEnabled ? undefined : 'none',\n ...slotStyles?.track,\n }}\n aria-live={autoPlay ? 'off' : 'polite'}\n onTransitionEnd={handleTrackTransitionEnd}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onPointerCancel={handlePointerUp}\n >\n {extendedSlides.map((slide, idx) => {\n const isClonePosition = canLoop && (idx === 0 || idx === extendedSlides.length - 1);\n const logicalIndex = idx - offset;\n const isActive = !isClonePosition && logicalIndex === realIndex;\n const isRendered = !lazyRender || (idx >= mountMin && idx <= mountMax);\n\n return (\n <div\n key={`carousel-slide-${idx}`}\n {...(isClonePosition ? {} : slideSemantics(logicalIndex))}\n className={cx(styles.carouselSlide, classNames?.slide)}\n style={{ width: `${100 / extendedSlides.length}%`, ...slotStyles?.slide }}\n inert={isActive ? undefined : true}\n >\n {isRendered ? slide : null}\n </div>\n );\n })}\n </div>\n\n {showArrows && count > 1 && (\n <>\n <ActionIcon\n icon={faChevronLeft}\n title={text.previous}\n aria-label={text.previous}\n aria-disabled={isPrevDisabled || undefined}\n onClick={() => !isPrevDisabled && goPrev()}\n className={cx(\n styles.carouselPrevButton,\n isPrevDisabled && styles.carouselButtonDisabled,\n classNames?.prevButton,\n )}\n style={slotStyles?.prevButton}\n />\n <ActionIcon\n icon={faChevronRight}\n title={text.next}\n aria-label={text.next}\n aria-disabled={isNextDisabled || undefined}\n onClick={() => !isNextDisabled && goNext()}\n className={cx(\n styles.carouselNextButton,\n isNextDisabled && styles.carouselButtonDisabled,\n classNames?.nextButton,\n )}\n style={slotStyles?.nextButton}\n />\n </>\n )}\n\n {hasTabs && (\n <div\n ref={dotsRef}\n role='tablist'\n aria-label={text.slides}\n className={cx(\n styles.carouselDots,\n // Both ends always: the strip's own padding holds the outer dots clear of the fade\n // until there is something to scroll, so this needs no measuring.\n fadeStyles.scrollFade,\n fadeStyles.scrollFadeX,\n fadeStyles.scrollFadeFadedStart,\n fadeStyles.scrollFadeFadedEnd,\n classNames?.dots,\n )}\n style={slotStyles?.dots}\n onKeyDown={handleDotsKeyDown}\n >\n {slides.map((_, index) => (\n <InteractableDiv\n key={`carousel-dot-${index}`}\n id={dotId(index)}\n role='tab'\n aria-label={text.goToSlide(index + 1)}\n aria-selected={index === realIndex}\n aria-controls={slideId(index)}\n // One tab stop for the whole set, arrow keys inside it.\n tabIndex={index === realIndex ? 0 : -1}\n onClick={() => goToIndex(index)}\n className={cx(styles.carouselDot, index === realIndex && styles.carouselDotActive, classNames?.dot)}\n style={slotStyles?.dot}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction buildTrackTransform(position: number, dragPercent: number, slideWidthPercent: number): string {\n return `translateX(calc(${-position * slideWidthPercent}% + ${dragPercent * (slideWidthPercent / 100)}%))`;\n}\n\nfunction clampIndex(index: number, count: number, canLoop: boolean): number {\n if (count === 0) return 0;\n if (canLoop) return ((index % count) + count) % count;\n return Math.max(0, Math.min(count - 1, index));\n}\n\nexport default Carousel;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"carousel.mjs","names":[],"sources":["../../../../package/common/carousel/carousel.tsx"],"sourcesContent":["import React, { useEffect, useLayoutEffect, useRef, useState } from 'react';\nimport cx from 'classnames';\nimport { faChevronLeft, faChevronRight } from '@fortawesome/free-solid-svg-icons';\n\nimport ActionIcon from '../actionIcon';\nimport InteractableDiv from '../interactableDiv';\nimport { useComponentDefaults, useLabels } from '../configProvider';\nimport type { CarouselLabels, CarouselProps } from './carousel.types';\n\nimport styles from './carousel.module.pcss';\nimport fadeStyles from 'components/common/styles/scrollFade.module.pcss';\nimport { ButtonStyleType } from '../button/button.types';\n\n// Opaque, because the arrows sit over the slide's own image; Neutral's fill is see-through.\nconst ARROW_COLOR = 'var(--background-accent)';\n\nconst AXIS_LOCK_THRESHOLD = 10;\nconst DRAG_COMMIT_RATIO = 0.2;\n\nconst DEFAULT_LABELS: Required<CarouselLabels> = {\n previous: 'Previous slide',\n next: 'Next slide',\n slides: 'Slides',\n goToSlide: (slide) => `Go to slide ${slide}`,\n};\n\nfunction Carousel(props: CarouselProps) {\n const {\n children,\n currentIndex,\n defaultIndex = 0,\n onChange = () => {},\n loop = true,\n autoPlay = false,\n autoPlayInterval = 4000,\n pauseOnHover = true,\n showArrows = true,\n showDots = true,\n swipeable = true,\n lazyRender = false,\n adaptiveHeight = false,\n className,\n style,\n classNames,\n styles: slotStyles,\n labels,\n ...rest\n } = useComponentDefaults('Carousel', props);\n const text = useLabels('Carousel', labels, DEFAULT_LABELS);\n\n const instanceId = React.useId();\n const slides = React.Children.toArray(children);\n const count = slides.length;\n const canLoop = loop && count > 1;\n const offset = canLoop ? 1 : 0;\n const extendedSlides = canLoop ? [slides[count - 1], ...slides, slides[0]] : slides;\n\n const isControlled = currentIndex !== undefined;\n const [internalIndex, setInternalIndex] = useState(() => clampIndex(defaultIndex, count, canLoop));\n const realIndex = clampIndex(isControlled ? currentIndex! : internalIndex, count, canLoop);\n\n const [displayIndex, setDisplayIndex] = useState(realIndex + offset);\n const [transitionEnabled, setTransitionEnabled] = useState(true);\n const prevRealIndexRef = useRef(realIndex);\n\n const [hovered, setHovered] = useState(false);\n const [focused, setFocused] = useState(false);\n const [dragging, setDragging] = useState(false);\n\n const containerRef = useRef<HTMLDivElement>(null);\n const trackRef = useRef<HTMLDivElement>(null);\n const dotsRef = useRef<HTMLDivElement>(null);\n\n const slideWidthPercent = extendedSlides.length > 0 ? 100 / extendedSlides.length : 100;\n\n useLayoutEffect(() => {\n const prevReal = prevRealIndexRef.current;\n prevRealIndexRef.current = realIndex;\n if (prevReal === realIndex) return;\n\n // A wrap parks the track on a clone until transitionEnd swaps it back, so a change arriving\n // before that has to animate from the normalised position rather than the clone.\n const lastExtendedIndex = extendedSlides.length - 1;\n let fromIndex = displayIndex;\n if (canLoop && displayIndex === 0) fromIndex = count;\n else if (canLoop && displayIndex === lastExtendedIndex) fromIndex = 1;\n\n const forwardWrap = canLoop && prevReal === count - 1 && realIndex === 0;\n const backwardWrap = canLoop && prevReal === 0 && realIndex === count - 1;\n\n let target: number;\n if (forwardWrap) target = fromIndex + 1;\n else if (backwardWrap) target = fromIndex - 1;\n else target = realIndex + offset;\n\n // Written straight to the node: the normalised position has to reach style recalculation on its\n // own, or it and the animated position collapse into one jump with no transition.\n const track = trackRef.current;\n if (fromIndex !== displayIndex && track) {\n track.style.transition = 'none';\n track.style.transform = buildTrackTransform(fromIndex, 0, slideWidthPercent);\n void track.offsetWidth;\n track.style.transition = '';\n }\n\n setTransitionEnabled(true);\n setDisplayIndex(target);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [realIndex]);\n\n // The window of slides `lazyRender` keeps mounted, as of the last settled position. Slides are\n // rendered for the union of this and the current window, so the ones a multi-step jump slides\n // past stay mounted until the transform transition ends instead of blanking out mid-flight.\n const [settledMountRange, setSettledMountRange] = useState(() => ({\n min: realIndex + offset - 1,\n max: realIndex + offset + 1,\n }));\n const mountMin = Math.min(settledMountRange.min, displayIndex - 1);\n const mountMax = Math.max(settledMountRange.max, displayIndex + 1);\n\n const [contentHeight, setContentHeight] = useState<number | undefined>(undefined);\n\n useLayoutEffect(() => {\n if (!adaptiveHeight) return;\n const slideElement = trackRef.current?.children[displayIndex] as HTMLElement | undefined;\n if (!slideElement) return;\n\n const update = () => setContentHeight(slideElement.offsetHeight);\n update();\n\n const observer = new ResizeObserver(update);\n observer.observe(slideElement);\n return () => observer.disconnect();\n }, [adaptiveHeight, displayIndex, count]);\n\n // Keeps the selected dot in view. Written as `scrollLeft` because `scrollIntoView` is free to\n // scroll the page along with it.\n useLayoutEffect(() => {\n const strip = dotsRef.current;\n const dot = strip?.children[realIndex] as HTMLElement | undefined;\n if (!strip || !dot) return;\n strip.scrollLeft = dot.offsetLeft - (strip.clientWidth - dot.offsetWidth) / 2;\n }, [realIndex, count]);\n\n function goToIndex(nextIndex: number) {\n const clamped = clampIndex(nextIndex, count, canLoop);\n if (!isControlled) setInternalIndex(clamped);\n onChange(clamped);\n }\n\n function goNext() {\n if (!canLoop && realIndex >= count - 1) return;\n goToIndex(realIndex + 1);\n }\n\n function goPrev() {\n if (!canLoop && realIndex <= 0) return;\n goToIndex(realIndex - 1);\n }\n\n function handleTrackTransitionEnd(event: React.TransitionEvent<HTMLDivElement>) {\n if (event.target !== event.currentTarget) return;\n setSettledMountRange({ min: displayIndex - 1, max: displayIndex + 1 });\n\n if (!canLoop) return;\n if (displayIndex === 0) {\n setTransitionEnabled(false);\n setDisplayIndex(count);\n } else if (displayIndex === extendedSlides.length - 1) {\n setTransitionEnabled(false);\n setDisplayIndex(1);\n }\n }\n\n // Hover and focus only ever pause the timer, so without one they are not worth tracking.\n const tracksPointerPause = autoPlay && pauseOnHover;\n const isPaused = hovered || focused || dragging;\n useEffect(() => {\n if (!autoPlay || count <= 1 || isPaused) return;\n const timer = setInterval(goNext, autoPlayInterval);\n return () => clearInterval(timer);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [autoPlay, autoPlayInterval, isPaused, realIndex, count]);\n\n // A drag follows the pointer through the node, not through state: a render per move event would\n // rebuild every slide and dot for something only the track's transform sees.\n const dragRef = useRef<{\n startX: number;\n startY: number;\n width: number;\n axisLocked: boolean;\n active: boolean;\n offsetPercent: number;\n } | null>(null);\n\n function handlePointerDown(event: React.PointerEvent<HTMLDivElement>) {\n if (!swipeable || count <= 1) return;\n dragRef.current = {\n startX: event.clientX,\n startY: event.clientY,\n // Measured once: measuring per move would force a layout between the transform writes.\n width: containerRef.current?.getBoundingClientRect().width || 1,\n axisLocked: false,\n active: true,\n offsetPercent: 0,\n };\n }\n\n function handlePointerMove(event: React.PointerEvent<HTMLDivElement>) {\n const drag = dragRef.current;\n if (!drag || !drag.active) return;\n\n const deltaX = event.clientX - drag.startX;\n const deltaY = event.clientY - drag.startY;\n\n if (!drag.axisLocked) {\n if (Math.abs(deltaX) < AXIS_LOCK_THRESHOLD && Math.abs(deltaY) < AXIS_LOCK_THRESHOLD) return;\n if (Math.abs(deltaY) > Math.abs(deltaX)) {\n drag.active = false;\n return;\n }\n drag.axisLocked = true;\n // Never on pointerdown: a captured pointer sends its `click` to the capture target too, so\n // capturing earlier would swallow every click meant for a button inside a slide.\n event.currentTarget.setPointerCapture?.(event.pointerId);\n setDragging(true);\n setTransitionEnabled(false);\n }\n\n drag.offsetPercent = (deltaX / drag.width) * 100;\n if (trackRef.current) {\n trackRef.current.style.transform = buildTrackTransform(displayIndex, drag.offsetPercent, slideWidthPercent);\n }\n }\n\n function handlePointerUp() {\n const drag = dragRef.current;\n dragRef.current = null;\n if (!drag || !drag.axisLocked) {\n setDragging(false);\n return;\n }\n\n setTransitionEnabled(true);\n setDragging(false);\n\n // React never saw the dragged transform, so it has to be handed back by hand, and always: a\n // drag that changes no index would otherwise strand the track off-screen. One that does change\n // it overwrites this in the same tick, and still animates on from where the pointer left off.\n if (trackRef.current) {\n trackRef.current.style.transition = '';\n trackRef.current.style.transform = buildTrackTransform(displayIndex, 0, slideWidthPercent);\n }\n\n if (Math.abs(drag.offsetPercent) >= DRAG_COMMIT_RATIO * 100) {\n if (drag.offsetPercent < 0) goNext();\n else goPrev();\n }\n }\n\n // Arrow keys belong to the carousel's own controls, never to the slides: a text field or a\n // scrollable region in a slide has to keep its own. `defaultPrevented` leaves the dots to their\n // own handling below.\n function handleKeyDown(event: React.KeyboardEvent<HTMLDivElement>) {\n if (event.defaultPrevented || trackRef.current?.contains(event.target as Node)) return;\n\n if (event.key === 'ArrowLeft') {\n event.preventDefault();\n goPrev();\n } else if (event.key === 'ArrowRight') {\n event.preventDefault();\n goNext();\n }\n }\n\n function handleDotsKeyDown(event: React.KeyboardEvent<HTMLDivElement>) {\n let next: number | null = null;\n if (event.key === 'ArrowLeft') next = realIndex - 1;\n else if (event.key === 'ArrowRight') next = realIndex + 1;\n else if (event.key === 'Home') next = 0;\n else if (event.key === 'End') next = count - 1;\n if (next === null) return;\n\n event.preventDefault();\n const clamped = clampIndex(next, count, canLoop);\n goToIndex(clamped);\n // The selected dot is the one holding the tab stop, so focus has to travel with the selection.\n (dotsRef.current?.children[clamped] as HTMLElement | undefined)?.focus();\n }\n\n // The dots are the APG tablist over the slides. Without them the slides describe themselves as\n // plain slides rather than as panels.\n const hasTabs = showDots && count > 1;\n const dotId = (index: number) => `${instanceId}-dot-${index}`;\n const slideId = (index: number) => `${instanceId}-slide-${index}`;\n\n // An unnamed landmark is worse than none, so the carousel is only a region once it has a name.\n const isNamed = rest['aria-label'] !== undefined || rest['aria-labelledby'] !== undefined;\n\n function slideSemantics(index: number) {\n if (hasTabs) {\n return { id: slideId(index), role: 'tabpanel', 'aria-labelledby': dotId(index) };\n }\n return {\n id: slideId(index),\n role: 'group',\n 'aria-roledescription': 'slide',\n 'aria-label': `${index + 1} of ${count}`,\n };\n }\n\n const isPrevDisabled = !canLoop && realIndex <= 0;\n const isNextDisabled = !canLoop && realIndex >= count - 1;\n\n const trackTransform = buildTrackTransform(displayIndex, 0, slideWidthPercent);\n\n return (\n <div\n {...rest}\n ref={containerRef}\n role={isNamed ? 'region' : 'group'}\n aria-roledescription='carousel'\n className={cx(styles.carousel, adaptiveHeight && styles.carouselAdaptive, classNames?.root, className)}\n style={{ height: adaptiveHeight ? contentHeight : undefined, ...style, ...slotStyles?.root }}\n onMouseEnter={tracksPointerPause ? () => setHovered(true) : undefined}\n onMouseLeave={tracksPointerPause ? () => setHovered(false) : undefined}\n onFocus={tracksPointerPause ? () => setFocused(true) : undefined}\n onBlur={tracksPointerPause ? () => setFocused(false) : undefined}\n onKeyDown={handleKeyDown}\n >\n <div\n ref={trackRef}\n className={cx(styles.carouselTrack, adaptiveHeight && styles.carouselTrackAdaptive, classNames?.track)}\n style={{\n width: `${extendedSlides.length * 100}%`,\n transform: trackTransform,\n transition: transitionEnabled ? undefined : 'none',\n ...slotStyles?.track,\n }}\n aria-live={autoPlay ? 'off' : 'polite'}\n onTransitionEnd={handleTrackTransitionEnd}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onPointerCancel={handlePointerUp}\n >\n {extendedSlides.map((slide, idx) => {\n const isClonePosition = canLoop && (idx === 0 || idx === extendedSlides.length - 1);\n const logicalIndex = idx - offset;\n const isActive = !isClonePosition && logicalIndex === realIndex;\n const isRendered = !lazyRender || (idx >= mountMin && idx <= mountMax);\n\n return (\n <div\n key={`carousel-slide-${idx}`}\n {...(isClonePosition ? {} : slideSemantics(logicalIndex))}\n className={cx(styles.carouselSlide, classNames?.slide)}\n style={{ width: `${100 / extendedSlides.length}%`, ...slotStyles?.slide }}\n inert={isActive ? undefined : true}\n >\n {isRendered ? slide : null}\n </div>\n );\n })}\n </div>\n\n {showArrows && count > 1 && (\n <>\n <ActionIcon\n styleType={ButtonStyleType.Filled}\n color={ARROW_COLOR}\n icon={faChevronLeft}\n title={text.previous}\n aria-label={text.previous}\n aria-disabled={isPrevDisabled || undefined}\n onClick={() => {\n if (!isPrevDisabled) goPrev();\n }}\n className={cx(\n styles.carouselPrevButton,\n isPrevDisabled && styles.carouselButtonDisabled,\n classNames?.prevButton,\n )}\n style={slotStyles?.prevButton}\n />\n <ActionIcon\n styleType={ButtonStyleType.Filled}\n color={ARROW_COLOR}\n icon={faChevronRight}\n title={text.next}\n aria-label={text.next}\n aria-disabled={isNextDisabled || undefined}\n onClick={() => {\n if (!isNextDisabled) goNext();\n }}\n className={cx(\n styles.carouselNextButton,\n isNextDisabled && styles.carouselButtonDisabled,\n classNames?.nextButton,\n )}\n style={slotStyles?.nextButton}\n />\n </>\n )}\n\n {hasTabs && (\n <div\n ref={dotsRef}\n role='tablist'\n aria-label={text.slides}\n className={cx(\n styles.carouselDots,\n // Both ends always: the strip's own padding holds the outer dots clear of the fade\n // until there is something to scroll, so this needs no measuring.\n fadeStyles.scrollFade,\n fadeStyles.scrollFadeX,\n fadeStyles.scrollFadeFadedStart,\n fadeStyles.scrollFadeFadedEnd,\n classNames?.dots,\n )}\n style={slotStyles?.dots}\n onKeyDown={handleDotsKeyDown}\n >\n {slides.map((_, index) => (\n <InteractableDiv\n key={`carousel-dot-${index}`}\n id={dotId(index)}\n role='tab'\n aria-label={text.goToSlide(index + 1)}\n aria-selected={index === realIndex}\n aria-controls={slideId(index)}\n // One tab stop for the whole set, arrow keys inside it.\n tabIndex={index === realIndex ? 0 : -1}\n onClick={() => goToIndex(index)}\n className={cx(styles.carouselDot, index === realIndex && styles.carouselDotActive, classNames?.dot)}\n style={slotStyles?.dot}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction buildTrackTransform(position: number, dragPercent: number, slideWidthPercent: number): string {\n return `translateX(calc(${-position * slideWidthPercent}% + ${dragPercent * (slideWidthPercent / 100)}%))`;\n}\n\nfunction clampIndex(index: number, count: number, canLoop: boolean): number {\n if (count === 0) return 0;\n if (canLoop) return ((index % count) + count) % count;\n return Math.max(0, Math.min(count - 1, index));\n}\n\nexport default Carousel;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"carousel.module.mjs","names":[],"sources":["../../../../package/common/carousel/carousel.module.pcss"],"sourcesContent":[".carousel {\n position: relative;\n overflow: hidden;\n border-radius: var(--default-border-radius);\n\n &-adaptive {\n transition: height 0.4s ease;\n }\n\n &-track {\n display: flex;\n align-items: stretch;\n transition: transform 0.4s ease;\n touch-action: pan-y;\n user-select: none;\n }\n\n &-trackAdaptive {\n align-items: flex-start;\n }\n\n &-slide {\n flex-shrink: 0;\n box-sizing: border-box;\n }\n\n &-prevButton,\n &-nextButton {\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n z-index: 1;\n width: 36px;\n height: 36px;\n
|
|
1
|
+
{"version":3,"file":"carousel.module.mjs","names":[],"sources":["../../../../package/common/carousel/carousel.module.pcss"],"sourcesContent":[".carousel {\n position: relative;\n overflow: hidden;\n border-radius: var(--default-border-radius);\n\n &-adaptive {\n transition: height 0.4s ease;\n }\n\n &-track {\n display: flex;\n align-items: stretch;\n transition: transform 0.4s ease;\n touch-action: pan-y;\n user-select: none;\n }\n\n &-trackAdaptive {\n align-items: flex-start;\n }\n\n &-slide {\n flex-shrink: 0;\n box-sizing: border-box;\n }\n\n /* Two classes, to outrank Button's radius and ActionIcon's box whichever stylesheet loads\n first. */\n & &-prevButton,\n & &-nextButton {\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n z-index: 1;\n width: 36px;\n height: 36px;\n border-radius: 50%;\n box-shadow: var(--card-shadow);\n transition: opacity 0.15s;\n }\n\n &-buttonDisabled {\n opacity: 0.35;\n pointer-events: none;\n }\n\n &-prevButton {\n left: 12px;\n }\n\n &-nextButton {\n right: 12px;\n }\n\n /* A scroll strip rather than a row that shrinks, so the dots keep their size at any slide count.\n The padding holds the outer dots clear of the fade until the strip has somewhere to scroll. */\n &-dots {\n position: absolute;\n bottom: 4px;\n left: 50%;\n transform: translateX(-50%);\n z-index: 1;\n display: flex;\n box-sizing: border-box;\n width: max-content;\n max-width: 100%;\n padding-inline: 16px;\n overflow-x: auto;\n overscroll-behavior-x: contain;\n scroll-behavior: smooth;\n\n /* Matches the strip's own `padding-inline`, so the first and last dot start out clear of the\n fade. The shared sheet's private length, not `--scroll-fade-length`, which would inherit. */\n --custom-scroll-fade-length: 16px;\n\n scrollbar-width: none;\n\n &::-webkit-scrollbar {\n display: none;\n }\n\n @media (prefers-reduced-motion: reduce) {\n scroll-behavior: auto;\n }\n }\n\n /* The dot stays 8px, its padding carries the hit area out to the 24px minimum. */\n &-dot {\n box-sizing: content-box;\n\n /* The strip is width-capped, and shrinking would pull the content box, the only part\n `background-clip` paints, down to nothing. */\n flex-shrink: 0;\n width: 8px;\n height: 8px;\n padding: 8px;\n border-radius: 2000px;\n background: var(--background-accent);\n background-clip: content-box;\n opacity: 0.6;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n transition:\n opacity 0.15s,\n background 0.15s,\n width 0.15s;\n\n &:hover {\n opacity: 0.85;\n }\n\n &:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--primary-lighter);\n }\n\n &-active {\n background: var(--primary-color);\n background-clip: content-box;\n opacity: 1;\n width: 20px;\n }\n }\n}\n"],"mappings":""}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{useLabels as t}from"../configProvider/useLabels.mjs";import{isSelfActivation as n}from"../utils/activationKey.mjs";import r
|
|
1
|
+
"use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{useLabels as t}from"../configProvider/useLabels.mjs";import{isSelfActivation as n}from"../utils/activationKey.mjs";import{ThemeColor as r}from"../themeProvider/color.types.mjs";import{toneProps as i,useToneCheck as a}from"../styles/tone.mjs";import o from"../ripple/ripple.mjs";import s from"../actionIcon/actionIcon.mjs";import c from"../interactableDiv/index.mjs";import{ChipStyleType as l}from"./chip.types.mjs";import u from"./chip.module.mjs";import{useMemo as d,useRef as f}from"react";import p from"classnames";import{faXmarkCircle as m}from"@fortawesome/free-solid-svg-icons";import{jsx as h,jsxs as g}from"react/jsx-runtime";var _={filled:u.chipStyleFilled,light:u.chipStyleLight,outlined:u.chipStyleOutlined},v={remove:`Remove`};function y(y){let{className:b=``,thumbnail:x=``,text:S=``,styleType:C=l.Light,color:w=r.Neutral,showRemoveIcon:T=!1,labels:E,onClick:D,onRemove:O,style:k,classNames:A,styles:j,...M}=e(`Chip`,y),N=t(`Chip`,E,v),P=f(null),F=i(w);a(`Chip`,[w]);function I(e){D&&n(e)&&P.current?.addRipple()}let L=d(()=>{if(typeof x==`string`&&x.startsWith(`http`))return x},[x]);return h(c,{...M,className:p(u.chip,F.className,_[C],D&&u.chipClickable,b,A?.root),style:{...F.style,...k,...j?.root},onClick:D,onKeyDown:I,children:h(o,{ref:P,disabled:!D,style:{borderRadius:`inherit`},children:g(`div`,{className:p(u.chipInner,A?.inner),style:j?.inner,children:[x&&h(`div`,{className:p(u.chipThumbnail,A?.thumbnail),style:{...L?{backgroundImage:`url(${L})`}:{},...j?.thumbnail},children:!L&&x}),h(`div`,{className:p(u.chipText,A?.text),style:j?.text,children:S}),T&&h(s,{icon:m,className:A?.removeIcon,style:j?.removeIcon,"aria-label":N.remove,onClick:e=>{e.stopPropagation(),O?.()}})]})})})}export{y as default};
|
|
2
2
|
//# sourceMappingURL=chip.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chip.mjs","names":[],"sources":["../../../../package/common/chip/chip.tsx"],"sourcesContent":["import React, { useMemo, useRef } from 'react';\nimport { faXmarkCircle } from '@fortawesome/free-solid-svg-icons';\nimport cx from 'classnames';\n\nimport Ripple from '../ripple';\nimport type { RippleHandle } from '../ripple';\nimport InteractableDiv from '../interactableDiv';\nimport ActionIcon from '../actionIcon';\nimport { ChipStyleType, ChipProps } from './chip.types';\nimport type { ChipLabels } from './chip.types';\nimport { useComponentDefaults, useLabels } from '../configProvider';\nimport { isSelfActivation } from '../utils/activationKey';\n\nimport styles from './chip.module.pcss';\n\nconst CLASS_BY_STYLE: Record<ChipStyleType, string> = {\n
|
|
1
|
+
{"version":3,"file":"chip.mjs","names":[],"sources":["../../../../package/common/chip/chip.tsx"],"sourcesContent":["import React, { useMemo, useRef } from 'react';\nimport { faXmarkCircle } from '@fortawesome/free-solid-svg-icons';\nimport cx from 'classnames';\n\nimport Ripple from '../ripple';\nimport type { RippleHandle } from '../ripple';\nimport InteractableDiv from '../interactableDiv';\nimport ActionIcon from '../actionIcon';\nimport { ChipStyleType, ChipProps } from './chip.types';\nimport type { ChipLabels } from './chip.types';\nimport { useComponentDefaults, useLabels } from '../configProvider';\nimport { isSelfActivation } from '../utils/activationKey';\nimport { ThemeColor } from '../themeProvider/color.types';\nimport { toneProps, useToneCheck } from '../styles/tone';\n\nimport styles from './chip.module.pcss';\n\nconst CLASS_BY_STYLE: Record<ChipStyleType, string> = {\n filled: styles.chipStyleFilled,\n light: styles.chipStyleLight,\n outlined: styles.chipStyleOutlined,\n};\n\nconst DEFAULT_LABELS: Required<ChipLabels> = {\n remove: 'Remove',\n};\n\nfunction Chip(props: ChipProps) {\n const {\n className = '',\n thumbnail = '',\n text = '',\n styleType = ChipStyleType.Light,\n color = ThemeColor.Neutral,\n showRemoveIcon = false,\n labels,\n onClick,\n onRemove,\n style,\n classNames,\n styles: slotStyles,\n ...rest\n } = useComponentDefaults('Chip', props);\n const resolvedLabels = useLabels('Chip', labels, DEFAULT_LABELS);\n const rippleRef = useRef<RippleHandle>(null);\n const tone = toneProps(color);\n useToneCheck('Chip', [color]);\n\n // Keyboard activation calls onClick directly without dispatching a DOM click, so Ripple's own\n // listener never sees it.\n function handleKeyDown(event: React.KeyboardEvent<HTMLDivElement>) {\n if (onClick && isSelfActivation(event)) rippleRef.current?.addRipple();\n }\n\n const thumbnailUrl = useMemo(() => {\n if (typeof thumbnail === 'string' && thumbnail.startsWith('http')) return thumbnail;\n return undefined;\n }, [thumbnail]);\n\n return (\n <InteractableDiv\n {...rest}\n className={cx(\n styles.chip,\n tone.className,\n CLASS_BY_STYLE[styleType],\n onClick && styles.chipClickable,\n className,\n classNames?.root,\n )}\n style={{ ...tone.style, ...style, ...slotStyles?.root }}\n onClick={onClick}\n onKeyDown={handleKeyDown}\n >\n <Ripple ref={rippleRef} disabled={!onClick} style={{ borderRadius: 'inherit' }}>\n <div className={cx(styles.chipInner, classNames?.inner)} style={slotStyles?.inner}>\n {thumbnail && (\n <div\n className={cx(styles.chipThumbnail, classNames?.thumbnail)}\n style={{\n ...(thumbnailUrl ? { backgroundImage: `url(${thumbnailUrl})` } : {}),\n ...slotStyles?.thumbnail,\n }}\n >\n {!thumbnailUrl && thumbnail}\n </div>\n )}\n <div className={cx(styles.chipText, classNames?.text)} style={slotStyles?.text}>\n {text}\n </div>\n {showRemoveIcon && (\n <ActionIcon\n icon={faXmarkCircle}\n className={classNames?.removeIcon}\n style={slotStyles?.removeIcon}\n aria-label={resolvedLabels.remove}\n onClick={(e) => {\n e.stopPropagation();\n onRemove?.();\n }}\n />\n )}\n </div>\n </Ripple>\n </InteractableDiv>\n );\n}\n\nexport default Chip;\n"],"mappings":"guBAiBA,IAAM,EAAgD,CACpD,OAAQ,EAAO,gBACf,MAAO,EAAO,eACd,SAAU,EAAO,iBACnB,EAEM,EAAuC,CAC3C,OAAQ,QACV,EAEA,SAAS,EAAK,EAAkB,CAC9B,GAAM,CACJ,YAAY,GACZ,YAAY,GACZ,OAAO,GACP,YAAY,EAAc,MAC1B,QAAQ,EAAW,QACnB,iBAAiB,GACjB,SACA,UACA,WACA,QACA,aACA,OAAQ,EACR,GAAG,GACD,EAAqB,OAAQ,CAAK,EAChC,EAAiB,EAAU,OAAQ,EAAQ,CAAc,EACzD,EAAY,EAAqB,IAAI,EACrC,EAAO,EAAU,CAAK,EAC5B,EAAa,OAAQ,CAAC,CAAK,CAAC,EAI5B,SAAS,EAAc,EAA4C,CAC7D,GAAW,EAAiB,CAAK,GAAG,EAAU,SAAS,UAAU,CACvE,CAEA,IAAM,EAAe,MAAc,CACjC,GAAI,OAAO,GAAc,UAAY,EAAU,WAAW,MAAM,EAAG,OAAO,CAE5E,EAAG,CAAC,CAAS,CAAC,EAEd,OACE,EAAC,EAAD,CACE,GAAI,EACJ,UAAW,EACT,EAAO,KACP,EAAK,UACL,EAAe,GACf,GAAW,EAAO,cAClB,EACA,GAAY,IACd,EACA,MAAO,CAAE,GAAG,EAAK,MAAO,GAAG,EAAO,GAAG,GAAY,IAAK,EAC7C,UACT,UAAW,EAEX,SAAA,EAAC,EAAD,CAAQ,IAAK,EAAW,SAAU,CAAC,EAAS,MAAO,CAAE,aAAc,SAAU,EAC3E,SAAA,EAAC,MAAD,CAAK,UAAW,EAAG,EAAO,UAAW,GAAY,KAAK,EAAG,MAAO,GAAY,MAA5E,SAAA,CACG,GACC,EAAC,MAAD,CACE,UAAW,EAAG,EAAO,cAAe,GAAY,SAAS,EACzD,MAAO,CACL,GAAI,EAAe,CAAE,gBAAiB,OAAO,EAAa,EAAG,EAAI,CAAC,EAClE,GAAG,GAAY,SACjB,EAEC,SAAA,CAAC,GAAgB,CACf,CAAA,EAEP,EAAC,MAAD,CAAK,UAAW,EAAG,EAAO,SAAU,GAAY,IAAI,EAAG,MAAO,GAAY,KACvE,SAAA,CACE,CAAA,EACJ,GACC,EAAC,EAAD,CACE,KAAM,EACN,UAAW,GAAY,WACvB,MAAO,GAAY,WACnB,aAAY,EAAe,OAC3B,QAAU,GAAM,CACd,EAAE,gBAAgB,EAClB,IAAW,CACb,CACD,CAAA,CAEA,GACC,CAAA,CACO,CAAA,CAErB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";var e=`chip_rCTMl`,t=`chip-clickable_WTVjG`,n=`chip-style-
|
|
1
|
+
"use client";var e=`chip_rCTMl`,t=`chip-clickable_WTVjG`,n=`chip-style-filled_gYANL`,r=`chip-style-light_5J4XG`,i=`chip-style-outlined_JFI-K`,a=`chip-inner_mfo-w`,o=`chip-text_d1juf`,s=`chip-thumbnail_-A7eU`,c=`chip-container_oNNmF`,l=`chip-container-inline_11QHw`,u={chip:e,"chip-clickable":`chip-clickable_WTVjG`,chipClickable:t,"chip-style-filled":`chip-style-filled_gYANL`,chipStyleFilled:n,"chip-style-light":`chip-style-light_5J4XG`,chipStyleLight:r,"chip-style-outlined":`chip-style-outlined_JFI-K`,chipStyleOutlined:i,"chip-inner":`chip-inner_mfo-w`,chipInner:a,"chip-text":`chip-text_d1juf`,chipText:o,"chip-thumbnail":`chip-thumbnail_-A7eU`,chipThumbnail:s,"chip-container":`chip-container_oNNmF`,chipContainer:c,"chip-container-inline":`chip-container-inline_11QHw`,chipContainerInline:l};export{e as chip,t as chipClickable,c as chipContainer,l as chipContainerInline,a as chipInner,n as chipStyleFilled,r as chipStyleLight,i as chipStyleOutlined,o as chipText,s as chipThumbnail,u as default};
|
|
2
2
|
//# sourceMappingURL=chip.module.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chip.module.mjs","names":[],"sources":["../../../../package/common/chip/chip.module.pcss"],"sourcesContent":[".chip {\n
|
|
1
|
+
{"version":3,"file":"chip.module.mjs","names":[],"sources":["../../../../package/common/chip/chip.module.pcss"],"sourcesContent":[".chip {\n border-radius: 99999px;\n width: fit-content;\n position: relative;\n box-sizing: border-box;\n max-width: 100%;\n\n &-clickable {\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n }\n\n &-style {\n &-filled {\n background: var(--tone-fill);\n\n /* Must follow the shorthand above, which resets background-image. */\n background-image: var(--tone-gradient);\n color: var(--tone-contrast);\n }\n\n &-light {\n background: var(--tone-light);\n color: var(--tone-text);\n }\n\n /* An inset shadow rather than a border, so an outlined chip is exactly as big as the rest. */\n &-outlined {\n box-shadow: inset 0 0 0 1px var(--tone-outline);\n color: var(--tone-text);\n }\n }\n\n &-inner {\n display: flex;\n gap: 8px;\n align-items: center;\n padding: 4px 8px;\n\n & > * {\n white-space: nowrap;\n }\n }\n\n &-text {\n text-overflow: ellipsis;\n overflow: hidden;\n }\n\n &-thumbnail {\n display: flex;\n justify-content: center;\n align-items: center;\n width: 18px;\n height: 18px;\n background: rgb(0 0 0 / 8%);\n border-radius: 18px;\n overflow: hidden;\n background-size: cover;\n }\n\n &-container {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n\n &-inline {\n flex-wrap: nowrap;\n overflow: auto;\n }\n }\n}\n"],"mappings":""}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";var e=function(e){return e.
|
|
1
|
+
"use client";var e=function(e){return e.Filled=`filled`,e.Light=`light`,e.Outlined=`outlined`,e}({});export{e as ChipStyleType};
|
|
2
2
|
//# sourceMappingURL=chip.types.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chip.types.mjs","names":[],"sources":["../../../../package/common/chip/chip.types.ts"],"sourcesContent":["import type { HtmlProps, SlotClassNames, SlotStyles } from '../types/slots.types';\n\nexport enum ChipStyleType {\n
|
|
1
|
+
{"version":3,"file":"chip.types.mjs","names":[],"sources":["../../../../package/common/chip/chip.types.ts"],"sourcesContent":["import type { HtmlProps, SlotClassNames, SlotStyles } from '../types/slots.types';\nimport type { ColorValue } from '../themeProvider/color.types';\n\n/** How much the chip stands out. Independent of its colour. */\nexport enum ChipStyleType {\n /** Solid fill. */\n Filled = 'filled',\n /** A light tint of the colour behind text in the colour. The default. */\n Light = 'light',\n /** Border and text in the colour, no fill. */\n Outlined = 'outlined',\n}\n\n/** Text Chip renders of its own, for translating it. */\nexport interface ChipLabels {\n /** The remove button, read out by screen readers (default `Remove`). */\n remove?: string;\n}\n\nexport type ChipSlots = 'root' | 'inner' | 'thumbnail' | 'text' | 'removeIcon';\n\nexport interface ChipProps extends HtmlProps {\n className?: string;\n text?: string;\n thumbnail?: React.ReactNode;\n styleType?: ChipStyleType;\n /** A `ThemeColor` (default `Neutral`) or any CSS colour, such as `'var(--brand)'`. */\n color?: ColorValue;\n showRemoveIcon?: boolean;\n /** Accessible name for the remove button. Default `'Remove'`. */\n onClick?: () => void;\n onRemove?: () => void;\n /** Overrides the text Chip renders of its own. Merged per key. */\n labels?: ChipLabels;\n /** Classes for the inner elements. See `ChipSlots`. */\n classNames?: SlotClassNames<ChipSlots>;\n /** Inline styles for the inner elements. See `ChipSlots`. */\n styles?: SlotStyles<ChipSlots>;\n}\n\nexport interface ChipContainerProps extends HtmlProps {\n className?: string;\n children?: React.ReactNode;\n inline?: boolean;\n}\n"],"mappings":"aAIA,IAAY,EAAL,SAAA,EAAA,OAEL,GAAA,OAAA,SAEA,EAAA,MAAA,QAEA,EAAA,SAAA,YACF,EAAA,CAAA,CAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{useLabels as e}from"../configProvider/useLabels.mjs";import t from"../interactableDiv/index.mjs";import{PopoverAlign as
|
|
1
|
+
"use client";import{useLabels as e}from"../configProvider/useLabels.mjs";import{ButtonStyleType as t}from"../button/button.types.mjs";import n from"../actionIcon/actionIcon.mjs";import r from"../interactableDiv/index.mjs";import{PopoverAlign as i,PopoverPlacement as a}from"../popover/popover.types.mjs";import o from"../popover/popover.mjs";import s from"../input/input.mjs";import{toHex as c}from"./toHex.mjs";import l from"./colorPicker.module.mjs";import{useRef as u,useState as d}from"react";import f from"classnames";import{faEyeDropper as p}from"@fortawesome/free-solid-svg-icons";import{jsx as m,jsxs as h}from"react/jsx-runtime";var g=typeof window<`u`&&`EyeDropper`in window;async function _(){let e=window.EyeDropper;if(!e)return null;try{return(await new e().open()).sRGBHex}catch{return null}}function v(e){return Math.max(0,Math.min(100,e))}function y(e){return/^#[0-9a-fA-F]{6}$/.test(e)||/^#[0-9a-fA-F]{8}$/.test(e)}function b(e){return/^#[0-9a-fA-F]{8}$/.test(e)?{hex6:e.slice(0,7),alpha:parseInt(e.slice(7,9),16)/255*100}:{hex6:e.slice(0,7),alpha:100}}function x(e,t,n){return!n||t>=100?e:`${e}${Math.round(t/100*255).toString(16).padStart(2,`0`)}`}function S(e,t){return`rgba(${parseInt(e.slice(1,3),16)}, ${parseInt(e.slice(3,5),16)}, ${parseInt(e.slice(5,7),16)}, ${t/100})`}function C(e){let t=parseInt(e.slice(1,3),16)/255,n=parseInt(e.slice(3,5),16)/255,r=parseInt(e.slice(5,7),16)/255,i=Math.max(t,n,r),a=i-Math.min(t,n,r),o=0;a!==0&&(o=i===t?(n-r)/a%6:i===n?(r-t)/a+2:(t-n)/a+4,o*=60,o<0&&(o+=360));let s=i===0?0:a/i*100,c=i*100;return{h:o,s,v:c}}function w(e,t,n){let r=t/100,i=n/100,a=i*r,o=a*(1-Math.abs(e/60%2-1)),s=i-a,c=0,l=0,u=0;e<60?(c=a,l=o,u=0):e<120?(c=o,l=a,u=0):e<180?(c=0,l=a,u=o):e<240?(c=0,l=o,u=a):e<300?(c=o,l=0,u=a):(c=a,l=0,u=o);let d=e=>Math.round((e+s)*255).toString(16).padStart(2,`0`);return`#${d(c)}${d(l)}${d(u)}`}function T({hex:e,onChange:t,useInputComponent:n=!1,className:r,style:i}){let[a,o]=d(e),[c,u]=d(e);e!==c&&(u(e),o(e));function p(e){o(e);let n=e.startsWith(`#`)?e:`#${e}`;y(n)&&t(n)}function h(){y(a.startsWith(`#`)?a:`#${a}`)||o(e)}return n?m(s,{value:a,onChange:e=>p(e),onBlur:h}):m(`input`,{type:`text`,value:a,onChange:e=>p(e.target.value),onBlur:h,className:f(l.hexInput,r),style:i,spellCheck:!1})}function E({hue:e,sat:r,val:i,alpha:a,onHueChange:o,onSVChange:s,onAlphaChange:c,showInput:d=!0,showAlpha:y=!1,labels:S,classNames:E,styles:D}){let O=u(null);function k(e){let t=O.current.getBoundingClientRect(),n=Math.max(0,Math.min(1,(e.clientX-t.left)/t.width)),r=Math.max(0,Math.min(1,(e.clientY-t.top)/t.height));return{s:n*100,v:(1-r)*100}}function A(e){let t=e.shiftKey?10:1,n=r,a=i;switch(e.key){case`ArrowLeft`:n-=t;break;case`ArrowRight`:n+=t;break;case`ArrowUp`:a+=t;break;case`ArrowDown`:a-=t;break;case`Home`:n=0;break;case`End`:n=100;break;case`PageUp`:a=100;break;case`PageDown`:a=0;break;default:return}e.preventDefault(),s(v(n),v(a))}function j(e){e.currentTarget.setPointerCapture(e.pointerId);let{s:t,v:n}=k(e);s(t,n);let r=e=>{let{s:t,v:n}=k(e);s(t,n)},i=()=>{window.removeEventListener(`pointermove`,r),window.removeEventListener(`pointerup`,i)};window.addEventListener(`pointermove`,r),window.addEventListener(`pointerup`,i)}function M(e){let{hex6:t,alpha:n}=b(e),{h:r,s:i,v:a}=C(t);o(r),s(i,a),y&&c(n)}let N=w(e,r,i),P=y?x(N,a,!0):N;return h(`div`,{className:f(l.panel,E?.panel),style:D?.panel,children:[h(`div`,{ref:O,role:`slider`,tabIndex:0,"aria-label":S.saturationAndBrightness,"aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":Math.round(r),"aria-valuetext":S.saturationAndBrightnessValue(Math.round(r),Math.round(i)),className:f(l.gradientArea,E?.gradient),style:{"--hue":e,...D?.gradient},onPointerDown:j,onKeyDown:A,children:[m(`div`,{className:l.gradientOverlay}),m(`div`,{className:l.cursor,style:{left:`${r}%`,top:`${100-i}%`}})]}),m(`input`,{type:`range`,min:0,max:359,value:Math.round(e),onChange:e=>o(Number(e.target.value)),className:f(l.hueSlider,E?.hueSlider),style:D?.hueSlider}),y&&m(`input`,{type:`range`,min:0,max:100,value:Math.round(a),onChange:e=>c(Number(e.target.value)),className:f(l.alphaSlider,E?.alphaSlider),style:{"--alpha-color":N,...D?.alphaSlider}}),(d||g)&&h(`div`,{className:l.hexRow,children:[d&&m(T,{hex:P,onChange:M,className:E?.hexInput,style:D?.hexInput}),g&&m(n,{icon:p,styleType:t.Outlined,className:f(l.eyeDropperButton,E?.eyeDropper),style:D?.eyeDropper,onClick:async()=>{let e=await _();e&&M(e)},"aria-label":S.pickFromScreen})]})]})}var D=`#3b82f6`,O={pickFromScreen:`Pick color from screen`,saturationAndBrightness:`Saturation and brightness`,saturationAndBrightnessValue:(e,t)=>`${e}% saturation, ${t}% brightness`};function k({className:t,value:n=D,onChange:s,showInput:p=!1,showAlpha:g=!1,inline:_=!1,labels:v,style:y,classNames:k,styles:A,...j}){let M=e(`ColorPicker`,v,O),[N,P]=d(!1),{hex6:F,alpha:I}=b(c(n)??D),L=C(F),[R,z]=d({h:L.h,s:L.s,v:L.v,a:I}),B=u(R),[V,H]=d(n);if(n!==V){H(n);let{hex6:e,alpha:t}=b(c(n)??D);if(e!==w(R.h,R.s,R.v)||t!==R.a){let n=C(e);z({h:n.h,s:n.s,v:n.v,a:t})}}let{h:U,s:W,v:G,a:K}=R;function q(e,t,n,r){s?.(x(w(e,t,n),r,g))}function J(e){B.current.h=e,z(t=>({...t,h:e})),q(e,B.current.s,B.current.v,B.current.a)}function Y(e,t){B.current.s=e,B.current.v=t,z(n=>({...n,s:e,v:t})),q(B.current.h,e,t,B.current.a)}function X(e){B.current.a=e,z(t=>({...t,a:e})),q(B.current.h,B.current.s,B.current.v,e)}let Z=w(U,W,G),ee=g?S(Z,K):Z,Q=x(Z,K,g),$={hue:U,sat:W,val:G,alpha:K,onHueChange:J,onSVChange:Y,onAlphaChange:X,showAlpha:g,labels:M,classNames:k,styles:A};return _?m(`div`,{...j,className:f(l.colorPicker,t,k?.root),style:{...y,...A?.root},children:m(E,{...$,showInput:p})}):h(`div`,{...j,className:f(l.colorPicker,t),children:[m(o,{isOpen:N,onOpenChange:P,placement:a.Bottom,align:i.Start,constrainWidth:!1,content:m(E,{...$}),children:h(r,{role:`button`,tabIndex:0,"aria-haspopup":`dialog`,"aria-expanded":N,className:f(l.swatch,k?.swatch),style:A?.swatch,children:[m(`div`,{className:l.swatchFill,style:{background:ee}}),m(`span`,{className:l.swatchHex,children:Q})]})}),p&&m(T,{hex:Q,onChange:e=>s?.(e),useInputComponent:!0})]})}export{k as default};
|
|
2
2
|
//# sourceMappingURL=colorPicker.mjs.map
|