@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,2 +1,2 @@
|
|
|
1
|
-
"use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{useLabels as t}from"../configProvider/useLabels.mjs";import{ButtonSize as n}from"../button/button.types.mjs";import r from"../button/button.mjs";import i from"../actionIcon/actionIcon.mjs";import"./timer.chime.mjs";import a from"./timer.module.mjs";import{useEffect as o,useImperativeHandle as ee,useMemo as te,useRef as s,useState as c}from"react";import l from"classnames";import{faMinus as ne,faPause as re,faPlay as ie,faPlus as ae,faXmark as oe}from"@fortawesome/free-solid-svg-icons";import{jsx as u,jsxs as d}from"react/jsx-runtime";var se=200,ce=1e3,le={cancel:`Cancel timer`};function ue(){return typeof window<`u`&&window.matchMedia?.(`(prefers-reduced-motion: reduce)`).matches===!0}function de(e){let t=Math.ceil(e/1e3),n=Math.floor(t/3600),r=Math.floor(t%3600/60),i=t%60,a=String(r).padStart(2,`0`),o=String(i).padStart(2,`0`);return n>0?`${n}:${a}:${o}`:`${a}:${o}`}function f(f){let{ref:fe,durationSeconds:p,autoStart:m=!0,resetOnDurationChange:pe=!0,onTick:h,onComplete:me,onStart:he,onPause:ge,onResume:_e,onCancel:ve,onAddTime:g,onRemoveTime:ye,showControls:_=!0,hideAddButton:be=!1,hideRemoveButton:xe=!1,hidePauseButton:Se=!1,hideCancelButton:Ce=!1,adjustSeconds:v=30,maxSeconds:y,label:b,formatTime:we=de,size:x,strokeWidth:S=10,counterClockwise:Te=!1,urgentThreshold:Ee=.1,urgentMinSeconds:De=3,pulseOnUrgent:Oe=!0,showRunningRipples:C=!1,playSoundOnComplete:w=!1,soundUrl:T,soundVolume:ke=.5,notifyOnComplete:E=!1,notificationTitle:Ae,notificationBody:je,className:Me,style:Ne,classNames:D,styles:O,labels:Pe,...Fe}=e(`Timer`,f),Ie=t(`Timer`,Pe,le),k=p*1e3,[A,Le]=c(m?`running`:`idle`),[j,Re]=c(k),[ze,Be]=c(0),[M,N]=c([]),P=s(j),F=s(A),I=s(k),L=s(!1),R=s(!1),z=s(!1),Ve=s(0);function B(e){P.current=e,Re(e)}function V(e){F.current=e,Le(e)}function H(){Be(e=>e+1)}o(()=>{if(A!==`running`)return;let e=Date.now(),t=P.current,n=setInterval(()=>{let n=Math.max(0,t-(Date.now()-e));B(n),h?.(n),n<=0&&V(`completed`)},se);return()=>clearInterval(n)},[A,ze]),o(()=>{if(A===`completed`&&!L.current){if(L.current=!0,me?.(),w)try{let e=new Audio(T||`data:audio/wav;base64,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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANACUAKwAKAMr/kv+R/9n/TwCxALwAVwCs/xb/8/5p/0YAFgFfAeYA3f/N/lP+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`);e.volume=ke,e.play()?.catch(()=>{})}catch{}if(E&&typeof Notification<`u`&&Notification.permission===`granted`)try{new Notification(Ae??`Timer done`,{body:je??(typeof b==`string`?b:void 0)})}catch{}}A!==`completed`&&(L.current=!1)},[A]),o(()=>{if(!z.current){z.current=!0;return}let e=p*1e3;I.current=e,B(e),L.current=!1,H(),pe&&V(m?`running`:`idle`)},[p]),o(()=>{if(!C||A!==`running`||ue())return;function e(){let e=++Ve.current;N(t=>[...t,e])}let t=setTimeout(e,0),n=setInterval(e,ce);return()=>{clearTimeout(t),clearInterval(n)}},[C,A]);function He(e){N(t=>t.filter(t=>t!==e))}function Ue(){E&&!R.current&&typeof Notification<`u`&&Notification.permission==="default"&&(R.current=!0,Notification.requestPermission().catch(()=>{}))}function U(){Ue(),(F.current===`completed`||F.current===`cancelled`)&&(B(I.current),L.current=!1),H(),V(`running`),he?.()}function W(){F.current===`running`&&(V(`paused`),ge?.())}function G(){F.current===`paused`&&(H(),V(`running`),_e?.())}function K(e){let t=y==null?1/0:y*1e3,n=Math.min(P.current+e*1e3,t);B(n),H(),g?.(e,Math.round(n/1e3)),F.current===`completed`&&n>0&&(L.current=!1,V(`running`))}function q(e){let t=Math.max(0,P.current-e*1e3);B(t),H(),ye?.(e,Math.round(t/1e3)),t<=0&&F.current===`running`&&V(`completed`)}function J(){B(I.current),V(`cancelled`),ve?.()}function We(){B(I.current),L.current=!1,V(`idle`)}ee(fe,()=>({start:U,pause:W,resume:G,addTime:K,removeTime:q,cancel:J,reset:We,getStatus:()=>F.current,getRemainingMs:()=>P.current}));let Y=50-S/2,X=te(()=>2*Math.PI*Y,[Y]),Ge=X*(1-(I.current>0?Math.min(1,j/I.current):0)),Z=Math.max(I.current*Ee,De*1e3),Q=A===`running`&&j<=Z,Ke=Q&&j<=Math.min(5e3,Z),$=A===`paused`,qe=_&&!be,Je=_&&!xe,Ye=_&&!Se,Xe=A===`running`?re:ie,Ze=A===`running`?`Pause`:$?`Resume`:A===`idle`?`Start`:`Restart`,Qe=A===`running`?W:$?G:U,$e=_&&!Ce;return d(`div`,{...Fe,className:l(a.timer,Oe&&Q&&a.timerPulsing,Ke&&a.timerCritical,Me,D?.root),style:{...x?{"--timer-size":x}:null,"--timer-stroke-width":`${S}px`,...Ne,...O?.root},children:[d(`div`,{className:l(a.timerRingWrapper,D?.ringWrapper),style:O?.ringWrapper,children:[M.length>0&&u(`div`,{className:l(a.timerRipples,D?.ripples),style:O?.ripples,children:M.map(e=>u(`span`,{className:l(a.timerRipple,D?.ripple),style:O?.ripple,onAnimationEnd:()=>He(e)},e))}),d(`svg`,{className:l(a.timerRingSvg,D?.ringSvg),viewBox:`0 0 100 100`,style:O?.ringSvg,children:[u(`circle`,{className:l(a.timerRingTrack,D?.ringTrack),cx:`50`,cy:`50`,r:Y,style:O?.ringTrack}),u(`circle`,{className:l(a.timerRingProgress,Q&&a.timerRingProgressUrgent,D?.ringProgress),cx:`50`,cy:`50`,r:Y,strokeDasharray:X,strokeDashoffset:Ge,style:{transition:$?`none`:void 0,transform:Te?`rotate(-90deg)`:void 0,...O?.ringProgress}})]}),d(`div`,{className:l(a.timerDisplay,D?.display),style:O?.display,children:[u(`span`,{className:l(a.timerTime,D?.time),style:O?.time,children:we(j)}),b&&u(`span`,{className:l(a.timerLabel,D?.label),style:O?.label,children:b})]})]}),_&&d(`div`,{className:l(a.timerControls,D?.controls),style:O?.controls,children:[d(`div`,{className:a.timerControlsRow,children:[Je&&u(i,{icon:ne,title:`Remove ${v}s`,onClick:()=>q(v),className:l(a.timerAdjustButton,D?.removeButton),style:O?.removeButton}),Ye&&u(r,{size:n.Small,icon:Xe,title:Ze,onClick:Qe,className:D?.pauseButton,style:O?.pauseButton}),qe&&u(i,{icon:ae,title:`Add ${v}s`,onClick:()=>K(v),className:l(a.timerAdjustButton,D?.addButton),style:O?.addButton})]}),$e&&u(i,{icon:oe,title:Ie.cancel,onClick:J,className:l(a.timerCancelButton,D?.cancelButton),style:O?.cancelButton})]})]})}export{f as default};
|
|
1
|
+
"use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{useLabels as t}from"../configProvider/useLabels.mjs";import{ButtonSize as n}from"../button/button.types.mjs";import r from"../button/button.mjs";import i from"../actionIcon/actionIcon.mjs";import"./timer.chime.mjs";import a from"./timer.module.mjs";import{useEffect as o,useImperativeHandle as ee,useMemo as te,useRef as s,useState as c}from"react";import l from"classnames";import{faMinus as ne,faPause as re,faPlay as ie,faPlus as ae,faXmark as oe}from"@fortawesome/free-solid-svg-icons";import{jsx as u,jsxs as d}from"react/jsx-runtime";var se=200,ce=1e3,le={cancel:`Cancel timer`};function ue(){return typeof window<`u`&&window.matchMedia?.(`(prefers-reduced-motion: reduce)`).matches===!0}function de(e){let t=Math.ceil(e/1e3),n=Math.floor(t/3600),r=Math.floor(t%3600/60),i=t%60,a=String(r).padStart(2,`0`),o=String(i).padStart(2,`0`);return n>0?`${n}:${a}:${o}`:`${a}:${o}`}function f(f){let{ref:fe,durationSeconds:p,autoStart:m=!0,resetOnDurationChange:pe=!0,onTick:h,onComplete:me,onStart:he,onPause:ge,onResume:_e,onCancel:ve,onAddTime:g,onRemoveTime:ye,showControls:_=!0,hideAddButton:be=!1,hideRemoveButton:xe=!1,hidePauseButton:Se=!1,hideCancelButton:Ce=!1,adjustSeconds:v=30,maxSeconds:y,label:b,formatTime:we=de,size:x,strokeWidth:S=10,counterClockwise:Te=!1,urgentThreshold:Ee=.1,urgentMinSeconds:De=3,pulseOnUrgent:Oe=!0,showRunningRipples:C=!1,playSoundOnComplete:w=!1,soundUrl:T,soundVolume:ke=.5,notifyOnComplete:E=!1,notificationTitle:Ae,notificationBody:je,className:Me,style:Ne,classNames:D,styles:O,labels:Pe,...Fe}=e(`Timer`,f),Ie=t(`Timer`,Pe,le),k=p*1e3,[A,Le]=c(m?`running`:`idle`),[j,Re]=c(k),[ze,Be]=c(0),[M,N]=c([]),P=s(j),F=s(A),I=s(k),L=s(!1),R=s(!1),z=s(!1),Ve=s(0);function B(e){P.current=e,Re(e)}function V(e){F.current=e,Le(e)}function H(){Be(e=>e+1)}o(()=>{if(A!==`running`)return;let e=Date.now(),t=P.current,n=setInterval(()=>{let n=Math.max(0,t-(Date.now()-e));B(n),h?.(n),n<=0&&V(`completed`)},se);return()=>clearInterval(n)},[A,ze]),o(()=>{if(A===`completed`&&!L.current){if(L.current=!0,me?.(),w)try{let e=new Audio(T||`data:audio/wav;base64,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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANACUAKwAKAMr/kv+R/9n/TwCxALwAVwCs/xb/8/5p/0YAFgFfAeYA3f/N/lP+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`);e.volume=ke,e.play()?.catch(()=>{})}catch{}if(E&&typeof Notification<`u`&&Notification.permission===`granted`)try{new Notification(Ae??`Timer done`,{body:je??(typeof b==`string`?b:void 0)})}catch{}}A!==`completed`&&(L.current=!1)},[A]),o(()=>{if(!z.current){z.current=!0;return}let e=p*1e3;I.current=e,B(e),L.current=!1,H(),pe&&V(m?`running`:`idle`)},[p]),o(()=>{if(!C||A!==`running`||ue())return;function e(){let e=++Ve.current;N(t=>[...t,e])}let t=setTimeout(e,0),n=setInterval(e,ce);return()=>{clearTimeout(t),clearInterval(n)}},[C,A]);function He(e){N(t=>t.filter(t=>t!==e))}function Ue(){E&&!R.current&&typeof Notification<`u`&&Notification.permission==="default"&&(R.current=!0,Notification.requestPermission().catch(()=>{}))}function U(){Ue(),(F.current===`completed`||F.current===`cancelled`)&&(B(I.current),L.current=!1),H(),V(`running`),he?.()}function W(){F.current===`running`&&(V(`paused`),ge?.())}function G(){F.current===`paused`&&(H(),V(`running`),_e?.())}function K(e){let t=y==null?1/0:y*1e3,n=Math.min(P.current+e*1e3,t);B(n),H(),g?.(e,Math.round(n/1e3)),F.current===`completed`&&n>0&&(L.current=!1,V(`running`))}function q(e){let t=Math.max(0,P.current-e*1e3);B(t),H(),ye?.(e,Math.round(t/1e3)),t<=0&&F.current===`running`&&V(`completed`)}function J(){B(I.current),V(`cancelled`),ve?.()}function We(){B(I.current),L.current=!1,V(`idle`)}ee(fe,()=>({start:U,pause:W,resume:G,addTime:K,removeTime:q,cancel:J,reset:We,getStatus:()=>F.current,getRemainingMs:()=>P.current}));let Y=50-S/2,X=te(()=>2*Math.PI*Y,[Y]),Ge=X*(1-(I.current>0?Math.min(1,j/I.current):0)),Z=Math.max(I.current*Ee,De*1e3),Q=A===`running`&&j<=Z,Ke=Q&&j<=Math.min(5e3,Z),$=A===`paused`,qe=_&&!be,Je=_&&!xe,Ye=_&&!Se,Xe=A===`running`?re:ie,Ze=A===`running`?`Pause`:$?`Resume`:A===`idle`?`Start`:`Restart`,Qe=A===`running`?W:$?G:U,$e=_&&!Ce;return d(`div`,{...Fe,className:l(a.timer,Oe&&Q&&a.timerPulsing,Ke&&a.timerCritical,Me,D?.root),style:{...x?{"--timer-size":x}:null,"--timer-stroke-width":`${S}px`,...Ne,...O?.root},children:[d(`div`,{className:l(a.timerRingWrapper,D?.ringWrapper),style:O?.ringWrapper,children:[M.length>0&&u(`div`,{className:l(a.timerRipples,D?.ripples),style:O?.ripples,children:M.map(e=>u(`span`,{className:l(a.timerRipple,D?.ripple),style:O?.ripple,onAnimationEnd:()=>He(e)},e))}),d(`svg`,{className:l(a.timerRingSvg,D?.ringSvg),viewBox:`0 0 100 100`,style:O?.ringSvg,children:[u(`circle`,{className:l(a.timerRingTrack,D?.ringTrack),cx:`50`,cy:`50`,r:Y,style:O?.ringTrack}),u(`circle`,{className:l(a.timerRingProgress,Q&&a.timerRingProgressUrgent,D?.ringProgress),cx:`50`,cy:`50`,r:Y,strokeDasharray:X,strokeDashoffset:Ge,style:{transition:$?`none`:void 0,transform:Te?`rotate(-90deg)`:void 0,...O?.ringProgress}})]}),d(`div`,{className:l(a.timerDisplay,D?.display),style:O?.display,children:[u(`span`,{className:l(a.timerTime,D?.time),style:O?.time,children:we(j)}),b&&u(`span`,{className:l(a.timerLabel,D?.label),style:O?.label,children:b})]})]}),_&&d(`div`,{className:l(a.timerControls,D?.controls),style:O?.controls,children:[d(`div`,{className:a.timerControlsRow,children:[Je&&u(i,{icon:ne,title:`Remove ${v}s`,onClick:()=>q(v),className:D?.removeButton,style:O?.removeButton}),Ye&&u(r,{size:n.Small,icon:Xe,title:Ze,onClick:Qe,className:D?.pauseButton,style:O?.pauseButton}),qe&&u(i,{icon:ae,title:`Add ${v}s`,onClick:()=>K(v),className:D?.addButton,style:O?.addButton})]}),$e&&u(i,{icon:oe,title:Ie.cancel,onClick:J,className:l(a.timerCancelButton,D?.cancelButton),style:O?.cancelButton})]})]})}export{f as default};
|
|
2
2
|
//# sourceMappingURL=timer.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timer.mjs","names":[],"sources":["../../../../package/common/timer/timer.tsx"],"sourcesContent":["import { useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';\nimport cx from 'classnames';\nimport { faPlus, faMinus, faPause, faPlay, faXmark } from '@fortawesome/free-solid-svg-icons';\n\nimport ActionIcon from '../actionIcon';\nimport Button from '../button';\nimport { ButtonSize } from '../button/button.types';\nimport { useComponentDefaults, useLabels } from '../configProvider';\nimport { DEFAULT_CHIME_DATA_URI } from './timer.chime';\nimport type { TimerLabels, TimerProps, TimerStatus } from './timer.types';\nimport styles from './timer.module.pcss';\n\nconst TICK_MS = 200;\nconst RIPPLE_SPAWN_INTERVAL_MS = 1000;\n\nconst DEFAULT_LABELS: Required<TimerLabels> = {\n cancel: 'Cancel timer',\n};\n\nfunction prefersReducedMotion(): boolean {\n return typeof window !== 'undefined' && window.matchMedia?.('(prefers-reduced-motion: reduce)').matches === true;\n}\n\nfunction formatTimeDefault(remainingMs: number) {\n const totalSeconds = Math.ceil(remainingMs / 1000);\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n const mm = String(minutes).padStart(2, '0');\n const ss = String(seconds).padStart(2, '0');\n return hours > 0 ? `${hours}:${mm}:${ss}` : `${mm}:${ss}`;\n}\n\nfunction Timer(props: TimerProps) {\n const {\n ref,\n durationSeconds,\n autoStart = true,\n resetOnDurationChange = true,\n\n onTick,\n onComplete,\n onStart,\n onPause,\n onResume,\n onCancel,\n onAddTime,\n onRemoveTime,\n\n showControls = true,\n hideAddButton = false,\n hideRemoveButton = false,\n hidePauseButton = false,\n hideCancelButton = false,\n adjustSeconds = 30,\n maxSeconds,\n\n label,\n formatTime = formatTimeDefault,\n size,\n strokeWidth = 10,\n counterClockwise = false,\n\n urgentThreshold = 0.1,\n urgentMinSeconds = 3,\n pulseOnUrgent = true,\n showRunningRipples = false,\n\n playSoundOnComplete = false,\n soundUrl,\n soundVolume = 0.5,\n notifyOnComplete = false,\n notificationTitle,\n notificationBody,\n\n className,\n style,\n classNames,\n styles: slotStyles,\n labels,\n ...rest\n } = useComponentDefaults('Timer', props);\n const text = useLabels('Timer', labels, DEFAULT_LABELS);\n\n const initialMs = durationSeconds * 1000;\n const [status, setStatusState] = useState<TimerStatus>(autoStart ? 'running' : 'idle');\n const [remainingMs, setRemainingMsState] = useState(initialMs);\n const [epoch, setEpoch] = useState(0);\n const [ripples, setRipples] = useState<number[]>([]);\n\n const remainingRef = useRef(remainingMs);\n const statusRef = useRef(status);\n const totalMsRef = useRef(initialMs);\n const completedFiredRef = useRef(false);\n const notifyPermissionRequestedRef = useRef(false);\n const mountedRef = useRef(false);\n const rippleIdRef = useRef(0);\n\n function setRemaining(next: number) {\n remainingRef.current = next;\n setRemainingMsState(next);\n }\n\n function setStatus(next: TimerStatus) {\n statusRef.current = next;\n setStatusState(next);\n }\n\n function bumpEpoch() {\n setEpoch((e) => e + 1);\n }\n\n // Ticking effect. Re-derives the remaining time from Date.now() every tick (rather than\n // accumulating setInterval's own drift), so it stays accurate over long countdowns. Any\n // external mutation of remainingRef (addTime/removeTime while already running, or a resume)\n // must bump `epoch` so this effect re-arms and re-captures a fresh start/startRemaining —\n // without that, a stale `startRemaining` captured before the mutation would silently\n // overwrite it on the next tick.\n useEffect(() => {\n if (status !== 'running') return undefined;\n const start = Date.now();\n const startRemaining = remainingRef.current;\n const id = setInterval(() => {\n const next = Math.max(0, startRemaining - (Date.now() - start));\n setRemaining(next);\n onTick?.(next);\n if (next <= 0) setStatus('completed');\n }, TICK_MS);\n return () => clearInterval(id);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [status, epoch]);\n\n // Fires onComplete exactly once per completion, plus the opt-in sound/notification.\n useEffect(() => {\n if (status === 'completed' && !completedFiredRef.current) {\n completedFiredRef.current = true;\n onComplete?.();\n if (playSoundOnComplete) {\n try {\n const audio = new Audio(soundUrl || DEFAULT_CHIME_DATA_URI);\n audio.volume = soundVolume;\n // play() can reject (autoplay policy) or, in some environments, return undefined\n // instead of a Promise — never let a blocked/unsupported playback surface as an error.\n audio.play()?.catch(() => {});\n } catch {\n // Audio unavailable/unsupported — fail silently.\n }\n }\n if (notifyOnComplete && typeof Notification !== 'undefined' && Notification.permission === 'granted') {\n try {\n new Notification(notificationTitle ?? 'Timer done', {\n body: notificationBody ?? (typeof label === 'string' ? label : undefined),\n });\n } catch {\n // Some browsers (e.g. certain mobile Safari versions) throw constructing\n // Notification outside specific contexts — fail silently, as documented.\n }\n }\n }\n if (status !== 'completed') completedFiredRef.current = false;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [status]);\n\n // durationSeconds prop change: reset (and optionally restart) at the new duration. Skips\n // the initial mount, since autoStart/initial state already cover that.\n useEffect(() => {\n if (!mountedRef.current) {\n mountedRef.current = true;\n return;\n }\n const nextMs = durationSeconds * 1000;\n totalMsRef.current = nextMs;\n setRemaining(nextMs);\n completedFiredRef.current = false;\n bumpEpoch();\n if (resetOnDurationChange) {\n setStatus(autoStart ? 'running' : 'idle');\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [durationSeconds]);\n\n // Running-ripple spawner: spawns a new ripple roughly every RIPPLE_SPAWN_INTERVAL_MS while\n // running, each animating once (via CSS, `forwards`) and removing itself on `onAnimationEnd`.\n // Pausing (or otherwise leaving `running`) only stops new spawns here — it doesn't touch\n // `ripples` — so whichever ripples are already mid-flight keep animating to completion\n // instead of vanishing mid-cycle.\n useEffect(() => {\n if (!showRunningRipples || status !== 'running' || prefersReducedMotion()) return undefined;\n function spawnRipple() {\n // Read now, not in the updater: two spawns before a render would both see the later id.\n const rippleId = ++rippleIdRef.current;\n setRipples((prev) => [...prev, rippleId]);\n }\n // A timer, so the cleanup cancels it too: StrictMode's second mount stacked a second ripple.\n const first = setTimeout(spawnRipple, 0);\n const id = setInterval(spawnRipple, RIPPLE_SPAWN_INTERVAL_MS);\n return () => {\n clearTimeout(first);\n clearInterval(id);\n };\n }, [showRunningRipples, status]);\n\n function handleRippleAnimationEnd(id: number) {\n setRipples((prev) => prev.filter((existingId) => existingId !== id));\n }\n\n function requestNotificationPermissionIfNeeded() {\n if (!notifyOnComplete || notifyPermissionRequestedRef.current) return;\n if (typeof Notification === 'undefined' || Notification.permission !== 'default') return;\n notifyPermissionRequestedRef.current = true;\n Notification.requestPermission().catch(() => {});\n }\n\n function start() {\n requestNotificationPermissionIfNeeded();\n if (statusRef.current === 'completed' || statusRef.current === 'cancelled') {\n setRemaining(totalMsRef.current);\n completedFiredRef.current = false;\n }\n bumpEpoch();\n setStatus('running');\n onStart?.();\n }\n\n function pause() {\n if (statusRef.current !== 'running') return;\n setStatus('paused');\n onPause?.();\n }\n\n function resume() {\n if (statusRef.current !== 'paused') return;\n bumpEpoch();\n setStatus('running');\n onResume?.();\n }\n\n function addTime(seconds: number) {\n const capped = maxSeconds != null ? maxSeconds * 1000 : Infinity;\n const next = Math.min(remainingRef.current + seconds * 1000, capped);\n setRemaining(next);\n bumpEpoch();\n onAddTime?.(seconds, Math.round(next / 1000));\n if (statusRef.current === 'completed' && next > 0) {\n completedFiredRef.current = false;\n setStatus('running');\n }\n }\n\n function removeTime(seconds: number) {\n const next = Math.max(0, remainingRef.current - seconds * 1000);\n setRemaining(next);\n bumpEpoch();\n onRemoveTime?.(seconds, Math.round(next / 1000));\n if (next <= 0 && statusRef.current === 'running') setStatus('completed');\n }\n\n function cancel() {\n setRemaining(totalMsRef.current);\n setStatus('cancelled');\n onCancel?.();\n }\n\n function reset() {\n setRemaining(totalMsRef.current);\n completedFiredRef.current = false;\n setStatus('idle');\n }\n\n useImperativeHandle(ref, () => ({\n start,\n pause,\n resume,\n addTime,\n removeTime,\n cancel,\n reset,\n getStatus: () => statusRef.current,\n getRemainingMs: () => remainingRef.current,\n }));\n\n const radius = 50 - strokeWidth / 2;\n const circumference = useMemo(() => 2 * Math.PI * radius, [radius]);\n const clampedFraction = totalMsRef.current > 0 ? Math.min(1, remainingMs / totalMsRef.current) : 0;\n const dashOffset = circumference * (1 - clampedFraction);\n const urgentMs = Math.max(totalMsRef.current * urgentThreshold, urgentMinSeconds * 1000);\n const isUrgent = status === 'running' && remainingMs <= urgentMs;\n const isCritical = isUrgent && remainingMs <= Math.min(5000, urgentMs);\n const isPaused = status === 'paused';\n\n // The pause button doubles as a play/restart button whenever there's nothing to pause —\n // idle (autoStart={false}), completed, or cancelled — rather than hiding itself, so there's\n // always a way to (re)start the countdown from the built-in controls alone.\n const showAddButton = showControls && !hideAddButton;\n const showRemoveButton = showControls && !hideRemoveButton;\n const showPauseButton = showControls && !hidePauseButton;\n const pauseButtonIcon = status === 'running' ? faPause : faPlay;\n const pauseButtonTitle =\n status === 'running' ? 'Pause' : isPaused ? 'Resume' : status === 'idle' ? 'Start' : 'Restart';\n const handlePauseButtonClick = status === 'running' ? pause : isPaused ? resume : start;\n const showCancelButton = showControls && !hideCancelButton;\n\n return (\n <div\n {...rest}\n className={cx(\n styles.timer,\n pulseOnUrgent && isUrgent && styles.timerPulsing,\n isCritical && styles.timerCritical,\n className,\n classNames?.root,\n )}\n style={\n {\n ...(size ? { '--timer-size': size } : null),\n '--timer-stroke-width': `${strokeWidth}px`,\n ...style,\n ...slotStyles?.root,\n } as React.CSSProperties\n }\n >\n <div className={cx(styles.timerRingWrapper, classNames?.ringWrapper)} style={slotStyles?.ringWrapper}>\n {ripples.length > 0 && (\n <div className={cx(styles.timerRipples, classNames?.ripples)} style={slotStyles?.ripples}>\n {ripples.map((id) => (\n <span\n key={id}\n className={cx(styles.timerRipple, classNames?.ripple)}\n style={slotStyles?.ripple}\n onAnimationEnd={() => handleRippleAnimationEnd(id)}\n />\n ))}\n </div>\n )}\n <svg className={cx(styles.timerRingSvg, classNames?.ringSvg)} viewBox='0 0 100 100' style={slotStyles?.ringSvg}>\n <circle\n className={cx(styles.timerRingTrack, classNames?.ringTrack)}\n cx='50'\n cy='50'\n r={radius}\n style={slotStyles?.ringTrack}\n />\n <circle\n className={cx(\n styles.timerRingProgress,\n isUrgent && styles.timerRingProgressUrgent,\n classNames?.ringProgress,\n )}\n cx='50'\n cy='50'\n r={radius}\n strokeDasharray={circumference}\n strokeDashoffset={dashOffset}\n style={{\n transition: isPaused ? 'none' : undefined,\n transform: counterClockwise ? 'rotate(-90deg)' : undefined,\n ...slotStyles?.ringProgress,\n }}\n />\n </svg>\n <div className={cx(styles.timerDisplay, classNames?.display)} style={slotStyles?.display}>\n <span className={cx(styles.timerTime, classNames?.time)} style={slotStyles?.time}>\n {formatTime(remainingMs)}\n </span>\n {label && (\n <span className={cx(styles.timerLabel, classNames?.label)} style={slotStyles?.label}>\n {label}\n </span>\n )}\n </div>\n </div>\n\n {showControls && (\n <div className={cx(styles.timerControls, classNames?.controls)} style={slotStyles?.controls}>\n <div className={styles.timerControlsRow}>\n {showRemoveButton && (\n <ActionIcon\n icon={faMinus}\n title={`Remove ${adjustSeconds}s`}\n onClick={() => removeTime(adjustSeconds)}\n className={cx(styles.timerAdjustButton, classNames?.removeButton)}\n style={slotStyles?.removeButton}\n />\n )}\n {showPauseButton && (\n <Button\n size={ButtonSize.Small}\n icon={pauseButtonIcon}\n title={pauseButtonTitle}\n onClick={handlePauseButtonClick}\n className={classNames?.pauseButton}\n style={slotStyles?.pauseButton}\n />\n )}\n {showAddButton && (\n <ActionIcon\n icon={faPlus}\n title={`Add ${adjustSeconds}s`}\n onClick={() => addTime(adjustSeconds)}\n className={cx(styles.timerAdjustButton, classNames?.addButton)}\n style={slotStyles?.addButton}\n />\n )}\n </div>\n {showCancelButton && (\n <ActionIcon\n icon={faXmark}\n title={text.cancel}\n onClick={cancel}\n className={cx(styles.timerCancelButton, classNames?.cancelButton)}\n style={slotStyles?.cancelButton}\n />\n )}\n </div>\n )}\n </div>\n );\n}\n\nexport default Timer;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"timer.mjs","names":[],"sources":["../../../../package/common/timer/timer.tsx"],"sourcesContent":["import { useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';\nimport cx from 'classnames';\nimport { faPlus, faMinus, faPause, faPlay, faXmark } from '@fortawesome/free-solid-svg-icons';\n\nimport ActionIcon from '../actionIcon';\nimport Button from '../button';\nimport { ButtonSize } from '../button/button.types';\nimport { useComponentDefaults, useLabels } from '../configProvider';\nimport { DEFAULT_CHIME_DATA_URI } from './timer.chime';\nimport type { TimerLabels, TimerProps, TimerStatus } from './timer.types';\nimport styles from './timer.module.pcss';\n\nconst TICK_MS = 200;\nconst RIPPLE_SPAWN_INTERVAL_MS = 1000;\n\nconst DEFAULT_LABELS: Required<TimerLabels> = {\n cancel: 'Cancel timer',\n};\n\nfunction prefersReducedMotion(): boolean {\n return typeof window !== 'undefined' && window.matchMedia?.('(prefers-reduced-motion: reduce)').matches === true;\n}\n\nfunction formatTimeDefault(remainingMs: number) {\n const totalSeconds = Math.ceil(remainingMs / 1000);\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n const mm = String(minutes).padStart(2, '0');\n const ss = String(seconds).padStart(2, '0');\n return hours > 0 ? `${hours}:${mm}:${ss}` : `${mm}:${ss}`;\n}\n\nfunction Timer(props: TimerProps) {\n const {\n ref,\n durationSeconds,\n autoStart = true,\n resetOnDurationChange = true,\n\n onTick,\n onComplete,\n onStart,\n onPause,\n onResume,\n onCancel,\n onAddTime,\n onRemoveTime,\n\n showControls = true,\n hideAddButton = false,\n hideRemoveButton = false,\n hidePauseButton = false,\n hideCancelButton = false,\n adjustSeconds = 30,\n maxSeconds,\n\n label,\n formatTime = formatTimeDefault,\n size,\n strokeWidth = 10,\n counterClockwise = false,\n\n urgentThreshold = 0.1,\n urgentMinSeconds = 3,\n pulseOnUrgent = true,\n showRunningRipples = false,\n\n playSoundOnComplete = false,\n soundUrl,\n soundVolume = 0.5,\n notifyOnComplete = false,\n notificationTitle,\n notificationBody,\n\n className,\n style,\n classNames,\n styles: slotStyles,\n labels,\n ...rest\n } = useComponentDefaults('Timer', props);\n const text = useLabels('Timer', labels, DEFAULT_LABELS);\n\n const initialMs = durationSeconds * 1000;\n const [status, setStatusState] = useState<TimerStatus>(autoStart ? 'running' : 'idle');\n const [remainingMs, setRemainingMsState] = useState(initialMs);\n const [epoch, setEpoch] = useState(0);\n const [ripples, setRipples] = useState<number[]>([]);\n\n const remainingRef = useRef(remainingMs);\n const statusRef = useRef(status);\n const totalMsRef = useRef(initialMs);\n const completedFiredRef = useRef(false);\n const notifyPermissionRequestedRef = useRef(false);\n const mountedRef = useRef(false);\n const rippleIdRef = useRef(0);\n\n function setRemaining(next: number) {\n remainingRef.current = next;\n setRemainingMsState(next);\n }\n\n function setStatus(next: TimerStatus) {\n statusRef.current = next;\n setStatusState(next);\n }\n\n function bumpEpoch() {\n setEpoch((e) => e + 1);\n }\n\n // Ticking effect. Re-derives the remaining time from Date.now() every tick (rather than\n // accumulating setInterval's own drift), so it stays accurate over long countdowns. Any\n // external mutation of remainingRef (addTime/removeTime while already running, or a resume)\n // must bump `epoch` so this effect re-arms and re-captures a fresh start/startRemaining —\n // without that, a stale `startRemaining` captured before the mutation would silently\n // overwrite it on the next tick.\n useEffect(() => {\n if (status !== 'running') return undefined;\n const start = Date.now();\n const startRemaining = remainingRef.current;\n const id = setInterval(() => {\n const next = Math.max(0, startRemaining - (Date.now() - start));\n setRemaining(next);\n onTick?.(next);\n if (next <= 0) setStatus('completed');\n }, TICK_MS);\n return () => clearInterval(id);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [status, epoch]);\n\n // Fires onComplete exactly once per completion, plus the opt-in sound/notification.\n useEffect(() => {\n if (status === 'completed' && !completedFiredRef.current) {\n completedFiredRef.current = true;\n onComplete?.();\n if (playSoundOnComplete) {\n try {\n const audio = new Audio(soundUrl || DEFAULT_CHIME_DATA_URI);\n audio.volume = soundVolume;\n // play() can reject (autoplay policy) or, in some environments, return undefined\n // instead of a Promise — never let a blocked/unsupported playback surface as an error.\n audio.play()?.catch(() => {});\n } catch {\n // Audio unavailable/unsupported — fail silently.\n }\n }\n if (notifyOnComplete && typeof Notification !== 'undefined' && Notification.permission === 'granted') {\n try {\n new Notification(notificationTitle ?? 'Timer done', {\n body: notificationBody ?? (typeof label === 'string' ? label : undefined),\n });\n } catch {\n // Some browsers (e.g. certain mobile Safari versions) throw constructing\n // Notification outside specific contexts — fail silently, as documented.\n }\n }\n }\n if (status !== 'completed') completedFiredRef.current = false;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [status]);\n\n // durationSeconds prop change: reset (and optionally restart) at the new duration. Skips\n // the initial mount, since autoStart/initial state already cover that.\n useEffect(() => {\n if (!mountedRef.current) {\n mountedRef.current = true;\n return;\n }\n const nextMs = durationSeconds * 1000;\n totalMsRef.current = nextMs;\n setRemaining(nextMs);\n completedFiredRef.current = false;\n bumpEpoch();\n if (resetOnDurationChange) {\n setStatus(autoStart ? 'running' : 'idle');\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [durationSeconds]);\n\n // Running-ripple spawner: spawns a new ripple roughly every RIPPLE_SPAWN_INTERVAL_MS while\n // running, each animating once (via CSS, `forwards`) and removing itself on `onAnimationEnd`.\n // Pausing (or otherwise leaving `running`) only stops new spawns here — it doesn't touch\n // `ripples` — so whichever ripples are already mid-flight keep animating to completion\n // instead of vanishing mid-cycle.\n useEffect(() => {\n if (!showRunningRipples || status !== 'running' || prefersReducedMotion()) return undefined;\n function spawnRipple() {\n // Read now, not in the updater: two spawns before a render would both see the later id.\n const rippleId = ++rippleIdRef.current;\n setRipples((prev) => [...prev, rippleId]);\n }\n // A timer, so the cleanup cancels it too: StrictMode's second mount stacked a second ripple.\n const first = setTimeout(spawnRipple, 0);\n const id = setInterval(spawnRipple, RIPPLE_SPAWN_INTERVAL_MS);\n return () => {\n clearTimeout(first);\n clearInterval(id);\n };\n }, [showRunningRipples, status]);\n\n function handleRippleAnimationEnd(id: number) {\n setRipples((prev) => prev.filter((existingId) => existingId !== id));\n }\n\n function requestNotificationPermissionIfNeeded() {\n if (!notifyOnComplete || notifyPermissionRequestedRef.current) return;\n if (typeof Notification === 'undefined' || Notification.permission !== 'default') return;\n notifyPermissionRequestedRef.current = true;\n Notification.requestPermission().catch(() => {});\n }\n\n function start() {\n requestNotificationPermissionIfNeeded();\n if (statusRef.current === 'completed' || statusRef.current === 'cancelled') {\n setRemaining(totalMsRef.current);\n completedFiredRef.current = false;\n }\n bumpEpoch();\n setStatus('running');\n onStart?.();\n }\n\n function pause() {\n if (statusRef.current !== 'running') return;\n setStatus('paused');\n onPause?.();\n }\n\n function resume() {\n if (statusRef.current !== 'paused') return;\n bumpEpoch();\n setStatus('running');\n onResume?.();\n }\n\n function addTime(seconds: number) {\n const capped = maxSeconds != null ? maxSeconds * 1000 : Infinity;\n const next = Math.min(remainingRef.current + seconds * 1000, capped);\n setRemaining(next);\n bumpEpoch();\n onAddTime?.(seconds, Math.round(next / 1000));\n if (statusRef.current === 'completed' && next > 0) {\n completedFiredRef.current = false;\n setStatus('running');\n }\n }\n\n function removeTime(seconds: number) {\n const next = Math.max(0, remainingRef.current - seconds * 1000);\n setRemaining(next);\n bumpEpoch();\n onRemoveTime?.(seconds, Math.round(next / 1000));\n if (next <= 0 && statusRef.current === 'running') setStatus('completed');\n }\n\n function cancel() {\n setRemaining(totalMsRef.current);\n setStatus('cancelled');\n onCancel?.();\n }\n\n function reset() {\n setRemaining(totalMsRef.current);\n completedFiredRef.current = false;\n setStatus('idle');\n }\n\n useImperativeHandle(ref, () => ({\n start,\n pause,\n resume,\n addTime,\n removeTime,\n cancel,\n reset,\n getStatus: () => statusRef.current,\n getRemainingMs: () => remainingRef.current,\n }));\n\n const radius = 50 - strokeWidth / 2;\n const circumference = useMemo(() => 2 * Math.PI * radius, [radius]);\n const clampedFraction = totalMsRef.current > 0 ? Math.min(1, remainingMs / totalMsRef.current) : 0;\n const dashOffset = circumference * (1 - clampedFraction);\n const urgentMs = Math.max(totalMsRef.current * urgentThreshold, urgentMinSeconds * 1000);\n const isUrgent = status === 'running' && remainingMs <= urgentMs;\n const isCritical = isUrgent && remainingMs <= Math.min(5000, urgentMs);\n const isPaused = status === 'paused';\n\n // The pause button doubles as a play/restart button whenever there's nothing to pause —\n // idle (autoStart={false}), completed, or cancelled — rather than hiding itself, so there's\n // always a way to (re)start the countdown from the built-in controls alone.\n const showAddButton = showControls && !hideAddButton;\n const showRemoveButton = showControls && !hideRemoveButton;\n const showPauseButton = showControls && !hidePauseButton;\n const pauseButtonIcon = status === 'running' ? faPause : faPlay;\n const pauseButtonTitle =\n status === 'running' ? 'Pause' : isPaused ? 'Resume' : status === 'idle' ? 'Start' : 'Restart';\n const handlePauseButtonClick = status === 'running' ? pause : isPaused ? resume : start;\n const showCancelButton = showControls && !hideCancelButton;\n\n return (\n <div\n {...rest}\n className={cx(\n styles.timer,\n pulseOnUrgent && isUrgent && styles.timerPulsing,\n isCritical && styles.timerCritical,\n className,\n classNames?.root,\n )}\n style={\n {\n ...(size ? { '--timer-size': size } : null),\n '--timer-stroke-width': `${strokeWidth}px`,\n ...style,\n ...slotStyles?.root,\n } as React.CSSProperties\n }\n >\n <div className={cx(styles.timerRingWrapper, classNames?.ringWrapper)} style={slotStyles?.ringWrapper}>\n {ripples.length > 0 && (\n <div className={cx(styles.timerRipples, classNames?.ripples)} style={slotStyles?.ripples}>\n {ripples.map((id) => (\n <span\n key={id}\n className={cx(styles.timerRipple, classNames?.ripple)}\n style={slotStyles?.ripple}\n onAnimationEnd={() => handleRippleAnimationEnd(id)}\n />\n ))}\n </div>\n )}\n <svg className={cx(styles.timerRingSvg, classNames?.ringSvg)} viewBox='0 0 100 100' style={slotStyles?.ringSvg}>\n <circle\n className={cx(styles.timerRingTrack, classNames?.ringTrack)}\n cx='50'\n cy='50'\n r={radius}\n style={slotStyles?.ringTrack}\n />\n <circle\n className={cx(\n styles.timerRingProgress,\n isUrgent && styles.timerRingProgressUrgent,\n classNames?.ringProgress,\n )}\n cx='50'\n cy='50'\n r={radius}\n strokeDasharray={circumference}\n strokeDashoffset={dashOffset}\n style={{\n transition: isPaused ? 'none' : undefined,\n transform: counterClockwise ? 'rotate(-90deg)' : undefined,\n ...slotStyles?.ringProgress,\n }}\n />\n </svg>\n <div className={cx(styles.timerDisplay, classNames?.display)} style={slotStyles?.display}>\n <span className={cx(styles.timerTime, classNames?.time)} style={slotStyles?.time}>\n {formatTime(remainingMs)}\n </span>\n {label && (\n <span className={cx(styles.timerLabel, classNames?.label)} style={slotStyles?.label}>\n {label}\n </span>\n )}\n </div>\n </div>\n\n {showControls && (\n <div className={cx(styles.timerControls, classNames?.controls)} style={slotStyles?.controls}>\n <div className={styles.timerControlsRow}>\n {showRemoveButton && (\n <ActionIcon\n icon={faMinus}\n title={`Remove ${adjustSeconds}s`}\n onClick={() => removeTime(adjustSeconds)}\n className={classNames?.removeButton}\n style={slotStyles?.removeButton}\n />\n )}\n {showPauseButton && (\n <Button\n size={ButtonSize.Small}\n icon={pauseButtonIcon}\n title={pauseButtonTitle}\n onClick={handlePauseButtonClick}\n className={classNames?.pauseButton}\n style={slotStyles?.pauseButton}\n />\n )}\n {showAddButton && (\n <ActionIcon\n icon={faPlus}\n title={`Add ${adjustSeconds}s`}\n onClick={() => addTime(adjustSeconds)}\n className={classNames?.addButton}\n style={slotStyles?.addButton}\n />\n )}\n </div>\n {showCancelButton && (\n <ActionIcon\n icon={faXmark}\n title={text.cancel}\n onClick={cancel}\n className={cx(styles.timerCancelButton, classNames?.cancelButton)}\n style={slotStyles?.cancelButton}\n />\n )}\n </div>\n )}\n </div>\n );\n}\n\nexport default Timer;\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";var e=`timer_cqe3R`,t=`timer-ringWrapper_OydlE`,n=`timer-ringSvg_qsV1X`,r=`timer-ripples_2Slkv`,i=`timer-ripple_TLdSx`,a=`timerRippleHalo_oEcXJ`,o=`timer-ringTrack_pGGs1`,s=`timer-ringProgress_LL8uQ`,c=`timer-ringProgress-urgent_MwwU2`,l=`timer-display_es2IX`,u=`timer-time_oMZ5O`,d=`timer-label_GknS-`,f=`timer-controls_LHM4q`,p=`timer-controlsRow_42JyZ`,m=`timer-
|
|
1
|
+
"use client";var e=`timer_cqe3R`,t=`timer-ringWrapper_OydlE`,n=`timer-ringSvg_qsV1X`,r=`timer-ripples_2Slkv`,i=`timer-ripple_TLdSx`,a=`timerRippleHalo_oEcXJ`,o=`timer-ringTrack_pGGs1`,s=`timer-ringProgress_LL8uQ`,c=`timer-ringProgress-urgent_MwwU2`,l=`timer-display_es2IX`,u=`timer-time_oMZ5O`,d=`timer-label_GknS-`,f=`timer-controls_LHM4q`,p=`timer-controlsRow_42JyZ`,m=`timer-cancelButton_ObL4-`,h=`timer-pulsing_795m4`,g=`timerHeartbeat_N40Zt`,_=`timer-critical_q-JzB`,v={timer:e,"timer-ringWrapper":`timer-ringWrapper_OydlE`,timerRingWrapper:t,"timer-ringSvg":`timer-ringSvg_qsV1X`,timerRingSvg:n,"timer-ripples":`timer-ripples_2Slkv`,timerRipples:r,"timer-ripple":`timer-ripple_TLdSx`,timerRipple:i,timerRippleHalo:a,"timer-ringTrack":`timer-ringTrack_pGGs1`,timerRingTrack:o,"timer-ringProgress":`timer-ringProgress_LL8uQ`,timerRingProgress:s,"timer-ringProgress-urgent":`timer-ringProgress-urgent_MwwU2`,timerRingProgressUrgent:c,"timer-display":`timer-display_es2IX`,timerDisplay:l,"timer-time":`timer-time_oMZ5O`,timerTime:u,"timer-label":`timer-label_GknS-`,timerLabel:d,"timer-controls":`timer-controls_LHM4q`,timerControls:f,"timer-controlsRow":`timer-controlsRow_42JyZ`,timerControlsRow:p,"timer-cancelButton":`timer-cancelButton_ObL4-`,timerCancelButton:m,"timer-pulsing":`timer-pulsing_795m4`,timerPulsing:h,timerHeartbeat:g,"timer-critical":`timer-critical_q-JzB`,timerCritical:_};export{v as default,e as timer,m as timerCancelButton,f as timerControls,p as timerControlsRow,_ as timerCritical,l as timerDisplay,g as timerHeartbeat,d as timerLabel,h as timerPulsing,s as timerRingProgress,c as timerRingProgressUrgent,n as timerRingSvg,o as timerRingTrack,t as timerRingWrapper,i as timerRipple,a as timerRippleHalo,r as timerRipples,u as timerTime};
|
|
2
2
|
//# sourceMappingURL=timer.module.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timer.module.mjs","names":[],"sources":["../../../../package/common/timer/timer.module.pcss"],"sourcesContent":[".timer {\n /* em, because the readout inside the ring is em too: a fixed ring stayed put while its own\n digits grew with the theme until they filled it. */\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1em;\n width: fit-content;\n\n &-ringWrapper {\n position: relative;\n width: var(--timer-size, 10em);\n height: var(--timer-size, 10em);\n transform-origin: center;\n }\n\n &-ringSvg {\n position: relative;\n width: 100%;\n height: 100%;\n overflow: visible;\n }\n\n &-ripples {\n position: absolute;\n inset: 0;\n pointer-events: none;\n }\n\n &-ripple {\n position: absolute;\n inset: 0;\n border-radius: 50%;\n border: 0.125em solid var(--timer-ripple-color, var(--timer-progress-color, var(--primary-color)));\n opacity: 0;\n transform: scale(0.94);\n\n /* One-shot per spawned instance (see the ripple spawner in timer.tsx), not an infinite\n loop — so pausing simply stops new spawns while already-mid-flight ripples keep\n animating to completion via `forwards` instead of vanishing mid-cycle. */\n animation: timerRippleHalo 3s ease-out forwards;\n }\n\n /* Not em, unlike everything else here: inside the svg this is a viewBox user unit, so it\n already scales with the ring, and it has to stay equal to the `strokeWidth` prop that\n timer.tsx subtracts from the circle's radius. */\n &-ringTrack {\n fill: none;\n stroke: var(--timer-track-color, var(--background-accent-light));\n stroke-width: var(--timer-stroke-width, 10px);\n }\n\n &-ringProgress {\n fill: none;\n stroke: var(--timer-progress-color, var(--primary-color));\n stroke-width: var(--timer-stroke-width, 10px);\n stroke-linecap: round;\n\n /* Single combined transform, not split across an SVG `transform` attribute on this element\n plus a separate CSS transform on an ancestor — that split combination, together with an\n actively-transitioning stroke-dashoffset, is a known trigger for SVG dash-rendering glitches\n in some engines (the visible arc appearing to jump/drift independent of the actual\n dashoffset value). scaleX(-1) mirrors so the depleting boundary sweeps clockwise (matching\n a clock face) instead of the counter-clockwise direction a <circle>'s implicit path winds\n by default; rotate(-90deg) moves the fixed anchor from 3 o'clock to 12 o'clock. Both applied\n around the circle's own center, which coincides with the viewBox center here. `counterClockwise`\n overrides this inline (timer.tsx) by dropping the scaleX(-1), keeping just the rotate — that\n default winding direction is exactly counter-clockwise, so no mirroring is needed for it. */\n transform: scaleX(-1) rotate(-90deg);\n transform-origin: 50% 50%;\n\n /* Matches (slightly exceeds) the JS tick interval (TICK_MS in timer.tsx) so the ring\n tracks the real remaining time closely instead of perpetually chasing a target that's\n always a full second stale — a much longer transition here reads as sluggish since the\n rendered ring never catches up to the true value while ticking continues. */\n transition:\n stroke-dashoffset 220ms linear,\n stroke 0.3s ease;\n\n &-urgent {\n stroke: var(--timer-urgent-color, var(--error-color));\n }\n }\n\n &-display {\n position: absolute;\n inset: 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n padding: 0 0.75em;\n }\n\n &-time {\n font-size: 1.4em;\n font-weight: 600;\n font-variant-numeric: tabular-nums;\n color: var(--timer-text-color, var(--text-color));\n }\n\n &-label {\n margin-top: 0.25em;\n font-size: 0.8em;\n color: var(--timer-label-color, var(--text-dark));\n }\n\n &-controls {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.5em;\n }\n\n &-controlsRow {\n display: flex;\n align-items: center;\n gap: 0.5em;\n }\n\n &-
|
|
1
|
+
{"version":3,"file":"timer.module.mjs","names":[],"sources":["../../../../package/common/timer/timer.module.pcss"],"sourcesContent":[".timer {\n /* em, because the readout inside the ring is em too: a fixed ring stayed put while its own\n digits grew with the theme until they filled it. */\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1em;\n width: fit-content;\n\n &-ringWrapper {\n position: relative;\n width: var(--timer-size, 10em);\n height: var(--timer-size, 10em);\n transform-origin: center;\n }\n\n &-ringSvg {\n position: relative;\n width: 100%;\n height: 100%;\n overflow: visible;\n }\n\n &-ripples {\n position: absolute;\n inset: 0;\n pointer-events: none;\n }\n\n &-ripple {\n position: absolute;\n inset: 0;\n border-radius: 50%;\n border: 0.125em solid var(--timer-ripple-color, var(--timer-progress-color, var(--primary-color)));\n opacity: 0;\n transform: scale(0.94);\n\n /* One-shot per spawned instance (see the ripple spawner in timer.tsx), not an infinite\n loop — so pausing simply stops new spawns while already-mid-flight ripples keep\n animating to completion via `forwards` instead of vanishing mid-cycle. */\n animation: timerRippleHalo 3s ease-out forwards;\n }\n\n /* Not em, unlike everything else here: inside the svg this is a viewBox user unit, so it\n already scales with the ring, and it has to stay equal to the `strokeWidth` prop that\n timer.tsx subtracts from the circle's radius. */\n &-ringTrack {\n fill: none;\n stroke: var(--timer-track-color, var(--background-accent-light));\n stroke-width: var(--timer-stroke-width, 10px);\n }\n\n &-ringProgress {\n fill: none;\n stroke: var(--timer-progress-color, var(--primary-color));\n stroke-width: var(--timer-stroke-width, 10px);\n stroke-linecap: round;\n\n /* Single combined transform, not split across an SVG `transform` attribute on this element\n plus a separate CSS transform on an ancestor — that split combination, together with an\n actively-transitioning stroke-dashoffset, is a known trigger for SVG dash-rendering glitches\n in some engines (the visible arc appearing to jump/drift independent of the actual\n dashoffset value). scaleX(-1) mirrors so the depleting boundary sweeps clockwise (matching\n a clock face) instead of the counter-clockwise direction a <circle>'s implicit path winds\n by default; rotate(-90deg) moves the fixed anchor from 3 o'clock to 12 o'clock. Both applied\n around the circle's own center, which coincides with the viewBox center here. `counterClockwise`\n overrides this inline (timer.tsx) by dropping the scaleX(-1), keeping just the rotate — that\n default winding direction is exactly counter-clockwise, so no mirroring is needed for it. */\n transform: scaleX(-1) rotate(-90deg);\n transform-origin: 50% 50%;\n\n /* Matches (slightly exceeds) the JS tick interval (TICK_MS in timer.tsx) so the ring\n tracks the real remaining time closely instead of perpetually chasing a target that's\n always a full second stale — a much longer transition here reads as sluggish since the\n rendered ring never catches up to the true value while ticking continues. */\n transition:\n stroke-dashoffset 220ms linear,\n stroke 0.3s ease;\n\n &-urgent {\n stroke: var(--timer-urgent-color, var(--error-color));\n }\n }\n\n &-display {\n position: absolute;\n inset: 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n padding: 0 0.75em;\n }\n\n &-time {\n font-size: 1.4em;\n font-weight: 600;\n font-variant-numeric: tabular-nums;\n color: var(--timer-text-color, var(--text-color));\n }\n\n &-label {\n margin-top: 0.25em;\n font-size: 0.8em;\n color: var(--timer-label-color, var(--text-dark));\n }\n\n &-controls {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.5em;\n }\n\n &-controlsRow {\n display: flex;\n align-items: center;\n gap: 0.5em;\n }\n\n &-cancelButton {\n opacity: 0.6;\n\n &:hover {\n opacity: 1;\n }\n }\n\n &-pulsing &-ringWrapper {\n animation: timerHeartbeat 1s ease-in-out infinite;\n }\n\n &-critical &-ringWrapper {\n animation-duration: 0.6s;\n }\n}\n\n@keyframes timerHeartbeat {\n 0%,\n 100% {\n transform: scale(1);\n }\n\n 50% {\n transform: scale(1.045);\n }\n}\n\n@keyframes timerRippleHalo {\n 0% {\n transform: scale(0.94);\n opacity: 0.5;\n }\n\n 100% {\n transform: scale(1.35);\n opacity: 0;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .timer-ringProgress {\n transition: stroke 0.3s ease;\n }\n\n .timer-pulsing .timer-ringWrapper {\n animation: none;\n }\n\n .timer-ripple {\n animation: none;\n opacity: 0;\n }\n}\n"],"mappings":""}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import e from"../actionIcon/actionIcon.mjs";import
|
|
1
|
+
"use client";import{ThemeColor as e}from"../themeProvider/color.types.mjs";import{toneProps as t,useToneCheck as n}from"../styles/tone.mjs";import r from"../actionIcon/actionIcon.mjs";import i from"./toast.module.mjs";import{useSwipeDismiss as a}from"../hooks/useSwipeDismiss.mjs";import{useEffect as o,useRef as s,useState as c}from"react";import l from"classnames";import{FontAwesomeIcon as u}from"@fortawesome/react-fontawesome";import{faBell as d,faCircleCheck as f,faCircleInfo as p,faCircleXmark as m,faTriangleExclamation as h,faXmark as g}from"@fortawesome/free-solid-svg-icons";import{jsx as _,jsxs as v}from"react/jsx-runtime";var y=new Map([[e.Info,p],[e.Success,f],[e.Warn,h],[e.Error,m]]);function b({item:e,isBottom:f,onDismiss:p,labels:m}){let{id:h,content:b,options:x,dismissing:S}=e,{duration:C,showRemainingTime:w,showCloseButton:T,pauseOnHover:E,color:D,classNames:O,styles:k}=x,A=t(D);n(`Toast`,[D]);let[j,M]=c(!1),[N,P]=c(!1),[F,I]=c(!1),{ref:L,isDragging:R}=a({onDismiss:()=>{I(!0),p(h)}}),z=E&&(j||N)||R,B=s(C);return o(()=>{if(C===0||z)return;let e=Date.now(),t=setTimeout(()=>p(h),B.current);return()=>{clearTimeout(t),B.current-=Date.now()-e}},[h,C,p,z]),v(`div`,{ref:L,className:l(i.toast,f?i.toastBottom:null,A.className,S&&!F&&i.toastDismissing,z&&i.toastPaused,O?.root),style:{...A.style,...k?.root},onMouseEnter:E?()=>M(!0):void 0,onMouseLeave:E?()=>M(!1):void 0,onFocus:E?()=>P(!0):void 0,onBlur:E?()=>P(!1):void 0,children:[_(u,{icon:y.get(D)??d,className:l(i.toastIcon,O?.icon),style:k?.icon}),_(`div`,{className:l(i.toastContent,O?.content),style:k?.content,children:b}),T&&_(r,{icon:g,color:`var(--text-dark)`,onClick:()=>p(h),className:l(i.toastCloseButton,O?.closeButton),style:k?.closeButton,"aria-label":m.close}),w&&C>0&&_(`div`,{className:l(i.toastProgressBar,O?.progressBar),style:{"--toast-duration":`${C}ms`,...k?.progressBar}})]})}export{b as default};
|
|
2
2
|
//# sourceMappingURL=toast.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toast.mjs","names":[],"sources":["../../../../package/common/toast/toast.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react';\nimport cx from 'classnames';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport {\n faCircleInfo,\n faCircleCheck,\n faCircleXmark,\n faTriangleExclamation,\n faBell,\n faXmark,\n} from '@fortawesome/free-solid-svg-icons';\n\nimport styles from './toast.module.pcss';\nimport type { ToastItem, ToastLabels } from './toast.types';\nimport ActionIcon from '../actionIcon';\nimport { useSwipeDismiss } from '../hooks/useSwipeDismiss';\n\ninterface ToastProps {\n item: ToastItem;\n isBottom: boolean;\n onDismiss: (id: string) => void;\n /** Already resolved by the provider: defaults, provider, then this toast's own. */\n labels: Required<ToastLabels>;\n}\n\nconst
|
|
1
|
+
{"version":3,"file":"toast.mjs","names":[],"sources":["../../../../package/common/toast/toast.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react';\nimport cx from 'classnames';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport {\n faCircleInfo,\n faCircleCheck,\n faCircleXmark,\n faTriangleExclamation,\n faBell,\n faXmark,\n} from '@fortawesome/free-solid-svg-icons';\n\nimport styles from './toast.module.pcss';\nimport type { ToastItem, ToastLabels } from './toast.types';\nimport ActionIcon from '../actionIcon';\nimport { useSwipeDismiss } from '../hooks/useSwipeDismiss';\nimport { ThemeColor } from '../themeProvider/color.types';\nimport { toneProps, useToneCheck } from '../styles/tone';\n\ninterface ToastProps {\n item: ToastItem;\n isBottom: boolean;\n onDismiss: (id: string) => void;\n /** Already resolved by the provider: defaults, provider, then this toast's own. */\n labels: Required<ToastLabels>;\n}\n\n// A Map, so a CSS colour can never hit an Object.prototype key.\nconst ICON_BY_COLOR = new Map<string, typeof faBell>([\n [ThemeColor.Info, faCircleInfo],\n [ThemeColor.Success, faCircleCheck],\n [ThemeColor.Warn, faTriangleExclamation],\n [ThemeColor.Error, faCircleXmark],\n]);\n\nfunction Toast({ item, isBottom, onDismiss, labels }: ToastProps) {\n const { id, content, options, dismissing } = item;\n const { duration, showRemainingTime, showCloseButton, pauseOnHover, color, classNames, styles: slotStyles } = options;\n const tone = toneProps(color);\n useToneCheck('Toast', [color]);\n\n const [hovered, setHovered] = useState(false);\n const [focused, setFocused] = useState(false);\n\n const [swiped, setSwiped] = useState(false);\n const { ref: swipeRef, isDragging } = useSwipeDismiss<HTMLDivElement>({\n onDismiss: () => {\n setSwiped(true);\n onDismiss(id);\n },\n });\n\n const paused = (pauseOnHover && (hovered || focused)) || isDragging;\n\n // Remaining time is carried across pause/resume cycles so the timer continues\n // where it left off instead of restarting on every hover.\n const remainingRef = useRef(duration);\n\n useEffect(() => {\n if (duration === 0 || paused) return;\n const start = Date.now();\n const timer = setTimeout(() => onDismiss(id), remainingRef.current);\n return () => {\n clearTimeout(timer);\n remainingRef.current -= Date.now() - start;\n };\n }, [id, duration, onDismiss, paused]);\n\n return (\n <div\n ref={swipeRef}\n className={cx(\n styles.toast,\n isBottom ? styles.toastBottom : null,\n tone.className,\n dismissing && !swiped && styles.toastDismissing,\n paused && styles.toastPaused,\n classNames?.root,\n )}\n style={{ ...tone.style, ...slotStyles?.root }}\n onMouseEnter={pauseOnHover ? () => setHovered(true) : undefined}\n onMouseLeave={pauseOnHover ? () => setHovered(false) : undefined}\n onFocus={pauseOnHover ? () => setFocused(true) : undefined}\n onBlur={pauseOnHover ? () => setFocused(false) : undefined}\n >\n <FontAwesomeIcon\n icon={ICON_BY_COLOR.get(color) ?? faBell}\n className={cx(styles.toastIcon, classNames?.icon)}\n style={slotStyles?.icon as React.CSSProperties & Record<`--fa-font-${string}`, string>}\n />\n\n <div className={cx(styles.toastContent, classNames?.content)} style={slotStyles?.content}>\n {content}\n </div>\n\n {showCloseButton && (\n <ActionIcon\n icon={faXmark}\n color='var(--text-dark)'\n onClick={() => onDismiss(id)}\n className={cx(styles.toastCloseButton, classNames?.closeButton)}\n style={slotStyles?.closeButton}\n aria-label={labels.close}\n />\n )}\n\n {showRemainingTime && duration > 0 && (\n <div\n className={cx(styles.toastProgressBar, classNames?.progressBar)}\n style={{ '--toast-duration': `${duration}ms`, ...slotStyles?.progressBar } as React.CSSProperties}\n />\n )}\n </div>\n );\n}\n\nexport default Toast;\n"],"mappings":"6nBA4BA,IAAM,EAAgB,IAAI,IAA2B,CACnD,CAAC,EAAW,KAAM,CAAY,EAC9B,CAAC,EAAW,QAAS,CAAa,EAClC,CAAC,EAAW,KAAM,CAAqB,EACvC,CAAC,EAAW,MAAO,CAAa,CAClC,CAAC,EAED,SAAS,EAAM,CAAE,OAAM,WAAU,YAAW,UAAsB,CAChE,GAAM,CAAE,KAAI,UAAS,UAAS,cAAe,EACvC,CAAE,WAAU,oBAAmB,kBAAiB,eAAc,QAAO,aAAY,OAAQ,GAAe,EACxG,EAAO,EAAU,CAAK,EAC5B,EAAa,QAAS,CAAC,CAAK,CAAC,EAE7B,GAAM,CAAC,EAAS,GAAc,EAAS,EAAK,EACtC,CAAC,EAAS,GAAc,EAAS,EAAK,EAEtC,CAAC,EAAQ,GAAa,EAAS,EAAK,EACpC,CAAE,IAAK,EAAU,cAAe,EAAgC,CACpE,cAAiB,CACf,EAAU,EAAI,EACd,EAAU,CAAE,CACd,CACF,CAAC,EAEK,EAAU,IAAiB,GAAW,IAAa,EAInD,EAAe,EAAO,CAAQ,EAYpC,OAVA,MAAgB,CACd,GAAI,IAAa,GAAK,EAAQ,OAC9B,IAAM,EAAQ,KAAK,IAAI,EACjB,EAAQ,eAAiB,EAAU,CAAE,EAAG,EAAa,OAAO,EAClE,UAAa,CACX,aAAa,CAAK,EAClB,EAAa,SAAW,KAAK,IAAI,EAAI,CACvC,CACF,EAAG,CAAC,EAAI,EAAU,EAAW,CAAM,CAAC,EAGlC,EAAC,MAAD,CACE,IAAK,EACL,UAAW,EACT,EAAO,MACP,EAAW,EAAO,YAAc,KAChC,EAAK,UACL,GAAc,CAAC,GAAU,EAAO,gBAChC,GAAU,EAAO,YACjB,GAAY,IACd,EACA,MAAO,CAAE,GAAG,EAAK,MAAO,GAAG,GAAY,IAAK,EAC5C,aAAc,MAAqB,EAAW,EAAI,EAAI,IAAA,GACtD,aAAc,MAAqB,EAAW,EAAK,EAAI,IAAA,GACvD,QAAS,MAAqB,EAAW,EAAI,EAAI,IAAA,GACjD,OAAQ,MAAqB,EAAW,EAAK,EAAI,IAAA,GAdnD,SAAA,CAgBE,EAAC,EAAD,CACE,KAAM,EAAc,IAAI,CAAK,GAAK,EAClC,UAAW,EAAG,EAAO,UAAW,GAAY,IAAI,EAChD,MAAO,GAAY,IACpB,CAAA,EAED,EAAC,MAAD,CAAK,UAAW,EAAG,EAAO,aAAc,GAAY,OAAO,EAAG,MAAO,GAAY,QAC9E,SAAA,CACE,CAAA,EAEJ,GACC,EAAC,EAAD,CACE,KAAM,EACN,MAAM,mBACN,YAAe,EAAU,CAAE,EAC3B,UAAW,EAAG,EAAO,iBAAkB,GAAY,WAAW,EAC9D,MAAO,GAAY,YACnB,aAAY,EAAO,KACpB,CAAA,EAGF,GAAqB,EAAW,GAC/B,EAAC,MAAD,CACE,UAAW,EAAG,EAAO,iBAAkB,GAAY,WAAW,EAC9D,MAAO,CAAE,mBAAoB,GAAG,EAAS,IAAK,GAAG,GAAY,WAAY,CAC1E,CAAA,CAEA,GAET"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";var e=`container_krdsW`,t=`container-top-left_zfDTO`,n=`container-top-center_CUIGc`,r=`container-top-right_sB0KU`,i=`container-bottom-left_toJdF`,a=`container-bottom-center_Bkf9m`,o=`container-bottom-right_oRSMc`,s=`toast_qBi4o`,c=`toastSlideDown_4lKWq`,l=`toast-bottom_X8ZIe`,u=`toastSlideUp_SGR5X`,d=`toast-dismissing_xKmB-`,f=`toastFadeOut_cvHYp`,p=`toast-paused_NPmT4`,m=`toastProgressBar_6vBs6`,h=`
|
|
1
|
+
"use client";var e=`container_krdsW`,t=`container-top-left_zfDTO`,n=`container-top-center_CUIGc`,r=`container-top-right_sB0KU`,i=`container-bottom-left_toJdF`,a=`container-bottom-center_Bkf9m`,o=`container-bottom-right_oRSMc`,s=`toast_qBi4o`,c=`toastSlideDown_4lKWq`,l=`toast-bottom_X8ZIe`,u=`toastSlideUp_SGR5X`,d=`toast-dismissing_xKmB-`,f=`toastFadeOut_cvHYp`,p=`toast-paused_NPmT4`,m=`toastProgressBar_6vBs6`,h=`toastIcon_xU1nA`,g=`toastContent_gvyIv`,_=`toastCloseButton_n-YST`,v=`toastShrink_h89HS`,y={container:e,"container-top-left":`container-top-left_zfDTO`,containerTopLeft:t,"container-top-center":`container-top-center_CUIGc`,containerTopCenter:n,"container-top-right":`container-top-right_sB0KU`,containerTopRight:r,"container-bottom-left":`container-bottom-left_toJdF`,containerBottomLeft:i,"container-bottom-center":`container-bottom-center_Bkf9m`,containerBottomCenter:a,"container-bottom-right":`container-bottom-right_oRSMc`,containerBottomRight:o,toast:s,toastSlideDown:c,"toast-bottom":`toast-bottom_X8ZIe`,toastBottom:l,toastSlideUp:u,"toast-dismissing":`toast-dismissing_xKmB-`,toastDismissing:d,toastFadeOut:f,"toast-paused":`toast-paused_NPmT4`,toastPaused:p,toastProgressBar:m,toastIcon:h,toastContent:g,toastCloseButton:_,toastShrink:v};export{e as container,a as containerBottomCenter,i as containerBottomLeft,o as containerBottomRight,n as containerTopCenter,t as containerTopLeft,r as containerTopRight,y as default,s as toast,l as toastBottom,_ as toastCloseButton,g as toastContent,d as toastDismissing,f as toastFadeOut,h as toastIcon,p as toastPaused,m as toastProgressBar,v as toastShrink,c as toastSlideDown,u as toastSlideUp};
|
|
2
2
|
//# sourceMappingURL=toast.module.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toast.module.mjs","names":[],"sources":["../../../../package/common/toast/toast.module.pcss"],"sourcesContent":[".container {\n position: fixed;\n z-index: 9999;\n display: flex;\n flex-direction: column;\n gap: 0.5em;\n pointer-events: none;\n padding: 1em;\n box-sizing: border-box;\n\n &-top-left {\n top: 0;\n left: 0;\n align-items: flex-start;\n }\n\n &-top-center {\n top: 0;\n left: 50%;\n transform: translateX(-50%);\n align-items: center;\n }\n\n &-top-right {\n top: 0;\n right: 0;\n align-items: flex-end;\n }\n\n &-bottom-left {\n bottom: 0;\n left: 0;\n align-items: flex-start;\n flex-direction: column-reverse;\n }\n\n &-bottom-center {\n bottom: 0;\n left: 50%;\n transform: translateX(-50%);\n align-items: center;\n flex-direction: column-reverse;\n }\n\n &-bottom-right {\n bottom: 0;\n right: 0;\n align-items: flex-end;\n flex-direction: column-reverse;\n }\n}\n\n.toast {\n pointer-events: all;\n display: flex;\n align-items: flex-start;\n gap: 0.625em;\n padding: 0.75em 0.875em;\n border-radius: var(--default-border-radius);\n background: var(--background-modal);\n color: var(--text-color);\n font-family: var(--default-font);\n box-shadow: var(--card-shadow);\n\n /* em, so the line length stays a measure rather than a pixel count. The screen\n wins over both: below about 270px the minimum alone was wider than the space\n the container had, and a toast pinned to one edge hung off the other. The 2em\n is the container's own padding, which is in the same em as these. */\n min-width: min(15em, calc(100vw - 2em));\n max-width: min(23.75em, calc(100vw - 2em));\n box-sizing: border-box;\n position: relative;\n\n /* Tells the browser vertical panning is native (so the page can still scroll behind the toast)\n while horizontal movement is left for useSwipeDismiss's own pointer handling to decide. */\n touch-action: pan-y;\n overflow: hidden;\n animation: toastSlideDown 0.25s ease forwards;\n\n &-bottom {\n animation: toastSlideUp 0.25s ease forwards;\n }\n\n &-dismissing {\n animation: toastFadeOut 0.2s ease forwards;\n }\n\n &-paused .toastProgressBar {\n animation-play-state: paused;\n }\n
|
|
1
|
+
{"version":3,"file":"toast.module.mjs","names":[],"sources":["../../../../package/common/toast/toast.module.pcss"],"sourcesContent":[".container {\n position: fixed;\n z-index: 9999;\n display: flex;\n flex-direction: column;\n gap: 0.5em;\n pointer-events: none;\n padding: 1em;\n box-sizing: border-box;\n\n &-top-left {\n top: 0;\n left: 0;\n align-items: flex-start;\n }\n\n &-top-center {\n top: 0;\n left: 50%;\n transform: translateX(-50%);\n align-items: center;\n }\n\n &-top-right {\n top: 0;\n right: 0;\n align-items: flex-end;\n }\n\n &-bottom-left {\n bottom: 0;\n left: 0;\n align-items: flex-start;\n flex-direction: column-reverse;\n }\n\n &-bottom-center {\n bottom: 0;\n left: 50%;\n transform: translateX(-50%);\n align-items: center;\n flex-direction: column-reverse;\n }\n\n &-bottom-right {\n bottom: 0;\n right: 0;\n align-items: flex-end;\n flex-direction: column-reverse;\n }\n}\n\n.toast {\n pointer-events: all;\n display: flex;\n align-items: flex-start;\n gap: 0.625em;\n padding: 0.75em 0.875em;\n border-radius: var(--default-border-radius);\n border-left: 0.1875em solid var(--tone);\n background: var(--background-modal);\n\n /* Must follow the shorthand above, which resets it. The gradient reaches over border-left only\n because its origin is the border box; the border is the fallback. */\n background-image: var(--tone-gradient);\n background-repeat: no-repeat;\n background-size: 0.1875em 100%;\n background-origin: border-box;\n color: var(--text-color);\n font-family: var(--default-font);\n box-shadow: var(--card-shadow);\n\n /* em, so the line length stays a measure rather than a pixel count. The screen\n wins over both: below about 270px the minimum alone was wider than the space\n the container had, and a toast pinned to one edge hung off the other. The 2em\n is the container's own padding, which is in the same em as these. */\n min-width: min(15em, calc(100vw - 2em));\n max-width: min(23.75em, calc(100vw - 2em));\n box-sizing: border-box;\n position: relative;\n\n /* Tells the browser vertical panning is native (so the page can still scroll behind the toast)\n while horizontal movement is left for useSwipeDismiss's own pointer handling to decide. */\n touch-action: pan-y;\n overflow: hidden;\n animation: toastSlideDown 0.25s ease forwards;\n\n &-bottom {\n animation: toastSlideUp 0.25s ease forwards;\n }\n\n &-dismissing {\n animation: toastFadeOut 0.2s ease forwards;\n }\n\n &-paused .toastProgressBar {\n animation-play-state: paused;\n }\n}\n\n.toastIcon {\n flex-shrink: 0;\n color: var(--tone);\n margin-top: 0.0667em; /* 1px against this element's own 0.9375em */\n font-size: 0.9375em;\n}\n\n.toastContent {\n flex: 1;\n font-size: 0.875em;\n line-height: 1.4;\n}\n\n/* Two classes, to outrank Button's font-size and ActionIcon's box whichever stylesheet loads\n first. */\n.toast .toastCloseButton {\n flex-shrink: 0;\n width: 1em;\n height: 1em;\n font-size: 0.8125em;\n opacity: 0.6;\n transition: opacity 0.15s;\n margin-top: 0.0769em; /* 1px against this element's own 0.8125em */\n\n &:hover {\n opacity: 1;\n }\n}\n\n.toastProgressBar {\n position: absolute;\n bottom: 0;\n left: 0;\n height: 0.1875em;\n width: 100%;\n background: currentcolor;\n opacity: 0.35;\n transform-origin: left;\n animation: toastShrink var(--toast-duration) linear forwards;\n}\n\n@keyframes toastSlideDown {\n from {\n opacity: 0;\n transform: translateY(-0.75em);\n }\n\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes toastSlideUp {\n from {\n opacity: 0;\n transform: translateY(0.75em);\n }\n\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes toastFadeOut {\n from {\n opacity: 1;\n transform: scale(1);\n }\n\n to {\n opacity: 0;\n transform: scale(0.92);\n }\n}\n\n@keyframes toastShrink {\n from {\n transform: scaleX(1);\n }\n\n to {\n transform: scaleX(0);\n }\n}\n\n/* The entrance and exit slide go. `toastShrink` stays: it is the remaining-time indicator, and a\n progress bar frozen at full width would tell the user the opposite of what is true. Removal is\n driven by a timer in toastProvider, not by these animations, so dropping them cannot strand a\n toast on screen. */\n@media (prefers-reduced-motion: reduce) {\n .toast,\n .toast-bottom,\n .toast-dismissing {\n animation: none;\n }\n}\n"],"mappings":""}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import e from"../bodyEnd/bodyEnd.mjs";import
|
|
1
|
+
"use client";import{ThemeColor as e}from"../themeProvider/color.types.mjs";import t from"../bodyEnd/bodyEnd.mjs";import n from"./toast.module.mjs";import r from"./toast.mjs";import{_registerToastHandler as i,_unregisterToastHandler as a}from"./toastService.mjs";import{useCallback as o,useInsertionEffect as s,useRef as c,useState as l}from"react";import u from"classnames";import{Fragment as d,jsx as f,jsxs as p}from"react/jsx-runtime";var m={position:`top-right`,duration:4e3,showRemainingTime:!0,showCloseButton:!0,allowStacking:!0,pauseOnHover:!0,labels:{close:`Close`}},h=220;function g(e){return n[`container-${e}`]}function _({children:_,position:v=m.position,duration:y=m.duration,showRemainingTime:b=m.showRemainingTime,showCloseButton:x=m.showCloseButton,allowStacking:S=m.allowStacking,pauseOnHover:C=m.pauseOnHover,labels:w}){let[T,E]=l([]),D=c(0),O=o(e=>{E(t=>t.map(t=>t.id===e?{...t,dismissing:!0}:t)),setTimeout(()=>{E(t=>t.filter(t=>t.id!==e))},h)},[]),k=o((t,n)=>{let r={position:n?.position??v,duration:n?.duration??y,showRemainingTime:n?.showRemainingTime??b,showCloseButton:n?.showCloseButton??x,pauseOnHover:n?.pauseOnHover??C,color:n?.color??e.Primary,classNames:n?.classNames,styles:n?.styles};D.current+=1;let i={id:`toast-${D.current}`,content:t,options:r,dismissing:!1,labels:n?.labels};E(e=>!S&&e.length>0?(setTimeout(()=>{E([i])},h),e.map(e=>({...e,dismissing:!0}))):[...e,i])},[v,y,b,x,S,C]),A=c(k);s(()=>{A.current=k},[k]),s(()=>{let e=(e,t)=>A.current(e,t);return i(e),()=>a(e)},[]);let j=T.reduce((e,t)=>{let n=t.options.position;return e[n]||(e[n]=[]),e[n].push(t),e},{});return p(d,{children:[_,f(t,{children:Object.entries(j).map(([e,t])=>f(`div`,{className:u(n.container,g(e)),children:t.map(t=>f(r,{item:t,isBottom:e.startsWith(`bottom`),onDismiss:O,labels:{...m.labels,...w,...t.labels}},t.id))},e))})]})}export{_ as default};
|
|
2
2
|
//# sourceMappingURL=toastHost.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toastHost.mjs","names":[],"sources":["../../../../package/common/toast/toastHost.tsx"],"sourcesContent":["import React, { useCallback, useInsertionEffect, useRef, useState } from 'react';\nimport cx from 'classnames';\nimport BodyEnd from 'components/common/bodyEnd';\n\nimport styles from './toast.module.pcss';\nimport Toast from './toast';\nimport { _registerToastHandler, _unregisterToastHandler } from './toastService';\nimport type {\n ToastContextConfig,\n ToastItem,\n ToastOptions,\n ResolvedToastOptions,\n ToastPosition,\n ToastLabels,\n ToastHostProps,\n} from './toast.types';\nimport type { ReactNode } from 'react';\n\nconst DEFAULTS: Required<ToastContextConfig> = {\n position: 'top-right',\n duration: 4000,\n showRemainingTime: true,\n showCloseButton: true,\n allowStacking: true,\n pauseOnHover: true,\n labels: { close: 'Close' },\n};\n\nconst DISMISS_ANIMATION_MS = 220;\n\nfunction positionToClass(position: ToastPosition): string {\n return styles[`container-${position}`];\n}\n\nfunction ToastHost({\n children,\n position = DEFAULTS.position,\n duration = DEFAULTS.duration,\n showRemainingTime = DEFAULTS.showRemainingTime,\n showCloseButton = DEFAULTS.showCloseButton,\n allowStacking = DEFAULTS.allowStacking,\n pauseOnHover = DEFAULTS.pauseOnHover,\n labels,\n}: ToastHostProps) {\n const [toasts, setToasts] = useState<ToastItem[]>([]);\n const counterRef = useRef(0);\n\n const dismiss = useCallback((id: string) => {\n setToasts((prev) => prev.map((t) => (t.id === id ? { ...t, dismissing: true } : t)));\n setTimeout(() => {\n setToasts((prev) => prev.filter((t) => t.id !== id));\n }, DISMISS_ANIMATION_MS);\n }, []);\n\n const addToast = useCallback(\n (content: ReactNode, options?: ToastOptions) => {\n const resolved: ResolvedToastOptions = {\n position: options?.position ?? position,\n duration: options?.duration ?? duration,\n showRemainingTime: options?.showRemainingTime ?? showRemainingTime,\n showCloseButton: options?.showCloseButton ?? showCloseButton,\n pauseOnHover: options?.pauseOnHover ?? pauseOnHover,\n
|
|
1
|
+
{"version":3,"file":"toastHost.mjs","names":[],"sources":["../../../../package/common/toast/toastHost.tsx"],"sourcesContent":["import React, { useCallback, useInsertionEffect, useRef, useState } from 'react';\nimport cx from 'classnames';\nimport BodyEnd from 'components/common/bodyEnd';\n\nimport styles from './toast.module.pcss';\nimport Toast from './toast';\nimport { _registerToastHandler, _unregisterToastHandler } from './toastService';\nimport type {\n ToastContextConfig,\n ToastItem,\n ToastOptions,\n ResolvedToastOptions,\n ToastPosition,\n ToastLabels,\n ToastHostProps,\n} from './toast.types';\nimport type { ReactNode } from 'react';\nimport { ThemeColor } from '../themeProvider/color.types';\n\nconst DEFAULTS: Required<ToastContextConfig> = {\n position: 'top-right',\n duration: 4000,\n showRemainingTime: true,\n showCloseButton: true,\n allowStacking: true,\n pauseOnHover: true,\n labels: { close: 'Close' },\n};\n\nconst DISMISS_ANIMATION_MS = 220;\n\nfunction positionToClass(position: ToastPosition): string {\n return styles[`container-${position}`];\n}\n\nfunction ToastHost({\n children,\n position = DEFAULTS.position,\n duration = DEFAULTS.duration,\n showRemainingTime = DEFAULTS.showRemainingTime,\n showCloseButton = DEFAULTS.showCloseButton,\n allowStacking = DEFAULTS.allowStacking,\n pauseOnHover = DEFAULTS.pauseOnHover,\n labels,\n}: ToastHostProps) {\n const [toasts, setToasts] = useState<ToastItem[]>([]);\n const counterRef = useRef(0);\n\n const dismiss = useCallback((id: string) => {\n setToasts((prev) => prev.map((t) => (t.id === id ? { ...t, dismissing: true } : t)));\n setTimeout(() => {\n setToasts((prev) => prev.filter((t) => t.id !== id));\n }, DISMISS_ANIMATION_MS);\n }, []);\n\n const addToast = useCallback(\n (content: ReactNode, options?: ToastOptions) => {\n const resolved: ResolvedToastOptions = {\n position: options?.position ?? position,\n duration: options?.duration ?? duration,\n showRemainingTime: options?.showRemainingTime ?? showRemainingTime,\n showCloseButton: options?.showCloseButton ?? showCloseButton,\n pauseOnHover: options?.pauseOnHover ?? pauseOnHover,\n color: options?.color ?? ThemeColor.Primary,\n classNames: options?.classNames,\n styles: options?.styles,\n };\n\n counterRef.current += 1;\n const id = `toast-${counterRef.current}`;\n const newToast: ToastItem = { id, content, options: resolved, dismissing: false, labels: options?.labels };\n\n setToasts((prev) => {\n if (!allowStacking && prev.length > 0) {\n // Mark all existing as dismissing, then replace\n setTimeout(() => {\n setToasts([newToast]);\n }, DISMISS_ANIMATION_MS);\n return prev.map((t) => ({ ...t, dismissing: true }));\n }\n return [...prev, newToast];\n });\n },\n [position, duration, showRemainingTime, showCloseButton, allowStacking, pauseOnHover],\n );\n\n // Insertion effects run before every layout and passive effect, including the app's, which as\n // this host's descendants would otherwise run first. Registered once, so that a settings change\n // does not move this host to the end of the list.\n const latestAddToast = useRef(addToast);\n useInsertionEffect(() => {\n latestAddToast.current = addToast;\n }, [addToast]);\n\n useInsertionEffect(() => {\n const show: typeof addToast = (content, options) => latestAddToast.current(content, options);\n _registerToastHandler(show);\n return () => _unregisterToastHandler(show);\n }, []);\n\n // Group toasts by position so per-toast position overrides work correctly\n const byPosition = toasts.reduce<Record<string, ToastItem[]>>((acc, t) => {\n const pos = t.options.position;\n if (!acc[pos]) acc[pos] = [];\n acc[pos].push(t);\n return acc;\n }, {});\n\n return (\n <>\n {children}\n <BodyEnd>\n {Object.entries(byPosition).map(([pos, items]) => (\n <div key={pos} className={cx(styles.container, positionToClass(pos as typeof position))}>\n {items.map((item) => (\n <Toast\n key={item.id}\n item={item}\n isBottom={pos.startsWith('bottom')}\n onDismiss={dismiss}\n labels={{ ...DEFAULTS.labels, ...labels, ...item.labels } as Required<ToastLabels>}\n />\n ))}\n </div>\n ))}\n </BodyEnd>\n </>\n );\n}\n\nexport default ToastHost;\n"],"mappings":"sbAmBA,IAAM,EAAyC,CAC7C,SAAU,YACV,SAAU,IACV,kBAAmB,GACnB,gBAAiB,GACjB,cAAe,GACf,aAAc,GACd,OAAQ,CAAE,MAAO,OAAQ,CAC3B,EAEM,EAAuB,IAE7B,SAAS,EAAgB,EAAiC,CACxD,OAAO,EAAO,aAAa,IAC7B,CAEA,SAAS,EAAU,CACjB,WACA,WAAW,EAAS,SACpB,WAAW,EAAS,SACpB,oBAAoB,EAAS,kBAC7B,kBAAkB,EAAS,gBAC3B,gBAAgB,EAAS,cACzB,eAAe,EAAS,aACxB,UACiB,CACjB,GAAM,CAAC,EAAQ,GAAa,EAAsB,CAAC,CAAC,EAC9C,EAAa,EAAO,CAAC,EAErB,EAAU,EAAa,GAAe,CAC1C,EAAW,GAAS,EAAK,IAAK,GAAO,EAAE,KAAO,EAAK,CAAE,GAAG,EAAG,WAAY,EAAK,EAAI,CAAE,CAAC,EACnF,eAAiB,CACf,EAAW,GAAS,EAAK,OAAQ,GAAM,EAAE,KAAO,CAAE,CAAC,CACrD,EAAG,CAAoB,CACzB,EAAG,CAAC,CAAC,EAEC,EAAW,GACd,EAAoB,IAA2B,CAC9C,IAAM,EAAiC,CACrC,SAAU,GAAS,UAAY,EAC/B,SAAU,GAAS,UAAY,EAC/B,kBAAmB,GAAS,mBAAqB,EACjD,gBAAiB,GAAS,iBAAmB,EAC7C,aAAc,GAAS,cAAgB,EACvC,MAAO,GAAS,OAAS,EAAW,QACpC,WAAY,GAAS,WACrB,OAAQ,GAAS,MACnB,EAEA,EAAW,SAAW,EAEtB,IAAM,EAAsB,CAAE,GAAA,SADV,EAAW,UACG,UAAS,QAAS,EAAU,WAAY,GAAO,OAAQ,GAAS,MAAO,EAEzG,EAAW,GACL,CAAC,GAAiB,EAAK,OAAS,GAElC,eAAiB,CACf,EAAU,CAAC,CAAQ,CAAC,CACtB,EAAG,CAAoB,EAChB,EAAK,IAAK,IAAO,CAAE,GAAG,EAAG,WAAY,EAAK,EAAE,GAE9C,CAAC,GAAG,EAAM,CAAQ,CAC1B,CACH,EACA,CAAC,EAAU,EAAU,EAAmB,EAAiB,EAAe,CAAY,CACtF,EAKM,EAAiB,EAAO,CAAQ,EACtC,MAAyB,CACvB,EAAe,QAAU,CAC3B,EAAG,CAAC,CAAQ,CAAC,EAEb,MAAyB,CACvB,IAAM,GAAyB,EAAS,IAAY,EAAe,QAAQ,EAAS,CAAO,EAE3F,OADA,EAAsB,CAAI,MACb,EAAwB,CAAI,CAC3C,EAAG,CAAC,CAAC,EAGL,IAAM,EAAa,EAAO,QAAqC,EAAK,IAAM,CACxE,IAAM,EAAM,EAAE,QAAQ,SAGtB,OAFK,EAAI,KAAM,EAAI,GAAO,CAAC,GAC3B,EAAI,EAAI,CAAC,KAAK,CAAC,EACR,CACT,EAAG,CAAC,CAAC,EAEL,OACE,EAAA,EAAA,CAAA,SAAA,CACG,EACD,EAAC,EAAD,CAAA,SACG,OAAO,QAAQ,CAAU,CAAC,CAAC,KAAK,CAAC,EAAK,KACrC,EAAC,MAAD,CAAe,UAAW,EAAG,EAAO,UAAW,EAAgB,CAAsB,CAAC,EACnF,SAAA,EAAM,IAAK,GACV,EAAC,EAAD,CAEQ,OACN,SAAU,EAAI,WAAW,QAAQ,EACjC,UAAW,EACX,OAAQ,CAAE,GAAG,EAAS,OAAQ,GAAG,EAAQ,GAAG,EAAK,MAAO,CACzD,EALM,EAAK,EAKX,CACF,CACE,EAVK,CAUL,CACN,CACM,CAAA,CACT,CAAA,CAAA,CAEN"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";var e=new WeakSet,t=!1,n=!1;function r(n){t&&e.add(n),t=!1}function i(){t=!1}function a(){t=!0,!n&&(n=!0,window.addEventListener(`click`,r,!0),window.addEventListener(`pointerdown`,i,!0))}function o(t){return e.has(t)}export{o as isDismissClick,a as markDismiss};
|
|
2
|
+
//# sourceMappingURL=dismissClick.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dismissClick.mjs","names":[],"sources":["../../../../package/common/utils/dismissClick.ts"],"sourcesContent":["// A press outside a Popover closes it on release, and the click that follows still reaches what\n// was under the pointer, so a click on another event can open that one. A click that creates\n// something (Calendar's empty time) asks here first, so a click that only closed a popover does not\n// also open the next one.\n\nconst dismissClicks = new WeakSet<Event>();\nlet armed = false;\nlet listening = false;\n\nfunction onClick(event: Event) {\n if (armed) dismissClicks.add(event);\n armed = false;\n}\n\n// A release with no click after it, such as the end of a drag, must not mark a later click.\nfunction onPress() {\n armed = false;\n}\n\n/** Records that the release just dispatched closed an overlay, which marks the click it raises. */\nexport function markDismiss(): void {\n armed = true;\n if (listening) return;\n listening = true;\n // Capturing on the window, so the click is marked before any handler below it runs.\n window.addEventListener('click', onClick, true);\n window.addEventListener('pointerdown', onPress, true);\n}\n\n/** Whether the click `event` ends a press that closed an overlay. */\nexport function isDismissClick(event: Event): boolean {\n return dismissClicks.has(event);\n}\n"],"mappings":"aAKA,IAAM,EAAgB,IAAI,QACtB,EAAQ,GACR,EAAY,GAEhB,SAAS,EAAQ,EAAc,CACzB,GAAO,EAAc,IAAI,CAAK,EAClC,EAAQ,EACV,CAGA,SAAS,GAAU,CACjB,EAAQ,EACV,CAGA,SAAgB,GAAoB,CAClC,EAAQ,GACJ,KACJ,EAAY,GAEZ,OAAO,iBAAiB,QAAS,EAAS,EAAI,EAC9C,OAAO,iBAAiB,cAAe,EAAS,EAAI,EACtD,CAGA,SAAgB,EAAe,EAAuB,CACpD,OAAO,EAAc,IAAI,CAAK,CAChC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isDev.mjs","names":[],"sources":["../../../../package/common/utils/isDev.ts"],"sourcesContent":["// No `typeof process` guard: a browser has no `process` even where a bundler replaced\n// `process.env.NODE_ENV`, so the guard turned every warning off. Unbundled, the ReferenceError\n// means production. Declared here rather than globally, to stay out of the .d.ts.\ndeclare const process: { env: { NODE_ENV?: string } };\n\nexport function isDev(): boolean {\n try {\n return process.env.NODE_ENV !== 'production';\n } catch {\n return false;\n }\n}\n"],"mappings":"aAKA,SAAgB,GAAiB,CAC/B,GAAI,CACF,OAAA,QAAA,IAAA,WAAgC,YAClC,MAAQ,CACN,MAAO,EACT,CACF"}
|
package/dist/esm/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{AccordionStyleType as e}from"./common/accordion/accordion.types.mjs";import t from"./common/configProvider/configProvider.mjs";import{useComponentDefaults as n}from"./common/configProvider/useComponentDefaults.mjs";import{useLabels as r}from"./common/configProvider/useLabels.mjs";import{usePresentationDefault as i}from"./common/configProvider/usePresentationDefault.mjs";import{Presentation as a}from"./common/configProvider/presentation.types.mjs";import o from"./common/accordion/accordion.mjs";import s from"./common/loading/spinnerLoading/index.mjs";import{ButtonSize as c,ButtonStyleType as l,ButtonType as u}from"./common/button/button.types.mjs";import d from"./common/ripple/ripple.mjs";import f from"./common/button/button.mjs";import p from"./common/actionButtons/actionButtons.mjs";import m from"./common/interactableDiv/index.mjs";import h from"./common/actionIcon/actionIcon.mjs";import g from"./common/scrollbarProvider/index.mjs";import{defaultTheme as _}from"./common/themeProvider/defaultTheme.mjs";import v from"./common/themeProvider/themeProvider.mjs";import{lightTheme as y}from"./common/themeProvider/lightTheme.mjs";import b from"./common/bodyEnd/bodyEnd.mjs";import x from"./common/hooks/useMediaQuery.mjs";import S from"./common/hooks/useCoarsePointer.mjs";import{useSwipeDismiss as C}from"./common/hooks/useSwipeDismiss.mjs";import{showToast as w}from"./common/toast/toastService.mjs";import T from"./common/ahroweProvider/ahroweProvider.mjs";import{AlertStyleType as E}from"./common/alert/alert.types.mjs";import D from"./common/alert/alert.mjs";import O from"./common/animatedLogo/animatedLogo.mjs";import{AnimatedTextUnit as k,AnimatedTextVariant as A}from"./common/animatedText/animatedText.types.mjs";import j from"./common/animatedText/animatedText.mjs";import{BadgePosition as M,BadgeStyleType as N}from"./common/badge/badge.types.mjs";import P from"./common/badge/badge.mjs";import F from"./common/avatar/avatar.mjs";import I from"./common/avatar/avatarGroup.mjs";import{PopoverAlign as L,PopoverPlacement as R,PopoverTrigger as z}from"./common/popover/popover.types.mjs";import{tabbablesIn as B}from"./common/hooks/useFocusBoundary.mjs";import{useVisualViewportSize as V}from"./common/hooks/useVisualViewportSize.mjs";import{useOverlay as H}from"./common/hooks/useOverlay.mjs";import U from"./common/popover/popover.mjs";import W from"./common/breadcrumb/breadcrumb.mjs";import{ButtonGroupOrientation as G}from"./common/buttonGroup/buttonGroup.types.mjs";import K from"./common/buttonGroup/buttonGroup.mjs";import{dateToDay as q,dateToTime as J,dayTimeToDate as Y,dayToDate as X}from"./common/utils/day.mjs";import{CalendarView as Z}from"./common/calendar/calendar.types.mjs";import Q from"./common/optionPicker/optionPicker.mjs";import $ from"./common/calendar/calendar.mjs";import{CardStyleType as ee}from"./common/card/card.types.mjs";import te from"./common/card/Card.mjs";import ne from"./common/card/CardHeader.mjs";import re from"./common/card/CardMedia.mjs";import ie from"./common/card/CardContent.mjs";import ae from"./common/card/CardActions.mjs";import oe from"./common/carousel/carousel.mjs";import se from"./common/checkbox/checkbox.mjs";import{ChipStyleType as ce}from"./common/chip/chip.types.mjs";import le from"./common/chip/chip.mjs";import ue from"./common/chip/chipContainer.mjs";import de from"./common/tooltip/tooltip.mjs";import{InputIconPosition as fe,InputType as pe}from"./common/input/input.types.mjs";import me from"./common/input/input.mjs";import he from"./common/colorPicker/colorPicker.mjs";import{useScrollEdges as ge}from"./common/hooks/useScrollEdges.mjs";import _e from"./common/modal/modal.mjs";import ve,{formatHotkey as ye}from"./common/hooks/useHotkeys.mjs";import{isMenuAction as be,isMenuHeading as xe,isMenuSeparator as Se}from"./common/menu/menu.types.mjs";import Ce from"./common/commandPalette/commandPalette.mjs";import we from"./common/confirmModal/confirmModal.mjs";import Te from"./common/hooks/useClipboard.mjs";import Ee from"./common/copyButton/copyButton.mjs";import{getLocale as De,mapLocale as Oe,setLocale as ke}from"./services/localization.mjs";import Ae from"./common/dropdown/dropdown.mjs";import je from"./common/datePicker/datePicker.mjs";import{DividerOrientation as Me,DividerTextPosition as Ne}from"./common/divider/divider.types.mjs";import Pe from"./common/divider/divider.mjs";import Fe from"./common/drawer/drawer.mjs";import{DropZoneReturnType as Ie,DropZoneStatus as Le}from"./common/dropZone/dropZone.types.mjs";import Re from"./common/dropZone/dropZone.mjs";import ze from"./common/emptyState/emptyState.mjs";import Be from"./common/errorBoundary/errorBoundary.mjs";import Ve from"./common/fab/fab.mjs";import He from"./common/flip/flip.mjs";import{DoorSwing as Ue,OpeningKind as We,PlanIssueKind as Ge,PlanUnitSystem as Ke,WallType as qe}from"./common/floorPlan/floorPlan.types.mjs";import{MIN_OPENING_WIDTH as Je,MIN_WALL_LENGTH as Ye}from"./common/floorPlan/floorPlan.geometry.mjs";import{DEFAULT_WALL_ATTRS as Xe,addOpening as Ze,addRect as Qe,addWall as $e,cleanupPlan as et,detachWall as tt,dissolveNode as nt,mergeNodes as rt,moveNode as it,removeOpening as at,removeWall as ot,scalePlan as st,splitWall as ct,transformPlan as lt,updateOpening as ut,validatePlan as dt,wallLength as ft,weldShortWalls as pt}from"./common/floorPlan/floorPlan.graph.mjs";import{MIN_FLOOR_HEIGHT as mt,addFloor as ht,duplicateFloor as gt,emptyFloor as _t,emptyFloorPlan as vt,floorBelow as yt,floorBounds as bt,floorIndex as xt,getFloor as St,moveFloor as Ct,removeFloor as wt,renameFloor as Tt,setFloor as Et,setFloorHeight as Dt,updateFloor as Ot}from"./common/floorPlan/floorPlan.plan.mjs";import{deriveFaces as kt,nodeDegrees as At}from"./common/floorPlan/floorPlan.faces.mjs";import{commitDerivation as jt,derivePlan as Mt,pruneUnmatchedRooms as Nt,roomAtPoint as Pt}from"./common/floorPlan/floorPlan.rooms.mjs";import{buildWallPaths as Ft,openingGeometry as It,wallCentrelineSpans as Lt}from"./common/floorPlan/floorPlan.path.mjs";import{HIT_PX as Rt,HIT_PX_COARSE as zt,hitTest as Bt,selectionsEqual as Vt,worldTolerances as Ht}from"./common/floorPlan/floorPlan.hit.mjs";import{DEFAULT_SNAP_OPTIONS as Ut,SnapKind as Wt,clientToWorld as Gt,resolveSnap as Kt}from"./common/floorPlan/floorPlan.snap.mjs";import{PLAN_FORMAT_VERSION as qt,planFromJson as Jt,planToJson as Yt}from"./common/floorPlan/floorPlan.json.mjs";import{buildPlanMesh as Xt}from"./common/floorPlan/floorPlan.mesh.mjs";import Zt from"./common/iconPicker/iconPicker.mjs";import Qt from"./common/idleManager/idleManager.mjs";import $t from"./common/inputDropdown/inputDropdown.mjs";import en from"./common/kanbanBoard/KanbanColumn.mjs";import tn from"./common/kanbanBoard/KanbanBoard.mjs";import nn from"./common/searchInput/searchInput.mjs";import rn from"./common/klipyPicker/klipyPicker.mjs";import an from"./common/menu/menu.mjs";import{menuHotkeys as on}from"./common/menu/menuHotkeys.mjs";import sn from"./common/multiSelect/multiSelect.mjs";import cn from"./common/numberInput/index.mjs";import{OtpInputCharset as ln}from"./common/otpInput/otpInput.types.mjs";import un from"./common/otpInput/otpInput.mjs";import dn from"./common/overscroll/overscroll.mjs";import fn from"./common/pagination/pagination.mjs";import pn from"./common/progressBar/progressBar.mjs";import{RadioGroupOrientation as mn}from"./common/radioGroup/radioGroup.types.mjs";import hn from"./common/radioGroup/radioGroup.mjs";import gn from"./common/rating/rating.mjs";import _n from"./common/revealLens/revealLens.mjs";import vn from"./common/roomDrawer/roomDrawer.mjs";import yn from"./common/roomViewer/roomViewer.mjs";import{ScrollFadeAxis as bn}from"./common/scrollFade/scrollFade.types.mjs";import xn from"./common/scrollFade/scrollFade.mjs";import{SectionHeaderSize as Sn}from"./common/sectionHeader/sectionHeader.types.mjs";import Cn from"./common/sectionHeader/sectionHeader.mjs";import{SkeletonAnimation as wn,SkeletonVariant as Tn}from"./common/skeleton/skeleton.types.mjs";import En from"./common/skeleton/skeleton.mjs";import Dn from"./common/slider/slider.mjs";import On from"./common/splitButton/splitButton.mjs";import{StepperAlignment as kn,StepperCollapse as An,StepperLabelPlacement as jn,StepperStyleType as Mn}from"./common/stepper/stepper.types.mjs";import Nn from"./common/stepper/stepper.mjs";import Pn from"./common/sticky/sticky.mjs";import Fn from"./common/switch/switch.mjs";import In from"./common/tabHeader/tabHeader.mjs";import Ln from"./common/textarea/textarea.mjs";import{useTheme as Rn}from"./common/themeProvider/useTheme.mjs";import zn,{TiltGroupContext as Bn,useTiltGroup as Vn}from"./common/tiltGroup/tiltGroup.mjs";import{defaultTiltEasing as Hn}from"./common/tilt/tiltMath.mjs";import Un from"./common/tilt/tilt.mjs";import Wn from"./common/timeInput/timeInput.mjs";import{TimelineAlignment as Gn,TimelineItemStatus as Kn}from"./common/timeline/timeline.types.mjs";import qn from"./common/timeline/timeline.mjs";import Jn from"./common/timer/timer.mjs";import Yn from"./common/virtualList/virtualList.mjs";import{flattenTree as Xn}from"./common/tree/flattenTree.mjs";import Zn from"./common/tree/tree.mjs";import{WeatherType as Qn}from"./common/weatherIcon/weatherIcon.types.mjs";import $n from"./common/weatherIcon/weatherIcon.mjs";import er from"./common/wizard/wizard.mjs";import tr from"./services/formValidation/FormValidatorGroupWithForm.mjs";import nr from"./services/formValidation/validatableComponent.mjs";import{useFormValidatorGroup as rr}from"./services/formValidation/useFormValidatorGroup.mjs";import{FormValidator as ir,Validators as ar,useFormValidator as or}from"./services/formValidation/index.mjs";import{hasEightPasswordChars as sr,hasOnePasswordDigit as cr,hasOnePasswordLetter as lr,isBic as ur,isDate as dr,isDay as fr,isEmail as pr,isISODate as mr,isNumber as hr,isPassword as gr,isURL as _r}from"@ahrowe/form-validation";export{o as Accordion,e as AccordionStyleType,p as ActionButtons,h as ActionIcon,T as AhroweProvider,D as Alert,E as AlertStyleType,O as AnimatedLogo,j as AnimatedText,k as AnimatedTextUnit,A as AnimatedTextVariant,F as Avatar,I as AvatarGroup,P as Badge,M as BadgePosition,N as BadgeStyleType,b as BodyEnd,W as Breadcrumb,f as Button,K as ButtonGroup,G as ButtonGroupOrientation,c as ButtonSize,l as ButtonStyleType,u as ButtonType,$ as Calendar,Z as CalendarView,te as Card,ae as CardActions,ie as CardContent,ne as CardHeader,re as CardMedia,ee as CardStyleType,oe as Carousel,se as Checkbox,le as Chip,ue as ChipContainer,ce as ChipStyleType,he as ColorPicker,Ce as CommandPalette,t as ConfigProvider,we as ConfirmModal,Ee as CopyButton,Ut as DEFAULT_SNAP_OPTIONS,Xe as DEFAULT_WALL_ATTRS,je as DatePicker,Pe as Divider,Me as DividerOrientation,Ne as DividerTextPosition,Ue as DoorSwing,Fe as Drawer,Re as DropZone,Ie as DropZoneReturnType,Le as DropZoneStatus,Ae as Dropdown,ze as EmptyState,Be as ErrorBoundary,Ve as Fab,He as Flip,ir as FormValidator,tr as FormValidatorGroup,Rt as HIT_PX,zt as HIT_PX_COARSE,Zt as IconPicker,Qt as IdleManager,me as Input,$t as InputDropdown,fe as InputIconPosition,pe as InputType,m as InteractableDiv,tn as KanbanBoard,en as KanbanColumn,rn as KlipyPicker,mt as MIN_FLOOR_HEIGHT,Je as MIN_OPENING_WIDTH,Ye as MIN_WALL_LENGTH,an as Menu,_e as Modal,sn as MultiSelect,cn as NumberInput,We as OpeningKind,Q as OptionPicker,un as OtpInput,ln as OtpInputCharset,dn as Overscroll,qt as PLAN_FORMAT_VERSION,fn as Pagination,Ge as PlanIssueKind,Ke as PlanUnitSystem,U as Popover,L as PopoverAlign,R as PopoverPlacement,z as PopoverTrigger,a as Presentation,pn as ProgressBar,hn as RadioGroup,mn as RadioGroupOrientation,gn as Rating,_n as RevealLens,d as Ripple,vn as RoomDrawer,yn as RoomViewer,xn as ScrollFade,bn as ScrollFadeAxis,g as ScrollbarProvider,nn as SearchInput,Cn as SectionHeader,Sn as SectionHeaderSize,En as Skeleton,wn as SkeletonAnimation,Tn as SkeletonVariant,Dn as Slider,Wt as SnapKind,s as SpinnerLoading,On as SplitButton,Nn as Stepper,kn as StepperAlignment,An as StepperCollapse,jn as StepperLabelPlacement,Mn as StepperStyleType,Pn as Sticky,Fn as Switch,In as TabHeader,Ln as Textarea,v as ThemeProvider,Un as Tilt,zn as TiltGroup,Bn as TiltGroupContext,Wn as TimeInput,qn as Timeline,Gn as TimelineAlignment,Kn as TimelineItemStatus,Jn as Timer,de as Tooltip,Zn as Tree,nr as ValidatableComponent,ar as Validators,Yn as VirtualList,qe as WallType,$n as WeatherIcon,Qn as WeatherType,er as Wizard,ht as addFloor,Ze as addOpening,Qe as addRect,$e as addWall,Xt as buildPlanMesh,Ft as buildWallPaths,et as cleanupPlan,Gt as clientToWorld,jt as commitDerivation,q as dateToDay,J as dateToTime,Y as dayTimeToDate,X as dayToDate,_ as defaultTheme,Hn as defaultTiltEasing,kt as deriveFaces,Mt as derivePlan,tt as detachWall,nt as dissolveNode,gt as duplicateFloor,_t as emptyFloor,vt as emptyFloorPlan,Xn as flattenTree,yt as floorBelow,bt as floorBounds,xt as floorIndex,ye as formatHotkey,St as getFloor,De as getLocale,sr as hasEightPasswordChars,cr as hasOnePasswordDigit,lr as hasOnePasswordLetter,Bt as hitTest,ur as isBic,dr as isDate,fr as isDay,pr as isEmail,mr as isISODate,be as isMenuAction,xe as isMenuHeading,Se as isMenuSeparator,hr as isNumber,gr as isPassword,_r as isURL,y as lightTheme,Oe as mapLocale,on as menuHotkeys,rt as mergeNodes,Ct as moveFloor,it as moveNode,At as nodeDegrees,It as openingGeometry,Jt as planFromJson,Yt as planToJson,Nt as pruneUnmatchedRooms,wt as removeFloor,at as removeOpening,ot as removeWall,Tt as renameFloor,Kt as resolveSnap,Pt as roomAtPoint,st as scalePlan,Vt as selectionsEqual,Et as setFloor,Dt as setFloorHeight,ke as setLocale,w as showToast,ct as splitWall,B as tabbablesIn,lt as transformPlan,Ot as updateFloor,ut as updateOpening,Te as useClipboard,S as useCoarsePointer,n as useComponentDefaults,or as useFormValidator,rr as useFormValidatorGroup,ve as useHotkeys,r as useLabels,x as useMediaQuery,H as useOverlay,i as usePresentationDefault,ge as useScrollEdges,C as useSwipeDismiss,Rn as useTheme,Vn as useTiltGroup,V as useVisualViewportSize,dt as validatePlan,Lt as wallCentrelineSpans,ft as wallLength,pt as weldShortWalls,Ht as worldTolerances};
|
|
1
|
+
"use client";import{AccordionStyleType as e}from"./common/accordion/accordion.types.mjs";import t from"./common/configProvider/configProvider.mjs";import{useComponentDefaults as n}from"./common/configProvider/useComponentDefaults.mjs";import{useLabels as r}from"./common/configProvider/useLabels.mjs";import{usePresentationDefault as i}from"./common/configProvider/usePresentationDefault.mjs";import{Presentation as a}from"./common/configProvider/presentation.types.mjs";import{ThemeColor as o}from"./common/themeProvider/color.types.mjs";import s from"./common/accordion/accordion.mjs";import c from"./common/loading/spinnerLoading/index.mjs";import{ButtonSize as l,ButtonStyleType as u,ButtonType as d}from"./common/button/button.types.mjs";import f from"./common/ripple/ripple.mjs";import p from"./common/button/button.mjs";import m from"./common/actionButtons/actionButtons.mjs";import h from"./common/actionIcon/actionIcon.mjs";import g from"./common/scrollbarProvider/index.mjs";import{defaultTheme as _}from"./common/themeProvider/defaultTheme.mjs";import v from"./common/themeProvider/themeProvider.mjs";import{lightTheme as y}from"./common/themeProvider/lightTheme.mjs";import b from"./common/bodyEnd/bodyEnd.mjs";import x from"./common/hooks/useMediaQuery.mjs";import S from"./common/hooks/useCoarsePointer.mjs";import{useSwipeDismiss as C}from"./common/hooks/useSwipeDismiss.mjs";import{showToast as w}from"./common/toast/toastService.mjs";import T from"./common/ahroweProvider/ahroweProvider.mjs";import E from"./common/alert/alert.mjs";import D from"./common/animatedLogo/animatedLogo.mjs";import{AnimatedTextUnit as O,AnimatedTextVariant as k}from"./common/animatedText/animatedText.types.mjs";import A from"./common/animatedText/animatedText.mjs";import{BadgePosition as j,BadgeStyleType as M}from"./common/badge/badge.types.mjs";import N from"./common/badge/badge.mjs";import P from"./common/avatar/avatar.mjs";import F from"./common/avatar/avatarGroup.mjs";import I from"./common/interactableDiv/index.mjs";import{PopoverAlign as L,PopoverPlacement as R,PopoverTrigger as z}from"./common/popover/popover.types.mjs";import{tabbablesIn as B}from"./common/hooks/useFocusBoundary.mjs";import{useVisualViewportSize as V}from"./common/hooks/useVisualViewportSize.mjs";import{useOverlay as H}from"./common/hooks/useOverlay.mjs";import U from"./common/popover/popover.mjs";import W from"./common/breadcrumb/breadcrumb.mjs";import{ButtonGroupOrientation as G}from"./common/buttonGroup/buttonGroup.types.mjs";import K from"./common/buttonGroup/buttonGroup.mjs";import{dateToDay as q,dateToTime as J,dayTimeToDate as Y,dayToDate as X}from"./common/utils/day.mjs";import{CalendarView as Z}from"./common/calendar/calendar.types.mjs";import Q from"./common/emptyState/emptyState.mjs";import $ from"./common/optionPicker/optionPicker.mjs";import ee from"./common/calendar/calendar.mjs";import{CardStyleType as te}from"./common/card/card.types.mjs";import ne from"./common/card/Card.mjs";import re from"./common/card/CardHeader.mjs";import ie from"./common/card/CardMedia.mjs";import ae from"./common/card/CardContent.mjs";import oe from"./common/card/CardActions.mjs";import se from"./common/carousel/carousel.mjs";import ce from"./common/checkbox/checkbox.mjs";import{ChipStyleType as le}from"./common/chip/chip.types.mjs";import ue from"./common/chip/chip.mjs";import de from"./common/chip/chipContainer.mjs";import fe from"./common/tooltip/tooltip.mjs";import{InputIconPosition as pe,InputType as me}from"./common/input/input.types.mjs";import he from"./common/input/input.mjs";import ge from"./common/colorPicker/colorPicker.mjs";import{useScrollEdges as _e}from"./common/hooks/useScrollEdges.mjs";import ve from"./common/modal/modal.mjs";import ye,{formatHotkey as be}from"./common/hooks/useHotkeys.mjs";import{isMenuAction as xe,isMenuHeading as Se,isMenuSeparator as Ce}from"./common/menu/menu.types.mjs";import we from"./common/commandPalette/commandPalette.mjs";import Te from"./common/confirmModal/confirmModal.mjs";import Ee from"./common/hooks/useClipboard.mjs";import De from"./common/copyButton/copyButton.mjs";import{getLocale as Oe,mapLocale as ke,setLocale as Ae}from"./services/localization.mjs";import je from"./common/dropdown/dropdown.mjs";import Me from"./common/datePicker/datePicker.mjs";import{DividerOrientation as Ne,DividerTextPosition as Pe}from"./common/divider/divider.types.mjs";import Fe from"./common/divider/divider.mjs";import Ie from"./common/drawer/drawer.mjs";import{DropZoneReturnType as Le,DropZoneStatus as Re}from"./common/dropZone/dropZone.types.mjs";import ze from"./common/dropZone/dropZone.mjs";import Be from"./common/errorBoundary/errorBoundary.mjs";import Ve from"./common/fab/fab.mjs";import He from"./common/flip/flip.mjs";import{DoorSwing as Ue,OpeningKind as We,PlanIssueKind as Ge,PlanUnitSystem as Ke,WallType as qe}from"./common/floorPlan/floorPlan.types.mjs";import{MIN_OPENING_WIDTH as Je,MIN_WALL_LENGTH as Ye}from"./common/floorPlan/floorPlan.geometry.mjs";import{DEFAULT_WALL_ATTRS as Xe,addOpening as Ze,addRect as Qe,addWall as $e,cleanupPlan as et,detachWall as tt,dissolveNode as nt,mergeNodes as rt,moveNode as it,removeOpening as at,removeWall as ot,scalePlan as st,splitWall as ct,transformPlan as lt,updateOpening as ut,validatePlan as dt,wallLength as ft,weldShortWalls as pt}from"./common/floorPlan/floorPlan.graph.mjs";import{MIN_FLOOR_HEIGHT as mt,addFloor as ht,duplicateFloor as gt,emptyFloor as _t,emptyFloorPlan as vt,floorBelow as yt,floorBounds as bt,floorIndex as xt,getFloor as St,moveFloor as Ct,removeFloor as wt,renameFloor as Tt,setFloor as Et,setFloorHeight as Dt,updateFloor as Ot}from"./common/floorPlan/floorPlan.plan.mjs";import{deriveFaces as kt,nodeDegrees as At}from"./common/floorPlan/floorPlan.faces.mjs";import{commitDerivation as jt,derivePlan as Mt,pruneUnmatchedRooms as Nt,roomAtPoint as Pt}from"./common/floorPlan/floorPlan.rooms.mjs";import{buildWallPaths as Ft,openingGeometry as It,wallCentrelineSpans as Lt}from"./common/floorPlan/floorPlan.path.mjs";import{HIT_PX as Rt,HIT_PX_COARSE as zt,hitTest as Bt,selectionsEqual as Vt,worldTolerances as Ht}from"./common/floorPlan/floorPlan.hit.mjs";import{DEFAULT_SNAP_OPTIONS as Ut,SnapKind as Wt,clientToWorld as Gt,resolveSnap as Kt}from"./common/floorPlan/floorPlan.snap.mjs";import{PLAN_FORMAT_VERSION as qt,planFromJson as Jt,planToJson as Yt}from"./common/floorPlan/floorPlan.json.mjs";import{buildPlanMesh as Xt}from"./common/floorPlan/floorPlan.mesh.mjs";import Zt from"./common/iconPicker/iconPicker.mjs";import Qt from"./common/idleManager/idleManager.mjs";import $t from"./common/inputDropdown/inputDropdown.mjs";import en from"./common/kanbanBoard/KanbanColumn.mjs";import tn from"./common/kanbanBoard/KanbanBoard.mjs";import nn from"./common/searchInput/searchInput.mjs";import rn from"./common/klipyPicker/klipyPicker.mjs";import an from"./common/menu/menu.mjs";import{menuHotkeys as on}from"./common/menu/menuHotkeys.mjs";import sn from"./common/multiSelect/multiSelect.mjs";import cn from"./common/numberInput/index.mjs";import{OtpInputCharset as ln}from"./common/otpInput/otpInput.types.mjs";import un from"./common/otpInput/otpInput.mjs";import dn from"./common/overscroll/overscroll.mjs";import fn from"./common/pagination/pagination.mjs";import pn from"./common/progressBar/progressBar.mjs";import{RadioGroupOrientation as mn}from"./common/radioGroup/radioGroup.types.mjs";import hn from"./common/radioGroup/radioGroup.mjs";import gn from"./common/rating/rating.mjs";import _n from"./common/revealLens/revealLens.mjs";import vn from"./common/roomDrawer/roomDrawer.mjs";import yn from"./common/roomViewer/roomViewer.mjs";import{ScrollFadeAxis as bn}from"./common/scrollFade/scrollFade.types.mjs";import xn from"./common/scrollFade/scrollFade.mjs";import{SectionHeaderSize as Sn}from"./common/sectionHeader/sectionHeader.types.mjs";import Cn from"./common/sectionHeader/sectionHeader.mjs";import{SkeletonAnimation as wn,SkeletonVariant as Tn}from"./common/skeleton/skeleton.types.mjs";import En from"./common/skeleton/skeleton.mjs";import Dn from"./common/slider/slider.mjs";import On from"./common/splitButton/splitButton.mjs";import{StepperAlignment as kn,StepperCollapse as An,StepperLabelPlacement as jn,StepperStyleType as Mn}from"./common/stepper/stepper.types.mjs";import Nn from"./common/stepper/stepper.mjs";import Pn from"./common/sticky/sticky.mjs";import Fn from"./common/switch/switch.mjs";import In from"./common/tabHeader/tabHeader.mjs";import Ln from"./common/textarea/textarea.mjs";import{useTheme as Rn}from"./common/themeProvider/useTheme.mjs";import zn,{TiltGroupContext as Bn,useTiltGroup as Vn}from"./common/tiltGroup/tiltGroup.mjs";import{defaultTiltEasing as Hn}from"./common/tilt/tiltMath.mjs";import Un from"./common/tilt/tilt.mjs";import Wn from"./common/timeInput/timeInput.mjs";import{TimelineAlignment as Gn}from"./common/timeline/timeline.types.mjs";import Kn from"./common/timeline/timeline.mjs";import qn from"./common/timer/timer.mjs";import Jn from"./common/virtualList/virtualList.mjs";import{flattenTree as Yn}from"./common/tree/flattenTree.mjs";import Xn from"./common/tree/tree.mjs";import{WeatherType as Zn}from"./common/weatherIcon/weatherIcon.types.mjs";import Qn from"./common/weatherIcon/weatherIcon.mjs";import $n from"./common/wizard/wizard.mjs";import er from"./services/formValidation/FormValidatorGroupWithForm.mjs";import tr from"./services/formValidation/validatableComponent.mjs";import{useFormValidatorGroup as nr}from"./services/formValidation/useFormValidatorGroup.mjs";import{FormValidator as rr,Validators as ir,useFormValidator as ar}from"./services/formValidation/index.mjs";import{hasEightPasswordChars as or,hasOnePasswordDigit as sr,hasOnePasswordLetter as cr,isBic as lr,isDate as ur,isDay as dr,isEmail as fr,isISODate as pr,isNumber as mr,isPassword as hr,isURL as gr}from"@ahrowe/form-validation";export{s as Accordion,e as AccordionStyleType,m as ActionButtons,h as ActionIcon,T as AhroweProvider,E as Alert,D as AnimatedLogo,A as AnimatedText,O as AnimatedTextUnit,k as AnimatedTextVariant,P as Avatar,F as AvatarGroup,N as Badge,j as BadgePosition,M as BadgeStyleType,b as BodyEnd,W as Breadcrumb,p as Button,K as ButtonGroup,G as ButtonGroupOrientation,l as ButtonSize,u as ButtonStyleType,d as ButtonType,ee as Calendar,Z as CalendarView,ne as Card,oe as CardActions,ae as CardContent,re as CardHeader,ie as CardMedia,te as CardStyleType,se as Carousel,ce as Checkbox,ue as Chip,de as ChipContainer,le as ChipStyleType,ge as ColorPicker,we as CommandPalette,t as ConfigProvider,Te as ConfirmModal,De as CopyButton,Ut as DEFAULT_SNAP_OPTIONS,Xe as DEFAULT_WALL_ATTRS,Me as DatePicker,Fe as Divider,Ne as DividerOrientation,Pe as DividerTextPosition,Ue as DoorSwing,Ie as Drawer,ze as DropZone,Le as DropZoneReturnType,Re as DropZoneStatus,je as Dropdown,Q as EmptyState,Be as ErrorBoundary,Ve as Fab,He as Flip,rr as FormValidator,er as FormValidatorGroup,Rt as HIT_PX,zt as HIT_PX_COARSE,Zt as IconPicker,Qt as IdleManager,he as Input,$t as InputDropdown,pe as InputIconPosition,me as InputType,I as InteractableDiv,tn as KanbanBoard,en as KanbanColumn,rn as KlipyPicker,mt as MIN_FLOOR_HEIGHT,Je as MIN_OPENING_WIDTH,Ye as MIN_WALL_LENGTH,an as Menu,ve as Modal,sn as MultiSelect,cn as NumberInput,We as OpeningKind,$ as OptionPicker,un as OtpInput,ln as OtpInputCharset,dn as Overscroll,qt as PLAN_FORMAT_VERSION,fn as Pagination,Ge as PlanIssueKind,Ke as PlanUnitSystem,U as Popover,L as PopoverAlign,R as PopoverPlacement,z as PopoverTrigger,a as Presentation,pn as ProgressBar,hn as RadioGroup,mn as RadioGroupOrientation,gn as Rating,_n as RevealLens,f as Ripple,vn as RoomDrawer,yn as RoomViewer,xn as ScrollFade,bn as ScrollFadeAxis,g as ScrollbarProvider,nn as SearchInput,Cn as SectionHeader,Sn as SectionHeaderSize,En as Skeleton,wn as SkeletonAnimation,Tn as SkeletonVariant,Dn as Slider,Wt as SnapKind,c as SpinnerLoading,On as SplitButton,Nn as Stepper,kn as StepperAlignment,An as StepperCollapse,jn as StepperLabelPlacement,Mn as StepperStyleType,Pn as Sticky,Fn as Switch,In as TabHeader,Ln as Textarea,o as ThemeColor,v as ThemeProvider,Un as Tilt,zn as TiltGroup,Bn as TiltGroupContext,Wn as TimeInput,Kn as Timeline,Gn as TimelineAlignment,qn as Timer,fe as Tooltip,Xn as Tree,tr as ValidatableComponent,ir as Validators,Jn as VirtualList,qe as WallType,Qn as WeatherIcon,Zn as WeatherType,$n as Wizard,ht as addFloor,Ze as addOpening,Qe as addRect,$e as addWall,Xt as buildPlanMesh,Ft as buildWallPaths,et as cleanupPlan,Gt as clientToWorld,jt as commitDerivation,q as dateToDay,J as dateToTime,Y as dayTimeToDate,X as dayToDate,_ as defaultTheme,Hn as defaultTiltEasing,kt as deriveFaces,Mt as derivePlan,tt as detachWall,nt as dissolveNode,gt as duplicateFloor,_t as emptyFloor,vt as emptyFloorPlan,Yn as flattenTree,yt as floorBelow,bt as floorBounds,xt as floorIndex,be as formatHotkey,St as getFloor,Oe as getLocale,or as hasEightPasswordChars,sr as hasOnePasswordDigit,cr as hasOnePasswordLetter,Bt as hitTest,lr as isBic,ur as isDate,dr as isDay,fr as isEmail,pr as isISODate,xe as isMenuAction,Se as isMenuHeading,Ce as isMenuSeparator,mr as isNumber,hr as isPassword,gr as isURL,y as lightTheme,ke as mapLocale,on as menuHotkeys,rt as mergeNodes,Ct as moveFloor,it as moveNode,At as nodeDegrees,It as openingGeometry,Jt as planFromJson,Yt as planToJson,Nt as pruneUnmatchedRooms,wt as removeFloor,at as removeOpening,ot as removeWall,Tt as renameFloor,Kt as resolveSnap,Pt as roomAtPoint,st as scalePlan,Vt as selectionsEqual,Et as setFloor,Dt as setFloorHeight,Ae as setLocale,w as showToast,ct as splitWall,B as tabbablesIn,lt as transformPlan,Ot as updateFloor,ut as updateOpening,Ee as useClipboard,S as useCoarsePointer,n as useComponentDefaults,ar as useFormValidator,nr as useFormValidatorGroup,ye as useHotkeys,r as useLabels,x as useMediaQuery,H as useOverlay,i as usePresentationDefault,_e as useScrollEdges,C as useSwipeDismiss,Rn as useTheme,Vn as useTiltGroup,V as useVisualViewportSize,dt as validatePlan,Lt as wallCentrelineSpans,ft as wallLength,pt as weldShortWalls,Ht as worldTolerances};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{
|
|
1
|
+
"use client";import{ThemeColor as e}from"../../common/themeProvider/color.types.mjs";import{showToast as t}from"../../common/toast/toastService.mjs";import{FormValidatorGroup as n,createFormComponent as r}from"@ahrowe/form-validation";var i=n=>{t(n[0].message,{color:e.Error})},a=class extends n{constructor(e,t=null,n){super(e,t,{...n,onSubmitError:n?.onSubmitError??i}),this.Form=r(this)}};export{a as default};
|
|
2
2
|
//# sourceMappingURL=FormValidatorGroupWithForm.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormValidatorGroupWithForm.mjs","names":[],"sources":["../../../../package/services/formValidation/FormValidatorGroupWithForm.tsx"],"sourcesContent":["import { showToast } from 'components/common/toast';\nimport { FormValidatorGroup, createFormComponent } from '@ahrowe/form-validation';\nimport type { FormGroup, FormValidatorGroupOptions, InferGroupValues, ValidationError } from '@ahrowe/form-validation';\nimport type React from 'react';\n\n/** Default onSubmitError: surface the first error as an error toast. Callers can override via options.onSubmitError. */\nconst defaultOnSubmitError = (errors: ValidationError[]): void => {\n showToast(errors[0].message, {
|
|
1
|
+
{"version":3,"file":"FormValidatorGroupWithForm.mjs","names":[],"sources":["../../../../package/services/formValidation/FormValidatorGroupWithForm.tsx"],"sourcesContent":["import { showToast } from 'components/common/toast';\nimport { FormValidatorGroup, createFormComponent } from '@ahrowe/form-validation';\nimport type { FormGroup, FormValidatorGroupOptions, InferGroupValues, ValidationError } from '@ahrowe/form-validation';\nimport type React from 'react';\nimport { ThemeColor } from '../../common/themeProvider/color.types';\n\n/** Default onSubmitError: surface the first error as an error toast. Callers can override via options.onSubmitError. */\nconst defaultOnSubmitError = (errors: ValidationError[]): void => {\n showToast(errors[0].message, { color: ThemeColor.Error });\n};\n\n/**\n * FormValidatorGroup with `this.Form` automatically attached.\n * Kept in a .tsx file so formValidatorGroup.ts stays framework-agnostic.\n *\n * This is the class you should use everywhere — it is a drop-in replacement\n * for FormValidatorGroup with one extra property: `this.Form`.\n *\n * Also injects the default toast-based onSubmitError so both hook and class-component\n * consumers surface errors out of the box; pass options.onSubmitError to override.\n */\nexport default class FormValidatorGroupWithForm<\n TGroup extends FormGroup = FormGroup,\n TInitial = InferGroupValues<TGroup>,\n> extends FormValidatorGroup<TGroup, TInitial> {\n Form: React.FC<React.FormHTMLAttributes<HTMLFormElement>>;\n\n constructor(\n groupDef: TGroup,\n component: { forceUpdate: () => void } | null = null,\n options?: FormValidatorGroupOptions<TGroup, TInitial>,\n ) {\n super(groupDef, component, { ...options, onSubmitError: options?.onSubmitError ?? defaultOnSubmitError });\n this.Form = createFormComponent(this);\n }\n}\n"],"mappings":"2OAOA,IAAM,EAAwB,GAAoC,CAChE,EAAU,EAAO,EAAE,CAAC,QAAS,CAAE,MAAO,EAAW,KAAM,CAAC,CAC1D,EAYqB,EAArB,cAGU,CAAqC,CAG7C,YACE,EACA,EAAgD,KAChD,EACA,CACA,MAAM,EAAU,EAAW,CAAE,GAAG,EAAS,cAAe,GAAS,eAAiB,CAAqB,CAAC,EACxG,KAAK,KAAO,EAAoB,IAAI,CACtC,CACF"}
|