@jasonshimmy/custom-elements-runtime 3.3.0 → 3.5.0

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.
Files changed (106) hide show
  1. package/README.md +28 -7
  2. package/dist/css-utils-Bn-dO44e.js +203 -0
  3. package/dist/{css-utils-CC43BbEy.js.map → css-utils-Bn-dO44e.js.map} +1 -1
  4. package/dist/{css-utils-CC43BbEy.js → css-utils-CFeP8SK1.cjs} +5 -71
  5. package/dist/{css-utils-mgjmH8qX.cjs.map → css-utils-CFeP8SK1.cjs.map} +1 -1
  6. package/dist/custom-elements-runtime.cjs.js +3 -4
  7. package/dist/custom-elements-runtime.cjs.js.map +1 -1
  8. package/dist/custom-elements-runtime.colors.cjs.js +1 -2
  9. package/dist/custom-elements-runtime.colors.cjs.js.map +1 -1
  10. package/dist/custom-elements-runtime.colors.es.js +277 -277
  11. package/dist/custom-elements-runtime.colors.es.js.map +1 -1
  12. package/dist/custom-elements-runtime.directive-enhancements.cjs.js +1 -2
  13. package/dist/custom-elements-runtime.directive-enhancements.cjs.js.map +1 -1
  14. package/dist/custom-elements-runtime.directive-enhancements.es.js +106 -122
  15. package/dist/custom-elements-runtime.directive-enhancements.es.js.map +1 -1
  16. package/dist/custom-elements-runtime.directives.cjs.js +1 -2
  17. package/dist/custom-elements-runtime.directives.cjs.js.map +1 -1
  18. package/dist/custom-elements-runtime.directives.es.js +60 -65
  19. package/dist/custom-elements-runtime.directives.es.js.map +1 -1
  20. package/dist/custom-elements-runtime.dom-jit-css.cjs.js +1 -7
  21. package/dist/custom-elements-runtime.dom-jit-css.cjs.js.map +1 -1
  22. package/dist/custom-elements-runtime.dom-jit-css.es.js +103 -115
  23. package/dist/custom-elements-runtime.dom-jit-css.es.js.map +1 -1
  24. package/dist/custom-elements-runtime.es.js +206 -253
  25. package/dist/custom-elements-runtime.es.js.map +1 -1
  26. package/dist/custom-elements-runtime.event-bus.cjs.js +1 -2
  27. package/dist/custom-elements-runtime.event-bus.cjs.js.map +1 -1
  28. package/dist/custom-elements-runtime.event-bus.es.js +102 -108
  29. package/dist/custom-elements-runtime.event-bus.es.js.map +1 -1
  30. package/dist/custom-elements-runtime.jit-css.cjs.js +1 -2
  31. package/dist/custom-elements-runtime.jit-css.cjs.js.map +1 -1
  32. package/dist/custom-elements-runtime.jit-css.es.js +14 -32
  33. package/dist/custom-elements-runtime.jit-css.es.js.map +1 -1
  34. package/dist/custom-elements-runtime.router.cjs.js +20 -21
  35. package/dist/custom-elements-runtime.router.cjs.js.map +1 -1
  36. package/dist/custom-elements-runtime.router.es.js +866 -926
  37. package/dist/custom-elements-runtime.router.es.js.map +1 -1
  38. package/dist/custom-elements-runtime.ssr-middleware.cjs.js +3 -4
  39. package/dist/custom-elements-runtime.ssr-middleware.cjs.js.map +1 -1
  40. package/dist/custom-elements-runtime.ssr-middleware.es.js +67 -73
  41. package/dist/custom-elements-runtime.ssr-middleware.es.js.map +1 -1
  42. package/dist/custom-elements-runtime.ssr.cjs.js +1 -1
  43. package/dist/custom-elements-runtime.ssr.es.js +3 -13
  44. package/dist/custom-elements-runtime.store.cjs.js +1 -2
  45. package/dist/custom-elements-runtime.store.cjs.js.map +1 -1
  46. package/dist/custom-elements-runtime.store.es.js +32 -33
  47. package/dist/custom-elements-runtime.store.es.js.map +1 -1
  48. package/dist/custom-elements-runtime.transitions.cjs.js +1 -2
  49. package/dist/custom-elements-runtime.transitions.cjs.js.map +1 -1
  50. package/dist/custom-elements-runtime.transitions.es.js +200 -210
  51. package/dist/custom-elements-runtime.transitions.es.js.map +1 -1
  52. package/dist/custom-elements-runtime.vite-plugin.cjs.js +4 -2
  53. package/dist/custom-elements-runtime.vite-plugin.cjs.js.map +1 -1
  54. package/dist/custom-elements-runtime.vite-plugin.es.js +155 -78
  55. package/dist/custom-elements-runtime.vite-plugin.es.js.map +1 -1
  56. package/dist/helpers-DcEpRwq5.cjs +5 -0
  57. package/dist/helpers-DcEpRwq5.cjs.map +1 -0
  58. package/dist/helpers-tJgb4Qve.js +693 -0
  59. package/dist/helpers-tJgb4Qve.js.map +1 -0
  60. package/dist/hooks-CEUnvtsA.js +407 -0
  61. package/dist/hooks-CEUnvtsA.js.map +1 -0
  62. package/dist/hooks-CNfugc95.cjs +2 -0
  63. package/dist/hooks-CNfugc95.cjs.map +1 -0
  64. package/dist/logger-DIJ0UH3R.js +36 -0
  65. package/dist/{logger-L25axmB-.js.map → logger-DIJ0UH3R.js.map} +1 -1
  66. package/dist/logger-Dkht1dCX.cjs +2 -0
  67. package/dist/{logger-BYIN7ysT.cjs.map → logger-Dkht1dCX.cjs.map} +1 -1
  68. package/dist/namespace-helpers-CIUkG8Mn.js +56 -0
  69. package/dist/{namespace-helpers-BucDdgz_.js.map → namespace-helpers-CIUkG8Mn.js.map} +1 -1
  70. package/dist/namespace-helpers-yYIb7INq.cjs +2 -0
  71. package/dist/{namespace-helpers-Bf7rm9JV.cjs.map → namespace-helpers-yYIb7INq.cjs.map} +1 -1
  72. package/dist/runtime/tag-utils.d.ts +11 -0
  73. package/dist/ssr-BpYy9XlW.js +170 -0
  74. package/dist/{ssr-B3lxl1vr.js.map → ssr-BpYy9XlW.js.map} +1 -1
  75. package/dist/ssr-CFabTOyi.cjs +4 -0
  76. package/dist/{ssr-DtD9e5iA.cjs.map → ssr-CFabTOyi.cjs.map} +1 -1
  77. package/dist/ssr.d.ts +33 -0
  78. package/dist/style-A8l3aQ52.cjs +55 -0
  79. package/dist/{style-Bjn8zDiZ.cjs.map → style-A8l3aQ52.cjs.map} +1 -1
  80. package/dist/style-DSSoCbC9.js +1877 -0
  81. package/dist/{style-DuDoj_xK.js.map → style-DSSoCbC9.js.map} +1 -1
  82. package/dist/tag-utils-CoSXTr1F.js +10 -0
  83. package/dist/tag-utils-CoSXTr1F.js.map +1 -0
  84. package/dist/tag-utils-XJ3dkcPQ.cjs +2 -0
  85. package/dist/tag-utils-XJ3dkcPQ.cjs.map +1 -0
  86. package/dist/template-compiler-B4B_jAPN.cjs +19 -0
  87. package/dist/{template-compiler-BB4JJdqk.cjs.map → template-compiler-B4B_jAPN.cjs.map} +1 -1
  88. package/dist/template-compiler-C3h8_vbE.js +3044 -0
  89. package/dist/{template-compiler-Cs5axmn4.js.map → template-compiler-C3h8_vbE.js.map} +1 -1
  90. package/dist/vite-plugin.d.ts +96 -2
  91. package/package.json +8 -8
  92. package/dist/css-utils-mgjmH8qX.cjs +0 -577
  93. package/dist/hooks-_3xP4G2N.js +0 -1189
  94. package/dist/hooks-_3xP4G2N.js.map +0 -1
  95. package/dist/hooks-fYQgZk2g.cjs +0 -7
  96. package/dist/hooks-fYQgZk2g.cjs.map +0 -1
  97. package/dist/logger-BYIN7ysT.cjs +0 -3
  98. package/dist/logger-L25axmB-.js +0 -41
  99. package/dist/namespace-helpers-Bf7rm9JV.cjs +0 -3
  100. package/dist/namespace-helpers-BucDdgz_.js +0 -61
  101. package/dist/ssr-B3lxl1vr.js +0 -165
  102. package/dist/ssr-DtD9e5iA.cjs +0 -5
  103. package/dist/style-Bjn8zDiZ.cjs +0 -56
  104. package/dist/style-DuDoj_xK.js +0 -1972
  105. package/dist/template-compiler-BB4JJdqk.cjs +0 -23
  106. package/dist/template-compiler-Cs5axmn4.js +0 -3236
