{"version":3,"file":"ListCommaContinuation.DvLabZT2.mjs","names":["useRef"],"sources":["https:/framerusercontent.com/modules/IMYeCXv03Hbcu6SU6Pzi/98iQJj0JNl6vUR4MC8pV/ListCommaContinuation.js"],"sourcesContent":["import{jsx as _jsx}from\"react/jsx-runtime\";import{useEffect,useRef}from\"react\";const OBSERVER_CONFIG={childList:true,subtree:true,characterData:true};const NBSP=\"\\xa0\";const SEPARATOR_PATTERN=/,|\\band\\b/;// ---------------------------------------------------------------------------\n// Shared: self-correcting DOM wrapper\n// ---------------------------------------------------------------------------\n/**\n * Watches a wrapper element and re-applies `correct` whenever the DOM\n * changes. The observer is disconnected while `correct` runs, so our own\n * mutations never re-trigger it (mutations made while disconnected are\n * never queued). Runs are batched per animation frame.\n *\n * `isRelevant` optionally filters mutation batches so unrelated changes\n * don't schedule a run. Only use it when the correction depends solely on\n * nodes the filter can see.\n *\n * SSR-safe: all DOM access happens inside the effect.\n */function useDomCorrection(correct,isRelevant){const wrapperRef=useRef(null);const observerRef=useRef(null);const rafIdRef=useRef(null);useEffect(()=>{const wrapper=wrapperRef.current;if(!wrapper)return;const runCheck=()=>{const observer=observerRef.current;observer?.disconnect();try{correct(wrapper);}finally{observer?.observe(wrapper,OBSERVER_CONFIG);}};const schedule=()=>{if(rafIdRef.current!==null)return;rafIdRef.current=requestAnimationFrame(()=>{rafIdRef.current=null;runCheck();});};if(typeof MutationObserver!==\"undefined\"){const observer=new MutationObserver(mutations=>{if(isRelevant&&!isRelevant(mutations))return;schedule();});observerRef.current=observer;observer.observe(wrapper,OBSERVER_CONFIG);}schedule();return()=>{if(rafIdRef.current!==null){cancelAnimationFrame(rafIdRef.current);rafIdRef.current=null;}observerRef.current?.disconnect();observerRef.current=null;};},[correct,isRelevant]);return wrapperRef;}function textOf(node){return node.textContent??\"\";}function mutationsMatch(mutations,matches){for(const mutation of mutations){if(mutation.type===\"characterData\"){if(matches(mutation.target))return true;continue;}if(mutation.type===\"childList\"){for(const node of mutation.addedNodes){if(matches(node))return true;}for(const node of mutation.removedNodes){if(matches(node))return true;}}}return false;}// ---------------------------------------------------------------------------\n// withListCommaContinuation\n// ---------------------------------------------------------------------------\nfunction getLastCommaElement(root){const candidates=Array.from(root.querySelectorAll(\"*\")).filter(element=>textOf(element).trim().endsWith(\",\"));return candidates[candidates.length-1]??null;}function hasContinuationTextAfter(root,element){const range=document.createRange();range.setStartAfter(element);range.setEnd(root,root.childNodes.length);return range.toString().trim().length>0;}function stripSingleTrailingComma(element){const walker=document.createTreeWalker(element,NodeFilter.SHOW_TEXT);let lastCommaTextNode=null;for(let node=walker.nextNode();node;node=walker.nextNode()){if(textOf(node).trim().endsWith(\",\")){lastCommaTextNode=node;}}if(!lastCommaTextNode)return;lastCommaTextNode.textContent=textOf(lastCommaTextNode).replace(/,\\s*$/,\"\");}function correctTrailingComma(root){const lastCommaElement=getLastCommaElement(root);if(!lastCommaElement)return;if(!hasContinuationTextAfter(root,lastCommaElement)){stripSingleTrailingComma(lastCommaElement);}}// Note: no relevance filter here on purpose. Whether a comma should be\n// stripped depends on content *after* the comma, so a mutation that never\n// touches a comma (e.g. removing the last, comma-free item) can still\n// change the outcome. The correction itself is cheap and rAF-batched.\nexport function withListCommaContinuation(Component){return function WithListCommaContinuation(props){const wrapperRef=useDomCorrection(correctTrailingComma);return /*#__PURE__*/_jsx(\"div\",{ref:wrapperRef,style:{display:\"contents\"},children:/*#__PURE__*/_jsx(Component,{...props})});};}// ---------------------------------------------------------------------------\n// withCommaAndSeparators\n// ---------------------------------------------------------------------------\nfunction isSeparatorText(value){const normalized=value.replace(/\\u00A0/g,\" \").trim();return normalized===\",\"||normalized===\"and\";}function getSeparatorElements(root){const separators=[];const walker=document.createTreeWalker(root,NodeFilter.SHOW_ELEMENT);for(let node=walker.nextNode();node;node=walker.nextNode()){const element=node;if(element.children.length===0&&isSeparatorText(textOf(element))){separators.push(element);}}return separators;}function applySeparatorRules(separators){const lastIndex=separators.length-1;separators.forEach((separator,index)=>{if(index===lastIndex){// Kept as \",\" (just hidden) so it is still detected as a\n// separator on later runs. It still contributes to ancestors'\n// textContent, so don't stack this override with\n// withListCommaContinuation on the same frame.\nseparator.textContent=\",\";separator.style.display=\"none\";}else if(index===lastIndex-1){separator.style.display=\"\";separator.textContent=`${NBSP}and${NBSP}`;}else{separator.style.display=\"\";separator.textContent=`,${NBSP}`;}});}function correctSeparators(root){applySeparatorRules(getSeparatorElements(root));}// Safe to filter here: the correction depends only on the separator\n// elements themselves, and every mutation that changes them contains a\n// comma or the standalone word \"and\".\nfunction separatorMutationsAreRelevant(mutations){return mutationsMatch(mutations,node=>SEPARATOR_PATTERN.test(textOf(node)));}export function withCommaAndSeparators(Component){return function WithCommaAndSeparators(props){const wrapperRef=useDomCorrection(correctSeparators,separatorMutationsAreRelevant);return /*#__PURE__*/_jsx(\"div\",{ref:wrapperRef,style:{display:\"contents\"},children:/*#__PURE__*/_jsx(Component,{...props})});};}\nexport const __FramerMetadata__ = {\"exports\":{\"withCommaAndSeparators\":{\"type\":\"reactHoc\",\"name\":\"withCommaAndSeparators\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withListCommaContinuation\":{\"type\":\"reactHoc\",\"name\":\"withListCommaContinuation\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./ListCommaContinuation.map"],"mappings":"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"}