@ahrowe/ui 0.4.4 → 0.5.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/checkbox/checkbox.mjs +1 -1
- package/dist/esm/common/checkbox/checkbox.mjs.map +1 -1
- package/dist/esm/common/confirmModal/confirmModal.mjs +1 -1
- package/dist/esm/common/confirmModal/confirmModal.mjs.map +1 -1
- package/dist/esm/common/dropdown/dropdown.mjs +1 -1
- package/dist/esm/common/dropdown/dropdown.mjs.map +1 -1
- package/dist/esm/common/dropdown/dropdown.module.mjs.map +1 -1
- package/dist/esm/common/input/input.mjs +1 -1
- package/dist/esm/common/input/input.mjs.map +1 -1
- package/dist/esm/common/input/input.module.mjs +1 -1
- package/dist/esm/common/input/input.module.mjs.map +1 -1
- package/dist/esm/common/themeProvider/defaultTheme.mjs +1 -1
- package/dist/esm/common/themeProvider/defaultTheme.mjs.map +1 -1
- package/dist/esm/common/virtualList/useColumns.mjs +1 -1
- package/dist/esm/common/virtualList/useColumns.mjs.map +1 -1
- package/dist/esm/common/virtualList/virtualList.mjs +1 -1
- package/dist/esm/common/virtualList/virtualList.mjs.map +1 -1
- package/dist/esm/common/virtualList/virtualList.module.mjs.map +1 -1
- package/dist/esm/common/virtualList/virtualList.utils.mjs +1 -1
- package/dist/esm/common/virtualList/virtualList.utils.mjs.map +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/style.css +1 -1
- package/dist/types/package/common/configProvider/configProvider.types.d.ts +2 -0
- package/dist/types/package/common/confirmModal/confirmModal.d.ts +1 -1
- package/dist/types/package/common/confirmModal/confirmModal.types.d.ts +3 -0
- package/dist/types/package/common/themeProvider/theme.types.d.ts +1 -0
- package/dist/types/package/common/virtualList/useColumns.d.ts +0 -1
- package/dist/types/package/common/virtualList/virtualList.types.d.ts +21 -0
- package/docs/ConfigProvider.md +1 -0
- package/docs/ConfirmModal.md +25 -0
- package/docs/VirtualList.md +30 -0
- package/package.json +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import t from"../loading/spinnerLoading/index.mjs";import n from"../ripple/ripple.mjs";import r from"./checkbox.module.mjs";import{useEffect as i,useRef as a,useState as o}from"react";import s from"classnames";import{jsx as c,jsxs as l}from"react/jsx-runtime";function u(u){let{label:d=``,selected:f=!1,onToggle:p=()=>{},className:m=``,style:h,disabled:g=!1,lineHeight:_=``,title:v=``,tabIndex:y=0,cursorDefault:b=!1,width:x=`17px`,height:S=`17px`,formValidator:C=null,children:w=null,background:T=null,isLoading:E=!1,classNames:D,styles:O,...k}=e(`Checkbox`,u),A=a(null),[,j]=o(0);i(()=>{if(!C)return;let e=()=>j(e=>e+1);return C.registerOnUpdateListener(e),()=>C.removeOnUpdateListener(e)},[C]);function M(e){g||E||(A.current?.addRipple(),C&&C.set(!C.value),p(!f,e))}let N=C?C.value:f;return l(`div`,{...k,className:s(r.checkbox,{[r.checkboxDisabled]:g,[r.checkboxPointer]:!b},m),style:h,onClick:M,onKeyPress:e=>{e.key===`Enter`&&M(e)},role:`checkbox`,"aria-checked":N,tabIndex:y,children:[c(`div`,{title:v,className:s(r.checkboxIcon,E?r.checkboxLoading:null,D?.icon),style:O?.icon,children:E?c(`div`,{style:{width:x,height:S},children:c(t,{className:r.checkboxLoadingSpinner})}):l(`div`,{style:{width:x,height:S,...O?.checkmark},className:s(r.checkboxCheckmark,N&&r.checkboxCheckmarkChecked,D?.checkmark),children:[c(n,{ref:A,manualOnly:!0,overflowHidden:!1,rippleAnimationLength:.3,rippleBackground:`radial-gradient(transparent, var(--primary-color))`}),c(`svg`,{strokeLinejoin:`round`,strokeLinecap:`round`,xmlns:`http://www.w3.org/2000/svg`,viewBox:`-0.5 -1.5 4 2.6`,width:`calc(${x} + 1px)`,height:`calc(${S} + 1px)`,...T?{style:{background:T}}:{},children:c(`path`,{d:`M 0 0 l 1 1 l 2 -2`,strokeWidth:`0.4`,fill:`none`})})]})}),c(`div`,{className:D?.label,style:{lineHeight:_||`100%`,...O?.label},children:w||d})]})}export{u as default};
|
|
1
|
+
import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import t from"../loading/spinnerLoading/index.mjs";import n from"../ripple/ripple.mjs";import r from"./checkbox.module.mjs";import{useEffect as i,useRef as a,useState as o}from"react";import s from"classnames";import{jsx as c,jsxs as l}from"react/jsx-runtime";function u(u){let{label:d=``,selected:f=!1,onToggle:p=()=>{},className:m=``,style:h,disabled:g=!1,lineHeight:_=``,title:v=``,tabIndex:y=0,cursorDefault:b=!1,width:x=`17px`,height:S=`17px`,formValidator:C=null,children:w=null,background:T=null,isLoading:E=!1,classNames:D,styles:O,...k}=e(`Checkbox`,u),A=a(null),[,j]=o(0);i(()=>{if(!C)return;let e=()=>j(e=>e+1);return C.registerOnUpdateListener(e),()=>C.removeOnUpdateListener(e)},[C]);function M(e){g||E||(A.current?.addRipple(),C&&C.set(!C.value),p(!f,e))}let N=C?C.value:f;return l(`div`,{...k,className:s(r.checkbox,{[r.checkboxDisabled]:g,[r.checkboxPointer]:!b},m),style:h,onClick:M,onKeyPress:e=>{e.key===`Enter`&&M(e)},role:`checkbox`,"aria-checked":N,"aria-disabled":g||void 0,tabIndex:y,children:[c(`div`,{title:v,className:s(r.checkboxIcon,E?r.checkboxLoading:null,D?.icon),style:O?.icon,children:E?c(`div`,{style:{width:x,height:S},children:c(t,{className:r.checkboxLoadingSpinner})}):l(`div`,{style:{width:x,height:S,...O?.checkmark},className:s(r.checkboxCheckmark,N&&r.checkboxCheckmarkChecked,D?.checkmark),children:[c(n,{ref:A,manualOnly:!0,overflowHidden:!1,rippleAnimationLength:.3,rippleBackground:`radial-gradient(transparent, var(--primary-color))`}),c(`svg`,{strokeLinejoin:`round`,strokeLinecap:`round`,xmlns:`http://www.w3.org/2000/svg`,viewBox:`-0.5 -1.5 4 2.6`,width:`calc(${x} + 1px)`,height:`calc(${S} + 1px)`,...T?{style:{background:T}}:{},children:c(`path`,{d:`M 0 0 l 1 1 l 2 -2`,strokeWidth:`0.4`,fill:`none`})})]})}),c(`div`,{className:D?.label,style:{lineHeight:_||`100%`,...O?.label},children:w||d})]})}export{u as default};
|
|
2
2
|
//# sourceMappingURL=checkbox.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkbox.mjs","names":[],"sources":["../../../../package/common/checkbox/checkbox.tsx"],"sourcesContent":["import { useRef, useEffect, useState, type ReactElement } from 'react';\nimport cx from 'classnames';\nimport Ripple from 'components/common/ripple';\nimport SpinnerLoading from '../loading/spinnerLoading';\nimport { useComponentDefaults } from '../configProvider';\n\nimport type { CheckboxProps } from './checkbox.types';\nimport styles from './checkbox.module.pcss';\n\nfunction Checkbox(props: CheckboxProps): ReactElement {\n const {\n label = '',\n selected = false,\n onToggle = () => {},\n className = '',\n style,\n disabled = false,\n lineHeight = '',\n title = '',\n tabIndex = 0,\n cursorDefault = false,\n width = '17px',\n height = '17px',\n formValidator = null,\n children = null,\n background = null,\n isLoading = false,\n classNames,\n styles: slotStyles,\n ...rest\n } = useComponentDefaults('Checkbox', props);\n const rippleRef = useRef<{ addRipple: () => void }>(null);\n const [, forceUpdate] = useState(0);\n\n useEffect(() => {\n if (!formValidator) return;\n const listener = () => forceUpdate((n) => n + 1);\n formValidator.registerOnUpdateListener(listener);\n return () => formValidator.removeOnUpdateListener(listener);\n }, [formValidator]);\n\n function handleToggle(event?: React.MouseEvent | React.KeyboardEvent) {\n if (disabled || isLoading) return;\n rippleRef.current?.addRipple();\n if (formValidator) {\n formValidator.set(!formValidator.value);\n }\n onToggle(!selected, event);\n }\n\n const currSelected = (formValidator ? formValidator.value : selected) as boolean;\n\n return (\n <div\n {...rest}\n className={cx(\n styles.checkbox,\n {\n [styles.checkboxDisabled]: disabled,\n [styles.checkboxPointer]: !cursorDefault,\n },\n className\n )}\n style={style}\n onClick={handleToggle}\n onKeyPress={(e) => { if (e.key === 'Enter') handleToggle(e); }}\n role=\"checkbox\"\n aria-checked={currSelected}\n tabIndex={tabIndex}\n >\n <div\n title={title}\n className={cx(styles.checkboxIcon, isLoading ? styles.checkboxLoading : null, classNames?.icon)}\n style={slotStyles?.icon}\n >\n {isLoading ? (\n <div style={{ width, height }}>\n <SpinnerLoading className={styles.checkboxLoadingSpinner} />\n </div>\n ) : (\n <div\n style={{ width, height, ...slotStyles?.checkmark }}\n className={cx(\n styles.checkboxCheckmark,\n currSelected && styles.checkboxCheckmarkChecked,\n classNames?.checkmark\n )}\n >\n <Ripple\n ref={rippleRef}\n manualOnly\n overflowHidden={false}\n rippleAnimationLength={0.3}\n rippleBackground=\"radial-gradient(transparent, var(--primary-color))\"\n />\n <svg\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"-0.5 -1.5 4 2.6\"\n width={`calc(${width} + 1px)`}\n height={`calc(${height} + 1px)`}\n {...(background ? { style: { background } } : {})}\n >\n <path d=\"M 0 0 l 1 1 l 2 -2\" strokeWidth=\"0.4\" fill=\"none\" />\n </svg>\n </div>\n )}\n </div>\n <div className={classNames?.label} style={{ lineHeight: lineHeight || '100%', ...slotStyles?.label }}>{children || label}</div>\n </div>\n );\n}\n\nexport default Checkbox;\n"],"mappings":"sVASA,SAAS,EAAS,EAAoC,CACpD,GAAM,CACN,QAAQ,GACR,WAAW,GACX,eAAiB,CAAC,EAClB,YAAY,GACZ,QACA,WAAW,GACX,aAAa,GACb,QAAQ,GACR,WAAW,EACX,gBAAgB,GAChB,QAAQ,OACR,SAAS,OACT,gBAAgB,KAChB,WAAW,KACX,aAAa,KACb,YAAY,GACZ,aACA,OAAQ,EACR,GAAG,GACC,EAAqB,WAAY,CAAK,EACpC,EAAY,EAAkC,IAAI,EAClD,EAAG,GAAe,EAAS,CAAC,EAElC,MAAgB,CACd,GAAI,CAAC,EAAe,OACpB,IAAM,MAAiB,EAAa,GAAM,EAAI,CAAC,EAE/C,OADA,EAAc,yBAAyB,CAAQ,MAClC,EAAc,uBAAuB,CAAQ,CAC5D,EAAG,CAAC,CAAa,CAAC,EAElB,SAAS,EAAa,EAAgD,CAChE,GAAY,IAChB,EAAU,SAAS,UAAU,EACzB,GACF,EAAc,IAAI,CAAC,EAAc,KAAK,EAExC,EAAS,CAAC,EAAU,CAAK,EAC3B,CAEA,IAAM,EAAgB,EAAgB,EAAc,MAAQ,EAE5D,OACE,EAAC,MAAD,CACE,GAAI,EACJ,UAAW,EACT,EAAO,SACP,EACG,EAAO,kBAAmB,GAC1B,EAAO,iBAAkB,CAAC,CAC7B,EACA,CACF,EACO,QACP,QAAS,EACT,WAAa,GAAM,CAAM,EAAE,MAAQ,SAAS,EAAa,CAAC,CAAG,EAC7D,KAAK,WACL,eAAc,
|
|
1
|
+
{"version":3,"file":"checkbox.mjs","names":[],"sources":["../../../../package/common/checkbox/checkbox.tsx"],"sourcesContent":["import { useRef, useEffect, useState, type ReactElement } from 'react';\nimport cx from 'classnames';\nimport Ripple from 'components/common/ripple';\nimport SpinnerLoading from '../loading/spinnerLoading';\nimport { useComponentDefaults } from '../configProvider';\n\nimport type { CheckboxProps } from './checkbox.types';\nimport styles from './checkbox.module.pcss';\n\nfunction Checkbox(props: CheckboxProps): ReactElement {\n const {\n label = '',\n selected = false,\n onToggle = () => {},\n className = '',\n style,\n disabled = false,\n lineHeight = '',\n title = '',\n tabIndex = 0,\n cursorDefault = false,\n width = '17px',\n height = '17px',\n formValidator = null,\n children = null,\n background = null,\n isLoading = false,\n classNames,\n styles: slotStyles,\n ...rest\n } = useComponentDefaults('Checkbox', props);\n const rippleRef = useRef<{ addRipple: () => void }>(null);\n const [, forceUpdate] = useState(0);\n\n useEffect(() => {\n if (!formValidator) return;\n const listener = () => forceUpdate((n) => n + 1);\n formValidator.registerOnUpdateListener(listener);\n return () => formValidator.removeOnUpdateListener(listener);\n }, [formValidator]);\n\n function handleToggle(event?: React.MouseEvent | React.KeyboardEvent) {\n if (disabled || isLoading) return;\n rippleRef.current?.addRipple();\n if (formValidator) {\n formValidator.set(!formValidator.value);\n }\n onToggle(!selected, event);\n }\n\n const currSelected = (formValidator ? formValidator.value : selected) as boolean;\n\n return (\n <div\n {...rest}\n className={cx(\n styles.checkbox,\n {\n [styles.checkboxDisabled]: disabled,\n [styles.checkboxPointer]: !cursorDefault,\n },\n className\n )}\n style={style}\n onClick={handleToggle}\n onKeyPress={(e) => { if (e.key === 'Enter') handleToggle(e); }}\n role=\"checkbox\"\n aria-checked={currSelected}\n aria-disabled={disabled || undefined}\n tabIndex={tabIndex}\n >\n <div\n title={title}\n className={cx(styles.checkboxIcon, isLoading ? styles.checkboxLoading : null, classNames?.icon)}\n style={slotStyles?.icon}\n >\n {isLoading ? (\n <div style={{ width, height }}>\n <SpinnerLoading className={styles.checkboxLoadingSpinner} />\n </div>\n ) : (\n <div\n style={{ width, height, ...slotStyles?.checkmark }}\n className={cx(\n styles.checkboxCheckmark,\n currSelected && styles.checkboxCheckmarkChecked,\n classNames?.checkmark\n )}\n >\n <Ripple\n ref={rippleRef}\n manualOnly\n overflowHidden={false}\n rippleAnimationLength={0.3}\n rippleBackground=\"radial-gradient(transparent, var(--primary-color))\"\n />\n <svg\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"-0.5 -1.5 4 2.6\"\n width={`calc(${width} + 1px)`}\n height={`calc(${height} + 1px)`}\n {...(background ? { style: { background } } : {})}\n >\n <path d=\"M 0 0 l 1 1 l 2 -2\" strokeWidth=\"0.4\" fill=\"none\" />\n </svg>\n </div>\n )}\n </div>\n <div className={classNames?.label} style={{ lineHeight: lineHeight || '100%', ...slotStyles?.label }}>{children || label}</div>\n </div>\n );\n}\n\nexport default Checkbox;\n"],"mappings":"sVASA,SAAS,EAAS,EAAoC,CACpD,GAAM,CACN,QAAQ,GACR,WAAW,GACX,eAAiB,CAAC,EAClB,YAAY,GACZ,QACA,WAAW,GACX,aAAa,GACb,QAAQ,GACR,WAAW,EACX,gBAAgB,GAChB,QAAQ,OACR,SAAS,OACT,gBAAgB,KAChB,WAAW,KACX,aAAa,KACb,YAAY,GACZ,aACA,OAAQ,EACR,GAAG,GACC,EAAqB,WAAY,CAAK,EACpC,EAAY,EAAkC,IAAI,EAClD,EAAG,GAAe,EAAS,CAAC,EAElC,MAAgB,CACd,GAAI,CAAC,EAAe,OACpB,IAAM,MAAiB,EAAa,GAAM,EAAI,CAAC,EAE/C,OADA,EAAc,yBAAyB,CAAQ,MAClC,EAAc,uBAAuB,CAAQ,CAC5D,EAAG,CAAC,CAAa,CAAC,EAElB,SAAS,EAAa,EAAgD,CAChE,GAAY,IAChB,EAAU,SAAS,UAAU,EACzB,GACF,EAAc,IAAI,CAAC,EAAc,KAAK,EAExC,EAAS,CAAC,EAAU,CAAK,EAC3B,CAEA,IAAM,EAAgB,EAAgB,EAAc,MAAQ,EAE5D,OACE,EAAC,MAAD,CACE,GAAI,EACJ,UAAW,EACT,EAAO,SACP,EACG,EAAO,kBAAmB,GAC1B,EAAO,iBAAkB,CAAC,CAC7B,EACA,CACF,EACO,QACP,QAAS,EACT,WAAa,GAAM,CAAM,EAAE,MAAQ,SAAS,EAAa,CAAC,CAAG,EAC7D,KAAK,WACL,eAAc,EACd,gBAAe,GAAY,IAAA,GACjB,oBAhBZ,CAkBE,EAAC,MAAD,CACS,QACP,UAAW,EAAG,EAAO,aAAc,EAAY,EAAO,gBAAkB,KAAM,GAAY,IAAI,EAC9F,MAAO,GAAY,cAElB,EACC,EAAC,MAAD,CAAK,MAAO,CAAE,QAAO,QAAO,WAC1B,EAAC,EAAD,CAAgB,UAAW,EAAO,sBAAyB,CAAA,CACxD,CAAA,EAEL,EAAC,MAAD,CACE,MAAO,CAAE,QAAO,SAAQ,GAAG,GAAY,SAAU,EACjD,UAAW,EACT,EAAO,kBACP,GAAgB,EAAO,yBACvB,GAAY,SACd,WANF,CAQE,EAAC,EAAD,CACE,IAAK,EACL,WAAA,GACA,eAAgB,GAChB,sBAAuB,GACvB,iBAAiB,oDAClB,CAAA,EACD,EAAC,MAAD,CACE,eAAe,QACf,cAAc,QACd,MAAM,6BACN,QAAQ,kBACR,MAAO,QAAQ,EAAM,SACrB,OAAQ,QAAQ,EAAO,SACvB,GAAK,EAAa,CAAE,MAAO,CAAE,YAAW,CAAE,EAAI,CAAC,WAE/C,EAAC,OAAD,CAAM,EAAE,qBAAqB,YAAY,MAAM,KAAK,MAAQ,CAAA,CACzD,CAAA,CACF,GAEJ,CAAA,EACL,EAAC,MAAD,CAAK,UAAW,GAAY,MAAO,MAAO,CAAE,WAAY,GAAc,OAAQ,GAAG,GAAY,KAAM,WAAI,GAAY,CAAW,CAAA,CAC3H,GAET"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import e from"../actionButtons/actionButtons.mjs";import
|
|
1
|
+
import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{ButtonStyleType as t}from"../button/button.types.mjs";import n from"../actionButtons/actionButtons.mjs";import r from"../modal/modal.mjs";import{useState as i}from"react";import{jsx as a,jsxs as o}from"react/jsx-runtime";function s(s){let{children:c=null,className:l=``,onClose:u=()=>{},onConfirm:d=()=>{},title:f=``,content:p=null,isOpen:m=void 0,submitLabel:h=`Confirm`,cancelLabel:g=`Cancel`,isDelete:_=!1,actionButtonsProps:v={}}=e(`ConfirmModal`,s),[y,b]=i(!1),[x,S]=i(!1);function C(e=!1){b(!1),u(e)}async function w(){S(!0);try{await d(),C(!0)}finally{S(!1)}}let T=o(r,{title:f,isOpen:m===void 0?y:m,onClose:()=>C(),className:c?void 0:l,children:[p,a(n,{onClose:()=>C(),onSubmit:w,submitLabel:h,cancelLabel:g,submitButtonStyle:_?t.Delete:void 0,isSubmitButtonLoading:x,...v})]});return c?o(`div`,{className:l,children:[a(`span`,{onClick:()=>b(!0),children:c}),T]}):T}export{s as default};
|
|
2
2
|
//# sourceMappingURL=confirmModal.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"confirmModal.mjs","names":[],"sources":["../../../../package/common/confirmModal/confirmModal.tsx"],"sourcesContent":["import { useState, type ReactElement } from 'react';\n\nimport Modal from '../modal';\nimport { ActionButtons } from '../actionButtons';\nimport type { ConfirmModalProps } from './confirmModal.types';\n\nfunction ConfirmModal({\n children = null,\n className = '',\n onClose = () => {},\n onConfirm = () => {},\n title = '',\n content = null,\n isOpen: propIsOpen = undefined,\n actionButtonsProps = {},\n}
|
|
1
|
+
{"version":3,"file":"confirmModal.mjs","names":[],"sources":["../../../../package/common/confirmModal/confirmModal.tsx"],"sourcesContent":["import { useState, type ReactElement } from 'react';\n\nimport Modal from '../modal';\nimport { ActionButtons } from '../actionButtons';\nimport { ButtonStyleType } from '../button';\nimport { useComponentDefaults } from '../configProvider';\nimport type { ConfirmModalProps } from './confirmModal.types';\n\nfunction ConfirmModal(props: ConfirmModalProps): ReactElement {\n const {\n children = null,\n className = '',\n onClose = () => {},\n onConfirm = () => {},\n title = '',\n content = null,\n isOpen: propIsOpen = undefined,\n submitLabel = 'Confirm',\n cancelLabel = 'Cancel',\n isDelete = false,\n actionButtonsProps = {},\n } = useComponentDefaults('ConfirmModal', props);\n const [internalOpen, setInternalOpen] = useState(false);\n const [isSubmitting, setIsSubmitting] = useState(false);\n\n function handleClose(didSubmit = false) {\n setInternalOpen(false);\n onClose(didSubmit);\n }\n\n async function handleConfirm() {\n setIsSubmitting(true);\n try {\n await onConfirm();\n handleClose(true);\n } finally {\n setIsSubmitting(false);\n }\n }\n\n const isOpen = propIsOpen === undefined ? internalOpen : propIsOpen;\n\n const modal = (\n <Modal title={title} isOpen={isOpen} onClose={() => handleClose()} className={children ? undefined : className}>\n {content}\n <ActionButtons\n onClose={() => handleClose()}\n onSubmit={handleConfirm}\n submitLabel={submitLabel}\n cancelLabel={cancelLabel}\n submitButtonStyle={isDelete ? ButtonStyleType.Delete : undefined}\n isSubmitButtonLoading={isSubmitting}\n {...actionButtonsProps}\n />\n </Modal>\n );\n\n if (!children) return modal;\n\n return (\n <div className={className}>\n <span onClick={() => setInternalOpen(true)}>{children}</span>\n {modal}\n </div>\n );\n}\n\nexport default ConfirmModal;\n"],"mappings":"sTAQA,SAAS,EAAa,EAAwC,CAC5D,GAAM,CACN,WAAW,KACX,YAAY,GACZ,cAAgB,CAAC,EACjB,gBAAkB,CAAC,EACnB,QAAQ,GACR,UAAU,KACV,OAAQ,EAAa,IAAA,GACrB,cAAc,UACd,cAAc,SACd,WAAW,GACX,qBAAqB,CAAC,GAClB,EAAqB,eAAgB,CAAK,EACxC,CAAC,EAAc,GAAmB,EAAS,EAAK,EAChD,CAAC,EAAc,GAAmB,EAAS,EAAK,EAEtD,SAAS,EAAY,EAAY,GAAO,CACtC,EAAgB,EAAK,EACrB,EAAQ,CAAS,CACnB,CAEA,eAAe,GAAgB,CAC7B,EAAgB,EAAI,EACpB,GAAI,CACF,MAAM,EAAU,EAChB,EAAY,EAAI,CAClB,QAAU,CACR,EAAgB,EAAK,CACvB,CACF,CAIA,IAAM,EACJ,EAAC,EAAD,CAAc,QAAe,OAHhB,IAAe,IAAA,GAAY,EAAe,EAGlB,YAAe,EAAY,EAAG,UAAW,EAAW,IAAA,GAAY,WAArG,CACG,EACD,EAAC,EAAD,CACE,YAAe,EAAY,EAC3B,SAAU,EACG,cACA,cACb,kBAAmB,EAAW,EAAgB,OAAS,IAAA,GACvD,sBAAuB,EACvB,GAAI,CACL,CAAA,CACI,IAKT,OAFK,EAGH,EAAC,MAAD,CAAgB,qBAAhB,CACE,EAAC,OAAD,CAAM,YAAe,EAAgB,EAAI,EAAI,UAAe,CAAA,EAC3D,CACE,IANe,CAQxB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import t from"../bodyEnd/bodyEnd.mjs";import{useFloatingPosition as n}from"../floatingMenu/useFloatingPosition.mjs";import r from"../tooltip/tooltip.mjs";import i from"../infiniteBlock/infiniteBlock.mjs";import a from"./dropdown.module.mjs";import{useEffect as o,useRef as s,useState as c}from"react";import l from"classnames";import{FontAwesomeIcon as ee}from"@fortawesome/react-fontawesome";import{faChevronDown as u}from"@fortawesome/free-solid-svg-icons";import{jsx as d,jsxs as f}from"react/jsx-runtime";import p from"downshift";function m(m){let{errorMessage:h=``,className:
|
|
1
|
+
import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import t from"../bodyEnd/bodyEnd.mjs";import{useFloatingPosition as n}from"../floatingMenu/useFloatingPosition.mjs";import r from"../tooltip/tooltip.mjs";import i from"../infiniteBlock/infiniteBlock.mjs";import a from"./dropdown.module.mjs";import{useEffect as o,useRef as s,useState as c}from"react";import l from"classnames";import{FontAwesomeIcon as ee}from"@fortawesome/react-fontawesome";import{faChevronDown as u}from"@fortawesome/free-solid-svg-icons";import{jsx as d,jsxs as f}from"react/jsx-runtime";import p from"downshift";function m(m){let{errorMessage:h=``,className:g=``,label:_=``,value:te=``,isValid:v=!0,tabIndex:y=0,isRequired:b=!1,customProps:x={},isRow:S=!1,disabled:C=!1,onScroll:w=()=>Promise.resolve(),onClick:T,onChange:E,onFocus:ne=null,onBlur:re=null,onMouseEnter:ie=null,onMouseLeave:ae=null,dropdownLabel:oe,isDropdownListWider:D=!1,inputClassName:se=``,dropDownIconClassName:ce=``,dropDownClassName:le=``,formValidator:O=null,labelClassName:ue=``,dropDownInputClassName:de=``,items:k=[],useMatLabelStyle:A=!0,alwaysFloatLabel:j=!1,placeholder:M=``,plainStyle:N=!1,scrollToSelected:P=!1,reactRef:F,...I}=e(`Dropdown`,m),[L,R]=c(!1),[z,B]=c(!1),[,V]=c(0),H=s(O),U=s(null),W=s(null),[G,fe]=c(!1),[pe,me]=c(10);o(()=>{if(G){let e=U.current?.getBoundingClientRect();me(e?.width??10)}},[G]),n({isOpen:G,triggerRef:U,anchorRef:W,panelRef:W,flipClassName:a.dropdownInputListAnimFlip}),o(()=>{if(H.current=O,!H.current)return;H.current.label=_??``,H.current.validate();let e=()=>V(e=>e+1);return H.current.registerOnUpdateListener(e),()=>H.current?.removeOnUpdateListener(e)},[O,_]);let he=e=>{B(!0),ie?.(e)},ge=e=>{B(!1),ae?.(e)},_e=e=>{R(!0),ne?.(e)},ve=e=>{H.current&&(H.current.touched=!0),R(!1),re?.(e)},ye=()=>O?O.touched&&O.hasError():!v||!!h,K=()=>!!(b||O?.validators.find(e=>e.validatorId===`required`)),q=e=>{O?(O.set(e),E?.(O.value,x)):E?.(e,x)},J=oe,Y=O?O.value:te,X=ye();k.forEach(e=>{e.key===Y&&(J=e.label)});let Z=J||Y,Q=Z==null||typeof Z==`string`&&Z.trim()===``,$=K()?d(`span`,{className:a.requiredMark,children:`*`}):null,be=_&&K()?`${_} *`:_;return f(`div`,{...I,className:l(g,a.dropdownLabel,a.dropdown,{[a.dropdownLabelColumn]:!S}),onMouseEnter:he,onMouseLeave:ge,children:[d(p,{onChange:e=>q((e||{key:``}).key),itemToString:e=>e?String(e.key):``,selectedItem:k.find(e=>e.key===Y)??null,onStateChange:e=>{typeof e.isOpen==`boolean`&&fe(e.isOpen)},stateReducer:(e,t)=>P&&Object.prototype.hasOwnProperty.call(t,`isOpen`)?{...t,highlightedIndex:t.isOpen?k.indexOf(e.selectedItem):null}:t,children:({getItemProps:e,getToggleButtonProps:n,isOpen:r,selectedItem:o,highlightedIndex:s,setHighlightedIndex:c})=>d(`div`,{children:f(`div`,{ref:U,onFocus:_e,onBlur:ve,className:l(a.dropdownInput,{[a.dropdownInputPlain]:N},de),children:[d(`button`,{tabIndex:y,type:`button`,disabled:C,style:D?{padding:`6px`,border:`none`}:{},className:l(a.dropdownInputButton,{[a.dropdownInputButtonDisabled]:C},se),...n(),onClick:e=>{n().onClick?.(e),T?.(e)},ref:F,children:Q?`\xA0`:Z}),d(`button`,{type:`button`,tabIndex:-1,disabled:C,className:l(a.dropdownInputButtonIcon,ce),...n(),onClick:e=>{n().onClick?.(e),T?.(e)},children:!C&&d(ee,{icon:u,className:l(a.dropdownInputButtonIconArrow,{[a.dropdownInputButtonIconArrowOpen]:r})})}),!C&&r?d(t,{children:d(`div`,{ref:W,className:l(a.dropdownInputListAnim,{[a.dropdownInputListAnimWider]:D}),style:{width:`${pe}px`},children:d(i,{onScroll:w,className:a.dropdownInputList,setHighlightedIndex:c,children:k.map((t,n)=>d(`div`,{...e({index:n,item:t,disabled:!!t.disabled}),className:l(a.dropdownInputListItem,le,{[a.dropdownInputListItemActive]:s===n,[a.dropdownInputListItemSelected]:o===t,[a.dropdownInputListItemDisabled]:!!t.disabled}),children:t.label},t.key))})})}):null,d(`fieldset`,{className:l(a.dropdownFieldset,{[a.dropdownBorderPlain]:N,[a.dropdownBorderFocused]:L,[a.dropdownBorderInvalid]:X,[a.dropdownBorderError]:X}),children:d(`legend`,{className:l(a.dropdownFieldsetLegend,{[a.dropdownFieldsetLegendActive]:A&&(j||L||!Q)}),children:d(`span`,{children:be})})}),A&&_&&f(`div`,{className:l(a.dropdownMatLabel,{[a.dropdownMatLabelFloating]:j||L||!Q}),children:[_,$]}),A&&M&&d(`div`,{className:l(a.dropdownPlaceholder,L&&!J&&a.dropdownPlaceholderShown),children:M})]})})}),_&&!A&&f(`div`,{className:l(a.dropdownLabelText,ue),children:[_,$]}),d(r,{variant:`error`,message:O?O.getCurrentErrorMessage():h||``,isVisible:X&&(L||z)})]})}export{m as default};
|
|
2
2
|
//# sourceMappingURL=dropdown.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dropdown.mjs","names":[],"sources":["../../../../package/common/dropdown/dropdown.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef } from 'react';\nimport cx from 'classnames';\nimport InfiniteBlock from 'components/common/infiniteBlock';\nimport BodyEnd from 'components/common/bodyEnd';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { faChevronDown as dropdownIcon } from '@fortawesome/free-solid-svg-icons';\nimport Downshift, { StateChangeOptions, DownshiftState } from 'downshift';\nimport Tooltip from 'components/common/tooltip';\n\nimport { useFloatingPosition } from '../floatingMenu/useFloatingPosition';\nimport { useComponentDefaults } from '../configProvider';\nimport styles from './dropdown.module.pcss';\nimport type { DropdownProps, DropdownItem } from './dropdown.types';\n\nfunction Dropdown(props: DropdownProps) {\n const {\n errorMessage = '',\n className = '',\n label = '',\n value = '',\n isValid = true,\n tabIndex = 0,\n isRequired = false,\n customProps = {},\n isRow = false,\n disabled = false,\n onScroll = () => Promise.resolve(),\n onClick,\n onChange,\n onFocus: onFocusProp = null,\n onBlur: onBlurProp = null,\n onMouseEnter: onMouseEnterProp = null,\n onMouseLeave: onMouseLeaveProp = null,\n dropdownLabel: dropdownLabelProp,\n isDropdownListWider = false,\n inputClassName = '',\n dropDownIconClassName = '',\n dropDownClassName = '',\n formValidator = null,\n labelClassName = '',\n dropDownInputClassName = '',\n items = [],\n useMatLabelStyle = true,\n alwaysFloatLabel = false,\n placeholder = '',\n plainStyle = false,\n scrollToSelected = false,\n reactRef,\n ...rest\n } = useComponentDefaults('Dropdown', props);\n const [isFocused, setIsFocused] = useState(false);\n const [isHovered, setIsHovered] = useState(false);\n const [, forceUpdate] = useState(0);\n const fvRef = useRef(formValidator);\n const triggerRef = useRef<HTMLDivElement>(null);\n const anchorRef = useRef<HTMLDivElement>(null);\n const [menuIsOpen, setMenuIsOpen] = useState(false);\n const [triggerWidth, setTriggerWidth] = useState(10);\n\n useEffect(() => {\n if (menuIsOpen) {\n const rect = triggerRef.current?.getBoundingClientRect();\n setTriggerWidth(rect?.width ?? 10);\n }\n }, [menuIsOpen]);\n\n useFloatingPosition({\n isOpen: menuIsOpen,\n triggerRef,\n anchorRef,\n panelRef: anchorRef,\n flipClassName: styles.dropdownInputListAnimFlip,\n });\n\n useEffect(() => {\n fvRef.current = formValidator;\n if (!fvRef.current) return;\n fvRef.current.label = label ?? '';\n fvRef.current.validate();\n const listener = () => forceUpdate(n => n + 1);\n fvRef.current.registerOnUpdateListener(listener);\n return () => fvRef.current?.removeOnUpdateListener(listener);\n }, [formValidator, label]);\n\n const onMouseEnterHandler = (event: React.MouseEvent) => {\n setIsHovered(true);\n onMouseEnterProp?.(event);\n };\n\n const onMouseLeaveHandler = (event: React.MouseEvent) => {\n setIsHovered(false);\n onMouseLeaveProp?.(event);\n };\n\n const onFocusHandler = (event: React.FocusEvent) => {\n setIsFocused(true);\n onFocusProp?.(event);\n };\n\n const onBlurHandler = (event: React.FocusEvent) => {\n if (fvRef.current) fvRef.current.touched = true;\n setIsFocused(false);\n onBlurProp?.(event);\n };\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?.validators.find(\n (v) => (v as { validatorId?: string }).validatorId === 'required'\n ));\n };\n\n const onChangeHandler = (val: string | number): void => {\n if (formValidator) {\n formValidator.set(val);\n onChange?.(formValidator.value, customProps);\n } else {\n onChange?.(val, customProps);\n }\n };\n\n let dropdownLabel = dropdownLabelProp;\n const currentValue = formValidator ? formValidator.value as string | number : value;\n const hasErr = hasError();\n\n items.forEach((item: DropdownItem) => {\n if (item.key === currentValue) {\n dropdownLabel = item.label as string;\n }\n });\n\n const displayValue = dropdownLabel || currentValue;\n const isDisplayBlank =\n displayValue == null ||\n (typeof displayValue === 'string' && displayValue.trim() === '');\n\n return (\n <div\n {...rest}\n className={cx(className, styles.dropdownLabel, styles.dropdown, {\n [styles.dropdownLabelColumn]: !isRow,\n })}\n onMouseEnter={onMouseEnterHandler}\n onMouseLeave={onMouseLeaveHandler}\n >\n <Downshift\n onChange={(selection: DropdownItem | null) => onChangeHandler((selection || { key: '' }).key)}\n itemToString={(item: DropdownItem | null) => (item ? String(item.key) : '')}\n selectedItem={items.find((el) => el.key === currentValue) ?? null}\n onStateChange={(changes: StateChangeOptions<DropdownItem>) => {\n if (typeof changes.isOpen === 'boolean') setMenuIsOpen(changes.isOpen);\n }}\n stateReducer={(state: DownshiftState<DropdownItem>, changes: StateChangeOptions<DropdownItem>) => {\n if (scrollToSelected && Object.prototype.hasOwnProperty.call(changes, 'isOpen')) {\n return {\n ...changes,\n highlightedIndex: changes.isOpen ? items.indexOf(state.selectedItem as DropdownItem) : null,\n };\n }\n return changes;\n }}\n >\n {({\n getItemProps,\n getToggleButtonProps,\n isOpen,\n selectedItem,\n highlightedIndex,\n setHighlightedIndex,\n }) => (\n <div>\n <div\n ref={triggerRef}\n onFocus={onFocusHandler}\n onBlur={onBlurHandler}\n className={cx(\n styles.dropdownInput,\n { [styles.dropdownInputPlain]: plainStyle },\n dropDownInputClassName\n )}\n >\n <button\n tabIndex={tabIndex}\n type=\"button\"\n disabled={disabled}\n style={isDropdownListWider ? { padding: '6px', border: 'none' } : {}}\n className={cx(\n styles.dropdownInputButton,\n { [styles.dropdownInputButtonDisabled]: disabled },\n inputClassName\n )}\n {...getToggleButtonProps()}\n onClick={(e: React.MouseEvent<HTMLButtonElement>) => {\n getToggleButtonProps().onClick?.(e);\n onClick?.(e);\n }}\n ref={reactRef}\n >\n {/* Non-breaking space when blank (same text-node layout as a\n real value) so the button keeps a full line of height. */}\n {isDisplayBlank ? '\\u00A0' : displayValue}\n </button>\n <button\n type=\"button\"\n tabIndex={-1}\n disabled={disabled}\n className={cx(styles.dropdownInputButtonIcon, dropDownIconClassName)}\n {...getToggleButtonProps()}\n onClick={(e: React.MouseEvent<HTMLButtonElement>) => {\n getToggleButtonProps().onClick?.(e);\n onClick?.(e);\n }}\n >\n {!disabled && (\n <FontAwesomeIcon\n icon={dropdownIcon}\n className={cx(styles.dropdownInputButtonIconArrow, {\n [styles.dropdownInputButtonIconArrowOpen]: isOpen,\n })}\n />\n )}\n </button>\n {!disabled && isOpen ? (\n <BodyEnd>\n <div\n ref={anchorRef}\n className={cx(styles.dropdownInputListAnim, {\n [styles.dropdownInputListAnimWider]: isDropdownListWider,\n })}\n style={{ width: `${triggerWidth}px` }}\n >\n <InfiniteBlock\n onScroll={onScroll}\n className={styles.dropdownInputList}\n setHighlightedIndex={setHighlightedIndex}\n >\n {items.map((item: DropdownItem, index: number) => (\n <div\n key={item.key}\n {...getItemProps({ index, item, disabled: !!item.disabled })}\n className={cx(styles.dropdownInputListItem, dropDownClassName, {\n [styles.dropdownInputListItemActive]: highlightedIndex === index,\n [styles.dropdownInputListItemSelected]: selectedItem === item,\n [styles.dropdownInputListItemDisabled]: !!item.disabled,\n })}\n >\n {item.label}\n </div>\n ))}\n </InfiniteBlock>\n </div>\n </BodyEnd>\n ) : null}\n <fieldset\n className={cx(styles.dropdownFieldset, {\n [styles.dropdownBorderPlain]: plainStyle,\n [styles.dropdownBorderFocused]: isFocused,\n [styles.dropdownBorderInvalid]: hasErr,\n [styles.dropdownBorderError]: hasErr,\n })}\n >\n <legend\n className={cx(styles.dropdownFieldsetLegend, {\n [styles.dropdownFieldsetLegendActive]:\n useMatLabelStyle && (alwaysFloatLabel || isFocused || !isDisplayBlank),\n })}\n >\n <span>{label}</span>\n </legend>\n </fieldset>\n {useMatLabelStyle && label && (\n <div\n className={cx(styles.dropdownMatLabel, {\n [styles.dropdownMatLabelFloating]: alwaysFloatLabel || isFocused || !isDisplayBlank,\n })}\n >\n {label}\n </div>\n )}\n {useMatLabelStyle && placeholder && (\n <div\n className={cx(\n styles.dropdownPlaceholder,\n isFocused && !dropdownLabel && styles.dropdownPlaceholderShown\n )}\n >\n {placeholder}\n </div>\n )}\n </div>\n </div>\n )}\n </Downshift>\n {label && !useMatLabelStyle && (\n <div className={cx(styles.dropdownLabelText, labelClassName)}>\n {label}\n {computedIsRequired() ? <div className={styles.requiredMark}>*</div> : null}\n </div>\n )}\n <Tooltip\n variant=\"error\"\n message={formValidator ? formValidator.getCurrentErrorMessage() : (errorMessage || '')}\n isVisible={hasErr && (isFocused || isHovered)}\n />\n </div>\n );\n}\n\nexport default Dropdown;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dropdown.mjs","names":[],"sources":["../../../../package/common/dropdown/dropdown.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef } from 'react';\nimport cx from 'classnames';\nimport InfiniteBlock from 'components/common/infiniteBlock';\nimport BodyEnd from 'components/common/bodyEnd';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { faChevronDown as dropdownIcon } from '@fortawesome/free-solid-svg-icons';\nimport Downshift, { StateChangeOptions, DownshiftState } from 'downshift';\nimport Tooltip from 'components/common/tooltip';\n\nimport { useFloatingPosition } from '../floatingMenu/useFloatingPosition';\nimport { useComponentDefaults } from '../configProvider';\nimport styles from './dropdown.module.pcss';\nimport type { DropdownProps, DropdownItem } from './dropdown.types';\n\nfunction Dropdown(props: DropdownProps) {\n const {\n errorMessage = '',\n className = '',\n label = '',\n value = '',\n isValid = true,\n tabIndex = 0,\n isRequired = false,\n customProps = {},\n isRow = false,\n disabled = false,\n onScroll = () => Promise.resolve(),\n onClick,\n onChange,\n onFocus: onFocusProp = null,\n onBlur: onBlurProp = null,\n onMouseEnter: onMouseEnterProp = null,\n onMouseLeave: onMouseLeaveProp = null,\n dropdownLabel: dropdownLabelProp,\n isDropdownListWider = false,\n inputClassName = '',\n dropDownIconClassName = '',\n dropDownClassName = '',\n formValidator = null,\n labelClassName = '',\n dropDownInputClassName = '',\n items = [],\n useMatLabelStyle = true,\n alwaysFloatLabel = false,\n placeholder = '',\n plainStyle = false,\n scrollToSelected = false,\n reactRef,\n ...rest\n } = useComponentDefaults('Dropdown', props);\n const [isFocused, setIsFocused] = useState(false);\n const [isHovered, setIsHovered] = useState(false);\n const [, forceUpdate] = useState(0);\n const fvRef = useRef(formValidator);\n const triggerRef = useRef<HTMLDivElement>(null);\n const anchorRef = useRef<HTMLDivElement>(null);\n const [menuIsOpen, setMenuIsOpen] = useState(false);\n const [triggerWidth, setTriggerWidth] = useState(10);\n\n useEffect(() => {\n if (menuIsOpen) {\n const rect = triggerRef.current?.getBoundingClientRect();\n setTriggerWidth(rect?.width ?? 10);\n }\n }, [menuIsOpen]);\n\n useFloatingPosition({\n isOpen: menuIsOpen,\n triggerRef,\n anchorRef,\n panelRef: anchorRef,\n flipClassName: styles.dropdownInputListAnimFlip,\n });\n\n useEffect(() => {\n fvRef.current = formValidator;\n if (!fvRef.current) return;\n fvRef.current.label = label ?? '';\n fvRef.current.validate();\n const listener = () => forceUpdate(n => n + 1);\n fvRef.current.registerOnUpdateListener(listener);\n return () => fvRef.current?.removeOnUpdateListener(listener);\n }, [formValidator, label]);\n\n const onMouseEnterHandler = (event: React.MouseEvent) => {\n setIsHovered(true);\n onMouseEnterProp?.(event);\n };\n\n const onMouseLeaveHandler = (event: React.MouseEvent) => {\n setIsHovered(false);\n onMouseLeaveProp?.(event);\n };\n\n const onFocusHandler = (event: React.FocusEvent) => {\n setIsFocused(true);\n onFocusProp?.(event);\n };\n\n const onBlurHandler = (event: React.FocusEvent) => {\n if (fvRef.current) fvRef.current.touched = true;\n setIsFocused(false);\n onBlurProp?.(event);\n };\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?.validators.find(\n (v) => (v as { validatorId?: string }).validatorId === 'required'\n ));\n };\n\n const onChangeHandler = (val: string | number): void => {\n if (formValidator) {\n formValidator.set(val);\n onChange?.(formValidator.value, customProps);\n } else {\n onChange?.(val, customProps);\n }\n };\n\n let dropdownLabel = dropdownLabelProp;\n const currentValue = formValidator ? formValidator.value as string | number : value;\n const hasErr = hasError();\n\n items.forEach((item: DropdownItem) => {\n if (item.key === currentValue) {\n dropdownLabel = item.label as string;\n }\n });\n\n const displayValue = dropdownLabel || currentValue;\n const isDisplayBlank =\n displayValue == null ||\n (typeof displayValue === 'string' && displayValue.trim() === '');\n\n const requiredMark = computedIsRequired() ? <span className={styles.requiredMark}>*</span> : null;\n const editedLabel = label && computedIsRequired() ? `${label} *` : label;\n\n return (\n <div\n {...rest}\n className={cx(className, styles.dropdownLabel, styles.dropdown, {\n [styles.dropdownLabelColumn]: !isRow,\n })}\n onMouseEnter={onMouseEnterHandler}\n onMouseLeave={onMouseLeaveHandler}\n >\n <Downshift\n onChange={(selection: DropdownItem | null) => onChangeHandler((selection || { key: '' }).key)}\n itemToString={(item: DropdownItem | null) => (item ? String(item.key) : '')}\n selectedItem={items.find((el) => el.key === currentValue) ?? null}\n onStateChange={(changes: StateChangeOptions<DropdownItem>) => {\n if (typeof changes.isOpen === 'boolean') setMenuIsOpen(changes.isOpen);\n }}\n stateReducer={(state: DownshiftState<DropdownItem>, changes: StateChangeOptions<DropdownItem>) => {\n if (scrollToSelected && Object.prototype.hasOwnProperty.call(changes, 'isOpen')) {\n return {\n ...changes,\n highlightedIndex: changes.isOpen ? items.indexOf(state.selectedItem as DropdownItem) : null,\n };\n }\n return changes;\n }}\n >\n {({\n getItemProps,\n getToggleButtonProps,\n isOpen,\n selectedItem,\n highlightedIndex,\n setHighlightedIndex,\n }) => (\n <div>\n <div\n ref={triggerRef}\n onFocus={onFocusHandler}\n onBlur={onBlurHandler}\n className={cx(\n styles.dropdownInput,\n { [styles.dropdownInputPlain]: plainStyle },\n dropDownInputClassName\n )}\n >\n <button\n tabIndex={tabIndex}\n type=\"button\"\n disabled={disabled}\n style={isDropdownListWider ? { padding: '6px', border: 'none' } : {}}\n className={cx(\n styles.dropdownInputButton,\n { [styles.dropdownInputButtonDisabled]: disabled },\n inputClassName\n )}\n {...getToggleButtonProps()}\n onClick={(e: React.MouseEvent<HTMLButtonElement>) => {\n getToggleButtonProps().onClick?.(e);\n onClick?.(e);\n }}\n ref={reactRef}\n >\n {/* Non-breaking space when blank (same text-node layout as a\n real value) so the button keeps a full line of height. */}\n {isDisplayBlank ? '\\u00A0' : displayValue}\n </button>\n <button\n type=\"button\"\n tabIndex={-1}\n disabled={disabled}\n className={cx(styles.dropdownInputButtonIcon, dropDownIconClassName)}\n {...getToggleButtonProps()}\n onClick={(e: React.MouseEvent<HTMLButtonElement>) => {\n getToggleButtonProps().onClick?.(e);\n onClick?.(e);\n }}\n >\n {!disabled && (\n <FontAwesomeIcon\n icon={dropdownIcon}\n className={cx(styles.dropdownInputButtonIconArrow, {\n [styles.dropdownInputButtonIconArrowOpen]: isOpen,\n })}\n />\n )}\n </button>\n {!disabled && isOpen ? (\n <BodyEnd>\n <div\n ref={anchorRef}\n className={cx(styles.dropdownInputListAnim, {\n [styles.dropdownInputListAnimWider]: isDropdownListWider,\n })}\n style={{ width: `${triggerWidth}px` }}\n >\n <InfiniteBlock\n onScroll={onScroll}\n className={styles.dropdownInputList}\n setHighlightedIndex={setHighlightedIndex}\n >\n {items.map((item: DropdownItem, index: number) => (\n <div\n key={item.key}\n {...getItemProps({ index, item, disabled: !!item.disabled })}\n className={cx(styles.dropdownInputListItem, dropDownClassName, {\n [styles.dropdownInputListItemActive]: highlightedIndex === index,\n [styles.dropdownInputListItemSelected]: selectedItem === item,\n [styles.dropdownInputListItemDisabled]: !!item.disabled,\n })}\n >\n {item.label}\n </div>\n ))}\n </InfiniteBlock>\n </div>\n </BodyEnd>\n ) : null}\n <fieldset\n className={cx(styles.dropdownFieldset, {\n [styles.dropdownBorderPlain]: plainStyle,\n [styles.dropdownBorderFocused]: isFocused,\n [styles.dropdownBorderInvalid]: hasErr,\n [styles.dropdownBorderError]: hasErr,\n })}\n >\n <legend\n className={cx(styles.dropdownFieldsetLegend, {\n [styles.dropdownFieldsetLegendActive]:\n useMatLabelStyle && (alwaysFloatLabel || isFocused || !isDisplayBlank),\n })}\n >\n <span>{editedLabel}</span>\n </legend>\n </fieldset>\n {useMatLabelStyle && label && (\n <div\n className={cx(styles.dropdownMatLabel, {\n [styles.dropdownMatLabelFloating]: alwaysFloatLabel || isFocused || !isDisplayBlank,\n })}\n >\n {label}\n {requiredMark}\n </div>\n )}\n {useMatLabelStyle && placeholder && (\n <div\n className={cx(\n styles.dropdownPlaceholder,\n isFocused && !dropdownLabel && styles.dropdownPlaceholderShown\n )}\n >\n {placeholder}\n </div>\n )}\n </div>\n </div>\n )}\n </Downshift>\n {label && !useMatLabelStyle && (\n <div className={cx(styles.dropdownLabelText, labelClassName)}>\n {label}\n {requiredMark}\n </div>\n )}\n <Tooltip\n variant=\"error\"\n message={formValidator ? formValidator.getCurrentErrorMessage() : (errorMessage || '')}\n isVisible={hasErr && (isFocused || isHovered)}\n />\n </div>\n );\n}\n\nexport default Dropdown;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dropdown.module.mjs","names":[],"sources":["../../../../package/common/dropdown/dropdown.module.pcss"],"sourcesContent":["\n.required-mark {\n padding: 0px 0px 0px 4px;\n color: var(--
|
|
1
|
+
{"version":3,"file":"dropdown.module.mjs","names":[],"sources":["../../../../package/common/dropdown/dropdown.module.pcss"],"sourcesContent":["\n.required-mark {\n padding: 0px 0px 0px 4px;\n color: var(--required-mark-color, var(--error-color));\n}\n\n.dropdown {\n position: relative;\n\n &-label {\n display: flex;\n\n &-column {\n flex-direction: column;\n }\n\n &-text {\n white-space: nowrap;\n margin-right: 5px;\n margin-bottom: 5px;\n display: flex;\n align-items: center;\n color: var(--text-color);\n font-size: 12px;\n position: absolute;\n top: -15px;\n }\n }\n\n &-input {\n position: relative;\n cursor: pointer;\n background-color: var(--input-background);\n border-radius: var(--default-border-radius);\n\n &-plain {\n background: transparent;\n }\n\n &:focus-within {\n outline: none;\n }\n\n &-button {\n padding: 7px 20% 7px 7.5px !important;\n background-color: transparent;\n border: none;\n font-family: inherit;\n font-size: inherit;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n cursor: pointer;\n text-align: left;\n width: 100%;\n line-height: 1.25;\n color: var(--text-color);\n\n &-disabled {\n background-color: var(--disabled-input-color);\n color: var(--disabled-font-color);\n border-radius: var(--default-border-radius);\n }\n\n &:focus {\n outline: none;\n }\n\n &-icon {\n float: right;\n background-color: transparent;\n border: none;\n position: absolute;\n outline: none;\n right: var(--spacing-s);\n top: 50%;\n transform: translateY(-50%);\n color: var(--text-color);\n cursor: pointer;\n\n &-arrow {\n transition: transform 0.25s;\n pointer-events: none;\n\n &-open {\n transform: rotate(180deg);\n }\n }\n }\n }\n\n &-list-anim {\n position: fixed;\n z-index: 1;\n color: var(--text-color);\n background: var(--background-modal);\n box-shadow: var(--card-shadow);\n border-radius: var(--default-border-radius);\n overflow: hidden;\n transform: scaleY(1);\n transition: transform 0.25s;\n transform-origin: right top;\n\n &-flip {\n transform-origin: right bottom;\n }\n\n &-wider {\n width: max-content !important;\n }\n }\n\n &-list {\n width: 100%;\n display: flex;\n flex-direction: column;\n overflow-y: auto;\n max-height: 160px;\n list-style-type: none;\n\n &-item {\n border: none;\n cursor: pointer;\n background-color: var(--background-modal);\n padding: 8px;\n text-align: left;\n border-radius: 0;\n transition: all 0.3s;\n\n &-active {\n background-color: var(--background-accent);\n }\n\n &-selected {\n font-weight: 500;\n }\n\n &:focus {\n outline: none;\n }\n\n &:hover {\n background-color: var(--background-accent);\n }\n\n &-disabled {\n background-color: var(--disabled-input-color);\n color: var(--disabled-font-color);\n cursor: not-allowed;\n\n &:hover {\n background-color: var(--disabled-input-color);\n }\n }\n }\n\n &-hidden {\n transform: scaleY(0);\n }\n }\n }\n\n &-fieldset {\n position: absolute;\n width: 100%;\n margin: 0;\n box-sizing: border-box;\n border-radius: var(--default-border-radius);\n inset: -10px 0 0 0;\n padding-left: 8px;\n border-width: 1px;\n border-style: solid;\n border-color: var(--border-color);\n pointer-events: none;\n user-select: none;\n\n &-legend {\n display: block;\n max-width: 0;\n transition: max-width 0.2s;\n white-space: nowrap;\n padding: 0;\n\n &-active {\n max-width: 300px;\n }\n\n span {\n font-size: 13px;\n padding: 5px;\n opacity: 0;\n }\n\n /* With an empty label the span would still reserve its padding, leaving a gap in\n the fieldset's top border. Collapse it so the notch closes when there's no label. */\n span:empty {\n padding: 0.000001px;\n }\n }\n }\n\n &-placeholder {\n position: absolute;\n top: 8px;\n left: 7px;\n transition: all 0.2s;\n opacity: 0;\n\n &-shown {\n animation: 0.2s fadeIn 0.3s forwards;\n }\n }\n\n &-matLabel {\n position: absolute;\n transition: all 0.3s;\n inset: 9px 0 0 7px;\n font-size: 16px;\n color: var(--input-label-resting-color, var(--text-light));\n pointer-events: none;\n user-select: none;\n\n &-floating {\n inset: -9px 0 0 14px;\n font-size: 13px;\n color: var(--input-label-floating-color, var(--text-color));\n }\n }\n\n @keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 0.5;\n }\n }\n\n &-border {\n outline: 1px solid var(--border-color);\n transition: border-color;\n background-color: var(--input-background);\n outline: none;\n\n &-focused {\n outline-color: var(--primary-color);\n border-color: var(--primary-color);\n }\n\n &-searchFocused {\n outline-color: var(--search-input-color);\n outline-width: 2px;\n border-color: var(--search-input-color);\n }\n\n &-plain {\n border-color: transparent;\n outline-color: transparent;\n }\n\n &-invalid {\n outline-color: var(--error-border-color);\n border-color: var(--error-border-color);\n }\n\n &-invalid:hover {\n outline-color: var(--error-border-color);\n border-color: var(--error-border-color);\n }\n\n &-error {\n outline-color: var(--error-border-color);\n border-color: var(--error-border-color);\n }\n }\n}\n"],"mappings":""}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import t from"../tooltip/tooltip.mjs";import n from"./input.module.mjs";import{InputType as r}from"./input.types.mjs";import i,{useCallback as ee,useEffect as a,useId as te,useRef as
|
|
1
|
+
import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import t from"../tooltip/tooltip.mjs";import n from"./input.module.mjs";import{InputType as r}from"./input.types.mjs";import i,{useCallback as ee,useEffect as a,useId as te,useRef as o,useState as s}from"react";import c from"classnames";import{FontAwesomeIcon as l}from"@fortawesome/react-fontawesome";import{faEnvelope as ne,faEye as re,faEyeSlash as ie,faPen as ae,faPhone as oe,faSearch as se,faXmark as ce}from"@fortawesome/free-solid-svg-icons";import{jsx as u,jsxs as d}from"react/jsx-runtime";function le(le){let{name:f=``,id:ue,label:p=``,errorMessage:m=``,isValid:de=!0,className:fe=``,style:pe,value:h=``,icon:g=null,onChange:_=()=>{},onFocus:v=null,onBlur:y=null,onMouseEnter:b=null,onMouseLeave:x=null,isUppercase:me=!1,isRequired:he=!1,tabIndex:ge=0,type:S=void 0,isRow:_e=!1,onIconClick:C=null,parse:w=null,formValidator:T=null,autoFocus:E=!1,suffix:D=null,upperRightLabel:O=null,labelInBorder:ve=!1,showCancel:ye=!1,onClearClicked:be,min:xe=null,max:Se=null,placeholder:k=``,useMatLabelStyle:A=!0,alwaysFloatLabel:Ce=!1,autoComplete:we=null,onClick:Te=()=>null,readOnly:Ee=!1,customInput:j,alwaysShowCancel:De=!1,multiline:M=!1,rows:N,autoResize:P=!1,classNames:F,styles:I,disabled:Oe=!1,...ke}=e(`Input`,le),[L,R]=s(!1),[z,B]=s(!1),[V,Ae]=s(!1),[,je]=s(0),H=o(null),U=o(T),Me=te(),W=ue||f||Me,G=ee(()=>{let e=H.current;!e||!P||(e.style.height=`auto`,e.style.height=`${e.scrollHeight}px`)},[P]);a(()=>{G()},[]),a(()=>{E&&H.current&&setTimeout(()=>{H.current?.focus()},1)},[E]),a(()=>{U.current=T;let e=U.current;if(!e)return;e.label=p??``,e.validate();let t=()=>je(e=>e+1);return e.registerOnUpdateListener(t),()=>{e.removeOnUpdateListener(t)}},[T,p]);let Ne=()=>T?T.touched&&T.hasError():!de||!!m,K=()=>!!(he||T&&T.validators.find(e=>e.validatorId===`required`)),Pe=e=>{B(!0),b&&b(e)},Fe=e=>{B(!1),x&&x(e)},Ie=e=>{R(!0),v&&v(e)},Le=e=>{U.current&&(U.current.touched=!0),R(!1),y&&y(e)},Re=e=>{let t,n;typeof e==`string`?n=e:(t=e,n=e.target.value),w&&(n=w(n)),T&&T.set(n),_&&_(n,t),G()},ze=()=>{if(S!==`email`)return S===`password`&&V?`text`:S},q=S&&S!==r.Date&&S!==r.Iban&&S!==r.HasNoIcon,J=q&&!A&&(S===r.Email||S===r.Phone||S===r.Search),Y={className:c(n.inputFieldIcon,{[n.inputFieldIconNotClickable]:!C,[n.inputFieldIconLeft]:J}),onClick:C??void 0},X=g,Be=X?i.cloneElement(X,{className:c(n.inputFieldIcon,{[n.inputFieldIconNotClickable]:!C&&!X.props.onClick},X.props.className),onClick:C??X.props.onClick}):null,Ve=!!g,He={className:c(n.inputFieldIcon,n.inputFieldIconPassword),onClick:()=>Ae(!V)},Z=Ne(),Q=p;Q&&K()&&(Q=`${Q} *`);let Ue=K()?u(`span`,{className:n.requiredMark,children:`*`}):null,We=T?T.value:h,$=A&&(Ce||L||We||S===r.Date);return d(`div`,{className:c(n.input,fe),style:pe,children:[d(`label`,{htmlFor:W,className:c(n.inputLabel,F?.label,{[n.inputLabelColumn]:!_e,[n.inputLabelInBorder]:ve}),style:I?.label,children:[p&&!A?d(`span`,{className:n.inputLabelText,children:[p,Ue]}):null,O&&u(`div`,{className:c(n.inputUpperRightLabel,F?.upperRightLabel),style:I?.upperRightLabel,children:O}),d(`div`,{className:c(n.inputContainer,{[n.inputContainerMultiline]:M},F?.container),style:I?.container,onMouseEnter:Pe,onMouseLeave:Fe,children:[Be,i.cloneElement(j||u(M?`textarea`:`input`,{}),{...ke,className:c(n.inputField,{[n.inputFieldUppercase]:me,[n.inputFieldDate]:S===r.Date,[n.inputFieldDefault]:S!==r.Date,[n.inputFieldWithIcon]:q||Ve,[n.inputFieldWithIconLeft]:J,[n.inputFieldMultiline]:M,[n.inputFieldMultilineAutoResize]:M&&P},F?.input),name:f,id:W,value:T?T.value:h,tabIndex:ge,ref:j?void 0:H,onChange:Re,onFocus:Ie,onBlur:Le,placeholder:A?``:k,autoComplete:we,onClick:Te,readOnly:Ee,disabled:Oe,...!M&&{type:ze(),min:xe,max:Se},...M&&N!==void 0&&{rows:N}}),D&&u(`div`,{className:c(n.inputFieldSuffix,F?.suffix),style:I?.suffix,children:D})]}),u(`fieldset`,{className:c(n.inputFieldset,F?.fieldset,{[n.inputContainerBorderFocused]:L,[n.inputContainerBorderSearchFocused]:S===r.Search&&(L||h),[n.inputContainerBorderInvalid]:Z,[n.inputContainerBorderError]:Z}),style:I?.fieldset,children:u(`legend`,{className:c(n.inputFieldsetLegend,{[n.inputFieldsetLegendActive]:$}),children:u(`span`,{children:Q})})}),A&&p&&d(`div`,{className:c(n.inputMatLabel,{[n.inputMatLabelFloating]:$,[n.inputMatLabelMultiline]:M&&!$}),children:[p,Ue]}),A&&k&&u(`div`,{className:c(n.inputPlaceholder,L&&!We&&n.inputPlaceholderShown,M&&n.inputPlaceholderMultiline),children:k}),u(t,{variant:`error`,message:T?T.getCurrentErrorMessage():m||``,isVisible:Z&&(L||z)})]}),S===r.Phone&&u(l,{icon:oe,...Y}),S===r.Email&&u(l,{icon:ne,...Y}),S===r.Edit&&u(l,{icon:ae,...Y}),S===r.Search&&u(l,{icon:se,...Y}),S===r.Password&&u(l,{icon:V?ie:re,...He}),(ye&&h&&(L||z)||De)&&u(l,{icon:ce,className:n.inputFieldIcon,onClick:be??void 0,onMouseEnter:()=>B(!0),onMouseLeave:()=>B(!1)})]})}export{le 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 { useComponentDefaults } from 'components/common/configProvider';\nimport styles from './input.module.pcss';\nimport type { InputProps } from './input.types';\nimport { InputType } 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 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 === 'email') return undefined;\n if (type === 'password' && isPasswordShown) return 'text';\n return type;\n };\n\n const hasIcon =\n type &&\n type !== InputType.Date &&\n type !== InputType.Iban &&\n type !== InputType.HasNoIcon;\n\n const hasIconLeft =\n hasIcon && !useMatLabelStyle &&\n (type === InputType.Email || type === InputType.Phone || type === InputType.Search);\n\n const iconProps = {\n className: cx(styles.inputFieldIcon, {\n [styles.inputFieldIconNotClickable]: !onIconClick,\n [styles.inputFieldIconLeft]: hasIconLeft,\n }),\n onClick: onIconClick ?? undefined,\n };\n\n const customIcon = icon as React.ReactElement<{ className?: string; onClick?: React.MouseEventHandler }> | null;\n const renderedIcon = customIcon\n ? React.cloneElement(customIcon, {\n className: cx(\n styles.inputFieldIcon,\n { [styles.inputFieldIconNotClickable]: !onIconClick && !customIcon.props.onClick },\n customIcon.props.className,\n ),\n onClick: onIconClick ?? customIcon.props.onClick,\n })\n : null;\n const hasCustomIcon = !!icon;\n\n const passwordIconProps = {\n className: cx(styles.inputFieldIcon, styles.inputFieldIconPassword),\n onClick: () => setIsPasswordShown(!isPasswordShown),\n };\n\n const hasErr = hasError();\n\n let editedLabel = label;\n if (editedLabel && computedIsRequired()) editedLabel = `${editedLabel} *`;\n\n const currVal = formValidator ? formValidator.value : value;\n const shouldFloatLabel = useMatLabelStyle && (alwaysFloatLabel || isFocused || currVal || type === InputType.Date);\n\n return (\n <div className={cx(styles.input, 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 {editedLabel && !useMatLabelStyle ? (\n <span className={styles.inputLabelText}>\n {`${editedLabel} `}\n {computedIsRequired() ? <span className={cx(styles.isRequired)}> *</span> : null}\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]: hasIconLeft,\n [styles.inputFieldMultiline]: multiline,\n [styles.inputFieldMultilineAutoResize]: multiline && autoResize,\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(), 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.inputContainerBorderFocused]: isFocused,\n [styles.inputContainerBorderSearchFocused]:\n type === InputType.Search && (isFocused || 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 {editedLabel}\n </div>\n )}\n {useMatLabelStyle && placeholder && (\n <div\n className={cx(\n styles.inputPlaceholder,\n isFocused && !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 && <FontAwesomeIcon icon={faPhone} {...iconProps} />}\n {type === InputType.Email && <FontAwesomeIcon icon={faEnvelope} {...iconProps} />}\n {type === InputType.Edit && <FontAwesomeIcon icon={faPen} {...iconProps} />}\n {type === InputType.Search && <FontAwesomeIcon icon={faSearch} {...iconProps} />}\n {type === InputType.Password && (\n <FontAwesomeIcon\n icon={isPasswordShown ? passwordShownIcon : passwordHiddenIcon}\n {...passwordIconProps}\n />\n )}\n\n {((showCancel && value && (isFocused || isHovered)) || alwaysShowCancel) && (\n <FontAwesomeIcon\n icon={faXmark}\n className={styles.inputFieldIcon}\n onClick={onClearClicked ?? undefined}\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 { useComponentDefaults } from 'components/common/configProvider';\nimport styles from './input.module.pcss';\nimport type { InputProps } from './input.types';\nimport { InputType } 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 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 === 'email') return undefined;\n if (type === 'password' && isPasswordShown) return 'text';\n return type;\n };\n\n const hasIcon =\n type &&\n type !== InputType.Date &&\n type !== InputType.Iban &&\n type !== InputType.HasNoIcon;\n\n const hasIconLeft =\n hasIcon && !useMatLabelStyle &&\n (type === InputType.Email || type === InputType.Phone || type === InputType.Search);\n\n const iconProps = {\n className: cx(styles.inputFieldIcon, {\n [styles.inputFieldIconNotClickable]: !onIconClick,\n [styles.inputFieldIconLeft]: hasIconLeft,\n }),\n onClick: onIconClick ?? undefined,\n };\n\n const customIcon = icon as React.ReactElement<{ className?: string; onClick?: React.MouseEventHandler }> | null;\n const renderedIcon = customIcon\n ? React.cloneElement(customIcon, {\n className: cx(\n styles.inputFieldIcon,\n { [styles.inputFieldIconNotClickable]: !onIconClick && !customIcon.props.onClick },\n customIcon.props.className,\n ),\n onClick: onIconClick ?? customIcon.props.onClick,\n })\n : null;\n const hasCustomIcon = !!icon;\n\n const passwordIconProps = {\n className: cx(styles.inputFieldIcon, styles.inputFieldIconPassword),\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 shouldFloatLabel = useMatLabelStyle && (alwaysFloatLabel || isFocused || currVal || type === InputType.Date);\n\n return (\n <div className={cx(styles.input, 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]: hasIconLeft,\n [styles.inputFieldMultiline]: multiline,\n [styles.inputFieldMultilineAutoResize]: multiline && autoResize,\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(), 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.inputContainerBorderFocused]: isFocused,\n [styles.inputContainerBorderSearchFocused]:\n type === InputType.Search && (isFocused || 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 isFocused && !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 && <FontAwesomeIcon icon={faPhone} {...iconProps} />}\n {type === InputType.Email && <FontAwesomeIcon icon={faEnvelope} {...iconProps} />}\n {type === InputType.Edit && <FontAwesomeIcon icon={faPen} {...iconProps} />}\n {type === InputType.Search && <FontAwesomeIcon icon={faSearch} {...iconProps} />}\n {type === InputType.Password && (\n <FontAwesomeIcon\n icon={isPasswordShown ? passwordShownIcon : passwordHiddenIcon}\n {...passwordIconProps}\n />\n )}\n\n {((showCancel && value && (isFocused || isHovered)) || alwaysShowCancel) && (\n <FontAwesomeIcon\n icon={faXmark}\n className={styles.inputFieldIcon}\n onClick={onClearClicked ?? undefined}\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
|
-
var e={"required-mark":`required-mark_xGJdX`,requiredMark:`required-mark_xGJdX`,
|
|
1
|
+
var e={"required-mark":`required-mark_xGJdX`,requiredMark:`required-mark_xGJdX`,input:`input_VKNCE`,"input-placeholder":`input-placeholder_IZH-l`,inputPlaceholder:`input-placeholder_IZH-l`,"input-placeholder-shown":`input-placeholder-shown_mm35e`,inputPlaceholderShown:`input-placeholder-shown_mm35e`,fadeIn:`fadeIn_kmX3i`,"input-placeholder-multiline":`input-placeholder-multiline_tLHAl`,inputPlaceholderMultiline:`input-placeholder-multiline_tLHAl`,"input-matLabel":`input-matLabel_-05ey`,inputMatLabel:`input-matLabel_-05ey`,"input-matLabel-floating":`input-matLabel-floating_1P2YE`,inputMatLabelFloating:`input-matLabel-floating_1P2YE`,"input-matLabel-multiline":`input-matLabel-multiline_miIZJ`,inputMatLabelMultiline:`input-matLabel-multiline_miIZJ`,"input-fieldset":`input-fieldset_XCibg`,inputFieldset:`input-fieldset_XCibg`,"input-fieldset-legend":`input-fieldset-legend_X23zp`,inputFieldsetLegend:`input-fieldset-legend_X23zp`,"input-fieldset-legend-active":`input-fieldset-legend-active_t-9hu`,inputFieldsetLegendActive:`input-fieldset-legend-active_t-9hu`,"input-container":`input-container_M1RoG`,inputContainer:`input-container_M1RoG`,"input-container-multiline":`input-container-multiline_eLw7h`,inputContainerMultiline:`input-container-multiline_eLw7h`,"input-container-border":`input-container-border_l131I`,inputContainerBorder:`input-container-border_l131I`,"input-container-border-focused":`input-container-border-focused_ct6oY`,inputContainerBorderFocused:`input-container-border-focused_ct6oY`,"input-container-border-searchFocused":`input-container-border-searchFocused_lq088`,inputContainerBorderSearchFocused:`input-container-border-searchFocused_lq088`,"input-container-border-invalid":`input-container-border-invalid_Wdbq2`,inputContainerBorderInvalid:`input-container-border-invalid_Wdbq2`,"input-container-border-error":`input-container-border-error_gzfPG`,inputContainerBorderError:`input-container-border-error_gzfPG`,"input-label":`input-label_w1hMR`,inputLabel:`input-label_w1hMR`,"input-label-column":`input-label-column_qBFPC`,inputLabelColumn:`input-label-column_qBFPC`,"input-label-text":`input-label-text_-J5qQ`,inputLabelText:`input-label-text_-J5qQ`,"input-upper-right-label":`input-upper-right-label_I-WG3`,inputUpperRightLabel:`input-upper-right-label_I-WG3`,"input-field":`input-field_pmDvZ`,inputField:`input-field_pmDvZ`,"input-field-withIcon":`input-field-withIcon_VpfmK`,inputFieldWithIcon:`input-field-withIcon_VpfmK`,"input-field-withIcon-left":`input-field-withIcon-left_Io7lU`,inputFieldWithIconLeft:`input-field-withIcon-left_Io7lU`,"input-field-suffix":`input-field-suffix_NZpXp`,inputFieldSuffix:`input-field-suffix_NZpXp`,"input-field-date":`input-field-date_UHJEZ`,inputFieldDate:`input-field-date_UHJEZ`,"input-field-default":`input-field-default_TKipA`,inputFieldDefault:`input-field-default_TKipA`,"input-field-uppercase":`input-field-uppercase_UV6f1`,inputFieldUppercase:`input-field-uppercase_UV6f1`,"input-field-multiline":`input-field-multiline_al3V1`,inputFieldMultiline:`input-field-multiline_al3V1`,"input-field-multiline-autoResize":`input-field-multiline-autoResize_nK33P`,inputFieldMultilineAutoResize:`input-field-multiline-autoResize_nK33P`,"input-field-icon":`input-field-icon_YyJIr`,inputFieldIcon:`input-field-icon_YyJIr`,"input-field-icon-left":`input-field-icon-left_m2XB1`,inputFieldIconLeft:`input-field-icon-left_m2XB1`,"input-field-icon-notClickable":`input-field-icon-notClickable_7j24I`,inputFieldIconNotClickable:`input-field-icon-notClickable_7j24I`,"input-error":`input-error_LIG23`,inputError:`input-error_LIG23`};export{e as default};
|
|
2
2
|
//# sourceMappingURL=input.module.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.module.mjs","names":[],"sources":["../../../../package/common/input/input.module.pcss"],"sourcesContent":["\n.required-mark {\n padding: 0px 0px 0px 4px;\n color: var(--
|
|
1
|
+
{"version":3,"file":"input.module.mjs","names":[],"sources":["../../../../package/common/input/input.module.pcss"],"sourcesContent":["\n.required-mark {\n padding: 0px 0px 0px 4px;\n color: var(--required-mark-color, var(--error-color));\n}\n\n.input {\n position: relative;\n width: 100%;\n --input-notch-height: 1.75em;\n\n &-placeholder {\n position: absolute;\n top: 50%;\n left: 7px;\n transform: translateY(-50%);\n transition: all 0.2s;\n opacity: 0;\n user-select: none;\n pointer-events: none;\n\n &-shown {\n animation: 0.2s fadeIn 0.3s forwards;\n }\n\n &-multiline {\n top: 14px;\n transform: translateY(0);\n }\n }\n\n &-matLabel {\n position: absolute;\n transition: all 0.3s;\n left: 7px;\n right: 0;\n top: 50%;\n transform: translateY(-50%);\n font-size: 1em;\n color: var(--input-label-resting-color, var(--text-light));\n pointer-events: none;\n user-select: none;\n\n &-floating {\n top: 0;\n bottom: auto;\n left: 14px;\n right: 0;\n font-size: 0.8em;\n color: var(--input-label-floating-color, var(--text-color));\n transform: translateY(-50%);\n }\n\n &-multiline {\n top: 14px;\n transform: translateY(0);\n }\n }\n\n &-fieldset {\n position: absolute;\n width: 100%;\n margin: 0;\n padding: 0;\n min-width: 0;\n box-sizing: border-box;\n border-radius: var(--default-border-radius);\n font-size: 0.8em;\n inset: calc(var(--input-notch-height) / -2) 0 0 0;\n padding-left: 8px;\n border-width: 1px;\n border-style: solid;\n border-color: var(--border-color);\n pointer-events: none;\n user-select: none;\n\n &-legend {\n display: block;\n max-width: 0;\n transition: max-width 0.2s;\n white-space: nowrap;\n padding: 0;\n\n &-active {\n max-width: 300px;\n }\n\n span {\n line-height: var(--input-notch-height);\n padding: 0 5px;\n opacity: 0;\n }\n\n span:empty {\n padding: 0.000001px;\n }\n }\n }\n\n &-container {\n display: flex;\n align-items: center;\n border-radius: var(--default-border-radius);\n background-color: var(--input-background);\n transition: border-color;\n cursor: text;\n height: 100%;\n\n &-multiline {\n overflow: hidden;\n padding-top: 10px;\n align-items: flex-start;\n }\n\n &-border {\n outline: 1px solid var(--border-color);\n transition: border-color;\n background-color: var(--input-background);\n outline: none;\n\n &-focused {\n outline-color: var(--primary-color);\n border-color: var(--primary-color);\n }\n\n &-searchFocused {\n outline-color: var(--search-input-color);\n outline-width: 2px;\n border-color: var(--search-input-color);\n }\n\n &-invalid {\n outline-color: var(--error-border-color);\n border-color: var(--error-border-color);\n }\n\n &-invalid:hover {\n outline-color: var(--error-border-color);\n border-color: var(--error-border-color);\n }\n\n &-error {\n outline-color: var(--error-border-color);\n border-color: var(--error-border-color);\n }\n }\n }\n\n &-label {\n display: flex;\n color: var(--text-color);\n height: 100%;\n\n &-column {\n flex-direction: column;\n }\n\n &-text {\n white-space: nowrap;\n margin-right: 5px;\n margin-bottom: 6px;\n display: flex;\n align-items: center;\n color: color(var(--border-color) lightness(40%));\n background-color: transparent;\n font-size: 12px;\n position: absolute;\n top: -15px;\n white-space: nowrap;\n }\n }\n\n &-upper-right-label {\n position: absolute;\n transform: translateY(calc(-100% - 1.5px));\n right: 8px;\n min-height: 12px;\n font-size: 12px;\n color: color(var(--border-color) lightness(40%));\n }\n\n &-field {\n appearance: none;\n -webkit-appearance: none;\n font-family: inherit;\n font-size: inherit;\n box-sizing: border-box;\n resize: none;\n width: 100%;\n border: none;\n border-radius: var(--default-border-radius);\n overflow: hidden;\n line-height: 1.25;\n color: var(--text-color);\n background: transparent;\n\n &:focus {\n outline: none;\n }\n\n &::placeholder {\n color: var(--text-light);\n }\n\n &-withIcon {\n padding-right: 37px !important;\n\n &-left {\n padding-right: 9px !important;\n padding-left: 37px !important;\n }\n }\n\n &-suffix {\n padding-right: 9px;\n }\n\n &-date {\n padding: 6px 9px;\n color-scheme: dark;\n\n svg {\n color: white;\n }\n }\n\n &-default {\n padding: 8px 7.5px 6px;\n }\n\n &[disabled] {\n background-color: var(--disabled-input-color);\n color: var(--disabled-font-color);\n -webkit-text-fill-color: var(--disabled-font-color);\n opacity: 1;\n\n &::placeholder {\n color: var(--disabled-font-color);\n -webkit-text-fill-color: var(--disabled-font-color);\n }\n }\n\n &-uppercase {\n text-transform: uppercase;\n }\n\n &-multiline {\n overflow-y: auto;\n resize: vertical;\n padding-top: 4px;\n min-height: 30px;\n\n &-autoResize {\n resize: none;\n overflow: hidden;\n }\n }\n\n &-icon {\n appearance: none;\n -webkit-appearance: none;\n box-sizing: border-box;\n cursor: pointer;\n background-color: transparent;\n border: none;\n position: absolute;\n outline: none;\n right: 10px;\n top: 8px;\n color: var(--input-icon-color);\n width: 19px !important;\n height: 19px !important;\n user-select: none;\n top: 50%;\n transform: translateY(-50%);\n\n &-left {\n left: 10px;\n }\n\n &-notClickable {\n pointer-events: none;\n }\n }\n }\n\n &-error {\n height: 1em;\n padding-top: 3px;\n color: var(--error-font-color);\n font-size: 11px;\n }\n\n @keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 0.5;\n }\n }\n}\n"],"mappings":""}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e={id:`default`,variables:{"--grey":`#8A8A8A`,"--lightgrey":`#e0e0e0`,"--lightergrey":`#B1B1B1`,"--white":`#FFFFFF`,"--red":`#D6002A`,"--lighter-red":`#ffeae9`,"--green":`#287626`,"--lighter-green":`#C4FFC9`,"--blue":`#5873d5`,"--lighter-blue":`#C6DBFF`,"--black":`black`,"--orange":`#ff7f50`,"--lighter-orange":`#ffe5d9`,"--primary-color":`#8184d6`,"--primary-accent":`#90CAF9`,"--primary-lighter":`#9a9ce4`,"--accent-color":`var(--grey)`,"--accent-color-light":`var(--lightgrey)`,"--text-color":`var(--white)`,"--text-dark":`var(--lightergrey)`,"--text-light":`var(--lightergrey)`,"--text-on-primary":`var(--white)`,"--text-on-delete":`var(--white)`,"--border-color":`#656574`,"--background":`#393945`,"--background-accent":`#33333c`,"--background-accent-dark":`var(--grey)`,"--background-accent-light":`#484856`,"--background-modal":`#484856`,"--success-color":`var(--green)`,"--success-lighter":`var(--lighter-green)`,"--error-color":`var(--red)`,"--error-lighter":`var(--lighter-red)`,"--info-color":`var(--blue)`,"--info-lighter":`var(--lighter-blue)`,"--warn-color":`var(--orange)`,"--warn-lighter":`var(--lighter-orange)`,"--default-font-size":`14px`,"--text-small-font-size":`12px`,"--header-font-size":`24px`,"--header-medium-font-size":`18px`,"--header-small-font-size":`16px`,"--default-font-weight":`400`,"--header-font-weight":`600`,"--input-background":`transparent`,"--input-icon-color":`var(--text-color)`,"--error-border-color":`var(--red)`,"--button-default-color":`var(--primary-color)`,"--button-default-border":`1px solid var(--primary-color)`,"--default-border-radius":`8px`,"--padding-sides":`15px`,"--margin-top":`10px`,"--default-font":`'Inter', sans-serif`,"--themed-font":`'Inter', sans-serif`,"--card-shadow":`0 3px 1px -2px rgb(0 0 0 / 20%), 0 2px 2px 0 rgb(0 0 0 / 14%), 0 1px 5px 0 rgb(0 0 0 / 12%)`,"--background-card-elevated":`var(--background-accent-light)`,"--background-card-outlined":`transparent`,"--background-card-filled":`var(--background-accent)`,"--spacing-s":`4px`,"--spacing-m":`8px`,"--spacing-l":`16px`}};export{e as defaultTheme};
|
|
1
|
+
var e={id:`default`,variables:{"--grey":`#8A8A8A`,"--lightgrey":`#e0e0e0`,"--lightergrey":`#B1B1B1`,"--white":`#FFFFFF`,"--red":`#D6002A`,"--lighter-red":`#ffeae9`,"--green":`#287626`,"--lighter-green":`#C4FFC9`,"--blue":`#5873d5`,"--lighter-blue":`#C6DBFF`,"--black":`black`,"--orange":`#ff7f50`,"--lighter-orange":`#ffe5d9`,"--primary-color":`#8184d6`,"--primary-accent":`#90CAF9`,"--primary-lighter":`#9a9ce4`,"--accent-color":`var(--grey)`,"--accent-color-light":`var(--lightgrey)`,"--text-color":`var(--white)`,"--text-dark":`var(--lightergrey)`,"--text-light":`var(--lightergrey)`,"--text-on-primary":`var(--white)`,"--text-on-delete":`var(--white)`,"--border-color":`#656574`,"--background":`#393945`,"--background-accent":`#33333c`,"--background-accent-dark":`var(--grey)`,"--background-accent-light":`#484856`,"--background-modal":`#484856`,"--success-color":`var(--green)`,"--success-lighter":`var(--lighter-green)`,"--error-color":`var(--red)`,"--error-lighter":`var(--lighter-red)`,"--required-mark-color":`var(--error-color)`,"--info-color":`var(--blue)`,"--info-lighter":`var(--lighter-blue)`,"--warn-color":`var(--orange)`,"--warn-lighter":`var(--lighter-orange)`,"--default-font-size":`14px`,"--text-small-font-size":`12px`,"--header-font-size":`24px`,"--header-medium-font-size":`18px`,"--header-small-font-size":`16px`,"--default-font-weight":`400`,"--header-font-weight":`600`,"--input-background":`transparent`,"--input-icon-color":`var(--text-color)`,"--error-border-color":`var(--red)`,"--button-default-color":`var(--primary-color)`,"--button-default-border":`1px solid var(--primary-color)`,"--default-border-radius":`8px`,"--padding-sides":`15px`,"--margin-top":`10px`,"--default-font":`'Inter', sans-serif`,"--themed-font":`'Inter', sans-serif`,"--card-shadow":`0 3px 1px -2px rgb(0 0 0 / 20%), 0 2px 2px 0 rgb(0 0 0 / 14%), 0 1px 5px 0 rgb(0 0 0 / 12%)`,"--background-card-elevated":`var(--background-accent-light)`,"--background-card-outlined":`transparent`,"--background-card-filled":`var(--background-accent)`,"--spacing-s":`4px`,"--spacing-m":`8px`,"--spacing-l":`16px`}};export{e as defaultTheme};
|
|
2
2
|
//# sourceMappingURL=defaultTheme.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaultTheme.mjs","names":[],"sources":["../../../../package/common/themeProvider/defaultTheme.ts"],"sourcesContent":["import type { Theme } from './theme.types';\n\n/**\n * Built-in default theme used by ThemeProvider when no `themes` prop is\n * supplied. Provides a complete set of CSS variables so the component\n * library renders correctly out of the box.\n */\nexport const defaultTheme: Theme = {\n id: 'default',\n variables: {\n '--grey': '#8A8A8A',\n '--lightgrey': '#e0e0e0',\n '--lightergrey': '#B1B1B1',\n '--white': '#FFFFFF',\n '--red': '#D6002A',\n '--lighter-red': '#ffeae9',\n '--green': '#287626',\n '--lighter-green': '#C4FFC9',\n '--blue': '#5873d5',\n '--lighter-blue': '#C6DBFF',\n '--black': 'black',\n '--orange': '#ff7f50',\n '--lighter-orange': '#ffe5d9',\n\n '--primary-color': '#8184d6',\n '--primary-accent': '#90CAF9',\n '--primary-lighter': '#9a9ce4',\n '--accent-color': 'var(--grey)',\n '--accent-color-light': 'var(--lightgrey)',\n\n '--text-color': 'var(--white)',\n '--text-dark': 'var(--lightergrey)',\n '--text-light': 'var(--lightergrey)',\n '--text-on-primary': 'var(--white)',\n '--text-on-delete': 'var(--white)',\n '--border-color': '#656574',\n\n '--background': '#393945',\n '--background-accent': '#33333c',\n '--background-accent-dark': 'var(--grey)',\n '--background-accent-light': '#484856',\n '--background-modal': '#484856',\n\n '--success-color': 'var(--green)',\n '--success-lighter': 'var(--lighter-green)',\n '--error-color': 'var(--red)',\n '--error-lighter': 'var(--lighter-red)',\n '--info-color': 'var(--blue)',\n '--info-lighter': 'var(--lighter-blue)',\n '--warn-color': 'var(--orange)',\n '--warn-lighter': 'var(--lighter-orange)',\n\n '--default-font-size': '14px',\n '--text-small-font-size': '12px',\n '--header-font-size': '24px',\n '--header-medium-font-size': '18px',\n '--header-small-font-size': '16px',\n\n '--default-font-weight': '400',\n '--header-font-weight': '600',\n\n '--input-background': 'transparent',\n '--input-icon-color': 'var(--text-color)',\n '--error-border-color': 'var(--red)',\n\n '--button-default-color': 'var(--primary-color)',\n '--button-default-border': '1px solid var(--primary-color)',\n\n '--default-border-radius': '8px',\n '--padding-sides': '15px',\n '--margin-top': '10px',\n\n '--default-font': \"'Inter', sans-serif\",\n '--themed-font': \"'Inter', sans-serif\",\n\n '--card-shadow':\n '0 3px 1px -2px rgb(0 0 0 / 20%), 0 2px 2px 0 rgb(0 0 0 / 14%), 0 1px 5px 0 rgb(0 0 0 / 12%)',\n\n '--background-card-elevated': 'var(--background-accent-light)',\n '--background-card-outlined': 'transparent',\n '--background-card-filled': 'var(--background-accent)',\n\n '--spacing-s': '4px',\n '--spacing-m': '8px',\n '--spacing-l': '16px',\n },\n};\n"],"mappings":"AAOA,IAAa,EAAsB,CACjC,GAAI,UACJ,UAAW,CACT,SAAU,UACV,cAAe,UACf,gBAAiB,UACjB,UAAW,UACX,QAAS,UACT,gBAAiB,UACjB,UAAW,UACX,kBAAmB,UACnB,SAAU,UACV,iBAAkB,UAClB,UAAW,QACX,WAAY,UACZ,mBAAoB,UAEpB,kBAAmB,UACnB,mBAAoB,UACpB,oBAAqB,UACrB,iBAAkB,cAClB,uBAAwB,mBAExB,eAAgB,eAChB,cAAe,qBACf,eAAgB,qBAChB,oBAAqB,eACrB,mBAAoB,eACpB,iBAAkB,UAElB,eAAgB,UAChB,sBAAuB,UACvB,2BAA4B,cAC5B,4BAA6B,UAC7B,qBAAsB,UAEtB,kBAAmB,eACnB,oBAAqB,uBACrB,gBAAiB,aACjB,kBAAmB,qBACnB,eAAgB,cAChB,iBAAkB,sBAClB,eAAgB,gBAChB,iBAAkB,wBAElB,sBAAuB,OACvB,yBAA0B,OAC1B,qBAAsB,OACtB,4BAA6B,OAC7B,2BAA4B,OAE5B,wBAAyB,MACzB,uBAAwB,MAExB,qBAAsB,cACtB,qBAAsB,oBACtB,uBAAwB,aAExB,yBAA0B,uBAC1B,0BAA2B,iCAE3B,0BAA2B,MAC3B,kBAAmB,OACnB,eAAgB,OAEhB,iBAAkB,sBAClB,gBAAiB,sBAEjB,gBACE,8FAEF,6BAA8B,iCAC9B,6BAA8B,cAC9B,2BAA4B,2BAE5B,cAAe,MACf,cAAe,MACf,cAAe,MACjB,CACF"}
|
|
1
|
+
{"version":3,"file":"defaultTheme.mjs","names":[],"sources":["../../../../package/common/themeProvider/defaultTheme.ts"],"sourcesContent":["import type { Theme } from './theme.types';\n\n/**\n * Built-in default theme used by ThemeProvider when no `themes` prop is\n * supplied. Provides a complete set of CSS variables so the component\n * library renders correctly out of the box.\n */\nexport const defaultTheme: Theme = {\n id: 'default',\n variables: {\n '--grey': '#8A8A8A',\n '--lightgrey': '#e0e0e0',\n '--lightergrey': '#B1B1B1',\n '--white': '#FFFFFF',\n '--red': '#D6002A',\n '--lighter-red': '#ffeae9',\n '--green': '#287626',\n '--lighter-green': '#C4FFC9',\n '--blue': '#5873d5',\n '--lighter-blue': '#C6DBFF',\n '--black': 'black',\n '--orange': '#ff7f50',\n '--lighter-orange': '#ffe5d9',\n\n '--primary-color': '#8184d6',\n '--primary-accent': '#90CAF9',\n '--primary-lighter': '#9a9ce4',\n '--accent-color': 'var(--grey)',\n '--accent-color-light': 'var(--lightgrey)',\n\n '--text-color': 'var(--white)',\n '--text-dark': 'var(--lightergrey)',\n '--text-light': 'var(--lightergrey)',\n '--text-on-primary': 'var(--white)',\n '--text-on-delete': 'var(--white)',\n '--border-color': '#656574',\n\n '--background': '#393945',\n '--background-accent': '#33333c',\n '--background-accent-dark': 'var(--grey)',\n '--background-accent-light': '#484856',\n '--background-modal': '#484856',\n\n '--success-color': 'var(--green)',\n '--success-lighter': 'var(--lighter-green)',\n '--error-color': 'var(--red)',\n '--error-lighter': 'var(--lighter-red)',\n '--required-mark-color': 'var(--error-color)',\n '--info-color': 'var(--blue)',\n '--info-lighter': 'var(--lighter-blue)',\n '--warn-color': 'var(--orange)',\n '--warn-lighter': 'var(--lighter-orange)',\n\n '--default-font-size': '14px',\n '--text-small-font-size': '12px',\n '--header-font-size': '24px',\n '--header-medium-font-size': '18px',\n '--header-small-font-size': '16px',\n\n '--default-font-weight': '400',\n '--header-font-weight': '600',\n\n '--input-background': 'transparent',\n '--input-icon-color': 'var(--text-color)',\n '--error-border-color': 'var(--red)',\n\n '--button-default-color': 'var(--primary-color)',\n '--button-default-border': '1px solid var(--primary-color)',\n\n '--default-border-radius': '8px',\n '--padding-sides': '15px',\n '--margin-top': '10px',\n\n '--default-font': \"'Inter', sans-serif\",\n '--themed-font': \"'Inter', sans-serif\",\n\n '--card-shadow':\n '0 3px 1px -2px rgb(0 0 0 / 20%), 0 2px 2px 0 rgb(0 0 0 / 14%), 0 1px 5px 0 rgb(0 0 0 / 12%)',\n\n '--background-card-elevated': 'var(--background-accent-light)',\n '--background-card-outlined': 'transparent',\n '--background-card-filled': 'var(--background-accent)',\n\n '--spacing-s': '4px',\n '--spacing-m': '8px',\n '--spacing-l': '16px',\n },\n};\n"],"mappings":"AAOA,IAAa,EAAsB,CACjC,GAAI,UACJ,UAAW,CACT,SAAU,UACV,cAAe,UACf,gBAAiB,UACjB,UAAW,UACX,QAAS,UACT,gBAAiB,UACjB,UAAW,UACX,kBAAmB,UACnB,SAAU,UACV,iBAAkB,UAClB,UAAW,QACX,WAAY,UACZ,mBAAoB,UAEpB,kBAAmB,UACnB,mBAAoB,UACpB,oBAAqB,UACrB,iBAAkB,cAClB,uBAAwB,mBAExB,eAAgB,eAChB,cAAe,qBACf,eAAgB,qBAChB,oBAAqB,eACrB,mBAAoB,eACpB,iBAAkB,UAElB,eAAgB,UAChB,sBAAuB,UACvB,2BAA4B,cAC5B,4BAA6B,UAC7B,qBAAsB,UAEtB,kBAAmB,eACnB,oBAAqB,uBACrB,gBAAiB,aACjB,kBAAmB,qBACnB,wBAAyB,qBACzB,eAAgB,cAChB,iBAAkB,sBAClB,eAAgB,gBAChB,iBAAkB,wBAElB,sBAAuB,OACvB,yBAA0B,OAC1B,qBAAsB,OACtB,4BAA6B,OAC7B,2BAA4B,OAE5B,wBAAyB,MACzB,uBAAwB,MAExB,qBAAsB,cACtB,qBAAsB,oBACtB,uBAAwB,aAExB,yBAA0B,uBAC1B,0BAA2B,iCAE3B,0BAA2B,MAC3B,kBAAmB,OACnB,eAAgB,OAEhB,iBAAkB,sBAClB,gBAAiB,sBAEjB,gBACE,8FAEF,6BAA8B,iCAC9B,6BAA8B,cAC9B,2BAA4B,2BAE5B,cAAe,MACf,cAAe,MACf,cAAe,MACjB,CACF"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{COLUMN_STORAGE_PREFIX as e,buildColumnTemplate as t,isColumnInitiallyVisible as n,loadPersistedColumns as r}from"./virtualList.utils.mjs";import{useCallback as i,useEffect as a,useLayoutEffect as o,useRef as s,useState as c}from"react";function l({columns:l,items:u,multiSelect:d,visibleColumnKeys:f,onVisibleColumnsChange:p,persistColumnsKey:m,showColumnToggle:h,rootRef:g,startIndex:_,endIndex:v,containerHeight:y,containerWidth:b}){let x=f!==void 0,[S,C]=c(!1),w
|
|
1
|
+
import{COLUMN_STORAGE_PREFIX as e,buildColumnTemplate as t,isColumnInitiallyVisible as n,loadPersistedColumns as r}from"./virtualList.utils.mjs";import{useCallback as i,useEffect as a,useLayoutEffect as o,useRef as s,useState as c}from"react";function l({columns:l,items:u,multiSelect:d,visibleColumnKeys:f,onVisibleColumnsChange:p,persistColumnsKey:m,showColumnToggle:h,rootRef:g,startIndex:_,endIndex:v,containerHeight:y,containerWidth:b}){let x=f!==void 0,[S,C]=c(!1),[w,T]=c({}),[E,D]=c(()=>{let e=r(m);return new Set((l??[]).filter(t=>n(t,e)).map(e=>e.key))}),O=s(new Set((l??[]).map(e=>e.key)));a(()=>{if(x)return;let e=l??[],t=new Set(e.map(e=>e.key)),i=O.current,a=t.size===i.size;if(a){for(let e of t)if(!i.has(e)){a=!1;break}}if(a)return;O.current=t;let o=r(m);D(t=>{let r=new Set;for(let a of e)i.has(a.key)?t.has(a.key)&&r.add(a.key):n(a,o)&&r.add(a.key);return r})},[l,x,m]),a(()=>{if(x||!m||typeof window>`u`)return;let t=l??[];if(!(t.length===0||E.size===0))try{window.localStorage.setItem(e+m,JSON.stringify({visible:[...E],known:t.map(e=>e.key)}))}catch{}},[E,l,x,m]);let k=x?new Set(f):E,A=(l??[]).filter(e=>e.lockVisible).map(e=>e.key),j=A.some(e=>!k.has(e))?new Set([...k,...A]):k,M=!!l?.length,N=M?l.filter(e=>j.has(e.key)):[],P=M?l.filter(e=>!e.defaultHidden&&!j.has(e.key)).length:0,F=M?`${d&&M?`40px `:``}${t(N,w)}`:void 0,I=h!==!1&&M&&l.some(e=>!e.hideFromToggle),L=N.filter(e=>e.width.type===`fit`),R=L.length>0,z=L.map(e=>e.key).join(`|`),[B,V]=c({key:z,items:u});(B.key!==z||B.items!==u)&&(V({key:z,items:u}),Object.keys(w).length>0&&T({}));let H=i(()=>{let e=g.current;if(!e)return;let t=new Map;e.querySelectorAll(`[data-fit-key]`).forEach(e=>{let n=e,r=n.getAttribute(`data-fit-key`);if(!r)return;let i=n.scrollWidth>n.clientWidth,a=n.scrollWidth;if(i||n.firstElementChild){let e=getComputedStyle(n),t=parseFloat(e.paddingLeft)||0,r=parseFloat(e.paddingRight)||0;if(i&&(a+=r),n.firstElementChild&&!i&&n.scrollWidth<=t+r+1){let e=1/0,i=-1/0;if(n.querySelectorAll(`*`).forEach(t=>{let n=t.getBoundingClientRect();n.left<e&&(e=n.left),n.right>i&&(i=n.right)}),i>e){let n=Math.ceil(i-e)+t+r;n>a&&(a=n)}}}a>(t.get(r)??0)&&t.set(r,a)}),t.size!==0&&T(n=>{let r=!1,i={...n};for(let[a,o]of t){if(o<=0)continue;let t=Math.min(Math.ceil(o),e.clientWidth);t>(n[a]??0)&&(i[a]=t,r=!0)}return r?i:n})},[g]),[U]=c(()=>typeof ResizeObserver>`u`?null:new ResizeObserver(()=>H())),W=s(new Set);a(()=>()=>{U?.disconnect(),W.current.clear()},[U]),o(()=>{if(!R)return;let e=g.current;if(!e||(H(),!U))return;let t=new Set(e.querySelectorAll(`[data-fit-key]`)),n=W.current;for(let e of n)t.has(e)||(U.unobserve(e),n.delete(e));for(let e of t)n.has(e)||(U.observe(e),n.add(e))},[R,z,w,_,v,y,b,u,H,U]),a(()=>{if(!R)return;let e=0,t=requestAnimationFrame(()=>{H(),e=requestAnimationFrame(()=>H())});return()=>{cancelAnimationFrame(t),cancelAnimationFrame(e)}},[R,z,u,H]);let G=i(()=>T({}),[]);function K(e){if(l?.find(t=>t.key===e)?.lockVisible)return;let t=new Set(j);if(t.has(e)){if(t.size<=1)return;t.delete(e)}else t.add(e);let n=[...t];x||D(t),p?.(n)}return{hasColumns:M,visibleColumns:N,columnTemplate:F,shouldShowToggle:I,effectiveVisible:j,manuallyHiddenCount:P,toggleOpen:S,setToggleOpen:C,handleToggleColumn:K,recalculateColumns:G}}export{l as useColumns};
|
|
2
2
|
//# sourceMappingURL=useColumns.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useColumns.mjs","names":[],"sources":["../../../../package/common/virtualList/useColumns.ts"],"sourcesContent":["import React, { useState, useRef, useEffect, useLayoutEffect, useCallback } from 'react';\n\nimport {\n buildColumnTemplate,\n loadPersistedColumns,\n isColumnInitiallyVisible,\n COLUMN_STORAGE_PREFIX,\n type PersistedColumns,\n} from './virtualList.utils';\nimport type { VirtualListColumn } from './virtualList.types';\n\ninterface UseColumnsArgs<T> {\n columns?: VirtualListColumn<T>[];\n items: T[];\n multiSelect: boolean;\n visibleColumnKeys?: string[];\n onVisibleColumnsChange?: (keys: string[]) => void;\n persistColumnsKey?: string;\n showColumnToggle?: boolean;\n rootRef: React.RefObject<HTMLDivElement | null>;\n /** Visible-window bounds — re-measure `fit` columns as new cells scroll in. */\n startIndex: number;\n endIndex: number;\n containerHeight: number;\n /** Re-measure `fit` columns when the container width settles (e.g. after a route transition). */\n containerWidth: number;\n}\n\ninterface UseColumnsResult<T> {\n hasColumns: boolean;\n visibleColumns: VirtualListColumn<T>[];\n columnTemplate: string | undefined;\n shouldShowToggle: boolean;\n effectiveVisible: Set<string>;\n /** How many default-visible columns the user has hidden (excludes defaultHidden). */\n manuallyHiddenCount: number;\n toggleOpen: boolean;\n setToggleOpen: React.Dispatch<React.SetStateAction<boolean>>;\n toggleRef: React.RefObject<HTMLDivElement | null>;\n handleToggleColumn: (key: string) => void;\n /** Imperative escape hatch: drop fit-column pins so they re-measure on the\n * next layout. For out-of-band content changes that don't flow through a new\n * `items` array or `columns` set (which reset automatically). */\n recalculateColumns: () => void;\n}\n\n/**\n * Table-mode column logic: visibility (controlled or uncontrolled, with\n * localStorage persistence and runtime reconciliation), the toggle popover, and\n * `fit`-column width measurement that pins one shared px track across the header\n * and every row grid so they stay aligned.\n */\nexport function useColumns<T>({\n columns,\n items,\n multiSelect,\n visibleColumnKeys,\n onVisibleColumnsChange,\n persistColumnsKey,\n showColumnToggle,\n rootRef,\n startIndex,\n endIndex,\n containerHeight,\n containerWidth,\n}: UseColumnsArgs<T>): UseColumnsResult<T> {\n const isControlled = visibleColumnKeys !== undefined;\n const [toggleOpen, setToggleOpen] = useState(false);\n const toggleRef = useRef<HTMLDivElement>(null);\n // Measured px widths for `fit` columns, keyed by column key. Pinning these\n // into the shared column template keeps the header and rows aligned (a raw\n // `fit-content` track resolves per-grid and drifts). See the effects below.\n const [fitWidths, setFitWidths] = useState<Record<string, number>>({});\n\n const [internalVisibleKeys, setInternalVisibleKeys] = useState<Set<string>>(() => {\n const persisted = loadPersistedColumns(persistColumnsKey);\n return new Set((columns ?? []).filter((c) => isColumnInitiallyVisible(c, persisted)).map((c) => c.key));\n });\n // The set of column keys the internal visibility state was last reconciled\n // against. The lazy initializer above only runs at mount, so without this a\n // list that mounts in list mode (no columns) and later switches to table mode\n // would keep an empty visible set and render no columns.\n const knownColumnKeysRef = useRef<Set<string>>(new Set((columns ?? []).map((c) => c.key)));\n\n // Re-derive internal visibility when the column set changes at runtime: new\n // columns get their saved/default visibility, removed columns drop out, and\n // existing columns keep whatever the user toggled them to. This is also what\n // applies persisted settings when a list switches from list mode to table\n // mode (columns absent at mount, supplied later).\n useEffect(() => {\n if (isControlled) return;\n const cols = columns ?? [];\n const currentKeys = new Set(cols.map((c) => c.key));\n const known = knownColumnKeysRef.current;\n let identical = currentKeys.size === known.size;\n if (identical) for (const k of currentKeys) if (!known.has(k)) { identical = false; break; }\n if (identical) return;\n knownColumnKeysRef.current = currentKeys;\n const persisted = loadPersistedColumns(persistColumnsKey);\n setInternalVisibleKeys((prev) => {\n const next = new Set<string>();\n for (const c of cols) {\n if (known.has(c.key)) {\n if (prev.has(c.key)) next.add(c.key); // preserve the current-session choice\n } else if (isColumnInitiallyVisible(c, persisted)) {\n next.add(c.key); // newly-added column: saved setting, else defaultHidden\n }\n }\n return next;\n });\n }, [columns, isControlled, persistColumnsKey]);\n\n // Persist visibility whenever it changes (uncontrolled mode only). Skip while\n // there are no columns, or the transient empty state during a list→table\n // switch before the reconcile effect above has filled in the visible set —\n // writing then would clobber the saved config with an empty set.\n useEffect(() => {\n if (isControlled || !persistColumnsKey || typeof window === 'undefined') return;\n const cols = columns ?? [];\n if (cols.length === 0 || internalVisibleKeys.size === 0) return;\n try {\n window.localStorage.setItem(\n COLUMN_STORAGE_PREFIX + persistColumnsKey,\n JSON.stringify({ visible: [...internalVisibleKeys], known: cols.map((c) => c.key) } satisfies PersistedColumns),\n );\n } catch {\n // Storage full or unavailable — non-fatal, just don't persist.\n }\n }, [internalVisibleKeys, columns, isControlled, persistColumnsKey]);\n\n const effectiveVisible: Set<string> = isControlled ? new Set(visibleColumnKeys) : internalVisibleKeys;\n\n useEffect(() => {\n if (!toggleOpen) return;\n function onMouseDown(e: MouseEvent) {\n if (toggleRef.current && !toggleRef.current.contains(e.target as Node)) {\n setToggleOpen(false);\n }\n }\n document.addEventListener('mousedown', onMouseDown);\n return () => document.removeEventListener('mousedown', onMouseDown);\n }, [toggleOpen]);\n\n const hasColumns = !!columns?.length;\n const visibleColumns = hasColumns ? columns!.filter((c) => effectiveVisible.has(c.key)) : [];\n // A column counts as \"manually hidden\" only if it's default-visible yet\n // currently hidden — a defaultHidden column being hidden is its default\n // state, not a user choice, so it never contributes to the chip.\n const manuallyHiddenCount = hasColumns\n ? columns!.filter((c) => !c.defaultHidden && !effectiveVisible.has(c.key)).length\n : 0;\n const selectPrefix = multiSelect && hasColumns ? '40px ' : '';\n const columnTemplate = hasColumns ? `${selectPrefix}${buildColumnTemplate(visibleColumns, fitWidths)}` : undefined;\n const shouldShowToggle = showColumnToggle !== false && hasColumns;\n\n // ── `fit` column width measurement ──────────────────────────────────────────\n const fitColumns = visibleColumns.filter((c) => c.width.type === 'fit');\n const hasFit = fitColumns.length > 0;\n const fitColKey = fitColumns.map((c) => c.key).join('|');\n\n // Drop the measured pins when the data or the fit-column set changes, so the\n // measure effect below re-reads the true intrinsic width on the next pass —\n // this is what lets a column shrink (during scroll the effect only grows it,\n // to avoid jitter). Resetting state during render is React's recommended\n // pattern for \"reset on prop change\" and avoids a cascading effect render.\n const [fitReset, setFitReset] = useState<{ key: string; items: T[] }>({ key: fitColKey, items });\n if (fitReset.key !== fitColKey || fitReset.items !== items) {\n setFitReset({ key: fitColKey, items });\n if (Object.keys(fitWidths).length > 0) setFitWidths({});\n }\n\n // Measure every fit cell currently in the DOM (header + visible rows), keyed\n // by its `data-fit-key`, and grow each column's pin to the widest. Reading the\n // key off the DOM (rather than closing over `fitColumns`) keeps this a stable\n // callback the ResizeObserver below can reuse. `scrollWidth` reports the true\n // content width even when the cell is pinned narrower than its content, so a\n // later pass always recovers a column first measured while it was still empty\n // (e.g. an actions cell whose buttons mount a tick after the row commits — its\n // empty width is just the padding, ~24px, which \"only grow\" can't undo).\n const measureFitWidths = useCallback(() => {\n const root = rootRef.current;\n if (!root) return;\n const maxByKey = new Map<string, number>();\n root.querySelectorAll('[data-fit-key]').forEach((node) => {\n const el = node as HTMLElement;\n const key = el.getAttribute('data-fit-key');\n if (!key) return;\n const overflowing = el.scrollWidth > el.clientWidth;\n let w = el.scrollWidth;\n // Only resolve computed padding when we actually need it — the overflow\n // fix-up, or the collapse check below — so the hot scroll path stays cheap\n // for plain in-flow cells.\n if (overflowing || el.firstElementChild) {\n const cs = getComputedStyle(el);\n const padLeft = parseFloat(cs.paddingLeft) || 0;\n const padRight = parseFloat(cs.paddingRight) || 0;\n // scrollWidth includes the left padding but drops the right padding when\n // the content overflows — add it back.\n if (overflowing) w += padRight;\n // Collapsed-content case (FontAwesome icons etc.): element children are\n // present, yet scrollWidth is only the cell's padding because their boxes\n // overflow via `overflow: visible` and carry no intrinsic width, so they\n // don't count toward scrollWidth (and, when right-aligned, overflow to the\n // *left* into negative offsets). ONLY then walk the descendants for their\n // true span — once a real width pins, the cell is no longer collapsed, so\n // this stops running on every scroll frame.\n if (el.firstElementChild && !overflowing && el.scrollWidth <= padLeft + padRight + 1) {\n let minLeft = Infinity;\n let maxRight = -Infinity;\n el.querySelectorAll('*').forEach((d) => {\n const r = d.getBoundingClientRect();\n if (r.left < minLeft) minLeft = r.left;\n if (r.right > maxRight) maxRight = r.right;\n });\n if (maxRight > minLeft) {\n const span = Math.ceil(maxRight - minLeft) + padLeft + padRight;\n if (span > w) w = span;\n }\n }\n }\n if (w > (maxByKey.get(key) ?? 0)) maxByKey.set(key, w);\n });\n if (maxByKey.size === 0) return;\n setFitWidths((prev) => {\n let changed = false;\n const next = { ...prev };\n for (const [key, max] of maxByKey) {\n if (max <= 0) continue;\n // Cap at the viewport width so one oversized cell can't blow out layout.\n const pinned = Math.min(Math.ceil(max), root.clientWidth);\n if (pinned > (prev[key] ?? 0)) { next[key] = pinned; changed = true; }\n }\n return changed ? next : prev;\n });\n }, [rootRef]);\n\n // One ResizeObserver shared across all fit cells. It re-measures whenever a\n // cell's box changes — crucially when content first appears after mount (which\n // changes the cell's height even while its width is pinned), so a too-early or\n // empty-cell measure self-corrects instead of sticking. Its initial callback\n // also fires once after layout settles, covering route transitions and other\n // post-mount layout shifts without depending on font/rAF timing.\n const [fitObserver] = useState<ResizeObserver | null>(() =>\n typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(() => measureFitWidths()),\n );\n const observedRef = useRef<Set<Element>>(new Set());\n useEffect(() => () => { fitObserver?.disconnect(); observedRef.current.clear(); }, [fitObserver]);\n\n // Measure synchronously (before paint, so a wider row scrolling in never shows\n // a clipped frame), then *diff* the observed set rather than re-observing every\n // cell. Re-observing fires a redundant ResizeObserver callback per node, and\n // `startIndex`/`endIndex` change every scroll frame — so observing only the\n // cells that entered (and dropping the ones that left) keeps stable, already\n // pinned cells from generating any observer traffic while scrolling. A newly\n // entered cell still fires exactly once, which is when we want to measure it.\n useLayoutEffect(() => {\n if (!hasFit) return;\n const root = rootRef.current;\n if (!root) return;\n measureFitWidths();\n if (!fitObserver) return;\n const current = new Set<Element>(root.querySelectorAll('[data-fit-key]'));\n const observed = observedRef.current;\n for (const el of observed) if (!current.has(el)) { fitObserver.unobserve(el); observed.delete(el); }\n for (const el of current) if (!observed.has(el)) { fitObserver.observe(el); observed.add(el); }\n }, [hasFit, fitColKey, fitWidths, startIndex, endIndex, containerHeight, containerWidth, items, measureFitWidths, fitObserver]);\n\n // Cheap insurance: re-measure on the next two frames after mount / data /\n // fit-column changes, in case the icons (or the injected FontAwesome sizing\n // CSS) resolve a frame after the first synchronous pass. Safe and scoped —\n // measureFitWidths only ever grows a pin, and this runs on mount / data change\n // (not every scroll frame), so it keeps the diff-observe perf win.\n useEffect(() => {\n if (!hasFit) return;\n let raf2 = 0;\n const raf1 = requestAnimationFrame(() => {\n measureFitWidths();\n raf2 = requestAnimationFrame(() => measureFitWidths());\n });\n return () => { cancelAnimationFrame(raf1); cancelAnimationFrame(raf2); };\n }, [hasFit, fitColKey, items, measureFitWidths]);\n\n // Force a fresh fit-column measure regardless of current pins. Always installs\n // a new empty object so the measure layout effect re-runs even when nothing\n // was pinned (e.g. content changed while the column was still fit-content).\n const recalculateColumns = useCallback(() => setFitWidths({}), []);\n\n function handleToggleColumn(key: string) {\n const next = new Set(effectiveVisible);\n if (next.has(key)) {\n if (next.size <= 1) return;\n next.delete(key);\n } else {\n next.add(key);\n }\n const nextArray = [...next];\n if (!isControlled) setInternalVisibleKeys(next);\n onVisibleColumnsChange?.(nextArray);\n }\n\n return {\n hasColumns,\n visibleColumns,\n columnTemplate,\n shouldShowToggle,\n effectiveVisible,\n manuallyHiddenCount,\n toggleOpen,\n setToggleOpen,\n toggleRef,\n handleToggleColumn,\n recalculateColumns,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useColumns.mjs","names":[],"sources":["../../../../package/common/virtualList/useColumns.ts"],"sourcesContent":["import React, { useState, useRef, useEffect, useLayoutEffect, useCallback } from 'react';\n\nimport {\n buildColumnTemplate,\n loadPersistedColumns,\n isColumnInitiallyVisible,\n COLUMN_STORAGE_PREFIX,\n type PersistedColumns,\n} from './virtualList.utils';\nimport type { VirtualListColumn } from './virtualList.types';\n\ninterface UseColumnsArgs<T> {\n columns?: VirtualListColumn<T>[];\n items: T[];\n multiSelect: boolean;\n visibleColumnKeys?: string[];\n onVisibleColumnsChange?: (keys: string[]) => void;\n persistColumnsKey?: string;\n showColumnToggle?: boolean;\n rootRef: React.RefObject<HTMLDivElement | null>;\n /** Visible-window bounds — re-measure `fit` columns as new cells scroll in. */\n startIndex: number;\n endIndex: number;\n containerHeight: number;\n /** Re-measure `fit` columns when the container width settles (e.g. after a route transition). */\n containerWidth: number;\n}\n\ninterface UseColumnsResult<T> {\n hasColumns: boolean;\n visibleColumns: VirtualListColumn<T>[];\n columnTemplate: string | undefined;\n shouldShowToggle: boolean;\n effectiveVisible: Set<string>;\n /** How many default-visible columns the user has hidden (excludes defaultHidden). */\n manuallyHiddenCount: number;\n toggleOpen: boolean;\n setToggleOpen: React.Dispatch<React.SetStateAction<boolean>>;\n handleToggleColumn: (key: string) => void;\n /** Imperative escape hatch: drop fit-column pins so they re-measure on the\n * next layout. For out-of-band content changes that don't flow through a new\n * `items` array or `columns` set (which reset automatically). */\n recalculateColumns: () => void;\n}\n\n/**\n * Table-mode column logic: visibility (controlled or uncontrolled, with\n * localStorage persistence and runtime reconciliation), the toggle popover, and\n * `fit`-column width measurement that pins one shared px track across the header\n * and every row grid so they stay aligned.\n */\nexport function useColumns<T>({\n columns,\n items,\n multiSelect,\n visibleColumnKeys,\n onVisibleColumnsChange,\n persistColumnsKey,\n showColumnToggle,\n rootRef,\n startIndex,\n endIndex,\n containerHeight,\n containerWidth,\n}: UseColumnsArgs<T>): UseColumnsResult<T> {\n const isControlled = visibleColumnKeys !== undefined;\n const [toggleOpen, setToggleOpen] = useState(false);\n // Measured px widths for `fit` columns, keyed by column key. Pinning these\n // into the shared column template keeps the header and rows aligned (a raw\n // `fit-content` track resolves per-grid and drifts). See the effects below.\n const [fitWidths, setFitWidths] = useState<Record<string, number>>({});\n\n const [internalVisibleKeys, setInternalVisibleKeys] = useState<Set<string>>(() => {\n const persisted = loadPersistedColumns(persistColumnsKey);\n return new Set((columns ?? []).filter((c) => isColumnInitiallyVisible(c, persisted)).map((c) => c.key));\n });\n // The set of column keys the internal visibility state was last reconciled\n // against. The lazy initializer above only runs at mount, so without this a\n // list that mounts in list mode (no columns) and later switches to table mode\n // would keep an empty visible set and render no columns.\n const knownColumnKeysRef = useRef<Set<string>>(new Set((columns ?? []).map((c) => c.key)));\n\n // Re-derive internal visibility when the column set changes at runtime: new\n // columns get their saved/default visibility, removed columns drop out, and\n // existing columns keep whatever the user toggled them to. This is also what\n // applies persisted settings when a list switches from list mode to table\n // mode (columns absent at mount, supplied later).\n useEffect(() => {\n if (isControlled) return;\n const cols = columns ?? [];\n const currentKeys = new Set(cols.map((c) => c.key));\n const known = knownColumnKeysRef.current;\n let identical = currentKeys.size === known.size;\n if (identical) for (const k of currentKeys) if (!known.has(k)) { identical = false; break; }\n if (identical) return;\n knownColumnKeysRef.current = currentKeys;\n const persisted = loadPersistedColumns(persistColumnsKey);\n setInternalVisibleKeys((prev) => {\n const next = new Set<string>();\n for (const c of cols) {\n if (known.has(c.key)) {\n if (prev.has(c.key)) next.add(c.key); // preserve the current-session choice\n } else if (isColumnInitiallyVisible(c, persisted)) {\n next.add(c.key); // newly-added column: saved setting, else defaultHidden\n }\n }\n return next;\n });\n }, [columns, isControlled, persistColumnsKey]);\n\n // Persist visibility whenever it changes (uncontrolled mode only). Skip while\n // there are no columns, or the transient empty state during a list→table\n // switch before the reconcile effect above has filled in the visible set —\n // writing then would clobber the saved config with an empty set.\n useEffect(() => {\n if (isControlled || !persistColumnsKey || typeof window === 'undefined') return;\n const cols = columns ?? [];\n if (cols.length === 0 || internalVisibleKeys.size === 0) return;\n try {\n window.localStorage.setItem(\n COLUMN_STORAGE_PREFIX + persistColumnsKey,\n JSON.stringify({ visible: [...internalVisibleKeys], known: cols.map((c) => c.key) } satisfies PersistedColumns),\n );\n } catch {\n // Storage full or unavailable — non-fatal, just don't persist.\n }\n }, [internalVisibleKeys, columns, isControlled, persistColumnsKey]);\n\n // Locked columns can never be hidden — force them into the visible set even if\n // a controlled `visibleColumnKeys` or persisted state omits them. Only clone\n // (rather than mutate the state Set) when a locked key is actually missing;\n // in uncontrolled mode they're already present via isColumnInitiallyVisible.\n const baseVisible: Set<string> = isControlled ? new Set(visibleColumnKeys) : internalVisibleKeys;\n const lockedKeys = (columns ?? []).filter((c) => c.lockVisible).map((c) => c.key);\n const effectiveVisible: Set<string> = lockedKeys.some((k) => !baseVisible.has(k))\n ? new Set([...baseVisible, ...lockedKeys])\n : baseVisible;\n\n const hasColumns = !!columns?.length;\n const visibleColumns = hasColumns ? columns!.filter((c) => effectiveVisible.has(c.key)) : [];\n // A column counts as \"manually hidden\" only if it's default-visible yet\n // currently hidden — a defaultHidden column being hidden is its default\n // state, not a user choice, so it never contributes to the chip.\n const manuallyHiddenCount = hasColumns\n ? columns!.filter((c) => !c.defaultHidden && !effectiveVisible.has(c.key)).length\n : 0;\n const selectPrefix = multiSelect && hasColumns ? '40px ' : '';\n const columnTemplate = hasColumns ? `${selectPrefix}${buildColumnTemplate(visibleColumns, fitWidths)}` : undefined;\n // Hide the gear entirely when nothing is left to toggle (every column opts out).\n const shouldShowToggle = showColumnToggle !== false && hasColumns && columns!.some((c) => !c.hideFromToggle);\n\n // ── `fit` column width measurement ──────────────────────────────────────────\n const fitColumns = visibleColumns.filter((c) => c.width.type === 'fit');\n const hasFit = fitColumns.length > 0;\n const fitColKey = fitColumns.map((c) => c.key).join('|');\n\n // Drop the measured pins when the data or the fit-column set changes, so the\n // measure effect below re-reads the true intrinsic width on the next pass —\n // this is what lets a column shrink (during scroll the effect only grows it,\n // to avoid jitter). Resetting state during render is React's recommended\n // pattern for \"reset on prop change\" and avoids a cascading effect render.\n const [fitReset, setFitReset] = useState<{ key: string; items: T[] }>({ key: fitColKey, items });\n if (fitReset.key !== fitColKey || fitReset.items !== items) {\n setFitReset({ key: fitColKey, items });\n if (Object.keys(fitWidths).length > 0) setFitWidths({});\n }\n\n // Measure every fit cell currently in the DOM (header + visible rows), keyed\n // by its `data-fit-key`, and grow each column's pin to the widest. Reading the\n // key off the DOM (rather than closing over `fitColumns`) keeps this a stable\n // callback the ResizeObserver below can reuse. `scrollWidth` reports the true\n // content width even when the cell is pinned narrower than its content, so a\n // later pass always recovers a column first measured while it was still empty\n // (e.g. an actions cell whose buttons mount a tick after the row commits — its\n // empty width is just the padding, ~24px, which \"only grow\" can't undo).\n const measureFitWidths = useCallback(() => {\n const root = rootRef.current;\n if (!root) return;\n const maxByKey = new Map<string, number>();\n root.querySelectorAll('[data-fit-key]').forEach((node) => {\n const el = node as HTMLElement;\n const key = el.getAttribute('data-fit-key');\n if (!key) return;\n const overflowing = el.scrollWidth > el.clientWidth;\n let w = el.scrollWidth;\n // Only resolve computed padding when we actually need it — the overflow\n // fix-up, or the collapse check below — so the hot scroll path stays cheap\n // for plain in-flow cells.\n if (overflowing || el.firstElementChild) {\n const cs = getComputedStyle(el);\n const padLeft = parseFloat(cs.paddingLeft) || 0;\n const padRight = parseFloat(cs.paddingRight) || 0;\n // scrollWidth includes the left padding but drops the right padding when\n // the content overflows — add it back.\n if (overflowing) w += padRight;\n // Collapsed-content case (FontAwesome icons etc.): element children are\n // present, yet scrollWidth is only the cell's padding because their boxes\n // overflow via `overflow: visible` and carry no intrinsic width, so they\n // don't count toward scrollWidth (and, when right-aligned, overflow to the\n // *left* into negative offsets). ONLY then walk the descendants for their\n // true span — once a real width pins, the cell is no longer collapsed, so\n // this stops running on every scroll frame.\n if (el.firstElementChild && !overflowing && el.scrollWidth <= padLeft + padRight + 1) {\n let minLeft = Infinity;\n let maxRight = -Infinity;\n el.querySelectorAll('*').forEach((d) => {\n const r = d.getBoundingClientRect();\n if (r.left < minLeft) minLeft = r.left;\n if (r.right > maxRight) maxRight = r.right;\n });\n if (maxRight > minLeft) {\n const span = Math.ceil(maxRight - minLeft) + padLeft + padRight;\n if (span > w) w = span;\n }\n }\n }\n if (w > (maxByKey.get(key) ?? 0)) maxByKey.set(key, w);\n });\n if (maxByKey.size === 0) return;\n setFitWidths((prev) => {\n let changed = false;\n const next = { ...prev };\n for (const [key, max] of maxByKey) {\n if (max <= 0) continue;\n // Cap at the viewport width so one oversized cell can't blow out layout.\n const pinned = Math.min(Math.ceil(max), root.clientWidth);\n if (pinned > (prev[key] ?? 0)) { next[key] = pinned; changed = true; }\n }\n return changed ? next : prev;\n });\n }, [rootRef]);\n\n // One ResizeObserver shared across all fit cells. It re-measures whenever a\n // cell's box changes — crucially when content first appears after mount (which\n // changes the cell's height even while its width is pinned), so a too-early or\n // empty-cell measure self-corrects instead of sticking. Its initial callback\n // also fires once after layout settles, covering route transitions and other\n // post-mount layout shifts without depending on font/rAF timing.\n const [fitObserver] = useState<ResizeObserver | null>(() =>\n typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(() => measureFitWidths()),\n );\n const observedRef = useRef<Set<Element>>(new Set());\n useEffect(() => () => { fitObserver?.disconnect(); observedRef.current.clear(); }, [fitObserver]);\n\n // Measure synchronously (before paint, so a wider row scrolling in never shows\n // a clipped frame), then *diff* the observed set rather than re-observing every\n // cell. Re-observing fires a redundant ResizeObserver callback per node, and\n // `startIndex`/`endIndex` change every scroll frame — so observing only the\n // cells that entered (and dropping the ones that left) keeps stable, already\n // pinned cells from generating any observer traffic while scrolling. A newly\n // entered cell still fires exactly once, which is when we want to measure it.\n useLayoutEffect(() => {\n if (!hasFit) return;\n const root = rootRef.current;\n if (!root) return;\n measureFitWidths();\n if (!fitObserver) return;\n const current = new Set<Element>(root.querySelectorAll('[data-fit-key]'));\n const observed = observedRef.current;\n for (const el of observed) if (!current.has(el)) { fitObserver.unobserve(el); observed.delete(el); }\n for (const el of current) if (!observed.has(el)) { fitObserver.observe(el); observed.add(el); }\n }, [hasFit, fitColKey, fitWidths, startIndex, endIndex, containerHeight, containerWidth, items, measureFitWidths, fitObserver]);\n\n // Cheap insurance: re-measure on the next two frames after mount / data /\n // fit-column changes, in case the icons (or the injected FontAwesome sizing\n // CSS) resolve a frame after the first synchronous pass. Safe and scoped —\n // measureFitWidths only ever grows a pin, and this runs on mount / data change\n // (not every scroll frame), so it keeps the diff-observe perf win.\n useEffect(() => {\n if (!hasFit) return;\n let raf2 = 0;\n const raf1 = requestAnimationFrame(() => {\n measureFitWidths();\n raf2 = requestAnimationFrame(() => measureFitWidths());\n });\n return () => { cancelAnimationFrame(raf1); cancelAnimationFrame(raf2); };\n }, [hasFit, fitColKey, items, measureFitWidths]);\n\n // Force a fresh fit-column measure regardless of current pins. Always installs\n // a new empty object so the measure layout effect re-runs even when nothing\n // was pinned (e.g. content changed while the column was still fit-content).\n const recalculateColumns = useCallback(() => setFitWidths({}), []);\n\n function handleToggleColumn(key: string) {\n // Locked columns can't be toggled off.\n if (columns?.find((c) => c.key === key)?.lockVisible) return;\n const next = new Set(effectiveVisible);\n if (next.has(key)) {\n if (next.size <= 1) return;\n next.delete(key);\n } else {\n next.add(key);\n }\n const nextArray = [...next];\n if (!isControlled) setInternalVisibleKeys(next);\n onVisibleColumnsChange?.(nextArray);\n }\n\n return {\n hasColumns,\n visibleColumns,\n columnTemplate,\n shouldShowToggle,\n effectiveVisible,\n manuallyHiddenCount,\n toggleOpen,\n setToggleOpen,\n handleToggleColumn,\n recalculateColumns,\n };\n}\n"],"mappings":"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"}
|