@@ -1,3 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("./custom-elements-runtime.directives.cjs.js");function w(n,e){return i.when(!n,e)}function g(n,e){return i.when(!n||n.length===0,e)}function m(n,e){return i.when(!!(n&&n.length>0),e)}function k(n,e,o){const t=[];return n.forEach((r,c)=>{e(r,c)&&t.push({item:r,originalIndex:c})}),t.map(({item:r,originalIndex:c},s)=>{const l=typeof r=="object"&&r!=null?r?.key??r?.id??`filtered-${c}`:`filtered-${c}`;return i.anchorBlock(o(r,c,s),`each-where-${l}`)})}function x(n,e){const o=i.nextDirectiveIndex(),t=n?.length??0;return t===0&&e.empty?i.anchorBlock(e.empty,`switch-length-${o}-empty`):t===1&&e.one?i.anchorBlock(e.one(n[0]),`switch-length-${o}-one`):e.exactly?.[t]?i.anchorBlock(e.exactly[t](n),`switch-length-${o}-${t}`):t>1&&e.many?i.anchorBlock(e.many(n),`switch-length-${o}-many`):i.anchorBlock([],`switch-length-${o}-fallback`)}function y(n,e,o){const t=new Map;return n.forEach(r=>{const c=e(r);t.has(c)||t.set(c,[]),t.get(c).push(r)}),Array.from(t.entries()).map(([r,c],s)=>i.anchorBlock(o(r,c,s),`each-group-${r}`))}function $(n,e,o,t){const r=o*e,c=Math.min(r+e,n.length);return n.slice(r,c).map((s,l)=>{const u=r+l,f=typeof s=="object"&&s!=null?s?.key??s?.id??`page-${u}`:`page-${u}`;return i.anchorBlock(t(s,u,l),`each-page-${f}`)})}function v(n,e){const o=i.nextDirectiveIndex();return n.loading&&e.loading?i.anchorBlock(e.loading,`promise-${o}-loading`):n.error&&e.error?i.anchorBlock(e.error(n.error),`promise-${o}-error`):n.data!==void 0&&e.success?i.anchorBlock(e.success(n.data),`promise-${o}-success`):e.idle?i.anchorBlock(e.idle,`promise-${o}-idle`):i.anchorBlock([],`promise-${o}-fallback`)}function h(n,e){const o=typeof window<"u"&&window.matchMedia?.(n)?.matches;return i.when(!!o,e)}var a={sm:"(min-width:640px)",md:"(min-width:768px)",lg:"(min-width:1024px)",xl:"(min-width:1280px)","2xl":"(min-width:1536px)",dark:"(prefers-color-scheme: dark)"},d=["sm","md","lg","xl","2xl"],p={sm:n=>h(a.sm,n),md:n=>h(a.md,n),lg:n=>h(a.lg,n),xl:n=>h(a.xl,n),"2xl":n=>h(a["2xl"],n),dark:n=>h(a.dark,n),light:n=>h("(prefers-color-scheme: light)",n),touch:n=>h("(hover: none) and (pointer: coarse)",n),mouse:n=>h("(hover: hover) and (pointer: fine)",n),reducedMotion:n=>h("(prefers-reduced-motion: reduce)",n),highContrast:n=>h("(prefers-contrast: high)",n),portrait:n=>h("(orientation: portrait)",n),landscape:n=>h("(orientation: landscape)",n)};function B(n,e){const o=[];n.includes("dark")?o.push(a.dark):n.includes("light")&&o.push("(prefers-color-scheme: light)");const t=n.filter(c=>d.includes(c)),r=t[t.length-1];return r&&r in a&&o.push(a[r]),h(o.length>0?o.join(" and "):"all",e)}function b(n){const e=[],o=i.nextDirectiveIndex();return n.base&&e.push(i.anchorBlock(n.base,`responsive-${o}-base`)),d.forEach(t=>{const r=n[t];r&&e.push(p[t](r))}),e}function O(n){const e=[];let o=null;return{case(t,r){const c=typeof t=="function"?t:s=>s===t;return e.push({condition:c,content:r}),this},when(t,r){return e.push({condition:t,content:r}),this},otherwise(t){return o=t,this},done(){const t=i.nextDirectiveIndex();for(let r=0;r<e.length;r++){const{condition:c,content:s}=e[r];if(c(n))return i.anchorBlock(s,`switch-on-${t}-case-${r}`)}return i.anchorBlock(o||[],`switch-on-${t}-otherwise`)}}}exports.eachGroup=y;exports.eachPage=$;exports.eachWhere=k;exports.mediaVariants=a;exports.responsive=p;exports.responsiveOrder=d;exports.responsiveSwitch=b;exports.switchOn=O;exports.switchOnLength=x;exports.switchOnPromise=v;exports.unless=w;exports.whenEmpty=g;exports.whenMedia=h;exports.whenNotEmpty=m;exports.whenVariants=B;
2
-
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./custom-elements-runtime.directives.cjs.js`);function t(t,n){return e.when(!t,n)}function n(t,n){return e.when(!t||t.length===0,n)}function r(t,n){return e.when(!!(t&&t.length>0),n)}function i(t,n,r){let i=[];return t.forEach((e,t)=>{n(e,t)&&i.push({item:e,originalIndex:t})}),i.map(({item:t,originalIndex:n},i)=>{let a=typeof t==`object`&&t?t?.key??t?.id??`filtered-${n}`:`filtered-${n}`;return e.anchorBlock(r(t,n,i),`each-where-${a}`)})}function a(t,n){let r=e.nextDirectiveIndex(),i=t?.length??0;return i===0&&n.empty?e.anchorBlock(n.empty,`switch-length-${r}-empty`):i===1&&n.one?e.anchorBlock(n.one(t[0]),`switch-length-${r}-one`):n.exactly?.[i]?e.anchorBlock(n.exactly[i](t),`switch-length-${r}-${i}`):i>1&&n.many?e.anchorBlock(n.many(t),`switch-length-${r}-many`):e.anchorBlock([],`switch-length-${r}-fallback`)}function o(t,n,r){let i=new Map;return t.forEach(e=>{let t=n(e);i.has(t)||i.set(t,[]),i.get(t).push(e)}),Array.from(i.entries()).map(([t,n],i)=>e.anchorBlock(r(t,n,i),`each-group-${t}`))}function s(t,n,r,i){let a=r*n,o=Math.min(a+n,t.length);return t.slice(a,o).map((t,n)=>{let r=a+n,o=typeof t==`object`&&t?t?.key??t?.id??`page-${r}`:`page-${r}`;return e.anchorBlock(i(t,r,n),`each-page-${o}`)})}function c(t,n){let r=e.nextDirectiveIndex();return t.loading&&n.loading?e.anchorBlock(n.loading,`promise-${r}-loading`):t.error&&n.error?e.anchorBlock(n.error(t.error),`promise-${r}-error`):t.data!==void 0&&n.success?e.anchorBlock(n.success(t.data),`promise-${r}-success`):n.idle?e.anchorBlock(n.idle,`promise-${r}-idle`):e.anchorBlock([],`promise-${r}-fallback`)}function l(t,n){let r=typeof window<`u`&&window.matchMedia?.(t)?.matches;return e.when(!!r,n)}var u={sm:`(min-width:640px)`,md:`(min-width:768px)`,lg:`(min-width:1024px)`,xl:`(min-width:1280px)`,"2xl":`(min-width:1536px)`,dark:`(prefers-color-scheme: dark)`},d=[`sm`,`md`,`lg`,`xl`,`2xl`],f={sm:e=>l(u.sm,e),md:e=>l(u.md,e),lg:e=>l(u.lg,e),xl:e=>l(u.xl,e),"2xl":e=>l(u[`2xl`],e),dark:e=>l(u.dark,e),light:e=>l(`(prefers-color-scheme: light)`,e),touch:e=>l(`(hover: none) and (pointer: coarse)`,e),mouse:e=>l(`(hover: hover) and (pointer: fine)`,e),reducedMotion:e=>l(`(prefers-reduced-motion: reduce)`,e),highContrast:e=>l(`(prefers-contrast: high)`,e),portrait:e=>l(`(orientation: portrait)`,e),landscape:e=>l(`(orientation: landscape)`,e)};function p(e,t){let n=[];e.includes(`dark`)?n.push(u.dark):e.includes(`light`)&&n.push(`(prefers-color-scheme: light)`);let r=e.filter(e=>d.includes(e)),i=r[r.length-1];return i&&i in u&&n.push(u[i]),l(n.length>0?n.join(` and `):`all`,t)}function m(t){let n=[],r=e.nextDirectiveIndex();return t.base&&n.push(e.anchorBlock(t.base,`responsive-${r}-base`)),d.forEach(e=>{let r=t[e];r&&n.push(f[e](r))}),n}function h(t){let n=[],r=null;return{case(e,t){let r=typeof e==`function`?e:t=>t===e;return n.push({condition:r,content:t}),this},when(e,t){return n.push({condition:e,content:t}),this},otherwise(e){return r=e,this},done(){let i=e.nextDirectiveIndex();for(let r=0;r<n.length;r++){let{condition:a,content:o}=n[r];if(a(t))return e.anchorBlock(o,`switch-on-${i}-case-${r}`)}return e.anchorBlock(r||[],`switch-on-${i}-otherwise`)}}}exports.eachGroup=o,exports.eachPage=s,exports.eachWhere=i,exports.mediaVariants=u,exports.responsive=f,exports.responsiveOrder=d,exports.responsiveSwitch=m,exports.switchOn=h,exports.switchOnLength=a,exports.switchOnPromise=c,exports.unless=t,exports.whenEmpty=n,exports.whenMedia=l,exports.whenNotEmpty=r,exports.whenVariants=p;
3
2
  //# sourceMappingURL=custom-elements-runtime.directive-enhancements.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"custom-elements-runtime.directive-enhancements.cjs.js","names":[],"sources":["../src/lib/directive-enhancements.ts"],"sourcesContent":["// Enhanced collection directives for better developer experience\n\nimport type { VNode } from './runtime/types';\nimport { when, anchorBlock, nextDirectiveIndex } from './directives';\n\n/**\n * Conditional rendering with negated condition (opposite of when)\n * @param cond - Boolean condition to negate\n * @param children - Content to render when condition is false\n */\nexport function unless(cond: boolean, children: VNode | VNode[]): VNode {\n return when(!cond, children);\n}\n\n/**\n * Render content only if array/collection is empty\n * @param collection - Array or collection to check\n * @param children - Content to render when empty\n */\nexport function whenEmpty<T>(\n collection: T[] | null | undefined,\n children: VNode | VNode[],\n): VNode {\n const isEmpty = !collection || collection.length === 0;\n return when(isEmpty, children);\n}\n\n/**\n * Render content only if array/collection has items\n * @param collection - Array or collection to check\n * @param children - Content to render when not empty\n */\nexport function whenNotEmpty<T>(\n collection: T[] | null | undefined,\n children: VNode | VNode[],\n): VNode {\n const hasItems = Boolean(collection && collection.length > 0);\n return when(hasItems, children);\n}\n\n/**\n * Enhanced each with filtering capability\n * @param list - Array to iterate over\n * @param predicate - Filter function (optional)\n * @param render - Render function for each item\n */\nexport function eachWhere<T>(\n list: T[],\n predicate: (item: T, index: number) => boolean,\n render: (item: T, index: number, filteredIndex: number) => VNode | VNode[],\n): VNode[] {\n const filtered: Array<{ item: T; originalIndex: number }> = [];\n\n list.forEach((item, index) => {\n if (predicate(item, index)) {\n filtered.push({ item, originalIndex: index });\n }\n });\n\n return filtered.map(({ item, originalIndex }, filteredIndex) => {\n const itemKey =\n typeof item === 'object' && item != null\n ? ((item as Record<string, unknown>)?.key ??\n (item as Record<string, unknown>)?.id ??\n `filtered-${originalIndex}`)\n : `filtered-${originalIndex}`;\n\n return anchorBlock(\n render(item, originalIndex, filteredIndex),\n `each-where-${itemKey}`,\n );\n });\n}\n\n/**\n * Render different content based on array length\n * @param list - Array to check\n * @param cases - Object with length-based cases\n */\nexport function switchOnLength<T>(\n list: T[],\n cases: {\n empty?: VNode | VNode[];\n one?: (item: T) => VNode | VNode[];\n many?: (items: T[]) => VNode | VNode[];\n exactly?: { [count: number]: (items: T[]) => VNode | VNode[] };\n },\n): VNode {\n const si = nextDirectiveIndex();\n const length = list?.length ?? 0;\n\n if (length === 0 && cases.empty) {\n return anchorBlock(cases.empty, `switch-length-${si}-empty`);\n }\n\n if (length === 1 && cases.one) {\n return anchorBlock(cases.one(list[0]), `switch-length-${si}-one`);\n }\n\n if (cases.exactly?.[length]) {\n return anchorBlock(\n cases.exactly[length](list),\n `switch-length-${si}-${length}`,\n );\n }\n\n if (length > 1 && cases.many) {\n return anchorBlock(cases.many(list), `switch-length-${si}-many`);\n }\n\n return anchorBlock([], `switch-length-${si}-fallback`);\n}\n\n/**\n * Group array items and render each group\n * @param list - Array to group\n * @param groupBy - Function to determine group key\n * @param renderGroup - Function to render each group\n */\nexport function eachGroup<T, K extends string | number>(\n list: T[],\n groupBy: (item: T) => K,\n renderGroup: (groupKey: K, items: T[], groupIndex: number) => VNode | VNode[],\n): VNode[] {\n const groups = new Map<K, T[]>();\n\n list.forEach((item) => {\n const key = groupBy(item);\n if (!groups.has(key)) {\n groups.set(key, []);\n }\n groups.get(key)!.push(item);\n });\n\n return Array.from(groups.entries()).map(([groupKey, items], groupIndex) => {\n return anchorBlock(\n renderGroup(groupKey, items, groupIndex),\n `each-group-${groupKey}`,\n );\n });\n}\n\n/**\n * Render with pagination/chunking\n * @param list - Array to chunk\n * @param pageSize - Items per page/chunk\n * @param currentPage - Current page (0-based)\n * @param render - Render function for visible items\n */\nexport function eachPage<T>(\n list: T[],\n pageSize: number,\n currentPage: number,\n render: (item: T, index: number, pageIndex: number) => VNode | VNode[],\n): VNode[] {\n const startIndex = currentPage * pageSize;\n const endIndex = Math.min(startIndex + pageSize, list.length);\n const pageItems = list.slice(startIndex, endIndex);\n\n return pageItems.map((item, pageIndex) => {\n const globalIndex = startIndex + pageIndex;\n const itemKey =\n typeof item === 'object' && item != null\n ? ((item as Record<string, unknown>)?.key ??\n (item as Record<string, unknown>)?.id ??\n `page-${globalIndex}`)\n : `page-${globalIndex}`;\n\n return anchorBlock(\n render(item, globalIndex, pageIndex),\n `each-page-${itemKey}`,\n );\n });\n}\n\n/* --- Async & Loading State Directives --- */\n\n/**\n * Render content based on Promise state\n * @param promiseState - Object with loading, data, error states\n * @param cases - Render functions for each state\n */\nexport function switchOnPromise<T, E = Error>(\n promiseState: {\n loading?: boolean;\n data?: T;\n error?: E;\n },\n cases: {\n loading?: VNode | VNode[];\n success?: (data: T) => VNode | VNode[];\n error?: (error: E) => VNode | VNode[];\n idle?: VNode | VNode[];\n },\n): VNode {\n const si = nextDirectiveIndex();\n\n if (promiseState.loading && cases.loading) {\n return anchorBlock(cases.loading, `promise-${si}-loading`);\n }\n\n if (promiseState.error && cases.error) {\n return anchorBlock(cases.error(promiseState.error), `promise-${si}-error`);\n }\n\n if (promiseState.data !== undefined && cases.success) {\n return anchorBlock(\n cases.success(promiseState.data),\n `promise-${si}-success`,\n );\n }\n\n if (cases.idle) {\n return anchorBlock(cases.idle, `promise-${si}-idle`);\n }\n\n return anchorBlock([], `promise-${si}-fallback`);\n}\n\n/* --- Utility Directives --- */\n\n/**\n * Render content based on screen size/media query\n * @param mediaQuery - CSS media query string\n * @param children - Content to render when media query matches\n */\nexport function whenMedia(\n mediaQuery: string,\n children: VNode | VNode[],\n): VNode {\n const matches =\n typeof window !== 'undefined' && window.matchMedia?.(mediaQuery)?.matches;\n return when(Boolean(matches), children);\n}\n\n/* --- Responsive & Media Query Directives (aligned with style.ts) --- */\n\n/**\n * Media variants matching those in style.ts\n */\nexport const mediaVariants = {\n // Responsive breakpoints (matching style.ts)\n sm: '(min-width:640px)',\n md: '(min-width:768px)',\n lg: '(min-width:1024px)',\n xl: '(min-width:1280px)',\n '2xl': '(min-width:1536px)',\n\n // Dark mode (matching style.ts)\n dark: '(prefers-color-scheme: dark)',\n} as const;\n\n/**\n * Responsive order matching style.ts\n */\nexport const responsiveOrder = ['sm', 'md', 'lg', 'xl', '2xl'] as const;\n\n/**\n * Individual responsive directives matching the style.ts breakpoint system\n */\nexport const responsive = {\n // Breakpoint-based rendering (matching style.ts exactly)\n sm: (children: VNode | VNode[]) => whenMedia(mediaVariants.sm, children),\n md: (children: VNode | VNode[]) => whenMedia(mediaVariants.md, children),\n lg: (children: VNode | VNode[]) => whenMedia(mediaVariants.lg, children),\n xl: (children: VNode | VNode[]) => whenMedia(mediaVariants.xl, children),\n '2xl': (children: VNode | VNode[]) =>\n whenMedia(mediaVariants['2xl'], children),\n\n // Dark mode (matching style.ts)\n dark: (children: VNode | VNode[]) => whenMedia(mediaVariants.dark, children),\n light: (children: VNode | VNode[]) =>\n whenMedia('(prefers-color-scheme: light)', children),\n\n // Accessibility and interaction preferences\n touch: (children: VNode | VNode[]) =>\n whenMedia('(hover: none) and (pointer: coarse)', children),\n mouse: (children: VNode | VNode[]) =>\n whenMedia('(hover: hover) and (pointer: fine)', children),\n reducedMotion: (children: VNode | VNode[]) =>\n whenMedia('(prefers-reduced-motion: reduce)', children),\n highContrast: (children: VNode | VNode[]) =>\n whenMedia('(prefers-contrast: high)', children),\n\n // Orientation\n portrait: (children: VNode | VNode[]) =>\n whenMedia('(orientation: portrait)', children),\n landscape: (children: VNode | VNode[]) =>\n whenMedia('(orientation: landscape)', children),\n} as const;\n\n/**\n * Advanced responsive directive that matches the style.ts multi-variant processing\n * Allows chaining responsive and dark mode conditions like in CSS classes\n * @param variants - Array of variant keys (e.g., ['dark', 'lg'])\n * @param children - Content to render when all variants match\n */\nexport function whenVariants(\n variants: Array<keyof typeof mediaVariants | 'light'>,\n children: VNode | VNode[],\n): VNode {\n const conditions: string[] = [];\n\n // Process dark/light mode\n if (variants.includes('dark')) {\n conditions.push(mediaVariants.dark);\n } else if (variants.includes('light')) {\n conditions.push('(prefers-color-scheme: light)');\n }\n\n // Process responsive variants (take the last one, matching style.ts behavior)\n const responsiveVariants = variants.filter((v) =>\n responsiveOrder.includes(v as (typeof responsiveOrder)[number]),\n );\n const lastResponsive = responsiveVariants[responsiveVariants.length - 1];\n if (lastResponsive && lastResponsive in mediaVariants) {\n conditions.push(\n mediaVariants[lastResponsive as keyof typeof mediaVariants],\n );\n }\n\n const mediaQuery = conditions.length > 0 ? conditions.join(' and ') : 'all';\n return whenMedia(mediaQuery, children);\n}\n\n/**\n * Responsive switch directive - render different content for different breakpoints\n * Mirrors the responsive behavior from the style system\n * @param content - Object with breakpoint keys and corresponding content\n */\nexport function responsiveSwitch(content: {\n base?: VNode | VNode[];\n sm?: VNode | VNode[];\n md?: VNode | VNode[];\n lg?: VNode | VNode[];\n xl?: VNode | VNode[];\n '2xl'?: VNode | VNode[];\n}): VNode[] {\n const results: VNode[] = [];\n\n const si = nextDirectiveIndex();\n\n // Handle light mode variants\n if (content.base) {\n // Base content (no media query)\n results.push(anchorBlock(content.base, `responsive-${si}-base`));\n }\n\n // Add responsive variants in order\n responsiveOrder.forEach((breakpoint) => {\n const breakpointContent = content[breakpoint];\n if (breakpointContent) {\n results.push(responsive[breakpoint](breakpointContent));\n }\n });\n\n return results;\n}\n\n/* --- Enhanced Match Directive --- */\n\n/**\n * Enhanced match directive with more fluent API\n * @param value - Value to match against\n */\nexport function switchOn<T>(value: T) {\n const branches: Array<{\n condition: (val: T) => boolean;\n content: VNode | VNode[];\n }> = [];\n let otherwiseContent: VNode | VNode[] | null = null;\n\n return {\n case(matcher: T | ((val: T) => boolean), content: VNode | VNode[]) {\n const condition =\n typeof matcher === 'function'\n ? (matcher as (val: T) => boolean)\n : (val: T) => val === matcher;\n\n branches.push({ condition, content });\n return this;\n },\n\n when(predicate: (val: T) => boolean, content: VNode | VNode[]) {\n branches.push({ condition: predicate, content });\n return this;\n },\n\n otherwise(content: VNode | VNode[]) {\n otherwiseContent = content;\n return this;\n },\n\n done() {\n const si = nextDirectiveIndex();\n for (let i = 0; i < branches.length; i++) {\n const { condition, content } = branches[i];\n if (condition(value)) {\n return anchorBlock(content, `switch-on-${si}-case-${i}`);\n }\n }\n return anchorBlock(otherwiseContent || [], `switch-on-${si}-otherwise`);\n },\n };\n}\n"],"mappings":"kIAUA,SAAgB,EAAO,EAAe,EAAkC,CACtE,OAAO,EAAA,KAAK,CAAC,EAAM,CAAA,EAQrB,SAAgB,EACd,EACA,EACO,CAEP,OAAO,EAAA,KADS,CAAC,GAAc,EAAW,SAAW,EAChC,CAAA,EAQvB,SAAgB,EACd,EACA,EACO,CAEP,OAAO,EAAA,KADU,GAAQ,GAAc,EAAW,OAAS,GACrC,CAAA,EASxB,SAAgB,EACd,EACA,EACA,EACS,CACT,MAAM,EAAsD,CAAA,EAE5D,OAAA,EAAK,QAAA,CAAS,EAAM,IAAU,CACxB,EAAU,EAAM,CAAA,GAClB,EAAS,KAAK,CAAE,KAAA,EAAM,cAAe,EAAO,IAIzC,EAAS,IAAA,CAAK,CAAE,KAAA,EAAM,cAAA,CAAA,EAAiB,IAAkB,CAC9D,MAAM,EACJ,OAAO,GAAS,UAAY,GAAQ,KAC9B,GAAkC,KACnC,GAAkC,IACnC,YAAY,CAAA,GACZ,YAAY,CAAA,GAElB,OAAO,EAAA,YACL,EAAO,EAAM,EAAe,CAAA,EAC5B,cAAc,CAAA,EAAA,IAUpB,SAAgB,EACd,EACA,EAMO,CACP,MAAM,EAAK,EAAA,mBAAA,EACL,EAAS,GAAM,QAAU,EAE/B,OAAI,IAAW,GAAK,EAAM,MACjB,EAAA,YAAY,EAAM,MAAO,iBAAiB,CAAA,QAAG,EAGlD,IAAW,GAAK,EAAM,IACjB,EAAA,YAAY,EAAM,IAAI,EAAK,CAAA,CAAA,EAAK,iBAAiB,CAAA,MAAG,EAGzD,EAAM,UAAU,CAAA,EACX,EAAA,YACL,EAAM,QAAQ,CAAA,EAAQ,CAAA,EACtB,iBAAiB,CAAA,IAAM,CAAA,EAAA,EAIvB,EAAS,GAAK,EAAM,KACf,EAAA,YAAY,EAAM,KAAK,CAAA,EAAO,iBAAiB,CAAA,OAAG,EAGpD,EAAA,YAAY,CAAA,EAAI,iBAAiB,CAAA,WAAG,EAS7C,SAAgB,EACd,EACA,EACA,EACS,CACT,MAAM,EAAS,IAAI,IAEnB,OAAA,EAAK,QAAS,GAAS,CACrB,MAAM,EAAM,EAAQ,CAAA,EACf,EAAO,IAAI,CAAA,GACd,EAAO,IAAI,EAAK,CAAA,CAAE,EAEpB,EAAO,IAAI,CAAA,EAAM,KAAK,CAAA,IAGjB,MAAM,KAAK,EAAO,QAAA,CAAS,EAAE,IAAA,CAAK,CAAC,EAAU,CAAA,EAAQ,IACnD,EAAA,YACL,EAAY,EAAU,EAAO,CAAA,EAC7B,cAAc,CAAA,EAAA,GAYpB,SAAgB,EACd,EACA,EACA,EACA,EACS,CACT,MAAM,EAAa,EAAc,EAC3B,EAAW,KAAK,IAAI,EAAa,EAAU,EAAK,MAAA,EAGtD,OAFkB,EAAK,MAAM,EAAY,CAAA,EAExB,IAAA,CAAK,EAAM,IAAc,CACxC,MAAM,EAAc,EAAa,EAC3B,EACJ,OAAO,GAAS,UAAY,GAAQ,KAC9B,GAAkC,KACnC,GAAkC,IACnC,QAAQ,CAAA,GACR,QAAQ,CAAA,GAEd,OAAO,EAAA,YACL,EAAO,EAAM,EAAa,CAAA,EAC1B,aAAa,CAAA,EAAA,IAYnB,SAAgB,EACd,EAKA,EAMO,CACP,MAAM,EAAK,EAAA,mBAAA,EAEX,OAAI,EAAa,SAAW,EAAM,QACzB,EAAA,YAAY,EAAM,QAAS,WAAW,CAAA,UAAG,EAG9C,EAAa,OAAS,EAAM,MACvB,EAAA,YAAY,EAAM,MAAM,EAAa,KAAA,EAAQ,WAAW,CAAA,QAAG,EAGhE,EAAa,OAAS,QAAa,EAAM,QACpC,EAAA,YACL,EAAM,QAAQ,EAAa,IAAA,EAC3B,WAAW,CAAA,UAAG,EAId,EAAM,KACD,EAAA,YAAY,EAAM,KAAM,WAAW,CAAA,OAAG,EAGxC,EAAA,YAAY,CAAA,EAAI,WAAW,CAAA,WAAG,EAUvC,SAAgB,EACd,EACA,EACO,CACP,MAAM,EACJ,OAAO,OAAW,KAAe,OAAO,aAAa,CAAA,GAAa,QACpE,OAAO,EAAA,KAAK,EAAQ,EAAU,CAAA,EAQhC,IAAa,EAAgB,CAE3B,GAAI,oBACJ,GAAI,oBACJ,GAAI,qBACJ,GAAI,qBACJ,MAAO,qBAGP,KAAM,gCAMK,EAAkB,CAAC,KAAM,KAAM,KAAM,KAAM,OAK3C,EAAa,CAExB,GAAK,GAA8B,EAAU,EAAc,GAAI,CAAA,EAC/D,GAAK,GAA8B,EAAU,EAAc,GAAI,CAAA,EAC/D,GAAK,GAA8B,EAAU,EAAc,GAAI,CAAA,EAC/D,GAAK,GAA8B,EAAU,EAAc,GAAI,CAAA,EAC/D,MAAQ,GACN,EAAU,EAAc,KAAA,EAAQ,CAAA,EAGlC,KAAO,GAA8B,EAAU,EAAc,KAAM,CAAA,EACnE,MAAQ,GACN,EAAU,gCAAiC,CAAA,EAG7C,MAAQ,GACN,EAAU,sCAAuC,CAAA,EACnD,MAAQ,GACN,EAAU,qCAAsC,CAAA,EAClD,cAAgB,GACd,EAAU,mCAAoC,CAAA,EAChD,aAAe,GACb,EAAU,2BAA4B,CAAA,EAGxC,SAAW,GACT,EAAU,0BAA2B,CAAA,EACvC,UAAY,GACV,EAAU,2BAA4B,CAAA,GAS1C,SAAgB,EACd,EACA,EACO,CACP,MAAM,EAAuB,CAAA,EAGzB,EAAS,SAAS,MAAA,EACpB,EAAW,KAAK,EAAc,IAAA,EACrB,EAAS,SAAS,OAAA,GAC3B,EAAW,KAAK,+BAAA,EAIlB,MAAM,EAAqB,EAAS,OAAQ,GAC1C,EAAgB,SAAS,CAAA,CAAsC,EAE3D,EAAiB,EAAmB,EAAmB,OAAS,CAAA,EACtE,OAAI,GAAkB,KAAkB,GACtC,EAAW,KACT,EAAc,CAAA,CAAA,EAKX,EADY,EAAW,OAAS,EAAI,EAAW,KAAK,OAAA,EAAW,MACzC,CAAA,EAQ/B,SAAgB,EAAiB,EAOrB,CACV,MAAM,EAAmB,CAAA,EAEnB,EAAK,EAAA,mBAAA,EAGX,OAAI,EAAQ,MAEV,EAAQ,KAAK,EAAA,YAAY,EAAQ,KAAM,cAAc,CAAA,OAAG,CAAO,EAIjE,EAAgB,QAAS,GAAe,CACtC,MAAM,EAAoB,EAAQ,CAAA,EAC9B,GACF,EAAQ,KAAK,EAAW,CAAA,EAAY,CAAA,CAAkB,IAInD,EAST,SAAgB,EAAY,EAAU,CACpC,MAAM,EAGD,CAAA,EACL,IAAI,EAA2C,KAE/C,MAAO,CACL,KAAK,EAAoC,EAA0B,CACjE,MAAM,EACJ,OAAO,GAAY,WACd,EACA,GAAW,IAAQ,EAE1B,OAAA,EAAS,KAAK,CAAE,UAAA,EAAW,QAAA,EAAS,EAC7B,MAGT,KAAK,EAAgC,EAA0B,CAC7D,OAAA,EAAS,KAAK,CAAE,UAAW,EAAW,QAAA,EAAS,EACxC,MAGT,UAAU,EAA0B,CAClC,OAAA,EAAmB,EACZ,MAGT,MAAO,CACL,MAAM,EAAK,EAAA,mBAAA,EACX,QAAS,EAAI,EAAG,EAAI,EAAS,OAAQ,IAAK,CACxC,KAAM,CAAE,UAAA,EAAW,QAAA,CAAA,EAAY,EAAS,CAAA,EACxC,GAAI,EAAU,CAAA,EACZ,OAAO,EAAA,YAAY,EAAS,aAAa,CAAA,SAAW,CAAA,EAAA,EAGxD,OAAO,EAAA,YAAY,GAAoB,CAAA,EAAI,aAAa,CAAA,YAAG"}
1
+ {"version":3,"file":"custom-elements-runtime.directive-enhancements.cjs.js","names":[],"sources":["../src/lib/directive-enhancements.ts"],"sourcesContent":["// Enhanced collection directives for better developer experience\n\nimport type { VNode } from './runtime/types';\nimport { when, anchorBlock, nextDirectiveIndex } from './directives';\n\n/**\n * Conditional rendering with negated condition (opposite of when)\n * @param cond - Boolean condition to negate\n * @param children - Content to render when condition is false\n */\nexport function unless(cond: boolean, children: VNode | VNode[]): VNode {\n return when(!cond, children);\n}\n\n/**\n * Render content only if array/collection is empty\n * @param collection - Array or collection to check\n * @param children - Content to render when empty\n */\nexport function whenEmpty<T>(\n collection: T[] | null | undefined,\n children: VNode | VNode[],\n): VNode {\n const isEmpty = !collection || collection.length === 0;\n return when(isEmpty, children);\n}\n\n/**\n * Render content only if array/collection has items\n * @param collection - Array or collection to check\n * @param children - Content to render when not empty\n */\nexport function whenNotEmpty<T>(\n collection: T[] | null | undefined,\n children: VNode | VNode[],\n): VNode {\n const hasItems = Boolean(collection && collection.length > 0);\n return when(hasItems, children);\n}\n\n/**\n * Enhanced each with filtering capability\n * @param list - Array to iterate over\n * @param predicate - Filter function (optional)\n * @param render - Render function for each item\n */\nexport function eachWhere<T>(\n list: T[],\n predicate: (item: T, index: number) => boolean,\n render: (item: T, index: number, filteredIndex: number) => VNode | VNode[],\n): VNode[] {\n const filtered: Array<{ item: T; originalIndex: number }> = [];\n\n list.forEach((item, index) => {\n if (predicate(item, index)) {\n filtered.push({ item, originalIndex: index });\n }\n });\n\n return filtered.map(({ item, originalIndex }, filteredIndex) => {\n const itemKey =\n typeof item === 'object' && item != null\n ? ((item as Record<string, unknown>)?.key ??\n (item as Record<string, unknown>)?.id ??\n `filtered-${originalIndex}`)\n : `filtered-${originalIndex}`;\n\n return anchorBlock(\n render(item, originalIndex, filteredIndex),\n `each-where-${itemKey}`,\n );\n });\n}\n\n/**\n * Render different content based on array length\n * @param list - Array to check\n * @param cases - Object with length-based cases\n */\nexport function switchOnLength<T>(\n list: T[],\n cases: {\n empty?: VNode | VNode[];\n one?: (item: T) => VNode | VNode[];\n many?: (items: T[]) => VNode | VNode[];\n exactly?: { [count: number]: (items: T[]) => VNode | VNode[] };\n },\n): VNode {\n const si = nextDirectiveIndex();\n const length = list?.length ?? 0;\n\n if (length === 0 && cases.empty) {\n return anchorBlock(cases.empty, `switch-length-${si}-empty`);\n }\n\n if (length === 1 && cases.one) {\n return anchorBlock(cases.one(list[0]), `switch-length-${si}-one`);\n }\n\n if (cases.exactly?.[length]) {\n return anchorBlock(\n cases.exactly[length](list),\n `switch-length-${si}-${length}`,\n );\n }\n\n if (length > 1 && cases.many) {\n return anchorBlock(cases.many(list), `switch-length-${si}-many`);\n }\n\n return anchorBlock([], `switch-length-${si}-fallback`);\n}\n\n/**\n * Group array items and render each group\n * @param list - Array to group\n * @param groupBy - Function to determine group key\n * @param renderGroup - Function to render each group\n */\nexport function eachGroup<T, K extends string | number>(\n list: T[],\n groupBy: (item: T) => K,\n renderGroup: (groupKey: K, items: T[], groupIndex: number) => VNode | VNode[],\n): VNode[] {\n const groups = new Map<K, T[]>();\n\n list.forEach((item) => {\n const key = groupBy(item);\n if (!groups.has(key)) {\n groups.set(key, []);\n }\n groups.get(key)!.push(item);\n });\n\n return Array.from(groups.entries()).map(([groupKey, items], groupIndex) => {\n return anchorBlock(\n renderGroup(groupKey, items, groupIndex),\n `each-group-${groupKey}`,\n );\n });\n}\n\n/**\n * Render with pagination/chunking\n * @param list - Array to chunk\n * @param pageSize - Items per page/chunk\n * @param currentPage - Current page (0-based)\n * @param render - Render function for visible items\n */\nexport function eachPage<T>(\n list: T[],\n pageSize: number,\n currentPage: number,\n render: (item: T, index: number, pageIndex: number) => VNode | VNode[],\n): VNode[] {\n const startIndex = currentPage * pageSize;\n const endIndex = Math.min(startIndex + pageSize, list.length);\n const pageItems = list.slice(startIndex, endIndex);\n\n return pageItems.map((item, pageIndex) => {\n const globalIndex = startIndex + pageIndex;\n const itemKey =\n typeof item === 'object' && item != null\n ? ((item as Record<string, unknown>)?.key ??\n (item as Record<string, unknown>)?.id ??\n `page-${globalIndex}`)\n : `page-${globalIndex}`;\n\n return anchorBlock(\n render(item, globalIndex, pageIndex),\n `each-page-${itemKey}`,\n );\n });\n}\n\n/* --- Async & Loading State Directives --- */\n\n/**\n * Render content based on Promise state\n * @param promiseState - Object with loading, data, error states\n * @param cases - Render functions for each state\n */\nexport function switchOnPromise<T, E = Error>(\n promiseState: {\n loading?: boolean;\n data?: T;\n error?: E;\n },\n cases: {\n loading?: VNode | VNode[];\n success?: (data: T) => VNode | VNode[];\n error?: (error: E) => VNode | VNode[];\n idle?: VNode | VNode[];\n },\n): VNode {\n const si = nextDirectiveIndex();\n\n if (promiseState.loading && cases.loading) {\n return anchorBlock(cases.loading, `promise-${si}-loading`);\n }\n\n if (promiseState.error && cases.error) {\n return anchorBlock(cases.error(promiseState.error), `promise-${si}-error`);\n }\n\n if (promiseState.data !== undefined && cases.success) {\n return anchorBlock(\n cases.success(promiseState.data),\n `promise-${si}-success`,\n );\n }\n\n if (cases.idle) {\n return anchorBlock(cases.idle, `promise-${si}-idle`);\n }\n\n return anchorBlock([], `promise-${si}-fallback`);\n}\n\n/* --- Utility Directives --- */\n\n/**\n * Render content based on screen size/media query\n * @param mediaQuery - CSS media query string\n * @param children - Content to render when media query matches\n */\nexport function whenMedia(\n mediaQuery: string,\n children: VNode | VNode[],\n): VNode {\n const matches =\n typeof window !== 'undefined' && window.matchMedia?.(mediaQuery)?.matches;\n return when(Boolean(matches), children);\n}\n\n/* --- Responsive & Media Query Directives (aligned with style.ts) --- */\n\n/**\n * Media variants matching those in style.ts\n */\nexport const mediaVariants = {\n // Responsive breakpoints (matching style.ts)\n sm: '(min-width:640px)',\n md: '(min-width:768px)',\n lg: '(min-width:1024px)',\n xl: '(min-width:1280px)',\n '2xl': '(min-width:1536px)',\n\n // Dark mode (matching style.ts)\n dark: '(prefers-color-scheme: dark)',\n} as const;\n\n/**\n * Responsive order matching style.ts\n */\nexport const responsiveOrder = ['sm', 'md', 'lg', 'xl', '2xl'] as const;\n\n/**\n * Individual responsive directives matching the style.ts breakpoint system\n */\nexport const responsive = {\n // Breakpoint-based rendering (matching style.ts exactly)\n sm: (children: VNode | VNode[]) => whenMedia(mediaVariants.sm, children),\n md: (children: VNode | VNode[]) => whenMedia(mediaVariants.md, children),\n lg: (children: VNode | VNode[]) => whenMedia(mediaVariants.lg, children),\n xl: (children: VNode | VNode[]) => whenMedia(mediaVariants.xl, children),\n '2xl': (children: VNode | VNode[]) =>\n whenMedia(mediaVariants['2xl'], children),\n\n // Dark mode (matching style.ts)\n dark: (children: VNode | VNode[]) => whenMedia(mediaVariants.dark, children),\n light: (children: VNode | VNode[]) =>\n whenMedia('(prefers-color-scheme: light)', children),\n\n // Accessibility and interaction preferences\n touch: (children: VNode | VNode[]) =>\n whenMedia('(hover: none) and (pointer: coarse)', children),\n mouse: (children: VNode | VNode[]) =>\n whenMedia('(hover: hover) and (pointer: fine)', children),\n reducedMotion: (children: VNode | VNode[]) =>\n whenMedia('(prefers-reduced-motion: reduce)', children),\n highContrast: (children: VNode | VNode[]) =>\n whenMedia('(prefers-contrast: high)', children),\n\n // Orientation\n portrait: (children: VNode | VNode[]) =>\n whenMedia('(orientation: portrait)', children),\n landscape: (children: VNode | VNode[]) =>\n whenMedia('(orientation: landscape)', children),\n} as const;\n\n/**\n * Advanced responsive directive that matches the style.ts multi-variant processing\n * Allows chaining responsive and dark mode conditions like in CSS classes\n * @param variants - Array of variant keys (e.g., ['dark', 'lg'])\n * @param children - Content to render when all variants match\n */\nexport function whenVariants(\n variants: Array<keyof typeof mediaVariants | 'light'>,\n children: VNode | VNode[],\n): VNode {\n const conditions: string[] = [];\n\n // Process dark/light mode\n if (variants.includes('dark')) {\n conditions.push(mediaVariants.dark);\n } else if (variants.includes('light')) {\n conditions.push('(prefers-color-scheme: light)');\n }\n\n // Process responsive variants (take the last one, matching style.ts behavior)\n const responsiveVariants = variants.filter((v) =>\n responsiveOrder.includes(v as (typeof responsiveOrder)[number]),\n );\n const lastResponsive = responsiveVariants[responsiveVariants.length - 1];\n if (lastResponsive && lastResponsive in mediaVariants) {\n conditions.push(\n mediaVariants[lastResponsive as keyof typeof mediaVariants],\n );\n }\n\n const mediaQuery = conditions.length > 0 ? conditions.join(' and ') : 'all';\n return whenMedia(mediaQuery, children);\n}\n\n/**\n * Responsive switch directive - render different content for different breakpoints\n * Mirrors the responsive behavior from the style system\n * @param content - Object with breakpoint keys and corresponding content\n */\nexport function responsiveSwitch(content: {\n base?: VNode | VNode[];\n sm?: VNode | VNode[];\n md?: VNode | VNode[];\n lg?: VNode | VNode[];\n xl?: VNode | VNode[];\n '2xl'?: VNode | VNode[];\n}): VNode[] {\n const results: VNode[] = [];\n\n const si = nextDirectiveIndex();\n\n // Handle light mode variants\n if (content.base) {\n // Base content (no media query)\n results.push(anchorBlock(content.base, `responsive-${si}-base`));\n }\n\n // Add responsive variants in order\n responsiveOrder.forEach((breakpoint) => {\n const breakpointContent = content[breakpoint];\n if (breakpointContent) {\n results.push(responsive[breakpoint](breakpointContent));\n }\n });\n\n return results;\n}\n\n/* --- Enhanced Match Directive --- */\n\n/**\n * Enhanced match directive with more fluent API\n * @param value - Value to match against\n */\nexport function switchOn<T>(value: T) {\n const branches: Array<{\n condition: (val: T) => boolean;\n content: VNode | VNode[];\n }> = [];\n let otherwiseContent: VNode | VNode[] | null = null;\n\n return {\n case(matcher: T | ((val: T) => boolean), content: VNode | VNode[]) {\n const condition =\n typeof matcher === 'function'\n ? (matcher as (val: T) => boolean)\n : (val: T) => val === matcher;\n\n branches.push({ condition, content });\n return this;\n },\n\n when(predicate: (val: T) => boolean, content: VNode | VNode[]) {\n branches.push({ condition: predicate, content });\n return this;\n },\n\n otherwise(content: VNode | VNode[]) {\n otherwiseContent = content;\n return this;\n },\n\n done() {\n const si = nextDirectiveIndex();\n for (let i = 0; i < branches.length; i++) {\n const { condition, content } = branches[i];\n if (condition(value)) {\n return anchorBlock(content, `switch-on-${si}-case-${i}`);\n }\n }\n return anchorBlock(otherwiseContent || [], `switch-on-${si}-otherwise`);\n },\n };\n}\n"],"mappings":"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"}
@@ -1,138 +1,122 @@
1
- import { anchorBlock as s, nextDirectiveIndex as a, when as d } from "./custom-elements-runtime.directives.es.js";
2
- function $(n, e) {
3
- return d(!n, e);
1
+ import { anchorBlock as e, nextDirectiveIndex as t, when as n } from "./custom-elements-runtime.directives.es.js";
2
+ //#region src/lib/directive-enhancements.ts
3
+ function r(e, t) {
4
+ return n(!e, t);
4
5
  }
5
- function y(n, e) {
6
- return d(!n || n.length === 0, e);
6
+ function i(e, t) {
7
+ return n(!e || e.length === 0, t);
7
8
  }
8
- function x(n, e) {
9
- return d(!!(n && n.length > 0), e);
9
+ function a(e, t) {
10
+ return n(!!(e && e.length > 0), t);
10
11
  }
11
- function k(n, e, o) {
12
- const t = [];
13
- return n.forEach((r, i) => {
14
- e(r, i) && t.push({
15
- item: r,
16
- originalIndex: i
17
- });
18
- }), t.map(({ item: r, originalIndex: i }, c) => {
19
- const l = typeof r == "object" && r != null ? r?.key ?? r?.id ?? `filtered-${i}` : `filtered-${i}`;
20
- return s(o(r, i, c), `each-where-${l}`);
21
- });
12
+ function o(t, n, r) {
13
+ let i = [];
14
+ return t.forEach((e, t) => {
15
+ n(e, t) && i.push({
16
+ item: e,
17
+ originalIndex: t
18
+ });
19
+ }), i.map(({ item: t, originalIndex: n }, i) => {
20
+ let a = typeof t == "object" && t ? t?.key ?? t?.id ?? `filtered-${n}` : `filtered-${n}`;
21
+ return e(r(t, n, i), `each-where-${a}`);
22
+ });
22
23
  }
23
- function v(n, e) {
24
- const o = a(), t = n?.length ?? 0;
25
- return t === 0 && e.empty ? s(e.empty, `switch-length-${o}-empty`) : t === 1 && e.one ? s(e.one(n[0]), `switch-length-${o}-one`) : e.exactly?.[t] ? s(e.exactly[t](n), `switch-length-${o}-${t}`) : t > 1 && e.many ? s(e.many(n), `switch-length-${o}-many`) : s([], `switch-length-${o}-fallback`);
24
+ function s(n, r) {
25
+ let i = t(), a = n?.length ?? 0;
26
+ return a === 0 && r.empty ? e(r.empty, `switch-length-${i}-empty`) : a === 1 && r.one ? e(r.one(n[0]), `switch-length-${i}-one`) : r.exactly?.[a] ? e(r.exactly[a](n), `switch-length-${i}-${a}`) : a > 1 && r.many ? e(r.many(n), `switch-length-${i}-many`) : e([], `switch-length-${i}-fallback`);
26
27
  }
27
- function b(n, e, o) {
28
- const t = /* @__PURE__ */ new Map();
29
- return n.forEach((r) => {
30
- const i = e(r);
31
- t.has(i) || t.set(i, []), t.get(i).push(r);
32
- }), Array.from(t.entries()).map(([r, i], c) => s(o(r, i, c), `each-group-${r}`));
28
+ function c(t, n, r) {
29
+ let i = /* @__PURE__ */ new Map();
30
+ return t.forEach((e) => {
31
+ let t = n(e);
32
+ i.has(t) || i.set(t, []), i.get(t).push(e);
33
+ }), Array.from(i.entries()).map(([t, n], i) => e(r(t, n, i), `each-group-${t}`));
33
34
  }
34
- function E(n, e, o, t) {
35
- const r = o * e, i = Math.min(r + e, n.length);
36
- return n.slice(r, i).map((c, l) => {
37
- const f = r + l, g = typeof c == "object" && c != null ? c?.key ?? c?.id ?? `page-${f}` : `page-${f}`;
38
- return s(t(c, f, l), `each-page-${g}`);
39
- });
35
+ function l(t, n, r, i) {
36
+ let a = r * n, o = Math.min(a + n, t.length);
37
+ return t.slice(a, o).map((t, n) => {
38
+ let r = a + n, o = typeof t == "object" && t ? t?.key ?? t?.id ?? `page-${r}` : `page-${r}`;
39
+ return e(i(t, r, n), `each-page-${o}`);
40
+ });
40
41
  }
41
- function M(n, e) {
42
- const o = a();
43
- return n.loading && e.loading ? s(e.loading, `promise-${o}-loading`) : n.error && e.error ? s(e.error(n.error), `promise-${o}-error`) : n.data !== void 0 && e.success ? s(e.success(n.data), `promise-${o}-success`) : e.idle ? s(e.idle, `promise-${o}-idle`) : s([], `promise-${o}-fallback`);
42
+ function u(n, r) {
43
+ let i = t();
44
+ return n.loading && r.loading ? e(r.loading, `promise-${i}-loading`) : n.error && r.error ? e(r.error(n.error), `promise-${i}-error`) : n.data !== void 0 && r.success ? e(r.success(n.data), `promise-${i}-success`) : r.idle ? e(r.idle, `promise-${i}-idle`) : e([], `promise-${i}-fallback`);
44
45
  }
45
- function h(n, e) {
46
- const o = typeof window < "u" && window.matchMedia?.(n)?.matches;
47
- return d(!!o, e);
46
+ function d(e, t) {
47
+ return n(!!(typeof window < "u" && window.matchMedia?.(e)?.matches), t);
48
48
  }
49
- var u = {
50
- sm: "(min-width:640px)",
51
- md: "(min-width:768px)",
52
- lg: "(min-width:1024px)",
53
- xl: "(min-width:1280px)",
54
- "2xl": "(min-width:1536px)",
55
- dark: "(prefers-color-scheme: dark)"
49
+ var f = {
50
+ sm: "(min-width:640px)",
51
+ md: "(min-width:768px)",
52
+ lg: "(min-width:1024px)",
53
+ xl: "(min-width:1280px)",
54
+ "2xl": "(min-width:1536px)",
55
+ dark: "(prefers-color-scheme: dark)"
56
56
  }, p = [
57
- "sm",
58
- "md",
59
- "lg",
60
- "xl",
61
- "2xl"
62
- ], w = {
63
- sm: (n) => h(u.sm, n),
64
- md: (n) => h(u.md, n),
65
- lg: (n) => h(u.lg, n),
66
- xl: (n) => h(u.xl, n),
67
- "2xl": (n) => h(u["2xl"], n),
68
- dark: (n) => h(u.dark, n),
69
- light: (n) => h("(prefers-color-scheme: light)", n),
70
- touch: (n) => h("(hover: none) and (pointer: coarse)", n),
71
- mouse: (n) => h("(hover: hover) and (pointer: fine)", n),
72
- reducedMotion: (n) => h("(prefers-reduced-motion: reduce)", n),
73
- highContrast: (n) => h("(prefers-contrast: high)", n),
74
- portrait: (n) => h("(orientation: portrait)", n),
75
- landscape: (n) => h("(orientation: landscape)", n)
57
+ "sm",
58
+ "md",
59
+ "lg",
60
+ "xl",
61
+ "2xl"
62
+ ], m = {
63
+ sm: (e) => d(f.sm, e),
64
+ md: (e) => d(f.md, e),
65
+ lg: (e) => d(f.lg, e),
66
+ xl: (e) => d(f.xl, e),
67
+ "2xl": (e) => d(f["2xl"], e),
68
+ dark: (e) => d(f.dark, e),
69
+ light: (e) => d("(prefers-color-scheme: light)", e),
70
+ touch: (e) => d("(hover: none) and (pointer: coarse)", e),
71
+ mouse: (e) => d("(hover: hover) and (pointer: fine)", e),
72
+ reducedMotion: (e) => d("(prefers-reduced-motion: reduce)", e),
73
+ highContrast: (e) => d("(prefers-contrast: high)", e),
74
+ portrait: (e) => d("(orientation: portrait)", e),
75
+ landscape: (e) => d("(orientation: landscape)", e)
76
76
  };
77
- function O(n, e) {
78
- const o = [];
79
- n.includes("dark") ? o.push(u.dark) : n.includes("light") && o.push("(prefers-color-scheme: light)");
80
- const t = n.filter((i) => p.includes(i)), r = t[t.length - 1];
81
- return r && r in u && o.push(u[r]), h(o.length > 0 ? o.join(" and ") : "all", e);
77
+ function h(e, t) {
78
+ let n = [];
79
+ e.includes("dark") ? n.push(f.dark) : e.includes("light") && n.push("(prefers-color-scheme: light)");
80
+ let r = e.filter((e) => p.includes(e)), i = r[r.length - 1];
81
+ return i && i in f && n.push(f[i]), d(n.length > 0 ? n.join(" and ") : "all", t);
82
82
  }
83
- function j(n) {
84
- const e = [], o = a();
85
- return n.base && e.push(s(n.base, `responsive-${o}-base`)), p.forEach((t) => {
86
- const r = n[t];
87
- r && e.push(w[t](r));
88
- }), e;
83
+ function g(n) {
84
+ let r = [], i = t();
85
+ return n.base && r.push(e(n.base, `responsive-${i}-base`)), p.forEach((e) => {
86
+ let t = n[e];
87
+ t && r.push(m[e](t));
88
+ }), r;
89
89
  }
90
- function B(n) {
91
- const e = [];
92
- let o = null;
93
- return {
94
- case(t, r) {
95
- const i = typeof t == "function" ? t : (c) => c === t;
96
- return e.push({
97
- condition: i,
98
- content: r
99
- }), this;
100
- },
101
- when(t, r) {
102
- return e.push({
103
- condition: t,
104
- content: r
105
- }), this;
106
- },
107
- otherwise(t) {
108
- return o = t, this;
109
- },
110
- done() {
111
- const t = a();
112
- for (let r = 0; r < e.length; r++) {
113
- const { condition: i, content: c } = e[r];
114
- if (i(n)) return s(c, `switch-on-${t}-case-${r}`);
115
- }
116
- return s(o || [], `switch-on-${t}-otherwise`);
117
- }
118
- };
90
+ function _(n) {
91
+ let r = [], i = null;
92
+ return {
93
+ case(e, t) {
94
+ let n = typeof e == "function" ? e : (t) => t === e;
95
+ return r.push({
96
+ condition: n,
97
+ content: t
98
+ }), this;
99
+ },
100
+ when(e, t) {
101
+ return r.push({
102
+ condition: e,
103
+ content: t
104
+ }), this;
105
+ },
106
+ otherwise(e) {
107
+ return i = e, this;
108
+ },
109
+ done() {
110
+ let a = t();
111
+ for (let t = 0; t < r.length; t++) {
112
+ let { condition: i, content: o } = r[t];
113
+ if (i(n)) return e(o, `switch-on-${a}-case-${t}`);
114
+ }
115
+ return e(i || [], `switch-on-${a}-otherwise`);
116
+ }
117
+ };
119
118
  }
120
- export {
121
- b as eachGroup,
122
- E as eachPage,
123
- k as eachWhere,
124
- u as mediaVariants,
125
- w as responsive,
126
- p as responsiveOrder,
127
- j as responsiveSwitch,
128
- B as switchOn,
129
- v as switchOnLength,
130
- M as switchOnPromise,
131
- $ as unless,
132
- y as whenEmpty,
133
- h as whenMedia,
134
- x as whenNotEmpty,
135
- O as whenVariants
136
- };
119
+ //#endregion
120
+ export { c as eachGroup, l as eachPage, o as eachWhere, f as mediaVariants, m as responsive, p as responsiveOrder, g as responsiveSwitch, _ as switchOn, s as switchOnLength, u as switchOnPromise, r as unless, i as whenEmpty, d as whenMedia, a as whenNotEmpty, h as whenVariants };
137
121
 
138
122
  //# sourceMappingURL=custom-elements-runtime.directive-enhancements.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"custom-elements-runtime.directive-enhancements.es.js","names":[],"sources":["../src/lib/directive-enhancements.ts"],"sourcesContent":["// Enhanced collection directives for better developer experience\n\nimport type { VNode } from './runtime/types';\nimport { when, anchorBlock, nextDirectiveIndex } from './directives';\n\n/**\n * Conditional rendering with negated condition (opposite of when)\n * @param cond - Boolean condition to negate\n * @param children - Content to render when condition is false\n */\nexport function unless(cond: boolean, children: VNode | VNode[]): VNode {\n return when(!cond, children);\n}\n\n/**\n * Render content only if array/collection is empty\n * @param collection - Array or collection to check\n * @param children - Content to render when empty\n */\nexport function whenEmpty<T>(\n collection: T[] | null | undefined,\n children: VNode | VNode[],\n): VNode {\n const isEmpty = !collection || collection.length === 0;\n return when(isEmpty, children);\n}\n\n/**\n * Render content only if array/collection has items\n * @param collection - Array or collection to check\n * @param children - Content to render when not empty\n */\nexport function whenNotEmpty<T>(\n collection: T[] | null | undefined,\n children: VNode | VNode[],\n): VNode {\n const hasItems = Boolean(collection && collection.length > 0);\n return when(hasItems, children);\n}\n\n/**\n * Enhanced each with filtering capability\n * @param list - Array to iterate over\n * @param predicate - Filter function (optional)\n * @param render - Render function for each item\n */\nexport function eachWhere<T>(\n list: T[],\n predicate: (item: T, index: number) => boolean,\n render: (item: T, index: number, filteredIndex: number) => VNode | VNode[],\n): VNode[] {\n const filtered: Array<{ item: T; originalIndex: number }> = [];\n\n list.forEach((item, index) => {\n if (predicate(item, index)) {\n filtered.push({ item, originalIndex: index });\n }\n });\n\n return filtered.map(({ item, originalIndex }, filteredIndex) => {\n const itemKey =\n typeof item === 'object' && item != null\n ? ((item as Record<string, unknown>)?.key ??\n (item as Record<string, unknown>)?.id ??\n `filtered-${originalIndex}`)\n : `filtered-${originalIndex}`;\n\n return anchorBlock(\n render(item, originalIndex, filteredIndex),\n `each-where-${itemKey}`,\n );\n });\n}\n\n/**\n * Render different content based on array length\n * @param list - Array to check\n * @param cases - Object with length-based cases\n */\nexport function switchOnLength<T>(\n list: T[],\n cases: {\n empty?: VNode | VNode[];\n one?: (item: T) => VNode | VNode[];\n many?: (items: T[]) => VNode | VNode[];\n exactly?: { [count: number]: (items: T[]) => VNode | VNode[] };\n },\n): VNode {\n const si = nextDirectiveIndex();\n const length = list?.length ?? 0;\n\n if (length === 0 && cases.empty) {\n return anchorBlock(cases.empty, `switch-length-${si}-empty`);\n }\n\n if (length === 1 && cases.one) {\n return anchorBlock(cases.one(list[0]), `switch-length-${si}-one`);\n }\n\n if (cases.exactly?.[length]) {\n return anchorBlock(\n cases.exactly[length](list),\n `switch-length-${si}-${length}`,\n );\n }\n\n if (length > 1 && cases.many) {\n return anchorBlock(cases.many(list), `switch-length-${si}-many`);\n }\n\n return anchorBlock([], `switch-length-${si}-fallback`);\n}\n\n/**\n * Group array items and render each group\n * @param list - Array to group\n * @param groupBy - Function to determine group key\n * @param renderGroup - Function to render each group\n */\nexport function eachGroup<T, K extends string | number>(\n list: T[],\n groupBy: (item: T) => K,\n renderGroup: (groupKey: K, items: T[], groupIndex: number) => VNode | VNode[],\n): VNode[] {\n const groups = new Map<K, T[]>();\n\n list.forEach((item) => {\n const key = groupBy(item);\n if (!groups.has(key)) {\n groups.set(key, []);\n }\n groups.get(key)!.push(item);\n });\n\n return Array.from(groups.entries()).map(([groupKey, items], groupIndex) => {\n return anchorBlock(\n renderGroup(groupKey, items, groupIndex),\n `each-group-${groupKey}`,\n );\n });\n}\n\n/**\n * Render with pagination/chunking\n * @param list - Array to chunk\n * @param pageSize - Items per page/chunk\n * @param currentPage - Current page (0-based)\n * @param render - Render function for visible items\n */\nexport function eachPage<T>(\n list: T[],\n pageSize: number,\n currentPage: number,\n render: (item: T, index: number, pageIndex: number) => VNode | VNode[],\n): VNode[] {\n const startIndex = currentPage * pageSize;\n const endIndex = Math.min(startIndex + pageSize, list.length);\n const pageItems = list.slice(startIndex, endIndex);\n\n return pageItems.map((item, pageIndex) => {\n const globalIndex = startIndex + pageIndex;\n const itemKey =\n typeof item === 'object' && item != null\n ? ((item as Record<string, unknown>)?.key ??\n (item as Record<string, unknown>)?.id ??\n `page-${globalIndex}`)\n : `page-${globalIndex}`;\n\n return anchorBlock(\n render(item, globalIndex, pageIndex),\n `each-page-${itemKey}`,\n );\n });\n}\n\n/* --- Async & Loading State Directives --- */\n\n/**\n * Render content based on Promise state\n * @param promiseState - Object with loading, data, error states\n * @param cases - Render functions for each state\n */\nexport function switchOnPromise<T, E = Error>(\n promiseState: {\n loading?: boolean;\n data?: T;\n error?: E;\n },\n cases: {\n loading?: VNode | VNode[];\n success?: (data: T) => VNode | VNode[];\n error?: (error: E) => VNode | VNode[];\n idle?: VNode | VNode[];\n },\n): VNode {\n const si = nextDirectiveIndex();\n\n if (promiseState.loading && cases.loading) {\n return anchorBlock(cases.loading, `promise-${si}-loading`);\n }\n\n if (promiseState.error && cases.error) {\n return anchorBlock(cases.error(promiseState.error), `promise-${si}-error`);\n }\n\n if (promiseState.data !== undefined && cases.success) {\n return anchorBlock(\n cases.success(promiseState.data),\n `promise-${si}-success`,\n );\n }\n\n if (cases.idle) {\n return anchorBlock(cases.idle, `promise-${si}-idle`);\n }\n\n return anchorBlock([], `promise-${si}-fallback`);\n}\n\n/* --- Utility Directives --- */\n\n/**\n * Render content based on screen size/media query\n * @param mediaQuery - CSS media query string\n * @param children - Content to render when media query matches\n */\nexport function whenMedia(\n mediaQuery: string,\n children: VNode | VNode[],\n): VNode {\n const matches =\n typeof window !== 'undefined' && window.matchMedia?.(mediaQuery)?.matches;\n return when(Boolean(matches), children);\n}\n\n/* --- Responsive & Media Query Directives (aligned with style.ts) --- */\n\n/**\n * Media variants matching those in style.ts\n */\nexport const mediaVariants = {\n // Responsive breakpoints (matching style.ts)\n sm: '(min-width:640px)',\n md: '(min-width:768px)',\n lg: '(min-width:1024px)',\n xl: '(min-width:1280px)',\n '2xl': '(min-width:1536px)',\n\n // Dark mode (matching style.ts)\n dark: '(prefers-color-scheme: dark)',\n} as const;\n\n/**\n * Responsive order matching style.ts\n */\nexport const responsiveOrder = ['sm', 'md', 'lg', 'xl', '2xl'] as const;\n\n/**\n * Individual responsive directives matching the style.ts breakpoint system\n */\nexport const responsive = {\n // Breakpoint-based rendering (matching style.ts exactly)\n sm: (children: VNode | VNode[]) => whenMedia(mediaVariants.sm, children),\n md: (children: VNode | VNode[]) => whenMedia(mediaVariants.md, children),\n lg: (children: VNode | VNode[]) => whenMedia(mediaVariants.lg, children),\n xl: (children: VNode | VNode[]) => whenMedia(mediaVariants.xl, children),\n '2xl': (children: VNode | VNode[]) =>\n whenMedia(mediaVariants['2xl'], children),\n\n // Dark mode (matching style.ts)\n dark: (children: VNode | VNode[]) => whenMedia(mediaVariants.dark, children),\n light: (children: VNode | VNode[]) =>\n whenMedia('(prefers-color-scheme: light)', children),\n\n // Accessibility and interaction preferences\n touch: (children: VNode | VNode[]) =>\n whenMedia('(hover: none) and (pointer: coarse)', children),\n mouse: (children: VNode | VNode[]) =>\n whenMedia('(hover: hover) and (pointer: fine)', children),\n reducedMotion: (children: VNode | VNode[]) =>\n whenMedia('(prefers-reduced-motion: reduce)', children),\n highContrast: (children: VNode | VNode[]) =>\n whenMedia('(prefers-contrast: high)', children),\n\n // Orientation\n portrait: (children: VNode | VNode[]) =>\n whenMedia('(orientation: portrait)', children),\n landscape: (children: VNode | VNode[]) =>\n whenMedia('(orientation: landscape)', children),\n} as const;\n\n/**\n * Advanced responsive directive that matches the style.ts multi-variant processing\n * Allows chaining responsive and dark mode conditions like in CSS classes\n * @param variants - Array of variant keys (e.g., ['dark', 'lg'])\n * @param children - Content to render when all variants match\n */\nexport function whenVariants(\n variants: Array<keyof typeof mediaVariants | 'light'>,\n children: VNode | VNode[],\n): VNode {\n const conditions: string[] = [];\n\n // Process dark/light mode\n if (variants.includes('dark')) {\n conditions.push(mediaVariants.dark);\n } else if (variants.includes('light')) {\n conditions.push('(prefers-color-scheme: light)');\n }\n\n // Process responsive variants (take the last one, matching style.ts behavior)\n const responsiveVariants = variants.filter((v) =>\n responsiveOrder.includes(v as (typeof responsiveOrder)[number]),\n );\n const lastResponsive = responsiveVariants[responsiveVariants.length - 1];\n if (lastResponsive && lastResponsive in mediaVariants) {\n conditions.push(\n mediaVariants[lastResponsive as keyof typeof mediaVariants],\n );\n }\n\n const mediaQuery = conditions.length > 0 ? conditions.join(' and ') : 'all';\n return whenMedia(mediaQuery, children);\n}\n\n/**\n * Responsive switch directive - render different content for different breakpoints\n * Mirrors the responsive behavior from the style system\n * @param content - Object with breakpoint keys and corresponding content\n */\nexport function responsiveSwitch(content: {\n base?: VNode | VNode[];\n sm?: VNode | VNode[];\n md?: VNode | VNode[];\n lg?: VNode | VNode[];\n xl?: VNode | VNode[];\n '2xl'?: VNode | VNode[];\n}): VNode[] {\n const results: VNode[] = [];\n\n const si = nextDirectiveIndex();\n\n // Handle light mode variants\n if (content.base) {\n // Base content (no media query)\n results.push(anchorBlock(content.base, `responsive-${si}-base`));\n }\n\n // Add responsive variants in order\n responsiveOrder.forEach((breakpoint) => {\n const breakpointContent = content[breakpoint];\n if (breakpointContent) {\n results.push(responsive[breakpoint](breakpointContent));\n }\n });\n\n return results;\n}\n\n/* --- Enhanced Match Directive --- */\n\n/**\n * Enhanced match directive with more fluent API\n * @param value - Value to match against\n */\nexport function switchOn<T>(value: T) {\n const branches: Array<{\n condition: (val: T) => boolean;\n content: VNode | VNode[];\n }> = [];\n let otherwiseContent: VNode | VNode[] | null = null;\n\n return {\n case(matcher: T | ((val: T) => boolean), content: VNode | VNode[]) {\n const condition =\n typeof matcher === 'function'\n ? (matcher as (val: T) => boolean)\n : (val: T) => val === matcher;\n\n branches.push({ condition, content });\n return this;\n },\n\n when(predicate: (val: T) => boolean, content: VNode | VNode[]) {\n branches.push({ condition: predicate, content });\n return this;\n },\n\n otherwise(content: VNode | VNode[]) {\n otherwiseContent = content;\n return this;\n },\n\n done() {\n const si = nextDirectiveIndex();\n for (let i = 0; i < branches.length; i++) {\n const { condition, content } = branches[i];\n if (condition(value)) {\n return anchorBlock(content, `switch-on-${si}-case-${i}`);\n }\n }\n return anchorBlock(otherwiseContent || [], `switch-on-${si}-otherwise`);\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"custom-elements-runtime.directive-enhancements.es.js","names":[],"sources":["../src/lib/directive-enhancements.ts"],"sourcesContent":["// Enhanced collection directives for better developer experience\n\nimport type { VNode } from './runtime/types';\nimport { when, anchorBlock, nextDirectiveIndex } from './directives';\n\n/**\n * Conditional rendering with negated condition (opposite of when)\n * @param cond - Boolean condition to negate\n * @param children - Content to render when condition is false\n */\nexport function unless(cond: boolean, children: VNode | VNode[]): VNode {\n return when(!cond, children);\n}\n\n/**\n * Render content only if array/collection is empty\n * @param collection - Array or collection to check\n * @param children - Content to render when empty\n */\nexport function whenEmpty<T>(\n collection: T[] | null | undefined,\n children: VNode | VNode[],\n): VNode {\n const isEmpty = !collection || collection.length === 0;\n return when(isEmpty, children);\n}\n\n/**\n * Render content only if array/collection has items\n * @param collection - Array or collection to check\n * @param children - Content to render when not empty\n */\nexport function whenNotEmpty<T>(\n collection: T[] | null | undefined,\n children: VNode | VNode[],\n): VNode {\n const hasItems = Boolean(collection && collection.length > 0);\n return when(hasItems, children);\n}\n\n/**\n * Enhanced each with filtering capability\n * @param list - Array to iterate over\n * @param predicate - Filter function (optional)\n * @param render - Render function for each item\n */\nexport function eachWhere<T>(\n list: T[],\n predicate: (item: T, index: number) => boolean,\n render: (item: T, index: number, filteredIndex: number) => VNode | VNode[],\n): VNode[] {\n const filtered: Array<{ item: T; originalIndex: number }> = [];\n\n list.forEach((item, index) => {\n if (predicate(item, index)) {\n filtered.push({ item, originalIndex: index });\n }\n });\n\n return filtered.map(({ item, originalIndex }, filteredIndex) => {\n const itemKey =\n typeof item === 'object' && item != null\n ? ((item as Record<string, unknown>)?.key ??\n (item as Record<string, unknown>)?.id ??\n `filtered-${originalIndex}`)\n : `filtered-${originalIndex}`;\n\n return anchorBlock(\n render(item, originalIndex, filteredIndex),\n `each-where-${itemKey}`,\n );\n });\n}\n\n/**\n * Render different content based on array length\n * @param list - Array to check\n * @param cases - Object with length-based cases\n */\nexport function switchOnLength<T>(\n list: T[],\n cases: {\n empty?: VNode | VNode[];\n one?: (item: T) => VNode | VNode[];\n many?: (items: T[]) => VNode | VNode[];\n exactly?: { [count: number]: (items: T[]) => VNode | VNode[] };\n },\n): VNode {\n const si = nextDirectiveIndex();\n const length = list?.length ?? 0;\n\n if (length === 0 && cases.empty) {\n return anchorBlock(cases.empty, `switch-length-${si}-empty`);\n }\n\n if (length === 1 && cases.one) {\n return anchorBlock(cases.one(list[0]), `switch-length-${si}-one`);\n }\n\n if (cases.exactly?.[length]) {\n return anchorBlock(\n cases.exactly[length](list),\n `switch-length-${si}-${length}`,\n );\n }\n\n if (length > 1 && cases.many) {\n return anchorBlock(cases.many(list), `switch-length-${si}-many`);\n }\n\n return anchorBlock([], `switch-length-${si}-fallback`);\n}\n\n/**\n * Group array items and render each group\n * @param list - Array to group\n * @param groupBy - Function to determine group key\n * @param renderGroup - Function to render each group\n */\nexport function eachGroup<T, K extends string | number>(\n list: T[],\n groupBy: (item: T) => K,\n renderGroup: (groupKey: K, items: T[], groupIndex: number) => VNode | VNode[],\n): VNode[] {\n const groups = new Map<K, T[]>();\n\n list.forEach((item) => {\n const key = groupBy(item);\n if (!groups.has(key)) {\n groups.set(key, []);\n }\n groups.get(key)!.push(item);\n });\n\n return Array.from(groups.entries()).map(([groupKey, items], groupIndex) => {\n return anchorBlock(\n renderGroup(groupKey, items, groupIndex),\n `each-group-${groupKey}`,\n );\n });\n}\n\n/**\n * Render with pagination/chunking\n * @param list - Array to chunk\n * @param pageSize - Items per page/chunk\n * @param currentPage - Current page (0-based)\n * @param render - Render function for visible items\n */\nexport function eachPage<T>(\n list: T[],\n pageSize: number,\n currentPage: number,\n render: (item: T, index: number, pageIndex: number) => VNode | VNode[],\n): VNode[] {\n const startIndex = currentPage * pageSize;\n const endIndex = Math.min(startIndex + pageSize, list.length);\n const pageItems = list.slice(startIndex, endIndex);\n\n return pageItems.map((item, pageIndex) => {\n const globalIndex = startIndex + pageIndex;\n const itemKey =\n typeof item === 'object' && item != null\n ? ((item as Record<string, unknown>)?.key ??\n (item as Record<string, unknown>)?.id ??\n `page-${globalIndex}`)\n : `page-${globalIndex}`;\n\n return anchorBlock(\n render(item, globalIndex, pageIndex),\n `each-page-${itemKey}`,\n );\n });\n}\n\n/* --- Async & Loading State Directives --- */\n\n/**\n * Render content based on Promise state\n * @param promiseState - Object with loading, data, error states\n * @param cases - Render functions for each state\n */\nexport function switchOnPromise<T, E = Error>(\n promiseState: {\n loading?: boolean;\n data?: T;\n error?: E;\n },\n cases: {\n loading?: VNode | VNode[];\n success?: (data: T) => VNode | VNode[];\n error?: (error: E) => VNode | VNode[];\n idle?: VNode | VNode[];\n },\n): VNode {\n const si = nextDirectiveIndex();\n\n if (promiseState.loading && cases.loading) {\n return anchorBlock(cases.loading, `promise-${si}-loading`);\n }\n\n if (promiseState.error && cases.error) {\n return anchorBlock(cases.error(promiseState.error), `promise-${si}-error`);\n }\n\n if (promiseState.data !== undefined && cases.success) {\n return anchorBlock(\n cases.success(promiseState.data),\n `promise-${si}-success`,\n );\n }\n\n if (cases.idle) {\n return anchorBlock(cases.idle, `promise-${si}-idle`);\n }\n\n return anchorBlock([], `promise-${si}-fallback`);\n}\n\n/* --- Utility Directives --- */\n\n/**\n * Render content based on screen size/media query\n * @param mediaQuery - CSS media query string\n * @param children - Content to render when media query matches\n */\nexport function whenMedia(\n mediaQuery: string,\n children: VNode | VNode[],\n): VNode {\n const matches =\n typeof window !== 'undefined' && window.matchMedia?.(mediaQuery)?.matches;\n return when(Boolean(matches), children);\n}\n\n/* --- Responsive & Media Query Directives (aligned with style.ts) --- */\n\n/**\n * Media variants matching those in style.ts\n */\nexport const mediaVariants = {\n // Responsive breakpoints (matching style.ts)\n sm: '(min-width:640px)',\n md: '(min-width:768px)',\n lg: '(min-width:1024px)',\n xl: '(min-width:1280px)',\n '2xl': '(min-width:1536px)',\n\n // Dark mode (matching style.ts)\n dark: '(prefers-color-scheme: dark)',\n} as const;\n\n/**\n * Responsive order matching style.ts\n */\nexport const responsiveOrder = ['sm', 'md', 'lg', 'xl', '2xl'] as const;\n\n/**\n * Individual responsive directives matching the style.ts breakpoint system\n */\nexport const responsive = {\n // Breakpoint-based rendering (matching style.ts exactly)\n sm: (children: VNode | VNode[]) => whenMedia(mediaVariants.sm, children),\n md: (children: VNode | VNode[]) => whenMedia(mediaVariants.md, children),\n lg: (children: VNode | VNode[]) => whenMedia(mediaVariants.lg, children),\n xl: (children: VNode | VNode[]) => whenMedia(mediaVariants.xl, children),\n '2xl': (children: VNode | VNode[]) =>\n whenMedia(mediaVariants['2xl'], children),\n\n // Dark mode (matching style.ts)\n dark: (children: VNode | VNode[]) => whenMedia(mediaVariants.dark, children),\n light: (children: VNode | VNode[]) =>\n whenMedia('(prefers-color-scheme: light)', children),\n\n // Accessibility and interaction preferences\n touch: (children: VNode | VNode[]) =>\n whenMedia('(hover: none) and (pointer: coarse)', children),\n mouse: (children: VNode | VNode[]) =>\n whenMedia('(hover: hover) and (pointer: fine)', children),\n reducedMotion: (children: VNode | VNode[]) =>\n whenMedia('(prefers-reduced-motion: reduce)', children),\n highContrast: (children: VNode | VNode[]) =>\n whenMedia('(prefers-contrast: high)', children),\n\n // Orientation\n portrait: (children: VNode | VNode[]) =>\n whenMedia('(orientation: portrait)', children),\n landscape: (children: VNode | VNode[]) =>\n whenMedia('(orientation: landscape)', children),\n} as const;\n\n/**\n * Advanced responsive directive that matches the style.ts multi-variant processing\n * Allows chaining responsive and dark mode conditions like in CSS classes\n * @param variants - Array of variant keys (e.g., ['dark', 'lg'])\n * @param children - Content to render when all variants match\n */\nexport function whenVariants(\n variants: Array<keyof typeof mediaVariants | 'light'>,\n children: VNode | VNode[],\n): VNode {\n const conditions: string[] = [];\n\n // Process dark/light mode\n if (variants.includes('dark')) {\n conditions.push(mediaVariants.dark);\n } else if (variants.includes('light')) {\n conditions.push('(prefers-color-scheme: light)');\n }\n\n // Process responsive variants (take the last one, matching style.ts behavior)\n const responsiveVariants = variants.filter((v) =>\n responsiveOrder.includes(v as (typeof responsiveOrder)[number]),\n );\n const lastResponsive = responsiveVariants[responsiveVariants.length - 1];\n if (lastResponsive && lastResponsive in mediaVariants) {\n conditions.push(\n mediaVariants[lastResponsive as keyof typeof mediaVariants],\n );\n }\n\n const mediaQuery = conditions.length > 0 ? conditions.join(' and ') : 'all';\n return whenMedia(mediaQuery, children);\n}\n\n/**\n * Responsive switch directive - render different content for different breakpoints\n * Mirrors the responsive behavior from the style system\n * @param content - Object with breakpoint keys and corresponding content\n */\nexport function responsiveSwitch(content: {\n base?: VNode | VNode[];\n sm?: VNode | VNode[];\n md?: VNode | VNode[];\n lg?: VNode | VNode[];\n xl?: VNode | VNode[];\n '2xl'?: VNode | VNode[];\n}): VNode[] {\n const results: VNode[] = [];\n\n const si = nextDirectiveIndex();\n\n // Handle light mode variants\n if (content.base) {\n // Base content (no media query)\n results.push(anchorBlock(content.base, `responsive-${si}-base`));\n }\n\n // Add responsive variants in order\n responsiveOrder.forEach((breakpoint) => {\n const breakpointContent = content[breakpoint];\n if (breakpointContent) {\n results.push(responsive[breakpoint](breakpointContent));\n }\n });\n\n return results;\n}\n\n/* --- Enhanced Match Directive --- */\n\n/**\n * Enhanced match directive with more fluent API\n * @param value - Value to match against\n */\nexport function switchOn<T>(value: T) {\n const branches: Array<{\n condition: (val: T) => boolean;\n content: VNode | VNode[];\n }> = [];\n let otherwiseContent: VNode | VNode[] | null = null;\n\n return {\n case(matcher: T | ((val: T) => boolean), content: VNode | VNode[]) {\n const condition =\n typeof matcher === 'function'\n ? (matcher as (val: T) => boolean)\n : (val: T) => val === matcher;\n\n branches.push({ condition, content });\n return this;\n },\n\n when(predicate: (val: T) => boolean, content: VNode | VNode[]) {\n branches.push({ condition: predicate, content });\n return this;\n },\n\n otherwise(content: VNode | VNode[]) {\n otherwiseContent = content;\n return this;\n },\n\n done() {\n const si = nextDirectiveIndex();\n for (let i = 0; i < branches.length; i++) {\n const { condition, content } = branches[i];\n if (condition(value)) {\n return anchorBlock(content, `switch-on-${si}-case-${i}`);\n }\n }\n return anchorBlock(otherwiseContent || [], `switch-on-${si}-otherwise`);\n },\n };\n}\n"],"mappings":"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"}
@@ -1,3 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var u="",i=0,h=[];function y(){u="",i=0,h.length=0}function d(){return i++}function f(n){const t=i++;return n!==void 0?n:u?`${u}.${t}`:`when-block-${t}`}function s(n){h.push([u,i]),u=n,i=0}function l(){const n=h[h.length-1];n&&(h.length--,[u,i]=n)}function v(n,t,e){const r=f(e);if(typeof t!="function")return o(n?t:[],r);if(!n)return o([],r);s(r);const c=t();return l(),o(c,r)}function $(n,t){return n.map((e,r)=>{const c=typeof e=="object"?e?.key??e?.id??`idx-${r}`:String(e);return o(t(e,r),`each-${c}`)})}function g(){const n=[];return{when(t,e){return n.push([t,e]),this},otherwise(t){return n.push([!0,t]),this},done(){const t=`match-${f()}`;for(let e=0;e<n.length;e++){const[r,c]=n[e];if(r){const a=`${t}-branch-${e}`;if(typeof c=="function"){s(a);const p=c();return l(),[o(p,a)]}return[o(c,a)]}}return[o([],`${t}-empty`)]}}}function o(n,t){return{tag:"#anchor",key:t,children:n?Array.isArray(n)?n.filter(e=>e!=null):[n].filter(e=>e!=null):[]}}exports.anchorBlock=o;exports.each=$;exports.match=g;exports.nextDirectiveIndex=d;exports.resetWhenCounter=y;exports.when=v;
2
-
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=``,t=0,n=[];function r(){e=``,t=0,n.length=0}function i(){return t++}function a(n){let r=t++;return n===void 0?e?`${e}.${r}`:`when-block-${r}`:n}function o(r){n.push([e,t]),e=r,t=0}function s(){let r=n[n.length-1];r&&(n.length--,[e,t]=r)}function c(e,t,n){let r=a(n);if(typeof t!=`function`)return d(e?t:[],r);if(!e)return d([],r);o(r);let i=t();return s(),d(i,r)}function l(e,t){return e.map((e,n)=>{let r=typeof e==`object`?e?.key??e?.id??`idx-${n}`:String(e);return d(t(e,n),`each-${r}`)})}function u(){let e=[];return{when(t,n){return e.push([t,n]),this},otherwise(t){return e.push([!0,t]),this},done(){let t=`match-${a()}`;for(let n=0;n<e.length;n++){let[r,i]=e[n];if(r){let e=`${t}-branch-${n}`;if(typeof i==`function`){o(e);let t=i();return s(),[d(t,e)]}return[d(i,e)]}}return[d([],`${t}-empty`)]}}}function d(e,t){return{tag:`#anchor`,key:t,children:e?Array.isArray(e)?e.filter(e=>e!=null):[e].filter(e=>e!=null):[]}}exports.anchorBlock=d,exports.each=l,exports.match=u,exports.nextDirectiveIndex=i,exports.resetWhenCounter=r,exports.when=c;
3
2
  //# sourceMappingURL=custom-elements-runtime.directives.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"custom-elements-runtime.directives.cjs.js","names":[],"sources":["../src/lib/directives.ts"],"sourcesContent":["import type { VNode } from './runtime/types';\n\n// ── Per-render directive scope tracking ─────────────────────────────────────\n//\n// A FLAT counter (index++) breaks when a when() factory itself contains more\n// when() calls: those inner calls consume counter slots, causing SUBSEQUENT\n// SIBLING when() calls to get a different index depending on whether the factory\n// ran. For example:\n//\n// when(A, () => { when(B); when(C); }) // ← factory may or may not run\n// when(D) // ← index shifts when factory runs\n//\n// The fix: each when() call claims its own slot (stable regardless of whether\n// the factory runs), then ENTERS a new child scope for the factory. Inner\n// when() calls consume indices in that child scope, never bleeding into the\n// sibling counter of the outer scope.\n//\n// Key format: root sibling 0 → \"when-block-0\"\n// child of \"when-block-0\" at pos 1 → \"when-block-0.1\"\n// grandchild → \"when-block-0.1.0\" etc.\n\n/** Current scope's parent prefix (empty string = root scope). */\nlet _scopeParent = '';\n/** Next sibling index inside the current scope. */\nlet _scopeIndex = 0;\n/** Stack of [parentPrefix, siblingIndex] for nested scopes. */\nconst _scopeStack: Array<readonly [string, number]> = [];\n\n/**\n * Reset all scope state at the start of each component render pass.\n * Called automatically by the component renderer — not needed in user code.\n * @internal\n */\nexport function resetWhenCounter(): void {\n _scopeParent = '';\n _scopeIndex = 0;\n _scopeStack.length = 0;\n}\n\n/**\n * Claim the next directive call index within the current scope.\n * Used by directive-enhancements.ts for non-when() directives (switchOnLength,\n * switchOnPromise, etc.) that need a stable unique number per call site.\n * @internal\n */\nexport function nextDirectiveIndex(): number {\n return _scopeIndex++;\n}\n\n/** Claim the next slot in the current scope and return its anchor key. */\nfunction claimKey(explicitKey?: string): string {\n const idx = _scopeIndex++;\n if (explicitKey !== undefined) return explicitKey;\n return _scopeParent ? `${_scopeParent}.${idx}` : `when-block-${idx}`;\n}\n\n/** Push a new child scope keyed under `anchorKey`. */\nfunction enterScope(anchorKey: string): void {\n _scopeStack.push([_scopeParent, _scopeIndex] as const);\n _scopeParent = anchorKey;\n _scopeIndex = 0;\n}\n\n/** Pop back to the parent scope. */\nfunction exitScope(): void {\n const top = _scopeStack[_scopeStack.length - 1];\n if (top) {\n _scopeStack.length--;\n [_scopeParent, _scopeIndex] = top;\n }\n}\n\n/* --- When --- */\nexport function when(\n cond: boolean,\n children: VNode | VNode[],\n key?: string,\n): VNode;\nexport function when(\n cond: boolean,\n factory: () => VNode | VNode[],\n key?: string,\n): VNode;\nexport function when(\n cond: boolean,\n childrenOrFactory: VNode | VNode[] | (() => VNode | VNode[]),\n key?: string,\n): VNode {\n // Claim this call's position BEFORE potentially entering a child scope.\n // This guarantees sibling when() calls always get the same index regardless\n // of whether a factory executes and how many when() calls it contains.\n const anchorKey = claimKey(key);\n\n if (typeof childrenOrFactory !== 'function') {\n return anchorBlock(cond ? childrenOrFactory : [], anchorKey);\n }\n\n if (!cond) {\n return anchorBlock([], anchorKey);\n }\n\n // Run the factory in a child scope so its inner when() calls don't\n // affect the sibling counter of the outer scope.\n enterScope(anchorKey);\n const children = childrenOrFactory();\n exitScope();\n return anchorBlock(children, anchorKey);\n}\n\n/* --- Each --- */\nexport function each<\n T extends string | number | boolean | { id?: string | number; key?: string },\n>(list: T[], render: (item: T, index: number) => VNode | VNode[]): VNode[] {\n return list.map((item, i) => {\n // For primitives, use value as key; for objects, prefer key/id\n const itemKey =\n typeof item === 'object'\n ? ((item as Record<string, unknown>)?.key ??\n (item as Record<string, unknown>)?.id ??\n `idx-${i}`)\n : String(item);\n return anchorBlock(render(item, i), `each-${itemKey}`);\n });\n}\n\n/* --- match --- */\ntype Branch = [\n condition: unknown,\n content: VNode | VNode[] | (() => VNode | VNode[]),\n];\n\nexport function match() {\n const branches: Branch[] = [];\n return {\n when(cond: unknown, content: VNode | VNode[] | (() => VNode | VNode[])) {\n branches.push([cond, content]);\n return this;\n },\n otherwise(content: VNode | VNode[]) {\n branches.push([true, content]);\n return this;\n },\n done() {\n const matchKey = `match-${claimKey()}`;\n for (let idx = 0; idx < branches.length; idx++) {\n const [cond, content] = branches[idx];\n if (cond) {\n const branchKey = `${matchKey}-branch-${idx}`;\n if (typeof content === 'function') {\n enterScope(branchKey);\n const payload = (content as () => VNode | VNode[])();\n exitScope();\n return [anchorBlock(payload, branchKey)];\n }\n return [anchorBlock(content, branchKey)];\n }\n }\n return [anchorBlock([], `${matchKey}-empty`)];\n },\n };\n}\n\n/**\n * Create a stable anchor block with consistent boundaries.\n * Always has start/end boundaries.\n */\nexport function anchorBlock(\n children: VNode | VNode[] | null | undefined,\n anchorKey: string,\n): VNode {\n // Normalize children to array, filtering out only null/undefined values.\n // Preserve meaningful falsy values such as 0, false, and empty string.\n const childArray = !children\n ? []\n : Array.isArray(children)\n ? children.filter((c) => c !== null && c !== undefined)\n : [children].filter((c) => c !== null && c !== undefined);\n\n return {\n tag: '#anchor',\n key: anchorKey,\n children: childArray,\n };\n}\n"],"mappings":"mEAsBA,IAAI,EAAe,GAEf,EAAc,EAEZ,EAAgD,CAAA,EAOtD,SAAgB,GAAyB,CACvC,EAAe,GACf,EAAc,EACd,EAAY,OAAS,EASvB,SAAgB,GAA6B,CAC3C,OAAO,IAIT,SAAS,EAAS,EAA8B,CAC9C,MAAM,EAAM,IACZ,OAAI,IAAgB,OAAkB,EAC/B,EAAe,GAAG,CAAA,IAAgB,CAAA,GAAQ,cAAc,CAAA,GAIjE,SAAS,EAAW,EAAyB,CAC3C,EAAY,KAAK,CAAC,EAAc,CAAA,CAAY,EAC5C,EAAe,EACf,EAAc,EAIhB,SAAS,GAAkB,CACzB,MAAM,EAAM,EAAY,EAAY,OAAS,CAAA,EACzC,IACF,EAAY,SACZ,CAAC,EAAc,CAAA,EAAe,GAelC,SAAgB,EACd,EACA,EACA,EACO,CAIP,MAAM,EAAY,EAAS,CAAA,EAE3B,GAAI,OAAO,GAAsB,WAC/B,OAAO,EAAY,EAAO,EAAoB,CAAA,EAAI,CAAA,EAGpD,GAAI,CAAC,EACH,OAAO,EAAY,CAAA,EAAI,CAAA,EAKzB,EAAW,CAAA,EACX,MAAM,EAAW,EAAA,EACjB,OAAA,EAAA,EACO,EAAY,EAAU,CAAA,EAI/B,SAAgB,EAEd,EAAW,EAA8D,CACzE,OAAO,EAAK,IAAA,CAAK,EAAM,IAAM,CAE3B,MAAM,EACJ,OAAO,GAAS,SACV,GAAkC,KACnC,GAAkC,IACnC,OAAO,CAAA,GACP,OAAO,CAAA,EACb,OAAO,EAAY,EAAO,EAAM,CAAA,EAAI,QAAQ,CAAA,EAAA,IAUhD,SAAgB,GAAQ,CACtB,MAAM,EAAqB,CAAA,EAC3B,MAAO,CACL,KAAK,EAAe,EAAoD,CACtE,OAAA,EAAS,KAAK,CAAC,EAAM,CAAA,CAAQ,EACtB,MAET,UAAU,EAA0B,CAClC,OAAA,EAAS,KAAK,CAAC,GAAM,CAAA,CAAQ,EACtB,MAET,MAAO,CACL,MAAM,EAAW,SAAS,EAAA,CAAU,GACpC,QAAS,EAAM,EAAG,EAAM,EAAS,OAAQ,IAAO,CAC9C,KAAM,CAAC,EAAM,CAAA,EAAW,EAAS,CAAA,EACjC,GAAI,EAAM,CACR,MAAM,EAAY,GAAG,CAAA,WAAmB,CAAA,GACxC,GAAI,OAAO,GAAY,WAAY,CACjC,EAAW,CAAA,EACX,MAAM,EAAW,EAAA,EACjB,OAAA,EAAA,EACO,CAAC,EAAY,EAAS,CAAA,CAAU,EAEzC,MAAO,CAAC,EAAY,EAAS,CAAA,CAAU,GAG3C,MAAO,CAAC,EAAY,CAAA,EAAI,GAAG,CAAA,QAAS,CAAQ,IASlD,SAAgB,EACd,EACA,EACO,CASP,MAAO,CACL,IAAK,UACL,IAAK,EACL,SATkB,EAEhB,MAAM,QAAQ,CAAA,EACZ,EAAS,OAAQ,GAAM,GAAM,IAAc,EAC3C,CAAC,CAAA,EAAU,OAAQ,GAAM,GAAM,IAAc,EAH/C,CAAA"}
