phlex-reactive 0.15.2 → 0.15.3

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.
@@ -638,12 +638,16 @@ function fieldResolver(c, owns) {
638
638
  }
639
639
 
640
640
  // --- Media bindings (issue #373) ---------------------------------------------
641
- // data-reactive-media='{"field","take"?,"pool","label"?,"blank"?}' on a preview
642
- // <img>: the owned field's value (its first `take` characters, or all of it)
643
- // is a key into `pool`, whose value is a SELECTOR for an <img> inside the root.
644
- // The core's copyMedia copies that element's src, srcset and alt — a pool
645
- // value is never assigned to anything. A key, selector or element that misses
646
- // clears the preview; `label` gets the alt (or `blank`) via textContent. An
641
+ // data-reactive-media='{"field","take"?,"match"?,"pending"?,"pool","label"?,"blank"?}'
642
+ // on a preview <img>: the owned field's value (its first `take` characters, or
643
+ // all of it) is a key into `pool`, whose value is a SELECTOR for an <img>
644
+ // inside the root. The core's copyMedia copies that element's src, srcset and
645
+ // alt — a pool value is never assigned to anything. A key, selector or element
646
+ // that misses clears the preview; `label` gets the alt (or `blank`) via
647
+ // textContent. A key shorter than `take`, or one the anchored `match` source
648
+ // rejects, is PENDING (issue #380) and never gets `blank`: "keep" leaves the
649
+ // preview and label alone, the default clears both. The preview's
650
+ // data-reactive-media-state names the outcome (pending | hit | miss). An
647
651
  // unowned field leaves the preview alone (the show default-deny); a malformed
648
652
  // attr warns and is skipped.
649
653
  const MEDIA_BINDING_SELECTOR = "[data-reactive-media]"
