@luna_ui/luna 0.3.5 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/dist/cli.mjs +1 -1
  2. package/dist/{index-CyEkcO3_.d.ts → index-vO066aMd.d.ts} +17 -6
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.js +1 -1
  5. package/dist/jsx-dev-runtime.js +1 -1
  6. package/dist/jsx-runtime.d.ts +1 -1
  7. package/dist/jsx-runtime.js +1 -1
  8. package/dist/src-DviLMStS.js +1 -0
  9. package/package.json +1 -1
  10. package/src/hydration/createHydrator.ts +62 -0
  11. package/src/hydration/delegate.ts +62 -0
  12. package/src/hydration/drag.ts +214 -0
  13. package/src/hydration/index.ts +12 -0
  14. package/src/hydration/keyboard.ts +64 -0
  15. package/src/hydration/toggle.ts +101 -0
  16. package/src/index.ts +26 -8
  17. package/tests/__screenshots__/{preact-signals-comparison.test.ts/DOM-Rendering-Comparison---Reactive-Updates-text-updates-match-1.png → apg.test.ts/APG-Components---Accessibility-Tests-Button-Pattern-disabled-button-has-aria-disabled-1.png} +0 -0
  18. package/tests/apg.test.ts +466 -0
  19. package/tests/debounced.test.ts +165 -0
  20. package/tests/dom.test.ts +3 -2
  21. package/tests/issue-11-show-null-to-truthy.test.ts +176 -0
  22. package/tests/solidjs-api.test.ts +5 -4
  23. package/dist/src-CHiGeWfy.js +0 -1
  24. package/tests/__screenshots__/context.test.ts/Context-API-context-with-reactive-effects-context-value-accessible-in-effect-1.png +0 -0
  25. package/tests/__screenshots__/dom.test.ts/DOM-API-For-component--SolidJS-style--For-updates-when-signal-changes-1.png +0 -0
  26. package/tests/__screenshots__/dom.test.ts/DOM-API-Show-component--SolidJS-style--Show-accepts-children-as-function-1.png +0 -0
  27. package/tests/__screenshots__/dom.test.ts/DOM-API-Show-component--SolidJS-style--Show-toggles-visibility-1.png +0 -0
  28. package/tests/__screenshots__/dom.test.ts/DOM-API-createElement-createElement-with-dynamic-attribute-1.png +0 -0
  29. package/tests/__screenshots__/dom.test.ts/DOM-API-createElement-createElement-with-dynamic-style-1.png +0 -0
  30. package/tests/__screenshots__/dom.test.ts/DOM-API-createElementNs--SVG-support--createElementNs-with-dynamic-attribute-1.png +0 -0
  31. package/tests/__screenshots__/dom.test.ts/DOM-API-effect-with-DOM-effect-tracks-signal-changes-1.png +0 -0
  32. package/tests/__screenshots__/dom.test.ts/DOM-API-forEach--list-rendering--forEach-handles-clear-to-empty-1.png +0 -0
  33. package/tests/__screenshots__/dom.test.ts/DOM-API-forEach--list-rendering--forEach-handles-empty-array-1.png +0 -0
  34. package/tests/__screenshots__/dom.test.ts/DOM-API-forEach--list-rendering--forEach-removes-items-1.png +0 -0
  35. package/tests/__screenshots__/dom.test.ts/DOM-API-forEach--list-rendering--forEach-renders-initial-list-1.png +0 -0
  36. package/tests/__screenshots__/dom.test.ts/DOM-API-forEach--list-rendering--forEach-updates-when-items-change-1.png +0 -0
  37. package/tests/__screenshots__/dom.test.ts/DOM-API-forEach-with-SVG-elements-forEach-handles-empty-to-non-empty-transition-in-SVG-1.png +0 -0
  38. package/tests/__screenshots__/dom.test.ts/DOM-API-forEach-with-SVG-elements-forEach-handles-reordering-in-SVG-1.png +0 -0
  39. package/tests/__screenshots__/dom.test.ts/DOM-API-forEach-with-SVG-elements-forEach-updates-SVG-elements-when-signal-changes-1.png +0 -0
  40. package/tests/__screenshots__/dom.test.ts/DOM-API-forEach-with-SVG-elements-forEach-with-nested-SVG-groups-1.png +0 -0
  41. package/tests/__screenshots__/dom.test.ts/DOM-API-ref-callback--JSX-style--ref-callback-with-nested-elements-1.png +0 -0
  42. package/tests/__screenshots__/dom.test.ts/DOM-API-show--conditional-rendering--show-creates-a-node-1.png +0 -0
  43. package/tests/__screenshots__/dom.test.ts/DOM-API-show--conditional-rendering--show-with-false-condition-creates-placeholder-1.png +0 -0
  44. package/tests/__screenshots__/dom.test.ts/DOM-API-text-nodes-textDyn-creates-reactive-text-node-1.png +0 -0
  45. package/tests/__screenshots__/integration.test.ts/Integration--Nested-Components-with-Context-Complex-nested-scenario-forEach-renders-correctly-without-show--initial-items--1.png +0 -0
  46. package/tests/__screenshots__/integration.test.ts/Integration--Nested-Components-with-Context-Complex-nested-scenario-forEach-with-context-renders-correctly-without-show-1.png +0 -0
  47. package/tests/__screenshots__/integration.test.ts/Integration--Nested-Components-with-Context-Complex-nested-scenario-nested-components-with-context--forEach--and-show-1.png +0 -0
  48. package/tests/__screenshots__/integration.test.ts/Integration--Nested-Components-with-Context-Complex-nested-scenario-show-and-forEach-inherit-context-from-Owner--fixed--1.png +0 -0
  49. package/tests/__screenshots__/integration.test.ts/Integration--Nested-Components-with-Context-Complex-nested-scenario-show-and-forEach-work-together--context-uses-default--1.png +0 -0
  50. package/tests/__screenshots__/integration.test.ts/Integration--Nested-Components-with-Context-Context---ForEach-integration-forEach-items-can-access-context-1.png +0 -0
  51. package/tests/__screenshots__/integration.test.ts/Integration--Nested-Components-with-Context-ForEach-with-reactive-updates-forEach-renders-initial-list-1.png +0 -0
  52. package/tests/__screenshots__/integration.test.ts/Integration--Nested-Components-with-Context-ForEach-with-reactive-updates-forEach-updates-when-signal-changes-1.png +0 -0
  53. package/tests/__screenshots__/integration.test.ts/Integration--Nested-Components-with-Context-ForEach-with-reactive-updates-forEach-with-object-items-1.png +0 -0
  54. package/tests/__screenshots__/integration.test.ts/Integration--Nested-Components-with-Context-Show--conditional-rendering--show-hides-when-condition-is-false-1.png +0 -0
  55. package/tests/__screenshots__/integration.test.ts/Integration--Nested-Components-with-Context-Show--conditional-rendering--show-renders-when-condition-is-true-1.png +0 -0
  56. package/tests/__screenshots__/integration.test.ts/Integration--Nested-Components-with-Context-Show--conditional-rendering--show-toggles-from-false-to-true-1.png +0 -0
  57. package/tests/__screenshots__/integration.test.ts/Integration--Nested-Components-with-Context-Show--conditional-rendering--show-toggles-reactively-1.png +0 -0
  58. package/tests/__screenshots__/lifecycle.test.ts/onCleanup-in-Component-Body--Solid-js-style--event-listener-pattern--Solid-js-docs-example--1.png +0 -0
  59. package/tests/__screenshots__/lifecycle.test.ts/onCleanup-in-Component-Body--Solid-js-style--multiple-cleanups-in-component-body--LIFO-order--1.png +0 -0
  60. package/tests/__screenshots__/lifecycle.test.ts/onCleanup-in-Component-Body--Solid-js-style--onCleanup-in-component-body-runs-on-unmount-1.png +0 -0
  61. package/tests/__screenshots__/lifecycle.test.ts/onCleanup-in-Component-Body--Solid-js-style--onCleanup-works-with-For-loop-items--component-body-style--1.png +0 -0
  62. package/tests/__screenshots__/lifecycle.test.ts/onCleanup-in-Component-Body--Solid-js-style--timer-cleanup-pattern--Solid-js-style--1.png +0 -0
  63. package/tests/__screenshots__/lifecycle.test.ts/onCleanup-in-Effects-effect-cleanup-runs-before-re-run-1.png +0 -0
  64. package/tests/__screenshots__/preact-signals-comparison.test.ts/Bulk-Updates-large-list-update-1.png +0 -0
  65. package/tests/__screenshots__/preact-signals-comparison.test.ts/Bulk-Updates-nested-batch-operations-1.png +0 -0
  66. package/tests/__screenshots__/preact-signals-comparison.test.ts/Bulk-Updates-rapid-sequential-updates-1.png +0 -0
  67. package/tests/__screenshots__/preact-signals-comparison.test.ts/DOM-Rendering-Comparison---Conditional-Show-component---visible-1.png +0 -0
  68. package/tests/__screenshots__/preact-signals-comparison.test.ts/DOM-Rendering-Comparison---Conditional-show-hide-element---visible-1.png +0 -0
  69. package/tests/__screenshots__/preact-signals-comparison.test.ts/DOM-Rendering-Comparison---Fragments-fragment-with-list-1.png +0 -0
  70. package/tests/__screenshots__/preact-signals-comparison.test.ts/DOM-Rendering-Comparison---Fragments-nested-fragments-1.png +0 -0
  71. package/tests/__screenshots__/preact-signals-comparison.test.ts/DOM-Rendering-Comparison---Fragments-simple-fragment-1.png +0 -0
  72. package/tests/__screenshots__/preact-signals-comparison.test.ts/DOM-Rendering-Comparison---Reactive-Updates-conditional-toggle-updates-1.png +0 -0
  73. package/tests/__screenshots__/preact-signals-comparison.test.ts/DOM-Rendering-Comparison---Reactive-Updates-list-addition-updates-match-1.png +0 -0
  74. package/tests/__screenshots__/preact-signals-comparison.test.ts/DOM-Rendering-Comparison---Reactive-Updates-list-removal-updates-match-1.png +0 -0
  75. package/tests/__screenshots__/preact-signals-comparison.test.ts/Dynamic-Attributes-Comparison-dynamic-className-updates-1.png +0 -0
  76. package/tests/__screenshots__/preact-signals-comparison.test.ts/Dynamic-Attributes-Comparison-dynamic-style-updates-1.png +0 -0
  77. package/tests/__screenshots__/preact-signals-comparison.test.ts/Dynamic-Attributes-Comparison-multiple-dynamic-attributes-1.png +0 -0
  78. package/tests/__screenshots__/preact-signals-comparison.test.ts/Edge-Cases-deeply-nested-conditionals-1.png +0 -0
  79. package/tests/__screenshots__/preact-signals-comparison.test.ts/Edge-Cases-list-transitions-from-empty-to-populated-1.png +0 -0
  80. package/tests/__screenshots__/preact-signals-comparison.test.ts/Edge-Cases-list-transitions-from-populated-to-empty-1.png +0 -0
  81. package/tests/__screenshots__/preact-signals-comparison.test.ts/Effect-Cleanup-Comparison-nested-effects-cleanup-order-1.png +0 -0
  82. package/tests/__screenshots__/preact-signals-comparison.test.ts/Effect-Cleanup-Comparison-nested-effects-with-inner-signal-change-1.png +0 -0
  83. package/tests/__screenshots__/preact-signals-comparison.test.ts/Effect-Cleanup-Comparison-onCleanup-is-called-when-effect-re-runs-1.png +0 -0
  84. package/tests/__screenshots__/preact-signals-comparison.test.ts/Effect-Cleanup-Comparison-onCleanup-with-resource-simulation-1.png +0 -0
  85. package/tests/__screenshots__/preact-signals-comparison.test.ts/Fragment-Comparison-with-Preact-Fragment-with-multiple-children--no-wrapper--1.png +0 -0
  86. package/tests/__screenshots__/preact-signals-comparison.test.ts/Fragment-Comparison-with-Preact-Fragment-with-no-children-1.png +0 -0
  87. package/tests/__screenshots__/preact-signals-comparison.test.ts/Fragment-Comparison-with-Preact-fragment-with-list-1.png +0 -0
  88. package/tests/__screenshots__/preact-signals-comparison.test.ts/Fragment-Comparison-with-Preact-nested-Fragments-work-correctly-1.png +0 -0
  89. package/tests/__screenshots__/preact-signals-comparison.test.ts/List-Reordering-complex-reordering-with-additions-and-removals-1.png +0 -0
  90. package/tests/__screenshots__/preact-signals-comparison.test.ts/List-Reordering-insert-in-middle-1.png +0 -0
  91. package/tests/__screenshots__/preact-signals-comparison.test.ts/List-Reordering-remove-from-middle-1.png +0 -0
  92. package/tests/__screenshots__/preact-signals-comparison.test.ts/List-Reordering-reverse-list-order-1.png +0 -0
  93. package/tests/__screenshots__/preact-signals-comparison.test.ts/List-Reordering-shuffle-list-1.png +0 -0
  94. package/tests/__screenshots__/preact-signals-comparison.test.ts/Luna-Conditional-Rendering-Show-component-renders-when-condition-is-true-1.png +0 -0
  95. package/tests/__screenshots__/preact-signals-comparison.test.ts/Luna-Conditional-Rendering-show-renders-content-when-initially-true-1.png +0 -0
  96. package/tests/__screenshots__/preact-signals-comparison.test.ts/Luna-Conditional-Rendering-show-toggles-visibility-dynamically-1.png +0 -0
  97. package/tests/__screenshots__/preact-signals-comparison.test.ts/Memo-Dependency-Chain-conditional-memo-dependencies-1.png +0 -0
  98. package/tests/__screenshots__/preact-signals-comparison.test.ts/Signal-Behavior-Comparison-basic-signal-get-set-produces-same-values-1.png +0 -0
  99. package/tests/__screenshots__/preact-signals-comparison.test.ts/Signal-Behavior-Comparison-batch-updates-produce-same-final-values-1.png +0 -0
  100. package/tests/__screenshots__/preact-signals-comparison.test.ts/Untrack-and-Peek-Behavior-peek-reads-value-without-tracking-1.png +0 -0
  101. package/tests/__screenshots__/preact-signals-comparison.test.ts/Untrack-and-Peek-Behavior-selective-tracking-with-untrack-1.png +0 -0
  102. package/tests/__screenshots__/preact-signals-comparison.test.ts/Untrack-and-Peek-Behavior-untrack-prevents-dependency-tracking-1.png +0 -0
  103. package/tests/__screenshots__/resource.test.ts/Resource-API--SolidJS-style--reactivity-accessor-is-reactive-1.png +0 -0
  104. package/tests/__screenshots__/resource.test.ts/Resource-API-AsyncState-helpers-stateError-returns-empty-string-for-non-failure-1.png +0 -0
  105. package/tests/__screenshots__/resource.test.ts/Resource-API-AsyncState-helpers-stateError-returns-undefined-for-non-failure-1.png +0 -0
  106. package/tests/__screenshots__/resource.test.ts/Resource-API-AsyncState-helpers-stateIsFailure-and-stateError-1.png +0 -0
  107. package/tests/__screenshots__/resource.test.ts/Resource-API-AsyncState-helpers-stateIsPending-1.png +0 -0
  108. package/tests/__screenshots__/resource.test.ts/Resource-API-AsyncState-helpers-stateIsSuccess-and-stateValue-1.png +0 -0
  109. package/tests/__screenshots__/resource.test.ts/Resource-API-AsyncState-helpers-stateValue-returns-undefined-for-non-success-1.png +0 -0
  110. package/tests/__screenshots__/resource.test.ts/Resource-API-createDeferred-reject-transitions-to-failure-1.png +0 -0
  111. package/tests/__screenshots__/resource.test.ts/Resource-API-createDeferred-resolve-transitions-to-success-1.png +0 -0
  112. package/tests/__screenshots__/resource.test.ts/Resource-API-createDeferred-returns-resource--resolve--and-reject-functions-1.png +0 -0
  113. package/tests/__screenshots__/resource.test.ts/Resource-API-createDeferred-starts-in-pending-state-1.png +0 -0
  114. package/tests/__screenshots__/resource.test.ts/Resource-API-createResource-async-resolve-works-1.png +0 -0
  115. package/tests/__screenshots__/resource.test.ts/Resource-API-createResource-starts-in-pending-state-1.png +0 -0
  116. package/tests/__screenshots__/resource.test.ts/Resource-API-createResource-transitions-to-failure-on-reject-1.png +0 -0
  117. package/tests/__screenshots__/resource.test.ts/Resource-API-createResource-transitions-to-success-on-resolve-1.png +0 -0
  118. package/tests/__screenshots__/resource.test.ts/Resource-API-integration-with-Promise-can-wrap-fetch-like-async-operations-1.png +0 -0
  119. package/tests/__screenshots__/resource.test.ts/Resource-API-integration-with-Promise-works-with-setTimeout-simulation-1.png +0 -0
  120. package/tests/__screenshots__/resource.test.ts/Resource-API-resourceGet-vs-resourcePeek-resourceGet-tracks-dependencies-1.png +0 -0
  121. package/tests/__screenshots__/resource.test.ts/Resource-API-resourceGet-vs-resourcePeek-resourcePeek-does-not-track-dependencies-1.png +0 -0
  122. package/tests/__screenshots__/resource.test.ts/Resource-API-resourceRefetch-refetch-resets-to-pending-and-re-runs-fetcher-1.png +0 -0
  123. package/tests/__screenshots__/solidjs-api.test.ts/Portal-component-Portal-renders-children-to-body-by-default-1.png +0 -0
  124. package/tests/__screenshots__/solidjs-api.test.ts/Portal-component-Portal-renders-to-selector-mount-target-1.png +0 -0
  125. package/tests/__screenshots__/solidjs-api.test.ts/SolidJS-API-compatibility-createEffect-tracks-dependencies-automatically-1.png +0 -0
  126. package/tests/__screenshots__/solidjs-api.test.ts/Switch-Match-component-Switch-with-accessor-condition-in-Match-1.png +0 -0
  127. package/tests/__screenshots__/solidjs-api.test.ts/Switch-Match-component-Switch-with-multiple-Match-components-1.png +0 -0
  128. package/tests/__screenshots__/solidjs-api.test.ts/Switch-Match-component-Switch-with-single-Match-and-fallback-1.png +0 -0
  129. package/tests/__screenshots__/solidjs-api.test.ts/Switch-Match-components-Switch-updates-DOM-when-signal-changes-1.png +0 -0
  130. package/tests/__screenshots__/solidjs-api.test.ts/on---utility-on-tracks-multiple-dependencies-1.png +0 -0
  131. package/tests/__screenshots__/solidjs-api.test.ts/on---utility-on-tracks-single-dependency-1.png +0 -0
  132. package/tests/__screenshots__/solidjs-api.test.ts/on---utility-on-with-defer-option-skips-initial-run-1.png +0 -0
  133. package/tests/__screenshots__/store.test.ts/createStore-Arrays-array-updates-work-1.png +0 -0
  134. package/tests/__screenshots__/store.test.ts/createStore-Reactivity-only-triggers-when-accessed-property-changes-1.png +0 -0
  135. package/tests/__screenshots__/store.test.ts/createStore-Reactivity-parent-path-change-notifies-child-accessors-1.png +0 -0
  136. package/tests/__screenshots__/store.test.ts/createStore-Reactivity-tracks-nested-property-access-1.png +0 -0
  137. package/tests/__screenshots__/store.test.ts/createStore-Reactivity-tracks-property-access-in-effects-1.png +0 -0