1
+ {"version":3,"file":"custom-elements-runtime.directives.cjs.js","names":[],"sources":["../src/lib/directives.ts"],"sourcesContent":["import type { VNode } from './runtime/types';\n\n// ── Per-render directive scope tracking ─────────────────────────────────────\n//\n// A FLAT counter (index++) breaks when a when() factory itself contains more\n// when() calls: those inner calls consume counter slots, causing SUBSEQUENT\n// SIBLING when() calls to get a different index depending on whether the factory\n// ran. For example:\n//\n// when(A, () => { when(B); when(C); }) // ← factory may or may not run\n// when(D) // ← index shifts when factory runs\n//\n// The fix: each when() call claims its own slot (stable regardless of whether\n// the factory runs), then ENTERS a new child scope for the factory. Inner\n// when() calls consume indices in that child scope, never bleeding into the\n// sibling counter of the outer scope.\n//\n// Key format: root sibling 0 → \"when-block-0\"\n// child of \"when-block-0\" at pos 1 → \"when-block-0.1\"\n// grandchild → \"when-block-0.1.0\" etc.\n\n/** Current scope's parent prefix (empty string = root scope). */\nlet _scopeParent = '';\n/** Next sibling index inside the current scope. */\nlet _scopeIndex = 0;\n/** Stack of [parentPrefix, siblingIndex] for nested scopes. */\nconst _scopeStack: Array<readonly [string, number]> = [];\n\n/**\n * Reset all scope state at the start of each component render pass.\n * Called automatically by the component renderer — not needed in user code.\n * @internal\n */\nexport function resetWhenCounter(): void {\n _scopeParent = '';\n _scopeIndex = 0;\n _scopeStack.length = 0;\n}\n\n/**\n * Claim the next directive call index within the current scope.\n * Used by directive-enhancements.ts for non-when() directives (switchOnLength,\n * switchOnPromise, etc.) that need a stable unique number per call site.\n * @internal\n */\nexport function nextDirectiveIndex(): number {\n return _scopeIndex++;\n}\n\n/** Claim the next slot in the current scope and return its anchor key. */\nfunction claimKey(explicitKey?: string): string {\n const idx = _scopeIndex++;\n if (explicitKey !== undefined) return explicitKey;\n return _scopeParent ? `${_scopeParent}.${idx}` : `when-block-${idx}`;\n}\n\n/** Push a new child scope keyed under `anchorKey`. */\nfunction enterScope(anchorKey: string): void {\n _scopeStack.push([_scopeParent, _scopeIndex] as const);\n _scopeParent = anchorKey;\n _scopeIndex = 0;\n}\n\n/** Pop back to the parent scope. */\nfunction exitScope(): void {\n const top = _scopeStack[_scopeStack.length - 1];\n if (top) {\n _scopeStack.length--;\n [_scopeParent, _scopeIndex] = top;\n }\n}\n\n/* --- When --- */\nexport function when(\n cond: boolean,\n children: VNode | VNode[],\n key?: string,\n): VNode;\nexport function when(\n cond: boolean,\n factory: () => VNode | VNode[],\n key?: string,\n): VNode;\nexport function when(\n cond: boolean,\n childrenOrFactory: VNode | VNode[] | (() => VNode | VNode[]),\n key?: string,\n): VNode {\n // Claim this call's position BEFORE potentially entering a child scope.\n // This guarantees sibling when() calls always get the same index regardless\n // of whether a factory executes and how many when() calls it contains.\n const anchorKey = claimKey(key);\n\n if (typeof childrenOrFactory !== 'function') {\n return anchorBlock(cond ? childrenOrFactory : [], anchorKey);\n }\n\n if (!cond) {\n return anchorBlock([], anchorKey);\n }\n\n // Run the factory in a child scope so its inner when() calls don't\n // affect the sibling counter of the outer scope.\n enterScope(anchorKey);\n const children = childrenOrFactory();\n exitScope();\n return anchorBlock(children, anchorKey);\n}\n\n/* --- Each --- */\nexport function each<\n T extends string | number | boolean | { id?: string | number; key?: string },\n>(list: T[], render: (item: T, index: number) => VNode | VNode[]): VNode[] {\n return list.map((item, i) => {\n // For primitives, use value as key; for objects, prefer key/id\n const itemKey =\n typeof item === 'object'\n ? ((item as Record<string, unknown>)?.key ??\n (item as Record<string, unknown>)?.id ??\n `idx-${i}`)\n : String(item);\n return anchorBlock(render(item, i), `each-${itemKey}`);\n });\n}\n\n/* --- match --- */\ntype Branch = [\n condition: unknown,\n content: VNode | VNode[] | (() => VNode | VNode[]),\n];\n\nexport function match() {\n const branches: Branch[] = [];\n return {\n when(cond: unknown, content: VNode | VNode[] | (() => VNode | VNode[])) {\n branches.push([cond, content]);\n return this;\n },\n otherwise(content: VNode | VNode[]) {\n branches.push([true, content]);\n return this;\n },\n done() {\n const matchKey = `match-${claimKey()}`;\n for (let idx = 0; idx < branches.length; idx++) {\n const [cond, content] = branches[idx];\n if (cond) {\n const branchKey = `${matchKey}-branch-${idx}`;\n if (typeof content === 'function') {\n enterScope(branchKey);\n const payload = (content as () => VNode | VNode[])();\n exitScope();\n return [anchorBlock(payload, branchKey)];\n }\n return [anchorBlock(content, branchKey)];\n }\n }\n return [anchorBlock([], `${matchKey}-empty`)];\n },\n };\n}\n\n/**\n * Create a stable anchor block with consistent boundaries.\n * Always has start/end boundaries.\n */\nexport function anchorBlock(\n children: VNode | VNode[] | null | undefined,\n anchorKey: string,\n): VNode {\n // Normalize children to array, filtering out only null/undefined values.\n // Preserve meaningful falsy values such as 0, false, and empty string.\n const childArray = !children\n ? []\n : Array.isArray(children)\n ? children.filter((c) => c !== null && c !== undefined)\n : [children].filter((c) => c !== null && c !== undefined);\n\n return {\n tag: '#anchor',\n key: anchorKey,\n children: childArray,\n };\n}\n"],"mappings":"mEAsBA,IAAI,EAAe,GAEf,EAAc,EAEZ,EAAgD,EAAE,CAOxD,SAAgB,GAAyB,CACvC,EAAe,GACf,EAAc,EACd,EAAY,OAAS,EASvB,SAAgB,GAA6B,CAC3C,MAAO,KAIT,SAAS,EAAS,EAA8B,CAC9C,IAAM,EAAM,IAEZ,OADI,IAAgB,IAAA,GACb,EAAe,GAAG,EAAa,GAAG,IAAQ,cAAc,IADzB,EAKxC,SAAS,EAAW,EAAyB,CAC3C,EAAY,KAAK,CAAC,EAAc,EAAY,CAAU,CACtD,EAAe,EACf,EAAc,EAIhB,SAAS,GAAkB,CACzB,IAAM,EAAM,EAAY,EAAY,OAAS,GACzC,IACF,EAAY,SACZ,CAAC,EAAc,GAAe,GAelC,SAAgB,EACd,EACA,EACA,EACO,CAIP,IAAM,EAAY,EAAS,EAAI,CAE/B,GAAI,OAAO,GAAsB,WAC/B,OAAO,EAAY,EAAO,EAAoB,EAAE,CAAE,EAAU,CAG9D,GAAI,CAAC,EACH,OAAO,EAAY,EAAE,CAAE,EAAU,CAKnC,EAAW,EAAU,CACrB,IAAM,EAAW,GAAmB,CAEpC,OADA,GAAW,CACJ,EAAY,EAAU,EAAU,CAIzC,SAAgB,EAEd,EAAW,EAA8D,CACzE,OAAO,EAAK,KAAK,EAAM,IAAM,CAE3B,IAAM,EACJ,OAAO,GAAS,SACV,GAAkC,KACnC,GAAkC,IACnC,OAAO,IACP,OAAO,EAAK,CAClB,OAAO,EAAY,EAAO,EAAM,EAAE,CAAE,QAAQ,IAAU,EACtD,CASJ,SAAgB,GAAQ,CACtB,IAAM,EAAqB,EAAE,CAC7B,MAAO,CACL,KAAK,EAAe,EAAoD,CAEtE,OADA,EAAS,KAAK,CAAC,EAAM,EAAQ,CAAC,CACvB,MAET,UAAU,EAA0B,CAElC,OADA,EAAS,KAAK,CAAC,GAAM,EAAQ,CAAC,CACvB,MAET,MAAO,CACL,IAAM,EAAW,SAAS,GAAU,GACpC,IAAK,IAAI,EAAM,EAAG,EAAM,EAAS,OAAQ,IAAO,CAC9C,GAAM,CAAC,EAAM,GAAW,EAAS,GACjC,GAAI,EAAM,CACR,IAAM,EAAY,GAAG,EAAS,UAAU,IACxC,GAAI,OAAO,GAAY,WAAY,CACjC,EAAW,EAAU,CACrB,IAAM,EAAW,GAAmC,CAEpD,OADA,GAAW,CACJ,CAAC,EAAY,EAAS,EAAU,CAAC,CAE1C,MAAO,CAAC,EAAY,EAAS,EAAU,CAAC,EAG5C,MAAO,CAAC,EAAY,EAAE,CAAE,GAAG,EAAS,QAAQ,CAAC,EAEhD,CAOH,SAAgB,EACd,EACA,EACO,CASP,MAAO,CACL,IAAK,UACL,IAAK,EACL,SATkB,EAEhB,MAAM,QAAQ,EAAS,CACrB,EAAS,OAAQ,GAAM,GAAM,KAAwB,CACrD,CAAC,EAAS,CAAC,OAAQ,GAAM,GAAM,KAAwB,CAHzD,EAAE,CASL"}