@ahrowe/ui 0.15.0 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/common/floatingMenu/useFloatingPosition.mjs +1 -1
- package/dist/esm/common/floatingMenu/useFloatingPosition.mjs.map +1 -1
- package/dist/esm/common/input/input.mjs +1 -1
- package/dist/esm/common/input/input.mjs.map +1 -1
- package/dist/esm/common/numberInput/numberInput.mjs +1 -1
- package/dist/esm/common/numberInput/numberInput.mjs.map +1 -1
- package/dist/esm/common/timeline/timeline.module.mjs.map +1 -1
- package/dist/index.cjs +6 -6
- package/dist/index.cjs.map +1 -1
- package/dist/style.css +1 -1
- package/docs/Dropdown.md +1 -1
- package/docs/FloatingMenu.md +2 -0
- package/docs/Input.md +25 -2
- package/docs/InputDropdown.md +1 -1
- package/package.json +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{getScrollableAncestors as e,isHiddenByAnyAncestor as t}from"../utils/scrollAncestors.mjs";import{useLayoutEffect as n}from"react";function r({isOpen:r,triggerRef:i,anchorRef:a,panelRef:o,flipClassName:s,placement:c=`bottom`}){n(()=>{if(!r)return;let n,l;function u(){let r=i.current,d=a.current;if(!r||!d){n=requestAnimationFrame(u);return}let f=e(r);function p(){let e=r.getBoundingClientRect(),n=o.current?.offsetHeight??0,i=window.innerHeight-e.bottom,a=e.top,l=c===`top`?a:i,u=l<n&&(c===`top`?i:a)>l,p=c===`top`?!u:u;d.classList.toggle(s,u),d.style.top=`${p?e.top-d.offsetHeight:e.bottom}px`,d.style.left=`${e.left}px`,d.style.visibility=t(e,f)?`hidden
|
|
1
|
+
import{getScrollableAncestors as e,isHiddenByAnyAncestor as t}from"../utils/scrollAncestors.mjs";import{useLayoutEffect as n}from"react";function r({isOpen:r,triggerRef:i,anchorRef:a,panelRef:o,flipClassName:s,placement:c=`bottom`}){n(()=>{if(!r)return;let n,l;function u(){let r=i.current,d=a.current;if(!r||!d){n=requestAnimationFrame(u);return}let f=e(r);function p(){let e=r.getBoundingClientRect(),n=o.current?.offsetHeight??0,i=window.innerHeight-e.bottom,a=e.top,l=c===`top`?a:i,u=l<n&&(c===`top`?i:a)>l,p=c===`top`?!u:u;d.classList.toggle(s,u),d.style.top=`${p?e.top-d.offsetHeight:e.bottom}px`,d.style.left=`${e.left}px`,d.style.visibility=t(e,f)?`hidden`:``;let m=o.current;m&&!h.has(m)&&g()}let m=new ResizeObserver(()=>p()),h=new Set;function g(){[d,o.current].forEach(e=>{!e||h.has(e)||(h.add(e),m.observe(e))})}p();let _=[window,...f];_.forEach(e=>e.addEventListener(`scroll`,p,{passive:!0})),window.addEventListener(`resize`,p),l=()=>{_.forEach(e=>e.removeEventListener(`scroll`,p)),window.removeEventListener(`resize`,p),m.disconnect()}}return u(),()=>{n!==void 0&&cancelAnimationFrame(n),l?.()}},[r,i,a,o,s,c])}export{r as useFloatingPosition};
|
|
2
2
|
//# sourceMappingURL=useFloatingPosition.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFloatingPosition.mjs","names":[],"sources":["../../../../package/common/floatingMenu/useFloatingPosition.ts"],"sourcesContent":["import { useLayoutEffect, type RefObject } from 'react';\nimport { getScrollableAncestors, isHiddenByAnyAncestor } from 'components/common/utils/scrollAncestors';\n\nexport interface UseFloatingPositionArgs {\n isOpen: boolean;\n /** The element the popup is anchored to. */\n triggerRef: RefObject<HTMLElement | null>;\n /** The `position: fixed` element that gets `top`/`left`/`visibility` written to it directly. */\n anchorRef: RefObject<HTMLElement | null>;\n /** The visible panel whose height decides whether there's room to render on the preferred side. */\n panelRef: RefObject<HTMLElement | null>;\n /** Class toggled on `anchorRef` when flipped to the non-preferred side. */\n flipClassName: string;\n /** Preferred side relative to the trigger (default `'bottom'`) — flips to the other side when there's no room. */\n placement?: 'top' | 'bottom';\n}\n\n/**\n * Keeps a portaled, `position: fixed` popup anchored to a trigger element: tracks the\n * trigger across scroll/resize on every real scrolling ancestor, flips above the trigger\n * when there's no room below, and hides (not closes) the popup when the trigger itself\n * scrolls behind a clipping ancestor — matching Floating UI's autoUpdate + hide middleware.\n *\n * Position/visibility are written straight to the DOM via refs, not through React state:\n * going through setState -> re-render -> commit adds a round-trip that lags behind the\n * browser's own scroll painting by at least a frame.\n */\nexport function useFloatingPosition({ isOpen, triggerRef, anchorRef, panelRef, flipClassName, placement = 'bottom' }: UseFloatingPositionArgs) {\n useLayoutEffect(() => {\n if (!isOpen) return;\n\n let rafId: number | undefined;\n let teardown: (() => void) | undefined;\n\n // The anchor/trigger may not be mounted yet on the very first invocation of this\n // effect: a portal target (e.g. BodyEnd's `#bodyEnd` div) can still be missing on\n // the initial render, in which case the portaled content — and this ref — commits\n // one render later. Since refs never change identity, that later commit doesn't\n // re-trigger this effect on its own, so retry on the next frame until it's there.\n function trySetup() {\n const trigger = triggerRef.current;\n const anchor = anchorRef.current;\n if (!trigger || !anchor) {\n rafId = requestAnimationFrame(trySetup);\n return;\n }\n const ancestors = getScrollableAncestors(trigger);\n\n function updatePos() {\n const rect = trigger!.getBoundingClientRect();\n const panelHeight = panelRef.current?.offsetHeight ?? 0;\n const spaceBelow = window.innerHeight - rect.bottom;\n const spaceAbove = rect.top;\n const preferredSpace = placement === 'top' ? spaceAbove : spaceBelow;\n const alternateSpace = placement === 'top' ? spaceBelow : spaceAbove;\n const flip = preferredSpace < panelHeight && alternateSpace > preferredSpace;\n const renderAbove = placement === 'top' ? !flip : flip;\n anchor!.classList.toggle(flipClassName, flip);\n // Shift up by the anchor's own height when rendering above, so this works whether\n // the anchor is a zero-height decorative wrapper (FloatingMenu, whose real panel\n // hangs off it via absolute-positioned CSS) or the visible panel itself\n // (Dropdown) — for the former the shift is a no-op (height 0).\n anchor!.style.top = `${renderAbove ? rect.top - anchor!.offsetHeight : rect.bottom}px`;\n anchor!.style.left = `${rect.left}px`;\n anchor!.style.visibility = isHiddenByAnyAncestor(rect, ancestors) ? 'hidden' : '';\n }\n\n updatePos();\n\n const scrollTargets: (Window | HTMLElement)[] = [window, ...ancestors];\n scrollTargets.forEach((t) => t.addEventListener('scroll', updatePos, { passive: true }));\n window.addEventListener('resize', updatePos);\n teardown = () => {\n scrollTargets.forEach((t) => t.removeEventListener('scroll', updatePos));\n window.removeEventListener('resize', updatePos);\n };\n }\n\n trySetup();\n\n return () => {\n if (rafId !== undefined) cancelAnimationFrame(rafId);\n teardown?.();\n };\n }, [isOpen, triggerRef, anchorRef, panelRef, flipClassName, placement]);\n}"],"mappings":"yIA2BA,SAAgB,EAAoB,CAAE,SAAQ,aAAY,YAAW,WAAU,gBAAe,YAAY,UAAqC,CAC7I,MAAsB,CACpB,GAAI,CAAC,EAAQ,OAEb,IAAI,EACA,EAOJ,SAAS,GAAW,CAClB,IAAM,EAAU,EAAW,QACrB,EAAS,EAAU,QACzB,GAAI,CAAC,GAAW,CAAC,EAAQ,CACvB,EAAQ,sBAAsB,CAAQ,EACtC,MACF,CACA,IAAM,EAAY,EAAuB,CAAO,EAEhD,SAAS,GAAY,CACnB,IAAM,EAAO,EAAS,sBAAsB,EACtC,EAAc,EAAS,SAAS,cAAgB,EAChD,EAAa,OAAO,YAAc,EAAK,OACvC,EAAa,EAAK,IAClB,EAAiB,IAAc,MAAQ,EAAa,EAEpD,EAAO,EAAiB,IADP,IAAc,MAAQ,EAAa,GACI,EACxD,EAAc,IAAc,MAAQ,CAAC,EAAO,EAClD,EAAQ,UAAU,OAAO,EAAe,CAAI,EAK5C,EAAQ,MAAM,IAAM,GAAG,EAAc,EAAK,IAAM,EAAQ,aAAe,EAAK,OAAO,IACnF,EAAQ,MAAM,KAAO,GAAG,EAAK,KAAK,IAClC,EAAQ,MAAM,WAAa,EAAsB,EAAM,CAAS,EAAI,SAAW,
|
|
1
|
+
{"version":3,"file":"useFloatingPosition.mjs","names":[],"sources":["../../../../package/common/floatingMenu/useFloatingPosition.ts"],"sourcesContent":["import { useLayoutEffect, type RefObject } from 'react';\nimport { getScrollableAncestors, isHiddenByAnyAncestor } from 'components/common/utils/scrollAncestors';\n\nexport interface UseFloatingPositionArgs {\n isOpen: boolean;\n /** The element the popup is anchored to. */\n triggerRef: RefObject<HTMLElement | null>;\n /** The `position: fixed` element that gets `top`/`left`/`visibility` written to it directly. */\n anchorRef: RefObject<HTMLElement | null>;\n /** The visible panel whose height decides whether there's room to render on the preferred side. */\n panelRef: RefObject<HTMLElement | null>;\n /** Class toggled on `anchorRef` when flipped to the non-preferred side. */\n flipClassName: string;\n /** Preferred side relative to the trigger (default `'bottom'`) — flips to the other side when there's no room. */\n placement?: 'top' | 'bottom';\n}\n\n/**\n * Keeps a portaled, `position: fixed` popup anchored to a trigger element: tracks the\n * trigger across scroll/resize on every real scrolling ancestor, flips above the trigger\n * when there's no room below, and hides (not closes) the popup when the trigger itself\n * scrolls behind a clipping ancestor — matching Floating UI's autoUpdate + hide middleware.\n *\n * Position/visibility are written straight to the DOM via refs, not through React state:\n * going through setState -> re-render -> commit adds a round-trip that lags behind the\n * browser's own scroll painting by at least a frame.\n */\nexport function useFloatingPosition({ isOpen, triggerRef, anchorRef, panelRef, flipClassName, placement = 'bottom' }: UseFloatingPositionArgs) {\n useLayoutEffect(() => {\n if (!isOpen) return;\n\n let rafId: number | undefined;\n let teardown: (() => void) | undefined;\n\n // The anchor/trigger may not be mounted yet on the very first invocation of this\n // effect: a portal target (e.g. BodyEnd's `#bodyEnd` div) can still be missing on\n // the initial render, in which case the portaled content — and this ref — commits\n // one render later. Since refs never change identity, that later commit doesn't\n // re-trigger this effect on its own, so retry on the next frame until it's there.\n function trySetup() {\n const trigger = triggerRef.current;\n const anchor = anchorRef.current;\n if (!trigger || !anchor) {\n rafId = requestAnimationFrame(trySetup);\n return;\n }\n const ancestors = getScrollableAncestors(trigger);\n\n function updatePos() {\n const rect = trigger!.getBoundingClientRect();\n const panelHeight = panelRef.current?.offsetHeight ?? 0;\n const spaceBelow = window.innerHeight - rect.bottom;\n const spaceAbove = rect.top;\n const preferredSpace = placement === 'top' ? spaceAbove : spaceBelow;\n const alternateSpace = placement === 'top' ? spaceBelow : spaceAbove;\n const flip = preferredSpace < panelHeight && alternateSpace > preferredSpace;\n const renderAbove = placement === 'top' ? !flip : flip;\n anchor!.classList.toggle(flipClassName, flip);\n // Shift up by the anchor's own height when rendering above, so this works whether\n // the anchor is a zero-height decorative wrapper (FloatingMenu, whose real panel\n // hangs off it via absolute-positioned CSS) or the visible panel itself\n // (Dropdown) — for the former the shift is a no-op (height 0).\n anchor!.style.top = `${renderAbove ? rect.top - anchor!.offsetHeight : rect.bottom}px`;\n anchor!.style.left = `${rect.left}px`;\n anchor!.style.visibility = isHiddenByAnyAncestor(rect, ancestors) ? 'hidden' : '';\n // The panel can mount a commit later than the anchor; once it's observed this\n // is a single Set lookup, so it costs nothing on the scroll path.\n const panel = panelRef.current;\n if (panel && !observed.has(panel)) observeSizeTargets();\n }\n\n // The panel's own height feeds both the flip decision and, when rendering above,\n // the top offset — so a popup whose content changes size while open (a filtered\n // list shrinking, an async list loading in) has to be re-measured, or it keeps a\n // top computed for its old height and ends up detached from the trigger.\n const resizeObserver = new ResizeObserver(() => updatePos());\n const observed = new Set<Element>();\n function observeSizeTargets() {\n // Both, since they're the same element for a panel-as-anchor consumer (Dropdown)\n // but not for a zero-height wrapper whose content sits inside it (FloatingMenu).\n // Called from updatePos too: the panel can mount a commit later than the anchor.\n [anchor, panelRef.current].forEach((el) => {\n if (!el || observed.has(el)) return;\n observed.add(el);\n resizeObserver.observe(el);\n });\n }\n\n updatePos();\n\n const scrollTargets: (Window | HTMLElement)[] = [window, ...ancestors];\n scrollTargets.forEach((t) => t.addEventListener('scroll', updatePos, { passive: true }));\n window.addEventListener('resize', updatePos);\n teardown = () => {\n scrollTargets.forEach((t) => t.removeEventListener('scroll', updatePos));\n window.removeEventListener('resize', updatePos);\n resizeObserver.disconnect();\n };\n }\n\n trySetup();\n\n return () => {\n if (rafId !== undefined) cancelAnimationFrame(rafId);\n teardown?.();\n };\n }, [isOpen, triggerRef, anchorRef, panelRef, flipClassName, placement]);\n}"],"mappings":"yIA2BA,SAAgB,EAAoB,CAAE,SAAQ,aAAY,YAAW,WAAU,gBAAe,YAAY,UAAqC,CAC7I,MAAsB,CACpB,GAAI,CAAC,EAAQ,OAEb,IAAI,EACA,EAOJ,SAAS,GAAW,CAClB,IAAM,EAAU,EAAW,QACrB,EAAS,EAAU,QACzB,GAAI,CAAC,GAAW,CAAC,EAAQ,CACvB,EAAQ,sBAAsB,CAAQ,EACtC,MACF,CACA,IAAM,EAAY,EAAuB,CAAO,EAEhD,SAAS,GAAY,CACnB,IAAM,EAAO,EAAS,sBAAsB,EACtC,EAAc,EAAS,SAAS,cAAgB,EAChD,EAAa,OAAO,YAAc,EAAK,OACvC,EAAa,EAAK,IAClB,EAAiB,IAAc,MAAQ,EAAa,EAEpD,EAAO,EAAiB,IADP,IAAc,MAAQ,EAAa,GACI,EACxD,EAAc,IAAc,MAAQ,CAAC,EAAO,EAClD,EAAQ,UAAU,OAAO,EAAe,CAAI,EAK5C,EAAQ,MAAM,IAAM,GAAG,EAAc,EAAK,IAAM,EAAQ,aAAe,EAAK,OAAO,IACnF,EAAQ,MAAM,KAAO,GAAG,EAAK,KAAK,IAClC,EAAQ,MAAM,WAAa,EAAsB,EAAM,CAAS,EAAI,SAAW,GAG/E,IAAM,EAAQ,EAAS,QACnB,GAAS,CAAC,EAAS,IAAI,CAAK,GAAG,EAAmB,CACxD,CAMA,IAAM,EAAiB,IAAI,mBAAqB,EAAU,CAAC,EACrD,EAAW,IAAI,IACrB,SAAS,GAAqB,CAI5B,CAAC,EAAQ,EAAS,OAAO,EAAE,QAAS,GAAO,CACrC,CAAC,GAAM,EAAS,IAAI,CAAE,IAC1B,EAAS,IAAI,CAAE,EACf,EAAe,QAAQ,CAAE,EAC3B,CAAC,CACH,CAEA,EAAU,EAEV,IAAM,EAA0C,CAAC,OAAQ,GAAG,CAAS,EACrE,EAAc,QAAS,GAAM,EAAE,iBAAiB,SAAU,EAAW,CAAE,QAAS,EAAK,CAAC,CAAC,EACvF,OAAO,iBAAiB,SAAU,CAAS,EAC3C,MAAiB,CACf,EAAc,QAAS,GAAM,EAAE,oBAAoB,SAAU,CAAS,CAAC,EACvE,OAAO,oBAAoB,SAAU,CAAS,EAC9C,EAAe,WAAW,CAC5B,CACF,CAIA,OAFA,EAAS,MAEI,CACP,IAAU,IAAA,IAAW,qBAAqB,CAAK,EACnD,IAAW,CACb,CACF,EAAG,CAAC,EAAQ,EAAY,EAAW,EAAU,EAAe,CAAS,CAAC,CACxE"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import t from"../tooltip/tooltip.mjs";import n from"../animatedIcon/animatedIcon.mjs";import r from"./input.module.mjs";import{InputIconPosition as i,InputType as a}from"./input.types.mjs";import ee,{useCallback as te,useEffect as o,useId as ne,useRef as s,useState as c}from"react";import l from"classnames";import{FontAwesomeIcon as u}from"@fortawesome/react-fontawesome";import{faEnvelope as re,faEye as ie,faEyeSlash as ae,faPen as oe,faPhone as se,faSearch as ce,faXmark as d}from"@fortawesome/free-solid-svg-icons";import{jsx as f,jsxs as p}from"react/jsx-runtime";function m(m){let{name:h=``,id:le,label:g=``,errorMessage:ue=``,isValid:de=!0,className:fe=``,style:pe,value:
|
|
1
|
+
import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import t from"../tooltip/tooltip.mjs";import n from"../animatedIcon/animatedIcon.mjs";import r from"./input.module.mjs";import{InputIconPosition as i,InputType as a}from"./input.types.mjs";import ee,{useCallback as te,useEffect as o,useId as ne,useRef as s,useState as c}from"react";import l from"classnames";import{FontAwesomeIcon as u}from"@fortawesome/react-fontawesome";import{faEnvelope as re,faEye as ie,faEyeSlash as ae,faPen as oe,faPhone as se,faSearch as ce,faXmark as d}from"@fortawesome/free-solid-svg-icons";import{jsx as f,jsxs as p}from"react/jsx-runtime";function m(m){let{name:h=``,id:le,label:g=``,errorMessage:ue=``,isValid:de=!0,className:fe=``,style:pe,value:me=``,icon:he=null,iconPosition:ge,onChange:_=()=>{},onFocus:_e=null,onBlur:ve=null,onMouseEnter:ye=null,onMouseLeave:be=null,isUppercase:xe=!1,isRequired:Se=!1,tabIndex:Ce=0,type:v=void 0,isRow:we=!1,onIconClick:y=null,parse:b=null,formValidator:x=null,autoFocus:S=!1,suffix:C=null,upperRightLabel:w=null,labelInBorder:Te=!1,showCancel:Ee=!1,onClearClicked:De,min:Oe=null,max:ke=null,placeholder:T=``,useMatLabelStyle:E=!0,alwaysFloatLabel:Ae=!1,autoComplete:je=null,onClick:Me=()=>null,readOnly:D=!1,customInput:O,alwaysShowCancel:Ne=!1,multiline:k=!1,rows:A,autoResize:j=!1,classNames:M,styles:N,disabled:P=!1,...F}=e(`Input`,m),[I,Pe]=c(!1),[Fe,L]=c(!1),[R,Ie]=c(!1),[,Le]=c(0),z=s(null),B=s(x),Re=ne(),ze=le||h||Re,Be=te(()=>{let e=z.current;!e||!j||(e.style.height=`auto`,e.style.height=`${e.scrollHeight}px`)},[j]);o(()=>{Be()},[]),o(()=>{S&&z.current&&setTimeout(()=>{z.current?.focus()},1)},[S]),o(()=>{B.current=x;let e=B.current;if(!e)return;e.label=g??``,e.validate();let t=()=>Le(e=>e+1);return e.registerOnUpdateListener(t),()=>{e.removeOnUpdateListener(t)}},[x,g]);let Ve=()=>x?x.touched&&x.hasError():!de||!!ue,He=()=>!!(Se||x&&x.validators.find(e=>e.validatorId===`required`)),Ue=e=>{L(!0),ye&&ye(e)},We=e=>{L(!1),be&&be(e)},Ge=e=>{Pe(!0),_e&&_e(e)},Ke=e=>{B.current&&(B.current.touched=!0),Pe(!1),ve&&ve(e)},qe=e=>{let t,n;typeof e==`string`?n=e:(t=e,n=e.target.value),b&&(n=b(n)),x&&x.set(n),_&&_(n,t),Be()},Je=()=>{if(v!==a.Email)return v===a.Phone?`tel`:v===a.Search?`search`:v===`password`&&R?`text`:v},Ye=()=>{if(v===a.Email)return`email`;if(v===a.Phone)return`tel`;if(v===a.Search)return`search`},V=v&&v!==a.Date&&v!==a.Iban&&v!==a.HasNoIcon,Xe=v===a.Search||v===a.Password,H=!!he,Ze=H&&!Xe,Qe=v===a.Email||v===a.Phone||v===a.Search,U=(ge??(!E&&Qe?i.Left:i.Right))===i.Left,W={className:l(r.inputFieldIcon,{[r.inputFieldIconNotClickable]:!y,[r.inputFieldIconLeft]:U}),onClick:y??void 0},G=he,$e=Ze&&G?ee.cloneElement(G,{className:l(r.inputFieldIcon,{[r.inputFieldIconNotClickable]:!y&&!G.props.onClick,[r.inputFieldIconLeft]:U},G.props.className),onClick:y??G.props.onClick}):null,et=(V||H)&&U,tt={className:l(r.inputFieldIcon,r.inputFieldIconPassword,{[r.inputFieldIconLeft]:U}),onClick:()=>Ie(!R)},K=Ve(),q=g;q&&He()&&(q=`${q} *`);let nt=He()?f(`span`,{className:r.requiredMark,children:`*`}):null,J=x?x.value:me,Y=I&&!D,X=E&&(Ae||Y||J||v===a.Date),Z=v===a.Search&&!!J,Q=O?.props;function $(){x&&x.set(``),_?.(``),De?.()}return p(`div`,{className:l(r.input,{[r.inputIconLeft]:et},fe),style:pe,children:[p(`label`,{htmlFor:ze,className:l(r.inputLabel,M?.label,{[r.inputLabelColumn]:!we,[r.inputLabelInBorder]:Te}),style:N?.label,children:[g&&!E?p(`span`,{className:r.inputLabelText,children:[g,nt]}):null,w&&f(`div`,{className:l(r.inputUpperRightLabel,M?.upperRightLabel),style:N?.upperRightLabel,children:w}),p(`div`,{className:l(r.inputContainer,{[r.inputContainerMultiline]:k},M?.container),style:N?.container,onMouseEnter:Ue,onMouseLeave:We,children:[$e,ee.cloneElement(O||f(k?`textarea`:`input`,{}),{...F,className:l(r.inputField,{[r.inputFieldUppercase]:xe,[r.inputFieldDate]:v===a.Date,[r.inputFieldDefault]:v!==a.Date,[r.inputFieldWithIcon]:V||H,[r.inputFieldWithIconLeft]:et,[r.inputFieldMultiline]:k,[r.inputFieldMultilineAutoResize]:k&&j,[r.inputFieldReadOnly]:D&&!P},M?.input,Q?.className),style:Q?.style||N?.input?{...Q?.style,...N?.input}:void 0,name:h,id:ze,value:J,tabIndex:Ce,ref:O?void 0:z,onChange:qe,onFocus:Ge,onBlur:Ke,placeholder:E?``:T,autoComplete:je,onClick:Me,readOnly:D,disabled:P,...!k&&{type:Je(),inputMode:F.inputMode??Ye(),min:Oe,max:ke},...k&&A!==void 0&&{rows:A}}),C&&f(`div`,{className:l(r.inputFieldSuffix,M?.suffix),style:N?.suffix,children:C})]}),f(`fieldset`,{className:l(r.inputFieldset,M?.fieldset,{[r.inputFieldsetNoNotch]:!g,[r.inputContainerBorderFocused]:Y,[r.inputContainerBorderSearchFocused]:v===a.Search&&(Y||!!J),[r.inputContainerBorderInvalid]:K,[r.inputContainerBorderError]:K}),style:N?.fieldset,children:f(`legend`,{className:l(r.inputFieldsetLegend,{[r.inputFieldsetLegendActive]:X}),children:f(`span`,{children:q})})}),E&&g&&p(`div`,{className:l(r.inputMatLabel,{[r.inputMatLabelFloating]:X,[r.inputMatLabelMultiline]:k&&!X}),children:[g,nt]}),E&&T&&f(`div`,{className:l(r.inputPlaceholder,Y&&!J&&r.inputPlaceholderShown,k&&r.inputPlaceholderMultiline),children:T}),f(t,{variant:`error`,message:x?x.getCurrentErrorMessage():ue||``,isVisible:K&&(I||Fe)})]}),v===a.Phone&&!H&&f(u,{icon:se,...W}),v===a.Email&&!H&&f(u,{icon:re,...W}),v===a.Edit&&!H&&f(u,{icon:oe,...W}),v===a.Search&&f(n,{icon:Z?d:ce,className:l(r.inputFieldIcon,{[r.inputFieldIconNotClickable]:!Z,[r.inputFieldIconLeft]:U}),onClick:Z?$:void 0}),v===a.Password&&f(u,{icon:R?ae:ie,...tt}),(Ee&&J&&(I||Fe)||Ne)&&v!==a.Search&&f(u,{icon:d,className:r.inputFieldIcon,onClick:$,onMouseEnter:()=>L(!0),onMouseLeave:()=>L(!1)})]})}export{m as default};
|
|
2
2
|
//# sourceMappingURL=input.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.mjs","names":[],"sources":["../../../../package/common/input/input.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useCallback, useId } from 'react';\nimport cx from 'classnames';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport {\n faPhone,\n faPen,\n faEnvelope,\n faSearch,\n faXmark,\n faEye as passwordHiddenIcon,\n faEyeSlash as passwordShownIcon,\n} from '@fortawesome/free-solid-svg-icons';\nimport Tooltip from 'components/common/tooltip';\nimport AnimatedIcon from 'components/common/animatedIcon';\nimport { useComponentDefaults } from 'components/common/configProvider';\nimport styles from './input.module.pcss';\nimport type { InputProps } from './input.types';\nimport { InputType, InputIconPosition } from './input.types';\n\nfunction Input(props: InputProps) {\n const {\n name = '',\n id,\n label = '',\n errorMessage = '',\n isValid = true,\n className = '',\n style,\n value = '',\n icon = null,\n iconPosition,\n onChange = () => {},\n onFocus: onFocusProp = null,\n onBlur: onBlurProp = null,\n onMouseEnter: onMouseEnterProp = null,\n onMouseLeave: onMouseLeaveProp = null,\n isUppercase = false,\n isRequired = false,\n tabIndex = 0,\n type = undefined,\n isRow = false,\n onIconClick = null,\n parse = null,\n formValidator = null,\n autoFocus = false,\n suffix = null,\n upperRightLabel = null,\n labelInBorder = false,\n showCancel = false,\n onClearClicked,\n min = null,\n max = null,\n placeholder = '',\n useMatLabelStyle = true,\n alwaysFloatLabel = false,\n autoComplete = null,\n onClick = () => null,\n readOnly = false,\n customInput,\n alwaysShowCancel = false,\n multiline = false,\n rows,\n autoResize = false,\n classNames,\n styles: slotStyles,\n disabled = false,\n ...rest\n } = useComponentDefaults('Input', props);\n const [isFocused, setIsFocused] = useState(false);\n const [isHovered, setIsHovered] = useState(false);\n const [isPasswordShown, setIsPasswordShown] = useState(false);\n const [, forceUpdate] = useState(0);\n\n const inputRef = useRef<HTMLInputElement | HTMLTextAreaElement>(null);\n const fvRef = useRef(formValidator);\n\n const generatedId = useId();\n const inputId = id || name || generatedId;\n\n const resizeTextarea = useCallback(() => {\n const el = inputRef.current;\n if (!el || !autoResize) return;\n el.style.height = 'auto';\n el.style.height = `${el.scrollHeight}px`;\n }, [autoResize]);\n\n useEffect(() => {\n resizeTextarea();\n }, []);\n\n useEffect(() => {\n if (autoFocus && inputRef.current) {\n setTimeout(() => { inputRef.current?.focus(); }, 1);\n }\n }, [autoFocus]);\n\n useEffect(() => {\n fvRef.current = formValidator;\n const fv = fvRef.current;\n if (!fv) return;\n fv.label = label ?? '';\n fv.validate();\n const listener = () => forceUpdate(n => n + 1);\n fv.registerOnUpdateListener(listener);\n return () => { fv.removeOnUpdateListener(listener); };\n }, [formValidator, label]);\n\n const hasError = (): boolean => {\n return formValidator\n ? (formValidator.touched && formValidator.hasError())\n : (!isValid || !!errorMessage);\n };\n\n const computedIsRequired = (): boolean => {\n return !!(isRequired || (formValidator && formValidator.validators.find(\n (v) => (v as { validatorId?: string }).validatorId === 'required'\n )));\n };\n\n const onMouseEnterHandler = (event: React.MouseEvent) => {\n setIsHovered(true);\n if (onMouseEnterProp) onMouseEnterProp(event);\n };\n\n const onMouseLeaveHandler = (event: React.MouseEvent) => {\n setIsHovered(false);\n if (onMouseLeaveProp) onMouseLeaveProp(event);\n };\n\n const onFocusHandler = (event: React.FocusEvent) => {\n setIsFocused(true);\n if (onFocusProp) onFocusProp(event);\n };\n\n const onBlurHandler = (event: React.FocusEvent) => {\n if (fvRef.current) fvRef.current.touched = true;\n setIsFocused(false);\n if (onBlurProp) onBlurProp(event);\n };\n\n const onChangeHandler = (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement> | string): void => {\n let parsedEvent: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement> | undefined;\n let val: string;\n\n if (typeof event !== 'string') {\n parsedEvent = event;\n val = event.target.value;\n } else {\n val = event;\n }\n\n if (parse) val = parse(val);\n if (formValidator) formValidator.set(val);\n if (onChange) onChange(val, parsedEvent);\n resizeTextarea();\n };\n\n const getInputType = (): string | undefined => {\n if (type === InputType.Email) return undefined;\n if (type === InputType.Phone) return 'tel';\n if (type === InputType.Search) return 'search';\n if (type === 'password' && isPasswordShown) return 'text';\n return type;\n };\n\n const getInputMode = (): React.HTMLAttributes<HTMLInputElement>['inputMode'] => {\n if (type === InputType.Email) return 'email';\n if (type === InputType.Phone) return 'tel';\n if (type === InputType.Search) return 'search';\n return undefined;\n };\n\n const hasIcon =\n type &&\n type !== InputType.Date &&\n type !== InputType.Iban &&\n type !== InputType.HasNoIcon;\n\n const isFunctionalIconType = type === InputType.Search || type === InputType.Password;\n const hasCustomIcon = !!icon;\n const customIconApplies = hasCustomIcon && !isFunctionalIconType;\n\n const defaultsLeftWithoutMatLabel = type === InputType.Email || type === InputType.Phone || type === InputType.Search;\n const resolvedIconPosition = iconPosition ?? (!useMatLabelStyle && defaultsLeftWithoutMatLabel ? InputIconPosition.Left : InputIconPosition.Right);\n const iconIsLeft = resolvedIconPosition === InputIconPosition.Left;\n\n const iconProps = {\n className: cx(styles.inputFieldIcon, {\n [styles.inputFieldIconNotClickable]: !onIconClick,\n [styles.inputFieldIconLeft]: iconIsLeft,\n }),\n onClick: onIconClick ?? undefined,\n };\n\n const customIcon = icon as React.ReactElement<{ className?: string; onClick?: React.MouseEventHandler }> | null;\n const renderedIcon = customIconApplies && customIcon\n ? React.cloneElement(customIcon, {\n className: cx(\n styles.inputFieldIcon,\n {\n [styles.inputFieldIconNotClickable]: !onIconClick && !customIcon.props.onClick,\n [styles.inputFieldIconLeft]: iconIsLeft,\n },\n customIcon.props.className,\n ),\n onClick: onIconClick ?? customIcon.props.onClick,\n })\n : null;\n\n const hasLeftIcon = (hasIcon || hasCustomIcon) && iconIsLeft;\n\n const passwordIconProps = {\n className: cx(styles.inputFieldIcon, styles.inputFieldIconPassword, { [styles.inputFieldIconLeft]: iconIsLeft }),\n onClick: () => setIsPasswordShown(!isPasswordShown),\n };\n\n const hasErr = hasError();\n\n let editedLabel = label;\n if (editedLabel && computedIsRequired()) editedLabel = `${editedLabel} *`;\n const requiredMark = computedIsRequired() ? <span className={styles.requiredMark}>*</span> : null;\n\n const currVal = formValidator ? formValidator.value : value;\n const showFocus = isFocused && !readOnly;\n const shouldFloatLabel = useMatLabelStyle && (alwaysFloatLabel || showFocus || currVal || type === InputType.Date);\n\n const isSearchCleared = type === InputType.Search && !!currVal;\n\n function handleClear() {\n if (formValidator) formValidator.set('');\n onChange?.('');\n onClearClicked?.();\n }\n\n return (\n <div className={cx(styles.input, { [styles.inputIconLeft]: hasLeftIcon }, className)} style={style}>\n <label\n htmlFor={inputId}\n className={cx(styles.inputLabel, classNames?.label, {\n [styles.inputLabelColumn]: !isRow,\n [styles.inputLabelInBorder]: labelInBorder,\n })}\n style={slotStyles?.label}\n >\n {label && !useMatLabelStyle ? (\n <span className={styles.inputLabelText}>\n {label}\n {requiredMark}\n </span>\n ) : null}\n {upperRightLabel && (\n <div className={cx(styles.inputUpperRightLabel, classNames?.upperRightLabel)} style={slotStyles?.upperRightLabel}>\n {upperRightLabel}\n </div>\n )}\n <div\n className={cx(styles.inputContainer, { [styles.inputContainerMultiline]: multiline }, classNames?.container)}\n style={slotStyles?.container}\n onMouseEnter={onMouseEnterHandler}\n onMouseLeave={onMouseLeaveHandler}\n >\n {renderedIcon}\n {React.cloneElement(customInput || (multiline ? <textarea /> : <input />), {\n ...rest,\n className: cx(\n styles.inputField,\n {\n [styles.inputFieldUppercase]: isUppercase,\n [styles.inputFieldDate]: type === InputType.Date,\n [styles.inputFieldDefault]: type !== InputType.Date,\n [styles.inputFieldWithIcon]: hasIcon || hasCustomIcon,\n [styles.inputFieldWithIconLeft]: hasLeftIcon,\n [styles.inputFieldMultiline]: multiline,\n [styles.inputFieldMultilineAutoResize]: multiline && autoResize,\n [styles.inputFieldReadOnly]: readOnly && !disabled,\n },\n classNames?.input\n ),\n name,\n id: inputId,\n value: formValidator ? formValidator.value : value,\n tabIndex,\n ref: customInput ? undefined : inputRef,\n onChange: onChangeHandler,\n onFocus: onFocusHandler,\n onBlur: onBlurHandler,\n placeholder: !useMatLabelStyle ? placeholder : '',\n autoComplete,\n onClick,\n readOnly,\n disabled,\n ...(!multiline && { type: getInputType(), inputMode: rest.inputMode ?? getInputMode(), min, max }),\n ...(multiline && rows !== undefined && { rows }),\n })}\n {suffix && <div className={cx(styles.inputFieldSuffix, classNames?.suffix)} style={slotStyles?.suffix}>{suffix}</div>}\n </div>\n <fieldset\n className={cx(styles.inputFieldset, classNames?.fieldset, {\n [styles.inputFieldsetNoNotch]: !label,\n [styles.inputContainerBorderFocused]: showFocus,\n [styles.inputContainerBorderSearchFocused]:\n type === InputType.Search && (showFocus || value),\n [styles.inputContainerBorderInvalid]: hasErr,\n [styles.inputContainerBorderError]: hasErr,\n })}\n style={slotStyles?.fieldset}\n >\n <legend\n className={cx(styles.inputFieldsetLegend, {\n [styles.inputFieldsetLegendActive]: shouldFloatLabel,\n })}\n >\n <span>{editedLabel}</span>\n </legend>\n </fieldset>\n {useMatLabelStyle && label && (\n <div\n className={cx(styles.inputMatLabel, {\n [styles.inputMatLabelFloating]: shouldFloatLabel,\n [styles.inputMatLabelMultiline]: multiline && !shouldFloatLabel,\n })}\n >\n {label}\n {requiredMark}\n </div>\n )}\n {useMatLabelStyle && placeholder && (\n <div\n className={cx(\n styles.inputPlaceholder,\n showFocus && !currVal && styles.inputPlaceholderShown,\n multiline && styles.inputPlaceholderMultiline,\n )}\n >\n {placeholder}\n </div>\n )}\n <Tooltip\n variant=\"error\"\n message={formValidator ? formValidator.getCurrentErrorMessage() : (errorMessage || '')}\n isVisible={hasErr && (isFocused || isHovered)}\n />\n </label>\n\n {type === InputType.Phone && !hasCustomIcon && <FontAwesomeIcon icon={faPhone} {...iconProps} />}\n {type === InputType.Email && !hasCustomIcon && <FontAwesomeIcon icon={faEnvelope} {...iconProps} />}\n {type === InputType.Edit && !hasCustomIcon && <FontAwesomeIcon icon={faPen} {...iconProps} />}\n {type === InputType.Search && (\n <AnimatedIcon\n icon={isSearchCleared ? faXmark : faSearch}\n className={cx(styles.inputFieldIcon, {\n [styles.inputFieldIconNotClickable]: !isSearchCleared,\n [styles.inputFieldIconLeft]: iconIsLeft,\n })}\n onClick={isSearchCleared ? handleClear : undefined}\n />\n )}\n {type === InputType.Password && (\n <FontAwesomeIcon\n icon={isPasswordShown ? passwordShownIcon : passwordHiddenIcon}\n {...passwordIconProps}\n />\n )}\n\n {((showCancel && value && (isFocused || isHovered)) || alwaysShowCancel) && type !== InputType.Search && (\n <FontAwesomeIcon\n icon={faXmark}\n className={styles.inputFieldIcon}\n onClick={handleClear}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n />\n )}\n </div>\n );\n}\n\nexport default Input;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"input.mjs","names":[],"sources":["../../../../package/common/input/input.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useCallback, useId } from 'react';\nimport cx from 'classnames';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport {\n faPhone,\n faPen,\n faEnvelope,\n faSearch,\n faXmark,\n faEye as passwordHiddenIcon,\n faEyeSlash as passwordShownIcon,\n} from '@fortawesome/free-solid-svg-icons';\nimport Tooltip from 'components/common/tooltip';\nimport AnimatedIcon from 'components/common/animatedIcon';\nimport { useComponentDefaults } from 'components/common/configProvider';\nimport styles from './input.module.pcss';\nimport type { InputProps } from './input.types';\nimport { InputType, InputIconPosition } from './input.types';\n\nfunction Input(props: InputProps) {\n const {\n name = '',\n id,\n label = '',\n errorMessage = '',\n isValid = true,\n className = '',\n style,\n value = '',\n icon = null,\n iconPosition,\n onChange = () => {},\n onFocus: onFocusProp = null,\n onBlur: onBlurProp = null,\n onMouseEnter: onMouseEnterProp = null,\n onMouseLeave: onMouseLeaveProp = null,\n isUppercase = false,\n isRequired = false,\n tabIndex = 0,\n type = undefined,\n isRow = false,\n onIconClick = null,\n parse = null,\n formValidator = null,\n autoFocus = false,\n suffix = null,\n upperRightLabel = null,\n labelInBorder = false,\n showCancel = false,\n onClearClicked,\n min = null,\n max = null,\n placeholder = '',\n useMatLabelStyle = true,\n alwaysFloatLabel = false,\n autoComplete = null,\n onClick = () => null,\n readOnly = false,\n customInput,\n alwaysShowCancel = false,\n multiline = false,\n rows,\n autoResize = false,\n classNames,\n styles: slotStyles,\n disabled = false,\n ...rest\n } = useComponentDefaults('Input', props);\n const [isFocused, setIsFocused] = useState(false);\n const [isHovered, setIsHovered] = useState(false);\n const [isPasswordShown, setIsPasswordShown] = useState(false);\n const [, forceUpdate] = useState(0);\n\n const inputRef = useRef<HTMLInputElement | HTMLTextAreaElement>(null);\n const fvRef = useRef(formValidator);\n\n const generatedId = useId();\n const inputId = id || name || generatedId;\n\n const resizeTextarea = useCallback(() => {\n const el = inputRef.current;\n if (!el || !autoResize) return;\n el.style.height = 'auto';\n el.style.height = `${el.scrollHeight}px`;\n }, [autoResize]);\n\n useEffect(() => {\n resizeTextarea();\n }, []);\n\n useEffect(() => {\n if (autoFocus && inputRef.current) {\n setTimeout(() => { inputRef.current?.focus(); }, 1);\n }\n }, [autoFocus]);\n\n useEffect(() => {\n fvRef.current = formValidator;\n const fv = fvRef.current;\n if (!fv) return;\n fv.label = label ?? '';\n fv.validate();\n const listener = () => forceUpdate(n => n + 1);\n fv.registerOnUpdateListener(listener);\n return () => { fv.removeOnUpdateListener(listener); };\n }, [formValidator, label]);\n\n const hasError = (): boolean => {\n return formValidator\n ? (formValidator.touched && formValidator.hasError())\n : (!isValid || !!errorMessage);\n };\n\n const computedIsRequired = (): boolean => {\n return !!(isRequired || (formValidator && formValidator.validators.find(\n (v) => (v as { validatorId?: string }).validatorId === 'required'\n )));\n };\n\n const onMouseEnterHandler = (event: React.MouseEvent) => {\n setIsHovered(true);\n if (onMouseEnterProp) onMouseEnterProp(event);\n };\n\n const onMouseLeaveHandler = (event: React.MouseEvent) => {\n setIsHovered(false);\n if (onMouseLeaveProp) onMouseLeaveProp(event);\n };\n\n const onFocusHandler = (event: React.FocusEvent) => {\n setIsFocused(true);\n if (onFocusProp) onFocusProp(event);\n };\n\n const onBlurHandler = (event: React.FocusEvent) => {\n if (fvRef.current) fvRef.current.touched = true;\n setIsFocused(false);\n if (onBlurProp) onBlurProp(event);\n };\n\n const onChangeHandler = (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement> | string): void => {\n let parsedEvent: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement> | undefined;\n let val: string;\n\n if (typeof event !== 'string') {\n parsedEvent = event;\n val = event.target.value;\n } else {\n val = event;\n }\n\n if (parse) val = parse(val);\n if (formValidator) formValidator.set(val);\n if (onChange) onChange(val, parsedEvent);\n resizeTextarea();\n };\n\n const getInputType = (): string | undefined => {\n if (type === InputType.Email) return undefined;\n if (type === InputType.Phone) return 'tel';\n if (type === InputType.Search) return 'search';\n if (type === 'password' && isPasswordShown) return 'text';\n return type;\n };\n\n const getInputMode = (): React.HTMLAttributes<HTMLInputElement>['inputMode'] => {\n if (type === InputType.Email) return 'email';\n if (type === InputType.Phone) return 'tel';\n if (type === InputType.Search) return 'search';\n return undefined;\n };\n\n const hasIcon =\n type &&\n type !== InputType.Date &&\n type !== InputType.Iban &&\n type !== InputType.HasNoIcon;\n\n const isFunctionalIconType = type === InputType.Search || type === InputType.Password;\n const hasCustomIcon = !!icon;\n const customIconApplies = hasCustomIcon && !isFunctionalIconType;\n\n const defaultsLeftWithoutMatLabel = type === InputType.Email || type === InputType.Phone || type === InputType.Search;\n const resolvedIconPosition = iconPosition ?? (!useMatLabelStyle && defaultsLeftWithoutMatLabel ? InputIconPosition.Left : InputIconPosition.Right);\n const iconIsLeft = resolvedIconPosition === InputIconPosition.Left;\n\n const iconProps = {\n className: cx(styles.inputFieldIcon, {\n [styles.inputFieldIconNotClickable]: !onIconClick,\n [styles.inputFieldIconLeft]: iconIsLeft,\n }),\n onClick: onIconClick ?? undefined,\n };\n\n const customIcon = icon as React.ReactElement<{ className?: string; onClick?: React.MouseEventHandler }> | null;\n const renderedIcon = customIconApplies && customIcon\n ? React.cloneElement(customIcon, {\n className: cx(\n styles.inputFieldIcon,\n {\n [styles.inputFieldIconNotClickable]: !onIconClick && !customIcon.props.onClick,\n [styles.inputFieldIconLeft]: iconIsLeft,\n },\n customIcon.props.className,\n ),\n onClick: onIconClick ?? customIcon.props.onClick,\n })\n : null;\n\n const hasLeftIcon = (hasIcon || hasCustomIcon) && iconIsLeft;\n\n const passwordIconProps = {\n className: cx(styles.inputFieldIcon, styles.inputFieldIconPassword, { [styles.inputFieldIconLeft]: iconIsLeft }),\n onClick: () => setIsPasswordShown(!isPasswordShown),\n };\n\n const hasErr = hasError();\n\n let editedLabel = label;\n if (editedLabel && computedIsRequired()) editedLabel = `${editedLabel} *`;\n const requiredMark = computedIsRequired() ? <span className={styles.requiredMark}>*</span> : null;\n\n const currVal = formValidator ? formValidator.value : value;\n const showFocus = isFocused && !readOnly;\n const shouldFloatLabel = useMatLabelStyle && (alwaysFloatLabel || showFocus || currVal || type === InputType.Date);\n\n const isSearchCleared = type === InputType.Search && !!currVal;\n\n const customInputProps = customInput?.props as\n | { className?: string; style?: React.CSSProperties }\n | undefined;\n\n function handleClear() {\n if (formValidator) formValidator.set('');\n onChange?.('');\n onClearClicked?.();\n }\n\n return (\n <div className={cx(styles.input, { [styles.inputIconLeft]: hasLeftIcon }, className)} style={style}>\n <label\n htmlFor={inputId}\n className={cx(styles.inputLabel, classNames?.label, {\n [styles.inputLabelColumn]: !isRow,\n [styles.inputLabelInBorder]: labelInBorder,\n })}\n style={slotStyles?.label}\n >\n {label && !useMatLabelStyle ? (\n <span className={styles.inputLabelText}>\n {label}\n {requiredMark}\n </span>\n ) : null}\n {upperRightLabel && (\n <div className={cx(styles.inputUpperRightLabel, classNames?.upperRightLabel)} style={slotStyles?.upperRightLabel}>\n {upperRightLabel}\n </div>\n )}\n <div\n className={cx(styles.inputContainer, { [styles.inputContainerMultiline]: multiline }, classNames?.container)}\n style={slotStyles?.container}\n onMouseEnter={onMouseEnterHandler}\n onMouseLeave={onMouseLeaveHandler}\n >\n {renderedIcon}\n {React.cloneElement(customInput || (multiline ? <textarea /> : <input />), {\n ...rest,\n className: cx(\n styles.inputField,\n {\n [styles.inputFieldUppercase]: isUppercase,\n [styles.inputFieldDate]: type === InputType.Date,\n [styles.inputFieldDefault]: type !== InputType.Date,\n [styles.inputFieldWithIcon]: hasIcon || hasCustomIcon,\n [styles.inputFieldWithIconLeft]: hasLeftIcon,\n [styles.inputFieldMultiline]: multiline,\n [styles.inputFieldMultilineAutoResize]: multiline && autoResize,\n [styles.inputFieldReadOnly]: readOnly && !disabled,\n },\n classNames?.input,\n customInputProps?.className,\n ),\n style: customInputProps?.style || slotStyles?.input\n ? { ...customInputProps?.style, ...slotStyles?.input }\n : undefined,\n name,\n id: inputId,\n value: currVal,\n tabIndex,\n ref: customInput ? undefined : inputRef,\n onChange: onChangeHandler,\n onFocus: onFocusHandler,\n onBlur: onBlurHandler,\n placeholder: !useMatLabelStyle ? placeholder : '',\n autoComplete,\n onClick,\n readOnly,\n disabled,\n ...(!multiline && { type: getInputType(), inputMode: rest.inputMode ?? getInputMode(), min, max }),\n ...(multiline && rows !== undefined && { rows }),\n })}\n {suffix && <div className={cx(styles.inputFieldSuffix, classNames?.suffix)} style={slotStyles?.suffix}>{suffix}</div>}\n </div>\n <fieldset\n className={cx(styles.inputFieldset, classNames?.fieldset, {\n [styles.inputFieldsetNoNotch]: !label,\n [styles.inputContainerBorderFocused]: showFocus,\n [styles.inputContainerBorderSearchFocused]:\n type === InputType.Search && (showFocus || !!currVal),\n [styles.inputContainerBorderInvalid]: hasErr,\n [styles.inputContainerBorderError]: hasErr,\n })}\n style={slotStyles?.fieldset}\n >\n <legend\n className={cx(styles.inputFieldsetLegend, {\n [styles.inputFieldsetLegendActive]: shouldFloatLabel,\n })}\n >\n <span>{editedLabel}</span>\n </legend>\n </fieldset>\n {useMatLabelStyle && label && (\n <div\n className={cx(styles.inputMatLabel, {\n [styles.inputMatLabelFloating]: shouldFloatLabel,\n [styles.inputMatLabelMultiline]: multiline && !shouldFloatLabel,\n })}\n >\n {label}\n {requiredMark}\n </div>\n )}\n {useMatLabelStyle && placeholder && (\n <div\n className={cx(\n styles.inputPlaceholder,\n showFocus && !currVal && styles.inputPlaceholderShown,\n multiline && styles.inputPlaceholderMultiline,\n )}\n >\n {placeholder}\n </div>\n )}\n <Tooltip\n variant=\"error\"\n message={formValidator ? formValidator.getCurrentErrorMessage() : (errorMessage || '')}\n isVisible={hasErr && (isFocused || isHovered)}\n />\n </label>\n\n {type === InputType.Phone && !hasCustomIcon && <FontAwesomeIcon icon={faPhone} {...iconProps} />}\n {type === InputType.Email && !hasCustomIcon && <FontAwesomeIcon icon={faEnvelope} {...iconProps} />}\n {type === InputType.Edit && !hasCustomIcon && <FontAwesomeIcon icon={faPen} {...iconProps} />}\n {type === InputType.Search && (\n <AnimatedIcon\n icon={isSearchCleared ? faXmark : faSearch}\n className={cx(styles.inputFieldIcon, {\n [styles.inputFieldIconNotClickable]: !isSearchCleared,\n [styles.inputFieldIconLeft]: iconIsLeft,\n })}\n onClick={isSearchCleared ? handleClear : undefined}\n />\n )}\n {type === InputType.Password && (\n <FontAwesomeIcon\n icon={isPasswordShown ? passwordShownIcon : passwordHiddenIcon}\n {...passwordIconProps}\n />\n )}\n\n {((showCancel && currVal && (isFocused || isHovered)) || alwaysShowCancel) && type !== InputType.Search && (\n <FontAwesomeIcon\n icon={faXmark}\n className={styles.inputFieldIcon}\n onClick={handleClear}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n />\n )}\n </div>\n );\n}\n\nexport default Input;\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import t from"../interactableDiv/index.mjs";import n from"../input/input.mjs";import r from"./numberInput.module.mjs";import"react";import i from"classnames";import{FontAwesomeIcon as a}from"@fortawesome/react-fontawesome";import{faChevronDown as o,faChevronUp as s}from"@fortawesome/free-solid-svg-icons";import{jsx as c,jsxs as l}from"react/jsx-runtime";import{NumericFormat as u}from"react-number-format";function d(d){let{value:f,onChange:p,formValidator:m,label:h,error:g,className:_,allowNegative:
|
|
1
|
+
import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import t from"../interactableDiv/index.mjs";import n from"../input/input.mjs";import r from"./numberInput.module.mjs";import"react";import i from"classnames";import{FontAwesomeIcon as a}from"@fortawesome/react-fontawesome";import{faChevronDown as o,faChevronUp as s}from"@fortawesome/free-solid-svg-icons";import{jsx as c,jsxs as l}from"react/jsx-runtime";import{NumericFormat as u}from"react-number-format";function d(d){let{value:f,onChange:p,formValidator:m,label:h,error:g,className:_,style:v,allowNegative:y=!1,decimalSeparator:b,thousandSeparator:x,prefix:S,suffix:C,decimalScale:w,fixedDecimalScale:T=!0,placeholder:E,sign:D,showArrows:O=!1,step:k=1,readOnly:A=!1,onKeyDown:j,...M}=e(`NumberInput`,d),N=m==null?f:m.value,P=D!=null&&N!=null?Math.abs(Number(N)):N,F=P==null?``:String(P);function I(e){let t=e;t!==void 0&&(D===`-`&&(t=-Math.abs(t)),D===`+`&&(t=Math.abs(t))),m?.set(t??null),p?.(t)}function L(e){if(A)return;let t=(N!=null&&N!==``?Number(N):0)+e;!y&&D!==`-`&&(t=Math.max(0,t)),D===`-`&&(t=Math.min(0,t)),I(t)}function R(e){if(A){j?.(e);return}if(e.key===`ArrowUp`){e.preventDefault(),L(e.shiftKey?k*10:k);return}if(e.key===`ArrowDown`){e.preventDefault(),L(e.shiftKey?-k*10:-k);return}j?.(e)}let z=D===`-`?`-`:D===`+`?`+`:S,B=O&&!A?l(`div`,{className:r.arrows,children:[c(t,{className:r.arrowBtn,tabIndex:-1,onMouseDown:e=>{e.preventDefault(),L(e.shiftKey?k*10:k)},children:c(a,{icon:s})}),c(t,{className:r.arrowBtn,tabIndex:-1,onMouseDown:e=>{e.preventDefault(),L(e.shiftKey?-k*10:-k)},children:c(a,{icon:o})})]}):null;return c(n,{label:h,className:i(r.numberInput,_),style:v,value:F,onChange:()=>{},formValidator:null,isValid:m?m.touched?!m.hasError():!0:!g,errorMessage:m?m.getCurrentErrorMessage()??``:g??``,placeholder:E,readOnly:A,suffix:B,inputMode:w===0?`numeric`:`decimal`,customInput:c(u,{onValueChange:e=>I(e.floatValue),allowNegative:D==null?y:!1,decimalSeparator:b,thousandSeparator:x,decimalScale:w,fixedDecimalScale:T,prefix:z,suffix:C,onKeyDown:O?R:j,...M})})}export{d as default};
|
|
2
2
|
//# sourceMappingURL=numberInput.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"numberInput.mjs","names":[],"sources":["../../../../package/common/numberInput/numberInput.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport React from 'react';\nimport cx from 'classnames';\nimport { NumericFormat, NumericFormatProps } from 'react-number-format';\nimport type { FormValidator } from 'services/formValidation';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { faChevronUp, faChevronDown } from '@fortawesome/free-solid-svg-icons';\n\nimport styles from './numberInput.module.pcss';\nimport Input from '../input';\nimport InteractableDiv from '../interactableDiv';\nimport { useComponentDefaults } from '../configProvider';\n\nexport interface NumberInputProps\n extends Omit<NumericFormatProps, 'onValueChange' | 'value' | 'customInput' | 'onChange' | 'step' | 'onKeyDown'> {\n value?: number | string;\n onChange?: (value: number | undefined) => void;\n formValidator?: FormValidator | null;\n label?: string;\n error?: string;\n className?: string;\n allowNegative?: boolean;\n decimalSeparator?: string;\n thousandSeparator?: string | boolean;\n prefix?: string;\n suffix?: string;\n decimalScale?: number;\n /**\n * Whether to pad the value to exactly `decimalScale` decimals. Default `true`\n * (e.g. with `decimalScale={2}`, `12` displays as `12.00`). Set `false` to make\n * `decimalScale` an upper limit only — the user may type fewer decimals and they\n * are kept as-is (`12` stays `12`, `12.1` stays `12.1`), while anything beyond\n * `decimalScale` is still truncated.\n */\n fixedDecimalScale?: boolean;\n placeholder?: string;\n sign?: '+' | '-';\n showArrows?: boolean;\n step?: number;\n readOnly?: boolean;\n onKeyDown?: (e: React.KeyboardEvent<HTMLInputElement>) => void;\n}\n\nfunction NumberInput(props: NumberInputProps): ReactElement {\n const {\n value,\n onChange,\n formValidator,\n label,\n error,\n className,\n allowNegative = false,\n decimalSeparator,\n thousandSeparator,\n prefix,\n suffix,\n decimalScale,\n fixedDecimalScale = true,\n placeholder,\n sign,\n showArrows = false,\n step = 1,\n readOnly = false,\n onKeyDown: onKeyDownProp,\n ...rest\n } = useComponentDefaults('NumberInput', props);\n const rawValue = formValidator != null ? formValidator.value as number | string : value;\n // When a sign is forced, display the absolute value — the prefix character carries the sign visually.\n const displayValue = sign != null && rawValue != null ? Math.abs(Number(rawValue)) : rawValue;\n const controlledValue = displayValue != null ? String(displayValue) : '';\n\n function handleValueChange(floatValue: number | undefined) {\n let out = floatValue;\n if (out !== undefined) {\n if (sign === '-') out = -Math.abs(out);\n if (sign === '+') out = Math.abs(out);\n }\n if (formValidator != null) formValidator.set(out ?? null);\n onChange?.(out);\n }\n\n function handleStep(delta: number) {\n if (readOnly) return;\n const current = rawValue != null && rawValue !== '' ? Number(rawValue) : 0;\n let next = current + delta;\n if (!allowNegative && sign !== '-') next = Math.max(0, next);\n if (sign === '-') next = Math.min(0, next);\n handleValueChange(next);\n }\n\n function handleKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {\n if (readOnly) { onKeyDownProp?.(e); return; }\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n handleStep(e.shiftKey ? step * 10 : step);\n return;\n }\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n handleStep(e.shiftKey ? -step * 10 : -step);\n return;\n }\n onKeyDownProp?.(e);\n }\n\n const resolvedPrefix = sign === '-' ? '-' : sign === '+' ? '+' : prefix;\n\n const arrowSuffix = showArrows && !readOnly ? (\n <div className={styles.arrows}>\n <InteractableDiv\n className={styles.arrowBtn}\n tabIndex={-1}\n onMouseDown={(e) => { e.preventDefault(); handleStep(e.shiftKey ? step * 10 : step); }}\n >\n <FontAwesomeIcon icon={faChevronUp} />\n </InteractableDiv>\n <InteractableDiv\n className={styles.arrowBtn}\n tabIndex={-1}\n onMouseDown={(e) => { e.preventDefault(); handleStep(e.shiftKey ? -step * 10 : -step); }}\n >\n <FontAwesomeIcon icon={faChevronDown} />\n </InteractableDiv>\n </div>\n ) : null;\n\n return (\n <Input\n label={label}\n className={cx(styles.numberInput, className)}\n value={controlledValue}\n onChange={() => {}}\n formValidator={null}\n isValid={formValidator ? (formValidator.touched ? !formValidator.hasError() : true) : !error}\n errorMessage={formValidator ? (formValidator.getCurrentErrorMessage() ?? '') : (error ?? '')}\n placeholder={placeholder}\n readOnly={readOnly}\n suffix={arrowSuffix}\n inputMode={decimalScale === 0 ? 'numeric' : 'decimal'}\n customInput={\n <NumericFormat\n onValueChange={(vals) => handleValueChange(vals.floatValue)}\n allowNegative={sign != null ? false : allowNegative}\n decimalSeparator={decimalSeparator}\n thousandSeparator={thousandSeparator}\n decimalScale={decimalScale}\n fixedDecimalScale={fixedDecimalScale}\n prefix={resolvedPrefix}\n suffix={suffix}\n onKeyDown={showArrows ? handleKeyDown : onKeyDownProp}\n {...rest}\n />\n }\n />\n );\n}\n\nexport default NumberInput;\n"],"mappings":"0eA2CA,SAAS,EAAY,EAAuC,CAC1D,GAAM,CACN,QACA,WACA,gBACA,QACA,QACA,YACA,gBAAgB,GAChB,mBACA,oBACA,SACA,SACA,eACA,oBAAoB,GACpB,cACA,OACA,aAAa,GACb,OAAO,EACP,WAAW,GACX,UAAW,EACX,GAAG,GACC,EAAqB,cAAe,CAAK,EACvC,EAAW,GAAiB,KAAgD,EAAzC,EAAc,MAEjD,EAAe,GAAQ,MAAQ,GAAY,KAAO,KAAK,IAAI,OAAO,CAAQ,CAAC,EAAI,EAC/E,EAAkB,GAAgB,KAA8B,GAAvB,OAAO,CAAY,EAElE,SAAS,EAAkB,EAAgC,CACzD,IAAI,EAAM,EACN,IAAQ,IAAA,KACN,IAAS,MAAK,EAAM,CAAC,KAAK,IAAI,CAAG,GACjC,IAAS,MAAK,EAAO,KAAK,IAAI,CAAG,IAEnC,GAAqC,IAAI,GAAO,IAAI,EACxD,IAAW,CAAG,CAChB,CAEA,SAAS,EAAW,EAAe,CACjC,GAAI,EAAU,OAEd,IAAI,GADY,GAAY,MAAQ,IAAa,GAAK,OAAO,CAAQ,EAAI,GACpD,EACjB,CAAC,GAAiB,IAAS,MAAK,EAAO,KAAK,IAAI,EAAG,CAAI,GACvD,IAAS,MAAK,EAAO,KAAK,IAAI,EAAG,CAAI,GACzC,EAAkB,CAAI,CACxB,CAEA,SAAS,EAAc,EAA0C,CAC/D,GAAI,EAAU,CAAE,IAAgB,CAAC,EAAG,MAAQ,CAC5C,GAAI,EAAE,MAAQ,UAAW,CACvB,EAAE,eAAe,EACjB,EAAW,EAAE,SAAW,EAAO,GAAK,CAAI,EACxC,MACF,CACA,GAAI,EAAE,MAAQ,YAAa,CACzB,EAAE,eAAe,EACjB,EAAW,EAAE,SAAW,CAAC,EAAO,GAAK,CAAC,CAAI,EAC1C,MACF,CACA,IAAgB,CAAC,CACnB,CAEA,IAAM,EAAiB,IAAS,IAAM,IAAM,IAAS,IAAM,IAAM,EAE3D,EAAc,GAAc,CAAC,EACjC,EAAC,MAAD,CAAK,UAAW,EAAO,gBAAvB,CACE,EAAC,EAAD,CACE,UAAW,EAAO,SAClB,SAAU,GACV,YAAc,GAAM,CAAE,EAAE,eAAe,EAAG,EAAW,EAAE,SAAW,EAAO,GAAK,CAAI,CAAG,WAErF,EAAC,EAAD,CAAiB,KAAM,CAAc,CAAA,CACtB,CAAA,EACjB,EAAC,EAAD,CACE,UAAW,EAAO,SAClB,SAAU,GACV,YAAc,GAAM,CAAE,EAAE,eAAe,EAAG,EAAW,EAAE,SAAW,CAAC,EAAO,GAAK,CAAC,CAAI,CAAG,WAEvF,EAAC,EAAD,CAAiB,KAAM,CAAgB,CAAA,CACxB,CAAA,CACd,IACH,KAEJ,OACE,EAAC,EAAD,CACS,QACP,UAAW,EAAG,EAAO,YAAa,CAAS,
|
|
1
|
+
{"version":3,"file":"numberInput.mjs","names":[],"sources":["../../../../package/common/numberInput/numberInput.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport React from 'react';\nimport cx from 'classnames';\nimport { NumericFormat, NumericFormatProps } from 'react-number-format';\nimport type { FormValidator } from 'services/formValidation';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { faChevronUp, faChevronDown } from '@fortawesome/free-solid-svg-icons';\n\nimport styles from './numberInput.module.pcss';\nimport Input from '../input';\nimport InteractableDiv from '../interactableDiv';\nimport { useComponentDefaults } from '../configProvider';\n\nexport interface NumberInputProps\n extends Omit<NumericFormatProps, 'onValueChange' | 'value' | 'customInput' | 'onChange' | 'step' | 'onKeyDown'> {\n value?: number | string;\n onChange?: (value: number | undefined) => void;\n formValidator?: FormValidator | null;\n label?: string;\n error?: string;\n className?: string;\n allowNegative?: boolean;\n decimalSeparator?: string;\n thousandSeparator?: string | boolean;\n prefix?: string;\n suffix?: string;\n decimalScale?: number;\n /**\n * Whether to pad the value to exactly `decimalScale` decimals. Default `true`\n * (e.g. with `decimalScale={2}`, `12` displays as `12.00`). Set `false` to make\n * `decimalScale` an upper limit only — the user may type fewer decimals and they\n * are kept as-is (`12` stays `12`, `12.1` stays `12.1`), while anything beyond\n * `decimalScale` is still truncated.\n */\n fixedDecimalScale?: boolean;\n placeholder?: string;\n sign?: '+' | '-';\n showArrows?: boolean;\n step?: number;\n readOnly?: boolean;\n onKeyDown?: (e: React.KeyboardEvent<HTMLInputElement>) => void;\n}\n\nfunction NumberInput(props: NumberInputProps): ReactElement {\n const {\n value,\n onChange,\n formValidator,\n label,\n error,\n className,\n style,\n allowNegative = false,\n decimalSeparator,\n thousandSeparator,\n prefix,\n suffix,\n decimalScale,\n fixedDecimalScale = true,\n placeholder,\n sign,\n showArrows = false,\n step = 1,\n readOnly = false,\n onKeyDown: onKeyDownProp,\n ...rest\n } = useComponentDefaults('NumberInput', props);\n const rawValue = formValidator != null ? formValidator.value as number | string : value;\n // When a sign is forced, display the absolute value — the prefix character carries the sign visually.\n const displayValue = sign != null && rawValue != null ? Math.abs(Number(rawValue)) : rawValue;\n const controlledValue = displayValue != null ? String(displayValue) : '';\n\n function handleValueChange(floatValue: number | undefined) {\n let out = floatValue;\n if (out !== undefined) {\n if (sign === '-') out = -Math.abs(out);\n if (sign === '+') out = Math.abs(out);\n }\n if (formValidator != null) formValidator.set(out ?? null);\n onChange?.(out);\n }\n\n function handleStep(delta: number) {\n if (readOnly) return;\n const current = rawValue != null && rawValue !== '' ? Number(rawValue) : 0;\n let next = current + delta;\n if (!allowNegative && sign !== '-') next = Math.max(0, next);\n if (sign === '-') next = Math.min(0, next);\n handleValueChange(next);\n }\n\n function handleKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {\n if (readOnly) { onKeyDownProp?.(e); return; }\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n handleStep(e.shiftKey ? step * 10 : step);\n return;\n }\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n handleStep(e.shiftKey ? -step * 10 : -step);\n return;\n }\n onKeyDownProp?.(e);\n }\n\n const resolvedPrefix = sign === '-' ? '-' : sign === '+' ? '+' : prefix;\n\n const arrowSuffix = showArrows && !readOnly ? (\n <div className={styles.arrows}>\n <InteractableDiv\n className={styles.arrowBtn}\n tabIndex={-1}\n onMouseDown={(e) => { e.preventDefault(); handleStep(e.shiftKey ? step * 10 : step); }}\n >\n <FontAwesomeIcon icon={faChevronUp} />\n </InteractableDiv>\n <InteractableDiv\n className={styles.arrowBtn}\n tabIndex={-1}\n onMouseDown={(e) => { e.preventDefault(); handleStep(e.shiftKey ? -step * 10 : -step); }}\n >\n <FontAwesomeIcon icon={faChevronDown} />\n </InteractableDiv>\n </div>\n ) : null;\n\n return (\n <Input\n label={label}\n className={cx(styles.numberInput, className)}\n style={style}\n value={controlledValue}\n onChange={() => {}}\n formValidator={null}\n isValid={formValidator ? (formValidator.touched ? !formValidator.hasError() : true) : !error}\n errorMessage={formValidator ? (formValidator.getCurrentErrorMessage() ?? '') : (error ?? '')}\n placeholder={placeholder}\n readOnly={readOnly}\n suffix={arrowSuffix}\n inputMode={decimalScale === 0 ? 'numeric' : 'decimal'}\n customInput={\n <NumericFormat\n onValueChange={(vals) => handleValueChange(vals.floatValue)}\n allowNegative={sign != null ? false : allowNegative}\n decimalSeparator={decimalSeparator}\n thousandSeparator={thousandSeparator}\n decimalScale={decimalScale}\n fixedDecimalScale={fixedDecimalScale}\n prefix={resolvedPrefix}\n suffix={suffix}\n onKeyDown={showArrows ? handleKeyDown : onKeyDownProp}\n {...rest}\n />\n }\n />\n );\n}\n\nexport default NumberInput;\n"],"mappings":"0eA2CA,SAAS,EAAY,EAAuC,CAC1D,GAAM,CACN,QACA,WACA,gBACA,QACA,QACA,YACA,QACA,gBAAgB,GAChB,mBACA,oBACA,SACA,SACA,eACA,oBAAoB,GACpB,cACA,OACA,aAAa,GACb,OAAO,EACP,WAAW,GACX,UAAW,EACX,GAAG,GACC,EAAqB,cAAe,CAAK,EACvC,EAAW,GAAiB,KAAgD,EAAzC,EAAc,MAEjD,EAAe,GAAQ,MAAQ,GAAY,KAAO,KAAK,IAAI,OAAO,CAAQ,CAAC,EAAI,EAC/E,EAAkB,GAAgB,KAA8B,GAAvB,OAAO,CAAY,EAElE,SAAS,EAAkB,EAAgC,CACzD,IAAI,EAAM,EACN,IAAQ,IAAA,KACN,IAAS,MAAK,EAAM,CAAC,KAAK,IAAI,CAAG,GACjC,IAAS,MAAK,EAAO,KAAK,IAAI,CAAG,IAEnC,GAAqC,IAAI,GAAO,IAAI,EACxD,IAAW,CAAG,CAChB,CAEA,SAAS,EAAW,EAAe,CACjC,GAAI,EAAU,OAEd,IAAI,GADY,GAAY,MAAQ,IAAa,GAAK,OAAO,CAAQ,EAAI,GACpD,EACjB,CAAC,GAAiB,IAAS,MAAK,EAAO,KAAK,IAAI,EAAG,CAAI,GACvD,IAAS,MAAK,EAAO,KAAK,IAAI,EAAG,CAAI,GACzC,EAAkB,CAAI,CACxB,CAEA,SAAS,EAAc,EAA0C,CAC/D,GAAI,EAAU,CAAE,IAAgB,CAAC,EAAG,MAAQ,CAC5C,GAAI,EAAE,MAAQ,UAAW,CACvB,EAAE,eAAe,EACjB,EAAW,EAAE,SAAW,EAAO,GAAK,CAAI,EACxC,MACF,CACA,GAAI,EAAE,MAAQ,YAAa,CACzB,EAAE,eAAe,EACjB,EAAW,EAAE,SAAW,CAAC,EAAO,GAAK,CAAC,CAAI,EAC1C,MACF,CACA,IAAgB,CAAC,CACnB,CAEA,IAAM,EAAiB,IAAS,IAAM,IAAM,IAAS,IAAM,IAAM,EAE3D,EAAc,GAAc,CAAC,EACjC,EAAC,MAAD,CAAK,UAAW,EAAO,gBAAvB,CACE,EAAC,EAAD,CACE,UAAW,EAAO,SAClB,SAAU,GACV,YAAc,GAAM,CAAE,EAAE,eAAe,EAAG,EAAW,EAAE,SAAW,EAAO,GAAK,CAAI,CAAG,WAErF,EAAC,EAAD,CAAiB,KAAM,CAAc,CAAA,CACtB,CAAA,EACjB,EAAC,EAAD,CACE,UAAW,EAAO,SAClB,SAAU,GACV,YAAc,GAAM,CAAE,EAAE,eAAe,EAAG,EAAW,EAAE,SAAW,CAAC,EAAO,GAAK,CAAC,CAAI,CAAG,WAEvF,EAAC,EAAD,CAAiB,KAAM,CAAgB,CAAA,CACxB,CAAA,CACd,IACH,KAEJ,OACE,EAAC,EAAD,CACS,QACP,UAAW,EAAG,EAAO,YAAa,CAAS,EACpC,QACP,MAAO,EACP,aAAgB,CAAC,EACjB,cAAe,KACf,QAAS,EAAiB,EAAc,QAAU,CAAC,EAAc,SAAS,EAAI,GAAQ,CAAC,EACvF,aAAc,EAAiB,EAAc,uBAAuB,GAAK,GAAO,GAAS,GAC5E,cACH,WACV,OAAQ,EACR,UAAW,IAAiB,EAAI,UAAY,UAC5C,YACE,EAAC,EAAD,CACE,cAAgB,GAAS,EAAkB,EAAK,UAAU,EAC1D,cAAe,GAAQ,KAAe,EAAR,GACZ,mBACC,oBACL,eACK,oBACnB,OAAQ,EACA,SACR,UAAW,EAAa,EAAgB,EACxC,GAAI,CACL,CAAA,CAEJ,CAAA,CAEL"}
|
|
@@ -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:
|
|
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: 0px -10px;\n padding: 0px 10px;\n\n &:hover {\n background-color: var(--background-accent-light);\n }\n &:focus-visible {\n outline: 2px solid 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 &:has(svg) {\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\n &-dot-primary {\n background-color: var(--primary-color);\n }\n &-dot-success {\n background-color: var(--success-color);\n }\n &-dot-warn {\n background-color: var(--warn-color);\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 &-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 &-alternate &-marker {\n grid-column: 2;\n grid-row: 1;\n }\n &-alternate &-content {\n grid-column: 1;\n grid-row: 1;\n text-align: right;\n }\n &-alternate &-header {\n flex-direction: row-reverse;\n }\n &-alternate &-item-right &-content {\n grid-column: 3;\n text-align: left;\n }\n &-alternate &-item-right &-header {\n flex-direction: row;\n }\n}\n"],"mappings":""}
|