@@ -651,26 +655,41 @@ const MEDIA_BINDING_SELECTOR = "[data-reactive-media]"
651
655
  function syncMedia(c, fieldValue, owns) {
652
656
  for (const el of c.root.querySelectorAll(MEDIA_BINDING_SELECTOR)) {
653
657
  if (!owns(el)) continue
654
- let wire
658
+ let wire, pattern
655
659
  try {
656
660
  wire = JSON.parse(el.getAttribute("data-reactive-media"))
661
+ if (wire?.match != null) pattern = new RegExp(`^(?:${wire.match})$`)
657
662
  } catch {}
658
- if (typeof wire?.field !== "string" || !wire.pool || typeof wire.pool !== "object") {
663
+ if (typeof wire?.field !== "string" || !wire.pool || typeof wire.pool !== "object" || (wire.match != null && !pattern)) {
659
664
  console.warn("[phlex-reactive] malformed data-reactive-media — skipped")
660
665
  continue
661
666
  }
662
667
  const value = fieldValue(wire.field)
663
668
  if (value === null) continue
664
669
  // Characters (code points), as Ruby counts them — not UTF-16 code units.
665
- const key = wire.take > 0 ? [...value].slice(0, wire.take).join("") : value
666
- const source = Object.hasOwn(wire.pool, key) ? mediaMatches(c, wire.pool[key])[0] : null
670
+ const chars = wire.take > 0 ? [...value] : null
671
+ const key = chars ? chars.slice(0, wire.take).join("") : value
672
+ const pending = chars?.length < wire.take || pattern?.test(key) === false
673
+ if (pending && wire.pending === "keep") {
674
+ mediaState(el, "pending")
675
+ continue
676
+ }
677
+ const source = !pending && Object.hasOwn(wire.pool, key) ? mediaMatches(c, wire.pool[key])[0] : null
667
678
  const alt = c.core.copyMedia(el, source ?? null)
668
- if (alt === null || typeof wire.label !== "string") continue
669
- const text = alt === false ? String(wire.blank ?? "") : alt
679
+ if (alt === null) continue
680
+ mediaState(el, pending ? "pending" : alt === false ? "miss" : "hit")
681
+ if (typeof wire.label !== "string") continue
682
+ const text = pending ? "" : alt === false ? String(wire.blank ?? "") : alt
670
683
  for (const node of mediaMatches(c, wire.label)) if (node.textContent !== text) node.textContent = text
671
684
  }
672
685
  }
673
686
 
687
+ // The outcome a stylesheet (or :has()) can hide a row on, written only when
688
+ // it changes.
689
+ function mediaState(el, state) {
690
+ if (el.getAttribute("data-reactive-media-state") !== state) el.setAttribute("data-reactive-media-state", state)
691
+ }
692
+
674
693
  // The owned elements a pool or label selector names — none when it does not
675
694
  // parse (a URL string is not a selector), and none for the "@root" sentinel:
676
695
  // a label naming the root would rewrite the whole root's text.
@@ -1,4 +1,4 @@
1
- import{confirmPredicate as ae}from"phlex/reactive/confirm_predicate";var g=new WeakMap,q=new WeakMap;function p(e,r){let t=g.get(e);if(!t){if(g.set(e,t={root:e.element,core:r,nestedIndex:0}),t.root)q.set(t.root,t)}return t}function d(e,r,t){for(let o of r.split(" "))e.root.addEventListener?.(o,t),e.offs.push(()=>e.root.removeEventListener?.(o,t))}function y(e,r){d(e,"turbo:morph-element",r),e.seeds.push(r),r()}function Be(e,r){let t=p(e,r);t.offs=[],t.seeds=[];let o,n,i,a;(t.wire=()=>{if(!t.show&&fe(t))t.show=(s)=>{if(t.flipping)return;if(s?.type==="input"||s?.type==="change")Ae(t,s.target);else t.groups=be(t),M(t);ge(t)},d(t,"input change",t.show),y(t,t.show);if(!t.arm&&de(t))d(t,"input change",(s)=>R(t,s)),y(t,t.arm=()=>{R(t,null),M(t)});if(!o&&(o=t.show||t.arm))d(t,"reset",()=>setTimeout(()=>{if(g.get(e)!==t)return;t.show?.(),t.arm?.()},0));if(!n&&(n=A(t)))d(t,"input",(s)=>xe(t,s)&&m(t)),y(t,()=>m(t));if(!i&&(i=S(t)))y(t,()=>Y(t));if(!a&&(a=Ce(t)))d(t,"input change",(s)=>V(t,s)),y(t,()=>O(t))})(),d(t,"keydown",(s)=>Ie(t,s)),d(t,"paste drop",(s)=>Pe(t,s)),d(t,"input",(s)=>We(t,s))}function Fe(e){let r=g.get(e);if(!r)return;g.delete(e),q.delete(r.root);for(let t of r.offs??[])t();r.groupObserver?.disconnect()}function Ke(e){let r=g.get(e);if(!r)return;for(let t of r.seeds)t();r.wire()}function h(e){if(typeof e.dispatchEvent==="function")e.dispatchEvent(new Event("input",{bubbles:!0}))}function He(e,r,t){return V(p(e,r),t)}function ze(e,r,t){return oe(p(e,r),t)}var se=/^#[A-Za-z_][\w-]*$/,D="[data-reactive-show-field], [data-reactive-show]";function ce(e,r){let t=e.getAttribute("data-reactive-show-equals");if(t!==null)return r===t;let o=e.getAttribute("data-reactive-show-not");if(o!==null)return r!==o;let n=e.getAttribute("data-reactive-show-in");if(n!==null){try{let i=JSON.parse(n);if(Array.isArray(i))return i.includes(r)}catch{}return console.warn(`[phlex-reactive] malformed reactive_show in: list ${JSON.stringify(n)} — skipped`),null}for(let i of X){let a=e.getAttribute(`data-reactive-show-${i}`);if(a!==null)return re(i,a,r)}return console.warn("[phlex-reactive] a reactive_show binding declares no predicate — skipped"),null}function I(e){try{let r=JSON.parse(e);if(r&&typeof r==="object"&&!Array.isArray(r))return r}catch{}return console.warn(`[phlex-reactive] malformed compound reactive_show payload ${JSON.stringify(e)} — skipped`),null}function le(e){try{let r=JSON.parse(e);if(Array.isArray(r)&&r.every((t)=>t&&typeof t==="object"&&Array.isArray(t.any)&&Array.isArray(t.ops)))return r}catch{}return console.warn(`[phlex-reactive] malformed reactive_on_complete payload ${JSON.stringify(e)} — skipped`),[]}function P(e,r){if(!e||typeof e!=="object")return null;let t=e.any;if(Array.isArray(t)&&(t.length===0||Array.isArray(t[0])))return v(t,r);return ue(e,r)}function ue(e,r){let t=Array.isArray(e.all)?"all":Array.isArray(e.any)?"any":null;if(!t)return null;let o=e[t];if(o.length===0)return null;let n=o.map((i)=>E(i,r));return t==="all"?n.every(Boolean):n.some(Boolean)}function b(e,r="show"){if(typeof e==="string"&&se.test(e))return!0;return console.warn(`[phlex-reactive] refused cross-root ${r} target ${JSON.stringify(e)} — skipped`),!1}function fe(e){if(e.root.getAttribute?.("data-reactive-show-targets"))return!0;if(e.root.getAttribute?.("data-reactive-group-targets"))return!0;let r=e.root.querySelectorAll?.(D)??[];for(let t of r)if(e.core.owns(t))return!0;for(let t of e.root.querySelectorAll?.(w)??[])if(e.core.owns(t))return!0;for(let t of e.root.querySelectorAll?.(F)??[])if(e.core.owns(t))return!0;return!1}function de(e){return!!e.root.getAttribute?.("data-reactive-on-complete")}function pe(e){let r=e.root.getAttribute?.("data-reactive-on-complete")??null;if(r!==e.onCompleteRaw)e.onCompleteRaw=r,e.onCompleteParsed=r==null?[]:le(r),e.onCompleteStates=e.onCompleteParsed.map(()=>!1);return e.onCompleteParsed}function R(e,r){let t=pe(e);if(!t.length)return;let o=B(e,e.core.ownership());t.forEach((n,i)=>{let a=v(n.any,o);if(a===null)return;let s=a&&!e.onCompleteStates[i]&&Boolean(r);if(e.onCompleteStates[i]=a,s)e.core.applyOps(n.ops,"@root")})}function ge(e){if(typeof e.root?.querySelectorAll!=="function")return;let r=e.core.ownership(),t=e.root.getAttribute?.("data-reactive-scope")||null,o=B(e,r);for(let n of e.root.querySelectorAll(D)){if(!r(n))continue;let i=n.getAttribute("data-reactive-show");if(i!==null){let l=P(I(i),o);if(l!==null)J(n,l,r,t);continue}let a=n.getAttribute("data-reactive-show-field");if(!a)continue;let s=o(a);if(s===null)continue;let c=ce(n,s);if(c===null)continue;J(n,c,r,t)}if(e.groups)we(e,o,r,t);ve(e,o,r),he(e,o),Se(e,o)}function J(e,r,t,o){if(e.hidden=!r,e.getAttribute("data-reactive-show-disable")!=="true")return;if(typeof e.querySelectorAll!=="function")return;for(let n of e.querySelectorAll("input[name], select[name], textarea[name]"))if(t(n))n.disabled=!r;if(e.name&&t(e))e.disabled=!r}function he(e,r){let t=W(e);for(let[o,n]of Object.entries(t)){if(o.startsWith("#")){ye(o,n,r);continue}if(!n||typeof n!=="object"||Array.isArray(n))continue;let i=r(o);if(i===null)continue;let a=(s,c)=>c?r(o,!0):i;for(let[s,c]of Object.entries(n)){if(!b(s))continue;let l;if(Array.isArray(c)){if(c.length===0){console.warn(`[phlex-reactive] malformed reactive_show_targets group for ${s} — skipped`);continue}l=c.every((u)=>E(u,a))}else{let u=ne(c,i);if(u===null){console.warn(`[phlex-reactive] malformed reactive_show_targets predicate for ${s} — skipped`);continue}l=u}for(let u of document.querySelectorAll(s))u.hidden=!l}}}function ye(e,r,t){if(!b(e))return;let o=r&&typeof r==="object"&&!Array.isArray(r)?r.any:null,n=Le(o);if(n===null){console.warn(`[phlex-reactive] malformed reactive_show_targets conditions for ${e} — skipped`);return}if(n.every((a)=>t(a)===null)&&!De(o))return;let i=v(o,t);if(i===null)return;for(let a of document.querySelectorAll(e))a.hidden=!i}function W(e,r="show",t="mode: { ... }, kind: { ... }"){let o=e.root.getAttribute?.(`data-reactive-${r}-targets`);if(!o)return{};try{let n=JSON.parse(o);if(n&&typeof n==="object"&&!Array.isArray(n))return n}catch{}return console.warn(`[phlex-reactive] malformed data-reactive-${r}-targets — ignored. `+`Did two reactive_${r}_targets calls collide on one root? Declare every entry in ONE call: reactive_${r}_targets(${t})`),{}}function me(e,r,t,o){let n=!1,i=null;for(let a of e.root.querySelectorAll(G(r,o))){if(!t(a))continue;if(a.type==="checkbox")return a.checked?"true":"false";if(a.type==="radio"){if(a.checked)return a.value??"";n=!0;continue}i??=a}if(i)return i.value??"";return n?"":null}function G(e,r){return`[name="${r&&!e.includes("[")?`${r}[${e}]`:e}"]`}function B(e,r){let t=e.root.getAttribute?.("data-reactive-scope")||null,o=new Map;return(n,i)=>{let a=i?`#${n}`:n;if(!o.has(a))o.set(a,i?_(e,n,r,t).filter((s)=>s.checked).length:me(e,n,r,t));return o.get(a)}}var F="[data-reactive-media]";function ve(e,r,t){for(let o of e.root.querySelectorAll(F)){if(!t(o))continue;let n;try{n=JSON.parse(o.getAttribute("data-reactive-media"))}catch{}if(typeof n?.field!=="string"||!n.pool||typeof n.pool!=="object"){console.warn("[phlex-reactive] malformed data-reactive-media — skipped");continue}let i=r(n.field);if(i===null)continue;let a=n.take>0?[...i].slice(0,n.take).join(""):i,s=Object.hasOwn(n.pool,a)?T(e,n.pool[a])[0]:null,c=e.core.copyMedia(o,s??null);if(c===null||typeof n.label!=="string")continue;let l=c===!1?String(n.blank??""):c;for(let u of T(e,n.label))if(u.textContent!==l)u.textContent=l}}function T(e,r){try{return r==="@root"?[]:e.core.opTargets({to:r})}catch{return[]}}var w="[data-reactive-enable], [data-reactive-select-all], [data-reactive-count]";function be(e){return!!e.root.querySelector?.(w)}function _(e,r,t,o){return[...e.root.querySelectorAll(G(r,o))].filter((n)=>n.type==="checkbox"&&t(n))}function Ae(e,r){let t=r?.getAttribute?.("data-reactive-select-all");if(t&&e.core.owns(r))K(e,t,r.checked,r)}function Ye(e,r,t){if(!r)return;let o=q.get(e)??{root:e,core:{ownership:()=>(n)=>n.closest('[data-controller~="reactive"]')===e}};K(o,r,t!==!1),o.show?.()}function K(e,r,t,o){let n=e.root.getAttribute?.("data-reactive-scope")||null,i=_(e,r,e.core.ownership(),n).filter((a)=>a!==o&&a.checked!==t);for(let a of i)a.checked=t;e.flipping=!0;try{for(let a of i)for(let s of["input","change"])a.dispatchEvent?.(new Event(s,{bubbles:!0}))}finally{e.flipping=!1}}function we(e,r,t,o){for(let n of e.root.querySelectorAll(w)){if(!t(n))continue;let i=n.getAttribute("data-reactive-enable");if(i!==null){let c=P(I(i),r);if(c!==null)n.disabled=!c}let a=n.getAttribute("data-reactive-count");if(a){let c=String(r(a,!0));if(n.textContent!==c)n.textContent=c}let s=n.getAttribute("data-reactive-select-all");if(s){let c=_(e,s,t,o).filter((u)=>u!==n),l=c.filter((u)=>u.checked).length;n.checked=l>0&&l===c.length,n.indeterminate=l>0&&l<c.length}}}function Se(e,r){for(let[t,o]of Object.entries(W(e,"group",'"ids[]" => { ... }, "tags[]" => { ... }'))){if(!o||typeof o!=="object"||Array.isArray(o))continue;let n=String(r(t,!0));for(let a of Array.isArray(o.count)?o.count:[]){if(!b(a,"group"))continue;for(let s of document.querySelectorAll(a))if(s.textContent!==n)s.textContent=n}let i=o.enable&&typeof o.enable==="object"?o.enable:{};for(let[a,s]of Object.entries(i)){if(!b(a,"group"))continue;let c=v(s?.any,r);if(c===null){console.warn(`[phlex-reactive] malformed reactive_group_targets enable for ${a} — skipped`);continue}for(let l of document.querySelectorAll(a))l.disabled=!c}}}function M(e){if(e.groupObserver||typeof MutationObserver!=="function")return;let r=(n)=>e.root.getAttribute?.(`data-reactive-${n}`)?.includes("checked_");if(!e.root.getAttribute?.("data-reactive-group-targets")&&!e.root.querySelector?.(`${w}, [data-reactive-show*=checked_]`)&&!r("show-targets")&&!r("on-complete"))return;let o=(n)=>n.nodeType===1&&(n.matches('input[type="checkbox"]')||!!n.querySelector('input[type="checkbox"]'));e.groupObserver=new MutationObserver((n)=>{if(!n.some((i)=>[...i.addedNodes,...i.removedNodes].some(o)))return;e.show?.(),e.arm?.()}),e.groupObserver.observe(e.root,{childList:!0,subtree:!0})}function A(e){return!!(e.root.getAttribute?.("data-reactive-filter-input")&&e.root.getAttribute?.("data-reactive-filter-option"))}function xe(e,r){let t=e.root.getAttribute("data-reactive-filter-input");return!!t&&typeof r.target?.matches==="function"&&r.target.matches(t)}function m(e){if(typeof e.root?.querySelectorAll!=="function")return;let r=e.root.getAttribute("data-reactive-filter-input"),t=e.root.getAttribute("data-reactive-filter-option");if(!r||!t)return;let o=e.core.ownership(),n=[...e.root.querySelectorAll(r)].find(o);if(!n)return;let i=(n.value??"").trim().toLowerCase(),a=0;for(let l of e.root.querySelectorAll(t)){if(!o(l))continue;let u=(l.getAttribute("data-reactive-filter-text")??l.textContent??"").toLowerCase(),f=l.hasAttribute?.("data-reactive-tags-selected")||i!==""&&!u.includes(i);if(l.hidden=f,f)l.removeAttribute("data-reactive-highlighted");else a++}let s=e.root.getAttribute("data-reactive-filter-group");if(s)for(let l of e.root.querySelectorAll(s)){if(!o(l))continue;let u=[...l.querySelectorAll(t)].filter(o);if(u.length===0)continue;l.hidden=u.every((f)=>f.hidden)}let c=e.root.getAttribute("data-reactive-filter-empty");if(c){for(let l of e.root.querySelectorAll(c))if(o(l))l.hidden=a>0}}function S(e){return!!e.root.getAttribute?.("data-reactive-tags-field")}function Ce(e){if(typeof e.root?.querySelector!=="function")return!1;return!!e.root.querySelector("[data-reactive-nested-json]")}function k(e){if(typeof e.root?.querySelectorAll!=="function")return null;let r=e.root.getAttribute("data-reactive-tags-field");if(!r)return null;let t=e.core.ownership();return[...e.root.querySelectorAll(r)].find(t)??null}function N(e){let r=new Set,t=[];for(let o of String(e.value??"").split(",")){let n=o.trim();if(n===""||r.has(n.toLowerCase()))continue;r.add(n.toLowerCase()),t.push(n)}return t}function H(e,r){let t=k(e);if(!t)return!1;let o=N(t),n=new Set(o.map((a)=>a.toLowerCase())),i=!1;for(let a of r){let s=String(a??"").trim();if(s===""||n.has(s.toLowerCase()))continue;n.add(s.toLowerCase()),o.push(s),i=!0}if(i)z(e,t,o);return i}function z(e,r,t){r.value=t.join(","),h(r),Y(e)}function qe(e){if(typeof e.root?.querySelectorAll!=="function")return null;let r=e.root.getAttribute("data-reactive-filter-input");if(!r)return null;let t=e.core.ownership();return[...e.root.querySelectorAll(r)].find(t)??null}function Y(e){let r=k(e);if(!r)return;let t=N(r),o=e.core.ownership();_e(e,t,o),ke(e,t,o)}function _e(e,r,t){let o=[...e.root.querySelectorAll("[data-reactive-tags-list]")].find(t);if(!o)return;let i=[...e.root.querySelectorAll("[data-reactive-tags-template]")].find(t)?.content?.firstElementChild;if(!i){if(!e.tagsWarnedTemplate)console.warn("[phlex-reactive] reactive_tags: no chip <template data-reactive-tags-template> found in this root — "+"chips will not render (the hidden field still updates). Add a template with a [data-reactive-tag-text] node and a reactive_tags_remove button."),e.tagsWarnedTemplate=!0;return}while(o.firstChild)o.removeChild(o.firstChild);for(let a of r){let s=i.cloneNode(!0);s.setAttribute?.("data-reactive-tag",a);let c=s.matches?.("[data-reactive-tag-text]")?s:(s.querySelectorAll?.("[data-reactive-tag-text]")??[])[0];if(c)c.textContent=a;let l=[...s.querySelectorAll?.('[data-action*="reactive#tagsRemove"]')??[]];if(s.matches?.('[data-action*="reactive#tagsRemove"]'))l.push(s);for(let u of l)u.setAttribute?.("data-reactive-tag-param",a);o.appendChild(s)}}function ke(e,r,t){let o=new Set(r.map((n)=>n.toLowerCase()));for(let n of e.root.querySelectorAll("[role=option]")){if(!t(n))continue;let i=n.getAttribute?.("data-reactive-tag-param");if(!i)continue;if(o.has(i.toLowerCase()))n.setAttribute("data-reactive-tags-selected","true"),n.hidden=!0,n.removeAttribute?.("data-reactive-highlighted");else if(n.hasAttribute?.("data-reactive-tags-selected")){if(n.removeAttribute("data-reactive-tags-selected"),!A(e))n.hidden=!1}}if(A(e))m(e)}function Ne(e){return e.nestedIndex=Math.max(e.nestedIndex+1,Date.now()),e.nestedIndex}function Oe(e,r){let t=[e,...e.querySelectorAll?.("*")??[]];for(let o of t)for(let n of["name","id","for"]){let i=o.getAttribute?.(n);if(i&&i.includes("NEW_ROW"))o.setAttribute?.(n,i.replaceAll("NEW_ROW",String(r)))}}function Ee(e,r){if(e.nestedWarned)return;console.warn(`[phlex-reactive] nested rows: no owned [data-reactive-nested-list="${r}"] container + <template data-reactive-nested-template="${r}"> pair found in this root — the add `+"trigger did nothing. Render both inside the same reactive root (reactive_nested_list / reactive_nested_template)."),e.nestedWarned=!0}function $e(e,r,t,o){if(!t)return null;let n;try{n=JSON.parse(t)}catch{return null}if(!n||typeof n!=="object")return null;let i=e.core.ownership(),a=[...r.querySelectorAll?.("input, select, textarea")??[]],s=[];for(let[c,l]of Object.entries(n)){let u=[...e.root.querySelectorAll?.(l)??[]].find(i);if(!u)continue;let f=a.find((x)=>Q(x.getAttribute?.("name"))===c);if(!f)continue;je(f,u),s.push(u)}if(o)for(let c of s)Re(c);return s[0]??null}function je(e,r){if(e.type==="checkbox")e.checked=r.type==="checkbox"?!!r.checked:C(r)!=="";else e.value=C(r);h(e)}function Re(e){if(e.type==="checkbox")e.checked=!1;else e.value="";h(e)}function Je(e,r){if(!e.includes("%{"))return e;return e.replace(/%\{(\w+)\}/g,(t,o)=>Object.prototype.hasOwnProperty.call(r,o)?r[o]:t)}function L(e,r){let t=[...r.querySelectorAll?.('input[name$="[_destroy]"]')??[]][0];if(t)t.value="1",h(t),r.hidden=!0;else r.parentNode?.removeChild?.(r);O(e)}function O(e){if(typeof e.root?.querySelectorAll!=="function")return;let r=e.core.ownership();for(let t of[...e.root.querySelectorAll("[data-reactive-nested-json]")].filter(r))Z(e,t.getAttribute("data-reactive-nested-json"))}function Te(e,r){let t=r.getAttribute?.("data-reactive-nested-json-field");if(!t)return null;let o=e.core.ownership();return[...e.root.querySelectorAll(t)].find(o)??null}function U(e,r){let t={},o=e.core.ownership();for(let n of[...r.querySelectorAll?.("input, select, textarea")??[]]){if(n.matches(":disabled")||n.type==="radio"&&!n.checked||!o(n))continue;let i=Q(n.getAttribute?.("name"));if(i===null||i==="_destroy")continue;t[i]=C(n)}return t}function Q(e){if(!e)return null;let r=e.match(/\[([^\][]+)\]$/);return r?r[1]:e}function C(e){if(e.type==="checkbox")return e.checked?e.value||"on":"";return e.value??""}function Z(e,r){let t=e.core.ownership(),o=[...e.root.querySelectorAll(`[data-reactive-nested-list="${r}"]`)].find(t);if(!o)return;let n=Te(e,o);if(!n)return;let i=[];for(let s of[...o.querySelectorAll?.("[data-reactive-nested-row]")??[]]){if(!t(s)||s.hidden)continue;i.push(U(e,s))}let a=JSON.stringify(i);if(n.value===a)return;n.value=a,h(n)}function Ue(e,r,t){let o=p(e,r);if(!S(o))return;if(t?.defaultPrevented)return;if(o.core.listnavOptions(t).some((a)=>a.hasAttribute?.("data-reactive-highlighted")))return;t?.preventDefault?.();let n=t?.currentTarget??t?.target;if(!n)return;if(!H(o,String(n.value??"").split(",")))return;if(n.value="",A(o))m(o)}function Qe(e,r,t){let o=p(e,r);if(!S(o))return;t?.preventDefault?.();let i=(t?.currentTarget??t?.target)?.getAttribute?.("data-reactive-tag-param");if(!i)return;if(!H(o,[i]))return;let a=qe(o);if(!a)return;a.value="",m(o),a.focus?.()}function Ze(e,r,t){let o=p(e,r);if(!S(o))return;t?.preventDefault?.();let i=(t?.currentTarget??t?.target)?.getAttribute?.("data-reactive-tag-param");if(!i)return;let a=k(o);if(!a)return;let s=N(a),c=s.filter((l)=>l.toLowerCase()!==i.toLowerCase());if(c.length===s.length)return;z(o,a,c)}function Ve(e,r,t){let o=p(e,r);t?.preventDefault?.();let n=t?.currentTarget??t?.target,i=n?.getAttribute?.("data-reactive-association-param");if(!i)return;if(typeof o.root?.querySelectorAll!=="function")return;let a=o.core.ownership(),s=[...o.root.querySelectorAll(`[data-reactive-nested-list="${i}"]`)].find(a),l=[...o.root.querySelectorAll(`[data-reactive-nested-template="${i}"]`)].find(a)?.content?.firstElementChild;if(!s||!l){Ee(o,i);return}let u=l.cloneNode(!0);Oe(u,Ne(o)),s.appendChild(u);let f=n?.getAttribute?.("data-reactive-nested-from-param"),x=n?.getAttribute?.("data-reactive-nested-clear-param")==="true",ie=$e(o,u,f,x);if(f)ie?.focus?.();else[...u.querySelectorAll?.("input, select, textarea")??[]][0]?.focus?.();if(s.getAttribute?.("data-reactive-nested-json")===i)Z(o,i)}function Xe(e,r,t){let o=p(e,r);t?.preventDefault?.();let n=t?.currentTarget??t?.target,i=n?.closest?.("[data-reactive-nested-row]");if(!i)return;if(i.closest?.('[data-controller~="reactive"]')!==o.root)return;let a=n?.getAttribute?.("data-reactive-confirm-param"),s=n?.getAttribute?.("data-reactive-confirm-when-param"),c=a||(s?oe(o,s):null);if(!c)return L(o,i);let l=U(o,i),u=Je(c,l);return o.core.confirm(u,{el:n,row:i,fields:l}).then((f)=>{if(f)L(o,i)})}function V(e,r){let t=r?.target;if(!t||!e.core.owns(t))return;O(e)}var X=["gte","gt","lte","lt"],Me=["len_eq","len_gte","len_gt","len_lte","len_lt"],ee=["checked_eq","checked_gte","checked_gt","checked_lte","checked_lt"];function te(e,r,t){if(!Number.isInteger(r))return console.warn(`[phlex-reactive] reactive_show ${e}: needs an integer literal, got ${JSON.stringify(r)} — skipped`),null;switch(e.slice(e.indexOf("_")+1)){case"eq":return t===r;case"gte":return t>=r;case"gt":return t>r;case"lte":return t<=r;case"lt":return t<r;default:return null}}function re(e,r,t){let o=Number(r);if(Number.isNaN(o))return console.warn(`[phlex-reactive] reactive_show ${e}: needs a numeric literal, got ${JSON.stringify(r)} — skipped`),null;let n=t==null?"":String(t).trim(),i=n===""?NaN:Number(n);if(Number.isNaN(i))return!1;switch(e){case"gte":return i>=o;case"gt":return i>o;case"lte":return i<=o;case"lt":return i<o;default:return null}}function ne(e,r){if(!e||typeof e!=="object")return null;if(typeof e.equals==="string")return r===e.equals;if(typeof e.not==="string")return r!==e.not;if(Array.isArray(e.in))return e.in.includes(r);for(let t of X)if(t in e)return re(t,e[t],r);for(let t of Me)if(t in e)return te(t,e[t],[...String(r??"")].length);return null}function E(e,r){if(!e||typeof e!=="object"||typeof e.field!=="string")return!1;let t=ee.find((n)=>(n in e));if(t){let n=r(e.field,!0);return te(t,e[t],Array.isArray(n)?n.length:Number(n)||0)===!0}let o=r(e.field)??"";return ne(e,o)===!0}function v(e,r){if(!Array.isArray(e)||e.length===0)return null;return e.some((t)=>Array.isArray(t)&&t.length>0&&t.every((o)=>E(o,r)))}function Le(e){if(!Array.isArray(e)||e.length===0)return null;let r=new Set;for(let t of e){if(!Array.isArray(t))continue;for(let o of t)if(o&&typeof o==="object"&&typeof o.field==="string")r.add(o.field)}return r.size>0?[...r]:null}function De(e){return e.flat().every((r)=>ee.some((t)=>(t in Object(r))))}function oe(e,r){let t=r;if(typeof r==="string")try{t=JSON.parse(r)}catch{return console.warn(`[phlex-reactive] malformed conditional confirm payload ${JSON.stringify(r)} — skipped`),null}if(!t||typeof t!=="object")return null;let{fields:o}=e.core.collectFields(),n=(a)=>o[a],i;if(typeof t.predicate==="string"){let a=ae(t.predicate);if(!a)return console.warn(`[phlex-reactive] confirm predicate "${t.predicate}" is not registered — proceeding without a dialog (register it with setConfirmPredicate)`),null;i=!!a(o)}else i=v(t.groups?.any,n)===!0;return i?t.message:null}function j(e,r){let t=r.target?.closest?.("[data-reactive-editable]");return t&&e.core.owns(t)?t:null}function Ie(e,r){let t=j(e,r);if(!t||r.isComposing||r.keyCode===229)return;if(r.key==="Enter"){let o=t.getAttribute("data-reactive-editable-enter");if(t.getAttribute("data-reactive-editable")==="multi"&&(o==null||r.shiftKey))return;if(r.preventDefault(),o==="submit")t.closest("form")?.requestSubmit();else if(o)e.core.applyOps(JSON.parse(o),"@root")}else if(r.key==="Escape"&&t.hasAttribute("data-reactive-editable-escape"))r.preventDefault(),t.textContent=e.core.served(t),h(t),t.blur()}function Pe(e,r){let t=j(e,r),o=t?.getAttribute("data-reactive-editable")!=="multi",n=(r.clipboardData??r.dataTransfer)?.getData("text/plain");if(!t||n==null||e.core.plain()&&!(o&&/[\r\n]/.test(n)))return;if(r.preventDefault(),o)n=n.replace(/\r?\n|\r/g," ");t.focus(),document.execCommand("insertText",!1,n)}function We(e,r){let t=j(e,r);if(t?.firstChild&&e.core.text(t)==="")t.replaceChildren()}export{Ye as checkGroup,ze as confirmMessage,Be as connect,Fe as disconnect,Ve as nestedAdd,Xe as nestedRemove,Ke as reseed,He as syncNestedJson,Ue as tagsAdd,Qe as tagsPick,Ze as tagsRemove};
1
+ import{confirmPredicate as se}from"phlex/reactive/confirm_predicate";var h=new WeakMap,q=new WeakMap;function p(e,r){let t=h.get(e);if(!t){if(h.set(e,t={root:e.element,core:r,nestedIndex:0}),t.root)q.set(t.root,t)}return t}function d(e,r,t){for(let o of r.split(" "))e.root.addEventListener?.(o,t),e.offs.push(()=>e.root.removeEventListener?.(o,t))}function m(e,r){d(e,"turbo:morph-element",r),e.seeds.push(r),r()}function Fe(e,r){let t=p(e,r);t.offs=[],t.seeds=[];let o,n,i,a;(t.wire=()=>{if(!t.show&&de(t))t.show=(s)=>{if(t.flipping)return;if(s?.type==="input"||s?.type==="change")we(t,s.target);else t.groups=Ae(t),D(t);he(t)},d(t,"input change",t.show),m(t,t.show);if(!t.arm&&pe(t))d(t,"input change",(s)=>J(t,s)),m(t,t.arm=()=>{J(t,null),D(t)});if(!o&&(o=t.show||t.arm))d(t,"reset",()=>setTimeout(()=>{if(h.get(e)!==t)return;t.show?.(),t.arm?.()},0));if(!n&&(n=S(t)))d(t,"input",(s)=>Ce(t,s)&&v(t)),m(t,()=>v(t));if(!i&&(i=C(t)))m(t,()=>Q(t));if(!a&&(a=ke(t)))d(t,"input change",(s)=>ee(t,s)),m(t,()=>E(t))})(),d(t,"keydown",(s)=>Pe(t,s)),d(t,"paste drop",(s)=>We(t,s)),d(t,"input",(s)=>Ge(t,s))}function Ke(e){let r=h.get(e);if(!r)return;h.delete(e),q.delete(r.root);for(let t of r.offs??[])t();r.groupObserver?.disconnect()}function He(e){let r=h.get(e);if(!r)return;for(let t of r.seeds)t();r.wire()}function y(e){if(typeof e.dispatchEvent==="function")e.dispatchEvent(new Event("input",{bubbles:!0}))}function ze(e,r,t){return ee(p(e,r),t)}function Ye(e,r,t){return ae(p(e,r),t)}var ce=/^#[A-Za-z_][\w-]*$/,P="[data-reactive-show-field], [data-reactive-show]";function le(e,r){let t=e.getAttribute("data-reactive-show-equals");if(t!==null)return r===t;let o=e.getAttribute("data-reactive-show-not");if(o!==null)return r!==o;let n=e.getAttribute("data-reactive-show-in");if(n!==null){try{let i=JSON.parse(n);if(Array.isArray(i))return i.includes(r)}catch{}return console.warn(`[phlex-reactive] malformed reactive_show in: list ${JSON.stringify(n)} — skipped`),null}for(let i of te){let a=e.getAttribute(`data-reactive-show-${i}`);if(a!==null)return oe(i,a,r)}return console.warn("[phlex-reactive] a reactive_show binding declares no predicate — skipped"),null}function W(e){try{let r=JSON.parse(e);if(r&&typeof r==="object"&&!Array.isArray(r))return r}catch{}return console.warn(`[phlex-reactive] malformed compound reactive_show payload ${JSON.stringify(e)} — skipped`),null}function ue(e){try{let r=JSON.parse(e);if(Array.isArray(r)&&r.every((t)=>t&&typeof t==="object"&&Array.isArray(t.any)&&Array.isArray(t.ops)))return r}catch{}return console.warn(`[phlex-reactive] malformed reactive_on_complete payload ${JSON.stringify(e)} — skipped`),[]}function G(e,r){if(!e||typeof e!=="object")return null;let t=e.any;if(Array.isArray(t)&&(t.length===0||Array.isArray(t[0])))return b(t,r);return fe(e,r)}function fe(e,r){let t=Array.isArray(e.all)?"all":Array.isArray(e.any)?"any":null;if(!t)return null;let o=e[t];if(o.length===0)return null;let n=o.map((i)=>j(i,r));return t==="all"?n.every(Boolean):n.some(Boolean)}function w(e,r="show"){if(typeof e==="string"&&ce.test(e))return!0;return console.warn(`[phlex-reactive] refused cross-root ${r} target ${JSON.stringify(e)} — skipped`),!1}function de(e){if(e.root.getAttribute?.("data-reactive-show-targets"))return!0;if(e.root.getAttribute?.("data-reactive-group-targets"))return!0;let r=e.root.querySelectorAll?.(P)??[];for(let t of r)if(e.core.owns(t))return!0;for(let t of e.root.querySelectorAll?.(x)??[])if(e.core.owns(t))return!0;for(let t of e.root.querySelectorAll?.(H)??[])if(e.core.owns(t))return!0;return!1}function pe(e){return!!e.root.getAttribute?.("data-reactive-on-complete")}function ge(e){let r=e.root.getAttribute?.("data-reactive-on-complete")??null;if(r!==e.onCompleteRaw)e.onCompleteRaw=r,e.onCompleteParsed=r==null?[]:ue(r),e.onCompleteStates=e.onCompleteParsed.map(()=>!1);return e.onCompleteParsed}function J(e,r){let t=ge(e);if(!t.length)return;let o=K(e,e.core.ownership());t.forEach((n,i)=>{let a=b(n.any,o);if(a===null)return;let s=a&&!e.onCompleteStates[i]&&Boolean(r);if(e.onCompleteStates[i]=a,s)e.core.applyOps(n.ops,"@root")})}function he(e){if(typeof e.root?.querySelectorAll!=="function")return;let r=e.core.ownership(),t=e.root.getAttribute?.("data-reactive-scope")||null,o=K(e,r);for(let n of e.root.querySelectorAll(P)){if(!r(n))continue;let i=n.getAttribute("data-reactive-show");if(i!==null){let c=G(W(i),o);if(c!==null)T(n,c,r,t);continue}let a=n.getAttribute("data-reactive-show-field");if(!a)continue;let s=o(a);if(s===null)continue;let l=le(n,s);if(l===null)continue;T(n,l,r,t)}if(e.groups)Se(e,o,r,t);be(e,o,r),ye(e,o),xe(e,o)}function T(e,r,t,o){if(e.hidden=!r,e.getAttribute("data-reactive-show-disable")!=="true")return;if(typeof e.querySelectorAll!=="function")return;for(let n of e.querySelectorAll("input[name], select[name], textarea[name]"))if(t(n))n.disabled=!r;if(e.name&&t(e))e.disabled=!r}function ye(e,r){let t=B(e);for(let[o,n]of Object.entries(t)){if(o.startsWith("#")){me(o,n,r);continue}if(!n||typeof n!=="object"||Array.isArray(n))continue;let i=r(o);if(i===null)continue;let a=(s,l)=>l?r(o,!0):i;for(let[s,l]of Object.entries(n)){if(!w(s))continue;let c;if(Array.isArray(l)){if(l.length===0){console.warn(`[phlex-reactive] malformed reactive_show_targets group for ${s} — skipped`);continue}c=l.every((u)=>j(u,a))}else{let u=ie(l,i);if(u===null){console.warn(`[phlex-reactive] malformed reactive_show_targets predicate for ${s} — skipped`);continue}c=u}for(let u of document.querySelectorAll(s))u.hidden=!c}}}function me(e,r,t){if(!w(e))return;let o=r&&typeof r==="object"&&!Array.isArray(r)?r.any:null,n=De(o);if(n===null){console.warn(`[phlex-reactive] malformed reactive_show_targets conditions for ${e} — skipped`);return}if(n.every((a)=>t(a)===null)&&!Ie(o))return;let i=b(o,t);if(i===null)return;for(let a of document.querySelectorAll(e))a.hidden=!i}function B(e,r="show",t="mode: { ... }, kind: { ... }"){let o=e.root.getAttribute?.(`data-reactive-${r}-targets`);if(!o)return{};try{let n=JSON.parse(o);if(n&&typeof n==="object"&&!Array.isArray(n))return n}catch{}return console.warn(`[phlex-reactive] malformed data-reactive-${r}-targets — ignored. `+`Did two reactive_${r}_targets calls collide on one root? Declare every entry in ONE call: reactive_${r}_targets(${t})`),{}}function ve(e,r,t,o){let n=!1,i=null;for(let a of e.root.querySelectorAll(F(r,o))){if(!t(a))continue;if(a.type==="checkbox")return a.checked?"true":"false";if(a.type==="radio"){if(a.checked)return a.value??"";n=!0;continue}i??=a}if(i)return i.value??"";return n?"":null}function F(e,r){return`[name="${r&&!e.includes("[")?`${r}[${e}]`:e}"]`}function K(e,r){let t=e.root.getAttribute?.("data-reactive-scope")||null,o=new Map;return(n,i)=>{let a=i?`#${n}`:n;if(!o.has(a))o.set(a,i?_(e,n,r,t).filter((s)=>s.checked).length:ve(e,n,r,t));return o.get(a)}}var H="[data-reactive-media]";function be(e,r,t){for(let o of e.root.querySelectorAll(H)){if(!t(o))continue;let n,i;try{if(n=JSON.parse(o.getAttribute("data-reactive-media")),n?.match!=null)i=new RegExp(`^(?:${n.match})$`)}catch{}if(typeof n?.field!=="string"||!n.pool||typeof n.pool!=="object"||n.match!=null&&!i){console.warn("[phlex-reactive] malformed data-reactive-media — skipped");continue}let a=r(n.field);if(a===null)continue;let s=n.take>0?[...a]:null,l=s?s.slice(0,n.take).join(""):a,c=s?.length<n.take||i?.test(l)===!1;if(c&&n.pending==="keep"){M(o,"pending");continue}let u=!c&&Object.hasOwn(n.pool,l)?L(e,n.pool[l])[0]:null,f=e.core.copyMedia(o,u??null);if(f===null)continue;if(M(o,c?"pending":f===!1?"miss":"hit"),typeof n.label!=="string")continue;let g=c?"":f===!1?String(n.blank??""):f;for(let A of L(e,n.label))if(A.textContent!==g)A.textContent=g}}function M(e,r){if(e.getAttribute("data-reactive-media-state")!==r)e.setAttribute("data-reactive-media-state",r)}function L(e,r){try{return r==="@root"?[]:e.core.opTargets({to:r})}catch{return[]}}var x="[data-reactive-enable], [data-reactive-select-all], [data-reactive-count]";function Ae(e){return!!e.root.querySelector?.(x)}function _(e,r,t,o){return[...e.root.querySelectorAll(F(r,o))].filter((n)=>n.type==="checkbox"&&t(n))}function we(e,r){let t=r?.getAttribute?.("data-reactive-select-all");if(t&&e.core.owns(r))z(e,t,r.checked,r)}function Ue(e,r,t){if(!r)return;let o=q.get(e)??{root:e,core:{ownership:()=>(n)=>n.closest('[data-controller~="reactive"]')===e}};z(o,r,t!==!1),o.show?.()}function z(e,r,t,o){let n=e.root.getAttribute?.("data-reactive-scope")||null,i=_(e,r,e.core.ownership(),n).filter((a)=>a!==o&&a.checked!==t);for(let a of i)a.checked=t;e.flipping=!0;try{for(let a of i)for(let s of["input","change"])a.dispatchEvent?.(new Event(s,{bubbles:!0}))}finally{e.flipping=!1}}function Se(e,r,t,o){for(let n of e.root.querySelectorAll(x)){if(!t(n))continue;let i=n.getAttribute("data-reactive-enable");if(i!==null){let l=G(W(i),r);if(l!==null)n.disabled=!l}let a=n.getAttribute("data-reactive-count");if(a){let l=String(r(a,!0));if(n.textContent!==l)n.textContent=l}let s=n.getAttribute("data-reactive-select-all");if(s){let l=_(e,s,t,o).filter((u)=>u!==n),c=l.filter((u)=>u.checked).length;n.checked=c>0&&c===l.length,n.indeterminate=c>0&&c<l.length}}}function xe(e,r){for(let[t,o]of Object.entries(B(e,"group",'"ids[]" => { ... }, "tags[]" => { ... }'))){if(!o||typeof o!=="object"||Array.isArray(o))continue;let n=String(r(t,!0));for(let a of Array.isArray(o.count)?o.count:[]){if(!w(a,"group"))continue;for(let s of document.querySelectorAll(a))if(s.textContent!==n)s.textContent=n}let i=o.enable&&typeof o.enable==="object"?o.enable:{};for(let[a,s]of Object.entries(i)){if(!w(a,"group"))continue;let l=b(s?.any,r);if(l===null){console.warn(`[phlex-reactive] malformed reactive_group_targets enable for ${a} — skipped`);continue}for(let c of document.querySelectorAll(a))c.disabled=!l}}}function D(e){if(e.groupObserver||typeof MutationObserver!=="function")return;let r=(n)=>e.root.getAttribute?.(`data-reactive-${n}`)?.includes("checked_");if(!e.root.getAttribute?.("data-reactive-group-targets")&&!e.root.querySelector?.(`${x}, [data-reactive-show*=checked_]`)&&!r("show-targets")&&!r("on-complete"))return;let o=(n)=>n.nodeType===1&&(n.matches('input[type="checkbox"]')||!!n.querySelector('input[type="checkbox"]'));e.groupObserver=new MutationObserver((n)=>{if(!n.some((i)=>[...i.addedNodes,...i.removedNodes].some(o)))return;e.show?.(),e.arm?.()}),e.groupObserver.observe(e.root,{childList:!0,subtree:!0})}function S(e){return!!(e.root.getAttribute?.("data-reactive-filter-input")&&e.root.getAttribute?.("data-reactive-filter-option"))}function Ce(e,r){let t=e.root.getAttribute("data-reactive-filter-input");return!!t&&typeof r.target?.matches==="function"&&r.target.matches(t)}function v(e){if(typeof e.root?.querySelectorAll!=="function")return;let r=e.root.getAttribute("data-reactive-filter-input"),t=e.root.getAttribute("data-reactive-filter-option");if(!r||!t)return;let o=e.core.ownership(),n=[...e.root.querySelectorAll(r)].find(o);if(!n)return;let i=(n.value??"").trim().toLowerCase(),a=0;for(let c of e.root.querySelectorAll(t)){if(!o(c))continue;let u=(c.getAttribute("data-reactive-filter-text")??c.textContent??"").toLowerCase(),f=c.hasAttribute?.("data-reactive-tags-selected")||i!==""&&!u.includes(i);if(c.hidden=f,f)c.removeAttribute("data-reactive-highlighted");else a++}let s=e.root.getAttribute("data-reactive-filter-group");if(s)for(let c of e.root.querySelectorAll(s)){if(!o(c))continue;let u=[...c.querySelectorAll(t)].filter(o);if(u.length===0)continue;c.hidden=u.every((f)=>f.hidden)}let l=e.root.getAttribute("data-reactive-filter-empty");if(l){for(let c of e.root.querySelectorAll(l))if(o(c))c.hidden=a>0}}function C(e){return!!e.root.getAttribute?.("data-reactive-tags-field")}function ke(e){if(typeof e.root?.querySelector!=="function")return!1;return!!e.root.querySelector("[data-reactive-nested-json]")}function N(e){if(typeof e.root?.querySelectorAll!=="function")return null;let r=e.root.getAttribute("data-reactive-tags-field");if(!r)return null;let t=e.core.ownership();return[...e.root.querySelectorAll(r)].find(t)??null}function O(e){let r=new Set,t=[];for(let o of String(e.value??"").split(",")){let n=o.trim();if(n===""||r.has(n.toLowerCase()))continue;r.add(n.toLowerCase()),t.push(n)}return t}function Y(e,r){let t=N(e);if(!t)return!1;let o=O(t),n=new Set(o.map((a)=>a.toLowerCase())),i=!1;for(let a of r){let s=String(a??"").trim();if(s===""||n.has(s.toLowerCase()))continue;n.add(s.toLowerCase()),o.push(s),i=!0}if(i)U(e,t,o);return i}function U(e,r,t){r.value=t.join(","),y(r),Q(e)}function qe(e){if(typeof e.root?.querySelectorAll!=="function")return null;let r=e.root.getAttribute("data-reactive-filter-input");if(!r)return null;let t=e.core.ownership();return[...e.root.querySelectorAll(r)].find(t)??null}function Q(e){let r=N(e);if(!r)return;let t=O(r),o=e.core.ownership();_e(e,t,o),Ne(e,t,o)}function _e(e,r,t){let o=[...e.root.querySelectorAll("[data-reactive-tags-list]")].find(t);if(!o)return;let i=[...e.root.querySelectorAll("[data-reactive-tags-template]")].find(t)?.content?.firstElementChild;if(!i){if(!e.tagsWarnedTemplate)console.warn("[phlex-reactive] reactive_tags: no chip <template data-reactive-tags-template> found in this root — "+"chips will not render (the hidden field still updates). Add a template with a [data-reactive-tag-text] node and a reactive_tags_remove button."),e.tagsWarnedTemplate=!0;return}while(o.firstChild)o.removeChild(o.firstChild);for(let a of r){let s=i.cloneNode(!0);s.setAttribute?.("data-reactive-tag",a);let l=s.matches?.("[data-reactive-tag-text]")?s:(s.querySelectorAll?.("[data-reactive-tag-text]")??[])[0];if(l)l.textContent=a;let c=[...s.querySelectorAll?.('[data-action*="reactive#tagsRemove"]')??[]];if(s.matches?.('[data-action*="reactive#tagsRemove"]'))c.push(s);for(let u of c)u.setAttribute?.("data-reactive-tag-param",a);o.appendChild(s)}}function Ne(e,r,t){let o=new Set(r.map((n)=>n.toLowerCase()));for(let n of e.root.querySelectorAll("[role=option]")){if(!t(n))continue;let i=n.getAttribute?.("data-reactive-tag-param");if(!i)continue;if(o.has(i.toLowerCase()))n.setAttribute("data-reactive-tags-selected","true"),n.hidden=!0,n.removeAttribute?.("data-reactive-highlighted");else if(n.hasAttribute?.("data-reactive-tags-selected")){if(n.removeAttribute("data-reactive-tags-selected"),!S(e))n.hidden=!1}}if(S(e))v(e)}function Oe(e){return e.nestedIndex=Math.max(e.nestedIndex+1,Date.now()),e.nestedIndex}function Ee(e,r){let t=[e,...e.querySelectorAll?.("*")??[]];for(let o of t)for(let n of["name","id","for"]){let i=o.getAttribute?.(n);if(i&&i.includes("NEW_ROW"))o.setAttribute?.(n,i.replaceAll("NEW_ROW",String(r)))}}function $e(e,r){if(e.nestedWarned)return;console.warn(`[phlex-reactive] nested rows: no owned [data-reactive-nested-list="${r}"] container + <template data-reactive-nested-template="${r}"> pair found in this root — the add `+"trigger did nothing. Render both inside the same reactive root (reactive_nested_list / reactive_nested_template)."),e.nestedWarned=!0}function je(e,r,t,o){if(!t)return null;let n;try{n=JSON.parse(t)}catch{return null}if(!n||typeof n!=="object")return null;let i=e.core.ownership(),a=[...r.querySelectorAll?.("input, select, textarea")??[]],s=[];for(let[l,c]of Object.entries(n)){let u=[...e.root.querySelectorAll?.(c)??[]].find(i);if(!u)continue;let f=a.find((g)=>V(g.getAttribute?.("name"))===l);if(!f)continue;Re(f,u),s.push(u)}if(o)for(let l of s)Je(l);return s[0]??null}function Re(e,r){if(e.type==="checkbox")e.checked=r.type==="checkbox"?!!r.checked:k(r)!=="";else e.value=k(r);y(e)}function Je(e){if(e.type==="checkbox")e.checked=!1;else e.value="";y(e)}function Te(e,r){if(!e.includes("%{"))return e;return e.replace(/%\{(\w+)\}/g,(t,o)=>Object.prototype.hasOwnProperty.call(r,o)?r[o]:t)}function I(e,r){let t=[...r.querySelectorAll?.('input[name$="[_destroy]"]')??[]][0];if(t)t.value="1",y(t),r.hidden=!0;else r.parentNode?.removeChild?.(r);E(e)}function E(e){if(typeof e.root?.querySelectorAll!=="function")return;let r=e.core.ownership();for(let t of[...e.root.querySelectorAll("[data-reactive-nested-json]")].filter(r))X(e,t.getAttribute("data-reactive-nested-json"))}function Me(e,r){let t=r.getAttribute?.("data-reactive-nested-json-field");if(!t)return null;let o=e.core.ownership();return[...e.root.querySelectorAll(t)].find(o)??null}function Z(e,r){let t={},o=e.core.ownership();for(let n of[...r.querySelectorAll?.("input, select, textarea")??[]]){if(n.matches(":disabled")||n.type==="radio"&&!n.checked||!o(n))continue;let i=V(n.getAttribute?.("name"));if(i===null||i==="_destroy")continue;t[i]=k(n)}return t}function V(e){if(!e)return null;let r=e.match(/\[([^\][]+)\]$/);return r?r[1]:e}function k(e){if(e.type==="checkbox")return e.checked?e.value||"on":"";return e.value??""}function X(e,r){let t=e.core.ownership(),o=[...e.root.querySelectorAll(`[data-reactive-nested-list="${r}"]`)].find(t);if(!o)return;let n=Me(e,o);if(!n)return;let i=[];for(let s of[...o.querySelectorAll?.("[data-reactive-nested-row]")??[]]){if(!t(s)||s.hidden)continue;i.push(Z(e,s))}let a=JSON.stringify(i);if(n.value===a)return;n.value=a,y(n)}function Qe(e,r,t){let o=p(e,r);if(!C(o))return;if(t?.defaultPrevented)return;if(o.core.listnavOptions(t).some((a)=>a.hasAttribute?.("data-reactive-highlighted")))return;t?.preventDefault?.();let n=t?.currentTarget??t?.target;if(!n)return;if(!Y(o,String(n.value??"").split(",")))return;if(n.value="",S(o))v(o)}function Ze(e,r,t){let o=p(e,r);if(!C(o))return;t?.preventDefault?.();let i=(t?.currentTarget??t?.target)?.getAttribute?.("data-reactive-tag-param");if(!i)return;if(!Y(o,[i]))return;let a=qe(o);if(!a)return;a.value="",v(o),a.focus?.()}function Ve(e,r,t){let o=p(e,r);if(!C(o))return;t?.preventDefault?.();let i=(t?.currentTarget??t?.target)?.getAttribute?.("data-reactive-tag-param");if(!i)return;let a=N(o);if(!a)return;let s=O(a),l=s.filter((c)=>c.toLowerCase()!==i.toLowerCase());if(l.length===s.length)return;U(o,a,l)}function Xe(e,r,t){let o=p(e,r);t?.preventDefault?.();let n=t?.currentTarget??t?.target,i=n?.getAttribute?.("data-reactive-association-param");if(!i)return;if(typeof o.root?.querySelectorAll!=="function")return;let a=o.core.ownership(),s=[...o.root.querySelectorAll(`[data-reactive-nested-list="${i}"]`)].find(a),c=[...o.root.querySelectorAll(`[data-reactive-nested-template="${i}"]`)].find(a)?.content?.firstElementChild;if(!s||!c){$e(o,i);return}let u=c.cloneNode(!0);Ee(u,Oe(o)),s.appendChild(u);let f=n?.getAttribute?.("data-reactive-nested-from-param"),g=n?.getAttribute?.("data-reactive-nested-clear-param")==="true",A=je(o,u,f,g);if(f)A?.focus?.();else[...u.querySelectorAll?.("input, select, textarea")??[]][0]?.focus?.();if(s.getAttribute?.("data-reactive-nested-json")===i)X(o,i)}function et(e,r,t){let o=p(e,r);t?.preventDefault?.();let n=t?.currentTarget??t?.target,i=n?.closest?.("[data-reactive-nested-row]");if(!i)return;if(i.closest?.('[data-controller~="reactive"]')!==o.root)return;let a=n?.getAttribute?.("data-reactive-confirm-param"),s=n?.getAttribute?.("data-reactive-confirm-when-param"),l=a||(s?ae(o,s):null);if(!l)return I(o,i);let c=Z(o,i),u=Te(l,c);return o.core.confirm(u,{el:n,row:i,fields:c}).then((f)=>{if(f)I(o,i)})}function ee(e,r){let t=r?.target;if(!t||!e.core.owns(t))return;E(e)}var te=["gte","gt","lte","lt"],Le=["len_eq","len_gte","len_gt","len_lte","len_lt"],re=["checked_eq","checked_gte","checked_gt","checked_lte","checked_lt"];function ne(e,r,t){if(!Number.isInteger(r))return console.warn(`[phlex-reactive] reactive_show ${e}: needs an integer literal, got ${JSON.stringify(r)} — skipped`),null;switch(e.slice(e.indexOf("_")+1)){case"eq":return t===r;case"gte":return t>=r;case"gt":return t>r;case"lte":return t<=r;case"lt":return t<r;default:return null}}function oe(e,r,t){let o=Number(r);if(Number.isNaN(o))return console.warn(`[phlex-reactive] reactive_show ${e}: needs a numeric literal, got ${JSON.stringify(r)} — skipped`),null;let n=t==null?"":String(t).trim(),i=n===""?NaN:Number(n);if(Number.isNaN(i))return!1;switch(e){case"gte":return i>=o;case"gt":return i>o;case"lte":return i<=o;case"lt":return i<o;default:return null}}function ie(e,r){if(!e||typeof e!=="object")return null;if(typeof e.equals==="string")return r===e.equals;if(typeof e.not==="string")return r!==e.not;if(Array.isArray(e.in))return e.in.includes(r);for(let t of te)if(t in e)return oe(t,e[t],r);for(let t of Le)if(t in e)return ne(t,e[t],[...String(r??"")].length);return null}function j(e,r){if(!e||typeof e!=="object"||typeof e.field!=="string")return!1;let t=re.find((n)=>(n in e));if(t){let n=r(e.field,!0);return ne(t,e[t],Array.isArray(n)?n.length:Number(n)||0)===!0}let o=r(e.field)??"";return ie(e,o)===!0}function b(e,r){if(!Array.isArray(e)||e.length===0)return null;return e.some((t)=>Array.isArray(t)&&t.length>0&&t.every((o)=>j(o,r)))}function De(e){if(!Array.isArray(e)||e.length===0)return null;let r=new Set;for(let t of e){if(!Array.isArray(t))continue;for(let o of t)if(o&&typeof o==="object"&&typeof o.field==="string")r.add(o.field)}return r.size>0?[...r]:null}function Ie(e){return e.flat().every((r)=>re.some((t)=>(t in Object(r))))}function ae(e,r){let t=r;if(typeof r==="string")try{t=JSON.parse(r)}catch{return console.warn(`[phlex-reactive] malformed conditional confirm payload ${JSON.stringify(r)} — skipped`),null}if(!t||typeof t!=="object")return null;let{fields:o}=e.core.collectFields(),n=(a)=>o[a],i;if(typeof t.predicate==="string"){let a=se(t.predicate);if(!a)return console.warn(`[phlex-reactive] confirm predicate "${t.predicate}" is not registered — proceeding without a dialog (register it with setConfirmPredicate)`),null;i=!!a(o)}else i=b(t.groups?.any,n)===!0;return i?t.message:null}function R(e,r){let t=r.target?.closest?.("[data-reactive-editable]");return t&&e.core.owns(t)?t:null}function Pe(e,r){let t=R(e,r);if(!t||r.isComposing||r.keyCode===229)return;if(r.key==="Enter"){let o=t.getAttribute("data-reactive-editable-enter");if(t.getAttribute("data-reactive-editable")==="multi"&&(o==null||r.shiftKey))return;if(r.preventDefault(),o==="submit")t.closest("form")?.requestSubmit();else if(o)e.core.applyOps(JSON.parse(o),"@root")}else if(r.key==="Escape"&&t.hasAttribute("data-reactive-editable-escape"))r.preventDefault(),t.textContent=e.core.served(t),y(t),t.blur()}function We(e,r){let t=R(e,r),o=t?.getAttribute("data-reactive-editable")!=="multi",n=(r.clipboardData??r.dataTransfer)?.getData("text/plain");if(!t||n==null||e.core.plain()&&!(o&&/[\r\n]/.test(n)))return;if(r.preventDefault(),o)n=n.replace(/\r?\n|\r/g," ");t.focus(),document.execCommand("insertText",!1,n)}function Ge(e,r){let t=R(e,r);if(t?.firstChild&&e.core.text(t)==="")t.replaceChildren()}export{Ue as checkGroup,Ye as confirmMessage,Fe as connect,Ke as disconnect,Xe as nestedAdd,et as nestedRemove,He as reseed,ze as syncNestedJson,Qe as tagsAdd,Ze as tagsPick,Ve as tagsRemove};
2
2
 
3
- //# debugId=099864F98B8480EC64756E2164756E21
3
+ //# debugId=37913BD89CC3850E64756E2164756E21
4
4
  //# sourceMappingURL=bindings.min.js.map