@ahrowe/ui 0.29.1 → 0.31.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/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.map +1 -1
- package/dist/esm/common/accordion/accordion.plain.module.mjs.map +1 -1
- package/dist/esm/common/accordion/accordion.primary.module.mjs.map +1 -1
- package/dist/esm/common/alert/alert.module.mjs.map +1 -1
- package/dist/esm/common/badge/badge.module.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/button/button.module.mjs +1 -1
- package/dist/esm/common/button/button.module.mjs.map +1 -1
- package/dist/esm/common/card/card.module.mjs.map +1 -1
- package/dist/esm/common/checkbox/checkbox.mjs +1 -1
- package/dist/esm/common/checkbox/checkbox.mjs.map +1 -1
- package/dist/esm/common/checkbox/checkbox.module.mjs +1 -1
- package/dist/esm/common/checkbox/checkbox.module.mjs.map +1 -1
- package/dist/esm/common/chip/chip.module.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/colorPicker/toHex.mjs +2 -0
- package/dist/esm/common/colorPicker/toHex.mjs.map +1 -0
- package/dist/esm/common/datePicker/datePicker.mjs +1 -1
- package/dist/esm/common/datePicker/datePicker.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/components/fabBase/fabBase.module.mjs.map +1 -1
- package/dist/esm/common/fab/fab.module.mjs.map +1 -1
- package/dist/esm/common/iconPicker/iconPicker.module.mjs.map +1 -1
- package/dist/esm/common/input/input.mjs +1 -1
- package/dist/esm/common/input/input.mjs.map +1 -1
- package/dist/esm/common/input/input.module.mjs +1 -1
- package/dist/esm/common/input/input.module.mjs.map +1 -1
- package/dist/esm/common/inputDropdown/inputDropdown.mjs +1 -1
- package/dist/esm/common/inputDropdown/inputDropdown.mjs.map +1 -1
- package/dist/esm/common/kanbanBoard/kanbanBoard.module.mjs.map +1 -1
- package/dist/esm/common/optionPicker/optionPicker.module.mjs.map +1 -1
- package/dist/esm/common/otpInput/otpInput.module.mjs.map +1 -1
- package/dist/esm/common/pagination/pagination.module.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/radioGroup/radioGroup.mjs +1 -1
- package/dist/esm/common/radioGroup/radioGroup.mjs.map +1 -1
- package/dist/esm/common/radioGroup/radioGroup.module.mjs.map +1 -1
- package/dist/esm/common/rating/rating.module.mjs.map +1 -1
- package/dist/esm/common/searchInput/searchInput.mjs +1 -1
- package/dist/esm/common/searchInput/searchInput.mjs.map +1 -1
- package/dist/esm/common/slider/slider.mjs +1 -1
- package/dist/esm/common/slider/slider.mjs.map +1 -1
- package/dist/esm/common/slider/slider.module.mjs.map +1 -1
- package/dist/esm/common/switch/switch.module.mjs.map +1 -1
- package/dist/esm/common/tabHeader/tabHeader.module.mjs.map +1 -1
- package/dist/esm/common/themeProvider/theme.module.mjs.map +1 -1
- package/dist/esm/common/themeProvider/themeProvider.mjs +1 -1
- package/dist/esm/common/themeProvider/themeProvider.mjs.map +1 -1
- package/dist/esm/common/themeProvider/themeVariablesContext.mjs +2 -0
- package/dist/esm/common/themeProvider/themeVariablesContext.mjs.map +1 -0
- 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/timer/timer.mjs +1 -1
- package/dist/esm/common/timer/timer.mjs.map +1 -1
- package/dist/esm/common/timer/timer.module.mjs.map +1 -1
- package/dist/esm/common/toast/toast.module.mjs.map +1 -1
- package/dist/esm/common/tooltip/tooltip.module.mjs.map +1 -1
- package/dist/esm/common/tree/tree.mjs +1 -1
- package/dist/esm/common/tree/tree.mjs.map +1 -1
- package/dist/esm/common/virtualList/useColumnResize.mjs +2 -0
- package/dist/esm/common/virtualList/useColumnResize.mjs.map +1 -0
- package/dist/esm/common/virtualList/useColumns.mjs +1 -1
- package/dist/esm/common/virtualList/useColumns.mjs.map +1 -1
- package/dist/esm/common/virtualList/useHeaderNavigation.mjs +2 -0
- package/dist/esm/common/virtualList/useHeaderNavigation.mjs.map +1 -0
- package/dist/esm/common/virtualList/useRowNavigation.mjs +2 -0
- package/dist/esm/common/virtualList/useRowNavigation.mjs.map +1 -0
- package/dist/esm/common/virtualList/useSorting.mjs +2 -0
- package/dist/esm/common/virtualList/useSorting.mjs.map +1 -0
- package/dist/esm/common/virtualList/useVirtualWindow.mjs +1 -1
- package/dist/esm/common/virtualList/useVirtualWindow.mjs.map +1 -1
- package/dist/esm/common/virtualList/virtualList.mjs +1 -1
- package/dist/esm/common/virtualList/virtualList.mjs.map +1 -1
- package/dist/esm/common/virtualList/virtualList.module.mjs +1 -1
- package/dist/esm/common/virtualList/virtualList.module.mjs.map +1 -1
- package/dist/esm/common/virtualList/virtualList.utils.mjs +1 -1
- package/dist/esm/common/virtualList/virtualList.utils.mjs.map +1 -1
- package/dist/esm/common/virtualList/virtualListHeader.mjs +2 -0
- package/dist/esm/common/virtualList/virtualListHeader.mjs.map +1 -0
- package/dist/esm/common/virtualList/virtualRow.mjs +1 -1
- package/dist/esm/common/virtualList/virtualRow.mjs.map +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.cjs.map +1 -1
- package/dist/style.css +1 -1
- package/dist/types/common/colorPicker/toHex.d.ts +11 -0
- package/dist/types/common/themeProvider/theme.types.d.ts +75 -3
- package/dist/types/common/themeProvider/themeVariablesContext.d.ts +11 -0
- package/dist/types/common/virtualList/useColumnResize.d.ts +59 -0
- package/dist/types/common/virtualList/useColumns.d.ts +12 -2
- package/dist/types/common/virtualList/useHeaderNavigation.d.ts +22 -0
- package/dist/types/common/virtualList/useRowNavigation.d.ts +50 -0
- package/dist/types/common/virtualList/useSorting.d.ts +26 -0
- package/dist/types/common/virtualList/useVirtualWindow.d.ts +1 -8
- package/dist/types/common/virtualList/virtualList.d.ts +1 -1
- package/dist/types/common/virtualList/virtualList.types.d.ts +82 -1
- package/dist/types/common/virtualList/virtualList.utils.d.ts +83 -1
- package/dist/types/common/virtualList/virtualListHeader.d.ts +35 -0
- package/dist/types/common/virtualList/virtualRow.d.ts +14 -1
- package/docs/Accordion.md +4 -0
- package/docs/Alert.md +4 -0
- package/docs/BodyEnd.md +3 -0
- package/docs/Button.md +6 -0
- package/docs/Card.md +6 -0
- package/docs/Checkbox.md +8 -0
- package/docs/ColorPicker.md +11 -1
- package/docs/Fab.md +16 -0
- package/docs/IconPicker.md +8 -0
- package/docs/Input.md +12 -0
- package/docs/OtpInput.md +4 -0
- package/docs/RadioGroup.md +6 -0
- package/docs/Rating.md +5 -0
- package/docs/Slider.md +6 -2
- package/docs/ThemeProvider.md +89 -1
- package/docs/Timer.md +7 -1
- package/docs/Toast.md +6 -0
- package/docs/Tooltip.md +15 -0
- package/docs/VirtualList.md +125 -7
- package/package.json +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"searchInput.mjs","names":[],"sources":["../../../../package/common/searchInput/searchInput.tsx"],"sourcesContent":["import { useEffect, useRef, type ReactElement } from 'react';\nimport Input from 'components/common/input';\nimport { InputType } from 'components/common/input/input.types';\nimport styles from './searchInput.module.pcss';\nimport type { SearchInputProps } from './searchInput.types';\n\nexport default function SearchInput({\n value,\n onChange,\n onDebounce,\n placeholder,\n label,\n debounceMs = 500,\n totalAmount,\n showAmount = true,\n className,\n width,\n ...rest\n}: SearchInputProps): ReactElement {\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(\n () => () => {\n if (timerRef.current !== null) clearTimeout(timerRef.current);\n },\n [],\n );\n\n function handleChange(val: unknown) {\n const str = val != null ? String(val) : '';\n const trimmed = str.trim() === '' ? '' : str;\n onChange(trimmed);\n if (timerRef.current !== null) clearTimeout(timerRef.current);\n timerRef.current = setTimeout(() => {\n onDebounce?.(trimmed);\n }, debounceMs);\n }\n\n const showCount = showAmount && typeof totalAmount === 'number' && !Number.isNaN(totalAmount);\n\n return (\n <div {...rest} className={className} style={width != null ? { width } : undefined}>\n <Input
|
|
1
|
+
{"version":3,"file":"searchInput.mjs","names":[],"sources":["../../../../package/common/searchInput/searchInput.tsx"],"sourcesContent":["import { useEffect, useRef, type ReactElement } from 'react';\nimport Input from 'components/common/input';\nimport { InputType } from 'components/common/input/input.types';\nimport styles from './searchInput.module.pcss';\nimport type { SearchInputProps } from './searchInput.types';\n\nexport default function SearchInput({\n value,\n onChange,\n onDebounce,\n placeholder,\n label,\n debounceMs = 500,\n totalAmount,\n showAmount = true,\n className,\n width,\n ...rest\n}: SearchInputProps): ReactElement {\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(\n () => () => {\n if (timerRef.current !== null) clearTimeout(timerRef.current);\n },\n [],\n );\n\n function handleChange(val: unknown) {\n const str = val != null ? String(val) : '';\n const trimmed = str.trim() === '' ? '' : str;\n onChange(trimmed);\n if (timerRef.current !== null) clearTimeout(timerRef.current);\n timerRef.current = setTimeout(() => {\n onDebounce?.(trimmed);\n }, debounceMs);\n }\n\n const showCount = showAmount && typeof totalAmount === 'number' && !Number.isNaN(totalAmount);\n\n return (\n <div {...rest} className={className} style={width != null ? { width } : undefined}>\n <Input\n autoComplete='off'\n type={InputType.Search}\n label={label}\n placeholder={placeholder}\n value={value}\n onChange={handleChange}\n />\n {showCount && (\n <p className={styles.resultCount}>\n {totalAmount} {totalAmount === 1 ? 'result' : 'results'}\n </p>\n )}\n </div>\n );\n}\n"],"mappings":"+NAMA,SAAwB,EAAY,CAClC,QACA,WACA,aACA,cACA,QACA,aAAa,IACb,cACA,aAAa,GACb,YACA,QACA,GAAG,GAC8B,CACjC,IAAM,EAAW,EAA6C,IAAI,EAElE,UACc,CACN,EAAS,UAAY,MAAM,aAAa,EAAS,OAAO,CAC9D,EACA,CAAC,CACH,EAEA,SAAS,EAAa,EAAc,CAClC,IAAM,EAAM,GAAO,KAAqB,GAAd,OAAO,CAAG,EAC9B,EAAU,EAAI,KAAK,IAAM,GAAK,GAAK,EACzC,EAAS,CAAO,EACZ,EAAS,UAAY,MAAM,aAAa,EAAS,OAAO,EAC5D,EAAS,QAAU,eAAiB,CAClC,IAAa,CAAO,CACtB,EAAG,CAAU,CACf,CAEA,IAAM,EAAY,GAAc,OAAO,GAAgB,UAAY,CAAC,OAAO,MAAM,CAAW,EAE5F,OACE,EAAC,MAAD,CAAK,GAAI,EAAiB,YAAW,MAAO,GAAS,KAAmB,IAAA,GAAZ,CAAE,OAAM,EAApE,SAAA,CACE,EAAC,EAAD,CACE,aAAa,MACb,KAAM,EAAU,OACT,QACM,cACN,QACP,SAAU,CACX,CAAA,EACA,GACC,EAAC,IAAD,CAAG,UAAW,EAAO,YAArB,SAAA,CACG,EAAY,IAAE,IAAgB,EAAI,SAAW,SAC7C,CAEF,CAAA,CAAA,GAET"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import e from"./slider.module.mjs";import t,{useEffect as n,useRef as r,useState as i}from"react";import a from"classnames";import{jsx as o,jsxs as s}from"react/jsx-runtime";function c(e){let t=String(e),n=t.indexOf(`.`);return n===-1?0:t.length-n-1}function l(l){let{min:u=0,max:d=100,step:f=1,disabled:p=!1,marks:m,showValue:
|
|
1
|
+
import e from"./slider.module.mjs";import t,{useEffect as n,useRef as r,useState as i}from"react";import a from"classnames";import{jsx as o,jsxs as s}from"react/jsx-runtime";function c(e){let t=String(e),n=t.indexOf(`.`);return n===-1?0:t.length-n-1}function l(l){let{min:u=0,max:d=100,step:f=1,disabled:p=!1,marks:m,showValue:ee=!1,formatValue:h,size:g,tabIndex:_=0,className:v,style:y,classNames:b,styles:x,"aria-label":S,range:C,value:w,defaultValue:T,onChange:te,onChangeEnd:ne,minRange:E=0,thumbLabels:re,...ie}=l,D=te,O=ne,k=C===!0,A=r(null),j=r(null),M=r([]),N=r(null),[ae,P]=i(!1),F=c(f);function I(e){return Math.min(d,Math.max(u,e))}function oe(e){let t=Math.round((e-u)/f)*f+u;return Number(I(t).toFixed(F))}function L(e){if(k){let t=e??[u,d];return[I(t[0]),I(t[1])]}return[I(e??u)]}function R(e){let t=k?2:1;return e.length===t?e:k?[e[0],d]:[e[0]]}let z=w!==void 0,[B,V]=i(()=>L(T)),H=z?L(w):R(B),U=r(H);n(()=>{U.current=H},[H]);function W(e){return k?[e[0],e[1]]:e[0]}function G(e,t){return k?e===0?[u,t[1]-E]:[t[0]+E,d]:[u,d]}function K(e,t,n){let r=U.current,[i,a]=G(e,r),o=oe(t);if(o<i&&(o=Number(Math.max(u,i).toFixed(F))),o>a&&(o=Number(Math.min(d,a).toFixed(F))),o===r[e]){n&&O?.(W(r));return}let s=[...r];s[e]=o,U.current=s,z||V(s),D?.(W(s)),n&&O?.(W(s))}function q(e){let t=A.current;if(!t)return U.current[0];let n=t.getBoundingClientRect(),r=n.width?(e-n.left)/n.width:0;return u+Math.min(1,Math.max(0,r))*(d-u)}function se(e){if(!k)return 0;let[t,n]=U.current,r=Math.abs(e-t),i=Math.abs(e-n);return r===i?+(e>n):r<i?0:1}function ce(e){if(p)return;e.preventDefault();let t=q(e.clientX),n=se(t);(k?M.current[n]:j.current)?.focus(),j.current?.setPointerCapture?.(e.pointerId),N.current=n,P(!0),K(n,t,!1)}function le(e){let t=N.current;t!==null&&K(t,q(e.clientX),!1)}function ue(e){N.current!==null&&(N.current=null,P(!1),j.current?.releasePointerCapture?.(e.pointerId),O?.(W(U.current)))}function J(e,t){if(p)return;let n=f*10,r=H[t],i=null;switch(e.key){case`ArrowRight`:case`ArrowUp`:i=r+f;break;case`ArrowLeft`:case`ArrowDown`:i=r-f;break;case`PageUp`:i=r+n;break;case`PageDown`:i=r-n;break;case`Home`:i=u;break;case`End`:i=d;break;default:return}e.preventDefault(),K(t,i,!0)}let Y=e=>d>u?(I(e)-u)/(d-u):0,X=e=>`${Y(e)*100}%`,de=k?{left:X(H[0]),width:`${(Y(H[1])-Y(H[0]))*100}%`}:{width:X(H[0])},Z=!!m?.some(e=>e.label!=null),Q=e=>h?h(e):e;function $(e){let t=H[e],n=Q(t),[r,i]=G(e,H);return{role:`slider`,"aria-valuemin":Number(Math.max(u,r).toFixed(F)),"aria-valuemax":Number(Math.min(d,i).toFixed(F)),"aria-valuenow":t,"aria-valuetext":typeof n==`string`||typeof n==`number`?String(n):void 0,"aria-orientation":`horizontal`,"aria-disabled":p||void 0}}let fe=k?{role:`group`,"aria-label":S,"aria-disabled":p||void 0}:{...$(0),"aria-label":S,tabIndex:p?-1:_};return o(`div`,{...ie,...fe,ref:j,className:a(e.slider,p&&e.sliderDisabled,ae&&e.sliderDragging,Z&&e.sliderHasMarkLabels,v,b?.root),style:{...g?{"--slider-thumb-size":g}:null,...y,...x?.root},onPointerDown:ce,onPointerMove:le,onPointerUp:ue,onKeyDown:k?void 0:e=>J(e,0),children:s(`div`,{ref:A,className:a(e.sliderTrack,b?.track),style:x?.track,children:[o(`div`,{className:a(e.sliderRange,b?.range),style:{...de,...x?.range}}),m?.map(n=>{let r=X(n.value);return s(t.Fragment,{children:[o(`span`,{className:a(e.sliderMark,b?.mark),style:{left:r,...x?.mark}}),n.label!=null&&o(`span`,{className:a(e.sliderMarkLabel,b?.markLabel),style:{left:r,...x?.markLabel},children:n.label})]},n.value)}),H.map((t,n)=>o(`div`,{ref:e=>{M.current[n]=e},className:a(e.sliderThumb,b?.thumb),style:{left:X(t),...x?.thumb},...k?{...$(n),"aria-label":re?.[n]??(n===0?`From`:`To`),tabIndex:p?-1:_,onKeyDown:e=>J(e,n)}:{},children:ee&&o(`span`,{className:a(e.sliderValue,b?.value),style:x?.value,children:Q(t)})},n))]})})}export{l as default};
|
|
2
2
|
//# sourceMappingURL=slider.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slider.mjs","names":[],"sources":["../../../../package/common/slider/slider.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState, type ReactElement } from 'react';\nimport cx from 'classnames';\nimport styles from './slider.module.pcss';\nimport type { RangeSliderProps, SingleSliderProps, SliderProps } from './slider.types';\n\n/**\n * Every prop of both variants, optional. Destructuring the union directly cannot reach the\n * range-only props, and leaving them in `...rest` spreads them onto the DOM node.\n */\ntype AnySliderProps = Omit<SingleSliderProps, 'onChange' | 'onChangeEnd' | 'value' | 'defaultValue' | 'range'> &\n Partial<Pick<RangeSliderProps, 'minRange' | 'thumbLabels'>> & {\n range?: boolean;\n value?: number | [number, number];\n defaultValue?: number | [number, number];\n onChange?: (value: never) => void;\n onChangeEnd?: (value: never) => void;\n };\n\n/** Count decimal places in a step so snapped values don't accumulate float error. */\nfunction decimalsOf(step: number): number {\n const s = String(step);\n const dot = s.indexOf('.');\n return dot === -1 ? 0 : s.length - dot - 1;\n}\n\nexport default function Slider(props: SliderProps): ReactElement {\n const {\n min = 0,\n max = 100,\n step = 1,\n disabled = false,\n marks,\n showValue = false,\n formatValue,\n size = '18px',\n tabIndex = 0,\n className,\n style,\n classNames,\n styles: slotStyles,\n 'aria-label': ariaLabel,\n range,\n value,\n defaultValue,\n onChange,\n onChangeEnd,\n minRange = 0,\n thumbLabels,\n ...rest\n } = props as AnySliderProps;\n\n // The union guarantees each handler matches `range`, but that link does not survive\n // destructuring, so the pair is widened once here rather than cast at every call.\n const emitChange = onChange as ((v: number | [number, number]) => void) | undefined;\n const emitEnd = onChangeEnd as ((v: number | [number, number]) => void) | undefined;\n\n const isRange = range === true;\n\n const trackRef = useRef<HTMLDivElement>(null);\n const rootRef = useRef<HTMLDivElement>(null);\n const thumbRefs = useRef<(HTMLDivElement | null)[]>([]);\n const draggingIndexRef = useRef<number | null>(null);\n const [dragging, setDragging] = useState(false);\n\n const decimals = decimalsOf(step);\n\n function clamp(v: number): number {\n return Math.min(max, Math.max(min, v));\n }\n\n function snap(v: number): number {\n const snapped = Math.round((v - min) / step) * step + min;\n return Number(clamp(snapped).toFixed(decimals));\n }\n\n /** Both modes run on an array internally; only the edges of the component know the difference. */\n function toValues(raw: number | [number, number] | undefined): number[] {\n if (isRange) {\n const pair = (raw as [number, number] | undefined) ?? [min, max];\n return [clamp(pair[0]), clamp(pair[1])];\n }\n return [clamp((raw as number | undefined) ?? min)];\n }\n\n /** Reshapes a stored pair or single if `range` is flipped after mount. */\n function fitToMode(values: number[]): number[] {\n const expected = isRange ? 2 : 1;\n if (values.length === expected) return values;\n return isRange ? [values[0], max] : [values[0]];\n }\n\n const isControlled = value !== undefined;\n const [internal, setInternal] = useState<number[]>(() => toValues(defaultValue));\n const current = isControlled ? toValues(value) : fitToMode(internal);\n\n // Latest committed values, for reading inside pointer handlers without stale closures. Synced\n // after render (never written during render) and optimistically in commit() so a drag burst\n // dedupes before the next render lands.\n const currentRef = useRef(current);\n useEffect(() => {\n currentRef.current = current;\n }, [current]);\n\n function payloadOf(next: number[]): number | [number, number] {\n return isRange ? [next[0], next[1]] : next[0];\n }\n\n /** How far this thumb may travel: the track, narrowed by its neighbour and `minRange`. */\n function boundsFor(index: number, values: number[]): [number, number] {\n if (!isRange) return [min, max];\n return index === 0 ? [min, values[1] - minRange] : [values[0] + minRange, max];\n }\n\n function commit(index: number, raw: number, ended: boolean) {\n const previous = currentRef.current;\n const [lower, upper] = boundsFor(index, previous);\n\n // Clamped after snapping, and rounded again: a bound derived from a neighbour plus `minRange`\n // is off the step grid and carries float error (0.3 - 0.1 is 0.19999999999999998).\n let snapped = snap(raw);\n if (snapped < lower) snapped = Number(Math.max(min, lower).toFixed(decimals));\n if (snapped > upper) snapped = Number(Math.min(max, upper).toFixed(decimals));\n\n // A keyboard step that lands on the same value still ends a gesture, but nothing changed,\n // so only onChangeEnd fires.\n if (snapped === previous[index]) {\n if (ended) emitEnd?.(payloadOf(previous));\n return;\n }\n\n const next = [...previous];\n next[index] = snapped;\n currentRef.current = next;\n if (!isControlled) setInternal(next);\n emitChange?.(payloadOf(next));\n if (ended) emitEnd?.(payloadOf(next));\n }\n\n function valueFromClientX(clientX: number): number {\n const track = trackRef.current;\n if (!track) return currentRef.current[0];\n const rect = track.getBoundingClientRect();\n const ratio = rect.width ? (clientX - rect.left) / rect.width : 0;\n return min + Math.min(1, Math.max(0, ratio)) * (max - min);\n }\n\n /**\n * The thumb closest to the press. On a tie the press direction decides, which is what keeps the\n * upper thumb reachable when the two sit on the same value and every distance ties.\n */\n function nearestThumb(target: number): number {\n if (!isRange) return 0;\n const [lo, hi] = currentRef.current;\n const toLo = Math.abs(target - lo);\n const toHi = Math.abs(target - hi);\n if (toLo === toHi) return target > hi ? 1 : 0;\n return toLo < toHi ? 0 : 1;\n }\n\n function handlePointerDown(e: React.PointerEvent<HTMLDivElement>) {\n if (disabled) return;\n e.preventDefault();\n const target = valueFromClientX(e.clientX);\n const index = nearestThumb(target);\n\n (isRange ? thumbRefs.current[index] : rootRef.current)?.focus();\n rootRef.current?.setPointerCapture?.(e.pointerId);\n draggingIndexRef.current = index;\n setDragging(true);\n commit(index, target, false);\n }\n\n function handlePointerMove(e: React.PointerEvent<HTMLDivElement>) {\n const index = draggingIndexRef.current;\n if (index === null) return;\n commit(index, valueFromClientX(e.clientX), false);\n }\n\n function handlePointerUp(e: React.PointerEvent<HTMLDivElement>) {\n if (draggingIndexRef.current === null) return;\n draggingIndexRef.current = null;\n setDragging(false);\n rootRef.current?.releasePointerCapture?.(e.pointerId);\n emitEnd?.(payloadOf(currentRef.current));\n }\n\n function handleKeyDown(e: React.KeyboardEvent<HTMLDivElement>, index: number) {\n if (disabled) return;\n const page = step * 10;\n const from = current[index];\n let next: number | null = null;\n\n switch (e.key) {\n case 'ArrowRight':\n case 'ArrowUp':\n next = from + step;\n break;\n case 'ArrowLeft':\n case 'ArrowDown':\n next = from - step;\n break;\n case 'PageUp':\n next = from + page;\n break;\n case 'PageDown':\n next = from - page;\n break;\n case 'Home':\n next = min;\n break;\n case 'End':\n next = max;\n break;\n default:\n return;\n }\n e.preventDefault();\n commit(index, next, true);\n }\n\n const fractionOf = (v: number) => (max > min ? (clamp(v) - min) / (max - min) : 0);\n const percentOf = (v: number) => `${fractionOf(v) * 100}%`;\n\n const rangeStyle = isRange\n ? { left: percentOf(current[0]), width: `${(fractionOf(current[1]) - fractionOf(current[0])) * 100}%` }\n : { width: percentOf(current[0]) };\n\n const hasMarkLabels = !!marks?.some((m) => m.label != null);\n const textOf = (v: number) => (formatValue ? formatValue(v) : v);\n\n function thumbAriaProps(index: number) {\n const v = current[index];\n const text = textOf(v);\n const [lower, upper] = boundsFor(index, current);\n return {\n role: 'slider' as const,\n 'aria-valuemin': Number(Math.max(min, lower).toFixed(decimals)),\n 'aria-valuemax': Number(Math.min(max, upper).toFixed(decimals)),\n 'aria-valuenow': v,\n 'aria-valuetext': typeof text === 'string' || typeof text === 'number' ? String(text) : undefined,\n 'aria-orientation': 'horizontal' as const,\n 'aria-disabled': disabled || undefined,\n };\n }\n\n // A single-thumb slider is the slider; a two-thumb one is a group of two, each its own slider.\n const rootAria = isRange\n ? { role: 'group' as const, 'aria-label': ariaLabel, 'aria-disabled': disabled || undefined }\n : { ...thumbAriaProps(0), 'aria-label': ariaLabel, tabIndex: disabled ? -1 : tabIndex };\n\n return (\n <div\n {...rest}\n {...rootAria}\n ref={rootRef}\n className={cx(\n styles.slider,\n disabled && styles.sliderDisabled,\n dragging && styles.sliderDragging,\n hasMarkLabels && styles.sliderHasMarkLabels,\n className,\n classNames?.root,\n )}\n style={{ '--slider-thumb-size': size, ...style, ...slotStyles?.root } as React.CSSProperties}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onKeyDown={isRange ? undefined : (e) => handleKeyDown(e, 0)}\n >\n <div ref={trackRef} className={cx(styles.sliderTrack, classNames?.track)} style={slotStyles?.track}>\n <div className={cx(styles.sliderRange, classNames?.range)} style={{ ...rangeStyle, ...slotStyles?.range }} />\n {marks?.map((mark) => {\n const left = percentOf(mark.value);\n return (\n <React.Fragment key={mark.value}>\n <span className={cx(styles.sliderMark, classNames?.mark)} style={{ left, ...slotStyles?.mark }} />\n {mark.label != null && (\n <span\n className={cx(styles.sliderMarkLabel, classNames?.markLabel)}\n style={{ left, ...slotStyles?.markLabel }}\n >\n {mark.label}\n </span>\n )}\n </React.Fragment>\n );\n })}\n {current.map((v, index) => (\n <div\n key={index}\n ref={(el) => {\n thumbRefs.current[index] = el;\n }}\n className={cx(styles.sliderThumb, classNames?.thumb)}\n style={{ left: percentOf(v), ...slotStyles?.thumb }}\n {...(isRange\n ? {\n ...thumbAriaProps(index),\n 'aria-label': thumbLabels?.[index] ?? (index === 0 ? 'From' : 'To'),\n tabIndex: disabled ? -1 : tabIndex,\n onKeyDown: (e: React.KeyboardEvent<HTMLDivElement>) => handleKeyDown(e, index),\n }\n : {})}\n >\n {showValue && (\n <span className={cx(styles.sliderValue, classNames?.value)} style={slotStyles?.value}>\n {textOf(v)}\n </span>\n )}\n </div>\n ))}\n </div>\n </div>\n );\n}\n"],"mappings":"8KAmBA,SAAS,EAAW,EAAsB,CACxC,IAAM,EAAI,OAAO,CAAI,EACf,EAAM,EAAE,QAAQ,GAAG,EACzB,OAAO,IAAQ,GAAK,EAAI,EAAE,OAAS,EAAM,CAC3C,CAEA,SAAwB,EAAO,EAAkC,CAC/D,GAAM,CACJ,MAAM,EACN,MAAM,IACN,OAAO,EACP,WAAW,GACX,QACA,YAAY,GACZ,cACA,OAAO,OACP,WAAW,EACX,aACA,SACA,aACA,OAAQ,EACR,aAAc,EACd,QACA,QACA,gBACA,YACA,eACA,WAAW,EACX,cACA,GAAG,GACD,EAIE,EAAa,GACb,EAAU,GAEV,EAAU,IAAU,GAEpB,EAAW,EAAuB,IAAI,EACtC,EAAU,EAAuB,IAAI,EACrC,EAAY,EAAkC,CAAC,CAAC,EAChD,EAAmB,EAAsB,IAAI,EAC7C,CAAC,GAAU,GAAe,EAAS,EAAK,EAExC,EAAW,EAAW,CAAI,EAEhC,SAAS,EAAM,EAAmB,CAChC,OAAO,KAAK,IAAI,EAAK,KAAK,IAAI,EAAK,CAAC,CAAC,CACvC,CAEA,SAAS,GAAK,EAAmB,CAC/B,IAAM,EAAU,KAAK,OAAO,EAAI,GAAO,CAAI,EAAI,EAAO,EACtD,OAAO,OAAO,EAAM,CAAO,CAAC,CAAC,QAAQ,CAAQ,CAAC,CAChD,CAGA,SAAS,EAAS,EAAsD,CACtE,GAAI,EAAS,CACX,IAAM,EAAQ,GAAwC,CAAC,EAAK,CAAG,EAC/D,MAAO,CAAC,EAAM,EAAK,EAAE,EAAG,EAAM,EAAK,EAAE,CAAC,CACxC,CACA,MAAO,CAAC,EAAO,GAA8B,CAAG,CAAC,CACnD,CAGA,SAAS,EAAU,EAA4B,CAC7C,IAAM,EAAW,EAAU,EAAI,EAE/B,OADI,EAAO,SAAW,EAAiB,EAChC,EAAU,CAAC,EAAO,GAAI,CAAG,EAAI,CAAC,EAAO,EAAE,CAChD,CAEA,IAAM,EAAe,IAAU,IAAA,GACzB,CAAC,EAAU,GAAe,MAAyB,EAAS,EAAY,CAAC,EACzE,EAAU,EAAe,EAAS,CAAK,EAAI,EAAU,CAAQ,EAK7D,EAAa,EAAO,CAAO,EACjC,MAAgB,CACd,EAAW,QAAU,CACvB,EAAG,CAAC,CAAO,CAAC,EAEZ,SAAS,EAAU,EAA2C,CAC5D,OAAO,EAAU,CAAC,EAAK,GAAI,EAAK,EAAE,EAAI,EAAK,EAC7C,CAGA,SAAS,EAAU,EAAe,EAAoC,CAEpE,OADK,EACE,IAAU,EAAI,CAAC,EAAK,EAAO,GAAK,CAAQ,EAAI,CAAC,EAAO,GAAK,EAAU,CAAG,EADxD,CAAC,EAAK,CAAG,CAEhC,CAEA,SAAS,EAAO,EAAe,EAAa,EAAgB,CAC1D,IAAM,EAAW,EAAW,QACtB,CAAC,EAAO,GAAS,EAAU,EAAO,CAAQ,EAI5C,EAAU,GAAK,CAAG,EAMtB,GALI,EAAU,IAAO,EAAU,OAAO,KAAK,IAAI,EAAK,CAAK,CAAC,CAAC,QAAQ,CAAQ,CAAC,GACxE,EAAU,IAAO,EAAU,OAAO,KAAK,IAAI,EAAK,CAAK,CAAC,CAAC,QAAQ,CAAQ,CAAC,GAIxE,IAAY,EAAS,GAAQ,CAC3B,GAAO,IAAU,EAAU,CAAQ,CAAC,EACxC,MACF,CAEA,IAAM,EAAO,CAAC,GAAG,CAAQ,EACzB,EAAK,GAAS,EACd,EAAW,QAAU,EAChB,GAAc,EAAY,CAAI,EACnC,IAAa,EAAU,CAAI,CAAC,EACxB,GAAO,IAAU,EAAU,CAAI,CAAC,CACtC,CAEA,SAAS,EAAiB,EAAyB,CACjD,IAAM,EAAQ,EAAS,QACvB,GAAI,CAAC,EAAO,OAAO,EAAW,QAAQ,GACtC,IAAM,EAAO,EAAM,sBAAsB,EACnC,EAAQ,EAAK,OAAS,EAAU,EAAK,MAAQ,EAAK,MAAQ,EAChE,OAAO,EAAM,KAAK,IAAI,EAAG,KAAK,IAAI,EAAG,CAAK,CAAC,GAAK,EAAM,EACxD,CAMA,SAAS,GAAa,EAAwB,CAC5C,GAAI,CAAC,EAAS,MAAO,GACrB,GAAM,CAAC,EAAI,GAAM,EAAW,QACtB,EAAO,KAAK,IAAI,EAAS,CAAE,EAC3B,EAAO,KAAK,IAAI,EAAS,CAAE,EAEjC,OADI,IAAS,EAAa,IAAS,GAC5B,EAAO,EAAO,EAAI,CAC3B,CAEA,SAAS,GAAkB,EAAuC,CAChE,GAAI,EAAU,OACd,EAAE,eAAe,EACjB,IAAM,EAAS,EAAiB,EAAE,OAAO,EACnC,EAAQ,GAAa,CAAM,GAEhC,EAAU,EAAU,QAAQ,GAAS,EAAQ,QAAA,EAAU,MAAM,EAC9D,EAAQ,SAAS,oBAAoB,EAAE,SAAS,EAChD,EAAiB,QAAU,EAC3B,EAAY,EAAI,EAChB,EAAO,EAAO,EAAQ,EAAK,CAC7B,CAEA,SAAS,GAAkB,EAAuC,CAChE,IAAM,EAAQ,EAAiB,QAC3B,IAAU,MACd,EAAO,EAAO,EAAiB,EAAE,OAAO,EAAG,EAAK,CAClD,CAEA,SAAS,GAAgB,EAAuC,CAC1D,EAAiB,UAAY,OACjC,EAAiB,QAAU,KAC3B,EAAY,EAAK,EACjB,EAAQ,SAAS,wBAAwB,EAAE,SAAS,EACpD,IAAU,EAAU,EAAW,OAAO,CAAC,EACzC,CAEA,SAAS,EAAc,EAAwC,EAAe,CAC5E,GAAI,EAAU,OACd,IAAM,EAAO,EAAO,GACd,EAAO,EAAQ,GACjB,EAAsB,KAE1B,OAAQ,EAAE,IAAV,CACE,IAAK,aACL,IAAK,UACH,EAAO,EAAO,EACd,MACF,IAAK,YACL,IAAK,YACH,EAAO,EAAO,EACd,MACF,IAAK,SACH,EAAO,EAAO,EACd,MACF,IAAK,WACH,EAAO,EAAO,EACd,MACF,IAAK,OACH,EAAO,EACP,MACF,IAAK,MACH,EAAO,EACP,MACF,QACE,MACJ,CACA,EAAE,eAAe,EACjB,EAAO,EAAO,EAAM,EAAI,CAC1B,CAEA,IAAM,EAAc,GAAe,EAAM,GAAO,EAAM,CAAC,EAAI,IAAQ,EAAM,GAAO,EAC1E,EAAa,GAAc,GAAG,EAAW,CAAC,EAAI,IAAI,GAElD,GAAa,EACf,CAAE,KAAM,EAAU,EAAQ,EAAE,EAAG,MAAO,IAAI,EAAW,EAAQ,EAAE,EAAI,EAAW,EAAQ,EAAE,GAAK,IAAI,EAAG,EACpG,CAAE,MAAO,EAAU,EAAQ,EAAE,CAAE,EAE7B,EAAgB,CAAC,CAAC,GAAO,KAAM,GAAM,EAAE,OAAS,IAAI,EACpD,EAAU,GAAe,EAAc,EAAY,CAAC,EAAI,EAE9D,SAAS,EAAe,EAAe,CACrC,IAAM,EAAI,EAAQ,GACZ,EAAO,EAAO,CAAC,EACf,CAAC,EAAO,GAAS,EAAU,EAAO,CAAO,EAC/C,MAAO,CACL,KAAM,SACN,gBAAiB,OAAO,KAAK,IAAI,EAAK,CAAK,CAAC,CAAC,QAAQ,CAAQ,CAAC,EAC9D,gBAAiB,OAAO,KAAK,IAAI,EAAK,CAAK,CAAC,CAAC,QAAQ,CAAQ,CAAC,EAC9D,gBAAiB,EACjB,iBAAkB,OAAO,GAAS,UAAY,OAAO,GAAS,SAAW,OAAO,CAAI,EAAI,IAAA,GACxF,mBAAoB,aACpB,gBAAiB,GAAY,IAAA,EAC/B,CACF,CAGA,IAAM,GAAW,EACb,CAAE,KAAM,QAAkB,aAAc,EAAW,gBAAiB,GAAY,IAAA,EAAU,EAC1F,CAAE,GAAG,EAAe,CAAC,EAAG,aAAc,EAAW,SAAU,EAAW,GAAK,CAAS,EAExF,OACE,EAAC,MAAD,CACE,GAAI,EACJ,GAAI,GACJ,IAAK,EACL,UAAW,EACT,EAAO,OACP,GAAY,EAAO,eACnB,IAAY,EAAO,eACnB,GAAiB,EAAO,oBACxB,GACA,GAAY,IACd,EACA,MAAO,CAAE,sBAAuB,EAAM,GAAG,GAAO,GAAG,GAAY,IAAK,EACpE,cAAe,GACf,cAAe,GACf,YAAa,GACb,UAAW,EAAU,IAAA,GAAa,GAAM,EAAc,EAAG,CAAC,EAE1D,SAAA,EAAC,MAAD,CAAK,IAAK,EAAU,UAAW,EAAG,EAAO,YAAa,GAAY,KAAK,EAAG,MAAO,GAAY,MAA7F,SAAA,CACE,EAAC,MAAD,CAAK,UAAW,EAAG,EAAO,YAAa,GAAY,KAAK,EAAG,MAAO,CAAE,GAAG,GAAY,GAAG,GAAY,KAAM,CAAI,CAAA,EAC3G,GAAO,IAAK,GAAS,CACpB,IAAM,EAAO,EAAU,EAAK,KAAK,EACjC,OACE,EAAC,EAAM,SAAP,CAAA,SAAA,CACE,EAAC,OAAD,CAAM,UAAW,EAAG,EAAO,WAAY,GAAY,IAAI,EAAG,MAAO,CAAE,OAAM,GAAG,GAAY,IAAK,CAAI,CAAA,EAChG,EAAK,OAAS,MACb,EAAC,OAAD,CACE,UAAW,EAAG,EAAO,gBAAiB,GAAY,SAAS,EAC3D,MAAO,CAAE,OAAM,GAAG,GAAY,SAAU,EAEvC,SAAA,EAAK,KACF,CAAA,CAEM,CAAA,EAVK,EAAK,KAUV,CAEpB,CAAC,EACA,EAAQ,KAAK,EAAG,IACf,EAAC,MAAD,CAEE,IAAM,GAAO,CACX,EAAU,QAAQ,GAAS,CAC7B,EACA,UAAW,EAAG,EAAO,YAAa,GAAY,KAAK,EACnD,MAAO,CAAE,KAAM,EAAU,CAAC,EAAG,GAAG,GAAY,KAAM,EAClD,GAAK,EACD,CACE,GAAG,EAAe,CAAK,EACvB,aAAc,IAAc,KAAW,IAAU,EAAI,OAAS,MAC9D,SAAU,EAAW,GAAK,EAC1B,UAAY,GAA2C,EAAc,EAAG,CAAK,CAC/E,EACA,CAAC,EAEJ,SAAA,GACC,EAAC,OAAD,CAAM,UAAW,EAAG,EAAO,YAAa,GAAY,KAAK,EAAG,MAAO,GAAY,MAC5E,SAAA,EAAO,CAAC,CACL,CAAA,CAEL,EApBE,CAoBF,CACN,CACE,GACF,CAAA,CAET"}
|
|
1
|
+
{"version":3,"file":"slider.mjs","names":[],"sources":["../../../../package/common/slider/slider.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState, type ReactElement } from 'react';\nimport cx from 'classnames';\nimport styles from './slider.module.pcss';\nimport type { RangeSliderProps, SingleSliderProps, SliderProps } from './slider.types';\n\n/**\n * Every prop of both variants, optional. Destructuring the union directly cannot reach the\n * range-only props, and leaving them in `...rest` spreads them onto the DOM node.\n */\ntype AnySliderProps = Omit<SingleSliderProps, 'onChange' | 'onChangeEnd' | 'value' | 'defaultValue' | 'range'> &\n Partial<Pick<RangeSliderProps, 'minRange' | 'thumbLabels'>> & {\n range?: boolean;\n value?: number | [number, number];\n defaultValue?: number | [number, number];\n onChange?: (value: never) => void;\n onChangeEnd?: (value: never) => void;\n };\n\n/** Count decimal places in a step so snapped values don't accumulate float error. */\nfunction decimalsOf(step: number): number {\n const s = String(step);\n const dot = s.indexOf('.');\n return dot === -1 ? 0 : s.length - dot - 1;\n}\n\nexport default function Slider(props: SliderProps): ReactElement {\n const {\n min = 0,\n max = 100,\n step = 1,\n disabled = false,\n marks,\n showValue = false,\n formatValue,\n size,\n tabIndex = 0,\n className,\n style,\n classNames,\n styles: slotStyles,\n 'aria-label': ariaLabel,\n range,\n value,\n defaultValue,\n onChange,\n onChangeEnd,\n minRange = 0,\n thumbLabels,\n ...rest\n } = props as AnySliderProps;\n\n // The union guarantees each handler matches `range`, but that link does not survive\n // destructuring, so the pair is widened once here rather than cast at every call.\n const emitChange = onChange as ((v: number | [number, number]) => void) | undefined;\n const emitEnd = onChangeEnd as ((v: number | [number, number]) => void) | undefined;\n\n const isRange = range === true;\n\n const trackRef = useRef<HTMLDivElement>(null);\n const rootRef = useRef<HTMLDivElement>(null);\n const thumbRefs = useRef<(HTMLDivElement | null)[]>([]);\n const draggingIndexRef = useRef<number | null>(null);\n const [dragging, setDragging] = useState(false);\n\n const decimals = decimalsOf(step);\n\n function clamp(v: number): number {\n return Math.min(max, Math.max(min, v));\n }\n\n function snap(v: number): number {\n const snapped = Math.round((v - min) / step) * step + min;\n return Number(clamp(snapped).toFixed(decimals));\n }\n\n /** Both modes run on an array internally; only the edges of the component know the difference. */\n function toValues(raw: number | [number, number] | undefined): number[] {\n if (isRange) {\n const pair = (raw as [number, number] | undefined) ?? [min, max];\n return [clamp(pair[0]), clamp(pair[1])];\n }\n return [clamp((raw as number | undefined) ?? min)];\n }\n\n /** Reshapes a stored pair or single if `range` is flipped after mount. */\n function fitToMode(values: number[]): number[] {\n const expected = isRange ? 2 : 1;\n if (values.length === expected) return values;\n return isRange ? [values[0], max] : [values[0]];\n }\n\n const isControlled = value !== undefined;\n const [internal, setInternal] = useState<number[]>(() => toValues(defaultValue));\n const current = isControlled ? toValues(value) : fitToMode(internal);\n\n // Latest committed values, for reading inside pointer handlers without stale closures. Synced\n // after render (never written during render) and optimistically in commit() so a drag burst\n // dedupes before the next render lands.\n const currentRef = useRef(current);\n useEffect(() => {\n currentRef.current = current;\n }, [current]);\n\n function payloadOf(next: number[]): number | [number, number] {\n return isRange ? [next[0], next[1]] : next[0];\n }\n\n /** How far this thumb may travel: the track, narrowed by its neighbour and `minRange`. */\n function boundsFor(index: number, values: number[]): [number, number] {\n if (!isRange) return [min, max];\n return index === 0 ? [min, values[1] - minRange] : [values[0] + minRange, max];\n }\n\n function commit(index: number, raw: number, ended: boolean) {\n const previous = currentRef.current;\n const [lower, upper] = boundsFor(index, previous);\n\n // Clamped after snapping, and rounded again: a bound derived from a neighbour plus `minRange`\n // is off the step grid and carries float error (0.3 - 0.1 is 0.19999999999999998).\n let snapped = snap(raw);\n if (snapped < lower) snapped = Number(Math.max(min, lower).toFixed(decimals));\n if (snapped > upper) snapped = Number(Math.min(max, upper).toFixed(decimals));\n\n // A keyboard step that lands on the same value still ends a gesture, but nothing changed,\n // so only onChangeEnd fires.\n if (snapped === previous[index]) {\n if (ended) emitEnd?.(payloadOf(previous));\n return;\n }\n\n const next = [...previous];\n next[index] = snapped;\n currentRef.current = next;\n if (!isControlled) setInternal(next);\n emitChange?.(payloadOf(next));\n if (ended) emitEnd?.(payloadOf(next));\n }\n\n function valueFromClientX(clientX: number): number {\n const track = trackRef.current;\n if (!track) return currentRef.current[0];\n const rect = track.getBoundingClientRect();\n const ratio = rect.width ? (clientX - rect.left) / rect.width : 0;\n return min + Math.min(1, Math.max(0, ratio)) * (max - min);\n }\n\n /**\n * The thumb closest to the press. On a tie the press direction decides, which is what keeps the\n * upper thumb reachable when the two sit on the same value and every distance ties.\n */\n function nearestThumb(target: number): number {\n if (!isRange) return 0;\n const [lo, hi] = currentRef.current;\n const toLo = Math.abs(target - lo);\n const toHi = Math.abs(target - hi);\n if (toLo === toHi) return target > hi ? 1 : 0;\n return toLo < toHi ? 0 : 1;\n }\n\n function handlePointerDown(e: React.PointerEvent<HTMLDivElement>) {\n if (disabled) return;\n e.preventDefault();\n const target = valueFromClientX(e.clientX);\n const index = nearestThumb(target);\n\n (isRange ? thumbRefs.current[index] : rootRef.current)?.focus();\n rootRef.current?.setPointerCapture?.(e.pointerId);\n draggingIndexRef.current = index;\n setDragging(true);\n commit(index, target, false);\n }\n\n function handlePointerMove(e: React.PointerEvent<HTMLDivElement>) {\n const index = draggingIndexRef.current;\n if (index === null) return;\n commit(index, valueFromClientX(e.clientX), false);\n }\n\n function handlePointerUp(e: React.PointerEvent<HTMLDivElement>) {\n if (draggingIndexRef.current === null) return;\n draggingIndexRef.current = null;\n setDragging(false);\n rootRef.current?.releasePointerCapture?.(e.pointerId);\n emitEnd?.(payloadOf(currentRef.current));\n }\n\n function handleKeyDown(e: React.KeyboardEvent<HTMLDivElement>, index: number) {\n if (disabled) return;\n const page = step * 10;\n const from = current[index];\n let next: number | null = null;\n\n switch (e.key) {\n case 'ArrowRight':\n case 'ArrowUp':\n next = from + step;\n break;\n case 'ArrowLeft':\n case 'ArrowDown':\n next = from - step;\n break;\n case 'PageUp':\n next = from + page;\n break;\n case 'PageDown':\n next = from - page;\n break;\n case 'Home':\n next = min;\n break;\n case 'End':\n next = max;\n break;\n default:\n return;\n }\n e.preventDefault();\n commit(index, next, true);\n }\n\n const fractionOf = (v: number) => (max > min ? (clamp(v) - min) / (max - min) : 0);\n const percentOf = (v: number) => `${fractionOf(v) * 100}%`;\n\n const rangeStyle = isRange\n ? { left: percentOf(current[0]), width: `${(fractionOf(current[1]) - fractionOf(current[0])) * 100}%` }\n : { width: percentOf(current[0]) };\n\n const hasMarkLabels = !!marks?.some((m) => m.label != null);\n const textOf = (v: number) => (formatValue ? formatValue(v) : v);\n\n function thumbAriaProps(index: number) {\n const v = current[index];\n const text = textOf(v);\n const [lower, upper] = boundsFor(index, current);\n return {\n role: 'slider' as const,\n 'aria-valuemin': Number(Math.max(min, lower).toFixed(decimals)),\n 'aria-valuemax': Number(Math.min(max, upper).toFixed(decimals)),\n 'aria-valuenow': v,\n 'aria-valuetext': typeof text === 'string' || typeof text === 'number' ? String(text) : undefined,\n 'aria-orientation': 'horizontal' as const,\n 'aria-disabled': disabled || undefined,\n };\n }\n\n // A single-thumb slider is the slider; a two-thumb one is a group of two, each its own slider.\n const rootAria = isRange\n ? { role: 'group' as const, 'aria-label': ariaLabel, 'aria-disabled': disabled || undefined }\n : { ...thumbAriaProps(0), 'aria-label': ariaLabel, tabIndex: disabled ? -1 : tabIndex };\n\n return (\n <div\n {...rest}\n {...rootAria}\n ref={rootRef}\n className={cx(\n styles.slider,\n disabled && styles.sliderDisabled,\n dragging && styles.sliderDragging,\n hasMarkLabels && styles.sliderHasMarkLabels,\n className,\n classNames?.root,\n )}\n style={\n { ...(size ? { '--slider-thumb-size': size } : null), ...style, ...slotStyles?.root } as React.CSSProperties\n }\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onKeyDown={isRange ? undefined : (e) => handleKeyDown(e, 0)}\n >\n <div ref={trackRef} className={cx(styles.sliderTrack, classNames?.track)} style={slotStyles?.track}>\n <div className={cx(styles.sliderRange, classNames?.range)} style={{ ...rangeStyle, ...slotStyles?.range }} />\n {marks?.map((mark) => {\n const left = percentOf(mark.value);\n return (\n <React.Fragment key={mark.value}>\n <span className={cx(styles.sliderMark, classNames?.mark)} style={{ left, ...slotStyles?.mark }} />\n {mark.label != null && (\n <span\n className={cx(styles.sliderMarkLabel, classNames?.markLabel)}\n style={{ left, ...slotStyles?.markLabel }}\n >\n {mark.label}\n </span>\n )}\n </React.Fragment>\n );\n })}\n {current.map((v, index) => (\n <div\n key={index}\n ref={(el) => {\n thumbRefs.current[index] = el;\n }}\n className={cx(styles.sliderThumb, classNames?.thumb)}\n style={{ left: percentOf(v), ...slotStyles?.thumb }}\n {...(isRange\n ? {\n ...thumbAriaProps(index),\n 'aria-label': thumbLabels?.[index] ?? (index === 0 ? 'From' : 'To'),\n tabIndex: disabled ? -1 : tabIndex,\n onKeyDown: (e: React.KeyboardEvent<HTMLDivElement>) => handleKeyDown(e, index),\n }\n : {})}\n >\n {showValue && (\n <span className={cx(styles.sliderValue, classNames?.value)} style={slotStyles?.value}>\n {textOf(v)}\n </span>\n )}\n </div>\n ))}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slider.module.mjs","names":[],"sources":["../../../../package/common/slider/slider.module.pcss"],"sourcesContent":[".slider {\n /* Theme tokens resolved once, each with a built-in fallback. Set any of the\n public `--slider-*` variables via ThemeProvider or `style` to override. */\n --custom-slider-track-color: var(--slider-track-color, var(--background-accent-light));\n --custom-slider-range-color: var(--slider-range-color, var(--primary-color));\n --custom-slider-thumb-color: var(--slider-thumb-color, var(--primary-color));\n --custom-slider-thumb-size: var(--slider-thumb-size,
|
|
1
|
+
{"version":3,"file":"slider.module.mjs","names":[],"sources":["../../../../package/common/slider/slider.module.pcss"],"sourcesContent":[".slider {\n /* Theme tokens resolved once, each with a built-in fallback. Set any of the\n public `--slider-*` variables via ThemeProvider or `style` to override. */\n --custom-slider-track-color: var(--slider-track-color, var(--background-accent-light));\n --custom-slider-range-color: var(--slider-range-color, var(--primary-color));\n --custom-slider-thumb-color: var(--slider-thumb-color, var(--primary-color));\n\n /* calc, not em: an unregistered custom property substitutes as tokens, so an em would\n resolve against whichever element uses it, and the mark label reads the thumb size while\n sitting on the smaller --text-small-font-size. */\n --custom-slider-thumb-size: var(--slider-thumb-size, calc(var(--default-font-size) * 1.125));\n --custom-slider-track-height: var(--slider-track-height, calc(var(--default-font-size) * 0.375));\n\n position: relative;\n display: flex;\n align-items: center;\n box-sizing: border-box;\n\n /* Fill the container, and allow shrinking when used inside a flex row so the\n track never collapses to nothing next to a sibling (e.g. a value readout). */\n width: 100%;\n min-width: 0;\n height: var(--custom-slider-thumb-size);\n padding: 0 calc(var(--custom-slider-thumb-size) / 2);\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n touch-action: none;\n user-select: none;\n\n &:focus-visible {\n outline: none;\n }\n\n /* Two selectors because focus lands in different places per mode: on the root for a single\n thumb, on the thumb itself in range mode, where each thumb is its own slider. */\n &:focus-visible .slider-thumb,\n & .slider-thumb:focus-visible {\n outline: none;\n box-shadow: 0 0 0 0.25em color-mix(in srgb, var(--custom-slider-range-color) 30%, transparent);\n }\n\n &-disabled {\n cursor: not-allowed;\n opacity: 0.5;\n }\n\n /* Reserve room under the track for mark labels. */\n &-has-mark-labels {\n margin-bottom: 1.375em;\n }\n\n &-track {\n position: relative;\n flex: 1;\n height: var(--custom-slider-track-height);\n background-color: var(--custom-slider-track-color);\n border-radius: 999px;\n }\n\n &-range {\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n background-color: var(--custom-slider-range-color);\n background-image: var(--primary-gradient, none);\n border-radius: 999px;\n transition: width 0.12s ease;\n }\n\n &-thumb {\n position: absolute;\n top: 50%;\n width: var(--custom-slider-thumb-size);\n height: var(--custom-slider-thumb-size);\n transform: translate(-50%, -50%);\n background-color: var(--custom-slider-thumb-color);\n border-radius: 50%;\n box-shadow: var(--card-shadow);\n transition:\n left 0.12s ease,\n box-shadow 0.15s ease;\n }\n\n /* No lag between pointer and thumb/fill while dragging. */\n &-dragging &-range,\n &-dragging &-thumb {\n transition: box-shadow 0.15s ease;\n }\n\n &-mark {\n position: absolute;\n top: 50%;\n width: 0.1875em;\n height: 0.1875em;\n transform: translate(-50%, -50%);\n border-radius: 50%;\n background-color: var(--background);\n pointer-events: none;\n }\n\n &-mark-label {\n position: absolute;\n top: calc(50% + var(--custom-slider-thumb-size));\n transform: translateX(-50%);\n font-size: var(--text-small-font-size, 12px);\n color: var(--text-dark);\n white-space: nowrap;\n pointer-events: none;\n }\n\n /* These em are against this bubble's own --text-small-font-size, not the slider's base, so\n the ratios differ from everywhere else in this file: 8px and 2px of 12px. */\n &-value {\n position: absolute;\n bottom: calc(100% + 0.6667em);\n left: 50%;\n transform: translateX(-50%);\n padding: 0.1667em 0.6667em;\n border-radius: var(--default-border-radius);\n background-color: var(--background-accent-light);\n color: var(--text-color);\n font-size: var(--text-small-font-size, 12px);\n white-space: nowrap;\n pointer-events: none;\n font-variant-numeric: tabular-nums;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .slider-range,\n .slider-thumb {\n transition: none;\n }\n}\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"switch.module.mjs","names":[],"sources":["../../../../package/common/switch/switch.module.pcss"],"sourcesContent":[".switch {\n user-select: none;\n display: flex;\n align-items: center;\n column-gap: 0.625em;\n width: fit-content;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n border: 1px solid transparent;\n margin: -1px;\n\n &:focus-visible {\n outline: none;\n border: 1px solid var(--focus-border-color, var(--primary-color));\n border-radius: var(--default-border-radius);\n }\n\n &-disabled {\n filter: brightness(0.8);\n cursor: not-allowed;\n }\n\n &-track {\n width: 2.25em;\n height: 1.25em;\n flex-shrink: 0;\n border-radius: var(--default-border-radius);\n background-color: var(--border-color);\n position: relative;\n transition: background-color 0.2s;\n box-sizing: border-box;\n padding: 0.125em;\n\n &-checked {\n background-color: var(--primary-color);\n }\n }\n\n &-thumb {\n width: 1em;\n height: 1em;\n border-radius: var(--default-border-radius);\n background-color: var(--background);\n box-shadow: var(--card-shadow);\n transform: translateX(0);\n transition: transform 0.2s;\n\n &-checked {\n transform: translateX(1em);\n }\n }\n\n &-label {\n line-height: 100%;\n color: var(--text-color);\n }\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"switch.module.mjs","names":[],"sources":["../../../../package/common/switch/switch.module.pcss"],"sourcesContent":[".switch {\n user-select: none;\n display: flex;\n align-items: center;\n column-gap: 0.625em;\n width: fit-content;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n border: 1px solid transparent;\n margin: -1px;\n\n &:focus-visible {\n outline: none;\n border: 1px solid var(--focus-border-color, var(--primary-color));\n border-radius: var(--default-border-radius);\n }\n\n &-disabled {\n filter: brightness(0.8);\n cursor: not-allowed;\n }\n\n &-track {\n width: 2.25em;\n height: 1.25em;\n flex-shrink: 0;\n border-radius: var(--default-border-radius);\n background-color: var(--border-color);\n position: relative;\n transition: background-color 0.2s;\n box-sizing: border-box;\n padding: 0.125em;\n\n &-checked {\n background-color: var(--primary-color);\n background-image: var(--primary-gradient, none);\n }\n }\n\n &-thumb {\n width: 1em;\n height: 1em;\n border-radius: var(--default-border-radius);\n background-color: var(--background);\n box-shadow: var(--card-shadow);\n transform: translateX(0);\n transition: transform 0.2s;\n\n &-checked {\n transform: translateX(1em);\n }\n }\n\n &-label {\n line-height: 100%;\n color: var(--text-color);\n }\n}\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tabHeader.module.mjs","names":[],"sources":["../../../../package/common/tabHeader/tabHeader.module.pcss"],"sourcesContent":[".tabHeader {\n display: flex;\n align-items: stretch;\n gap: 4px;\n border-bottom: 1px solid var(--border-color);\n user-select: none;\n overflow-x: auto;\n\n &-tab {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n color: var(--text-dark);\n border-bottom: 2px solid transparent;\n border-radius: var(--default-border-radius) var(--default-border-radius) 0 0;\n transition:\n color 0.2s,\n background 0.2s,\n border-color 0.2s;\n white-space: nowrap;\n\n &:hover {\n background: var(--background-accent-light);\n color: var(--text-color);\n }\n\n &-active {\n color: var(--primary-color);\n border-bottom-color: var(--primary-color);\n\n &:hover {\n color: var(--primary-color);\n }\n }\n\n &-disabled {\n opacity: 0.5;\n pointer-events: none;\n cursor: default;\n }\n }\n\n &-icon {\n font-size: 18px;\n flex-shrink: 0;\n }\n\n &-labels {\n display: flex;\n flex-direction: column;\n text-align: left;\n line-height: 1.25;\n }\n\n &-title {\n font-weight: var(--header-font-weight, 600);\n font-size: var(--default-font-size);\n }\n\n &-subtitle {\n font-size: var(--text-small-font-size);\n color: var(--text-dark);\n }\n}\n\n@media (width <= 640px) {\n .tabHeader-tab:not(.tabHeader-tab-active) .tabHeader-labels {\n display: none;\n }\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"tabHeader.module.mjs","names":[],"sources":["../../../../package/common/tabHeader/tabHeader.module.pcss"],"sourcesContent":[".tabHeader {\n display: flex;\n align-items: stretch;\n gap: 4px;\n border-bottom: 1px solid var(--border-color);\n user-select: none;\n overflow-x: auto;\n\n &-tab {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n color: var(--text-dark);\n border-bottom: 2px solid transparent;\n border-radius: var(--default-border-radius) var(--default-border-radius) 0 0;\n transition:\n color 0.2s,\n background 0.2s,\n border-color 0.2s;\n white-space: nowrap;\n\n &:hover {\n /* Longhand, not the shorthand: hover beats -active on specificity, and the shorthand\n would reset the active tab's gradient indicator away while the pointer is over it. */\n background-color: var(--background-accent-light);\n color: var(--text-color);\n }\n\n &-active {\n color: var(--primary-color);\n border-bottom-color: var(--primary-color);\n\n /* Paints the gradient exactly over border-bottom, which a background layer only reaches\n because its origin is the border box. The border stays as the no-gradient fallback. */\n background-image: var(--primary-gradient, none);\n background-repeat: no-repeat;\n background-size: 100% 2px;\n background-position: bottom;\n background-origin: border-box;\n\n &:hover {\n color: var(--primary-color);\n }\n }\n\n &-disabled {\n opacity: 0.5;\n pointer-events: none;\n cursor: default;\n }\n }\n\n &-icon {\n font-size: 18px;\n flex-shrink: 0;\n }\n\n &-labels {\n display: flex;\n flex-direction: column;\n text-align: left;\n line-height: 1.25;\n }\n\n &-title {\n font-weight: var(--header-font-weight, 600);\n font-size: var(--default-font-size);\n }\n\n &-subtitle {\n font-size: var(--text-small-font-size);\n color: var(--text-dark);\n }\n}\n\n@media (width <= 640px) {\n .tabHeader-tab:not(.tabHeader-tab-active) .tabHeader-labels {\n display: none;\n }\n}\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme.module.mjs","names":[],"sources":["../../../../package/common/themeProvider/theme.module.pcss"],"sourcesContent":[".themeRoot {\n font-family: var(--default-font);\n font-size: var(--default-font-size);\n font-weight: var(--default-font-weight);\n color: var(--text-color);\n}\n\n.colorFade * {\n transition: background 0.3s ease-in-out;\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"theme.module.mjs","names":[],"sources":["../../../../package/common/themeProvider/theme.module.pcss"],"sourcesContent":[".themeRoot {\n font-family: var(--default-font);\n font-size: var(--default-font-size);\n font-weight: var(--default-font-weight);\n color: var(--text-color);\n}\n\n/* The class is doubled to beat a component's own `transition` declaration. `.colorFade *` and a\n plain `.drawer` both count as one class, so which one a descendant gets was decided by whichever\n stylesheet the bundler happened to emit last, and the theme fade silently stopped applying to\n whole components when that order moved. */\n.colorFade.colorFade * {\n transition: background 0.3s ease-in-out;\n}\n"],"mappings":""}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{ThemeVariablesContext as e}from"./themeVariablesContext.mjs";import{defaultTheme as t}from"./defaultTheme.mjs";import n from"./theme.module.mjs";import r,{Component as i}from"react";import a from"classnames";import{jsx as o}from"react/jsx-runtime";var s=class extends i{constructor(...e){super(...e),this.state={resolvedVariables:{},colorFadeActive:!1,currentThemeColor:null},this.colorFadeTimeout=null,this.wrapperRef=r.createRef(),this.themeColorMeta=null,this.createdThemeColorMeta=!1,this.applyTheme=e=>{let n=this.props.themes??[t],r=n.find(e=>!e.baseThemeId)??n[0],i=r?r.variables:{},a=n.find(t=>t.id===e),o=a?this.resolveChain(a.id):[],s=Object.assign({},i,...o);this.setState({resolvedVariables:s,colorFadeActive:!0}),this.colorFadeTimeout&&clearTimeout(this.colorFadeTimeout),this.colorFadeTimeout=setTimeout(()=>{this.setState({colorFadeActive:!1}),this.colorFadeTimeout=null},500),setTimeout(()=>{this.wrapperRef.current&&this.setState({currentThemeColor:getComputedStyle(this.wrapperRef.current).getPropertyValue(`--primary-color`).trim()})},1)}}componentDidMount(){this.applyTheme(this.props.currentThemeId),this.syncThemeColorMeta(this.state.currentThemeColor??``)}componentDidUpdate(e,t){t.currentThemeColor!==this.state.currentThemeColor&&this.syncThemeColorMeta(this.state.currentThemeColor??``),(e.currentThemeId!==this.props.currentThemeId||e.themes!==this.props.themes)&&this.applyTheme(this.props.currentThemeId)}componentWillUnmount(){this.colorFadeTimeout&&clearTimeout(this.colorFadeTimeout),this.createdThemeColorMeta&&=(this.themeColorMeta?.remove(),this.themeColorMeta=null,!1)}syncThemeColorMeta(e){if(typeof document<`u`){if(!this.themeColorMeta){let e=document.head.querySelector(`meta[name="theme-color"]`);if(e)this.themeColorMeta=e;else{let e=document.createElement(`meta`);e.setAttribute(`name`,`theme-color`),document.head.appendChild(e),this.themeColorMeta=e,this.createdThemeColorMeta=!0}}this.themeColorMeta.setAttribute(`content`,e)}}resolveChain(e){let n=(this.props.themes??[t]).find(t=>t.id===e);return n?[...n.baseThemeId?this.resolveChain(n.baseThemeId):[],n.variables]:[]}render(){let{children:t}=this.props,{resolvedVariables:r,colorFadeActive:i}=this.state;return o(`div`,{ref:this.wrapperRef,id:`themeProvider`,className:a(n.themeRoot,i&&n.colorFade),style:r,children:o(e.Provider,{value:r,children:t})})}};export{s as default};
|
|
2
2
|
//# sourceMappingURL=themeProvider.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"themeProvider.mjs","names":[],"sources":["../../../../package/common/themeProvider/themeProvider.tsx"],"sourcesContent":["import React, { Component } from 'react';\nimport cx from 'classnames';\n\nimport type { Theme } from './theme.types';\nimport { defaultTheme } from './defaultTheme';\nimport styles from './theme.module.pcss';\n\ninterface Props {\n children: React.ReactNode;\n themes?: Theme[];\n currentThemeId?: string;\n}\n\ninterface State {\n resolvedVariables: Record<string, string>;\n colorFadeActive: boolean;\n currentThemeColor: string | null;\n}\n\nclass ThemeProvider extends Component<Props, State> {\n state: State = {\n resolvedVariables: {},\n colorFadeActive: false,\n currentThemeColor: null,\n };\n\n private colorFadeTimeout: ReturnType<typeof setTimeout> | null = null;\n private wrapperRef = React.createRef<HTMLDivElement>();\n private themeColorMeta: HTMLMetaElement | null = null;\n private createdThemeColorMeta = false;\n\n componentDidMount() {\n this.applyTheme(this.props.currentThemeId);\n this.syncThemeColorMeta(this.state.currentThemeColor ?? '');\n }\n\n componentDidUpdate(prevProps: Props, prevState: State) {\n if (prevState.currentThemeColor !== this.state.currentThemeColor) {\n this.syncThemeColorMeta(this.state.currentThemeColor ?? '');\n }\n if (prevProps.currentThemeId !== this.props.currentThemeId || prevProps.themes !== this.props.themes) {\n this.applyTheme(this.props.currentThemeId);\n }\n }\n\n componentWillUnmount() {\n if (this.colorFadeTimeout) clearTimeout(this.colorFadeTimeout);\n // Only remove the meta tag if we created it; leave a host-app tag intact.\n // Also clear the cached refs — StrictMode's dev-only mount/unmount/remount\n // cycle reuses this instance, and a stale ref would otherwise point at a\n // detached element on remount instead of re-inserting into <head>.\n if (this.createdThemeColorMeta) {\n this.themeColorMeta?.remove();\n this.themeColorMeta = null;\n this.createdThemeColorMeta = false;\n }\n }\n\n /**\n * Replaces the former react-helmet usage: keep a single\n * <meta name=\"theme-color\"> in sync with the active theme's primary colour.\n * Reuses a tag the host app already declares; otherwise creates its own\n * (and removes it again on unmount).\n */\n private syncThemeColorMeta(color: string) {\n if (typeof document === 'undefined') return;\n\n if (!this.themeColorMeta) {\n const existing = document.head.querySelector<HTMLMetaElement>('meta[name=\"theme-color\"]');\n if (existing) {\n this.themeColorMeta = existing;\n } else {\n const meta = document.createElement('meta');\n meta.setAttribute('name', 'theme-color');\n document.head.appendChild(meta);\n this.themeColorMeta = meta;\n this.createdThemeColorMeta = true;\n }\n }\n\n this.themeColorMeta.setAttribute('content', color);\n }\n\n /**\n * Resolves the full variable set for a given theme ID by walking up the\n * baseThemeId chain. Returns variables ordered from deepest ancestor to\n * the requested theme so callers can merge in order (later entries win).\n */\n private resolveChain(id: string): Record<string, string>[] {\n const themes = this.props.themes ?? [defaultTheme];\n const theme = themes.find((t) => t.id === id);\n if (!theme) return [];\n\n const parentVars = theme.baseThemeId ? this.resolveChain(theme.baseThemeId) : [];\n\n return [...parentVars, theme.variables as Record<string, string>];\n }\n\n private applyTheme = (currentThemeId: string | undefined) => {\n const themes = this.props.themes ?? [defaultTheme];\n\n // The root theme is the first theme without a baseThemeId.\n // It is always applied as the variable foundation.\n const rootTheme = themes.find((t) => !t.baseThemeId) ?? themes[0];\n const rootVars: Record<string, string> = rootTheme ? (rootTheme.variables as Record<string, string>) : {};\n\n // Resolve the selected theme's full inheritance chain.\n const selectedTheme = themes.find((t) => t.id === currentThemeId);\n const chainVars = selectedTheme ? this.resolveChain(selectedTheme.id) : [];\n\n // Merge: root foundation → ancestor chain → selected theme (each step overrides)\n const resolvedVariables = Object.assign({}, rootVars, ...chainVars);\n\n this.setState({ resolvedVariables, colorFadeActive: true });\n\n if (this.colorFadeTimeout) clearTimeout(this.colorFadeTimeout);\n this.colorFadeTimeout = setTimeout(() => {\n this.setState({ colorFadeActive: false });\n this.colorFadeTimeout = null;\n }, 500);\n\n // Read --primary-color after the new style is painted for the theme-color meta tag.\n setTimeout(() => {\n if (this.wrapperRef.current) {\n this.setState({\n currentThemeColor: getComputedStyle(this.wrapperRef.current).getPropertyValue('--primary-color').trim(),\n });\n }\n }, 1);\n };\n\n render() {\n const { children } = this.props;\n const { resolvedVariables, colorFadeActive } = this.state;\n\n return (\n <div\n ref={this.wrapperRef}\n id='themeProvider'\n className={cx(styles.themeRoot, colorFadeActive && styles.colorFade)}\n style={resolvedVariables as React.CSSProperties}\n >\n {children}
|
|
1
|
+
{"version":3,"file":"themeProvider.mjs","names":[],"sources":["../../../../package/common/themeProvider/themeProvider.tsx"],"sourcesContent":["import React, { Component } from 'react';\nimport cx from 'classnames';\n\nimport type { Theme } from './theme.types';\nimport { defaultTheme } from './defaultTheme';\nimport { ThemeVariablesContext } from './themeVariablesContext';\nimport styles from './theme.module.pcss';\n\ninterface Props {\n children: React.ReactNode;\n themes?: Theme[];\n currentThemeId?: string;\n}\n\ninterface State {\n resolvedVariables: Record<string, string>;\n colorFadeActive: boolean;\n currentThemeColor: string | null;\n}\n\nclass ThemeProvider extends Component<Props, State> {\n state: State = {\n resolvedVariables: {},\n colorFadeActive: false,\n currentThemeColor: null,\n };\n\n private colorFadeTimeout: ReturnType<typeof setTimeout> | null = null;\n private wrapperRef = React.createRef<HTMLDivElement>();\n private themeColorMeta: HTMLMetaElement | null = null;\n private createdThemeColorMeta = false;\n\n componentDidMount() {\n this.applyTheme(this.props.currentThemeId);\n this.syncThemeColorMeta(this.state.currentThemeColor ?? '');\n }\n\n componentDidUpdate(prevProps: Props, prevState: State) {\n if (prevState.currentThemeColor !== this.state.currentThemeColor) {\n this.syncThemeColorMeta(this.state.currentThemeColor ?? '');\n }\n if (prevProps.currentThemeId !== this.props.currentThemeId || prevProps.themes !== this.props.themes) {\n this.applyTheme(this.props.currentThemeId);\n }\n }\n\n componentWillUnmount() {\n if (this.colorFadeTimeout) clearTimeout(this.colorFadeTimeout);\n // Only remove the meta tag if we created it; leave a host-app tag intact.\n // Also clear the cached refs — StrictMode's dev-only mount/unmount/remount\n // cycle reuses this instance, and a stale ref would otherwise point at a\n // detached element on remount instead of re-inserting into <head>.\n if (this.createdThemeColorMeta) {\n this.themeColorMeta?.remove();\n this.themeColorMeta = null;\n this.createdThemeColorMeta = false;\n }\n }\n\n /**\n * Replaces the former react-helmet usage: keep a single\n * <meta name=\"theme-color\"> in sync with the active theme's primary colour.\n * Reuses a tag the host app already declares; otherwise creates its own\n * (and removes it again on unmount).\n */\n private syncThemeColorMeta(color: string) {\n if (typeof document === 'undefined') return;\n\n if (!this.themeColorMeta) {\n const existing = document.head.querySelector<HTMLMetaElement>('meta[name=\"theme-color\"]');\n if (existing) {\n this.themeColorMeta = existing;\n } else {\n const meta = document.createElement('meta');\n meta.setAttribute('name', 'theme-color');\n document.head.appendChild(meta);\n this.themeColorMeta = meta;\n this.createdThemeColorMeta = true;\n }\n }\n\n this.themeColorMeta.setAttribute('content', color);\n }\n\n /**\n * Resolves the full variable set for a given theme ID by walking up the\n * baseThemeId chain. Returns variables ordered from deepest ancestor to\n * the requested theme so callers can merge in order (later entries win).\n */\n private resolveChain(id: string): Record<string, string>[] {\n const themes = this.props.themes ?? [defaultTheme];\n const theme = themes.find((t) => t.id === id);\n if (!theme) return [];\n\n const parentVars = theme.baseThemeId ? this.resolveChain(theme.baseThemeId) : [];\n\n return [...parentVars, theme.variables as Record<string, string>];\n }\n\n private applyTheme = (currentThemeId: string | undefined) => {\n const themes = this.props.themes ?? [defaultTheme];\n\n // The root theme is the first theme without a baseThemeId.\n // It is always applied as the variable foundation.\n const rootTheme = themes.find((t) => !t.baseThemeId) ?? themes[0];\n const rootVars: Record<string, string> = rootTheme ? (rootTheme.variables as Record<string, string>) : {};\n\n // Resolve the selected theme's full inheritance chain.\n const selectedTheme = themes.find((t) => t.id === currentThemeId);\n const chainVars = selectedTheme ? this.resolveChain(selectedTheme.id) : [];\n\n // Merge: root foundation → ancestor chain → selected theme (each step overrides)\n const resolvedVariables = Object.assign({}, rootVars, ...chainVars);\n\n this.setState({ resolvedVariables, colorFadeActive: true });\n\n if (this.colorFadeTimeout) clearTimeout(this.colorFadeTimeout);\n this.colorFadeTimeout = setTimeout(() => {\n this.setState({ colorFadeActive: false });\n this.colorFadeTimeout = null;\n }, 500);\n\n // Read --primary-color after the new style is painted for the theme-color meta tag.\n setTimeout(() => {\n if (this.wrapperRef.current) {\n this.setState({\n currentThemeColor: getComputedStyle(this.wrapperRef.current).getPropertyValue('--primary-color').trim(),\n });\n }\n }, 1);\n };\n\n render() {\n const { children } = this.props;\n const { resolvedVariables, colorFadeActive } = this.state;\n\n return (\n <div\n ref={this.wrapperRef}\n id='themeProvider'\n className={cx(styles.themeRoot, colorFadeActive && styles.colorFade)}\n style={resolvedVariables as React.CSSProperties}\n >\n <ThemeVariablesContext.Provider value={resolvedVariables}>{children}</ThemeVariablesContext.Provider>\n </div>\n );\n }\n}\n\nexport default ThemeProvider;\n"],"mappings":"+PAoBA,IAAM,EAAN,cAA4B,CAAwB,+BACnC,KAAA,MAAA,CACb,kBAAmB,CAAC,EACpB,gBAAiB,GACjB,kBAAmB,IACrB,EAEiE,KAAA,iBAAA,KAC5C,KAAA,WAAA,EAAM,UAA0B,EACJ,KAAA,eAAA,KACjB,KAAA,sBAAA,GAqEV,KAAA,WAAA,GAAuC,CAC3D,IAAM,EAAS,KAAK,MAAM,QAAU,CAAC,CAAY,EAI3C,EAAY,EAAO,KAAM,GAAM,CAAC,EAAE,WAAW,GAAK,EAAO,GACzD,EAAmC,EAAa,EAAU,UAAuC,CAAC,EAGlG,EAAgB,EAAO,KAAM,GAAM,EAAE,KAAO,CAAc,EAC1D,EAAY,EAAgB,KAAK,aAAa,EAAc,EAAE,EAAI,CAAC,EAGnE,EAAoB,OAAO,OAAO,CAAC,EAAG,EAAU,GAAG,CAAS,EAElE,KAAK,SAAS,CAAE,oBAAmB,gBAAiB,EAAK,CAAC,EAEtD,KAAK,kBAAkB,aAAa,KAAK,gBAAgB,EAC7D,KAAK,iBAAmB,eAAiB,CACvC,KAAK,SAAS,CAAE,gBAAiB,EAAM,CAAC,EACxC,KAAK,iBAAmB,IAC1B,EAAG,GAAG,EAGN,eAAiB,CACX,KAAK,WAAW,SAClB,KAAK,SAAS,CACZ,kBAAmB,iBAAiB,KAAK,WAAW,OAAO,CAAC,CAAC,iBAAiB,iBAAiB,CAAC,CAAC,KAAK,CACxG,CAAC,CAEL,EAAG,CAAC,CACN,EAlGA,mBAAoB,CAClB,KAAK,WAAW,KAAK,MAAM,cAAc,EACzC,KAAK,mBAAmB,KAAK,MAAM,mBAAqB,EAAE,CAC5D,CAEA,mBAAmB,EAAkB,EAAkB,CACjD,EAAU,oBAAsB,KAAK,MAAM,mBAC7C,KAAK,mBAAmB,KAAK,MAAM,mBAAqB,EAAE,GAExD,EAAU,iBAAmB,KAAK,MAAM,gBAAkB,EAAU,SAAW,KAAK,MAAM,SAC5F,KAAK,WAAW,KAAK,MAAM,cAAc,CAE7C,CAEA,sBAAuB,CACjB,KAAK,kBAAkB,aAAa,KAAK,gBAAgB,EAK7D,AAGE,KAAK,yBAFL,KAAK,gBAAgB,OAAO,EAC5B,KAAK,eAAiB,KACO,GAEjC,CAQA,mBAA2B,EAAe,CACpC,UAAO,SAAa,IAExB,IAAI,CAAC,KAAK,eAAgB,CACxB,IAAM,EAAW,SAAS,KAAK,cAA+B,0BAA0B,EACxF,GAAI,EACF,KAAK,eAAiB,MACjB,CACL,IAAM,EAAO,SAAS,cAAc,MAAM,EAC1C,EAAK,aAAa,OAAQ,aAAa,EACvC,SAAS,KAAK,YAAY,CAAI,EAC9B,KAAK,eAAiB,EACtB,KAAK,sBAAwB,EAC/B,CACF,CAEA,KAAK,eAAe,aAAa,UAAW,CAAK,CAFjD,CAGF,CAOA,aAAqB,EAAsC,CAEzD,IAAM,GADS,KAAK,MAAM,QAAU,CAAC,CAAY,EAAA,CAC5B,KAAM,GAAM,EAAE,KAAO,CAAE,EAK5C,OAJK,EAIE,CAAC,GAFW,EAAM,YAAc,KAAK,aAAa,EAAM,WAAW,EAAI,CAAC,EAExD,EAAM,SAAmC,EAJ7C,CAAC,CAKtB,CAmCA,QAAS,CACP,GAAM,CAAE,YAAa,KAAK,MACpB,CAAE,oBAAmB,mBAAoB,KAAK,MAEpD,OACE,EAAC,MAAD,CACE,IAAK,KAAK,WACV,GAAG,gBACH,UAAW,EAAG,EAAO,UAAW,GAAmB,EAAO,SAAS,EACnE,MAAO,EAEP,SAAA,EAAC,EAAsB,SAAvB,CAAgC,MAAO,EAAoB,UAAyC,CAAA,CACjG,CAAA,CAET,CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"themeVariablesContext.mjs","names":[],"sources":["../../../../package/common/themeProvider/themeVariablesContext.ts"],"sourcesContent":["import { createContext } from 'react';\n\n/**\n * The nearest ThemeProvider's resolved variables, for content that renders outside its DOM\n * subtree. Theme variables reach a component by CSS inheritance, which a portal breaks: a\n * `BodyEnd` child lands wherever `#bodyEnd` happens to be, so it picks up whatever provider\n * wraps *that* node rather than the one it was written under.\n *\n * Deliberately its own module rather than a member of `themeProvider.tsx`: BodyEnd needs the\n * context and nothing else, and importing the component for it would pull the whole\n * ThemeProvider into every bundle that uses a portal.\n */\nexport const ThemeVariablesContext = createContext<Record<string, string> | null>(null);\n"],"mappings":"sCAYA,IAAa,EAAwB,EAA6C,IAAI"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{ButtonStyleType as e}from"../button/button.types.mjs";import t from"../button/button.mjs";import{Align as n}from"../floatingMenu/floatingMenu.types.mjs";import r from"../floatingMenu/floatingMenu.mjs";import i from"../tooltip/tooltip.mjs";import a from"../input/input.mjs";import ee from"../modal/modal.mjs";import{clampHour as te,clampToRange as o,formatTime as s,parseTimeString as c,snapMinute as l}from"./timeFunctions.mjs";import ne from"./components/clockDial/clockDial.mjs";import u from"./timeInput.module.mjs";import{useEffect as re,useRef as ie,useState as d}from"react";import f from"classnames";import{FontAwesomeIcon as ae}from"@fortawesome/react-fontawesome";import{faClock as oe}from"@fortawesome/free-solid-svg-icons";import{jsx as p,jsxs as m}from"react/jsx-runtime";import h from"@mona-health/react-input-mask";function g({value:g,selected:se,onChange:ce=()=>null,onSelect:_=()=>null,formValidator:v=null,isInline:y=!1,isModal:b=!1,noInput:le=!1,noHeader:ue=!1,showClearButton:x=!1,showNowButton:S=!1,minuteStep:C=1,use24Hour:w=!0,minTime:T=null,maxTime:E=null,label:D=``,isValid:de=!0,errorMessage:O=``,isRequired:k=!1,disabled:A=!1,className:fe=``,style:pe,classNames:j,styles:M,...me}){let N=()=>v?v.value||``:g??se??``,[P,F]=d(N),[I,L]=d(!1),[R,z]=d(`hours`),[he,B]=d(!1),[ge,V]=d(!1),[,_e]=d(0),H=N(),[ve,ye]=d(H),U=ie(v);!v&&ve!==H&&(ye(H),F(H)),re(()=>{if(U.current=v,!v)return;let e=()=>{F(v.value||``),_e(e=>e+1)};return v.registerOnUpdateListener(e),()=>v.removeOnUpdateListener(e)},[v]);let be=()=>v?v.touched&&v.hasError():!de||!!O,xe=()=>!!(k||v?.validators.find(e=>e.validatorId===`required`)),W=e=>{let t=e?s(e):null;v&&v.set(t),ce?.(t)},G=e=>{F(e?s(e):``),W(e)},K=c(P),q=K??{hours:12,minutes:0},J=e=>{let t={hours:e.hours,minutes:l(e.minutes,C)};G(o(t,T,E))},Se=e=>{let t={hours:e.hours,minutes:l(e.minutes,C)},n=o(t,T,E);if(G(n),R===`hours`){z(`minutes`);return}_?.(s(n)),y||L(!1)},Y=()=>{A||(z(`hours`),L(!0))},Ce=({previousState:e,nextState:t})=>{if(!e||t.value===e.value)return t;let n=t.value,r=n.slice(0,2);/^\d\d$/.test(r)&&Number(r)>23&&(n=`23${n.slice(2)}`);let i=n.slice(3,5);return/^\d\d$/.test(i)&&Number(i)>59&&(n=`${n.slice(0,3)}59`),n===t.value?t:{...t,value:n}},we=e=>{F(e);let t=c(e);t&&W(t)},Te=()=>{U.current&&(U.current.touched=!0),B(!1),W(c(P))},X=e=>{e!==q.hours>=12&&G({hours:te(q.hours+(e?12:-12)),minutes:q.minutes})},Z=be(),Ee=K?String(w?K.hours:(K.hours+11)%12+1).padStart(2,`0`):`--`,De=K?String(K.minutes).padStart(2,`0`):`--`,Oe=ue?null:m(`div`,{className:f(u.timeInputClockHeader,j?.clockHeader),style:M?.clockHeader,children:[p(`button`,{type:`button`,className:f(u.timeInputHeaderSegment,R===`hours`&&u.timeInputHeaderSegmentActive,j?.headerSegment),style:M?.headerSegment,onClick:()=>z(`hours`),children:Ee}),p(`span`,{className:u.timeInputHeaderColon,children:`:`}),p(`button`,{type:`button`,className:f(u.timeInputHeaderSegment,R===`minutes`&&u.timeInputHeaderSegmentActive,j?.headerSegment),style:M?.headerSegment,onClick:()=>z(`minutes`),children:De}),!w&&m(`div`,{className:f(u.timeInputMeridiem,j?.meridiem),style:M?.meridiem,children:[p(`button`,{type:`button`,className:f(q.hours<12&&u.timeInputMeridiemActive),onClick:()=>X(!1),children:`AM`}),p(`button`,{type:`button`,className:f(q.hours>=12&&u.timeInputMeridiemActive),onClick:()=>X(!0),children:`PM`})]})]}),ke=x||S?m(`div`,{className:f(u.timeInputFooter,j?.footer),style:M?.footer,children:[S&&p(t,{styleType:e.Default,onClick:()=>{let e=new Date;J({hours:e.getHours(),minutes:e.getMinutes()})},children:`Now`}),x&&p(t,{styleType:e.Default,onClick:()=>{G(null),_?.(null)},children:`Clear`})]}):null,Q=m(`div`,{className:f(u.timeInputClock,j?.clock),style:M?.clock,children:[Oe,p(ne,{time:q,mode:R,use24Hour:w,minuteStep:C,onChange:J,onCommit:Se,classNames:j,styles:M}),ke]}),$=le?null:p(a,{label:`${D}${xe()?` *`:``}`,value:P,icon:p(ae,{icon:oe}),onIconClick:Y,onClick:Y,readOnly:b,disabled:A,isValid:!Z,customInput:p(h,{mask:`99:99`,maskPlaceholder:`_`,beforeMaskedStateChange:Ce}),onChange:e=>we(e),onBlur:Te,onFocus:()=>B(!0),onMouseEnter:()=>V(!0),onMouseLeave:()=>V(!1)}),Ae=y?Q:b?p(ee,{hideHeader:!0,isOpen:I,onClose:()=>L(!1),children:Q}):p(r,{isOpen:I,onOpenChange:L,content:Q,align:n.Left,dontCloseOnChildClick:!0,children:$});return m(`div`,{className:f(u.timeInput,j?.root,fe),style:{...M?.root,...pe},...me,children:[(b||y)&&$,Ae,p(i,{variant:`error`,message:v?v.getCurrentErrorMessage()??``:O||``,isVisible:Z&&(he||ge)})]})}export{g as default};
|
|
1
|
+
import{ButtonStyleType as e}from"../button/button.types.mjs";import t from"../button/button.mjs";import{Align as n}from"../floatingMenu/floatingMenu.types.mjs";import r from"../floatingMenu/floatingMenu.mjs";import i from"../tooltip/tooltip.mjs";import a from"../input/input.mjs";import ee from"../modal/modal.mjs";import{clampHour as te,clampToRange as o,formatTime as s,parseTimeString as c,snapMinute as l}from"./timeFunctions.mjs";import ne from"./components/clockDial/clockDial.mjs";import u from"./timeInput.module.mjs";import{useEffect as re,useRef as ie,useState as d}from"react";import f from"classnames";import{FontAwesomeIcon as ae}from"@fortawesome/react-fontawesome";import{faClock as oe}from"@fortawesome/free-solid-svg-icons";import{jsx as p,jsxs as m}from"react/jsx-runtime";import h from"@mona-health/react-input-mask";function g({value:g,selected:se,onChange:ce=()=>null,onSelect:_=()=>null,formValidator:v=null,isInline:y=!1,isModal:b=!1,noInput:le=!1,noHeader:ue=!1,showClearButton:x=!1,showNowButton:S=!1,minuteStep:C=1,use24Hour:w=!0,minTime:T=null,maxTime:E=null,label:D=``,isValid:de=!0,errorMessage:O=``,isRequired:k=!1,disabled:A=!1,className:fe=``,style:pe,classNames:j,styles:M,...me}){let N=()=>v?v.value||``:g??se??``,[P,F]=d(N),[I,L]=d(!1),[R,z]=d(`hours`),[he,B]=d(!1),[ge,V]=d(!1),[,_e]=d(0),H=N(),[ve,ye]=d(H),U=ie(v);!v&&ve!==H&&(ye(H),F(H)),re(()=>{if(U.current=v,!v)return;let e=()=>{F(v.value||``),_e(e=>e+1)};return v.registerOnUpdateListener(e),()=>v.removeOnUpdateListener(e)},[v]);let be=()=>v?v.touched&&v.hasError():!de||!!O,xe=()=>!!(k||v?.validators.find(e=>e.validatorId===`required`)),W=e=>{let t=e?s(e):null;v&&v.set(t),ce?.(t)},G=e=>{F(e?s(e):``),W(e)},K=c(P),q=K??{hours:12,minutes:0},J=e=>{let t={hours:e.hours,minutes:l(e.minutes,C)};G(o(t,T,E))},Se=e=>{let t={hours:e.hours,minutes:l(e.minutes,C)},n=o(t,T,E);if(G(n),R===`hours`){z(`minutes`);return}_?.(s(n)),y||L(!1)},Y=()=>{A||(z(`hours`),L(!0))},Ce=({previousState:e,nextState:t})=>{if(!e||t.value===e.value)return t;let n=t.value,r=n.slice(0,2);/^\d\d$/.test(r)&&Number(r)>23&&(n=`23${n.slice(2)}`);let i=n.slice(3,5);return/^\d\d$/.test(i)&&Number(i)>59&&(n=`${n.slice(0,3)}59`),n===t.value?t:{...t,value:n}},we=e=>{F(e);let t=c(e);t&&W(t)},Te=()=>{U.current&&(U.current.touched=!0),B(!1),W(c(P))},X=e=>{e!==q.hours>=12&&G({hours:te(q.hours+(e?12:-12)),minutes:q.minutes})},Z=be(),Ee=K?String(w?K.hours:(K.hours+11)%12+1).padStart(2,`0`):`--`,De=K?String(K.minutes).padStart(2,`0`):`--`,Oe=ue?null:m(`div`,{className:f(u.timeInputClockHeader,j?.clockHeader),style:M?.clockHeader,children:[p(`button`,{type:`button`,className:f(u.timeInputHeaderSegment,R===`hours`&&u.timeInputHeaderSegmentActive,j?.headerSegment),style:M?.headerSegment,onClick:()=>z(`hours`),children:Ee}),p(`span`,{className:u.timeInputHeaderColon,children:`:`}),p(`button`,{type:`button`,className:f(u.timeInputHeaderSegment,R===`minutes`&&u.timeInputHeaderSegmentActive,j?.headerSegment),style:M?.headerSegment,onClick:()=>z(`minutes`),children:De}),!w&&m(`div`,{className:f(u.timeInputMeridiem,j?.meridiem),style:M?.meridiem,children:[p(`button`,{type:`button`,className:f(q.hours<12&&u.timeInputMeridiemActive),onClick:()=>X(!1),children:`AM`}),p(`button`,{type:`button`,className:f(q.hours>=12&&u.timeInputMeridiemActive),onClick:()=>X(!0),children:`PM`})]})]}),ke=x||S?m(`div`,{className:f(u.timeInputFooter,j?.footer),style:M?.footer,children:[S&&p(t,{styleType:e.Default,onClick:()=>{let e=new Date;J({hours:e.getHours(),minutes:e.getMinutes()})},children:`Now`}),x&&p(t,{styleType:e.Default,onClick:()=>{G(null),_?.(null)},children:`Clear`})]}):null,Q=m(`div`,{className:f(u.timeInputClock,j?.clock),style:M?.clock,children:[Oe,p(ne,{time:q,mode:R,use24Hour:w,minuteStep:C,onChange:J,onCommit:Se,classNames:j,styles:M}),ke]}),$=le?null:p(a,{autoComplete:`off`,label:`${D}${xe()?` *`:``}`,value:P,icon:p(ae,{icon:oe}),onIconClick:Y,onClick:Y,readOnly:b,disabled:A,isValid:!Z,customInput:p(h,{mask:`99:99`,maskPlaceholder:`_`,beforeMaskedStateChange:Ce}),onChange:e=>we(e),onBlur:Te,onFocus:()=>B(!0),onMouseEnter:()=>V(!0),onMouseLeave:()=>V(!1)}),Ae=y?Q:b?p(ee,{hideHeader:!0,isOpen:I,onClose:()=>L(!1),children:Q}):p(r,{isOpen:I,onOpenChange:L,content:Q,align:n.Left,dontCloseOnChildClick:!0,children:$});return m(`div`,{className:f(u.timeInput,j?.root,fe),style:{...M?.root,...pe},...me,children:[(b||y)&&$,Ae,p(i,{variant:`error`,message:v?v.getCurrentErrorMessage()??``:O||``,isVisible:Z&&(he||ge)})]})}export{g as default};
|
|
2
2
|
//# sourceMappingURL=timeInput.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timeInput.mjs","names":[],"sources":["../../../../package/common/timeInput/timeInput.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef } from 'react';\nimport cx from 'classnames';\nimport InputMask, { type BeforeMaskedStateChangeStates, type InputState } from '@mona-health/react-input-mask';\nimport { faClock } from '@fortawesome/free-solid-svg-icons';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport Input from '../input';\nimport Modal from '../modal';\nimport FloatingMenu from '../floatingMenu';\nimport Button from '../button';\nimport { ButtonStyleType } from '../button/button.types';\nimport Tooltip from '../tooltip';\nimport ClockDial from './components/clockDial';\nimport { Align } from '../floatingMenu/floatingMenu.types';\nimport { type TimeValue, parseTimeString, formatTime, snapMinute, clampToRange, clampHour } from './timeFunctions';\nimport type { TimeInputProps } from './timeInput.types';\n\nimport styles from './timeInput.module.pcss';\n\ntype ClockMode = 'hours' | 'minutes';\n\nexport default function TimeInput({\n value,\n selected,\n onChange = () => null,\n onSelect = () => null,\n formValidator = null,\n isInline = false,\n isModal = false,\n noInput = false,\n noHeader = false,\n showClearButton = false,\n showNowButton = false,\n minuteStep = 1,\n use24Hour = true,\n minTime = null,\n maxTime = null,\n label = '',\n isValid = true,\n errorMessage = '',\n isRequired = false,\n disabled = false,\n className = '',\n style,\n classNames,\n styles: slotStyles,\n ...rest\n}: TimeInputProps) {\n const getExternalString = (): string => {\n if (formValidator) return (formValidator.value as string) || '';\n return value ?? selected ?? '';\n };\n\n const [currentTimeString, setCurrentTimeString] = useState(getExternalString);\n const [isPickerOpen, setIsPickerOpen] = useState(false);\n const [mode, setMode] = useState<ClockMode>('hours');\n const [isFocused, setIsFocused] = useState(false);\n const [isHovered, setIsHovered] = useState(false);\n const [, forceUpdate] = useState(0);\n\n const externalString = getExternalString();\n const [prevExternal, setPrevExternal] = useState(externalString);\n const fvRef = useRef(formValidator);\n\n // Sync when the controlled value changes externally.\n if (!formValidator && prevExternal !== externalString) {\n setPrevExternal(externalString);\n setCurrentTimeString(externalString);\n }\n\n useEffect(() => {\n fvRef.current = formValidator;\n if (!formValidator) return;\n const listener = () => {\n setCurrentTimeString((formValidator.value as string) || '');\n forceUpdate((n) => n + 1);\n };\n formValidator.registerOnUpdateListener(listener);\n return () => formValidator.removeOnUpdateListener(listener);\n }, [formValidator]);\n\n const hasError = (): boolean =>\n formValidator ? formValidator.touched && formValidator.hasError() : !isValid || !!errorMessage;\n\n const computedIsRequired = (): boolean =>\n !!(isRequired || formValidator?.validators.find((v) => (v as { validatorId?: string }).validatorId === 'required'));\n\n /** Push a value out to formValidator/onChange without touching the input string. */\n const emit = (time: TimeValue | null) => {\n const str = time ? formatTime(time) : null;\n if (formValidator) formValidator.set(str);\n onChange?.(str);\n };\n\n const applyTime = (time: TimeValue | null) => {\n setCurrentTimeString(time ? formatTime(time) : '');\n emit(time);\n };\n\n const parsed = parseTimeString(currentTimeString);\n const dialTime: TimeValue = parsed ?? { hours: 12, minutes: 0 };\n\n const handleDialChange = (time: TimeValue) => {\n const snapped = { hours: time.hours, minutes: snapMinute(time.minutes, minuteStep) };\n applyTime(clampToRange(snapped, minTime, maxTime));\n };\n\n const handleDialCommit = (time: TimeValue) => {\n const snapped = { hours: time.hours, minutes: snapMinute(time.minutes, minuteStep) };\n const next = clampToRange(snapped, minTime, maxTime);\n applyTime(next);\n if (mode === 'hours') {\n setMode('minutes');\n return;\n }\n onSelect?.(formatTime(next));\n if (!isInline) setIsPickerOpen(false);\n };\n\n const openPicker = () => {\n if (disabled) return;\n setMode('hours');\n setIsPickerOpen(true);\n };\n\n const beforeMaskedStateChange = ({ previousState, nextState }: BeforeMaskedStateChangeStates): InputState => {\n if (!previousState || nextState.value === previousState.value) return nextState;\n let v = nextState.value;\n const hourStr = v.slice(0, 2);\n if (/^\\d\\d$/.test(hourStr) && Number(hourStr) > 23) v = `23${v.slice(2)}`;\n const minStr = v.slice(3, 5);\n if (/^\\d\\d$/.test(minStr) && Number(minStr) > 59) v = `${v.slice(0, 3)}59`;\n return v === nextState.value ? nextState : { ...nextState, value: v };\n };\n\n const handleInputChange = (v: string) => {\n setCurrentTimeString(v);\n const t = parseTimeString(v);\n if (t) emit(t);\n };\n\n const handleBlur = () => {\n if (fvRef.current) fvRef.current.touched = true;\n setIsFocused(false);\n emit(parseTimeString(currentTimeString));\n };\n\n const setMeridiem = (pm: boolean) => {\n const isPm = dialTime.hours >= 12;\n if (pm === isPm) return;\n applyTime({ hours: clampHour(dialTime.hours + (pm ? 12 : -12)), minutes: dialTime.minutes });\n };\n\n const hasErr = hasError();\n const displayHours = parsed\n ? String(use24Hour ? parsed.hours : ((parsed.hours + 11) % 12) + 1).padStart(2, '0')\n : '--';\n const displayMinutes = parsed ? String(parsed.minutes).padStart(2, '0') : '--';\n\n const header = noHeader ? null : (\n <div className={cx(styles.timeInputClockHeader, classNames?.clockHeader)} style={slotStyles?.clockHeader}>\n <button\n type='button'\n className={cx(\n styles.timeInputHeaderSegment,\n mode === 'hours' && styles.timeInputHeaderSegmentActive,\n classNames?.headerSegment,\n )}\n style={slotStyles?.headerSegment}\n onClick={() => setMode('hours')}\n >\n {displayHours}\n </button>\n <span className={styles.timeInputHeaderColon}>:</span>\n <button\n type='button'\n className={cx(\n styles.timeInputHeaderSegment,\n mode === 'minutes' && styles.timeInputHeaderSegmentActive,\n classNames?.headerSegment,\n )}\n style={slotStyles?.headerSegment}\n onClick={() => setMode('minutes')}\n >\n {displayMinutes}\n </button>\n {!use24Hour && (\n <div className={cx(styles.timeInputMeridiem, classNames?.meridiem)} style={slotStyles?.meridiem}>\n <button\n type='button'\n className={cx(dialTime.hours < 12 && styles.timeInputMeridiemActive)}\n onClick={() => setMeridiem(false)}\n >\n AM\n </button>\n <button\n type='button'\n className={cx(dialTime.hours >= 12 && styles.timeInputMeridiemActive)}\n onClick={() => setMeridiem(true)}\n >\n PM\n </button>\n </div>\n )}\n </div>\n );\n\n const footer =\n showClearButton || showNowButton ? (\n <div className={cx(styles.timeInputFooter, classNames?.footer)} style={slotStyles?.footer}>\n {showNowButton && (\n <Button\n styleType={ButtonStyleType.Default}\n onClick={() => {\n const now = new Date();\n handleDialChange({ hours: now.getHours(), minutes: now.getMinutes() });\n }}\n >\n Now\n </Button>\n )}\n {showClearButton && (\n <Button\n styleType={ButtonStyleType.Default}\n onClick={() => {\n applyTime(null);\n onSelect?.(null);\n }}\n >\n Clear\n </Button>\n )}\n </div>\n ) : null;\n\n const pickerContent = (\n <div className={cx(styles.timeInputClock, classNames?.clock)} style={slotStyles?.clock}>\n {header}\n <ClockDial\n time={dialTime}\n mode={mode}\n use24Hour={use24Hour}\n minuteStep={minuteStep}\n onChange={handleDialChange}\n onCommit={handleDialCommit}\n classNames={classNames}\n styles={slotStyles}\n />\n {footer}\n </div>\n );\n\n const input = noInput ? null : (\n <Input\n label={`${label}${computedIsRequired() ? ' *' : ''}`}\n value={currentTimeString}\n icon={<FontAwesomeIcon icon={faClock} />}\n onIconClick={openPicker}\n onClick={openPicker}\n readOnly={isModal}\n disabled={disabled}\n isValid={!hasErr}\n customInput={<InputMask mask='99:99' maskPlaceholder='_' beforeMaskedStateChange={beforeMaskedStateChange} />}\n onChange={(v) => handleInputChange(v as string)}\n onBlur={handleBlur}\n onFocus={() => setIsFocused(true)}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n />\n );\n\n const picker = (() => {\n if (isInline) return pickerContent;\n if (isModal) {\n return (\n <Modal hideHeader isOpen={isPickerOpen} onClose={() => setIsPickerOpen(false)}>\n {pickerContent}\n </Modal>\n );\n }\n return (\n <FloatingMenu\n isOpen={isPickerOpen}\n onOpenChange={setIsPickerOpen}\n content={pickerContent}\n align={Align.Left}\n dontCloseOnChildClick\n >\n {input}\n </FloatingMenu>\n );\n })();\n\n return (\n <div\n className={cx(styles.timeInput, classNames?.root, className)}\n style={{ ...slotStyles?.root, ...style }}\n {...rest}\n >\n {(isModal || isInline) && input}\n {picker}\n <Tooltip\n variant='error'\n message={formValidator ? (formValidator.getCurrentErrorMessage() ?? '') : errorMessage || ''}\n isVisible={hasErr && (isFocused || isHovered)}\n />\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"timeInput.mjs","names":[],"sources":["../../../../package/common/timeInput/timeInput.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef } from 'react';\nimport cx from 'classnames';\nimport InputMask, { type BeforeMaskedStateChangeStates, type InputState } from '@mona-health/react-input-mask';\nimport { faClock } from '@fortawesome/free-solid-svg-icons';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport Input from '../input';\nimport Modal from '../modal';\nimport FloatingMenu from '../floatingMenu';\nimport Button from '../button';\nimport { ButtonStyleType } from '../button/button.types';\nimport Tooltip from '../tooltip';\nimport ClockDial from './components/clockDial';\nimport { Align } from '../floatingMenu/floatingMenu.types';\nimport { type TimeValue, parseTimeString, formatTime, snapMinute, clampToRange, clampHour } from './timeFunctions';\nimport type { TimeInputProps } from './timeInput.types';\n\nimport styles from './timeInput.module.pcss';\n\ntype ClockMode = 'hours' | 'minutes';\n\nexport default function TimeInput({\n value,\n selected,\n onChange = () => null,\n onSelect = () => null,\n formValidator = null,\n isInline = false,\n isModal = false,\n noInput = false,\n noHeader = false,\n showClearButton = false,\n showNowButton = false,\n minuteStep = 1,\n use24Hour = true,\n minTime = null,\n maxTime = null,\n label = '',\n isValid = true,\n errorMessage = '',\n isRequired = false,\n disabled = false,\n className = '',\n style,\n classNames,\n styles: slotStyles,\n ...rest\n}: TimeInputProps) {\n const getExternalString = (): string => {\n if (formValidator) return (formValidator.value as string) || '';\n return value ?? selected ?? '';\n };\n\n const [currentTimeString, setCurrentTimeString] = useState(getExternalString);\n const [isPickerOpen, setIsPickerOpen] = useState(false);\n const [mode, setMode] = useState<ClockMode>('hours');\n const [isFocused, setIsFocused] = useState(false);\n const [isHovered, setIsHovered] = useState(false);\n const [, forceUpdate] = useState(0);\n\n const externalString = getExternalString();\n const [prevExternal, setPrevExternal] = useState(externalString);\n const fvRef = useRef(formValidator);\n\n // Sync when the controlled value changes externally.\n if (!formValidator && prevExternal !== externalString) {\n setPrevExternal(externalString);\n setCurrentTimeString(externalString);\n }\n\n useEffect(() => {\n fvRef.current = formValidator;\n if (!formValidator) return;\n const listener = () => {\n setCurrentTimeString((formValidator.value as string) || '');\n forceUpdate((n) => n + 1);\n };\n formValidator.registerOnUpdateListener(listener);\n return () => formValidator.removeOnUpdateListener(listener);\n }, [formValidator]);\n\n const hasError = (): boolean =>\n formValidator ? formValidator.touched && formValidator.hasError() : !isValid || !!errorMessage;\n\n const computedIsRequired = (): boolean =>\n !!(isRequired || formValidator?.validators.find((v) => (v as { validatorId?: string }).validatorId === 'required'));\n\n /** Push a value out to formValidator/onChange without touching the input string. */\n const emit = (time: TimeValue | null) => {\n const str = time ? formatTime(time) : null;\n if (formValidator) formValidator.set(str);\n onChange?.(str);\n };\n\n const applyTime = (time: TimeValue | null) => {\n setCurrentTimeString(time ? formatTime(time) : '');\n emit(time);\n };\n\n const parsed = parseTimeString(currentTimeString);\n const dialTime: TimeValue = parsed ?? { hours: 12, minutes: 0 };\n\n const handleDialChange = (time: TimeValue) => {\n const snapped = { hours: time.hours, minutes: snapMinute(time.minutes, minuteStep) };\n applyTime(clampToRange(snapped, minTime, maxTime));\n };\n\n const handleDialCommit = (time: TimeValue) => {\n const snapped = { hours: time.hours, minutes: snapMinute(time.minutes, minuteStep) };\n const next = clampToRange(snapped, minTime, maxTime);\n applyTime(next);\n if (mode === 'hours') {\n setMode('minutes');\n return;\n }\n onSelect?.(formatTime(next));\n if (!isInline) setIsPickerOpen(false);\n };\n\n const openPicker = () => {\n if (disabled) return;\n setMode('hours');\n setIsPickerOpen(true);\n };\n\n const beforeMaskedStateChange = ({ previousState, nextState }: BeforeMaskedStateChangeStates): InputState => {\n if (!previousState || nextState.value === previousState.value) return nextState;\n let v = nextState.value;\n const hourStr = v.slice(0, 2);\n if (/^\\d\\d$/.test(hourStr) && Number(hourStr) > 23) v = `23${v.slice(2)}`;\n const minStr = v.slice(3, 5);\n if (/^\\d\\d$/.test(minStr) && Number(minStr) > 59) v = `${v.slice(0, 3)}59`;\n return v === nextState.value ? nextState : { ...nextState, value: v };\n };\n\n const handleInputChange = (v: string) => {\n setCurrentTimeString(v);\n const t = parseTimeString(v);\n if (t) emit(t);\n };\n\n const handleBlur = () => {\n if (fvRef.current) fvRef.current.touched = true;\n setIsFocused(false);\n emit(parseTimeString(currentTimeString));\n };\n\n const setMeridiem = (pm: boolean) => {\n const isPm = dialTime.hours >= 12;\n if (pm === isPm) return;\n applyTime({ hours: clampHour(dialTime.hours + (pm ? 12 : -12)), minutes: dialTime.minutes });\n };\n\n const hasErr = hasError();\n const displayHours = parsed\n ? String(use24Hour ? parsed.hours : ((parsed.hours + 11) % 12) + 1).padStart(2, '0')\n : '--';\n const displayMinutes = parsed ? String(parsed.minutes).padStart(2, '0') : '--';\n\n const header = noHeader ? null : (\n <div className={cx(styles.timeInputClockHeader, classNames?.clockHeader)} style={slotStyles?.clockHeader}>\n <button\n type='button'\n className={cx(\n styles.timeInputHeaderSegment,\n mode === 'hours' && styles.timeInputHeaderSegmentActive,\n classNames?.headerSegment,\n )}\n style={slotStyles?.headerSegment}\n onClick={() => setMode('hours')}\n >\n {displayHours}\n </button>\n <span className={styles.timeInputHeaderColon}>:</span>\n <button\n type='button'\n className={cx(\n styles.timeInputHeaderSegment,\n mode === 'minutes' && styles.timeInputHeaderSegmentActive,\n classNames?.headerSegment,\n )}\n style={slotStyles?.headerSegment}\n onClick={() => setMode('minutes')}\n >\n {displayMinutes}\n </button>\n {!use24Hour && (\n <div className={cx(styles.timeInputMeridiem, classNames?.meridiem)} style={slotStyles?.meridiem}>\n <button\n type='button'\n className={cx(dialTime.hours < 12 && styles.timeInputMeridiemActive)}\n onClick={() => setMeridiem(false)}\n >\n AM\n </button>\n <button\n type='button'\n className={cx(dialTime.hours >= 12 && styles.timeInputMeridiemActive)}\n onClick={() => setMeridiem(true)}\n >\n PM\n </button>\n </div>\n )}\n </div>\n );\n\n const footer =\n showClearButton || showNowButton ? (\n <div className={cx(styles.timeInputFooter, classNames?.footer)} style={slotStyles?.footer}>\n {showNowButton && (\n <Button\n styleType={ButtonStyleType.Default}\n onClick={() => {\n const now = new Date();\n handleDialChange({ hours: now.getHours(), minutes: now.getMinutes() });\n }}\n >\n Now\n </Button>\n )}\n {showClearButton && (\n <Button\n styleType={ButtonStyleType.Default}\n onClick={() => {\n applyTime(null);\n onSelect?.(null);\n }}\n >\n Clear\n </Button>\n )}\n </div>\n ) : null;\n\n const pickerContent = (\n <div className={cx(styles.timeInputClock, classNames?.clock)} style={slotStyles?.clock}>\n {header}\n <ClockDial\n time={dialTime}\n mode={mode}\n use24Hour={use24Hour}\n minuteStep={minuteStep}\n onChange={handleDialChange}\n onCommit={handleDialCommit}\n classNames={classNames}\n styles={slotStyles}\n />\n {footer}\n </div>\n );\n\n const input = noInput ? null : (\n <Input\n autoComplete='off'\n label={`${label}${computedIsRequired() ? ' *' : ''}`}\n value={currentTimeString}\n icon={<FontAwesomeIcon icon={faClock} />}\n onIconClick={openPicker}\n onClick={openPicker}\n readOnly={isModal}\n disabled={disabled}\n isValid={!hasErr}\n customInput={<InputMask mask='99:99' maskPlaceholder='_' beforeMaskedStateChange={beforeMaskedStateChange} />}\n onChange={(v) => handleInputChange(v as string)}\n onBlur={handleBlur}\n onFocus={() => setIsFocused(true)}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n />\n );\n\n const picker = (() => {\n if (isInline) return pickerContent;\n if (isModal) {\n return (\n <Modal hideHeader isOpen={isPickerOpen} onClose={() => setIsPickerOpen(false)}>\n {pickerContent}\n </Modal>\n );\n }\n return (\n <FloatingMenu\n isOpen={isPickerOpen}\n onOpenChange={setIsPickerOpen}\n content={pickerContent}\n align={Align.Left}\n dontCloseOnChildClick\n >\n {input}\n </FloatingMenu>\n );\n })();\n\n return (\n <div\n className={cx(styles.timeInput, classNames?.root, className)}\n style={{ ...slotStyles?.root, ...style }}\n {...rest}\n >\n {(isModal || isInline) && input}\n {picker}\n <Tooltip\n variant='error'\n message={formValidator ? (formValidator.getCurrentErrorMessage() ?? '') : errorMessage || ''}\n isVisible={hasErr && (isFocused || isHovered)}\n />\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{renderIcon as e}from"../utils/renderIcon.mjs";import t from"../interactableDiv/index.mjs";import n from"./timeline.module.mjs";import{TimelineAlignment as r,TimelineItemStatus as i}from"./timeline.types.mjs";import"react";import a from"classnames";import{Fragment as o,jsx as s,jsxs as c}from"react/jsx-runtime";var l={[i.Primary]:n.timelineDotPrimary,[i.Success]:n.timelineDotSuccess,[i.Warn]:n.timelineDotWarn,[i.Error]:n.timelineDotError};function u({items:u=[],alignment:d=r.Left,className:f,style:p,classNames:m,styles:h,...g}){return s(`div`,{...g,className:a(n.timeline,{[n.timelineRight]:d===r.Right,[n.timelineAlternate]:d===r.Alternate},m?.root,f),style:{...h?.root,...p},children:u.map((f,p)=>{let g=f.id??p,_=p===u.length-1,v=d===r.Alternate&&p%2==1,y=!!f.onClick&&!f.disabled,b=c(o,{children:[c(`div`,{className:a(n.timelineMarker,m?.marker),style:h?.marker,children:[s(`div`,{className:a(n.timelineDot,{[n.timelineDotWithIcon]:!!f.icon},l[f.status??i.Default],m?.dot),style:h?.dot,children:f.icon?e(f.icon):null}),!_&&s(`div`,{className:a(n.timelineConnector,m?.connector),style:h?.connector})]}),c(`div`,{className:a(n.timelineContent,m?.content),style:h?.content,children:[c(`div`,{className:n.timelineHeader,children:[s(`div`,{className:a(n.timelineTitle,m?.title),style:h?.title,children:f.title}),f.timestamp!=null&&s(`div`,{className:a(n.timelineTimestamp,m?.timestamp),style:h?.timestamp,children:f.timestamp})]}),f.description!=null&&s(`div`,{className:a(n.timelineDescription,m?.description),style:h?.description,children:f.description}),f.content]})]}),x=a(n.timelineItem,{[n.timelineItemRight]:v},{[n.timelineItemClickable]:y},{[n.timelineItemDisabled]:f.disabled},m?.item);return y?s(t,{className:x,style:h?.item,onClick:f.onClick,children:b},g):s(`div`,{className:x,style:h?.item,"aria-disabled":f.disabled||void 0,children:b},g)})})}export{u as default};
|
|
1
|
+
import{renderIcon as e}from"../utils/renderIcon.mjs";import t from"../interactableDiv/index.mjs";import n from"./timeline.module.mjs";import{TimelineAlignment as r,TimelineItemStatus as i}from"./timeline.types.mjs";import"react";import a from"classnames";import{Fragment as o,jsx as s,jsxs as c}from"react/jsx-runtime";var l={[i.Primary]:n.timelineDotPrimary,[i.Success]:n.timelineDotSuccess,[i.Warn]:n.timelineDotWarn,[i.Error]:n.timelineDotError};function u({items:u=[],alignment:d=r.Left,className:f,style:p,classNames:m,styles:h,...g}){let _=u.some(e=>!!e.icon);return s(`div`,{...g,className:a(n.timeline,{[n.timelineRight]:d===r.Right,[n.timelineAlternate]:d===r.Alternate,[n.timelineWithIcons]:_},m?.root,f),style:{...h?.root,...p},children:u.map((f,p)=>{let g=f.id??p,_=p===u.length-1,v=d===r.Alternate&&p%2==1,y=!!f.onClick&&!f.disabled,b=c(o,{children:[c(`div`,{className:a(n.timelineMarker,m?.marker),style:h?.marker,children:[s(`div`,{className:a(n.timelineDot,{[n.timelineDotWithIcon]:!!f.icon},l[f.status??i.Default],m?.dot),style:h?.dot,children:f.icon?e(f.icon):null}),!_&&s(`div`,{className:a(n.timelineConnector,m?.connector),style:h?.connector})]}),c(`div`,{className:a(n.timelineContent,m?.content),style:h?.content,children:[c(`div`,{className:n.timelineHeader,children:[s(`div`,{className:a(n.timelineTitle,m?.title),style:h?.title,children:f.title}),f.timestamp!=null&&s(`div`,{className:a(n.timelineTimestamp,m?.timestamp),style:h?.timestamp,children:f.timestamp})]}),f.description!=null&&s(`div`,{className:a(n.timelineDescription,m?.description),style:h?.description,children:f.description}),f.content]})]}),x=a(n.timelineItem,{[n.timelineItemRight]:v},{[n.timelineItemClickable]:y},{[n.timelineItemDisabled]:f.disabled},m?.item);return y?s(t,{className:x,style:h?.item,onClick:f.onClick,children:b},g):s(`div`,{className:x,style:h?.item,"aria-disabled":f.disabled||void 0,children:b},g)})})}export{u as default};
|
|
2
2
|
//# sourceMappingURL=timeline.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timeline.mjs","names":[],"sources":["../../../../package/common/timeline/timeline.tsx"],"sourcesContent":["import React from 'react';\nimport cx from 'classnames';\nimport InteractableDiv from '../interactableDiv';\nimport styles from './timeline.module.pcss';\nimport { TimelineAlignment, TimelineItemStatus, type TimelineProps, type TimelineItem } from './timeline.types';\nimport { renderIcon } from '../utils/renderIcon';\n\n// TimelineItemStatus.Default is intentionally absent: it uses .timeline-dot's own\n// background-color, so no modifier class is needed for it.\nconst STATUS_CLASS: Partial<Record<TimelineItemStatus, string>> = {\n [TimelineItemStatus.Primary]: styles.timelineDotPrimary,\n [TimelineItemStatus.Success]: styles.timelineDotSuccess,\n [TimelineItemStatus.Warn]: styles.timelineDotWarn,\n [TimelineItemStatus.Error]: styles.timelineDotError,\n};\n\nexport default function Timeline({\n items = [],\n alignment = TimelineAlignment.Left,\n className,\n style,\n classNames,\n styles: slotStyles,\n ...rest\n}: TimelineProps) {\n return (\n <div\n {...rest}\n className={cx(\n styles.timeline,\n {\n [styles.timelineRight]: alignment === TimelineAlignment.Right,\n [styles.timelineAlternate]: alignment === TimelineAlignment.Alternate,\n },\n classNames?.root,\n className,\n )}\n style={{ ...slotStyles?.root, ...style }}\n >\n {items.map((item: TimelineItem, index: number) => {\n const key = item.id ?? index;\n const isLast = index === items.length - 1;\n const isAlternateRight = alignment === TimelineAlignment.Alternate && index % 2 === 1;\n const isClickable = !!item.onClick && !item.disabled;\n\n const itemContent = (\n <>\n <div className={cx(styles.timelineMarker, classNames?.marker)} style={slotStyles?.marker}>\n <div\n className={cx(\n styles.timelineDot,\n { [styles.timelineDotWithIcon]: !!item.icon },\n STATUS_CLASS[item.status ?? TimelineItemStatus.Default],\n classNames?.dot,\n )}\n style={slotStyles?.dot}\n >\n {item.icon ? renderIcon(item.icon) : null}\n </div>\n {!isLast && (\n <div className={cx(styles.timelineConnector, classNames?.connector)} style={slotStyles?.connector} />\n )}\n </div>\n <div className={cx(styles.timelineContent, classNames?.content)} style={slotStyles?.content}>\n <div className={styles.timelineHeader}>\n <div className={cx(styles.timelineTitle, classNames?.title)} style={slotStyles?.title}>\n {item.title}\n </div>\n {item.timestamp != null && (\n <div className={cx(styles.timelineTimestamp, classNames?.timestamp)} style={slotStyles?.timestamp}>\n {item.timestamp}\n </div>\n )}\n </div>\n {item.description != null && (\n <div\n className={cx(styles.timelineDescription, classNames?.description)}\n style={slotStyles?.description}\n >\n {item.description}\n </div>\n )}\n {item.content}\n </div>\n </>\n );\n\n const itemClassName = cx(\n styles.timelineItem,\n { [styles.timelineItemRight]: isAlternateRight },\n { [styles.timelineItemClickable]: isClickable },\n { [styles.timelineItemDisabled]: item.disabled },\n classNames?.item,\n );\n\n if (isClickable) {\n return (\n <InteractableDiv key={key} className={itemClassName} style={slotStyles?.item} onClick={item.onClick}>\n {itemContent}\n </InteractableDiv>\n );\n }\n\n return (\n <div key={key} className={itemClassName} style={slotStyles?.item} aria-disabled={item.disabled || undefined}>\n {itemContent}\n </div>\n );\n })}\n </div>\n );\n}\n"],"mappings":"+TASA,IAAM,EAA4D,EAC/D,EAAmB,SAAU,EAAO,oBACpC,EAAmB,SAAU,EAAO,oBACpC,EAAmB,MAAO,EAAO,iBACjC,EAAmB,OAAQ,EAAO,gBACrC,EAEA,SAAwB,EAAS,CAC/B,QAAQ,CAAC,EACT,YAAY,EAAkB,KAC9B,YACA,QACA,aACA,OAAQ,EACR,GAAG,GACa,
|
|
1
|
+
{"version":3,"file":"timeline.mjs","names":[],"sources":["../../../../package/common/timeline/timeline.tsx"],"sourcesContent":["import React from 'react';\nimport cx from 'classnames';\nimport InteractableDiv from '../interactableDiv';\nimport styles from './timeline.module.pcss';\nimport { TimelineAlignment, TimelineItemStatus, type TimelineProps, type TimelineItem } from './timeline.types';\nimport { renderIcon } from '../utils/renderIcon';\n\n// TimelineItemStatus.Default is intentionally absent: it uses .timeline-dot's own\n// background-color, so no modifier class is needed for it.\nconst STATUS_CLASS: Partial<Record<TimelineItemStatus, string>> = {\n [TimelineItemStatus.Primary]: styles.timelineDotPrimary,\n [TimelineItemStatus.Success]: styles.timelineDotSuccess,\n [TimelineItemStatus.Warn]: styles.timelineDotWarn,\n [TimelineItemStatus.Error]: styles.timelineDotError,\n};\n\nexport default function Timeline({\n items = [],\n alignment = TimelineAlignment.Left,\n className,\n style,\n classNames,\n styles: slotStyles,\n ...rest\n}: TimelineProps) {\n // An icon dot is bigger than a plain one, and the marker is only as wide as the dot\n // inside it — so mixing the two put every row's spine and content column at a different\n // x. Widening the marker for the whole timeline fixes the alignment; doing it only when\n // an icon is actually present leaves an icon-less timeline exactly where it was.\n const hasIcons = items.some((item: TimelineItem) => !!item.icon);\n\n return (\n <div\n {...rest}\n className={cx(\n styles.timeline,\n {\n [styles.timelineRight]: alignment === TimelineAlignment.Right,\n [styles.timelineAlternate]: alignment === TimelineAlignment.Alternate,\n [styles.timelineWithIcons]: hasIcons,\n },\n classNames?.root,\n className,\n )}\n style={{ ...slotStyles?.root, ...style }}\n >\n {items.map((item: TimelineItem, index: number) => {\n const key = item.id ?? index;\n const isLast = index === items.length - 1;\n const isAlternateRight = alignment === TimelineAlignment.Alternate && index % 2 === 1;\n const isClickable = !!item.onClick && !item.disabled;\n\n const itemContent = (\n <>\n <div className={cx(styles.timelineMarker, classNames?.marker)} style={slotStyles?.marker}>\n <div\n className={cx(\n styles.timelineDot,\n { [styles.timelineDotWithIcon]: !!item.icon },\n STATUS_CLASS[item.status ?? TimelineItemStatus.Default],\n classNames?.dot,\n )}\n style={slotStyles?.dot}\n >\n {item.icon ? renderIcon(item.icon) : null}\n </div>\n {!isLast && (\n <div className={cx(styles.timelineConnector, classNames?.connector)} style={slotStyles?.connector} />\n )}\n </div>\n <div className={cx(styles.timelineContent, classNames?.content)} style={slotStyles?.content}>\n <div className={styles.timelineHeader}>\n <div className={cx(styles.timelineTitle, classNames?.title)} style={slotStyles?.title}>\n {item.title}\n </div>\n {item.timestamp != null && (\n <div className={cx(styles.timelineTimestamp, classNames?.timestamp)} style={slotStyles?.timestamp}>\n {item.timestamp}\n </div>\n )}\n </div>\n {item.description != null && (\n <div\n className={cx(styles.timelineDescription, classNames?.description)}\n style={slotStyles?.description}\n >\n {item.description}\n </div>\n )}\n {item.content}\n </div>\n </>\n );\n\n const itemClassName = cx(\n styles.timelineItem,\n { [styles.timelineItemRight]: isAlternateRight },\n { [styles.timelineItemClickable]: isClickable },\n { [styles.timelineItemDisabled]: item.disabled },\n classNames?.item,\n );\n\n if (isClickable) {\n return (\n <InteractableDiv key={key} className={itemClassName} style={slotStyles?.item} onClick={item.onClick}>\n {itemContent}\n </InteractableDiv>\n );\n }\n\n return (\n <div key={key} className={itemClassName} style={slotStyles?.item} aria-disabled={item.disabled || undefined}>\n {itemContent}\n </div>\n );\n })}\n </div>\n );\n}\n"],"mappings":"+TASA,IAAM,EAA4D,EAC/D,EAAmB,SAAU,EAAO,oBACpC,EAAmB,SAAU,EAAO,oBACpC,EAAmB,MAAO,EAAO,iBACjC,EAAmB,OAAQ,EAAO,gBACrC,EAEA,SAAwB,EAAS,CAC/B,QAAQ,CAAC,EACT,YAAY,EAAkB,KAC9B,YACA,QACA,aACA,OAAQ,EACR,GAAG,GACa,CAKhB,IAAM,EAAW,EAAM,KAAM,GAAuB,CAAC,CAAC,EAAK,IAAI,EAE/D,OACE,EAAC,MAAD,CACE,GAAI,EACJ,UAAW,EACT,EAAO,SACP,EACG,EAAO,eAAgB,IAAc,EAAkB,OACvD,EAAO,mBAAoB,IAAc,EAAkB,WAC3D,EAAO,mBAAoB,CAC9B,EACA,GAAY,KACZ,CACF,EACA,MAAO,CAAE,GAAG,GAAY,KAAM,GAAG,CAAM,EAEtC,SAAA,EAAM,KAAK,EAAoB,IAAkB,CAChD,IAAM,EAAM,EAAK,IAAM,EACjB,EAAS,IAAU,EAAM,OAAS,EAClC,EAAmB,IAAc,EAAkB,WAAa,EAAQ,GAAM,EAC9E,EAAc,CAAC,CAAC,EAAK,SAAW,CAAC,EAAK,SAEtC,EACJ,EAAA,EAAA,CAAA,SAAA,CACE,EAAC,MAAD,CAAK,UAAW,EAAG,EAAO,eAAgB,GAAY,MAAM,EAAG,MAAO,GAAY,OAAlF,SAAA,CACE,EAAC,MAAD,CACE,UAAW,EACT,EAAO,YACP,EAAG,EAAO,qBAAsB,CAAC,CAAC,EAAK,IAAK,EAC5C,EAAa,EAAK,QAAU,EAAmB,SAC/C,GAAY,GACd,EACA,MAAO,GAAY,IAElB,SAAA,EAAK,KAAO,EAAW,EAAK,IAAI,EAAI,IAClC,CAAA,EACJ,CAAC,GACA,EAAC,MAAD,CAAK,UAAW,EAAG,EAAO,kBAAmB,GAAY,SAAS,EAAG,MAAO,GAAY,SAAY,CAAA,CAEnG,CACL,CAAA,EAAA,EAAC,MAAD,CAAK,UAAW,EAAG,EAAO,gBAAiB,GAAY,OAAO,EAAG,MAAO,GAAY,QAApF,SAAA,CACE,EAAC,MAAD,CAAK,UAAW,EAAO,eAAvB,SAAA,CACE,EAAC,MAAD,CAAK,UAAW,EAAG,EAAO,cAAe,GAAY,KAAK,EAAG,MAAO,GAAY,MAC7E,SAAA,EAAK,KACH,CAAA,EACJ,EAAK,WAAa,MACjB,EAAC,MAAD,CAAK,UAAW,EAAG,EAAO,kBAAmB,GAAY,SAAS,EAAG,MAAO,GAAY,UACrF,SAAA,EAAK,SACH,CAAA,CAEJ,IACJ,EAAK,aAAe,MACnB,EAAC,MAAD,CACE,UAAW,EAAG,EAAO,oBAAqB,GAAY,WAAW,EACjE,MAAO,GAAY,YAElB,SAAA,EAAK,WACH,CAAA,EAEN,EAAK,OACH,CACL,CAAA,CAAA,CAAA,CAAA,EAGE,EAAgB,EACpB,EAAO,aACP,EAAG,EAAO,mBAAoB,CAAiB,EAC/C,EAAG,EAAO,uBAAwB,CAAY,EAC9C,EAAG,EAAO,sBAAuB,EAAK,QAAS,EAC/C,GAAY,IACd,EAUA,OARI,EAEA,EAAC,EAAD,CAA2B,UAAW,EAAe,MAAO,GAAY,KAAM,QAAS,EAAK,QACzF,SAAA,CACc,EAFK,CAEL,EAKnB,EAAC,MAAD,CAAe,UAAW,EAAe,MAAO,GAAY,KAAM,gBAAe,EAAK,UAAY,IAAA,GAC/F,SAAA,CACE,EAFK,CAEL,CAET,CAAC,CACE,CAAA,CAET"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e=`timeline_VtQdt`,t=`timeline-item_s8-U2`,n=`timeline-item-connector_06FQ0`,r=`timeline-item-clickable_0w8zK`,i=`timeline-item-disabled_EkWVA`,a=`timeline-marker_u6jDA`,o=`timeline-dot_l-s7C`,s=`timeline-dot-with-icon_6JK7D`,c=`timeline-dot-primary_5Uk-e`,l=`timeline-dot-success_iEoLv`,u=`timeline-dot-warn_-6G8K`,d=`timeline-dot-error_-10M7`,f=`timeline-
|
|
1
|
+
var e=`timeline_VtQdt`,t=`timeline-item_s8-U2`,n=`timeline-item-connector_06FQ0`,r=`timeline-item-clickable_0w8zK`,i=`timeline-item-disabled_EkWVA`,a=`timeline-marker_u6jDA`,o=`timeline-dot_l-s7C`,s=`timeline-dot-with-icon_6JK7D`,c=`timeline-dot-primary_5Uk-e`,l=`timeline-dot-success_iEoLv`,u=`timeline-dot-warn_-6G8K`,d=`timeline-dot-error_-10M7`,f=`timeline-with-icons_ylDAw`,p=`timeline-connector_VuXnH`,m=`timeline-content_K4Ztg`,h=`timeline-header_xr4Tw`,g=`timeline-title_MZ26k`,_=`timeline-timestamp_-0w-N`,v=`timeline-description_WcWIu`,y=`timeline-right_fZEKn`,b=`timeline-alternate_Kv9LY`,x=`timeline-item-right_s5ELB`,S={timeline:e,"timeline-item":`timeline-item_s8-U2`,timelineItem:t,"timeline-item-connector":`timeline-item-connector_06FQ0`,timelineItemConnector:n,"timeline-item-clickable":`timeline-item-clickable_0w8zK`,timelineItemClickable:r,"timeline-item-disabled":`timeline-item-disabled_EkWVA`,timelineItemDisabled:i,"timeline-marker":`timeline-marker_u6jDA`,timelineMarker:a,"timeline-dot":`timeline-dot_l-s7C`,timelineDot:o,"timeline-dot-with-icon":`timeline-dot-with-icon_6JK7D`,timelineDotWithIcon:s,"timeline-dot-primary":`timeline-dot-primary_5Uk-e`,timelineDotPrimary:c,"timeline-dot-success":`timeline-dot-success_iEoLv`,timelineDotSuccess:l,"timeline-dot-warn":`timeline-dot-warn_-6G8K`,timelineDotWarn:u,"timeline-dot-error":`timeline-dot-error_-10M7`,timelineDotError:d,"timeline-with-icons":`timeline-with-icons_ylDAw`,timelineWithIcons:f,"timeline-connector":`timeline-connector_VuXnH`,timelineConnector:p,"timeline-content":`timeline-content_K4Ztg`,timelineContent:m,"timeline-header":`timeline-header_xr4Tw`,timelineHeader:h,"timeline-title":`timeline-title_MZ26k`,timelineTitle:g,"timeline-timestamp":`timeline-timestamp_-0w-N`,timelineTimestamp:_,"timeline-description":`timeline-description_WcWIu`,timelineDescription:v,"timeline-right":`timeline-right_fZEKn`,timelineRight:y,"timeline-alternate":`timeline-alternate_Kv9LY`,timelineAlternate:b,"timeline-item-right":`timeline-item-right_s5ELB`,timelineItemRight:x};export{S as default,e as timeline,b as timelineAlternate,p as timelineConnector,m as timelineContent,v as timelineDescription,o as timelineDot,d as timelineDotError,c as timelineDotPrimary,l as timelineDotSuccess,u as timelineDotWarn,s as timelineDotWithIcon,h as timelineHeader,t as timelineItem,r as timelineItemClickable,n as timelineItemConnector,i as timelineItemDisabled,x as timelineItemRight,a as timelineMarker,y as timelineRight,_ as timelineTimestamp,g as timelineTitle,f as timelineWithIcons};
|
|
2
2
|
//# sourceMappingURL=timeline.module.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timeline.module.mjs","names":[],"sources":["../../../../package/common/timeline/timeline.module.pcss"],"sourcesContent":[".timeline {\n /* Theme tokens resolved once, each with a built-in fallback. Set any of the\n public `--timeline-*` variables via ThemeProvider (theme-wide) or `style`\n (per instance) to override; unset ones fall back to the values below. */\n --custom-timeline-dot-size: var(--timeline-dot-size, 14px);\n --custom-timeline-dot-color: var(--timeline-dot-color, var(--primary-color));\n --custom-timeline-dot-border: var(--timeline-dot-border, var(--background));\n --custom-timeline-line-color: var(--timeline-line-color, var(--border-color));\n --custom-timeline-line-thickness: var(--timeline-line-thickness, 2px);\n --custom-timeline-gap: var(--timeline-gap, 16px);\n --custom-timeline-item-gap: var(--timeline-item-gap, 20px);\n --custom-timeline-icon-dot-size: var(--timeline-icon-dot-size, 28px);\n\n display: flex;\n flex-direction: column;\n color: var(--text-color);\n\n &-item {\n display: flex;\n gap: var(--custom-timeline-gap);\n border-radius: var(--default-border-radius);\n\n &:last-child &-connector {\n display: none;\n }\n }\n\n &-item-clickable {\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n transition: background-color 0.15s ease;\n margin: 0 -10px;\n padding: 0 10px;\n\n &:hover {\n background-color: var(--background-accent-light);\n }\n\n &:focus-visible {\n outline: 2px solid var(--focus-border-color, var(--primary-color));\n outline-offset: -2px;\n }\n }\n\n &-item-disabled {\n opacity: 0.5;\n }\n\n &-marker {\n display: flex;\n flex-direction: column;\n align-items: center;\n flex-shrink: 0;\n }\n\n &-dot {\n width: var(--custom-timeline-dot-size);\n height: var(--custom-timeline-dot-size);\n border-radius: 50%;\n background-color: var(--custom-timeline-dot-color);\n box-shadow: 0 0 0 3px var(--custom-timeline-dot-border);\n flex-shrink: 0;\n }\n\n /* Set by the component whenever the item has an icon — not inferred from the\n rendered markup (`:has(svg)`), which would miss a custom icon element that\n isn't an <svg>, e.g. an <img>. */\n &-dot-with-icon {\n width: var(--custom-timeline-icon-dot-size);\n height: var(--custom-timeline-icon-dot-size);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--text-on-primary);\n font-size: calc(var(--custom-timeline-icon-dot-size) * 0.5);\n }\n\n &-dot-primary {\n background-color: var(--primary-color);\n }\n\n &-dot-success {\n background-color: var(--success-color);\n }\n\n &-dot-warn {\n background-color: var(--warn-color);\n }\n\n &-dot-error {\n background-color: var(--error-color);\n }\n\n &-connector {\n flex: 1 1 auto;\n width: var(--custom-timeline-line-thickness);\n min-height: 12px;\n background-color: var(--custom-timeline-line-color);\n margin: 4px 0;\n }\n\n &-content {\n flex: 1 1 auto;\n min-width: 0;\n padding-bottom: var(--custom-timeline-item-gap);\n }\n\n &-header {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: 8px;\n }\n\n &-title {\n font-weight: 600;\n color: var(--text-color);\n }\n\n &-timestamp {\n flex-shrink: 0;\n color: var(--text-dark);\n font-size: var(--text-small-font-size, 0.85em);\n white-space: nowrap;\n }\n\n &-description {\n color: var(--text-dark);\n margin-top: 2px;\n }\n\n /* Right: markers + line on the right, content on the left */\n &-right &-item {\n flex-direction: row-reverse;\n text-align: right;\n }\n\n &-right &-header {\n flex-direction: row-reverse;\n }\n\n /* Alternate: two-column layout, entries alternating left/right of a centered line */\n &-alternate &-item {\n display: grid;\n grid-template-columns: 1fr auto 1fr;\n align-items: start;\n gap: var(--custom-timeline-gap);\n }\n\n &-alternate &-marker {\n grid-column: 2;\n grid-row: 1;\n }\n\n &-alternate &-content {\n grid-column: 1;\n grid-row: 1;\n text-align: right;\n }\n\n &-alternate &-header {\n flex-direction: row-reverse;\n }\n\n &-alternate &-item-right &-content {\n grid-column: 3;\n text-align: left;\n }\n\n &-alternate &-item-right &-header {\n flex-direction: row;\n }\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"timeline.module.mjs","names":[],"sources":["../../../../package/common/timeline/timeline.module.pcss"],"sourcesContent":[".timeline {\n /* Theme tokens resolved once, each with a built-in fallback. Set any of the\n public `--timeline-*` variables via ThemeProvider (theme-wide) or `style`\n (per instance) to override; unset ones fall back to the values below. */\n --custom-timeline-dot-size: var(--timeline-dot-size, 14px);\n --custom-timeline-dot-color: var(--timeline-dot-color, var(--primary-color));\n --custom-timeline-dot-border: var(--timeline-dot-border, var(--background));\n --custom-timeline-line-color: var(--timeline-line-color, var(--border-color));\n --custom-timeline-line-thickness: var(--timeline-line-thickness, 2px);\n --custom-timeline-gap: var(--timeline-gap, 16px);\n --custom-timeline-item-gap: var(--timeline-item-gap, 20px);\n --custom-timeline-icon-dot-size: var(--timeline-icon-dot-size, 28px);\n\n display: flex;\n flex-direction: column;\n color: var(--text-color);\n\n &-item {\n display: flex;\n gap: var(--custom-timeline-gap);\n border-radius: var(--default-border-radius);\n\n &:last-child &-connector {\n display: none;\n }\n }\n\n &-item-clickable {\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n transition: background-color 0.15s ease;\n margin: 0 -10px;\n padding: 0 10px;\n\n &:hover {\n background-color: var(--background-accent-light);\n }\n\n &:focus-visible {\n outline: 2px solid var(--focus-border-color, var(--primary-color));\n outline-offset: -2px;\n }\n }\n\n &-item-disabled {\n opacity: 0.5;\n }\n\n &-marker {\n display: flex;\n flex-direction: column;\n align-items: center;\n flex-shrink: 0;\n }\n\n &-dot {\n width: var(--custom-timeline-dot-size);\n height: var(--custom-timeline-dot-size);\n border-radius: 50%;\n background-color: var(--custom-timeline-dot-color);\n box-shadow: 0 0 0 3px var(--custom-timeline-dot-border);\n flex-shrink: 0;\n }\n\n /* Set by the component whenever the item has an icon — not inferred from the\n rendered markup (`:has(svg)`), which would miss a custom icon element that\n isn't an <svg>, e.g. an <img>. */\n &-dot-with-icon {\n width: var(--custom-timeline-icon-dot-size);\n height: var(--custom-timeline-icon-dot-size);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--text-on-primary);\n font-size: calc(var(--custom-timeline-icon-dot-size) * 0.5);\n }\n\n &-dot-primary {\n background-color: var(--primary-color);\n }\n\n &-dot-success {\n background-color: var(--success-color);\n }\n\n &-dot-warn {\n background-color: var(--warn-color);\n }\n\n &-dot-error {\n background-color: var(--error-color);\n }\n\n /* Set by the component when ANY item has an icon. Every marker is then as wide as the\n widest dot it could hold, so the connectors line up into one vertical spine and every\n content column starts at the same x. max(), because a consumer is free to set the icon\n dot smaller than the plain one. */\n &-with-icons &-marker {\n width: max(var(--custom-timeline-dot-size), var(--custom-timeline-icon-dot-size));\n }\n\n &-connector {\n flex: 1 1 auto;\n width: var(--custom-timeline-line-thickness);\n min-height: 12px;\n background-color: var(--custom-timeline-line-color);\n margin: 4px 0;\n }\n\n &-content {\n flex: 1 1 auto;\n min-width: 0;\n padding-bottom: var(--custom-timeline-item-gap);\n }\n\n &-header {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: 8px;\n }\n\n &-title {\n font-weight: 600;\n color: var(--text-color);\n }\n\n &-timestamp {\n flex-shrink: 0;\n color: var(--text-dark);\n font-size: var(--text-small-font-size, 0.85em);\n white-space: nowrap;\n }\n\n &-description {\n color: var(--text-dark);\n margin-top: 2px;\n }\n\n /* Right: markers + line on the right, content on the left */\n &-right &-item {\n flex-direction: row-reverse;\n text-align: right;\n }\n\n &-right &-header {\n flex-direction: row-reverse;\n }\n\n /* Alternate: two-column layout, entries alternating left/right of a centered line */\n &-alternate &-item {\n display: grid;\n grid-template-columns: 1fr auto 1fr;\n align-items: start;\n gap: var(--custom-timeline-gap);\n }\n\n &-alternate &-marker {\n grid-column: 2;\n grid-row: 1;\n }\n\n &-alternate &-content {\n grid-column: 1;\n grid-row: 1;\n text-align: right;\n }\n\n &-alternate &-header {\n flex-direction: row-reverse;\n }\n\n &-alternate &-item-right &-content {\n grid-column: 3;\n text-align: left;\n }\n\n &-alternate &-item-right &-header {\n flex-direction: row;\n }\n}\n"],"mappings":""}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{ButtonSize as t}from"../button/button.types.mjs";import n from"../button/button.mjs";import r from"../actionIcon/actionIcon.mjs";import"./timer.chime.mjs";import i from"./timer.module.mjs";import{forwardRef as a,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;function f(){return typeof window<`u`&&window.matchMedia?.(`(prefers-reduced-motion: reduce)`).matches===!0}function le(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}`}var p=a(function(a,p){let{durationSeconds:m,autoStart:h=!0,resetOnDurationChange:ue=!0,onTick:de,onComplete:fe,onStart:pe,onPause:me,onResume:he,onCancel:ge,onAddTime:_e,onRemoveTime:ve,showControls:g=!0,hideAddButton:ye=!1,hideRemoveButton:be=!1,hidePauseButton:xe=!1,hideCancelButton:Se=!1,adjustSeconds:_=30,maxSeconds:v,label:y,formatTime:Ce=le,size:we=`160px`,strokeWidth:b=10,counterClockwise:Te=!1,urgentThreshold:Ee=.1,urgentMinSeconds:De=3,pulseOnUrgent:Oe=!0,showRunningRipples:x=!1,playSoundOnComplete:ke=!1,soundUrl:S,soundVolume:C=.5,notifyOnComplete:w=!1,notificationTitle:Ae,notificationBody:je,className:Me,style:Ne,classNames:T,styles:E,...Pe}=e(`Timer`,a),D=m*1e3,[O,Fe]=c(h?`running`:`idle`),[k,Ie]=c(D),[Le,Re]=c(0),[A,j]=c([]),M=s(k),N=s(O),P=s(D),F=s(!1),I=s(!1),L=s(!1),R=s(0);function z(e){M.current=e,Ie(e)}function B(e){N.current=e,Fe(e)}function V(){Re(e=>e+1)}o(()=>{if(O!==`running`)return;let e=Date.now(),t=M.current,n=setInterval(()=>{let n=Math.max(0,t-(Date.now()-e));z(n),de?.(n),n<=0&&B(`completed`)},se);return()=>clearInterval(n)},[O,Le]),o(()=>{if(O===`completed`&&!F.current){if(F.current=!0,fe?.(),ke)try{let e=new Audio(S||`data:audio/wav;base64,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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANACUAKwAKAMr/kv+R/9n/TwCxALwAVwCs/xb/8/5p/0YAFgFfAeYA3f/N/lP+wP7s/zwB9QGiAV4Azv7O/ff9Rf8RAWACcQImASb/g/0s/WH+jACEAjADIALY/4v9gfxZ/bD/TAK/AzAD2gD2/Rb8S/yN/q4B/wMyBBkCyP4H/F77Ov2qANgDAgV3A/r/aPyz+tr7Tf87A34F0AR7AUH9bfqS+rD9JQKJBfsFLAOQ/qP6jPn1+6EADgXSBucERQBk++74RvrE/gYEMQeABkECs/zW+M74svx1AvwGygdeBIH+Wvm795b6bwAmBpwIbQa2AIP6NPeg+BX+rATSCD0IKgNK/FX3A/eU+50CVQibCawFmv4w+O71HvkWABwHXAoHCE0Bx/mJ9ez2Q/0sBWAKAgo0BAr87PU19Vj6nQKRCWkLFAfa/ib3KfSR95f/7gcQDLEJCQIv+fDzLfVO/IUF1wvNC1wF8fuf9GbzAPl2Aq8KMg2TCEH/PvZv8vL18v6cCLMNaAvoAr/4bPJn8zn7tgUzDZoNogYA/HDznPGR9ycCqwvxDiUKzv979cTwRfQq/iQJQg8oDegDdvgB8ZzxBvq/BXQOZg8BCDf8YfLY7wz2sQGDDKQQyAuBANz0Ku+M8j79hAm6EO4OCAVU+LDv0u+4+KEFlQ8rEXgJlfx08SDudfQWATgNRxJ5DVYBZfSm7cvwM/y+CRkStxBEBlv4fu4L7lH3WgWWEOgSAgsZ/avwduzO8lYAxg3WEzIPTQIU9DnsBu8J+88JXBN9EpsHifhr7Uvs1PXuBHMRmRSdDML9B/Dd6hzxdP8tDk8V8hBkA+zz5+pB7cT5uAmAFD8UCQnf+HrslepF9FsELBI6FkYOjv6J71npYu9y/mwOrha1EpcE6/Oz6X/rZfh6CYQV+RWLClv5revu6KbypAO/EsgX+Q99/zPv7eek7VH9hA7yF3cU5QUS9J7ow+nx9hUJZBamFx8M/PkF61fn/PDKAisTQBmzEYsABe+b5uTrE/x0DhcZNBZLB2H0q+cR6Gn1iQggF0QZwA3A+oTq1eVI79ABbxOeGm8TtgH/7mblJ+q9+jwOGxroF8YI1vTc5m3m0vPaB7YXzxpsD6f7Kupq5JDttwCME+EbKxX9AiDvUeRw6FD53Q39GpEZUgpw9TLm2uQv8gcHJRhEHB8Rrvz36Rrj1+uB/4ETBh3iFlsEae9e48Pm0PdYDbsbLBvsCy72ruVb44LwFAZtGKEd1RLS/e3p5+Ef6jL+TRMKHpIYzgXZ747iJOVA9q4MUhyzHJEND/dR5fPh0O4BBY0Y4h6LFBL/CurT4G7ozPzzEuweNxpTB27w4+GV46P04QvDHCUePQ8P+BzlpeAd7dIDhRgFID0WagBP6uDfxuZS+3MSqR/MG+cIJ/Fe4Rni/fLzCg0dfx/uEC75EOV032vriQJVGAgh5xfXAbvqEd8r5cj5zRFBIFAdhgoD8gHhteBR8eYJLh29IJ4SaPor5WLev+koAf4X6SGHGVYDTetm3qDjMfgFEbMgvh4tDP/yy+Bq36PvuwgoHd4hSxS6+23lcd0c6LT/gBelIhgb5QQC7OLdKeKR9hoQ/CAUINgNGfS94Dze9+13B/oc3yLwFSP91+Wj3IXmL/7dFjwjlxx/BtvshN3I4Or0EA8eIVAhgw9P9dfgLN1P7BsGpBy9I4sXnv5m5vrb/+Sd/BcWrCMCHiEI1O1P3YHfQPPpDRghbSIrEZ72GeE+3LHqqwQoHHgkGBkoABrnd9uL4wD7LxX1I1Ufxwnr7kHdVd6Y8agM6iBrI80SA/iC4XLbHukpA4YbDSWUGr4B8ecb2y7iXfknFBYkjSBvCx/wXN1J3fTvTwuUIEckZBR7+RHiy9qb55oBwRp8JfsbXQPp6Ofa6uC39wITDySoIRQNbPGe3V3cWe7hCRggACXuFQP7xOJK2ivmAADaGcMlSx0BBf/p2trB3xL2whHgI6Misg7P8gfelNvK7GEIdx+TJWcXl/yb4/DZ0ORf/tMY4iWAHqYGMuv22rfecfRqEIojfCNHEEb0l97v2knr0waxHv8lyxg0/pLkvdmP47v8rhfaJZgfSQh+7Drbzt3Y8v0ODSMyJM4RzfVL33Da2+k7BckdRSYZGtb/qeWz2WniGPttFqklkSDlCeHtpdsH3Urxfg1qIsMkRRNg9yPgGNqD6JsDwRxiJkwbegHc5tDZYeF4+RUVUSVpIXkLWO823GTcy+/wC6MhLiWoFP34HOHn2UPn9wGbG1gmYhwcAyroFtp54N/3pxPSJB0i/wzg8Ozc59te7lcKuSBxJfQVn/o04t/ZHuZUAFoaJSZaHbkEjumD2rTfUvYnEi0krCJ2DnTyxd2R2wbttgivH40lJhdE/Gnj/9kX5bP+/xjLJTAeTAYH6xbbE9/T9JgQZCMVI9gPEvTA3mLbx+sSB4cegCU8GOf9uORG2jHkGv2PF0kl4x7UB5DsztuX3mbz/Q54IlcjJRG29dvfXNui6mwFQx1MJTMZhf8f5rXabOOM+w0WoiRxH0sJJ+6q3ELeDfJaDWwhcSNXEl33E+F925vpygPmG+8kCRobAZvnStvL4gv6exTXI9kfrwrI76jdFN7N8LILQSBjI24TA/ll4sbbtOguAnMabCS8GqQCJ+kF3FDinPjdEugiGyD9C2/xxd4P3qfvCgr6Hi0jZhSk+s/jN9zv550A7RjDI0sbHgTB6uTc++FB9zYR2SE0IDINGfMA4DHenu5kCJkdzyI9FT38TuXO3E3nGf9YF/UitBuFBWbs5N3N4f71iw+rICYgSw7D9Fbhe9617cUGIxxLIvIVyv3e5ovd0eam/bUVBCL1G9YGEu4E38jh1fTeDWEf7x9FD2j2xOLt3u3sLwWZGqAhghZI/33obN575kj8ChTyIBAcDwjB70Pg6uHJ8zQM/R2RHx8QBvhH5IbfSeynA/4Y0CDtFrMAJupv30zmAPtaEsEfAhwrCW/xnOE04tzyjwqCHAsf1xCY+dzlRODL6y8CVxfdHzAXCQLX65LgRebT+agQdB7MGyoKGvMO46biEfL0CPMaYB5rERv7f+cm4XLrywCnFckeTBdHA4zt0+Fm5sL4+A4MHW4bCQu+9JXkP+Np8WYHVRmPHdgRjfwu6SriQOt+//ETlR1BF2kEQO8v46/m0PdNDY0b6RrFC1b2Lub94+bw5wWpF5scIBLp/eTqT+M260r+ORJFHA0XbgXx8KTkH+cA96sL+xk+Gl0M4PfW59/kifB9BPMVhhs/Ei3/nuyS5FXrM/2DENsasRZSBpvyL+a351L2FgpYGG4Z0AxY+Yrp5OVT8CkDNxRRGjcSVgBZ7vHlm+s7/NEOWRkuFhUHO/TM53ToyvWRCKcWehgdDbz6ResK50Xw7gF5Ev8YBxJiARHwaecI7GT7KQ3DF4UVswfM9XnpVeln9R8H7BRlF0INCPwG7U7oXvDPALwQkxevEU4CwvH26J3sr/qMCxwWtxQtCEz3MetZ6iv1wwUrEzAWPw05/cfurumg8M//BA8PFjARGANp85fqV+0f+v8JZxTFE4AIuPjy7H7rFvWABGcR3RQUDUz+hfAn6wnx8P5UDXYUihC+AwL1R+w27rX5hQioErESrAgM+rjuwuwq9VkDpA9wE8IMQf898rfsmfEz/rALzBLAD0AEivYD7jjvcvkgB+IQfRGwCEb7f/Ai7mX1UALlDesRSAwUAOzzWe5P8pv9GwoUEdEOmwT+98jvW/BW+dQFGA8sEIwIYvxD8pvvyfVoAS4MUhCnC8MAjPUM8CrzKP2YCFEPwA3PBFv5k/Gc8WL5pARPDcAOQAhg/QL0K/FT9qIAggqmDuEKTQEd98vxKPTc/CsHhw2PDNsEnvpf8/rylvmSA4oLPA3NBzz+t/XO8gP3AADlCOwM+AmxAZn4k/NH9bf81gW6C0ELvwTE+yj1cvTx+aACzQmiCzMH9f5f94H02PeE/1sHJwvsCO4B//lh9YX2u/ydBOwJ1wl8BMv87fYA9nT60QEbCPYJdAaJ//f4QvbQ+C7/5QVaCb8HBAJK+zH33/fm/IIDIghVCBEEsf2o+KP3HPslAXcGPAiRBff/e/oM+On5AP+IBIoHdQbyAXr8//hU+Tj9hgJgBr0GfwN0/lb6Vvnq+58A5QR2BosEPgDp+9z5Ivv5/kYDuQUQBbcBiv3H+t/6sv2tAagEEwXIAhL/9fsW+9v8PwBoA6kEZQNeAD39rvt3/Bv/IQLsA5EDVgF6/of8f/xS/vcA/gJaA+0Biv+A/eD87f0HAAMC1wIhAlUAdf5+/ef9ZP8cASUC/QHNAEb/O/4w/hf/ZwBlAZUB7wDb//X+sP4f//b/uAAEAcEAJQCO/0r/bv/U/zkAaQBXAB8A7v/f/+7/`);e.volume=C,e.play()?.catch(()=>{})}catch{}if(w&&typeof Notification<`u`&&Notification.permission===`granted`)try{new Notification(Ae??`Timer done`,{body:je??(typeof y==`string`?y:void 0)})}catch{}}O!==`completed`&&(F.current=!1)},[O]),o(()=>{if(!L.current){L.current=!0;return}let e=m*1e3;P.current=e,z(e),F.current=!1,V(),ue&&B(h?`running`:`idle`)},[m]),o(()=>{if(!x||O!==`running`||f())return;function e(){R.current+=1,j(e=>[...e,R.current])}e();let t=setInterval(e,ce);return()=>clearInterval(t)},[x,O]);function ze(e){j(t=>t.filter(t=>t!==e))}function Be(){w&&!I.current&&typeof Notification<`u`&&Notification.permission==="default"&&(I.current=!0,Notification.requestPermission().catch(()=>{}))}function H(){Be(),(N.current===`completed`||N.current===`cancelled`)&&(z(P.current),F.current=!1),V(),B(`running`),pe?.()}function U(){N.current===`running`&&(B(`paused`),me?.())}function W(){N.current===`paused`&&(V(),B(`running`),he?.())}function G(e){let t=v==null?1/0:v*1e3,n=Math.min(M.current+e*1e3,t);z(n),V(),_e?.(e,Math.round(n/1e3)),N.current===`completed`&&n>0&&(F.current=!1,B(`running`))}function K(e){let t=Math.max(0,M.current-e*1e3);z(t),V(),ve?.(e,Math.round(t/1e3)),t<=0&&N.current===`running`&&B(`completed`)}function q(){z(P.current),B(`cancelled`),ge?.()}function Ve(){z(P.current),F.current=!1,B(`idle`)}ee(p,()=>({start:H,pause:U,resume:W,addTime:G,removeTime:K,cancel:q,reset:Ve,getStatus:()=>N.current,getRemainingMs:()=>M.current}));let J=50-b/2,Y=te(()=>2*Math.PI*J,[J]),He=Y*(1-(P.current>0?Math.min(1,k/P.current):0)),X=Math.max(P.current*Ee,De*1e3),Z=O===`running`&&k<=X,Ue=Z&&k<=Math.min(5e3,X),Q=O===`paused`,We=g&&!ye,$=g&&!be,Ge=g&&!xe,Ke=O===`running`?re:ie,qe=O===`running`?`Pause`:Q?`Resume`:O===`idle`?`Start`:`Restart`,Je=O===`running`?U:Q?W:H,Ye=g&&!Se;return d(`div`,{...Pe,className:l(i.timer,Oe&&Z&&i.timerPulsing,Ue&&i.timerCritical,Me,T?.root),style:{"--timer-size":we,"--timer-stroke-width":`${b}px`,...Ne,...E?.root},children:[d(`div`,{className:l(i.timerRingWrapper,T?.ringWrapper),style:E?.ringWrapper,children:[A.length>0&&u(`div`,{className:l(i.timerRipples,T?.ripples),style:E?.ripples,children:A.map(e=>u(`span`,{className:l(i.timerRipple,T?.ripple),style:E?.ripple,onAnimationEnd:()=>ze(e)},e))}),d(`svg`,{className:l(i.timerRingSvg,T?.ringSvg),viewBox:`0 0 100 100`,style:E?.ringSvg,children:[u(`circle`,{className:l(i.timerRingTrack,T?.ringTrack),cx:`50`,cy:`50`,r:J,style:E?.ringTrack}),u(`circle`,{className:l(i.timerRingProgress,Z&&i.timerRingProgressUrgent,T?.ringProgress),cx:`50`,cy:`50`,r:J,strokeDasharray:Y,strokeDashoffset:He,style:{transition:Q?`none`:void 0,transform:Te?`rotate(-90deg)`:void 0,...E?.ringProgress}})]}),d(`div`,{className:l(i.timerDisplay,T?.display),style:E?.display,children:[u(`span`,{className:l(i.timerTime,T?.time),style:E?.time,children:Ce(k)}),y&&u(`span`,{className:l(i.timerLabel,T?.label),style:E?.label,children:y})]})]}),g&&d(`div`,{className:l(i.timerControls,T?.controls),style:E?.controls,children:[d(`div`,{className:i.timerControlsRow,children:[$&&u(r,{icon:ne,title:`Remove ${_}s`,onClick:()=>K(_),className:l(i.timerAdjustButton,T?.removeButton),style:E?.removeButton}),Ge&&u(n,{size:t.Small,icon:Ke,title:qe,onClick:Je,className:T?.pauseButton,style:E?.pauseButton}),We&&u(r,{icon:ae,title:`Add ${_}s`,onClick:()=>G(_),className:l(i.timerAdjustButton,T?.addButton),style:E?.addButton})]}),Ye&&u(r,{icon:oe,title:`Cancel timer`,onClick:q,className:l(i.timerCancelButton,T?.cancelButton),style:E?.cancelButton})]})]})});p.displayName=`Timer`;export{p as default};
|
|
1
|
+
import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{ButtonSize as t}from"../button/button.types.mjs";import n from"../button/button.mjs";import r from"../actionIcon/actionIcon.mjs";import"./timer.chime.mjs";import i from"./timer.module.mjs";import{forwardRef as a,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;function le(){return typeof window<`u`&&window.matchMedia?.(`(prefers-reduced-motion: reduce)`).matches===!0}function f(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}`}var p=a(function(a,p){let{durationSeconds:m,autoStart:h=!0,resetOnDurationChange:ue=!0,onTick:de,onComplete:fe,onStart:pe,onPause:me,onResume:he,onCancel:ge,onAddTime:_e,onRemoveTime:ve,showControls:g=!0,hideAddButton:ye=!1,hideRemoveButton:be=!1,hidePauseButton:xe=!1,hideCancelButton:Se=!1,adjustSeconds:_=30,maxSeconds:v,label:y,formatTime:Ce=f,size:b,strokeWidth:x=10,counterClockwise:we=!1,urgentThreshold:Te=.1,urgentMinSeconds:Ee=3,pulseOnUrgent:De=!0,showRunningRipples:S=!1,playSoundOnComplete:Oe=!1,soundUrl:ke,soundVolume:C=.5,notifyOnComplete:w=!1,notificationTitle:Ae,notificationBody:je,className:Me,style:Ne,classNames:T,styles:E,...Pe}=e(`Timer`,a),D=m*1e3,[O,Fe]=c(h?`running`:`idle`),[k,Ie]=c(D),[Le,Re]=c(0),[A,j]=c([]),M=s(k),N=s(O),P=s(D),F=s(!1),I=s(!1),L=s(!1),R=s(0);function z(e){M.current=e,Ie(e)}function B(e){N.current=e,Fe(e)}function V(){Re(e=>e+1)}o(()=>{if(O!==`running`)return;let e=Date.now(),t=M.current,n=setInterval(()=>{let n=Math.max(0,t-(Date.now()-e));z(n),de?.(n),n<=0&&B(`completed`)},se);return()=>clearInterval(n)},[O,Le]),o(()=>{if(O===`completed`&&!F.current){if(F.current=!0,fe?.(),Oe)try{let e=new Audio(ke||`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=C,e.play()?.catch(()=>{})}catch{}if(w&&typeof Notification<`u`&&Notification.permission===`granted`)try{new Notification(Ae??`Timer done`,{body:je??(typeof y==`string`?y:void 0)})}catch{}}O!==`completed`&&(F.current=!1)},[O]),o(()=>{if(!L.current){L.current=!0;return}let e=m*1e3;P.current=e,z(e),F.current=!1,V(),ue&&B(h?`running`:`idle`)},[m]),o(()=>{if(!S||O!==`running`||le())return;function e(){R.current+=1,j(e=>[...e,R.current])}e();let t=setInterval(e,ce);return()=>clearInterval(t)},[S,O]);function ze(e){j(t=>t.filter(t=>t!==e))}function Be(){w&&!I.current&&typeof Notification<`u`&&Notification.permission==="default"&&(I.current=!0,Notification.requestPermission().catch(()=>{}))}function H(){Be(),(N.current===`completed`||N.current===`cancelled`)&&(z(P.current),F.current=!1),V(),B(`running`),pe?.()}function U(){N.current===`running`&&(B(`paused`),me?.())}function W(){N.current===`paused`&&(V(),B(`running`),he?.())}function G(e){let t=v==null?1/0:v*1e3,n=Math.min(M.current+e*1e3,t);z(n),V(),_e?.(e,Math.round(n/1e3)),N.current===`completed`&&n>0&&(F.current=!1,B(`running`))}function K(e){let t=Math.max(0,M.current-e*1e3);z(t),V(),ve?.(e,Math.round(t/1e3)),t<=0&&N.current===`running`&&B(`completed`)}function q(){z(P.current),B(`cancelled`),ge?.()}function Ve(){z(P.current),F.current=!1,B(`idle`)}ee(p,()=>({start:H,pause:U,resume:W,addTime:G,removeTime:K,cancel:q,reset:Ve,getStatus:()=>N.current,getRemainingMs:()=>M.current}));let J=50-x/2,Y=te(()=>2*Math.PI*J,[J]),He=Y*(1-(P.current>0?Math.min(1,k/P.current):0)),X=Math.max(P.current*Te,Ee*1e3),Z=O===`running`&&k<=X,Ue=Z&&k<=Math.min(5e3,X),Q=O===`paused`,We=g&&!ye,$=g&&!be,Ge=g&&!xe,Ke=O===`running`?re:ie,qe=O===`running`?`Pause`:Q?`Resume`:O===`idle`?`Start`:`Restart`,Je=O===`running`?U:Q?W:H,Ye=g&&!Se;return d(`div`,{...Pe,className:l(i.timer,De&&Z&&i.timerPulsing,Ue&&i.timerCritical,Me,T?.root),style:{...b?{"--timer-size":b}:null,"--timer-stroke-width":`${x}px`,...Ne,...E?.root},children:[d(`div`,{className:l(i.timerRingWrapper,T?.ringWrapper),style:E?.ringWrapper,children:[A.length>0&&u(`div`,{className:l(i.timerRipples,T?.ripples),style:E?.ripples,children:A.map(e=>u(`span`,{className:l(i.timerRipple,T?.ripple),style:E?.ripple,onAnimationEnd:()=>ze(e)},e))}),d(`svg`,{className:l(i.timerRingSvg,T?.ringSvg),viewBox:`0 0 100 100`,style:E?.ringSvg,children:[u(`circle`,{className:l(i.timerRingTrack,T?.ringTrack),cx:`50`,cy:`50`,r:J,style:E?.ringTrack}),u(`circle`,{className:l(i.timerRingProgress,Z&&i.timerRingProgressUrgent,T?.ringProgress),cx:`50`,cy:`50`,r:J,strokeDasharray:Y,strokeDashoffset:He,style:{transition:Q?`none`:void 0,transform:we?`rotate(-90deg)`:void 0,...E?.ringProgress}})]}),d(`div`,{className:l(i.timerDisplay,T?.display),style:E?.display,children:[u(`span`,{className:l(i.timerTime,T?.time),style:E?.time,children:Ce(k)}),y&&u(`span`,{className:l(i.timerLabel,T?.label),style:E?.label,children:y})]})]}),g&&d(`div`,{className:l(i.timerControls,T?.controls),style:E?.controls,children:[d(`div`,{className:i.timerControlsRow,children:[$&&u(r,{icon:ne,title:`Remove ${_}s`,onClick:()=>K(_),className:l(i.timerAdjustButton,T?.removeButton),style:E?.removeButton}),Ge&&u(n,{size:t.Small,icon:Ke,title:qe,onClick:Je,className:T?.pauseButton,style:E?.pauseButton}),We&&u(r,{icon:ae,title:`Add ${_}s`,onClick:()=>G(_),className:l(i.timerAdjustButton,T?.addButton),style:E?.addButton})]}),Ye&&u(r,{icon:oe,title:`Cancel timer`,onClick:q,className:l(i.timerCancelButton,T?.cancelButton),style:E?.cancelButton})]})]})});p.displayName=`Timer`;export{p as default};
|
|
2
2
|
//# sourceMappingURL=timer.mjs.map
|