@@ -0,0 +1,64 @@
1
+ /**
2
+ * keyboard - Keyboard event handler helper
3
+ *
4
+ * Map keyboard keys to handler functions.
5
+ */
6
+
7
+ export type KeyboardHandlers = {
8
+ [key: string]: (event: KeyboardEvent) => void;
9
+ };
10
+
11
+ /**
12
+ * Set up keyboard handlers on an element or document
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * // Handle Escape on document
17
+ * keyboard(document, {
18
+ * Escape: () => close()
19
+ * });
20
+ *
21
+ * // Handle arrow keys on a specific element
22
+ * keyboard(slider, {
23
+ * ArrowUp: () => increment(),
24
+ * ArrowDown: () => decrement(),
25
+ * ArrowLeft: () => decrement(),
26
+ * ArrowRight: () => increment()
27
+ * });
28
+ * ```
29
+ */
30
+ export function keyboard(
31
+ target: Element | Document | null,
32
+ handlers: KeyboardHandlers
33
+ ): () => void {
34
+ if (!target) return () => {};
35
+
36
+ const handler = (e: Event) => {
37
+ const key = (e as KeyboardEvent).key;
38
+ const fn = handlers[key];
39
+ if (fn) {
40
+ fn(e as KeyboardEvent);
41
+ }
42
+ };
43
+
44
+ target.addEventListener('keydown', handler);
45
+
46
+ // Return cleanup function
47
+ return () => {
48
+ target.removeEventListener('keydown', handler);
49
+ };
50
+ }
51
+
52
+ /**
53
+ * Handle Escape key to close something
54
+ *
55
+ * @example
56
+ * ```ts
57
+ * onEscape(() => {
58
+ * dialog.dataset.state = 'closed';
59
+ * });
60
+ * ```
61
+ */
62
+ export function onEscape(handler: () => void): () => void {
63
+ return keyboard(document, { Escape: handler });
64
+ }
@@ -0,0 +1,101 @@
1
+ /**
2
+ * toggle - Binary state toggle helper
3
+ *
4
+ * Toggles between two states on click, using data-* or aria-* attributes.
5
+ * CSS handles visual changes via attribute selectors.
6
+ */
7
+
8
+ export interface ToggleOptions {
9
+ /**
10
+ * Selector for the element to toggle state on.
11
+ * If not provided, the trigger element itself is used.
12
+ * Use closest() to find ancestor.
13
+ */
14
+ target?: string;
15
+
16
+ /**
17
+ * The two states to toggle between.
18
+ * @default ['open', 'closed'] for data-state
19
+ * @default ['true', 'false'] for aria-checked
20
+ */
21
+ states?: [string, string];
22
+
23
+ /**
24
+ * Attribute to update.
25
+ * @default 'data-state'
26
+ */
27
+ attribute?: string;
28
+
29
+ /**
30
+ * Callback when state changes.
31
+ */
32
+ onChange?: (state: string, element: Element) => void;
33
+ }
34
+
35
+ /**
36
+ * Set up click-to-toggle behavior on matching elements
37
+ *
38
+ * @example
39
+ * ```ts
40
+ * // Toggle data-state on parent [data-accordion-item]
41
+ * toggle(el, '[data-accordion-trigger]', {
42
+ * target: '[data-accordion-item]',
43
+ * states: ['open', 'closed']
44
+ * });
45
+ *
46
+ * // Toggle aria-checked on the button itself
47
+ * toggle(el, '[data-switch-toggle]', {
48
+ * attribute: 'aria-checked',
49
+ * states: ['true', 'false']
50
+ * });
51
+ * ```
52
+ */
53
+ export function toggle(
54
+ root: Element,
55
+ selector: string,
56
+ options: ToggleOptions = {}
57
+ ): () => void {
58
+ const {
59
+ target,
60
+ attribute = 'data-state',
61
+ states = attribute === 'aria-checked' ? ['true', 'false'] : ['open', 'closed'],
62
+ onChange,
63
+ } = options;
64
+
65
+ const [stateA, stateB] = states;
66
+ const handlers: Array<{ el: Element; handler: EventListener }> = [];
67
+
68
+ root.querySelectorAll(selector).forEach((trigger) => {
69
+ const handler = () => {
70
+ // Find target element
71
+ const targetEl = target
72
+ ? trigger.closest(target)
73
+ : trigger;
74
+
75
+ if (!targetEl) return;
76
+
77
+ // Get current state and toggle
78
+ const current = targetEl.getAttribute(attribute);
79
+ const next = current === stateA ? stateB : stateA;
80
+
81
+ targetEl.setAttribute(attribute, next);
82
+
83
+ // Also update aria-checked if toggling data-state on a button
84
+ if (attribute === 'data-state' && targetEl.tagName === 'BUTTON') {
85
+ targetEl.setAttribute('aria-checked', next === stateA ? 'true' : 'false');
86
+ }
87
+
88
+ onChange?.(next, targetEl);
89
+ };
90
+
91
+ trigger.addEventListener('click', handler);
92
+ handlers.push({ el: trigger, handler });
93
+ });
94
+
95
+ // Return cleanup function
96
+ return () => {
97
+ handlers.forEach(({ el, handler }) => {
98
+ el.removeEventListener('click', handler);
99
+ });
100
+ };
101
+ }
package/src/index.ts CHANGED
@@ -23,8 +23,11 @@ export interface ForProps<T> {
23
23
  export interface ShowProps<T> {
24
24
  when: T | Accessor<T>;
25
25
  fallback?: LunaNode;
26
- /** Must be a function to ensure proper lifecycle (onCleanup/onMount) support */
27
- children: (() => LunaNode) | ((item: NonNullable<T>) => LunaNode);
26
+ /**
27
+ * Children receives an accessor function (SolidJS-style).
28
+ * Use: {(item) => <p>{item()}</p>}
29
+ */
30
+ children: (() => LunaNode) | ((item: Accessor<NonNullable<T>>) => LunaNode);
28
31
  }
29
32
 
30
33
  export interface IndexProps<T> {
@@ -48,8 +51,11 @@ export interface ProviderProps<T> {
48
51
 
49
52
  export interface MatchProps<T> {
50
53
  when: T | Accessor<T>;
51
- /** Must be a function to ensure proper lifecycle (onCleanup/onMount) support */
52
- children: (() => LunaNode) | ((item: NonNullable<T>) => LunaNode);
54
+ /**
55
+ * Children receives an accessor function (SolidJS-style).
56
+ * Use: {(item) => <p>{item()}</p>}
57
+ */
58
+ children: (() => LunaNode) | ((item: Accessor<NonNullable<T>>) => LunaNode);
53
59
  }
54
60
 
55
61
  export interface SwitchProps {
@@ -149,7 +155,7 @@ import {
149
155
  portalToSelector,
150
156
  portalWithShadow,
151
157
  portalToElementWithShadow,
152
- } from "../../../target/js/release/build/platform/js/api/api.js";
158
+ } from "../../../target/js/release/build/js/api/api.js";
153
159
 
154
160
  // ============================================================================
155
161
  // SolidJS-compatible Signal API
@@ -447,6 +453,9 @@ export function For<T>(props: ForProps<T>): any {
447
453
 
448
454
  /**
449
455
  * Show component for conditional rendering (SolidJS-style)
456
+ *
457
+ * The children function receives an accessor (getter function), not the raw value.
458
+ * This matches SolidJS behavior where you use: {(item) => <p>{item()}</p>}
450
459
  */
451
460
  export function Show<T>(props: ShowProps<T>): any {
452
461
  const { when, children } = props;
@@ -455,9 +464,13 @@ export function Show<T>(props: ShowProps<T>): any {
455
464
  // Convert when to a getter if it's not already
456
465
  const condition = typeof when === "function" ? when : () => when;
457
466
 
467
+ // Create a stable accessor for the condition value
468
+ // This matches SolidJS behavior where children receives an accessor
469
+ const valueAccessor = () => condition() as NonNullable<T>;
470
+
458
471
  return show(
459
472
  () => Boolean(condition()),
460
- () => resolveChild(children, condition())
473
+ () => resolveChild(children, valueAccessor)
461
474
  );
462
475
  }
463
476
 
@@ -564,17 +577,22 @@ export function Switch(props: SwitchProps): any {
564
577
 
565
578
  /**
566
579
  * Match component for use inside Switch (SolidJS-style)
580
+ *
581
+ * The children function receives an accessor (getter function), matching SolidJS.
567
582
  */
568
583
  export function Match<T>(props: MatchProps<T>): { __isMatch: true; when: () => boolean; condition: () => T; children: () => any } {
569
584
  const { when, children } = props;
570
585
  const condition = typeof when === "function" ? when : () => when;
571
586
 
587
+ // Create a stable accessor for the condition value (SolidJS-style)
588
+ const valueAccessor = () => condition() as NonNullable<T>;
589
+
572
590
  return {
573
591
  __isMatch: true,
574
592
  when: () => Boolean(condition()),
575
593
  condition,
576
- // Wrap children in a function that resolves with condition value
577
- children: () => resolveChild(children, condition()),
594
+ // Pass accessor instead of raw value to match SolidJS behavior
595
+ children: () => resolveChild(children, valueAccessor),
578
596
  };
579
597
  }
580
598