@ahrowe/ui 0.29.1 → 0.30.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.
Files changed (93) hide show
  1. package/dist/esm/common/accordion/accordion.mjs +1 -1
  2. package/dist/esm/common/accordion/accordion.mjs.map +1 -1
  3. package/dist/esm/common/accordion/accordion.module.mjs.map +1 -1
  4. package/dist/esm/common/accordion/accordion.plain.module.mjs.map +1 -1
  5. package/dist/esm/common/accordion/accordion.primary.module.mjs.map +1 -1
  6. package/dist/esm/common/alert/alert.module.mjs.map +1 -1
  7. package/dist/esm/common/badge/badge.module.mjs.map +1 -1
  8. package/dist/esm/common/bodyEnd/bodyEnd.mjs +1 -1
  9. package/dist/esm/common/bodyEnd/bodyEnd.mjs.map +1 -1
  10. package/dist/esm/common/button/button.module.mjs +1 -1
  11. package/dist/esm/common/button/button.module.mjs.map +1 -1
  12. package/dist/esm/common/card/card.module.mjs.map +1 -1
  13. package/dist/esm/common/checkbox/checkbox.mjs +1 -1
  14. package/dist/esm/common/checkbox/checkbox.mjs.map +1 -1
  15. package/dist/esm/common/checkbox/checkbox.module.mjs +1 -1
  16. package/dist/esm/common/checkbox/checkbox.module.mjs.map +1 -1
  17. package/dist/esm/common/chip/chip.module.mjs.map +1 -1
  18. package/dist/esm/common/colorPicker/colorPicker.mjs +1 -1
  19. package/dist/esm/common/colorPicker/colorPicker.mjs.map +1 -1
  20. package/dist/esm/common/colorPicker/colorPicker.module.mjs.map +1 -1
  21. package/dist/esm/common/colorPicker/toHex.mjs +2 -0
  22. package/dist/esm/common/colorPicker/toHex.mjs.map +1 -0
  23. package/dist/esm/common/datePicker/datePicker.mjs +1 -1
  24. package/dist/esm/common/datePicker/datePicker.mjs.map +1 -1
  25. package/dist/esm/common/fab/components/fabBase/fabBase.mjs +1 -1
  26. package/dist/esm/common/fab/components/fabBase/fabBase.mjs.map +1 -1
  27. package/dist/esm/common/fab/components/fabBase/fabBase.module.mjs.map +1 -1
  28. package/dist/esm/common/fab/fab.module.mjs.map +1 -1
  29. package/dist/esm/common/iconPicker/iconPicker.module.mjs.map +1 -1
  30. package/dist/esm/common/input/input.mjs +1 -1
  31. package/dist/esm/common/input/input.mjs.map +1 -1
  32. package/dist/esm/common/input/input.module.mjs +1 -1
  33. package/dist/esm/common/input/input.module.mjs.map +1 -1
  34. package/dist/esm/common/inputDropdown/inputDropdown.mjs +1 -1
  35. package/dist/esm/common/inputDropdown/inputDropdown.mjs.map +1 -1
  36. package/dist/esm/common/kanbanBoard/kanbanBoard.module.mjs.map +1 -1
  37. package/dist/esm/common/optionPicker/optionPicker.module.mjs.map +1 -1
  38. package/dist/esm/common/otpInput/otpInput.module.mjs.map +1 -1
  39. package/dist/esm/common/pagination/pagination.module.mjs.map +1 -1
  40. package/dist/esm/common/progressBar/progressBar.module.mjs +1 -1
  41. package/dist/esm/common/progressBar/progressBar.module.mjs.map +1 -1
  42. package/dist/esm/common/radioGroup/radioGroup.mjs +1 -1
  43. package/dist/esm/common/radioGroup/radioGroup.mjs.map +1 -1
  44. package/dist/esm/common/radioGroup/radioGroup.module.mjs.map +1 -1
  45. package/dist/esm/common/rating/rating.module.mjs.map +1 -1
  46. package/dist/esm/common/searchInput/searchInput.mjs +1 -1
  47. package/dist/esm/common/searchInput/searchInput.mjs.map +1 -1
  48. package/dist/esm/common/slider/slider.mjs +1 -1
  49. package/dist/esm/common/slider/slider.mjs.map +1 -1
  50. package/dist/esm/common/slider/slider.module.mjs.map +1 -1
  51. package/dist/esm/common/switch/switch.module.mjs.map +1 -1
  52. package/dist/esm/common/tabHeader/tabHeader.module.mjs.map +1 -1
  53. package/dist/esm/common/themeProvider/theme.module.mjs.map +1 -1
  54. package/dist/esm/common/themeProvider/themeProvider.mjs +1 -1
  55. package/dist/esm/common/themeProvider/themeProvider.mjs.map +1 -1
  56. package/dist/esm/common/themeProvider/themeVariablesContext.mjs +2 -0
  57. package/dist/esm/common/themeProvider/themeVariablesContext.mjs.map +1 -0
  58. package/dist/esm/common/timeInput/timeInput.mjs +1 -1
  59. package/dist/esm/common/timeInput/timeInput.mjs.map +1 -1
  60. package/dist/esm/common/timeline/timeline.mjs +1 -1
  61. package/dist/esm/common/timeline/timeline.mjs.map +1 -1
  62. package/dist/esm/common/timeline/timeline.module.mjs +1 -1
  63. package/dist/esm/common/timeline/timeline.module.mjs.map +1 -1
  64. package/dist/esm/common/timer/timer.mjs +1 -1
  65. package/dist/esm/common/timer/timer.mjs.map +1 -1
  66. package/dist/esm/common/timer/timer.module.mjs.map +1 -1
  67. package/dist/esm/common/toast/toast.module.mjs.map +1 -1
  68. package/dist/esm/common/tooltip/tooltip.module.mjs.map +1 -1
  69. package/dist/index.cjs +3 -3
  70. package/dist/index.cjs.map +1 -1
  71. package/dist/style.css +1 -1
  72. package/dist/types/common/colorPicker/toHex.d.ts +11 -0
  73. package/dist/types/common/themeProvider/theme.types.d.ts +75 -3
  74. package/dist/types/common/themeProvider/themeVariablesContext.d.ts +11 -0
  75. package/docs/Accordion.md +4 -0
  76. package/docs/Alert.md +4 -0
  77. package/docs/BodyEnd.md +3 -0
  78. package/docs/Button.md +6 -0
  79. package/docs/Card.md +6 -0
  80. package/docs/Checkbox.md +8 -0
  81. package/docs/ColorPicker.md +11 -1
  82. package/docs/Fab.md +16 -0
  83. package/docs/IconPicker.md +8 -0
  84. package/docs/Input.md +12 -0
  85. package/docs/OtpInput.md +4 -0
  86. package/docs/RadioGroup.md +6 -0
  87. package/docs/Rating.md +5 -0
  88. package/docs/Slider.md +6 -2
  89. package/docs/ThemeProvider.md +89 -1
  90. package/docs/Timer.md +7 -1
  91. package/docs/Toast.md +6 -0
  92. package/docs/Tooltip.md +15 -0
  93. 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 type={InputType.Search} label={label} placeholder={placeholder} value={value} onChange={handleChange} />\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,CAAO,KAAM,EAAU,OAAe,QAAoB,cAAoB,QAAO,SAAU,CAAe,CAAA,EAC7G,GACC,EAAC,IAAD,CAAG,UAAW,EAAO,YAArB,SAAA,CACG,EAAY,IAAE,IAAgB,EAAI,SAAW,SAC7C,CAEF,CAAA,CAAA,GAET"}
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:h=!1,formatValue:g,size:_=`18px`,tabIndex:v=0,className:ee,style:te,classNames:y,styles:b,"aria-label":x,range:S,value:C,defaultValue:ne,onChange:re,onChangeEnd:ie,minRange:w=0,thumbLabels:T,...E}=l,D=re,O=ie,k=S===!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=C!==void 0,[B,V]=i(()=>L(ne)),H=z?L(C):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]-w]:[t[0]+w,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=>g?g(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":x,"aria-disabled":p||void 0}:{...$(0),"aria-label":x,tabIndex:p?-1:v};return o(`div`,{...E,...fe,ref:j,className:a(e.slider,p&&e.sliderDisabled,ae&&e.sliderDragging,Z&&e.sliderHasMarkLabels,ee,y?.root),style:{"--slider-thumb-size":_,...te,...b?.root},onPointerDown:ce,onPointerMove:le,onPointerUp:ue,onKeyDown:k?void 0:e=>J(e,0),children:s(`div`,{ref:A,className:a(e.sliderTrack,y?.track),style:b?.track,children:[o(`div`,{className:a(e.sliderRange,y?.range),style:{...de,...b?.range}}),m?.map(n=>{let r=X(n.value);return s(t.Fragment,{children:[o(`span`,{className:a(e.sliderMark,y?.mark),style:{left:r,...b?.mark}}),n.label!=null&&o(`span`,{className:a(e.sliderMarkLabel,y?.markLabel),style:{left:r,...b?.markLabel},children:n.label})]},n.value)}),H.map((t,n)=>o(`div`,{ref:e=>{M.current[n]=e},className:a(e.sliderThumb,y?.thumb),style:{left:X(t),...b?.thumb},...k?{...$(n),"aria-label":T?.[n]??(n===0?`From`:`To`),tabIndex:p?-1:v,onKeyDown:e=>J(e,n)}:{},children:h&&o(`span`,{className:a(e.sliderValue,y?.value),style:b?.value,children:Q(t)})},n))]})})}export{l as default};
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":"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"}
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, 18px);\n --custom-slider-track-height: var(--slider-track-height, 6px);\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 4px 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: 22px;\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 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: 3px;\n height: 3px;\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 &-value {\n position: absolute;\n bottom: calc(100% + 8px);\n left: 50%;\n transform: translateX(-50%);\n padding: 2px 8px;\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
+ {"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{defaultTheme as e}from"./defaultTheme.mjs";import t from"./theme.module.mjs";import n,{Component as r}from"react";import i from"classnames";import{jsx as a}from"react/jsx-runtime";var o=class extends r{constructor(...t){super(...t),this.state={resolvedVariables:{},colorFadeActive:!1,currentThemeColor:null},this.colorFadeTimeout=null,this.wrapperRef=n.createRef(),this.themeColorMeta=null,this.createdThemeColorMeta=!1,this.applyTheme=t=>{let n=this.props.themes??[e],r=n.find(e=>!e.baseThemeId)??n[0],i=r?r.variables:{},a=n.find(e=>e.id===t),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(t){let n=(this.props.themes??[e]).find(e=>e.id===t);return n?[...n.baseThemeId?this.resolveChain(n.baseThemeId):[],n.variables]:[]}render(){let{children:e}=this.props,{resolvedVariables:n,colorFadeActive:r}=this.state;return a(`div`,{ref:this.wrapperRef,id:`themeProvider`,className:i(t.themeRoot,r&&t.colorFade),style:n,children:e})}};export{o as default};
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}\n </div>\n );\n }\n}\n\nexport default ThemeProvider;\n"],"mappings":"2LAmBA,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,EAEN,UACE,CAAA,CAET,CACF"}
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,2 @@
1
+ import{createContext as e}from"react";var t=e(null);export{t as ThemeVariablesContext};
2
+ //# sourceMappingURL=themeVariablesContext.mjs.map
@@ -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,CAChB,OACE,EAAC,MAAD,CACE,GAAI,EACJ,UAAW,EACT,EAAO,SACP,EACG,EAAO,eAAgB,IAAc,EAAkB,OACvD,EAAO,mBAAoB,IAAc,EAAkB,SAC9D,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
+ {"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-connector_VuXnH`,p=`timeline-content_K4Ztg`,m=`timeline-header_xr4Tw`,h=`timeline-title_MZ26k`,g=`timeline-timestamp_-0w-N`,_=`timeline-description_WcWIu`,v=`timeline-right_fZEKn`,y=`timeline-alternate_Kv9LY`,b=`timeline-item-right_s5ELB`,x={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-connector":`timeline-connector_VuXnH`,timelineConnector:f,"timeline-content":`timeline-content_K4Ztg`,timelineContent:p,"timeline-header":`timeline-header_xr4Tw`,timelineHeader:m,"timeline-title":`timeline-title_MZ26k`,timelineTitle:h,"timeline-timestamp":`timeline-timestamp_-0w-N`,timelineTimestamp:g,"timeline-description":`timeline-description_WcWIu`,timelineDescription:_,"timeline-right":`timeline-right_fZEKn`,timelineRight:v,"timeline-alternate":`timeline-alternate_Kv9LY`,timelineAlternate:y,"timeline-item-right":`timeline-item-right_s5ELB`,timelineItemRight:b};export{x as default,e as timeline,y as timelineAlternate,f as timelineConnector,p as timelineContent,_ as timelineDescription,o as timelineDot,d as timelineDotError,c as timelineDotPrimary,l as timelineDotSuccess,u as timelineDotWarn,s as timelineDotWithIcon,m as timelineHeader,t as timelineItem,r as timelineItemClickable,n as timelineItemConnector,i as timelineItemDisabled,b as timelineItemRight,a as timelineMarker,v as timelineRight,g as timelineTimestamp,h as timelineTitle};
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+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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(!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,UklGRkYeAABXQVZFZm10IBAAAAABAAEAESsAACJWAAACABAAZGF0YSIeAAAAAAkAIAA4AEQANwAPANH/jv9b/07/cf/F/zkAsAAJAScB+QCCANv/K/+h/mX+j/4d//P/3QChAQkC8QFZAV0AOP80/pb9i/0g/jj/kgDaAbsC9gJzAkwBwv82/gz9k/zz/Bz+y/+ZARMD1QOoA44CxQC6/u782PvD+778kv7SAO8CYQTGBPwDLALE/1j9hfvD+kz7Bf2J/zwCcgSbBWUF1QNGAVX+vPsk+vj5TPvU/fYA7QP6BZYGkAUjA+D/k/wP+vj4nPna+y3/xQK+BVkHKActBeABC/6h+nz4LPjN+QD9AAHTBIQHYggvBy4EFgDn+6v4NPfm9576uP4zA/YGDAnsCJUGkgLc/Zz54vZh9kL4FfzvAKAF/AgqCtYITQVmAFX7W/d49Sv2Ufkq/ocDFgizCrIKCQhaA8f9sPhY9Zr0rfYW+8QAUwZiCuoLgwp9BtAA3voh9sjzb/T194T9wAMgCUwMdQyJCTgEzv3d9+Dz2fIR9QT6fwDsBrMLoQ00DL4HUgGC+v30JPKy8o32yPzeAxAK1A01DhILKwXu/ST3evIf8W/z4PghAGsH7wxMD+YNDQnrAUH68fOP8PjwGfX2++ED6ApKD+4PowwxBin+hfYq8W/vyfGs96r/zgcTDusQmQ9pCpwCGvr+8gvvQu+d8xD7ygOkC60QoBE5DkcHff4C9u/vy+0i8Gr2HP8WCCAPeRJIEc8LYgMP+iXyme2S7RnyF/qYA0YM+hFHE9IPbgjp/pn1zO407HzuHPV3/kIIEhD3E/MSPg07BB/6ZvE87OvrkPAN+U4DzQwxE+EUbBGjCW3/TfXC7a7q2ezD87z9UwjrEGEVlhS0DigFSfrD8PTqT+oF7/P36gI4DVAUbhYEE+QKCAAc9dLsOek862Hy7vxKCKkRuBYxFi8QJgaM+jzww+nA6Hnty/ZvAocNVhXqF5kULwy5AAf1/OvY56Xp+vAM/CYISxL4F8AXrBE0B+j60O+r6EDn7+uY9d0Bug1BFlQZKRaDDX0BDPVB64vmGOiN7xr76AfREiAZQxkpE08IXPuB76zn0OVo6lr0NQHSDRIXqhqxF90OVAIs9aPqVeWX5h/uGPqSBzsTMBq2GqUUdgnn+07vx+Zy5OfoFPN6AM4NxxfrGzAZOxA8A2b1Ieo35CPlsOwI+SMHiBMmGxgcHRanCof8Nu/+5SnjbufH8av/sA1gGBUdohqbETQEufW76TLjvuND6+z3nga5EwEcaB2OF+ELPP0671Hl9eH/5XfwzP53DdwYJx4HHPsSOgUk9nLpR+Jr4tvpx/YDBs4TwRyjHvcYIA0D/lnvwOTY4J3kJe/d/SYNOxkgH1wdWRRLBqb2Rul34SvheeiZ9VMFxxNkHcgfVhpjDtz+ku9N5NTfSOPT7eD8vAx9Gf4fnx6yFWYHPvc26cPg/98f52b0kQSlE+od1SCpG6gPxP/l7/bj6t4D4oPs1/s7DKMZwSDPHwUXiQjr90HpLODq3tDlL/O9A2kTVB7KIe0c7RC6AFDwveMa3tHgOOvF+qMLrBlnIeogTxiyCar4aemy3+3djeT18doCExOfHqUiIh4vErsB0/Cg42bdsd/06ar5+AqZGfEh7iGPGd8Ke/mr6VXfCN1Z473w6QGkEs4eZCNEH20TxwJr8aHjz9yn3rjoivg5CmoZXSLbIsIaDgxb+gbqFt8+3DXih+/sAB4S3x4IJFIgpBTbAxnyvuNV3LTdh+dm92kJIBmrIq4j5xs8DUr7e+r03o/bJOFV7uX/ghHTHpAkSyHSFfQE2fL24/jb2Nxj5kD2iQi8GNwiZyT7HGgORPwH6/De/Nom4Crt1v7QEKoe+SQuIvUWEgar80rkudsW3E3lG/WbB0AY7yIFJfwdjw9I/anrCd+G2j3fCOzC/QwQZh5GJfgiDBgxB430uOSY22/bSOT486EGqxfkIoYl6h6vEFX+Yew/3y3abN7x6qn8Ng8HHnQlqCMTGU8IffU+5ZXb49pW49nynQUBF7wi6yXCH8YRZ/8s7ZHf8tmz3efpjvtQDo0dhCU+JAsabAl59t3lsNtz2nfiwvGQBEEWeCIyJoQg0xJ+AAju/t/W2RPd7Oh0+lwN+hx2Jbkk8BqDCn/3kubo2yHaruGz8H4DbhUXIlsmLSHSE5YB9e6G4NfZjtwB6Fz5WwxPHEslFyXAG5QLjvhc5z3c7Nn84K/vaAKJFJshZia8IcMUrgLv7ybh9tkl3CjnSfhRC44bAiVYJXwcnAyi+TrortzU2WLguO5QAZMTBCFTJjEipBXDA/bw3+E02tjbY+Y99z4KtxqcJHslIB2ZDbv6Kuk63dvZ4t/Q7TgAkBJUICEmiiJyFtQECPKu4o7aqNu05Tn2JQnNGRokgSWsHYoO1fsp6uHdANp83/jsIv+AEY0f0iXHIiwX3gUh85LjBtuV2xzlQPUHCNEYfCNpJR8ebA/v/DfroN5D2jHfMuwR/mYQrh5mJeci0RfgBkH0iuSZ26DbnORU9OgGxRfFIjIldx49EAf+Uux436TaA9+B6wf9RA+7Hd0k6iJfGNcHZfWU5Ujcyds15HbzyQWrFvQh3iS0Hv0QG/927WfgItvy3uTqBfwcDrQcOCTPItUYwQiL9q7mEd0Q3OnjqfKtBIUVCyFsJNUeqREoAKPuauG92/7eXuoO++8Mmxt3I5YiMhmdCbD31efz3XXcuOPt8ZUDVBQMIN0j2R4/EiwB1u+B4nPcJ9/w6SP6wAtzGp0iPyJ0GWkK1PgK6e3e+Nyi40bxgwIbE/geMiPAHr8SJgIN8anjRd1v35vpRvmSCjwZqiHLIZwZIwvz+Ujq/d+X3arjs/B6AdwR0R1qIooeJxMUA0by4uQw3tPfYel6+GYJ+RefIDohpxnJCwv7j+si4VLezuM28HsAmBCYHIghNh52E/MDf/Mo5jTfVeBB6cD3PgisFn4fjCCXGVoMG/zb7FniKd8P5NLviP9TD1AbjSDFHawTwgS29HrnT+D04DzpGPcdB1cVSR7BH2oZ1Qwh/Szuo+Mb4G3khu+k/g4O+Rl5HzcdxhN/Bej11+iB4bDhVOmG9gQG/BMAHdweHxk5DRr+fu/75Cbh6eRT79D9zAyXGE0ejBzGEyoGFPc76sbih+KI6Qr29gSeEqcb3R24GIQNBf/Q8GLmSeKB5TzvDv2OCysXDR3EG6kTvwY3+KXrHuR549nppfX0Az0RPhrEHDUYtg3h/x/y1OeC4zbmP+9e/FcKuBW4G+IacRM/B0/5Eu2H5YXkRupZ9QAD3Q/IGJMblBfNDaoAavNP6dHkB+de78T7KAk/FFEa5RkcE6cHXPqB7v/mquXQ6ib1HAKADkcXTBrYFskNYQGu9NLqNObz55nvP/sECMIS2RjOGKoS9wda++/vhOjn5nbrDfVKASgNvRXwGAAWqg0DAur1Wuyp5/no8O/R+uwGRRFTF58XHRIuCEj8W/EU6jnoOOwO9YoA1gsrFIEXDRVvDY8CG/fl7S7pGOpj8Hv64gXID8AVWRZzEUsIJf3B8q3roOkV7Sv14P+NCpUSARYAFBkNBAM/+HHvwepP6/LwP/rpBE4OIxT9FK4QTQju/SH0TO0a6w3uZPVL/08J+xBwFNsSpwxhA1X5/PBg7J3snPEc+gEE2gx9Eo0Tzw80CKP+d/Xw7qXsHe+39c3+HghhD9ISnhEZDKUDW/qD8gnuAO5i8hT6LANtC9EQCxLVDgEIQv/C9pfwP+5H8Cf2Z/77BskNKBFLEG8LzwNP+wX0u+9370LzJvpsAgkKIQ94EMINsgfK/wH4PfLm74fxsfYZ/ukFNAx0D+MOqwrgAzD8gPVy8f/wO/RT+sEBsAhuDdYOlwxHBzsAMfni85nx3vJX9+b96ASmCrkNZw3NCdUD/Pzx9i3zmPJO9Zz6LgFlB7wLJw1WC8IGkgBQ+oP1VfNI9Bf4zP37Ax4J+AvaC9YIsAOy/Vb46vRA9Hj2//qyACgGDAptC/8JIgbRAF37HvcZ9cb18fjN/SIDoQc0Cj4KxgdwA1L+rvmn9vT1uPd9+08A/ARgCKsJlAhnBfUAV/yw+OH2VPfk+ej9XwIwBm4IkwifBhUD2f73+mD4svcO+Rb8BgDjA7sG4gcWB5ME/gA8/Tj6rfjy+O/6H/60Ac0EqgbdBmMFoAJI/y/8Ffp4+Xb6yfzX/90CHwUUBogFpwPtAAv+tPt4+p36Efxw/iABeQPoBB0FEQQQAp3/VP3D+0X78fuV/cH/7AGNA0QE7AOjAsIAwv4i/UP8VPxI/dv+pgA2Ai0DVQOtAmYB2P9l/mf9Fv18/Xn+x/8RAQgCdAJCAogBfABi/4D+Cv4U/pP+Yf9FAAYBeAGHATcBpAD5/2H/Af/o/hX/dP/n/04AkQClAI4AWQAbAOj/zf/L/9v/8v8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANACUAKwAKAMr/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