phlex-reactive 0.16.12 → 0.16.13

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.
@@ -1341,9 +1341,9 @@ function warnNestedOnce(c, assoc) {
1341
1341
  // two features can't drift). Sources resolve root-scoped and owned (#15); an
1342
1342
  // unresolved source or an unmatched key is silently skipped (the row still
1343
1343
  // adds — a half-mapped binding must never throw on click). Returns the FIRST
1344
- // source control read (for focus), or null. With `clear`, resets every source
1345
- // it read via the set-value + dispatch contract (#183) so dirty/show/compute
1346
- // observe the reset.
1344
+ // source control read (for focus), or null. With a `clear` mode ("true" or
1345
+ // "reset", #466), resets every source it read via the set-value + dispatch
1346
+ // contract (#183) so dirty/show/compute observe the reset.
1347
1347
  function seedNestedRow(c, row, fromJson, clear) {
1348
1348
  if (!fromJson) return null
1349
1349
  let map
@@ -1363,9 +1363,10 @@ function seedNestedRow(c, row, fromJson, clear) {
1363
1363
  const target = rowFields.find((field) => nestedJsonKey(field.getAttribute?.("name")) === key)
1364
1364
  if (!target) continue
1365
1365
  seedNestedField(target, source)
1366
- sources.push(source)
1366
+ // One source can feed several row fields: clear it (and dispatch) once.
1367
+ if (!sources.includes(source)) sources.push(source)
1367
1368
  }
1368
- if (clear) for (const source of sources) clearNestedSource(source)
1369
+ if (clear) for (const source of sources) clearNestedSource(source, clear)
1369
1370
  return sources[0] ?? null
1370
1371
  }
1371
1372
 
@@ -1385,9 +1386,25 @@ function seedNestedField(target, source) {
1385
1386
 
1386
1387
  // Reset a source control after a fill-then-add (issue #208), dispatching a
1387
1388
  // bubbling `input` so dirty tracking / reactive_show / compute see the reset.
1388
- function clearNestedSource(source) {
1389
- if (source.type === "checkbox") source.checked = false
1390
- else source.value = ""
1389
+ // "true" empties it; "reset" (issue #466) puts it back to its server-rendered
1390
+ // default, the way a form reset would: a checkbox (or that one radio — the
1391
+ // selector names an element, not its group) to defaultChecked, a select to its reset option(s), anything else to defaultValue. A one-row
1392
+ // single select resets to its last defaultSelected option or, with none, its
1393
+ // first enabled one; a multiple (or size > 1) select to exactly its
1394
+ // defaultSelected options — the rule dirty tracking diffs against (form.js
1395
+ // fieldDirty, issue #297), so a reset source reads clean.
1396
+ function clearNestedSource(source, mode) {
1397
+ const reset = mode === "reset"
1398
+ if (source.type === "checkbox" || (reset && source.type === "radio")) {
1399
+ source.checked = reset && !!source.defaultChecked
1400
+ } else if (reset && source.options) {
1401
+ const options = Array.from(source.options)
1402
+ const single = !source.multiple && !(source.size > 1)
1403
+ const pick = options.filter((o) => o.defaultSelected).pop() ?? options.find((o) => !o.closest?.("optgroup")?.disabled && !o.disabled)
1404
+ for (const o of options) o.selected = single ? o === pick : !!o.defaultSelected
1405
+ } else {
1406
+ source.value = reset ? (source.defaultValue ?? "") : ""
1407
+ }
1391
1408
  fireInput(source)
1392
1409
  }
1393
1410
 
@@ -1623,7 +1640,8 @@ export function nestedAdd(controller, core, event) {
1623
1640
  // reads. `seeded` is the FIRST source we cleared/read, so fill-then-add can
1624
1641
  // return focus to the sources instead of stealing it into the new row.
1625
1642
  const fromJson = trigger?.getAttribute?.("data-reactive-nested-from-param")
1626
- const clear = trigger?.getAttribute?.("data-reactive-nested-clear-param") === "true"
1643
+ const clearParam = trigger?.getAttribute?.("data-reactive-nested-clear-param")
1644
+ const clear = clearParam === "true" || clearParam === "reset" ? clearParam : null
1627
1645
  const firstSource = seedNestedRow(c, row, fromJson, clear)
1628
1646
 
1629
1647
  // Focus: inline-edit (no from:) focuses the new row's first field so you
@@ -1,4 +1,4 @@
1
- import{confirmPredicate as de}from"phlex/reactive/confirm_predicate";var m=new WeakMap,k=new WeakMap;function y(e,r){let t=m.get(e);if(!t){if(m.set(e,t={root:e.element,core:r,nestedIndex:0}),t.root)k.set(t.root,t)}return t}function h(e,r,t){for(let n of r.split(" "))e.root.addEventListener?.(n,t),e.offs.push(()=>e.root.removeEventListener?.(n,t))}function b(e,r){h(e,"turbo:morph-element",r),e.seeds.push(r),r()}function st(e,r){let t=y(e,r);t.offs=[],t.seeds=[];let n,o,i,s,a;(t.wire=()=>{if(!t.show&&me(t))t.show=(c)=>{if(t.flipping)return;if(c?.type==="input"||c?.type==="change")je(t,c.target);else t.groups=$e(t),F(t);W(t)},h(t,"input change",t.show),h(t,"focusout",(c)=>{let l=c.target?.getAttribute?.("name");if(!l||t.touched?.has(l)||!t.core.bindingOwns(c.target))return;if((t.touched??=new Set).add(l),t.root.querySelector?.("[data-reactive-show-after]"))W(t)}),b(t,t.show);if(!t.arm&&be(t))h(t,"input change",(c)=>D(t,c)),b(t,t.arm=()=>{D(t,null),F(t)});if(!n&&(n=t.show||t.arm))h(t,"reset",()=>setTimeout(()=>{if(m.get(e)!==t)return;t.show?.(),t.arm?.()},0));if(!o&&(o=t.show||t.arm))h(t,"reactive:connect reactive:persist-restored",(c)=>{if(c.target===t.root||!pe(t,c.target))return;t.show?.(),t.arm?.()});if(!i&&(i=x(t)))h(t,"input",(c)=>Je(t,c)&&A(t)),b(t,()=>A(t));if(!s&&(s=O(t)))b(t,()=>te(t));if(!a&&(a=We(t)))h(t,"input change",(c)=>ie(t,c)),b(t,()=>T(t))})(),h(t,"keydown",(c)=>tt(t,c)),h(t,"paste drop",(c)=>rt(t,c)),h(t,"input",(c)=>nt(t,c))}function pe(e,r){return[...r.querySelectorAll?.("[data-reactive-shared-field]")??[]].some(e.core.bindingOwns)}function at(e){let r=m.get(e);if(!r)return;m.delete(e),k.delete(r.root);for(let t of r.offs??[])t();r.groupObserver?.disconnect()}function ct(e){let r=m.get(e);if(!r)return;for(let t of r.seeds)t();r.wire()}function v(e){if(typeof e.dispatchEvent==="function")e.dispatchEvent(new Event("input",{bubbles:!0}))}function lt(e,r,t){return ie(y(e,r),t)}function ut(e,r,t){return ue(y(e,r),t)}var ge=/^#[A-Za-z_][\w-]*$/,K="[data-reactive-show-field], [data-reactive-show]";function he(e,r){let t=e.getAttribute("data-reactive-show-equals");if(t!==null)return r===t;let n=e.getAttribute("data-reactive-show-not");if(n!==null)return r!==n;let o=e.getAttribute("data-reactive-show-in");if(o!==null){try{let i=JSON.parse(o);if(Array.isArray(i))return i.includes(r)}catch{}return console.warn(`[phlex-reactive] malformed reactive_show in: list ${JSON.stringify(o)} — skipped`),null}for(let i of se){let s=e.getAttribute(`data-reactive-show-${i}`);if(s!==null)return ce(i,s,r)}return console.warn("[phlex-reactive] a reactive_show binding declares no predicate — skipped"),null}function H(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 ye(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 V(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 w(t,r);return ve(e,r)}function ve(e,r){let t=Array.isArray(e.all)?"all":Array.isArray(e.any)?"any":null;if(!t)return null;let n=e[t];if(n.length===0)return null;let o=n.map((i)=>J(i,r));return t==="all"?o.every(Boolean):o.some(Boolean)}function S(e,r="show"){if(typeof e==="string"&&ge.test(e))return!0;return console.warn(`[phlex-reactive] refused cross-root ${r} target ${JSON.stringify(e)} — skipped`),!1}function me(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?.(K)??[];for(let t of r)if(e.core.owns(t))return!0;for(let t of e.root.querySelectorAll?.(_)??[])if(e.core.owns(t))return!0;for(let t of e.root.querySelectorAll?.(`${U}, ${Z}`)??[])if(e.core.owns(t))return!0;return e.root.hasAttribute?.("data-reactive-css-vars")??!1}function be(e){return!!e.root.getAttribute?.("data-reactive-on-complete")}function Ae(e){let r=e.root.getAttribute?.("data-reactive-on-complete")??null;if(r!==e.onCompleteRaw)e.onCompleteRaw=r,e.onCompleteParsed=r==null?[]:ye(r),e.onCompleteStates=e.onCompleteParsed.map(()=>!1);return e.onCompleteParsed}function D(e,r){let t=Ae(e);if(!t.length)return;let n=Y(e,e.core.bindingOwnership());t.forEach((o,i)=>{let s=w(o.any,n);if(s===null)return;let a=s&&!e.onCompleteStates[i]&&Boolean(r);if(e.onCompleteStates[i]=s,a)e.core.applyOps(o.ops,"@root")})}function W(e){if(typeof e.root?.querySelectorAll!=="function")return;let r=e.core.ownership(),t=e.core.bindingOwnership(),n=e.root.getAttribute?.("data-reactive-scope")||null,o=Y(e,t),i=[];for(let s of e.root.querySelectorAll(K)){if(!r(s))continue;let a=s.getAttribute("data-reactive-show");if(a!==null){let d=V(H(a),o);if(d===null)continue;let f=s.getAttribute("data-reactive-show-after"),p=d&&(f==null||!!e.touched?.has(E(f,n)));L(s,p,t);let g=(e.shown??=new WeakMap).get(s);if(e.shown.set(s,p),we.some((fe)=>s.hasAttribute(`data-reactive-show-${fe}`))&&g!==void 0&&g!==p)i.push(s);continue}let c=s.getAttribute("data-reactive-show-field");if(!c)continue;let l=o(c);if(l===null)continue;let u=he(s,l);if(u===null)continue;L(s,u,t)}if(e.groups)Me(e,o,r,n);Ne(e,o,r),qe(e,o,r,n,t),xe(e,o),Te(e,o);for(let s of i)Se(e,s,t,n)}var we=["clear","focus","scroll"];function Se(e,r,t,n){if(r.hidden){let a=[];try{a=JSON.parse(r.getAttribute("data-reactive-show-clear")??"[]")}catch{}let c=new Set((Array.isArray(a)?a:[]).map((l)=>E(String(l),n)));for(let l of c.size?e.root.querySelectorAll("[name]"):[]){if(!c.has(l.getAttribute("name"))||!t(l)||l.type==="file")continue;if(l.type==="checkbox"||l.type==="radio"){if(l.checked)l.checked=!1,v(l)}else e.core.setValue(l,"")}return}let o=r.getAttribute("data-reactive-show-scroll")==="true";if(o)r.scrollIntoView?.({block:"nearest"});let i=r.getAttribute("data-reactive-show-focus"),s=null;try{s=i?e.root.querySelector(i):null}catch{}s?.focus?.(o?{preventScroll:!0}:void 0)}function L(e,r,t){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 xe(e,r){let t=z(e);for(let[n,o]of Object.entries(t)){if(n.startsWith("#")){_e(n,o,r);continue}if(!o||typeof o!=="object"||Array.isArray(o))continue;let i=r(n);if(i===null)continue;let s=(a,c)=>c?r(n,!0):i;for(let[a,c]of Object.entries(o)){if(!S(a))continue;let l;if(Array.isArray(c)){if(c.length===0){console.warn(`[phlex-reactive] malformed reactive_show_targets group for ${a} — skipped`);continue}l=c.every((u)=>J(u,s))}else{let u=le(c,i);if(u===null){console.warn(`[phlex-reactive] malformed reactive_show_targets predicate for ${a} — skipped`);continue}l=u}for(let u of document.querySelectorAll(a))u.hidden=!l}}}function _e(e,r,t){if(!S(e))return;let n=r&&typeof r==="object"&&!Array.isArray(r)?r.any:null,o=Xe(n);if(o===null){console.warn(`[phlex-reactive] malformed reactive_show_targets conditions for ${e} — skipped`);return}if(o.every((s)=>t(s)===null)&&!et(n))return;let i=w(n,t);if(i===null)return;for(let s of document.querySelectorAll(e))s.hidden=!i}function z(e,r="show",t="mode: { ... }, kind: { ... }"){let n=e.root.getAttribute?.(`data-reactive-${r}-targets`);if(!n)return{};try{let o=JSON.parse(n);if(o&&typeof o==="object"&&!Array.isArray(o))return o}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 Oe(e,r,t,n){let o=!1,i=null;for(let s of e.root.querySelectorAll(q(r,n))){if(!t(s))continue;if(s.type==="checkbox")return s.checked?"true":"false";if(s.type==="radio"){if(s.checked)return s.value??"";o=!0;continue}i??=s}if(i)return i.value??"";return o?"":null}function q(e,r){return`[name="${E(e,r)}"]`}function E(e,r){return r&&!e.includes("[")?`${r}[${e}]`:e}function Y(e,r){let t=e.root.getAttribute?.("data-reactive-scope")||null,n=new Map;return(o,i)=>{let s=i?`#${o}`:o;if(!n.has(s))n.set(s,i?R(e,o,r,t).filter((a)=>a.checked).length:Oe(e,o,r,t));return n.get(s)}}var U="[data-reactive-media]";function Ne(e,r,t){for(let n of e.root.querySelectorAll(U)){if(!t(n))continue;let o,i,s;try{if(o=JSON.parse(n.getAttribute("data-reactive-media")),o?.match!=null)i=new RegExp(`^(?:${o.match})$`);if(o?.when!=null)s=new RegExp(`^(?:${o.when})$`)}catch{}if(typeof o?.field!=="string"||!o.pool||typeof o.pool!=="object"||o.match!=null&&!i||o.when!=null&&!s){console.warn("[phlex-reactive] malformed data-reactive-media — skipped");continue}let a=r(o.field);if(a===null)continue;let c=o.take>0?[...a]:null,l=c?c.slice(0,o.take).join(""):a,u=c?.length<o.take||i?.test(l)===!1||s?.test(a)===!1;if(u&&o.pending==="keep"){P(n,"pending");continue}let d=!u&&Object.hasOwn(o.pool,l)?G(e,o.pool[l])[0]:null,f=e.core.copyMedia(n,d??null);if(f===null)continue;if(P(n,u?"pending":f===!1?"miss":"hit"),typeof o.label!=="string")continue;let p=u?"":f===!1?String(o.blank??""):f;for(let g of G(e,o.label))if(g.textContent!==p)g.textContent=p}}function P(e,r){if(e.getAttribute("data-reactive-media-state")!==r)e.setAttribute("data-reactive-media-state",r)}function G(e,r){try{return r==="@root"?[]:e.core.opTargets({to:r})}catch{return[]}}var Z="[data-reactive-css-vars]",Ce=/^--[a-z0-9-]+$/i,ke=["","px","%","deg","turn","ms","s","em","rem","fr"];function qe(e,r,t,n,o){let i=[...e.root.querySelectorAll(Z)].filter(t);if(e.root.hasAttribute("data-reactive-css-vars"))i.unshift(e.root);for(let s of i){let a;try{a=JSON.parse(s.getAttribute("data-reactive-css-vars"))}catch{}if(!Array.isArray(a?.to)||!a.vars||typeof a.vars!=="object"){console.warn("[phlex-reactive] malformed data-reactive-css-vars — skipped (two reactive_css_vars on one element?)");continue}let c=a.to.flatMap((l)=>{let u={to:l,global:a.global===!0},d=[];try{d=e.core.opTargets(u)}catch{}if(!d.length)e.core.diagnose("reactive_css_vars",u);return d});for(let[l,u]of Object.entries(a.vars)){let d=u?.unit??"";if(!Ce.test(l)||!ke.includes(d)||typeof u?.field!=="string"){console.warn(`[phlex-reactive] refused reactive_css_vars entry ${JSON.stringify(l)} — skipped`);continue}let f=Ee(e,r,u.field,o,n);if(f===void 0)continue;let p=f===null?"":`${f}${d}`;for(let g of c){if(g.style.getPropertyValue(l)===p)continue;if(p)g.style.setProperty(l,p);else g.style.removeProperty(l)}}}}function Ee(e,r,t,n,o){let i=r(t);if(i===null)return;if((i==="true"||i==="false")&&[...e.root.querySelectorAll(q(t,o))].some((a)=>n(a)&&a.type==="checkbox"))return i==="true"?1:0;let s=i.trim()?Number(i):NaN;return Number.isFinite(s)?s:null}var _="[data-reactive-enable], [data-reactive-select-all], [data-reactive-count]";function $e(e){return!!e.root.querySelector?.(_)}function R(e,r,t,n,o){return[...e.root.querySelectorAll(q(r,n))].filter((i)=>i.type==="checkbox"&&t(i)&&(!o||Re(i.getAttribute("data-reactive-group"),o)))}function Re(e,r){return e===r||!!e?.startsWith(`${r}.`)}function je(e,r){let t=r?.getAttribute?.("data-reactive-select-all");if(t&&e.core.owns(r))Q(e,t,r.checked,r,r.getAttribute("data-reactive-select-all-under"))}function ft(e,r,t){if(!r)return;let n=k.get(e)??{root:e,core:{ownership:()=>(o)=>o.closest('[data-controller~="reactive"]')===e}};Q(n,r,t!==!1),n.show?.()}function Q(e,r,t,n,o){let i=e.root.getAttribute?.("data-reactive-scope")||null,s=R(e,r,e.core.ownership(),i,o).filter((a)=>a!==n&&a.checked!==t);for(let a of s)a.checked=t;e.flipping=!0;try{for(let a of s)for(let c of["input","change"])a.dispatchEvent?.(new Event(c,{bubbles:!0}))}finally{e.flipping=!1}}function Me(e,r,t,n){for(let o of e.root.querySelectorAll(_)){if(!t(o))continue;let i=o.getAttribute("data-reactive-enable");if(i!==null){let c=V(H(i),r);if(c!==null)o.disabled=!c}let s=o.getAttribute("data-reactive-count");if(s){let c=String(r(s,!0));if(o.textContent!==c)o.textContent=c}let a=o.getAttribute("data-reactive-select-all");if(a){let c=o.getAttribute("data-reactive-select-all-under"),l=R(e,a,t,n,c).filter((d)=>d!==o),u=l.filter((d)=>d.checked).length;o.checked=u>0&&u===l.length,o.indeterminate=u>0&&u<l.length}}}function Te(e,r){for(let[t,n]of Object.entries(z(e,"group",'"ids[]" => { ... }, "tags[]" => { ... }'))){if(!n||typeof n!=="object"||Array.isArray(n))continue;let o=String(r(t,!0));for(let s of Array.isArray(n.count)?n.count:[]){if(!S(s,"group"))continue;for(let a of document.querySelectorAll(s))if(a.textContent!==o)a.textContent=o}let i=n.enable&&typeof n.enable==="object"?n.enable:{};for(let[s,a]of Object.entries(i)){if(!S(s,"group"))continue;let c=w(a?.any,r);if(c===null){console.warn(`[phlex-reactive] malformed reactive_group_targets enable for ${s} — skipped`);continue}for(let l of document.querySelectorAll(s))l.disabled=!c}}}function F(e){if(e.groupObserver||typeof MutationObserver!=="function")return;let r=(o)=>e.root.getAttribute?.(`data-reactive-${o}`)?.includes("checked_");if(!e.root.getAttribute?.("data-reactive-group-targets")&&!e.root.querySelector?.(`${_}, [data-reactive-show*=checked_]`)&&!r("show-targets")&&!r("on-complete"))return;let n=(o)=>o.nodeType===1&&(o.matches('input[type="checkbox"]')||!!o.querySelector('input[type="checkbox"]'));e.groupObserver=new MutationObserver((o)=>{if(!o.some((i)=>[...i.addedNodes,...i.removedNodes].some(n)))return;e.show?.(),e.arm?.()}),e.groupObserver.observe(e.root,{childList:!0,subtree:!0})}function x(e){return!!(e.root.getAttribute?.("data-reactive-filter-input")&&e.root.getAttribute?.("data-reactive-filter-option"))}function Je(e,r){let t=e.root.getAttribute("data-reactive-filter-input");return!!t&&typeof r.target?.matches==="function"&&r.target.matches(t)}var Ie=/[\s\-'(),./]/;function De(e,r,t){if(e==="prefix")return r.startsWith(t);if(e!=="word_start")return r.includes(t);for(let n=r.indexOf(t);n!==-1;n=r.indexOf(t,n+1))if(n===0||Ie.test(r[n-1]))return!0;return!1}function A(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 n=e.core.ownership(),o=[...e.root.querySelectorAll(r)].find(n);if(!o)return;let i=e.root.getAttribute("data-reactive-filter-match"),s=e.root.hasAttribute?.("data-reactive-filter-fold"),a=(f)=>{let p=(f??"").toLowerCase().trim();return s?p.normalize("NFD").replace(/\p{M}/gu,""):p},c=a(o.value),l=0;for(let f of e.root.querySelectorAll(t)){if(!n(f))continue;let p=f.hasAttribute?.("data-reactive-tags-selected")||c!==""&&!De(i,a(f.getAttribute("data-reactive-filter-text")??f.textContent),c);if(f.hidden=p,p)f.removeAttribute("data-reactive-highlighted");else l++}let u=e.root.getAttribute("data-reactive-filter-group");if(u)for(let f of e.root.querySelectorAll(u)){if(!n(f))continue;let p=[...f.querySelectorAll(t)].filter(n);if(p.length===0)continue;f.hidden=p.every((g)=>g.hidden)}let d=e.root.getAttribute("data-reactive-filter-empty");if(d){for(let f of e.root.querySelectorAll(d))if(n(f))f.hidden=l>0}}function O(e){return!!e.root.getAttribute?.("data-reactive-tags-field")}function We(e){if(typeof e.root?.querySelector!=="function")return!1;return!!e.root.querySelector("[data-reactive-nested-json]")}function j(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 M(e){let r=new Set,t=[];for(let n of String(e.value??"").split(",")){let o=n.trim();if(o===""||r.has(o.toLowerCase()))continue;r.add(o.toLowerCase()),t.push(o)}return t}function X(e,r){let t=j(e);if(!t)return!1;let n=M(t),o=new Set(n.map((s)=>s.toLowerCase())),i=!1;for(let s of r){let a=String(s??"").trim();if(a===""||o.has(a.toLowerCase()))continue;o.add(a.toLowerCase()),n.push(a),i=!0}if(i)ee(e,t,n);return i}function ee(e,r,t){r.value=t.join(","),v(r),te(e)}function Le(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 te(e){let r=j(e);if(!r)return;let t=M(r),n=e.core.ownership();Pe(e,t,n),Ge(e,t,n)}function Pe(e,r,t){let n=[...e.root.querySelectorAll("[data-reactive-tags-list]")].find(t);if(!n)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(n.firstChild)n.removeChild(n.firstChild);for(let s of r){let a=i.cloneNode(!0);a.setAttribute?.("data-reactive-tag",s);let c=a.matches?.("[data-reactive-tag-text]")?a:(a.querySelectorAll?.("[data-reactive-tag-text]")??[])[0];if(c)c.textContent=s;let l=[...a.querySelectorAll?.('[data-action*="reactive#tagsRemove"]')??[]];if(a.matches?.('[data-action*="reactive#tagsRemove"]'))l.push(a);for(let u of l)u.setAttribute?.("data-reactive-tag-param",s);n.appendChild(a)}}function Ge(e,r,t){let n=new Set(r.map((o)=>o.toLowerCase()));for(let o of e.root.querySelectorAll("[role=option]")){if(!t(o))continue;let i=o.getAttribute?.("data-reactive-tag-param");if(!i)continue;if(n.has(i.toLowerCase()))o.setAttribute("data-reactive-tags-selected","true"),o.hidden=!0,o.removeAttribute?.("data-reactive-highlighted");else if(o.hasAttribute?.("data-reactive-tags-selected")){if(o.removeAttribute("data-reactive-tags-selected"),!x(e))o.hidden=!1}}if(x(e))A(e)}function Fe(e){return e.nestedIndex=Math.max(e.nestedIndex+1,Date.now()),e.nestedIndex}function Be(e,r){let t=[e,...e.querySelectorAll?.("*")??[]];for(let n of t)for(let o of["name","id","for"]){let i=n.getAttribute?.(o);if(i&&i.includes("NEW_ROW"))n.setAttribute?.(o,i.replaceAll("NEW_ROW",String(r)))}}function Ke(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 He(e,r,t,n){if(!t)return null;let o;try{o=JSON.parse(t)}catch{return null}if(!o||typeof o!=="object")return null;let i=e.core.ownership(),s=[...r.querySelectorAll?.("input, select, textarea")??[]],a=[];for(let[c,l]of Object.entries(o)){let u=[...e.root.querySelectorAll?.(l)??[]].find(i);if(!u)continue;let d=s.find((f)=>ne(f.getAttribute?.("name"))===c);if(!d)continue;Ve(d,u),a.push(u)}if(n)for(let c of a)ze(c);return a[0]??null}function Ve(e,r){if(e.type==="checkbox")e.checked=r.type==="checkbox"?!!r.checked:N(r)!=="";else e.value=N(r);v(e)}function ze(e){if(e.type==="checkbox")e.checked=!1;else e.value="";v(e)}function Ye(e,r){if(!e.includes("%{"))return e;return e.replace(/%\{(\w+)\}/g,(t,n)=>Object.prototype.hasOwnProperty.call(r,n)?r[n]:t)}function B(e,r){let t=[...r.querySelectorAll?.('input[name$="[_destroy]"]')??[]][0];if(t)t.value="1",v(t),r.hidden=!0;else r.parentNode?.removeChild?.(r);T(e)}function T(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))oe(e,t.getAttribute("data-reactive-nested-json"))}function Ue(e,r){let t=r.getAttribute?.("data-reactive-nested-json-field");if(!t)return null;let n=e.core.ownership();return[...e.root.querySelectorAll(t)].find(n)??null}function re(e,r){let t={},n=e.core.ownership();for(let o of[...r.querySelectorAll?.("input, select, textarea")??[]]){if(o.matches(":disabled")||o.type==="radio"&&!o.checked||!n(o))continue;let i=ne(o.getAttribute?.("name"));if(i===null||i==="_destroy")continue;t[i]=N(o)}return t}function ne(e){if(!e)return null;let r=e.match(/\[([^\][]+)\]$/);return r?r[1]:e}function N(e){if(e.type==="checkbox")return e.checked?e.value||"on":"";return e.value??""}function oe(e,r){let t=e.core.ownership(),n=[...e.root.querySelectorAll(`[data-reactive-nested-list="${r}"]`)].find(t);if(!n)return;let o=Ue(e,n);if(!o)return;let i=[];for(let a of[...n.querySelectorAll?.("[data-reactive-nested-row]")??[]]){if(!t(a)||a.hidden)continue;i.push(re(e,a))}let s=JSON.stringify(i);if(o.value===s)return;o.value=s,v(o)}function dt(e,r,t){let n=y(e,r);if(!O(n))return;if(t?.defaultPrevented)return;if(n.core.listnavOptions(t).some((s)=>s.hasAttribute?.("data-reactive-highlighted")))return;t?.preventDefault?.();let o=t?.currentTarget??t?.target;if(!o)return;if(!X(n,String(o.value??"").split(",")))return;if(o.value="",x(n))A(n)}function pt(e,r,t){let n=y(e,r);if(!O(n))return;t?.preventDefault?.();let i=(t?.currentTarget??t?.target)?.getAttribute?.("data-reactive-tag-param");if(!i)return;if(!X(n,[i]))return;let s=Le(n);if(!s)return;s.value="",A(n),s.focus?.()}function gt(e,r,t){let n=y(e,r);if(!O(n))return;t?.preventDefault?.();let i=(t?.currentTarget??t?.target)?.getAttribute?.("data-reactive-tag-param");if(!i)return;let s=j(n);if(!s)return;let a=M(s),c=a.filter((l)=>l.toLowerCase()!==i.toLowerCase());if(c.length===a.length)return;ee(n,s,c)}function ht(e,r,t){let n=y(e,r);t?.preventDefault?.();let o=t?.currentTarget??t?.target,i=o?.getAttribute?.("data-reactive-association-param");if(!i)return;if(typeof n.root?.querySelectorAll!=="function")return;let s=n.core.ownership(),a=[...n.root.querySelectorAll(`[data-reactive-nested-list="${i}"]`)].find(s),l=[...n.root.querySelectorAll(`[data-reactive-nested-template="${i}"]`)].find(s)?.content?.firstElementChild;if(!a||!l){Ke(n,i);return}let u=l.cloneNode(!0);Be(u,Fe(n)),a.appendChild(u);let d=o?.getAttribute?.("data-reactive-nested-from-param"),f=o?.getAttribute?.("data-reactive-nested-clear-param")==="true",p=He(n,u,d,f);if(d)p?.focus?.();else[...u.querySelectorAll?.("input, select, textarea")??[]][0]?.focus?.();if(a.getAttribute?.("data-reactive-nested-json")===i)oe(n,i)}function yt(e,r,t){let n=y(e,r);t?.preventDefault?.();let o=t?.currentTarget??t?.target,i=o?.closest?.("[data-reactive-nested-row]");if(!i)return;if(i.closest?.('[data-controller~="reactive"]')!==n.root)return;let s=o?.getAttribute?.("data-reactive-confirm-param"),a=o?.getAttribute?.("data-reactive-confirm-when-param"),c=s||(a?ue(n,a):null);if(!c)return B(n,i);let l=re(n,i),u=Ye(c,l);return n.core.confirm(u,{el:o,row:i,fields:l}).then((d)=>{if(d)B(n,i)})}function ie(e,r){let t=r?.target;if(!t||!e.core.owns(t))return;T(e)}var se=["gte","gt","lte","lt"],Ze=["len_eq","len_gte","len_gt","len_lte","len_lt"],ae=["checked_eq","checked_gte","checked_gt","checked_lte","checked_lt"],Qe=["digits_eq","digits_gte","digits_lt","digits_lte"];function C(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 ce(e,r,t){let n=Number(r);if(Number.isNaN(n))return console.warn(`[phlex-reactive] reactive_show ${e}: needs a numeric literal, got ${JSON.stringify(r)} — skipped`),null;let o=t==null?"":String(t).trim(),i=o===""?NaN:Number(o);if(Number.isNaN(i))return!1;switch(e){case"gte":return i>=n;case"gt":return i>n;case"lte":return i<=n;case"lt":return i<n;default:return null}}function le(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 se)if(t in e)return ce(t,e[t],r);for(let t of Ze)if(t in e)return C(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=ae.find((i)=>(i in e));if(t){let i=r(e.field,!0);return C(t,e[t],Array.isArray(i)?i.length:Number(i)||0)===!0}if(typeof e.same==="string"){let i=(s)=>{let a=String(r(s)??"");return e.fold===!0?a.replace(/[A-Z]/g,(c)=>String.fromCharCode(c.charCodeAt(0)+32)):a};return i(e.field)===i(e.same)!==(e.negate===!0)}let n=Qe.filter((i)=>(i in e));if(n.length){let i=String(r(e.field)??"");if(!n.every((a)=>Number.isInteger(e[a]))||e.prefix!=null&&typeof e.prefix!=="string")return!1;return(/^[0-9]*$/.test(i)&&n.every((a)=>C(a,e[a],i.length))&&i.startsWith(e.prefix??""))!==(e.negate===!0)}let o=r(e.field)??"";return le(e,o)===!0}function w(e,r){if(!Array.isArray(e)||e.length===0)return null;return e.some((t)=>Array.isArray(t)&&t.length>0&&t.every((n)=>J(n,r)))}function Xe(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 n of t){if(n&&typeof n==="object"&&typeof n.field==="string")r.add(n.field);if(typeof n?.same==="string")r.add(n.same)}}return r.size>0?[...r]:null}function et(e){return e.flat().every((r)=>ae.some((t)=>(t in Object(r))))}function ue(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:n}=e.core.collectFields(),o=(s)=>n[s],i;if(typeof t.predicate==="string"){let s=de(t.predicate);if(!s)return console.warn(`[phlex-reactive] confirm predicate "${t.predicate}" is not registered — proceeding without a dialog (register it with setConfirmPredicate)`),null;i=!!s(n)}else i=w(t.groups?.any,o)===!0;return i?t.message:null}function I(e,r){let t=r.target?.closest?.("[data-reactive-editable]");return t&&e.core.owns(t)?t:null}function tt(e,r){let t=I(e,r);if(!t||r.isComposing||r.keyCode===229)return;if(r.key==="Enter"){let n=t.getAttribute("data-reactive-editable-enter");if(t.getAttribute("data-reactive-editable")==="multi"&&(n==null||r.shiftKey))return;if(r.preventDefault(),n==="submit")t.closest("form")?.requestSubmit();else if(n)e.core.applyOps(JSON.parse(n),"@root")}else if(r.key==="Escape"&&t.hasAttribute("data-reactive-editable-escape"))r.preventDefault(),t.textContent=e.core.served(t),v(t),t.blur()}function rt(e,r){let t=I(e,r),n=t?.getAttribute("data-reactive-editable")!=="multi",o=(r.clipboardData??r.dataTransfer)?.getData("text/plain");if(!t||o==null||e.core.plain()&&!(n&&/[\r\n]/.test(o)))return;if(r.preventDefault(),n)o=o.replace(/\r?\n|\r/g," ");t.focus(),document.execCommand("insertText",!1,o)}function nt(e,r){let t=I(e,r);if(t?.firstChild&&e.core.text(t)==="")t.replaceChildren()}export{ft as checkGroup,ut as confirmMessage,st as connect,at as disconnect,ht as nestedAdd,yt as nestedRemove,ct as reseed,lt as syncNestedJson,dt as tagsAdd,pt as tagsPick,gt as tagsRemove};
1
+ import{confirmPredicate as de}from"phlex/reactive/confirm_predicate";var m=new WeakMap,k=new WeakMap;function y(e,r){let t=m.get(e);if(!t){if(m.set(e,t={root:e.element,core:r,nestedIndex:0}),t.root)k.set(t.root,t)}return t}function h(e,r,t){for(let n of r.split(" "))e.root.addEventListener?.(n,t),e.offs.push(()=>e.root.removeEventListener?.(n,t))}function b(e,r){h(e,"turbo:morph-element",r),e.seeds.push(r),r()}function st(e,r){let t=y(e,r);t.offs=[],t.seeds=[];let n,o,i,s,a;(t.wire=()=>{if(!t.show&&me(t))t.show=(c)=>{if(t.flipping)return;if(c?.type==="input"||c?.type==="change")je(t,c.target);else t.groups=$e(t),F(t);W(t)},h(t,"input change",t.show),h(t,"focusout",(c)=>{let l=c.target?.getAttribute?.("name");if(!l||t.touched?.has(l)||!t.core.bindingOwns(c.target))return;if((t.touched??=new Set).add(l),t.root.querySelector?.("[data-reactive-show-after]"))W(t)}),b(t,t.show);if(!t.arm&&be(t))h(t,"input change",(c)=>D(t,c)),b(t,t.arm=()=>{D(t,null),F(t)});if(!n&&(n=t.show||t.arm))h(t,"reset",()=>setTimeout(()=>{if(m.get(e)!==t)return;t.show?.(),t.arm?.()},0));if(!o&&(o=t.show||t.arm))h(t,"reactive:connect reactive:persist-restored",(c)=>{if(c.target===t.root||!pe(t,c.target))return;t.show?.(),t.arm?.()});if(!i&&(i=x(t)))h(t,"input",(c)=>Je(t,c)&&A(t)),b(t,()=>A(t));if(!s&&(s=O(t)))b(t,()=>te(t));if(!a&&(a=We(t)))h(t,"input change",(c)=>ie(t,c)),b(t,()=>T(t))})(),h(t,"keydown",(c)=>tt(t,c)),h(t,"paste drop",(c)=>rt(t,c)),h(t,"input",(c)=>nt(t,c))}function pe(e,r){return[...r.querySelectorAll?.("[data-reactive-shared-field]")??[]].some(e.core.bindingOwns)}function at(e){let r=m.get(e);if(!r)return;m.delete(e),k.delete(r.root);for(let t of r.offs??[])t();r.groupObserver?.disconnect()}function ct(e){let r=m.get(e);if(!r)return;for(let t of r.seeds)t();r.wire()}function v(e){if(typeof e.dispatchEvent==="function")e.dispatchEvent(new Event("input",{bubbles:!0}))}function lt(e,r,t){return ie(y(e,r),t)}function ut(e,r,t){return ue(y(e,r),t)}var ge=/^#[A-Za-z_][\w-]*$/,K="[data-reactive-show-field], [data-reactive-show]";function he(e,r){let t=e.getAttribute("data-reactive-show-equals");if(t!==null)return r===t;let n=e.getAttribute("data-reactive-show-not");if(n!==null)return r!==n;let o=e.getAttribute("data-reactive-show-in");if(o!==null){try{let i=JSON.parse(o);if(Array.isArray(i))return i.includes(r)}catch{}return console.warn(`[phlex-reactive] malformed reactive_show in: list ${JSON.stringify(o)} — skipped`),null}for(let i of se){let s=e.getAttribute(`data-reactive-show-${i}`);if(s!==null)return ce(i,s,r)}return console.warn("[phlex-reactive] a reactive_show binding declares no predicate — skipped"),null}function H(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 ye(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 V(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 w(t,r);return ve(e,r)}function ve(e,r){let t=Array.isArray(e.all)?"all":Array.isArray(e.any)?"any":null;if(!t)return null;let n=e[t];if(n.length===0)return null;let o=n.map((i)=>J(i,r));return t==="all"?o.every(Boolean):o.some(Boolean)}function S(e,r="show"){if(typeof e==="string"&&ge.test(e))return!0;return console.warn(`[phlex-reactive] refused cross-root ${r} target ${JSON.stringify(e)} — skipped`),!1}function me(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?.(K)??[];for(let t of r)if(e.core.owns(t))return!0;for(let t of e.root.querySelectorAll?.(_)??[])if(e.core.owns(t))return!0;for(let t of e.root.querySelectorAll?.(`${U}, ${Z}`)??[])if(e.core.owns(t))return!0;return e.root.hasAttribute?.("data-reactive-css-vars")??!1}function be(e){return!!e.root.getAttribute?.("data-reactive-on-complete")}function Ae(e){let r=e.root.getAttribute?.("data-reactive-on-complete")??null;if(r!==e.onCompleteRaw)e.onCompleteRaw=r,e.onCompleteParsed=r==null?[]:ye(r),e.onCompleteStates=e.onCompleteParsed.map(()=>!1);return e.onCompleteParsed}function D(e,r){let t=Ae(e);if(!t.length)return;let n=Y(e,e.core.bindingOwnership());t.forEach((o,i)=>{let s=w(o.any,n);if(s===null)return;let a=s&&!e.onCompleteStates[i]&&Boolean(r);if(e.onCompleteStates[i]=s,a)e.core.applyOps(o.ops,"@root")})}function W(e){if(typeof e.root?.querySelectorAll!=="function")return;let r=e.core.ownership(),t=e.core.bindingOwnership(),n=e.root.getAttribute?.("data-reactive-scope")||null,o=Y(e,t),i=[];for(let s of e.root.querySelectorAll(K)){if(!r(s))continue;let a=s.getAttribute("data-reactive-show");if(a!==null){let d=V(H(a),o);if(d===null)continue;let f=s.getAttribute("data-reactive-show-after"),p=d&&(f==null||!!e.touched?.has(E(f,n)));L(s,p,t);let g=(e.shown??=new WeakMap).get(s);if(e.shown.set(s,p),we.some((fe)=>s.hasAttribute(`data-reactive-show-${fe}`))&&g!==void 0&&g!==p)i.push(s);continue}let c=s.getAttribute("data-reactive-show-field");if(!c)continue;let l=o(c);if(l===null)continue;let u=he(s,l);if(u===null)continue;L(s,u,t)}if(e.groups)Me(e,o,r,n);Ne(e,o,r),qe(e,o,r,n,t),xe(e,o),Te(e,o);for(let s of i)Se(e,s,t,n)}var we=["clear","focus","scroll"];function Se(e,r,t,n){if(r.hidden){let a=[];try{a=JSON.parse(r.getAttribute("data-reactive-show-clear")??"[]")}catch{}let c=new Set((Array.isArray(a)?a:[]).map((l)=>E(String(l),n)));for(let l of c.size?e.root.querySelectorAll("[name]"):[]){if(!c.has(l.getAttribute("name"))||!t(l)||l.type==="file")continue;if(l.type==="checkbox"||l.type==="radio"){if(l.checked)l.checked=!1,v(l)}else e.core.setValue(l,"")}return}let o=r.getAttribute("data-reactive-show-scroll")==="true";if(o)r.scrollIntoView?.({block:"nearest"});let i=r.getAttribute("data-reactive-show-focus"),s=null;try{s=i?e.root.querySelector(i):null}catch{}s?.focus?.(o?{preventScroll:!0}:void 0)}function L(e,r,t){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 xe(e,r){let t=z(e);for(let[n,o]of Object.entries(t)){if(n.startsWith("#")){_e(n,o,r);continue}if(!o||typeof o!=="object"||Array.isArray(o))continue;let i=r(n);if(i===null)continue;let s=(a,c)=>c?r(n,!0):i;for(let[a,c]of Object.entries(o)){if(!S(a))continue;let l;if(Array.isArray(c)){if(c.length===0){console.warn(`[phlex-reactive] malformed reactive_show_targets group for ${a} — skipped`);continue}l=c.every((u)=>J(u,s))}else{let u=le(c,i);if(u===null){console.warn(`[phlex-reactive] malformed reactive_show_targets predicate for ${a} — skipped`);continue}l=u}for(let u of document.querySelectorAll(a))u.hidden=!l}}}function _e(e,r,t){if(!S(e))return;let n=r&&typeof r==="object"&&!Array.isArray(r)?r.any:null,o=Xe(n);if(o===null){console.warn(`[phlex-reactive] malformed reactive_show_targets conditions for ${e} — skipped`);return}if(o.every((s)=>t(s)===null)&&!et(n))return;let i=w(n,t);if(i===null)return;for(let s of document.querySelectorAll(e))s.hidden=!i}function z(e,r="show",t="mode: { ... }, kind: { ... }"){let n=e.root.getAttribute?.(`data-reactive-${r}-targets`);if(!n)return{};try{let o=JSON.parse(n);if(o&&typeof o==="object"&&!Array.isArray(o))return o}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 Oe(e,r,t,n){let o=!1,i=null;for(let s of e.root.querySelectorAll(q(r,n))){if(!t(s))continue;if(s.type==="checkbox")return s.checked?"true":"false";if(s.type==="radio"){if(s.checked)return s.value??"";o=!0;continue}i??=s}if(i)return i.value??"";return o?"":null}function q(e,r){return`[name="${E(e,r)}"]`}function E(e,r){return r&&!e.includes("[")?`${r}[${e}]`:e}function Y(e,r){let t=e.root.getAttribute?.("data-reactive-scope")||null,n=new Map;return(o,i)=>{let s=i?`#${o}`:o;if(!n.has(s))n.set(s,i?R(e,o,r,t).filter((a)=>a.checked).length:Oe(e,o,r,t));return n.get(s)}}var U="[data-reactive-media]";function Ne(e,r,t){for(let n of e.root.querySelectorAll(U)){if(!t(n))continue;let o,i,s;try{if(o=JSON.parse(n.getAttribute("data-reactive-media")),o?.match!=null)i=new RegExp(`^(?:${o.match})$`);if(o?.when!=null)s=new RegExp(`^(?:${o.when})$`)}catch{}if(typeof o?.field!=="string"||!o.pool||typeof o.pool!=="object"||o.match!=null&&!i||o.when!=null&&!s){console.warn("[phlex-reactive] malformed data-reactive-media — skipped");continue}let a=r(o.field);if(a===null)continue;let c=o.take>0?[...a]:null,l=c?c.slice(0,o.take).join(""):a,u=c?.length<o.take||i?.test(l)===!1||s?.test(a)===!1;if(u&&o.pending==="keep"){P(n,"pending");continue}let d=!u&&Object.hasOwn(o.pool,l)?G(e,o.pool[l])[0]:null,f=e.core.copyMedia(n,d??null);if(f===null)continue;if(P(n,u?"pending":f===!1?"miss":"hit"),typeof o.label!=="string")continue;let p=u?"":f===!1?String(o.blank??""):f;for(let g of G(e,o.label))if(g.textContent!==p)g.textContent=p}}function P(e,r){if(e.getAttribute("data-reactive-media-state")!==r)e.setAttribute("data-reactive-media-state",r)}function G(e,r){try{return r==="@root"?[]:e.core.opTargets({to:r})}catch{return[]}}var Z="[data-reactive-css-vars]",Ce=/^--[a-z0-9-]+$/i,ke=["","px","%","deg","turn","ms","s","em","rem","fr"];function qe(e,r,t,n,o){let i=[...e.root.querySelectorAll(Z)].filter(t);if(e.root.hasAttribute("data-reactive-css-vars"))i.unshift(e.root);for(let s of i){let a;try{a=JSON.parse(s.getAttribute("data-reactive-css-vars"))}catch{}if(!Array.isArray(a?.to)||!a.vars||typeof a.vars!=="object"){console.warn("[phlex-reactive] malformed data-reactive-css-vars — skipped (two reactive_css_vars on one element?)");continue}let c=a.to.flatMap((l)=>{let u={to:l,global:a.global===!0},d=[];try{d=e.core.opTargets(u)}catch{}if(!d.length)e.core.diagnose("reactive_css_vars",u);return d});for(let[l,u]of Object.entries(a.vars)){let d=u?.unit??"";if(!Ce.test(l)||!ke.includes(d)||typeof u?.field!=="string"){console.warn(`[phlex-reactive] refused reactive_css_vars entry ${JSON.stringify(l)} — skipped`);continue}let f=Ee(e,r,u.field,o,n);if(f===void 0)continue;let p=f===null?"":`${f}${d}`;for(let g of c){if(g.style.getPropertyValue(l)===p)continue;if(p)g.style.setProperty(l,p);else g.style.removeProperty(l)}}}}function Ee(e,r,t,n,o){let i=r(t);if(i===null)return;if((i==="true"||i==="false")&&[...e.root.querySelectorAll(q(t,o))].some((a)=>n(a)&&a.type==="checkbox"))return i==="true"?1:0;let s=i.trim()?Number(i):NaN;return Number.isFinite(s)?s:null}var _="[data-reactive-enable], [data-reactive-select-all], [data-reactive-count]";function $e(e){return!!e.root.querySelector?.(_)}function R(e,r,t,n,o){return[...e.root.querySelectorAll(q(r,n))].filter((i)=>i.type==="checkbox"&&t(i)&&(!o||Re(i.getAttribute("data-reactive-group"),o)))}function Re(e,r){return e===r||!!e?.startsWith(`${r}.`)}function je(e,r){let t=r?.getAttribute?.("data-reactive-select-all");if(t&&e.core.owns(r))Q(e,t,r.checked,r,r.getAttribute("data-reactive-select-all-under"))}function ft(e,r,t){if(!r)return;let n=k.get(e)??{root:e,core:{ownership:()=>(o)=>o.closest('[data-controller~="reactive"]')===e}};Q(n,r,t!==!1),n.show?.()}function Q(e,r,t,n,o){let i=e.root.getAttribute?.("data-reactive-scope")||null,s=R(e,r,e.core.ownership(),i,o).filter((a)=>a!==n&&a.checked!==t);for(let a of s)a.checked=t;e.flipping=!0;try{for(let a of s)for(let c of["input","change"])a.dispatchEvent?.(new Event(c,{bubbles:!0}))}finally{e.flipping=!1}}function Me(e,r,t,n){for(let o of e.root.querySelectorAll(_)){if(!t(o))continue;let i=o.getAttribute("data-reactive-enable");if(i!==null){let c=V(H(i),r);if(c!==null)o.disabled=!c}let s=o.getAttribute("data-reactive-count");if(s){let c=String(r(s,!0));if(o.textContent!==c)o.textContent=c}let a=o.getAttribute("data-reactive-select-all");if(a){let c=o.getAttribute("data-reactive-select-all-under"),l=R(e,a,t,n,c).filter((d)=>d!==o),u=l.filter((d)=>d.checked).length;o.checked=u>0&&u===l.length,o.indeterminate=u>0&&u<l.length}}}function Te(e,r){for(let[t,n]of Object.entries(z(e,"group",'"ids[]" => { ... }, "tags[]" => { ... }'))){if(!n||typeof n!=="object"||Array.isArray(n))continue;let o=String(r(t,!0));for(let s of Array.isArray(n.count)?n.count:[]){if(!S(s,"group"))continue;for(let a of document.querySelectorAll(s))if(a.textContent!==o)a.textContent=o}let i=n.enable&&typeof n.enable==="object"?n.enable:{};for(let[s,a]of Object.entries(i)){if(!S(s,"group"))continue;let c=w(a?.any,r);if(c===null){console.warn(`[phlex-reactive] malformed reactive_group_targets enable for ${s} — skipped`);continue}for(let l of document.querySelectorAll(s))l.disabled=!c}}}function F(e){if(e.groupObserver||typeof MutationObserver!=="function")return;let r=(o)=>e.root.getAttribute?.(`data-reactive-${o}`)?.includes("checked_");if(!e.root.getAttribute?.("data-reactive-group-targets")&&!e.root.querySelector?.(`${_}, [data-reactive-show*=checked_]`)&&!r("show-targets")&&!r("on-complete"))return;let n=(o)=>o.nodeType===1&&(o.matches('input[type="checkbox"]')||!!o.querySelector('input[type="checkbox"]'));e.groupObserver=new MutationObserver((o)=>{if(!o.some((i)=>[...i.addedNodes,...i.removedNodes].some(n)))return;e.show?.(),e.arm?.()}),e.groupObserver.observe(e.root,{childList:!0,subtree:!0})}function x(e){return!!(e.root.getAttribute?.("data-reactive-filter-input")&&e.root.getAttribute?.("data-reactive-filter-option"))}function Je(e,r){let t=e.root.getAttribute("data-reactive-filter-input");return!!t&&typeof r.target?.matches==="function"&&r.target.matches(t)}var Ie=/[\s\-'(),./]/;function De(e,r,t){if(e==="prefix")return r.startsWith(t);if(e!=="word_start")return r.includes(t);for(let n=r.indexOf(t);n!==-1;n=r.indexOf(t,n+1))if(n===0||Ie.test(r[n-1]))return!0;return!1}function A(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 n=e.core.ownership(),o=[...e.root.querySelectorAll(r)].find(n);if(!o)return;let i=e.root.getAttribute("data-reactive-filter-match"),s=e.root.hasAttribute?.("data-reactive-filter-fold"),a=(f)=>{let p=(f??"").toLowerCase().trim();return s?p.normalize("NFD").replace(/\p{M}/gu,""):p},c=a(o.value),l=0;for(let f of e.root.querySelectorAll(t)){if(!n(f))continue;let p=f.hasAttribute?.("data-reactive-tags-selected")||c!==""&&!De(i,a(f.getAttribute("data-reactive-filter-text")??f.textContent),c);if(f.hidden=p,p)f.removeAttribute("data-reactive-highlighted");else l++}let u=e.root.getAttribute("data-reactive-filter-group");if(u)for(let f of e.root.querySelectorAll(u)){if(!n(f))continue;let p=[...f.querySelectorAll(t)].filter(n);if(p.length===0)continue;f.hidden=p.every((g)=>g.hidden)}let d=e.root.getAttribute("data-reactive-filter-empty");if(d){for(let f of e.root.querySelectorAll(d))if(n(f))f.hidden=l>0}}function O(e){return!!e.root.getAttribute?.("data-reactive-tags-field")}function We(e){if(typeof e.root?.querySelector!=="function")return!1;return!!e.root.querySelector("[data-reactive-nested-json]")}function j(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 M(e){let r=new Set,t=[];for(let n of String(e.value??"").split(",")){let o=n.trim();if(o===""||r.has(o.toLowerCase()))continue;r.add(o.toLowerCase()),t.push(o)}return t}function X(e,r){let t=j(e);if(!t)return!1;let n=M(t),o=new Set(n.map((s)=>s.toLowerCase())),i=!1;for(let s of r){let a=String(s??"").trim();if(a===""||o.has(a.toLowerCase()))continue;o.add(a.toLowerCase()),n.push(a),i=!0}if(i)ee(e,t,n);return i}function ee(e,r,t){r.value=t.join(","),v(r),te(e)}function Le(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 te(e){let r=j(e);if(!r)return;let t=M(r),n=e.core.ownership();Pe(e,t,n),Ge(e,t,n)}function Pe(e,r,t){let n=[...e.root.querySelectorAll("[data-reactive-tags-list]")].find(t);if(!n)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(n.firstChild)n.removeChild(n.firstChild);for(let s of r){let a=i.cloneNode(!0);a.setAttribute?.("data-reactive-tag",s);let c=a.matches?.("[data-reactive-tag-text]")?a:(a.querySelectorAll?.("[data-reactive-tag-text]")??[])[0];if(c)c.textContent=s;let l=[...a.querySelectorAll?.('[data-action*="reactive#tagsRemove"]')??[]];if(a.matches?.('[data-action*="reactive#tagsRemove"]'))l.push(a);for(let u of l)u.setAttribute?.("data-reactive-tag-param",s);n.appendChild(a)}}function Ge(e,r,t){let n=new Set(r.map((o)=>o.toLowerCase()));for(let o of e.root.querySelectorAll("[role=option]")){if(!t(o))continue;let i=o.getAttribute?.("data-reactive-tag-param");if(!i)continue;if(n.has(i.toLowerCase()))o.setAttribute("data-reactive-tags-selected","true"),o.hidden=!0,o.removeAttribute?.("data-reactive-highlighted");else if(o.hasAttribute?.("data-reactive-tags-selected")){if(o.removeAttribute("data-reactive-tags-selected"),!x(e))o.hidden=!1}}if(x(e))A(e)}function Fe(e){return e.nestedIndex=Math.max(e.nestedIndex+1,Date.now()),e.nestedIndex}function Be(e,r){let t=[e,...e.querySelectorAll?.("*")??[]];for(let n of t)for(let o of["name","id","for"]){let i=n.getAttribute?.(o);if(i&&i.includes("NEW_ROW"))n.setAttribute?.(o,i.replaceAll("NEW_ROW",String(r)))}}function Ke(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 He(e,r,t,n){if(!t)return null;let o;try{o=JSON.parse(t)}catch{return null}if(!o||typeof o!=="object")return null;let i=e.core.ownership(),s=[...r.querySelectorAll?.("input, select, textarea")??[]],a=[];for(let[c,l]of Object.entries(o)){let u=[...e.root.querySelectorAll?.(l)??[]].find(i);if(!u)continue;let d=s.find((f)=>ne(f.getAttribute?.("name"))===c);if(!d)continue;if(Ve(d,u),!a.includes(u))a.push(u)}if(n)for(let c of a)ze(c,n);return a[0]??null}function Ve(e,r){if(e.type==="checkbox")e.checked=r.type==="checkbox"?!!r.checked:N(r)!=="";else e.value=N(r);v(e)}function ze(e,r){let t=r==="reset";if(e.type==="checkbox"||t&&e.type==="radio")e.checked=t&&!!e.defaultChecked;else if(t&&e.options){let n=Array.from(e.options),o=!e.multiple&&!(e.size>1),i=n.filter((s)=>s.defaultSelected).pop()??n.find((s)=>!s.closest?.("optgroup")?.disabled&&!s.disabled);for(let s of n)s.selected=o?s===i:!!s.defaultSelected}else e.value=t?e.defaultValue??"":"";v(e)}function Ye(e,r){if(!e.includes("%{"))return e;return e.replace(/%\{(\w+)\}/g,(t,n)=>Object.prototype.hasOwnProperty.call(r,n)?r[n]:t)}function B(e,r){let t=[...r.querySelectorAll?.('input[name$="[_destroy]"]')??[]][0];if(t)t.value="1",v(t),r.hidden=!0;else r.parentNode?.removeChild?.(r);T(e)}function T(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))oe(e,t.getAttribute("data-reactive-nested-json"))}function Ue(e,r){let t=r.getAttribute?.("data-reactive-nested-json-field");if(!t)return null;let n=e.core.ownership();return[...e.root.querySelectorAll(t)].find(n)??null}function re(e,r){let t={},n=e.core.ownership();for(let o of[...r.querySelectorAll?.("input, select, textarea")??[]]){if(o.matches(":disabled")||o.type==="radio"&&!o.checked||!n(o))continue;let i=ne(o.getAttribute?.("name"));if(i===null||i==="_destroy")continue;t[i]=N(o)}return t}function ne(e){if(!e)return null;let r=e.match(/\[([^\][]+)\]$/);return r?r[1]:e}function N(e){if(e.type==="checkbox")return e.checked?e.value||"on":"";return e.value??""}function oe(e,r){let t=e.core.ownership(),n=[...e.root.querySelectorAll(`[data-reactive-nested-list="${r}"]`)].find(t);if(!n)return;let o=Ue(e,n);if(!o)return;let i=[];for(let a of[...n.querySelectorAll?.("[data-reactive-nested-row]")??[]]){if(!t(a)||a.hidden)continue;i.push(re(e,a))}let s=JSON.stringify(i);if(o.value===s)return;o.value=s,v(o)}function dt(e,r,t){let n=y(e,r);if(!O(n))return;if(t?.defaultPrevented)return;if(n.core.listnavOptions(t).some((s)=>s.hasAttribute?.("data-reactive-highlighted")))return;t?.preventDefault?.();let o=t?.currentTarget??t?.target;if(!o)return;if(!X(n,String(o.value??"").split(",")))return;if(o.value="",x(n))A(n)}function pt(e,r,t){let n=y(e,r);if(!O(n))return;t?.preventDefault?.();let i=(t?.currentTarget??t?.target)?.getAttribute?.("data-reactive-tag-param");if(!i)return;if(!X(n,[i]))return;let s=Le(n);if(!s)return;s.value="",A(n),s.focus?.()}function gt(e,r,t){let n=y(e,r);if(!O(n))return;t?.preventDefault?.();let i=(t?.currentTarget??t?.target)?.getAttribute?.("data-reactive-tag-param");if(!i)return;let s=j(n);if(!s)return;let a=M(s),c=a.filter((l)=>l.toLowerCase()!==i.toLowerCase());if(c.length===a.length)return;ee(n,s,c)}function ht(e,r,t){let n=y(e,r);t?.preventDefault?.();let o=t?.currentTarget??t?.target,i=o?.getAttribute?.("data-reactive-association-param");if(!i)return;if(typeof n.root?.querySelectorAll!=="function")return;let s=n.core.ownership(),a=[...n.root.querySelectorAll(`[data-reactive-nested-list="${i}"]`)].find(s),l=[...n.root.querySelectorAll(`[data-reactive-nested-template="${i}"]`)].find(s)?.content?.firstElementChild;if(!a||!l){Ke(n,i);return}let u=l.cloneNode(!0);Be(u,Fe(n)),a.appendChild(u);let d=o?.getAttribute?.("data-reactive-nested-from-param"),f=o?.getAttribute?.("data-reactive-nested-clear-param"),g=He(n,u,d,f==="true"||f==="reset"?f:null);if(d)g?.focus?.();else[...u.querySelectorAll?.("input, select, textarea")??[]][0]?.focus?.();if(a.getAttribute?.("data-reactive-nested-json")===i)oe(n,i)}function yt(e,r,t){let n=y(e,r);t?.preventDefault?.();let o=t?.currentTarget??t?.target,i=o?.closest?.("[data-reactive-nested-row]");if(!i)return;if(i.closest?.('[data-controller~="reactive"]')!==n.root)return;let s=o?.getAttribute?.("data-reactive-confirm-param"),a=o?.getAttribute?.("data-reactive-confirm-when-param"),c=s||(a?ue(n,a):null);if(!c)return B(n,i);let l=re(n,i),u=Ye(c,l);return n.core.confirm(u,{el:o,row:i,fields:l}).then((d)=>{if(d)B(n,i)})}function ie(e,r){let t=r?.target;if(!t||!e.core.owns(t))return;T(e)}var se=["gte","gt","lte","lt"],Ze=["len_eq","len_gte","len_gt","len_lte","len_lt"],ae=["checked_eq","checked_gte","checked_gt","checked_lte","checked_lt"],Qe=["digits_eq","digits_gte","digits_lt","digits_lte"];function C(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 ce(e,r,t){let n=Number(r);if(Number.isNaN(n))return console.warn(`[phlex-reactive] reactive_show ${e}: needs a numeric literal, got ${JSON.stringify(r)} — skipped`),null;let o=t==null?"":String(t).trim(),i=o===""?NaN:Number(o);if(Number.isNaN(i))return!1;switch(e){case"gte":return i>=n;case"gt":return i>n;case"lte":return i<=n;case"lt":return i<n;default:return null}}function le(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 se)if(t in e)return ce(t,e[t],r);for(let t of Ze)if(t in e)return C(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=ae.find((i)=>(i in e));if(t){let i=r(e.field,!0);return C(t,e[t],Array.isArray(i)?i.length:Number(i)||0)===!0}if(typeof e.same==="string"){let i=(s)=>{let a=String(r(s)??"");return e.fold===!0?a.replace(/[A-Z]/g,(c)=>String.fromCharCode(c.charCodeAt(0)+32)):a};return i(e.field)===i(e.same)!==(e.negate===!0)}let n=Qe.filter((i)=>(i in e));if(n.length){let i=String(r(e.field)??"");if(!n.every((a)=>Number.isInteger(e[a]))||e.prefix!=null&&typeof e.prefix!=="string")return!1;return(/^[0-9]*$/.test(i)&&n.every((a)=>C(a,e[a],i.length))&&i.startsWith(e.prefix??""))!==(e.negate===!0)}let o=r(e.field)??"";return le(e,o)===!0}function w(e,r){if(!Array.isArray(e)||e.length===0)return null;return e.some((t)=>Array.isArray(t)&&t.length>0&&t.every((n)=>J(n,r)))}function Xe(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 n of t){if(n&&typeof n==="object"&&typeof n.field==="string")r.add(n.field);if(typeof n?.same==="string")r.add(n.same)}}return r.size>0?[...r]:null}function et(e){return e.flat().every((r)=>ae.some((t)=>(t in Object(r))))}function ue(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:n}=e.core.collectFields(),o=(s)=>n[s],i;if(typeof t.predicate==="string"){let s=de(t.predicate);if(!s)return console.warn(`[phlex-reactive] confirm predicate "${t.predicate}" is not registered — proceeding without a dialog (register it with setConfirmPredicate)`),null;i=!!s(n)}else i=w(t.groups?.any,o)===!0;return i?t.message:null}function I(e,r){let t=r.target?.closest?.("[data-reactive-editable]");return t&&e.core.owns(t)?t:null}function tt(e,r){let t=I(e,r);if(!t||r.isComposing||r.keyCode===229)return;if(r.key==="Enter"){let n=t.getAttribute("data-reactive-editable-enter");if(t.getAttribute("data-reactive-editable")==="multi"&&(n==null||r.shiftKey))return;if(r.preventDefault(),n==="submit")t.closest("form")?.requestSubmit();else if(n)e.core.applyOps(JSON.parse(n),"@root")}else if(r.key==="Escape"&&t.hasAttribute("data-reactive-editable-escape"))r.preventDefault(),t.textContent=e.core.served(t),v(t),t.blur()}function rt(e,r){let t=I(e,r),n=t?.getAttribute("data-reactive-editable")!=="multi",o=(r.clipboardData??r.dataTransfer)?.getData("text/plain");if(!t||o==null||e.core.plain()&&!(n&&/[\r\n]/.test(o)))return;if(r.preventDefault(),n)o=o.replace(/\r?\n|\r/g," ");t.focus(),document.execCommand("insertText",!1,o)}function nt(e,r){let t=I(e,r);if(t?.firstChild&&e.core.text(t)==="")t.replaceChildren()}export{ft as checkGroup,ut as confirmMessage,st as connect,at as disconnect,ht as nestedAdd,yt as nestedRemove,ct as reseed,lt as syncNestedJson,dt as tagsAdd,pt as tagsPick,gt as tagsRemove};
2
2
 
3
- //# debugId=0E6A93F98751F98F64756E2164756E21
3
+ //# debugId=57464E03CF36FB0164756E2164756E21
4
4
  //# sourceMappingURL=bindings.min.js.map