@hyperfixi/behaviors 2.3.0 → 2.4.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 (71) hide show
  1. package/dist/all.browser.global.js +26 -48
  2. package/dist/all.browser.global.js.map +1 -1
  3. package/dist/behaviors/autodismiss.d.cts +1 -1
  4. package/dist/behaviors/autodismiss.d.ts +1 -1
  5. package/dist/behaviors/clickoutside.d.cts +1 -1
  6. package/dist/behaviors/clickoutside.d.ts +1 -1
  7. package/dist/behaviors/clipboard.d.cts +1 -1
  8. package/dist/behaviors/clipboard.d.ts +1 -1
  9. package/dist/behaviors/draggable.d.cts +1 -1
  10. package/dist/behaviors/draggable.d.ts +1 -1
  11. package/dist/behaviors/focustrap.d.cts +1 -1
  12. package/dist/behaviors/focustrap.d.ts +1 -1
  13. package/dist/behaviors/removable.d.cts +1 -1
  14. package/dist/behaviors/removable.d.ts +1 -1
  15. package/dist/behaviors/resizable.cjs +12 -34
  16. package/dist/behaviors/resizable.cjs.map +1 -1
  17. package/dist/behaviors/resizable.d.cts +1 -1
  18. package/dist/behaviors/resizable.d.ts +1 -1
  19. package/dist/behaviors/resizable.js +2 -2
  20. package/dist/behaviors/scrollreveal.d.cts +1 -1
  21. package/dist/behaviors/scrollreveal.d.ts +1 -1
  22. package/dist/behaviors/sortable.cjs +7 -21
  23. package/dist/behaviors/sortable.cjs.map +1 -1
  24. package/dist/behaviors/sortable.d.cts +1 -1
  25. package/dist/behaviors/sortable.d.ts +1 -1
  26. package/dist/behaviors/sortable.js +2 -2
  27. package/dist/behaviors/tabs.d.cts +1 -1
  28. package/dist/behaviors/tabs.d.ts +1 -1
  29. package/dist/behaviors/toggleable.d.cts +1 -1
  30. package/dist/behaviors/toggleable.d.ts +1 -1
  31. package/dist/{chunk-MVNHMYIK.js → chunk-BBIIOGMF.js} +3 -3
  32. package/dist/{chunk-TLLGH5KX.js → chunk-IMDFEGIT.js} +3 -3
  33. package/dist/{chunk-TLLGH5KX.js.map → chunk-IMDFEGIT.js.map} +1 -1
  34. package/dist/{chunk-IQM32TEY.js → chunk-IT6TYVMW.js} +3 -3
  35. package/dist/{chunk-IQM32TEY.js.map → chunk-IT6TYVMW.js.map} +1 -1
  36. package/dist/{chunk-NC6I6T7T.js → chunk-V2M4W3LO.js} +7 -21
  37. package/dist/chunk-V2M4W3LO.js.map +1 -0
  38. package/dist/{chunk-U5GNXZUF.js → chunk-ZBSWTV6I.js} +12 -34
  39. package/dist/chunk-ZBSWTV6I.js.map +1 -0
  40. package/dist/index.cjs +19 -55
  41. package/dist/index.cjs.map +1 -1
  42. package/dist/index.d.cts +2 -2
  43. package/dist/index.d.ts +2 -2
  44. package/dist/index.js +5 -5
  45. package/dist/loaders.cjs +19 -55
  46. package/dist/loaders.cjs.map +1 -1
  47. package/dist/loaders.js +3 -3
  48. package/dist/registry.d.cts +1 -1
  49. package/dist/registry.d.ts +1 -1
  50. package/dist/resizable.browser.global.js +13 -28
  51. package/dist/resizable.browser.global.js.map +1 -1
  52. package/dist/resolver.browser.global.js +20 -42
  53. package/dist/resolver.browser.global.js.map +1 -1
  54. package/dist/schemas/index.cjs +17 -53
  55. package/dist/schemas/index.cjs.map +1 -1
  56. package/dist/schemas/index.d.cts +2 -2
  57. package/dist/schemas/index.d.ts +2 -2
  58. package/dist/schemas/index.js +2 -2
  59. package/dist/sortable.browser.global.js +8 -15
  60. package/dist/sortable.browser.global.js.map +1 -1
  61. package/dist/{types-DCCtVQS5.d.ts → types-BY-jB5FV.d.cts} +1 -1
  62. package/dist/{types-DCCtVQS5.d.cts → types-BY-jB5FV.d.ts} +1 -1
  63. package/package.json +2 -2
  64. package/src/behaviors/resizable.ts +1 -1
  65. package/src/behaviors/sortable.ts +1 -1
  66. package/src/browser-resolver-bundle.ts +1 -1
  67. package/src/schemas/resizable.schema.ts +11 -33
  68. package/src/schemas/sortable.schema.ts +6 -20
  69. package/dist/chunk-NC6I6T7T.js.map +0 -1
  70. package/dist/chunk-U5GNXZUF.js.map +0 -1
  71. /package/dist/{chunk-MVNHMYIK.js.map → chunk-BBIIOGMF.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/schemas/index.ts","../../src/schemas/draggable.schema.ts","../../src/schemas/sortable.schema.ts","../../src/schemas/resizable.schema.ts","../../src/schemas/removable.schema.ts","../../src/schemas/toggleable.schema.ts","../../src/schemas/clipboard.schema.ts","../../src/schemas/autodismiss.schema.ts","../../src/schemas/clickoutside.schema.ts","../../src/schemas/focustrap.schema.ts","../../src/schemas/scrollreveal.schema.ts","../../src/schemas/tabs.schema.ts"],"sourcesContent":["/**\n * Behavior Schemas\n *\n * Central export point for all behavior schemas.\n * Used by the registry and code generation.\n */\n\n// Types\nexport type {\n BehaviorSchema,\n BehaviorCategory,\n BehaviorTier,\n ParameterSchema,\n EventSchema,\n BehaviorModule,\n LokaScriptInstance,\n} from './types';\n\n// Individual schemas\nexport { draggableSchema } from './draggable.schema';\nexport { sortableSchema } from './sortable.schema';\nexport { resizableSchema } from './resizable.schema';\nexport { removableSchema } from './removable.schema';\nexport { toggleableSchema } from './toggleable.schema';\nexport { clipboardSchema } from './clipboard.schema';\nexport { autoDismissSchema } from './autodismiss.schema';\nexport { clickOutsideSchema } from './clickoutside.schema';\nexport { focusTrapSchema } from './focustrap.schema';\nexport { scrollRevealSchema } from './scrollreveal.schema';\nexport { tabsSchema } from './tabs.schema';\n\n// All schemas as a collection\nimport { draggableSchema } from './draggable.schema';\nimport { sortableSchema } from './sortable.schema';\nimport { resizableSchema } from './resizable.schema';\nimport { removableSchema } from './removable.schema';\nimport { toggleableSchema } from './toggleable.schema';\nimport { clipboardSchema } from './clipboard.schema';\nimport { autoDismissSchema } from './autodismiss.schema';\nimport { clickOutsideSchema } from './clickoutside.schema';\nimport { focusTrapSchema } from './focustrap.schema';\nimport { scrollRevealSchema } from './scrollreveal.schema';\nimport { tabsSchema } from './tabs.schema';\nimport type { BehaviorSchema } from './types';\n\n/**\n * All behavior schemas indexed by name.\n */\nexport const ALL_SCHEMAS: Record<string, BehaviorSchema> = {\n Draggable: draggableSchema,\n Sortable: sortableSchema,\n Resizable: resizableSchema,\n Removable: removableSchema,\n Toggleable: toggleableSchema,\n Clipboard: clipboardSchema,\n AutoDismiss: autoDismissSchema,\n ClickOutside: clickOutsideSchema,\n FocusTrap: focusTrapSchema,\n ScrollReveal: scrollRevealSchema,\n Tabs: tabsSchema,\n};\n\n/**\n * Get all schema names.\n */\nexport function getSchemaNames(): string[] {\n return Object.keys(ALL_SCHEMAS);\n}\n\n/**\n * Find a schema by name. Returns undefined if not found.\n *\n * Note: For the throwing version, use `getSchema()` from the registry\n * (exported from '@hyperfixi/behaviors').\n */\nexport function findSchema(name: string): BehaviorSchema | undefined {\n return ALL_SCHEMAS[name];\n}\n","import type { BehaviorSchema } from './types';\n\n/**\n * Draggable Behavior Schema\n *\n * Makes elements draggable with pointer events.\n * Supports custom drag handles and lifecycle events.\n */\nexport const draggableSchema: BehaviorSchema = {\n name: 'Draggable',\n category: 'ui',\n tier: 'core',\n version: '1.0.0',\n description: 'Makes elements draggable with pointer events',\n parameters: [\n {\n name: 'dragHandle',\n type: 'selector',\n optional: true,\n default: 'me',\n description: 'CSS selector for the drag handle element',\n },\n ],\n events: [\n { name: 'draggable:start', description: 'Fired when drag begins' },\n { name: 'draggable:move', description: 'Fired during each movement' },\n { name: 'draggable:end', description: 'Fired when drag completes' },\n ],\n requirements: ['position: absolute or position: fixed on the element'],\n source: `\nbehavior Draggable(dragHandle)\n init\n if no dragHandle set dragHandle to me\n end\n on pointerdown(clientX, clientY) from dragHandle\n halt the event\n trigger draggable:start\n measure x\n set startX to it\n measure y\n set startY to it\n set xoff to clientX - startX\n set yoff to clientY - startY\n repeat until event pointerup from document\n wait for pointermove(clientX, clientY) or\n pointerup(clientX, clientY) from document\n add { left: \\${clientX - xoff}px; top: \\${clientY - yoff}px; }\n trigger draggable:move\n end\n trigger draggable:end\n end\nend\n`.trim(),\n};\n","import type { BehaviorSchema } from './types';\n\n/**\n * Sortable Behavior Schema\n *\n * Drag-and-drop reordering of list items.\n * Apply to a container element; children become sortable.\n *\n * Note: This behavior fires lifecycle events but does NOT automatically\n * reorder DOM elements. Users must handle actual reordering in their\n * `sortable:move` event handlers.\n */\nexport const sortableSchema: BehaviorSchema = {\n name: 'Sortable',\n category: 'ui',\n tier: 'common',\n version: '1.0.0',\n description: 'Makes child elements reorderable via drag-and-drop',\n parameters: [\n {\n name: 'handle',\n type: 'selector',\n optional: true,\n default: 'none',\n description: 'CSS selector for drag handles within items',\n },\n {\n name: 'dragClass',\n type: 'string',\n optional: true,\n default: 'sorting',\n description: 'CSS class added to item during drag',\n },\n ],\n events: [\n { name: 'sortable:start', description: 'Fired when drag begins' },\n {\n name: 'sortable:move',\n description: 'Fired during drag — handle this event to reorder DOM elements',\n },\n { name: 'sortable:end', description: 'Fired when drag completes' },\n ],\n requirements: ['Users must handle DOM reordering in sortable:move event handlers'],\n source: `\nbehavior Sortable(handle, dragClass)\n init\n if dragClass is undefined\n set dragClass to \"sorting\"\n end\n end\n on pointerdown(clientY) from me\n js(me, handle, event)\n var target = event.target;\n var item = target.closest(\"li\");\n if (!item || !me.contains(item)) return false;\n if (handle && !target.closest(handle)) return false;\n event.preventDefault();\n event.stopPropagation();\n return true;\n end\n if it is false\n exit\n end\n add .{dragClass} to me\n trigger sortable:start on me\n repeat until event pointerup from document\n wait for pointermove(clientY) from document\n trigger sortable:move on me\n end\n remove .{dragClass} from me\n trigger sortable:end on me\n end\nend`.trim(),\n};\n","import type { BehaviorSchema } from './types';\n\n/**\n * Resizable Behavior Schema\n *\n * Makes elements resizable by dragging edges or corners.\n * Supports minimum/maximum dimensions and resize handles.\n */\nexport const resizableSchema: BehaviorSchema = {\n name: 'Resizable',\n category: 'ui',\n tier: 'optional',\n version: '1.0.0',\n description: 'Makes elements resizable by dragging',\n parameters: [\n {\n name: 'handle',\n type: 'selector',\n optional: true,\n default: 'me',\n description: 'CSS selector for the resize handle (defaults to the element itself)',\n },\n {\n name: 'minWidth',\n type: 'number',\n optional: true,\n default: 50,\n description: 'Minimum width in pixels',\n },\n {\n name: 'minHeight',\n type: 'number',\n optional: true,\n default: 50,\n description: 'Minimum height in pixels',\n },\n {\n name: 'maxWidth',\n type: 'number',\n optional: true,\n default: 9999,\n description: 'Maximum width in pixels',\n },\n {\n name: 'maxHeight',\n type: 'number',\n optional: true,\n default: 9999,\n description: 'Maximum height in pixels',\n },\n ],\n events: [\n { name: 'resizable:start', description: 'Fired when resize begins' },\n { name: 'resizable:resize', description: 'Fired during resize' },\n { name: 'resizable:end', description: 'Fired when resize completes' },\n ],\n source: `\nbehavior Resizable(handle, minWidth, minHeight, maxWidth, maxHeight)\n init\n if handle is undefined\n set handle to me\n end\n if minWidth is undefined\n set minWidth to 50\n end\n if minHeight is undefined\n set minHeight to 50\n end\n if maxWidth is undefined\n set maxWidth to 9999\n end\n if maxHeight is undefined\n set maxHeight to 9999\n end\n end\n on pointerdown(clientX, clientY) from handle\n halt the event\n trigger resizable:start\n measure width\n set startWidth to it\n measure height\n set startHeight to it\n set startX to clientX\n set startY to clientY\n repeat until event pointerup from document\n wait for pointermove(clientX, clientY) or pointerup from document\n js(startWidth, startHeight, clientX, clientY, startX, startY, minWidth, maxWidth, minHeight, maxHeight, me)\n var nw = Math.max(minWidth, Math.min(maxWidth, startWidth + (clientX - startX)));\n var nh = Math.max(minHeight, Math.min(maxHeight, startHeight + (clientY - startY)));\n me.style.width = nw + 'px';\n me.style.height = nh + 'px';\n end\n trigger resizable:resize\n end\n trigger resizable:end\n end\nend\n`.trim(),\n};\n","import type { BehaviorSchema } from './types';\n\n/**\n * Removable Behavior Schema\n *\n * Removes an element when a trigger is clicked.\n * Supports optional confirmation and transition effects.\n *\n * @since 1.2.0 — `trigger` parameter renamed to `triggerEl` to avoid\n * shadowing the hyperscript `trigger` command keyword. Users migrating\n * from v1.x should update: `install Removable(triggerEl: .close-btn)`.\n */\nexport const removableSchema: BehaviorSchema = {\n name: 'Removable',\n category: 'data',\n tier: 'common',\n version: '1.2.0',\n description: 'Makes elements removable on click',\n parameters: [\n {\n name: 'triggerEl',\n type: 'selector',\n optional: true,\n default: 'me',\n description: 'Element that triggers removal (e.g., a close button)',\n },\n {\n name: 'confirmRemoval',\n type: 'boolean',\n optional: true,\n default: false,\n description: 'Show confirmation dialog before removal',\n },\n {\n name: 'effect',\n type: 'string',\n optional: true,\n default: 'none',\n enum: ['fade', 'none'],\n description: 'Transition effect: \"fade\" or \"none\"',\n },\n ],\n events: [\n { name: 'removable:before', description: 'Fired before removal (cancelable)' },\n { name: 'removable:removed', description: 'Fired after removal' },\n ],\n source: `\nbehavior Removable(triggerEl, confirmRemoval, effect)\n init\n if triggerEl is undefined\n set triggerEl to me\n end\n end\n on click from triggerEl\n if confirmRemoval\n js(me)\n if (!window.confirm(\"Are you sure?\")) return \"cancel\";\n end\n if it is \"cancel\"\n halt\n end\n end\n trigger removable:before\n if effect is \"fade\"\n transition opacity to 0 over 300ms\n end\n trigger removable:removed\n remove me\n end\nend\n`.trim(),\n};\n","import type { BehaviorSchema } from './types';\n\n/**\n * Toggleable Behavior Schema\n *\n * Toggles a CSS class on click.\n * Useful for accordions, dropdowns, and toggle buttons.\n */\nexport const toggleableSchema: BehaviorSchema = {\n name: 'Toggleable',\n category: 'form',\n tier: 'core',\n version: '1.0.0',\n description: 'Toggles a CSS class on click',\n parameters: [\n {\n name: 'cls',\n type: 'string',\n optional: true,\n default: 'active',\n description: 'CSS class to toggle',\n },\n {\n name: 'target',\n type: 'selector',\n optional: true,\n default: 'me',\n description: 'Element to toggle the class on',\n },\n ],\n events: [\n { name: 'toggleable:on', description: 'Fired when class is added' },\n { name: 'toggleable:off', description: 'Fired when class is removed' },\n ],\n source: `\nbehavior Toggleable(cls, target)\n init\n if cls is undefined\n set cls to \"active\"\n end\n if target is undefined\n set target to me\n end\n end\n on click\n toggle .{cls} on target\n js(target, cls)\n var eventName = target.classList.contains(cls) ? 'toggleable:on' : 'toggleable:off';\n target.dispatchEvent(new CustomEvent(eventName, { bubbles: true }));\n end\n end\nend`.trim(),\n};\n","import type { BehaviorSchema } from './types';\n\n/**\n * Clipboard Behavior Schema\n *\n * Copies text to clipboard on click with visual feedback.\n * Uses the Clipboard API with execCommand fallback.\n */\nexport const clipboardSchema: BehaviorSchema = {\n name: 'Clipboard',\n category: 'ui',\n tier: 'core',\n version: '1.0.0',\n description: 'Copies text to clipboard on click with visual feedback',\n parameters: [\n {\n name: 'text',\n type: 'string',\n optional: true,\n description: 'Literal text to copy (takes priority over source)',\n },\n {\n name: 'source',\n type: 'selector',\n optional: true,\n default: 'me',\n description: 'Element whose textContent or value is copied',\n },\n {\n name: 'feedback',\n type: 'selector',\n optional: true,\n description: 'Element to show .copied feedback on (defaults to the installed element)',\n },\n {\n name: 'feedbackDuration',\n type: 'number',\n optional: true,\n default: 2000,\n description: 'Duration in ms to show .copied class feedback',\n },\n ],\n events: [\n { name: 'clipboard:copied', description: 'Fired after text is copied successfully' },\n { name: 'clipboard:error', description: 'Fired when clipboard write fails' },\n ],\n requirements: [\n 'navigator.clipboard.writeText() requires HTTPS or localhost',\n 'Falls back to document.execCommand(\"copy\") for older browsers',\n ],\n source: `\nbehavior Clipboard(text, source, feedback, feedbackDuration)\n init\n if feedbackDuration is undefined\n set feedbackDuration to 2000\n end\n if source is undefined\n set source to me\n end\n end\n on click\n if text is not undefined\n set copyText to text\n else\n set copyText to source's textContent\n end\n js(me, copyText, feedback, feedbackDuration)\n async function copyToClipboard(t) {\n if (navigator.clipboard && navigator.clipboard.writeText) {\n await navigator.clipboard.writeText(t);\n return;\n }\n var ta = document.createElement('textarea');\n ta.value = t;\n ta.style.position = 'fixed';\n ta.style.opacity = '0';\n document.body.appendChild(ta);\n ta.select();\n try { document.execCommand('copy'); } finally { document.body.removeChild(ta); }\n }\n try {\n await copyToClipboard(copyText);\n var feedbackEl = feedback ? (typeof feedback === 'string' ? document.querySelector(feedback) : feedback) : me;\n if (!feedbackEl) feedbackEl = me;\n feedbackEl.classList.add('copied');\n me.dispatchEvent(new CustomEvent('clipboard:copied', { bubbles: true, detail: { text: copyText } }));\n setTimeout(function() { feedbackEl.classList.remove('copied'); }, feedbackDuration);\n } catch(err) {\n me.dispatchEvent(new CustomEvent('clipboard:error', { bubbles: true, detail: { error: err } }));\n }\n end\n end\nend`.trim(),\n};\n","import type { BehaviorSchema } from './types';\n\n/**\n * AutoDismiss Behavior Schema\n *\n * Auto-removes flash messages and toasts after a configurable delay.\n * Supports pause-on-hover and fade effect.\n */\nexport const autoDismissSchema: BehaviorSchema = {\n name: 'AutoDismiss',\n category: 'ui',\n tier: 'core',\n version: '1.0.0',\n description: 'Auto-removes elements after a delay with optional pause-on-hover',\n parameters: [\n {\n name: 'delay',\n type: 'number',\n optional: true,\n default: 5000,\n description: 'Time in ms before the element is removed',\n },\n {\n name: 'pauseOnHover',\n type: 'boolean',\n optional: true,\n default: true,\n description: 'Pause the countdown when the mouse hovers over the element',\n },\n {\n name: 'effect',\n type: 'string',\n optional: true,\n default: 'none',\n enum: ['fade', 'none'],\n description: 'Transition effect before removal: \"fade\" or \"none\"',\n },\n ],\n events: [\n { name: 'autodismiss:start', description: 'Fired when the countdown timer starts' },\n {\n name: 'autodismiss:dismissed',\n description: 'Fired before removal (cancelable via preventDefault)',\n },\n { name: 'autodismiss:paused', description: 'Fired when the timer is paused on hover' },\n { name: 'autodismiss:resumed', description: 'Fired when the timer resumes on mouseleave' },\n ],\n source: `\nbehavior AutoDismiss(delay, pauseOnHover, effect)\n init\n if delay is undefined\n set delay to 5000\n end\n if pauseOnHover is undefined\n set pauseOnHover to true\n end\n if effect is undefined\n set effect to \"none\"\n end\n js(me, delay, effect, pauseOnHover)\n me.dispatchEvent(new CustomEvent('autodismiss:start', { bubbles: true }));\n var remaining = delay;\n var startedAt = Date.now();\n var timerId = null;\n function dismiss() {\n var ev = new CustomEvent('autodismiss:dismissed', { bubbles: true, cancelable: true });\n me.dispatchEvent(ev);\n if (ev.defaultPrevented) return;\n if (effect === 'fade') {\n me.style.transition = 'opacity 300ms';\n me.style.opacity = '0';\n setTimeout(function() { me.remove(); }, 300);\n } else {\n me.remove();\n }\n }\n function start() {\n startedAt = Date.now();\n timerId = setTimeout(dismiss, remaining);\n }\n start();\n if (pauseOnHover) {\n me.addEventListener('mouseenter', function() {\n if (timerId != null) {\n clearTimeout(timerId);\n timerId = null;\n remaining -= Date.now() - startedAt;\n if (remaining < 0) remaining = 0;\n me.dispatchEvent(new CustomEvent('autodismiss:paused', { bubbles: true }));\n }\n });\n me.addEventListener('mouseleave', function() {\n if (timerId == null && me.isConnected) {\n me.dispatchEvent(new CustomEvent('autodismiss:resumed', { bubbles: true }));\n start();\n }\n });\n }\n end\n end\nend`.trim(),\n};\n","import type { BehaviorSchema } from './types';\n\n/**\n * ClickOutside Behavior Schema\n *\n * Fires an event when the user clicks outside the element.\n * Uses pointerdown instead of click to avoid timing issues.\n */\nexport const clickOutsideSchema: BehaviorSchema = {\n name: 'ClickOutside',\n category: 'ui',\n tier: 'core',\n version: '1.0.0',\n description: 'Fires an event when the user clicks outside the element',\n parameters: [\n {\n name: 'active',\n type: 'boolean',\n optional: true,\n default: true,\n description: 'Whether the listener is active (can be toggled programmatically)',\n },\n ],\n events: [\n { name: 'clickoutside', description: 'Fired when a pointer press occurs outside the element' },\n {\n name: 'clickoutside:activate',\n description: 'Listen for this event to programmatically activate detection',\n },\n {\n name: 'clickoutside:deactivate',\n description: 'Listen for this event to programmatically deactivate detection',\n },\n ],\n requirements: ['Uses pointerdown instead of click to avoid timing issues with removed elements'],\n source: `\nbehavior ClickOutside(active)\n init\n if active is undefined\n set active to true\n end\n end\n on pointerdown from document\n js(me, active)\n if (!me.isConnected) return;\n if (active && !me.contains(event.target)) {\n me.dispatchEvent(new CustomEvent('clickoutside', { bubbles: true }));\n }\n end\n end\n on clickoutside:activate\n set active to true\n end\n on clickoutside:deactivate\n set active to false\n end\nend`.trim(),\n};\n","import type { BehaviorSchema } from './types';\n\n/**\n * FocusTrap Behavior Schema\n *\n * Confines Tab navigation inside an element and restores focus on release.\n * Manages aria-modal for accessibility compliance.\n */\nexport const focusTrapSchema: BehaviorSchema = {\n name: 'FocusTrap',\n category: 'ui',\n tier: 'core',\n version: '1.0.0',\n description: 'Confines Tab navigation inside an element with ARIA support',\n parameters: [\n {\n name: 'active',\n type: 'boolean',\n optional: true,\n default: true,\n description: 'Whether the trap is active on install',\n },\n {\n name: 'initialFocus',\n type: 'selector',\n optional: true,\n description: 'Element to focus when the trap activates',\n },\n {\n name: 'returnFocus',\n type: 'boolean',\n optional: true,\n default: true,\n description: 'Restore focus to the previously focused element on deactivation',\n },\n ],\n events: [\n { name: 'focustrap:activated', description: 'Fired when the trap is activated' },\n { name: 'focustrap:deactivated', description: 'Fired when the trap is deactivated' },\n ],\n requirements: [\n 'Sets aria-modal=\"true\" on the element when active',\n 'Listens for focustrap:activate and focustrap:deactivate custom events for programmatic control',\n ],\n source: `\nbehavior FocusTrap(active, initialFocus, returnFocus)\n init\n if active is undefined\n set active to true\n end\n if returnFocus is undefined\n set returnFocus to true\n end\n js(me, active, initialFocus, returnFocus)\n var FOCUSABLE = 'a[href],button:not(:disabled),input:not(:disabled),select:not(:disabled),textarea:not(:disabled),[tabindex]:not([tabindex=\"-1\"])';\n var isActive = false;\n var previouslyFocused = null;\n function getFocusable() { return Array.from(me.querySelectorAll(FOCUSABLE)); }\n function activate() {\n if (isActive) return;\n isActive = true;\n previouslyFocused = document.activeElement;\n me.setAttribute('aria-modal', 'true');\n var initEl = initialFocus ? (typeof initialFocus === 'string' ? me.querySelector(initialFocus) : initialFocus) : null;\n if (initEl) { initEl.focus(); } else { var f = getFocusable(); if (f.length) f[0].focus(); }\n me.dispatchEvent(new CustomEvent('focustrap:activated', { bubbles: true }));\n }\n function deactivate() {\n if (!isActive) return;\n isActive = false;\n me.removeAttribute('aria-modal');\n if (returnFocus && previouslyFocused instanceof HTMLElement) previouslyFocused.focus();\n previouslyFocused = null;\n me.dispatchEvent(new CustomEvent('focustrap:deactivated', { bubbles: true }));\n }\n me.addEventListener('keydown', function(e) {\n if (!isActive || e.key !== 'Tab') return;\n var focusable = getFocusable();\n if (focusable.length === 0) { e.preventDefault(); return; }\n e.preventDefault();\n var idx = focusable.indexOf(document.activeElement);\n if (e.shiftKey) {\n focusable[idx <= 0 ? focusable.length - 1 : idx - 1].focus();\n } else {\n focusable[idx >= focusable.length - 1 ? 0 : idx + 1].focus();\n }\n });\n me.addEventListener('focustrap:activate', function() { activate(); });\n me.addEventListener('focustrap:deactivate', function() { deactivate(); });\n if (active) activate();\n end\n end\nend`.trim(),\n};\n","import type { BehaviorSchema } from './types';\n\n/**\n * ScrollReveal Behavior Schema\n *\n * Adds a class or fires events when the element enters or exits the viewport.\n * Uses the IntersectionObserver web standard API.\n */\nexport const scrollRevealSchema: BehaviorSchema = {\n name: 'ScrollReveal',\n category: 'layout',\n tier: 'common',\n version: '1.0.0',\n description: 'Adds a class when the element enters the viewport via IntersectionObserver',\n parameters: [\n {\n name: 'cls',\n type: 'string',\n optional: true,\n default: 'revealed',\n description: 'CSS class added when element enters viewport',\n },\n {\n name: 'threshold',\n type: 'number',\n optional: true,\n default: 0.1,\n description: 'Intersection ratio threshold (0-1) for triggering',\n },\n {\n name: 'once',\n type: 'boolean',\n optional: true,\n default: true,\n description: 'If true, disconnect observer after first intersection',\n },\n ],\n events: [\n { name: 'scrollreveal:enter', description: 'Fired when the element enters the viewport' },\n { name: 'scrollreveal:exit', description: 'Fired when the element exits the viewport' },\n ],\n requirements: ['Uses IntersectionObserver API (supported in all modern browsers)'],\n source: `\nbehavior ScrollReveal(cls, threshold, once)\n init\n if cls is undefined\n set cls to \"revealed\"\n end\n if threshold is undefined\n set threshold to 0.1\n end\n if once is undefined\n set once to true\n end\n js(me, cls, threshold, once)\n var obs = new IntersectionObserver(function(entries) {\n for (var i = 0; i < entries.length; i++) {\n if (entries[i].isIntersecting) {\n me.classList.add(cls);\n me.dispatchEvent(new CustomEvent('scrollreveal:enter', { bubbles: true }));\n if (once) obs.disconnect();\n } else if (!once) {\n me.classList.remove(cls);\n me.dispatchEvent(new CustomEvent('scrollreveal:exit', { bubbles: true }));\n }\n }\n }, { threshold: threshold });\n obs.observe(me);\n end\n end\nend`.trim(),\n};\n","import type { BehaviorSchema } from './types';\n\nexport const tabsSchema: BehaviorSchema = {\n name: 'Tabs',\n category: 'ui',\n tier: 'core',\n version: '1.0.0',\n description:\n 'WAI-ARIA compliant tabs with roving tabindex keyboard navigation. ' +\n 'Auto-wires role, aria-selected, aria-controls, and aria-labelledby attributes.',\n parameters: [\n {\n name: 'orientation',\n type: 'string',\n optional: true,\n default: 'horizontal',\n enum: ['horizontal', 'vertical'],\n description: 'Arrow key direction: horizontal (Left/Right) or vertical (Up/Down)',\n },\n {\n name: 'activeTab',\n type: 'number',\n optional: true,\n default: 0,\n description: 'Initial active tab index (zero-based)',\n },\n {\n name: 'wrap',\n type: 'boolean',\n optional: true,\n default: true,\n description: 'Wrap to first/last tab when navigating past the end',\n },\n {\n name: 'activeClass',\n type: 'string',\n optional: true,\n default: 'active',\n description: 'CSS class applied to the active tab and its panel',\n },\n ],\n events: [\n {\n name: 'tabs:change',\n description: 'Fired before tab selection changes (cancelable via preventDefault)',\n },\n { name: 'tabs:changed', description: 'Fired after tab selection has changed' },\n ],\n requirements: [\n 'Sets role=\"tablist\" on the tab container',\n 'Sets role=\"tab\" on tab buttons and role=\"tabpanel\" on content panels',\n 'Manages aria-selected, aria-controls, aria-labelledby, and tabindex',\n 'Keyboard: Arrow keys navigate, Home/End jump to first/last, Tab exits tablist',\n ],\n source: `\nbehavior Tabs(orientation, activeTab, wrap, activeClass)\n init\n if orientation is undefined\n set orientation to \"horizontal\"\n end\n if activeTab is undefined\n set activeTab to 0\n end\n if wrap is undefined\n set wrap to true\n end\n if activeClass is undefined\n set activeClass to \"active\"\n end\n js(me, orientation, activeTab, wrap, activeClass)\n var tabs = Array.from(me.querySelectorAll('[role=\"tab\"]'));\n var panels = Array.from(me.querySelectorAll('[role=\"tabpanel\"]'));\n if (tabs.length === 0 || panels.length === 0) return;\n var tablist = me.querySelector('[role=\"tablist\"]') || tabs[0].parentElement;\n if (tablist) tablist.setAttribute('aria-orientation', orientation);\n var count = Math.min(tabs.length, panels.length);\n var idN = 0;\n for (var i = 0; i < count; i++) {\n if (!tabs[i].id) tabs[i].id = 'tab-' + (++idN);\n if (!panels[i].id) panels[i].id = 'tabpanel-' + idN;\n tabs[i].setAttribute('aria-controls', panels[i].id);\n panels[i].setAttribute('aria-labelledby', tabs[i].id);\n }\n var cur = Math.max(0, Math.min(activeTab, count - 1));\n function activate(idx, prev) {\n if (idx === prev || idx < 0 || idx >= count) return false;\n var ev = new CustomEvent('tabs:change', { bubbles: true, cancelable: true, detail: { index: idx, previousIndex: prev } });\n me.dispatchEvent(ev);\n if (ev.defaultPrevented) return false;\n if (prev >= 0 && prev < count) {\n tabs[prev].setAttribute('aria-selected', 'false');\n tabs[prev].setAttribute('tabindex', '-1');\n tabs[prev].classList.remove(activeClass);\n panels[prev].setAttribute('aria-hidden', 'true');\n panels[prev].classList.remove(activeClass);\n }\n tabs[idx].setAttribute('aria-selected', 'true');\n tabs[idx].setAttribute('tabindex', '0');\n tabs[idx].classList.add(activeClass);\n panels[idx].setAttribute('aria-hidden', 'false');\n panels[idx].classList.add(activeClass);\n cur = idx;\n me.dispatchEvent(new CustomEvent('tabs:changed', { bubbles: true, detail: { index: idx } }));\n return true;\n }\n for (var j = 0; j < count; j++) {\n tabs[j].setAttribute('aria-selected', 'false');\n tabs[j].setAttribute('tabindex', '-1');\n panels[j].setAttribute('aria-hidden', 'true');\n panels[j].classList.remove(activeClass);\n }\n tabs[cur].setAttribute('aria-selected', 'true');\n tabs[cur].setAttribute('tabindex', '0');\n tabs[cur].classList.add(activeClass);\n panels[cur].setAttribute('aria-hidden', 'false');\n panels[cur].classList.add(activeClass);\n for (var k = 0; k < count; k++) {\n (function(idx) {\n tabs[idx].addEventListener('click', function() { if (activate(idx, cur)) tabs[idx].focus(); });\n })(k);\n }\n (tablist || me).addEventListener('keydown', function(e) {\n var nk = orientation === 'horizontal' ? 'ArrowRight' : 'ArrowDown';\n var pk = orientation === 'horizontal' ? 'ArrowLeft' : 'ArrowUp';\n var next = null;\n if (e.key === nk) { next = cur + 1; if (next >= count) next = wrap ? 0 : null; }\n else if (e.key === pk) { next = cur - 1; if (next < 0) next = wrap ? count - 1 : null; }\n else if (e.key === 'Home') next = 0;\n else if (e.key === 'End') next = count - 1;\n if (next !== null) { e.preventDefault(); if (activate(next, cur)) tabs[next].focus(); }\n });\n end\n end\nend`.trim(),\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/schemas/index.ts","../../src/schemas/draggable.schema.ts","../../src/schemas/sortable.schema.ts","../../src/schemas/resizable.schema.ts","../../src/schemas/removable.schema.ts","../../src/schemas/toggleable.schema.ts","../../src/schemas/clipboard.schema.ts","../../src/schemas/autodismiss.schema.ts","../../src/schemas/clickoutside.schema.ts","../../src/schemas/focustrap.schema.ts","../../src/schemas/scrollreveal.schema.ts","../../src/schemas/tabs.schema.ts"],"sourcesContent":["/**\n * Behavior Schemas\n *\n * Central export point for all behavior schemas.\n * Used by the registry and code generation.\n */\n\n// Types\nexport type {\n BehaviorSchema,\n BehaviorCategory,\n BehaviorTier,\n ParameterSchema,\n EventSchema,\n BehaviorModule,\n LokaScriptInstance,\n} from './types';\n\n// Individual schemas\nexport { draggableSchema } from './draggable.schema';\nexport { sortableSchema } from './sortable.schema';\nexport { resizableSchema } from './resizable.schema';\nexport { removableSchema } from './removable.schema';\nexport { toggleableSchema } from './toggleable.schema';\nexport { clipboardSchema } from './clipboard.schema';\nexport { autoDismissSchema } from './autodismiss.schema';\nexport { clickOutsideSchema } from './clickoutside.schema';\nexport { focusTrapSchema } from './focustrap.schema';\nexport { scrollRevealSchema } from './scrollreveal.schema';\nexport { tabsSchema } from './tabs.schema';\n\n// All schemas as a collection\nimport { draggableSchema } from './draggable.schema';\nimport { sortableSchema } from './sortable.schema';\nimport { resizableSchema } from './resizable.schema';\nimport { removableSchema } from './removable.schema';\nimport { toggleableSchema } from './toggleable.schema';\nimport { clipboardSchema } from './clipboard.schema';\nimport { autoDismissSchema } from './autodismiss.schema';\nimport { clickOutsideSchema } from './clickoutside.schema';\nimport { focusTrapSchema } from './focustrap.schema';\nimport { scrollRevealSchema } from './scrollreveal.schema';\nimport { tabsSchema } from './tabs.schema';\nimport type { BehaviorSchema } from './types';\n\n/**\n * All behavior schemas indexed by name.\n */\nexport const ALL_SCHEMAS: Record<string, BehaviorSchema> = {\n Draggable: draggableSchema,\n Sortable: sortableSchema,\n Resizable: resizableSchema,\n Removable: removableSchema,\n Toggleable: toggleableSchema,\n Clipboard: clipboardSchema,\n AutoDismiss: autoDismissSchema,\n ClickOutside: clickOutsideSchema,\n FocusTrap: focusTrapSchema,\n ScrollReveal: scrollRevealSchema,\n Tabs: tabsSchema,\n};\n\n/**\n * Get all schema names.\n */\nexport function getSchemaNames(): string[] {\n return Object.keys(ALL_SCHEMAS);\n}\n\n/**\n * Find a schema by name. Returns undefined if not found.\n *\n * Note: For the throwing version, use `getSchema()` from the registry\n * (exported from '@hyperfixi/behaviors').\n */\nexport function findSchema(name: string): BehaviorSchema | undefined {\n return ALL_SCHEMAS[name];\n}\n","import type { BehaviorSchema } from './types';\n\n/**\n * Draggable Behavior Schema\n *\n * Makes elements draggable with pointer events.\n * Supports custom drag handles and lifecycle events.\n */\nexport const draggableSchema: BehaviorSchema = {\n name: 'Draggable',\n category: 'ui',\n tier: 'core',\n version: '1.0.0',\n description: 'Makes elements draggable with pointer events',\n parameters: [\n {\n name: 'dragHandle',\n type: 'selector',\n optional: true,\n default: 'me',\n description: 'CSS selector for the drag handle element',\n },\n ],\n events: [\n { name: 'draggable:start', description: 'Fired when drag begins' },\n { name: 'draggable:move', description: 'Fired during each movement' },\n { name: 'draggable:end', description: 'Fired when drag completes' },\n ],\n requirements: ['position: absolute or position: fixed on the element'],\n source: `\nbehavior Draggable(dragHandle)\n init\n if no dragHandle set dragHandle to me\n end\n on pointerdown(clientX, clientY) from dragHandle\n halt the event\n trigger draggable:start\n measure x\n set startX to it\n measure y\n set startY to it\n set xoff to clientX - startX\n set yoff to clientY - startY\n repeat until event pointerup from document\n wait for pointermove(clientX, clientY) or\n pointerup(clientX, clientY) from document\n add { left: \\${clientX - xoff}px; top: \\${clientY - yoff}px; }\n trigger draggable:move\n end\n trigger draggable:end\n end\nend\n`.trim(),\n};\n","import type { BehaviorSchema } from './types';\n\n/**\n * Sortable Behavior Schema\n *\n * Drag-and-drop reordering of list items.\n * Apply to a container element; children become sortable.\n *\n * Note: This behavior fires lifecycle events but does NOT automatically\n * reorder DOM elements. Users must handle actual reordering in their\n * `sortable:move` event handlers.\n */\nexport const sortableSchema: BehaviorSchema = {\n name: 'Sortable',\n category: 'ui',\n tier: 'common',\n version: '1.0.0',\n description: 'Makes child elements reorderable via drag-and-drop',\n parameters: [\n {\n name: 'dragClass',\n type: 'string',\n optional: true,\n default: 'sorting',\n description: 'CSS class added to item during drag',\n },\n ],\n events: [\n { name: 'sortable:start', description: 'Fired when drag begins' },\n {\n name: 'sortable:move',\n description: 'Fired during drag — handle this event to reorder DOM elements',\n },\n { name: 'sortable:end', description: 'Fired when drag completes' },\n ],\n requirements: ['Users must handle DOM reordering in sortable:move event handlers'],\n source: `\nbehavior Sortable(dragClass)\n init\n if dragClass is undefined\n set dragClass to \"sorting\"\n end\n end\n on pointerdown(clientY) from me\n set item to the closest <li/> to the target\n if item is null\n exit\n end\n halt the event\n add .{dragClass} to item\n trigger sortable:start on me\n repeat until event pointerup from document\n wait for pointermove(clientY) from document\n trigger sortable:move on me\n end\n remove .{dragClass} from item\n trigger sortable:end on me\n end\nend`.trim(),\n};\n","import type { BehaviorSchema } from './types';\n\n/**\n * Resizable Behavior Schema\n *\n * Makes elements resizable by dragging edges or corners.\n * Supports minimum/maximum dimensions and resize handles.\n */\nexport const resizableSchema: BehaviorSchema = {\n name: 'Resizable',\n category: 'ui',\n tier: 'optional',\n version: '1.0.0',\n description: 'Makes elements resizable by dragging',\n parameters: [\n {\n name: 'minWidth',\n type: 'number',\n optional: true,\n default: 50,\n description: 'Minimum width in pixels',\n },\n {\n name: 'minHeight',\n type: 'number',\n optional: true,\n default: 50,\n description: 'Minimum height in pixels',\n },\n {\n name: 'maxWidth',\n type: 'number',\n optional: true,\n default: 9999,\n description: 'Maximum width in pixels',\n },\n {\n name: 'maxHeight',\n type: 'number',\n optional: true,\n default: 9999,\n description: 'Maximum height in pixels',\n },\n ],\n events: [\n { name: 'resizable:start', description: 'Fired when resize begins' },\n { name: 'resizable:resize', description: 'Fired during resize' },\n { name: 'resizable:end', description: 'Fired when resize completes' },\n ],\n source: `\nbehavior Resizable(minWidth, minHeight, maxWidth, maxHeight)\n on pointerdown(clientX, clientY) from me\n halt the event\n trigger resizable:start\n measure width\n set startWidth to it\n measure height\n set startHeight to it\n set startX to clientX\n set startY to clientY\n repeat until event pointerup from document\n wait for pointermove(clientX, clientY) from document\n set newWidth to startWidth + clientX - startX\n set newHeight to startHeight + clientY - startY\n if newWidth < minWidth then set newWidth to minWidth end\n if newWidth > maxWidth then set newWidth to maxWidth end\n if newHeight < minHeight then set newHeight to minHeight end\n if newHeight > maxHeight then set newHeight to maxHeight end\n set my style.width to newWidth + \"px\"\n set my style.height to newHeight + \"px\"\n trigger resizable:resize\n end\n trigger resizable:end\n end\nend\n`.trim(),\n};\n","import type { BehaviorSchema } from './types';\n\n/**\n * Removable Behavior Schema\n *\n * Removes an element when a trigger is clicked.\n * Supports optional confirmation and transition effects.\n *\n * @since 1.2.0 — `trigger` parameter renamed to `triggerEl` to avoid\n * shadowing the hyperscript `trigger` command keyword. Users migrating\n * from v1.x should update: `install Removable(triggerEl: .close-btn)`.\n */\nexport const removableSchema: BehaviorSchema = {\n name: 'Removable',\n category: 'data',\n tier: 'common',\n version: '1.2.0',\n description: 'Makes elements removable on click',\n parameters: [\n {\n name: 'triggerEl',\n type: 'selector',\n optional: true,\n default: 'me',\n description: 'Element that triggers removal (e.g., a close button)',\n },\n {\n name: 'confirmRemoval',\n type: 'boolean',\n optional: true,\n default: false,\n description: 'Show confirmation dialog before removal',\n },\n {\n name: 'effect',\n type: 'string',\n optional: true,\n default: 'none',\n enum: ['fade', 'none'],\n description: 'Transition effect: \"fade\" or \"none\"',\n },\n ],\n events: [\n { name: 'removable:before', description: 'Fired before removal (cancelable)' },\n { name: 'removable:removed', description: 'Fired after removal' },\n ],\n source: `\nbehavior Removable(triggerEl, confirmRemoval, effect)\n init\n if triggerEl is undefined\n set triggerEl to me\n end\n end\n on click from triggerEl\n if confirmRemoval\n js(me)\n if (!window.confirm(\"Are you sure?\")) return \"cancel\";\n end\n if it is \"cancel\"\n halt\n end\n end\n trigger removable:before\n if effect is \"fade\"\n transition opacity to 0 over 300ms\n end\n trigger removable:removed\n remove me\n end\nend\n`.trim(),\n};\n","import type { BehaviorSchema } from './types';\n\n/**\n * Toggleable Behavior Schema\n *\n * Toggles a CSS class on click.\n * Useful for accordions, dropdowns, and toggle buttons.\n */\nexport const toggleableSchema: BehaviorSchema = {\n name: 'Toggleable',\n category: 'form',\n tier: 'core',\n version: '1.0.0',\n description: 'Toggles a CSS class on click',\n parameters: [\n {\n name: 'cls',\n type: 'string',\n optional: true,\n default: 'active',\n description: 'CSS class to toggle',\n },\n {\n name: 'target',\n type: 'selector',\n optional: true,\n default: 'me',\n description: 'Element to toggle the class on',\n },\n ],\n events: [\n { name: 'toggleable:on', description: 'Fired when class is added' },\n { name: 'toggleable:off', description: 'Fired when class is removed' },\n ],\n source: `\nbehavior Toggleable(cls, target)\n init\n if cls is undefined\n set cls to \"active\"\n end\n if target is undefined\n set target to me\n end\n end\n on click\n toggle .{cls} on target\n js(target, cls)\n var eventName = target.classList.contains(cls) ? 'toggleable:on' : 'toggleable:off';\n target.dispatchEvent(new CustomEvent(eventName, { bubbles: true }));\n end\n end\nend`.trim(),\n};\n","import type { BehaviorSchema } from './types';\n\n/**\n * Clipboard Behavior Schema\n *\n * Copies text to clipboard on click with visual feedback.\n * Uses the Clipboard API with execCommand fallback.\n */\nexport const clipboardSchema: BehaviorSchema = {\n name: 'Clipboard',\n category: 'ui',\n tier: 'core',\n version: '1.0.0',\n description: 'Copies text to clipboard on click with visual feedback',\n parameters: [\n {\n name: 'text',\n type: 'string',\n optional: true,\n description: 'Literal text to copy (takes priority over source)',\n },\n {\n name: 'source',\n type: 'selector',\n optional: true,\n default: 'me',\n description: 'Element whose textContent or value is copied',\n },\n {\n name: 'feedback',\n type: 'selector',\n optional: true,\n description: 'Element to show .copied feedback on (defaults to the installed element)',\n },\n {\n name: 'feedbackDuration',\n type: 'number',\n optional: true,\n default: 2000,\n description: 'Duration in ms to show .copied class feedback',\n },\n ],\n events: [\n { name: 'clipboard:copied', description: 'Fired after text is copied successfully' },\n { name: 'clipboard:error', description: 'Fired when clipboard write fails' },\n ],\n requirements: [\n 'navigator.clipboard.writeText() requires HTTPS or localhost',\n 'Falls back to document.execCommand(\"copy\") for older browsers',\n ],\n source: `\nbehavior Clipboard(text, source, feedback, feedbackDuration)\n init\n if feedbackDuration is undefined\n set feedbackDuration to 2000\n end\n if source is undefined\n set source to me\n end\n end\n on click\n if text is not undefined\n set copyText to text\n else\n set copyText to source's textContent\n end\n js(me, copyText, feedback, feedbackDuration)\n async function copyToClipboard(t) {\n if (navigator.clipboard && navigator.clipboard.writeText) {\n await navigator.clipboard.writeText(t);\n return;\n }\n var ta = document.createElement('textarea');\n ta.value = t;\n ta.style.position = 'fixed';\n ta.style.opacity = '0';\n document.body.appendChild(ta);\n ta.select();\n try { document.execCommand('copy'); } finally { document.body.removeChild(ta); }\n }\n try {\n await copyToClipboard(copyText);\n var feedbackEl = feedback ? (typeof feedback === 'string' ? document.querySelector(feedback) : feedback) : me;\n if (!feedbackEl) feedbackEl = me;\n feedbackEl.classList.add('copied');\n me.dispatchEvent(new CustomEvent('clipboard:copied', { bubbles: true, detail: { text: copyText } }));\n setTimeout(function() { feedbackEl.classList.remove('copied'); }, feedbackDuration);\n } catch(err) {\n me.dispatchEvent(new CustomEvent('clipboard:error', { bubbles: true, detail: { error: err } }));\n }\n end\n end\nend`.trim(),\n};\n","import type { BehaviorSchema } from './types';\n\n/**\n * AutoDismiss Behavior Schema\n *\n * Auto-removes flash messages and toasts after a configurable delay.\n * Supports pause-on-hover and fade effect.\n */\nexport const autoDismissSchema: BehaviorSchema = {\n name: 'AutoDismiss',\n category: 'ui',\n tier: 'core',\n version: '1.0.0',\n description: 'Auto-removes elements after a delay with optional pause-on-hover',\n parameters: [\n {\n name: 'delay',\n type: 'number',\n optional: true,\n default: 5000,\n description: 'Time in ms before the element is removed',\n },\n {\n name: 'pauseOnHover',\n type: 'boolean',\n optional: true,\n default: true,\n description: 'Pause the countdown when the mouse hovers over the element',\n },\n {\n name: 'effect',\n type: 'string',\n optional: true,\n default: 'none',\n enum: ['fade', 'none'],\n description: 'Transition effect before removal: \"fade\" or \"none\"',\n },\n ],\n events: [\n { name: 'autodismiss:start', description: 'Fired when the countdown timer starts' },\n {\n name: 'autodismiss:dismissed',\n description: 'Fired before removal (cancelable via preventDefault)',\n },\n { name: 'autodismiss:paused', description: 'Fired when the timer is paused on hover' },\n { name: 'autodismiss:resumed', description: 'Fired when the timer resumes on mouseleave' },\n ],\n source: `\nbehavior AutoDismiss(delay, pauseOnHover, effect)\n init\n if delay is undefined\n set delay to 5000\n end\n if pauseOnHover is undefined\n set pauseOnHover to true\n end\n if effect is undefined\n set effect to \"none\"\n end\n js(me, delay, effect, pauseOnHover)\n me.dispatchEvent(new CustomEvent('autodismiss:start', { bubbles: true }));\n var remaining = delay;\n var startedAt = Date.now();\n var timerId = null;\n function dismiss() {\n var ev = new CustomEvent('autodismiss:dismissed', { bubbles: true, cancelable: true });\n me.dispatchEvent(ev);\n if (ev.defaultPrevented) return;\n if (effect === 'fade') {\n me.style.transition = 'opacity 300ms';\n me.style.opacity = '0';\n setTimeout(function() { me.remove(); }, 300);\n } else {\n me.remove();\n }\n }\n function start() {\n startedAt = Date.now();\n timerId = setTimeout(dismiss, remaining);\n }\n start();\n if (pauseOnHover) {\n me.addEventListener('mouseenter', function() {\n if (timerId != null) {\n clearTimeout(timerId);\n timerId = null;\n remaining -= Date.now() - startedAt;\n if (remaining < 0) remaining = 0;\n me.dispatchEvent(new CustomEvent('autodismiss:paused', { bubbles: true }));\n }\n });\n me.addEventListener('mouseleave', function() {\n if (timerId == null && me.isConnected) {\n me.dispatchEvent(new CustomEvent('autodismiss:resumed', { bubbles: true }));\n start();\n }\n });\n }\n end\n end\nend`.trim(),\n};\n","import type { BehaviorSchema } from './types';\n\n/**\n * ClickOutside Behavior Schema\n *\n * Fires an event when the user clicks outside the element.\n * Uses pointerdown instead of click to avoid timing issues.\n */\nexport const clickOutsideSchema: BehaviorSchema = {\n name: 'ClickOutside',\n category: 'ui',\n tier: 'core',\n version: '1.0.0',\n description: 'Fires an event when the user clicks outside the element',\n parameters: [\n {\n name: 'active',\n type: 'boolean',\n optional: true,\n default: true,\n description: 'Whether the listener is active (can be toggled programmatically)',\n },\n ],\n events: [\n { name: 'clickoutside', description: 'Fired when a pointer press occurs outside the element' },\n {\n name: 'clickoutside:activate',\n description: 'Listen for this event to programmatically activate detection',\n },\n {\n name: 'clickoutside:deactivate',\n description: 'Listen for this event to programmatically deactivate detection',\n },\n ],\n requirements: ['Uses pointerdown instead of click to avoid timing issues with removed elements'],\n source: `\nbehavior ClickOutside(active)\n init\n if active is undefined\n set active to true\n end\n end\n on pointerdown from document\n js(me, active)\n if (!me.isConnected) return;\n if (active && !me.contains(event.target)) {\n me.dispatchEvent(new CustomEvent('clickoutside', { bubbles: true }));\n }\n end\n end\n on clickoutside:activate\n set active to true\n end\n on clickoutside:deactivate\n set active to false\n end\nend`.trim(),\n};\n","import type { BehaviorSchema } from './types';\n\n/**\n * FocusTrap Behavior Schema\n *\n * Confines Tab navigation inside an element and restores focus on release.\n * Manages aria-modal for accessibility compliance.\n */\nexport const focusTrapSchema: BehaviorSchema = {\n name: 'FocusTrap',\n category: 'ui',\n tier: 'core',\n version: '1.0.0',\n description: 'Confines Tab navigation inside an element with ARIA support',\n parameters: [\n {\n name: 'active',\n type: 'boolean',\n optional: true,\n default: true,\n description: 'Whether the trap is active on install',\n },\n {\n name: 'initialFocus',\n type: 'selector',\n optional: true,\n description: 'Element to focus when the trap activates',\n },\n {\n name: 'returnFocus',\n type: 'boolean',\n optional: true,\n default: true,\n description: 'Restore focus to the previously focused element on deactivation',\n },\n ],\n events: [\n { name: 'focustrap:activated', description: 'Fired when the trap is activated' },\n { name: 'focustrap:deactivated', description: 'Fired when the trap is deactivated' },\n ],\n requirements: [\n 'Sets aria-modal=\"true\" on the element when active',\n 'Listens for focustrap:activate and focustrap:deactivate custom events for programmatic control',\n ],\n source: `\nbehavior FocusTrap(active, initialFocus, returnFocus)\n init\n if active is undefined\n set active to true\n end\n if returnFocus is undefined\n set returnFocus to true\n end\n js(me, active, initialFocus, returnFocus)\n var FOCUSABLE = 'a[href],button:not(:disabled),input:not(:disabled),select:not(:disabled),textarea:not(:disabled),[tabindex]:not([tabindex=\"-1\"])';\n var isActive = false;\n var previouslyFocused = null;\n function getFocusable() { return Array.from(me.querySelectorAll(FOCUSABLE)); }\n function activate() {\n if (isActive) return;\n isActive = true;\n previouslyFocused = document.activeElement;\n me.setAttribute('aria-modal', 'true');\n var initEl = initialFocus ? (typeof initialFocus === 'string' ? me.querySelector(initialFocus) : initialFocus) : null;\n if (initEl) { initEl.focus(); } else { var f = getFocusable(); if (f.length) f[0].focus(); }\n me.dispatchEvent(new CustomEvent('focustrap:activated', { bubbles: true }));\n }\n function deactivate() {\n if (!isActive) return;\n isActive = false;\n me.removeAttribute('aria-modal');\n if (returnFocus && previouslyFocused instanceof HTMLElement) previouslyFocused.focus();\n previouslyFocused = null;\n me.dispatchEvent(new CustomEvent('focustrap:deactivated', { bubbles: true }));\n }\n me.addEventListener('keydown', function(e) {\n if (!isActive || e.key !== 'Tab') return;\n var focusable = getFocusable();\n if (focusable.length === 0) { e.preventDefault(); return; }\n e.preventDefault();\n var idx = focusable.indexOf(document.activeElement);\n if (e.shiftKey) {\n focusable[idx <= 0 ? focusable.length - 1 : idx - 1].focus();\n } else {\n focusable[idx >= focusable.length - 1 ? 0 : idx + 1].focus();\n }\n });\n me.addEventListener('focustrap:activate', function() { activate(); });\n me.addEventListener('focustrap:deactivate', function() { deactivate(); });\n if (active) activate();\n end\n end\nend`.trim(),\n};\n","import type { BehaviorSchema } from './types';\n\n/**\n * ScrollReveal Behavior Schema\n *\n * Adds a class or fires events when the element enters or exits the viewport.\n * Uses the IntersectionObserver web standard API.\n */\nexport const scrollRevealSchema: BehaviorSchema = {\n name: 'ScrollReveal',\n category: 'layout',\n tier: 'common',\n version: '1.0.0',\n description: 'Adds a class when the element enters the viewport via IntersectionObserver',\n parameters: [\n {\n name: 'cls',\n type: 'string',\n optional: true,\n default: 'revealed',\n description: 'CSS class added when element enters viewport',\n },\n {\n name: 'threshold',\n type: 'number',\n optional: true,\n default: 0.1,\n description: 'Intersection ratio threshold (0-1) for triggering',\n },\n {\n name: 'once',\n type: 'boolean',\n optional: true,\n default: true,\n description: 'If true, disconnect observer after first intersection',\n },\n ],\n events: [\n { name: 'scrollreveal:enter', description: 'Fired when the element enters the viewport' },\n { name: 'scrollreveal:exit', description: 'Fired when the element exits the viewport' },\n ],\n requirements: ['Uses IntersectionObserver API (supported in all modern browsers)'],\n source: `\nbehavior ScrollReveal(cls, threshold, once)\n init\n if cls is undefined\n set cls to \"revealed\"\n end\n if threshold is undefined\n set threshold to 0.1\n end\n if once is undefined\n set once to true\n end\n js(me, cls, threshold, once)\n var obs = new IntersectionObserver(function(entries) {\n for (var i = 0; i < entries.length; i++) {\n if (entries[i].isIntersecting) {\n me.classList.add(cls);\n me.dispatchEvent(new CustomEvent('scrollreveal:enter', { bubbles: true }));\n if (once) obs.disconnect();\n } else if (!once) {\n me.classList.remove(cls);\n me.dispatchEvent(new CustomEvent('scrollreveal:exit', { bubbles: true }));\n }\n }\n }, { threshold: threshold });\n obs.observe(me);\n end\n end\nend`.trim(),\n};\n","import type { BehaviorSchema } from './types';\n\nexport const tabsSchema: BehaviorSchema = {\n name: 'Tabs',\n category: 'ui',\n tier: 'core',\n version: '1.0.0',\n description:\n 'WAI-ARIA compliant tabs with roving tabindex keyboard navigation. ' +\n 'Auto-wires role, aria-selected, aria-controls, and aria-labelledby attributes.',\n parameters: [\n {\n name: 'orientation',\n type: 'string',\n optional: true,\n default: 'horizontal',\n enum: ['horizontal', 'vertical'],\n description: 'Arrow key direction: horizontal (Left/Right) or vertical (Up/Down)',\n },\n {\n name: 'activeTab',\n type: 'number',\n optional: true,\n default: 0,\n description: 'Initial active tab index (zero-based)',\n },\n {\n name: 'wrap',\n type: 'boolean',\n optional: true,\n default: true,\n description: 'Wrap to first/last tab when navigating past the end',\n },\n {\n name: 'activeClass',\n type: 'string',\n optional: true,\n default: 'active',\n description: 'CSS class applied to the active tab and its panel',\n },\n ],\n events: [\n {\n name: 'tabs:change',\n description: 'Fired before tab selection changes (cancelable via preventDefault)',\n },\n { name: 'tabs:changed', description: 'Fired after tab selection has changed' },\n ],\n requirements: [\n 'Sets role=\"tablist\" on the tab container',\n 'Sets role=\"tab\" on tab buttons and role=\"tabpanel\" on content panels',\n 'Manages aria-selected, aria-controls, aria-labelledby, and tabindex',\n 'Keyboard: Arrow keys navigate, Home/End jump to first/last, Tab exits tablist',\n ],\n source: `\nbehavior Tabs(orientation, activeTab, wrap, activeClass)\n init\n if orientation is undefined\n set orientation to \"horizontal\"\n end\n if activeTab is undefined\n set activeTab to 0\n end\n if wrap is undefined\n set wrap to true\n end\n if activeClass is undefined\n set activeClass to \"active\"\n end\n js(me, orientation, activeTab, wrap, activeClass)\n var tabs = Array.from(me.querySelectorAll('[role=\"tab\"]'));\n var panels = Array.from(me.querySelectorAll('[role=\"tabpanel\"]'));\n if (tabs.length === 0 || panels.length === 0) return;\n var tablist = me.querySelector('[role=\"tablist\"]') || tabs[0].parentElement;\n if (tablist) tablist.setAttribute('aria-orientation', orientation);\n var count = Math.min(tabs.length, panels.length);\n var idN = 0;\n for (var i = 0; i < count; i++) {\n if (!tabs[i].id) tabs[i].id = 'tab-' + (++idN);\n if (!panels[i].id) panels[i].id = 'tabpanel-' + idN;\n tabs[i].setAttribute('aria-controls', panels[i].id);\n panels[i].setAttribute('aria-labelledby', tabs[i].id);\n }\n var cur = Math.max(0, Math.min(activeTab, count - 1));\n function activate(idx, prev) {\n if (idx === prev || idx < 0 || idx >= count) return false;\n var ev = new CustomEvent('tabs:change', { bubbles: true, cancelable: true, detail: { index: idx, previousIndex: prev } });\n me.dispatchEvent(ev);\n if (ev.defaultPrevented) return false;\n if (prev >= 0 && prev < count) {\n tabs[prev].setAttribute('aria-selected', 'false');\n tabs[prev].setAttribute('tabindex', '-1');\n tabs[prev].classList.remove(activeClass);\n panels[prev].setAttribute('aria-hidden', 'true');\n panels[prev].classList.remove(activeClass);\n }\n tabs[idx].setAttribute('aria-selected', 'true');\n tabs[idx].setAttribute('tabindex', '0');\n tabs[idx].classList.add(activeClass);\n panels[idx].setAttribute('aria-hidden', 'false');\n panels[idx].classList.add(activeClass);\n cur = idx;\n me.dispatchEvent(new CustomEvent('tabs:changed', { bubbles: true, detail: { index: idx } }));\n return true;\n }\n for (var j = 0; j < count; j++) {\n tabs[j].setAttribute('aria-selected', 'false');\n tabs[j].setAttribute('tabindex', '-1');\n panels[j].setAttribute('aria-hidden', 'true');\n panels[j].classList.remove(activeClass);\n }\n tabs[cur].setAttribute('aria-selected', 'true');\n tabs[cur].setAttribute('tabindex', '0');\n tabs[cur].classList.add(activeClass);\n panels[cur].setAttribute('aria-hidden', 'false');\n panels[cur].classList.add(activeClass);\n for (var k = 0; k < count; k++) {\n (function(idx) {\n tabs[idx].addEventListener('click', function() { if (activate(idx, cur)) tabs[idx].focus(); });\n })(k);\n }\n (tablist || me).addEventListener('keydown', function(e) {\n var nk = orientation === 'horizontal' ? 'ArrowRight' : 'ArrowDown';\n var pk = orientation === 'horizontal' ? 'ArrowLeft' : 'ArrowUp';\n var next = null;\n if (e.key === nk) { next = cur + 1; if (next >= count) next = wrap ? 0 : null; }\n else if (e.key === pk) { next = cur - 1; if (next < 0) next = wrap ? count - 1 : null; }\n else if (e.key === 'Home') next = 0;\n else if (e.key === 'End') next = count - 1;\n if (next !== null) { e.preventDefault(); if (activate(next, cur)) tabs[next].focus(); }\n });\n end\n end\nend`.trim(),\n};\n"],"mappings":"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","names":[]}
@@ -1,5 +1,5 @@
1
- import { B as BehaviorSchema } from '../types-DCCtVQS5.cjs';
2
- export { b as BehaviorCategory, a as BehaviorModule, c as BehaviorTier, E as EventSchema, L as LokaScriptInstance, P as ParameterSchema } from '../types-DCCtVQS5.cjs';
1
+ import { b as BehaviorSchema } from '../types-BY-jB5FV.cjs';
2
+ export { B as BehaviorCategory, a as BehaviorModule, c as BehaviorTier, E as EventSchema, L as LokaScriptInstance, P as ParameterSchema } from '../types-BY-jB5FV.cjs';
3
3
 
4
4
  /**
5
5
  * Draggable Behavior Schema
@@ -1,5 +1,5 @@
1
- import { B as BehaviorSchema } from '../types-DCCtVQS5.js';
2
- export { b as BehaviorCategory, a as BehaviorModule, c as BehaviorTier, E as EventSchema, L as LokaScriptInstance, P as ParameterSchema } from '../types-DCCtVQS5.js';
1
+ import { b as BehaviorSchema } from '../types-BY-jB5FV.js';
2
+ export { B as BehaviorCategory, a as BehaviorModule, c as BehaviorTier, E as EventSchema, L as LokaScriptInstance, P as ParameterSchema } from '../types-BY-jB5FV.js';
3
3
 
4
4
  /**
5
5
  * Draggable Behavior Schema
@@ -3,13 +3,13 @@ import {
3
3
  } from "../chunk-HMU342XE.js";
4
4
  import {
5
5
  resizableSchema
6
- } from "../chunk-U5GNXZUF.js";
6
+ } from "../chunk-ZBSWTV6I.js";
7
7
  import {
8
8
  scrollRevealSchema
9
9
  } from "../chunk-URZGNPTQ.js";
10
10
  import {
11
11
  sortableSchema
12
- } from "../chunk-NC6I6T7T.js";
12
+ } from "../chunk-V2M4W3LO.js";
13
13
  import {
14
14
  tabsSchema
15
15
  } from "../chunk-HQDYH45I.js";
@@ -1,31 +1,24 @@
1
- "use strict";var HyperFixiBehaviors=(()=>{var s=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var h=Object.prototype.hasOwnProperty;var f=(e,t)=>{for(var r in t)s(e,r,{get:t[r],enumerable:!0})},b=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of v(t))!h.call(e,n)&&n!==r&&s(e,n,{get:()=>t[n],enumerable:!(o=g(t,n))||o.enumerable});return e};var S=e=>b(s({},"__esModule",{value:!0}),e);var E={};f(E,{default:()=>k,registerSortable:()=>c,sortableMetadata:()=>x,sortableSource:()=>w});var i={name:"Sortable",category:"ui",tier:"common",version:"1.0.0",description:"Makes child elements reorderable via drag-and-drop",parameters:[{name:"handle",type:"selector",optional:!0,default:"none",description:"CSS selector for drag handles within items"},{name:"dragClass",type:"string",optional:!0,default:"sorting",description:"CSS class added to item during drag"}],events:[{name:"sortable:start",description:"Fired when drag begins"},{name:"sortable:move",description:"Fired during drag \u2014 handle this event to reorder DOM elements"},{name:"sortable:end",description:"Fired when drag completes"}],requirements:["Users must handle DOM reordering in sortable:move event handlers"],source:`
2
- behavior Sortable(handle, dragClass)
1
+ "use strict";var HyperFixiBehaviors=(()=>{var s=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var h=Object.prototype.hasOwnProperty;var b=(e,t)=>{for(var r in t)s(e,r,{get:t[r],enumerable:!0})},f=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of v(t))!h.call(e,n)&&n!==r&&s(e,n,{get:()=>t[n],enumerable:!(o=g(t,n))||o.enumerable});return e};var S=e=>f(s({},"__esModule",{value:!0}),e);var E={};b(E,{default:()=>k,registerSortable:()=>l,sortableMetadata:()=>x,sortableSource:()=>w});var i={name:"Sortable",category:"ui",tier:"common",version:"1.0.0",description:"Makes child elements reorderable via drag-and-drop",parameters:[{name:"dragClass",type:"string",optional:!0,default:"sorting",description:"CSS class added to item during drag"}],events:[{name:"sortable:start",description:"Fired when drag begins"},{name:"sortable:move",description:"Fired during drag \u2014 handle this event to reorder DOM elements"},{name:"sortable:end",description:"Fired when drag completes"}],requirements:["Users must handle DOM reordering in sortable:move event handlers"],source:`
2
+ behavior Sortable(dragClass)
3
3
  init
4
4
  if dragClass is undefined
5
5
  set dragClass to "sorting"
6
6
  end
7
7
  end
8
8
  on pointerdown(clientY) from me
9
- js(me, handle, event)
10
- var target = event.target;
11
- var item = target.closest("li");
12
- if (!item || !me.contains(item)) return false;
13
- if (handle && !target.closest(handle)) return false;
14
- event.preventDefault();
15
- event.stopPropagation();
16
- return true;
17
- end
18
- if it is false
9
+ set item to the closest <li/> to the target
10
+ if item is null
19
11
  exit
20
12
  end
21
- add .{dragClass} to me
13
+ halt the event
14
+ add .{dragClass} to item
22
15
  trigger sortable:start on me
23
16
  repeat until event pointerup from document
24
17
  wait for pointermove(clientY) from document
25
18
  trigger sortable:move on me
26
19
  end
27
- remove .{dragClass} from me
20
+ remove .{dragClass} from item
28
21
  trigger sortable:end on me
29
22
  end
30
- end`.trim()};function l(){if(typeof window>"u")return null;let e=window;return e.lokascript||e.hyperfixi||null}var w=i.source,x=i;function y(e,t){let r=t.dragClass||"sorting",o=t.handle||null;e.addEventListener("pointerdown",n=>{let d=n.target,a=d.closest("li");if(!a||!e.contains(a)||o&&!d.closest(o))return;n.preventDefault(),a.classList.add(r),e.dispatchEvent(new CustomEvent("sortable:start",{bubbles:!0,detail:{item:a}}));function m(u){e.dispatchEvent(new CustomEvent("sortable:move",{bubbles:!0,detail:{clientY:u.clientY,item:a}}))}function p(){document.removeEventListener("pointermove",m),document.removeEventListener("pointerup",p),a.classList.remove(r),e.dispatchEvent(new CustomEvent("sortable:end",{bubbles:!0,detail:{item:a}}))}document.addEventListener("pointermove",m),document.addEventListener("pointerup",p)})}async function c(e){let t=e||l();if(!t)throw new Error("LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.");let r={type:"behavior",name:"Sortable",parameters:["handle","dragClass"],eventHandlers:[],imperativeInstaller:y},o=t.createContext?t.createContext():{locals:new Map,globals:new Map};await t.execute(r,o)}l()&&c().catch(console.error);var k={source:i.source,metadata:i,register:c};return S(E);})();
23
+ end`.trim()};function c(){if(typeof window>"u")return null;let e=window;return e.lokascript||e.hyperfixi||null}var w=i.source,x=i;function y(e,t){let r=t.dragClass||"sorting",o=t.handle||null;e.addEventListener("pointerdown",n=>{let d=n.target,a=d.closest("li");if(!a||!e.contains(a)||o&&!d.closest(o))return;n.preventDefault(),a.classList.add(r),e.dispatchEvent(new CustomEvent("sortable:start",{bubbles:!0,detail:{item:a}}));function m(u){e.dispatchEvent(new CustomEvent("sortable:move",{bubbles:!0,detail:{clientY:u.clientY,item:a}}))}function p(){document.removeEventListener("pointermove",m),document.removeEventListener("pointerup",p),a.classList.remove(r),e.dispatchEvent(new CustomEvent("sortable:end",{bubbles:!0,detail:{item:a}}))}document.addEventListener("pointermove",m),document.addEventListener("pointerup",p)})}async function l(e){let t=e||c();if(!t)throw new Error("LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.");let r={type:"behavior",name:"Sortable",parameters:["dragClass"],eventHandlers:[],imperativeInstaller:y},o=t.createContext?t.createContext():{locals:new Map,globals:new Map};await t.execute(r,o)}c()&&l().catch(console.error);var k={source:i.source,metadata:i,register:l};return S(E);})();
31
24
  //# sourceMappingURL=sortable.browser.global.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/behaviors/sortable.ts","../src/schemas/sortable.schema.ts","../src/schemas/types.ts"],"sourcesContent":["/**\n * Sortable Behavior — Imperative Implementation\n *\n * Drag-and-drop reordering of list items.\n * Apply to a container element; children become sortable.\n *\n * Note: This behavior fires lifecycle events but does NOT automatically\n * reorder DOM elements. Users must handle actual reordering in their\n * `sortable:move` event handlers.\n *\n * @example\n * ```html\n * <ul _=\"install Sortable\">\n * <li>Item 1</li>\n * <li>Item 2</li>\n * </ul>\n * ```\n */\n\nimport { sortableSchema } from '../schemas/sortable.schema';\nimport type { LokaScriptInstance } from '../schemas/types';\nimport { resolveRuntime } from '../schemas/types';\n\n// Re-export schema-derived values for backwards compatibility\nexport const sortableSource = sortableSchema.source;\nexport const sortableMetadata = sortableSchema;\n\n/**\n * Imperative installer for Sortable behavior.\n */\nfunction installSortable(element: HTMLElement, params: Record<string, any>): void {\n const dragClass = params.dragClass || 'sorting';\n const handleSelector = params.handle || null;\n\n element.addEventListener('pointerdown', (e: PointerEvent) => {\n const target = e.target as HTMLElement;\n const item = target.closest('li');\n if (!item || !element.contains(item)) return;\n\n // If a handle selector is specified, only start drag from the handle\n if (handleSelector) {\n const handleEl = target.closest(handleSelector);\n if (!handleEl) return;\n }\n\n e.preventDefault();\n item.classList.add(dragClass);\n element.dispatchEvent(new CustomEvent('sortable:start', { bubbles: true, detail: { item } }));\n\n function onMove(ev: PointerEvent) {\n element.dispatchEvent(\n new CustomEvent('sortable:move', {\n bubbles: true,\n detail: { clientY: ev.clientY, item },\n })\n );\n }\n\n function onUp() {\n document.removeEventListener('pointermove', onMove);\n document.removeEventListener('pointerup', onUp);\n item!.classList.remove(dragClass);\n element.dispatchEvent(new CustomEvent('sortable:end', { bubbles: true, detail: { item } }));\n }\n\n document.addEventListener('pointermove', onMove);\n document.addEventListener('pointerup', onUp);\n });\n}\n\n/**\n * Register the Sortable behavior with LokaScript.\n */\nexport async function registerSortable(hyperfixi?: LokaScriptInstance): Promise<void> {\n const hf = hyperfixi || resolveRuntime();\n\n if (!hf) {\n throw new Error(\n 'LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.'\n );\n }\n\n const syntheticNode = {\n type: 'behavior',\n name: 'Sortable',\n parameters: ['handle', 'dragClass'],\n eventHandlers: [],\n imperativeInstaller: installSortable,\n };\n const ctx = hf.createContext ? hf.createContext() : { locals: new Map(), globals: new Map() };\n await hf.execute(syntheticNode, ctx);\n}\n\n// Auto-register when loaded as a script tag\nif (resolveRuntime()) {\n registerSortable().catch(console.error);\n}\n\nexport default {\n source: sortableSchema.source,\n metadata: sortableSchema,\n register: registerSortable,\n};\n","import type { BehaviorSchema } from './types';\n\n/**\n * Sortable Behavior Schema\n *\n * Drag-and-drop reordering of list items.\n * Apply to a container element; children become sortable.\n *\n * Note: This behavior fires lifecycle events but does NOT automatically\n * reorder DOM elements. Users must handle actual reordering in their\n * `sortable:move` event handlers.\n */\nexport const sortableSchema: BehaviorSchema = {\n name: 'Sortable',\n category: 'ui',\n tier: 'common',\n version: '1.0.0',\n description: 'Makes child elements reorderable via drag-and-drop',\n parameters: [\n {\n name: 'handle',\n type: 'selector',\n optional: true,\n default: 'none',\n description: 'CSS selector for drag handles within items',\n },\n {\n name: 'dragClass',\n type: 'string',\n optional: true,\n default: 'sorting',\n description: 'CSS class added to item during drag',\n },\n ],\n events: [\n { name: 'sortable:start', description: 'Fired when drag begins' },\n {\n name: 'sortable:move',\n description: 'Fired during drag — handle this event to reorder DOM elements',\n },\n { name: 'sortable:end', description: 'Fired when drag completes' },\n ],\n requirements: ['Users must handle DOM reordering in sortable:move event handlers'],\n source: `\nbehavior Sortable(handle, dragClass)\n init\n if dragClass is undefined\n set dragClass to \"sorting\"\n end\n end\n on pointerdown(clientY) from me\n js(me, handle, event)\n var target = event.target;\n var item = target.closest(\"li\");\n if (!item || !me.contains(item)) return false;\n if (handle && !target.closest(handle)) return false;\n event.preventDefault();\n event.stopPropagation();\n return true;\n end\n if it is false\n exit\n end\n add .{dragClass} to me\n trigger sortable:start on me\n repeat until event pointerup from document\n wait for pointermove(clientY) from document\n trigger sortable:move on me\n end\n remove .{dragClass} from me\n trigger sortable:end on me\n end\nend`.trim(),\n};\n","/**\n * Behavior Schema Types\n *\n * Defines the structure for behavior metadata used for:\n * - Code generation (TypeScript types, documentation)\n * - Runtime categorization and lazy loading\n * - Tooling and IDE integration\n */\n\n/**\n * Behavior categories for organization.\n * - ui: Visual interaction behaviors (drag, resize, sort)\n * - data: Data manipulation behaviors (remove, transform)\n * - animation: Animation and transition behaviors\n * - form: Form-related behaviors (validation, toggle states)\n * - layout: Layout behaviors (sticky, scrollspy)\n */\nexport type BehaviorCategory = 'ui' | 'data' | 'animation' | 'form' | 'layout';\n\n/**\n * Loading tiers for lazy loading optimization.\n * - core: Always loaded (essential behaviors)\n * - common: High usage (loaded for typical apps)\n * - optional: Low usage (loaded on demand)\n */\nexport type BehaviorTier = 'core' | 'common' | 'optional';\n\n/**\n * Schema for a behavior parameter.\n */\nexport interface ParameterSchema {\n name: string;\n type: 'string' | 'number' | 'boolean' | 'selector' | 'element';\n optional?: boolean;\n default?: string | number | boolean;\n /** Allowed values for constrained parameters */\n enum?: string[];\n description: string;\n}\n\n/**\n * Schema for a behavior event.\n */\nexport interface EventSchema {\n name: string;\n description: string;\n}\n\n/**\n * Complete schema for a behavior.\n * This is the source of truth for all behavior metadata.\n */\nexport interface BehaviorSchema {\n /** Behavior name (PascalCase) */\n name: string;\n /** Category for organization */\n category: BehaviorCategory;\n /** Loading tier for lazy loading */\n tier: BehaviorTier;\n /** Semantic version */\n version: string;\n /** Human-readable description */\n description: string;\n /** Parameter definitions */\n parameters: ParameterSchema[];\n /** Event definitions */\n events: EventSchema[];\n /** The hyperscript behavior source code */\n source: string;\n /** Optional requirements or notes */\n requirements?: string[];\n}\n\n/**\n * Runtime behavior module interface.\n * This is what gets registered with the hyperfixi runtime.\n */\nexport interface BehaviorModule {\n source: string;\n metadata: BehaviorSchema;\n register: (hyperfixi?: LokaScriptInstance) => Promise<void>;\n}\n\n/**\n * Minimal LokaScript instance interface for behavior registration.\n */\nexport interface LokaScriptInstance {\n compileSync: (\n code: string,\n options?: { traditional?: boolean; language?: string }\n ) => {\n ok: boolean;\n ast?: unknown;\n errors?: Array<{ message: string; line?: number; column?: number }>;\n };\n execute: (ast: unknown, ctx: unknown) => Promise<unknown>;\n createContext?: () => { locals: Map<string, unknown>; globals: Map<string, unknown> };\n}\n\n/**\n * Typed window interface for behavior auto-registration.\n * Avoids `(window as any)` casts throughout the codebase.\n * Checks both `window.lokascript` and `window.hyperfixi` for the runtime instance.\n */\nexport interface LokaScriptWindow {\n lokascript?: LokaScriptInstance;\n hyperfixi?: LokaScriptInstance;\n __hyperfixi_behaviors_ready?: Promise<void> | undefined;\n}\n\n/**\n * Resolve the LokaScript runtime from window globals.\n * Checks both `window.lokascript` and `window.hyperfixi`.\n */\nexport function resolveRuntime(): LokaScriptInstance | null {\n if (typeof window === 'undefined') return null;\n const win = window as unknown as LokaScriptWindow;\n return win.lokascript || win.hyperfixi || null;\n}\n"],"mappings":"scAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,aAAAE,EAAA,qBAAAC,EAAA,qBAAAC,EAAA,mBAAAC,ICYO,IAAMC,EAAiC,CAC5C,KAAM,WACN,SAAU,KACV,KAAM,SACN,QAAS,QACT,YAAa,qDACb,WAAY,CACV,CACE,KAAM,SACN,KAAM,WACN,SAAU,GACV,QAAS,OACT,YAAa,4CACf,EACA,CACE,KAAM,YACN,KAAM,SACN,SAAU,GACV,QAAS,UACT,YAAa,qCACf,CACF,EACA,OAAQ,CACN,CAAE,KAAM,iBAAkB,YAAa,wBAAyB,EAChE,CACE,KAAM,gBACN,YAAa,oEACf,EACA,CAAE,KAAM,eAAgB,YAAa,2BAA4B,CACnE,EACA,aAAc,CAAC,kEAAkE,EACjF,OAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KA6BL,KAAK,CACV,ECyCO,SAASC,GAA4C,CAC1D,GAAI,OAAO,OAAW,IAAa,OAAO,KAC1C,IAAMC,EAAM,OACZ,OAAOA,EAAI,YAAcA,EAAI,WAAa,IAC5C,CF9FO,IAAMC,EAAiBC,EAAe,OAChCC,EAAmBD,EAKhC,SAASE,EAAgBC,EAAsBC,EAAmC,CAChF,IAAMC,EAAYD,EAAO,WAAa,UAChCE,EAAiBF,EAAO,QAAU,KAExCD,EAAQ,iBAAiB,cAAgBI,GAAoB,CAC3D,IAAMC,EAASD,EAAE,OACXE,EAAOD,EAAO,QAAQ,IAAI,EAIhC,GAHI,CAACC,GAAQ,CAACN,EAAQ,SAASM,CAAI,GAG/BH,GAEE,CADaE,EAAO,QAAQF,CAAc,EAC/B,OAGjBC,EAAE,eAAe,EACjBE,EAAK,UAAU,IAAIJ,CAAS,EAC5BF,EAAQ,cAAc,IAAI,YAAY,iBAAkB,CAAE,QAAS,GAAM,OAAQ,CAAE,KAAAM,CAAK,CAAE,CAAC,CAAC,EAE5F,SAASC,EAAOC,EAAkB,CAChCR,EAAQ,cACN,IAAI,YAAY,gBAAiB,CAC/B,QAAS,GACT,OAAQ,CAAE,QAASQ,EAAG,QAAS,KAAAF,CAAK,CACtC,CAAC,CACH,CACF,CAEA,SAASG,GAAO,CACd,SAAS,oBAAoB,cAAeF,CAAM,EAClD,SAAS,oBAAoB,YAAaE,CAAI,EAC9CH,EAAM,UAAU,OAAOJ,CAAS,EAChCF,EAAQ,cAAc,IAAI,YAAY,eAAgB,CAAE,QAAS,GAAM,OAAQ,CAAE,KAAAM,CAAK,CAAE,CAAC,CAAC,CAC5F,CAEA,SAAS,iBAAiB,cAAeC,CAAM,EAC/C,SAAS,iBAAiB,YAAaE,CAAI,CAC7C,CAAC,CACH,CAKA,eAAsBC,EAAiBC,EAA+C,CACpF,IAAMC,EAAKD,GAAaE,EAAe,EAEvC,GAAI,CAACD,EACH,MAAM,IAAI,MACR,yFACF,EAGF,IAAME,EAAgB,CACpB,KAAM,WACN,KAAM,WACN,WAAY,CAAC,SAAU,WAAW,EAClC,cAAe,CAAC,EAChB,oBAAqBf,CACvB,EACMgB,EAAMH,EAAG,cAAgBA,EAAG,cAAc,EAAI,CAAE,OAAQ,IAAI,IAAO,QAAS,IAAI,GAAM,EAC5F,MAAMA,EAAG,QAAQE,EAAeC,CAAG,CACrC,CAGIF,EAAe,GACjBH,EAAiB,EAAE,MAAM,QAAQ,KAAK,EAGxC,IAAOM,EAAQ,CACb,OAAQnB,EAAe,OACvB,SAAUA,EACV,SAAUa,CACZ","names":["sortable_exports","__export","sortable_default","registerSortable","sortableMetadata","sortableSource","sortableSchema","resolveRuntime","win","sortableSource","sortableSchema","sortableMetadata","installSortable","element","params","dragClass","handleSelector","e","target","item","onMove","ev","onUp","registerSortable","hyperfixi","hf","resolveRuntime","syntheticNode","ctx","sortable_default"]}
1
+ {"version":3,"sources":["../src/behaviors/sortable.ts","../src/schemas/sortable.schema.ts","../src/schemas/types.ts"],"sourcesContent":["/**\n * Sortable Behavior — Imperative Implementation\n *\n * Drag-and-drop reordering of list items.\n * Apply to a container element; children become sortable.\n *\n * Note: This behavior fires lifecycle events but does NOT automatically\n * reorder DOM elements. Users must handle actual reordering in their\n * `sortable:move` event handlers.\n *\n * @example\n * ```html\n * <ul _=\"install Sortable\">\n * <li>Item 1</li>\n * <li>Item 2</li>\n * </ul>\n * ```\n */\n\nimport { sortableSchema } from '../schemas/sortable.schema';\nimport type { LokaScriptInstance } from '../schemas/types';\nimport { resolveRuntime } from '../schemas/types';\n\n// Re-export schema-derived values for backwards compatibility\nexport const sortableSource = sortableSchema.source;\nexport const sortableMetadata = sortableSchema;\n\n/**\n * Imperative installer for Sortable behavior.\n */\nfunction installSortable(element: HTMLElement, params: Record<string, any>): void {\n const dragClass = params.dragClass || 'sorting';\n const handleSelector = params.handle || null;\n\n element.addEventListener('pointerdown', (e: PointerEvent) => {\n const target = e.target as HTMLElement;\n const item = target.closest('li');\n if (!item || !element.contains(item)) return;\n\n // If a handle selector is specified, only start drag from the handle\n if (handleSelector) {\n const handleEl = target.closest(handleSelector);\n if (!handleEl) return;\n }\n\n e.preventDefault();\n item.classList.add(dragClass);\n element.dispatchEvent(new CustomEvent('sortable:start', { bubbles: true, detail: { item } }));\n\n function onMove(ev: PointerEvent) {\n element.dispatchEvent(\n new CustomEvent('sortable:move', {\n bubbles: true,\n detail: { clientY: ev.clientY, item },\n })\n );\n }\n\n function onUp() {\n document.removeEventListener('pointermove', onMove);\n document.removeEventListener('pointerup', onUp);\n item!.classList.remove(dragClass);\n element.dispatchEvent(new CustomEvent('sortable:end', { bubbles: true, detail: { item } }));\n }\n\n document.addEventListener('pointermove', onMove);\n document.addEventListener('pointerup', onUp);\n });\n}\n\n/**\n * Register the Sortable behavior with LokaScript.\n */\nexport async function registerSortable(hyperfixi?: LokaScriptInstance): Promise<void> {\n const hf = hyperfixi || resolveRuntime();\n\n if (!hf) {\n throw new Error(\n 'LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.'\n );\n }\n\n const syntheticNode = {\n type: 'behavior',\n name: 'Sortable',\n parameters: ['dragClass'],\n eventHandlers: [],\n imperativeInstaller: installSortable,\n };\n const ctx = hf.createContext ? hf.createContext() : { locals: new Map(), globals: new Map() };\n await hf.execute(syntheticNode, ctx);\n}\n\n// Auto-register when loaded as a script tag\nif (resolveRuntime()) {\n registerSortable().catch(console.error);\n}\n\nexport default {\n source: sortableSchema.source,\n metadata: sortableSchema,\n register: registerSortable,\n};\n","import type { BehaviorSchema } from './types';\n\n/**\n * Sortable Behavior Schema\n *\n * Drag-and-drop reordering of list items.\n * Apply to a container element; children become sortable.\n *\n * Note: This behavior fires lifecycle events but does NOT automatically\n * reorder DOM elements. Users must handle actual reordering in their\n * `sortable:move` event handlers.\n */\nexport const sortableSchema: BehaviorSchema = {\n name: 'Sortable',\n category: 'ui',\n tier: 'common',\n version: '1.0.0',\n description: 'Makes child elements reorderable via drag-and-drop',\n parameters: [\n {\n name: 'dragClass',\n type: 'string',\n optional: true,\n default: 'sorting',\n description: 'CSS class added to item during drag',\n },\n ],\n events: [\n { name: 'sortable:start', description: 'Fired when drag begins' },\n {\n name: 'sortable:move',\n description: 'Fired during drag — handle this event to reorder DOM elements',\n },\n { name: 'sortable:end', description: 'Fired when drag completes' },\n ],\n requirements: ['Users must handle DOM reordering in sortable:move event handlers'],\n source: `\nbehavior Sortable(dragClass)\n init\n if dragClass is undefined\n set dragClass to \"sorting\"\n end\n end\n on pointerdown(clientY) from me\n set item to the closest <li/> to the target\n if item is null\n exit\n end\n halt the event\n add .{dragClass} to item\n trigger sortable:start on me\n repeat until event pointerup from document\n wait for pointermove(clientY) from document\n trigger sortable:move on me\n end\n remove .{dragClass} from item\n trigger sortable:end on me\n end\nend`.trim(),\n};\n","/**\n * Behavior Schema Types\n *\n * Defines the structure for behavior metadata used for:\n * - Code generation (TypeScript types, documentation)\n * - Runtime categorization and lazy loading\n * - Tooling and IDE integration\n */\n\n/**\n * Behavior categories for organization.\n * - ui: Visual interaction behaviors (drag, resize, sort)\n * - data: Data manipulation behaviors (remove, transform)\n * - animation: Animation and transition behaviors\n * - form: Form-related behaviors (validation, toggle states)\n * - layout: Layout behaviors (sticky, scrollspy)\n */\nexport type BehaviorCategory = 'ui' | 'data' | 'animation' | 'form' | 'layout';\n\n/**\n * Loading tiers for lazy loading optimization.\n * - core: Always loaded (essential behaviors)\n * - common: High usage (loaded for typical apps)\n * - optional: Low usage (loaded on demand)\n */\nexport type BehaviorTier = 'core' | 'common' | 'optional';\n\n/**\n * Schema for a behavior parameter.\n */\nexport interface ParameterSchema {\n name: string;\n type: 'string' | 'number' | 'boolean' | 'selector' | 'element';\n optional?: boolean;\n default?: string | number | boolean;\n /** Allowed values for constrained parameters */\n enum?: string[];\n description: string;\n}\n\n/**\n * Schema for a behavior event.\n */\nexport interface EventSchema {\n name: string;\n description: string;\n}\n\n/**\n * Complete schema for a behavior.\n * This is the source of truth for all behavior metadata.\n */\nexport interface BehaviorSchema {\n /** Behavior name (PascalCase) */\n name: string;\n /** Category for organization */\n category: BehaviorCategory;\n /** Loading tier for lazy loading */\n tier: BehaviorTier;\n /** Semantic version */\n version: string;\n /** Human-readable description */\n description: string;\n /** Parameter definitions */\n parameters: ParameterSchema[];\n /** Event definitions */\n events: EventSchema[];\n /** The hyperscript behavior source code */\n source: string;\n /** Optional requirements or notes */\n requirements?: string[];\n}\n\n/**\n * Runtime behavior module interface.\n * This is what gets registered with the hyperfixi runtime.\n */\nexport interface BehaviorModule {\n source: string;\n metadata: BehaviorSchema;\n register: (hyperfixi?: LokaScriptInstance) => Promise<void>;\n}\n\n/**\n * Minimal LokaScript instance interface for behavior registration.\n */\nexport interface LokaScriptInstance {\n compileSync: (\n code: string,\n options?: { traditional?: boolean; language?: string }\n ) => {\n ok: boolean;\n ast?: unknown;\n errors?: Array<{ message: string; line?: number; column?: number }>;\n };\n execute: (ast: unknown, ctx: unknown) => Promise<unknown>;\n createContext?: () => { locals: Map<string, unknown>; globals: Map<string, unknown> };\n}\n\n/**\n * Typed window interface for behavior auto-registration.\n * Avoids `(window as any)` casts throughout the codebase.\n * Checks both `window.lokascript` and `window.hyperfixi` for the runtime instance.\n */\nexport interface LokaScriptWindow {\n lokascript?: LokaScriptInstance;\n hyperfixi?: LokaScriptInstance;\n __hyperfixi_behaviors_ready?: Promise<void> | undefined;\n}\n\n/**\n * Resolve the LokaScript runtime from window globals.\n * Checks both `window.lokascript` and `window.hyperfixi`.\n */\nexport function resolveRuntime(): LokaScriptInstance | null {\n if (typeof window === 'undefined') return null;\n const win = window as unknown as LokaScriptWindow;\n return win.lokascript || win.hyperfixi || null;\n}\n"],"mappings":"scAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,aAAAE,EAAA,qBAAAC,EAAA,qBAAAC,EAAA,mBAAAC,ICYO,IAAMC,EAAiC,CAC5C,KAAM,WACN,SAAU,KACV,KAAM,SACN,QAAS,QACT,YAAa,qDACb,WAAY,CACV,CACE,KAAM,YACN,KAAM,SACN,SAAU,GACV,QAAS,UACT,YAAa,qCACf,CACF,EACA,OAAQ,CACN,CAAE,KAAM,iBAAkB,YAAa,wBAAyB,EAChE,CACE,KAAM,gBACN,YAAa,oEACf,EACA,CAAE,KAAM,eAAgB,YAAa,2BAA4B,CACnE,EACA,aAAc,CAAC,kEAAkE,EACjF,OAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAsBL,KAAK,CACV,ECuDO,SAASC,GAA4C,CAC1D,GAAI,OAAO,OAAW,IAAa,OAAO,KAC1C,IAAMC,EAAM,OACZ,OAAOA,EAAI,YAAcA,EAAI,WAAa,IAC5C,CF9FO,IAAMC,EAAiBC,EAAe,OAChCC,EAAmBD,EAKhC,SAASE,EAAgBC,EAAsBC,EAAmC,CAChF,IAAMC,EAAYD,EAAO,WAAa,UAChCE,EAAiBF,EAAO,QAAU,KAExCD,EAAQ,iBAAiB,cAAgBI,GAAoB,CAC3D,IAAMC,EAASD,EAAE,OACXE,EAAOD,EAAO,QAAQ,IAAI,EAIhC,GAHI,CAACC,GAAQ,CAACN,EAAQ,SAASM,CAAI,GAG/BH,GAEE,CADaE,EAAO,QAAQF,CAAc,EAC/B,OAGjBC,EAAE,eAAe,EACjBE,EAAK,UAAU,IAAIJ,CAAS,EAC5BF,EAAQ,cAAc,IAAI,YAAY,iBAAkB,CAAE,QAAS,GAAM,OAAQ,CAAE,KAAAM,CAAK,CAAE,CAAC,CAAC,EAE5F,SAASC,EAAOC,EAAkB,CAChCR,EAAQ,cACN,IAAI,YAAY,gBAAiB,CAC/B,QAAS,GACT,OAAQ,CAAE,QAASQ,EAAG,QAAS,KAAAF,CAAK,CACtC,CAAC,CACH,CACF,CAEA,SAASG,GAAO,CACd,SAAS,oBAAoB,cAAeF,CAAM,EAClD,SAAS,oBAAoB,YAAaE,CAAI,EAC9CH,EAAM,UAAU,OAAOJ,CAAS,EAChCF,EAAQ,cAAc,IAAI,YAAY,eAAgB,CAAE,QAAS,GAAM,OAAQ,CAAE,KAAAM,CAAK,CAAE,CAAC,CAAC,CAC5F,CAEA,SAAS,iBAAiB,cAAeC,CAAM,EAC/C,SAAS,iBAAiB,YAAaE,CAAI,CAC7C,CAAC,CACH,CAKA,eAAsBC,EAAiBC,EAA+C,CACpF,IAAMC,EAAKD,GAAaE,EAAe,EAEvC,GAAI,CAACD,EACH,MAAM,IAAI,MACR,yFACF,EAGF,IAAME,EAAgB,CACpB,KAAM,WACN,KAAM,WACN,WAAY,CAAC,WAAW,EACxB,cAAe,CAAC,EAChB,oBAAqBf,CACvB,EACMgB,EAAMH,EAAG,cAAgBA,EAAG,cAAc,EAAI,CAAE,OAAQ,IAAI,IAAO,QAAS,IAAI,GAAM,EAC5F,MAAMA,EAAG,QAAQE,EAAeC,CAAG,CACrC,CAGIF,EAAe,GACjBH,EAAiB,EAAE,MAAM,QAAQ,KAAK,EAGxC,IAAOM,EAAQ,CACb,OAAQnB,EAAe,OACvB,SAAUA,EACV,SAAUa,CACZ","names":["sortable_exports","__export","sortable_default","registerSortable","sortableMetadata","sortableSource","sortableSchema","resolveRuntime","win","sortableSource","sortableSchema","sortableMetadata","installSortable","element","params","dragClass","handleSelector","e","target","item","onMove","ev","onUp","registerSortable","hyperfixi","hf","resolveRuntime","syntheticNode","ctx","sortable_default"]}
@@ -97,4 +97,4 @@ interface LokaScriptInstance {
97
97
  };
98
98
  }
99
99
 
100
- export type { BehaviorSchema as B, EventSchema as E, LokaScriptInstance as L, ParameterSchema as P, BehaviorModule as a, BehaviorCategory as b, BehaviorTier as c };
100
+ export type { BehaviorCategory as B, EventSchema as E, LokaScriptInstance as L, ParameterSchema as P, BehaviorModule as a, BehaviorSchema as b, BehaviorTier as c };
@@ -97,4 +97,4 @@ interface LokaScriptInstance {
97
97
  };
98
98
  }
99
99
 
100
- export type { BehaviorSchema as B, EventSchema as E, LokaScriptInstance as L, ParameterSchema as P, BehaviorModule as a, BehaviorCategory as b, BehaviorTier as c };
100
+ export type { BehaviorCategory as B, EventSchema as E, LokaScriptInstance as L, ParameterSchema as P, BehaviorModule as a, BehaviorSchema as b, BehaviorTier as c };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperfixi/behaviors",
3
- "version": "2.3.0",
3
+ "version": "2.4.0",
4
4
  "description": "Reusable hyperscript behaviors for LokaScript",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -117,7 +117,7 @@
117
117
  "@hyperfixi/core": "*",
118
118
  "tsup": "^8.0.0",
119
119
  "typescript": "^5.0.0",
120
- "vitest": "^4.0.0"
120
+ "vitest": "^4.1.5"
121
121
  },
122
122
  "keywords": [
123
123
  "hyperscript",
@@ -84,7 +84,7 @@ export async function registerResizable(hyperfixi?: LokaScriptInstance): Promise
84
84
  const syntheticNode = {
85
85
  type: 'behavior',
86
86
  name: 'Resizable',
87
- parameters: ['handle', 'minWidth', 'minHeight', 'maxWidth', 'maxHeight'],
87
+ parameters: [],
88
88
  eventHandlers: [],
89
89
  imperativeInstaller: installResizable,
90
90
  };
@@ -83,7 +83,7 @@ export async function registerSortable(hyperfixi?: LokaScriptInstance): Promise<
83
83
  const syntheticNode = {
84
84
  type: 'behavior',
85
85
  name: 'Sortable',
86
- parameters: ['handle', 'dragClass'],
86
+ parameters: ['dragClass'],
87
87
  eventHandlers: [],
88
88
  imperativeInstaller: installSortable,
89
89
  };
@@ -18,7 +18,7 @@ function init() {
18
18
 
19
19
  // Compile and register each behavior definition with the runtime.
20
20
  // This is equivalent to having them in a <script type="text/hyperscript"> block.
21
- for (const [name, source] of Object.entries(BEHAVIOR_SOURCES)) {
21
+ for (const source of Object.values(BEHAVIOR_SOURCES)) {
22
22
  const result = hf.compileSync(source, { traditional: true });
23
23
  if (result?.ok && result.ast) {
24
24
  // execute() registers the behavior in the runtime's behaviorRegistry
@@ -13,13 +13,6 @@ export const resizableSchema: BehaviorSchema = {
13
13
  version: '1.0.0',
14
14
  description: 'Makes elements resizable by dragging',
15
15
  parameters: [
16
- {
17
- name: 'handle',
18
- type: 'selector',
19
- optional: true,
20
- default: 'me',
21
- description: 'CSS selector for the resize handle (defaults to the element itself)',
22
- },
23
16
  {
24
17
  name: 'minWidth',
25
18
  type: 'number',
@@ -55,25 +48,8 @@ export const resizableSchema: BehaviorSchema = {
55
48
  { name: 'resizable:end', description: 'Fired when resize completes' },
56
49
  ],
57
50
  source: `
58
- behavior Resizable(handle, minWidth, minHeight, maxWidth, maxHeight)
59
- init
60
- if handle is undefined
61
- set handle to me
62
- end
63
- if minWidth is undefined
64
- set minWidth to 50
65
- end
66
- if minHeight is undefined
67
- set minHeight to 50
68
- end
69
- if maxWidth is undefined
70
- set maxWidth to 9999
71
- end
72
- if maxHeight is undefined
73
- set maxHeight to 9999
74
- end
75
- end
76
- on pointerdown(clientX, clientY) from handle
51
+ behavior Resizable(minWidth, minHeight, maxWidth, maxHeight)
52
+ on pointerdown(clientX, clientY) from me
77
53
  halt the event
78
54
  trigger resizable:start
79
55
  measure width
@@ -83,13 +59,15 @@ behavior Resizable(handle, minWidth, minHeight, maxWidth, maxHeight)
83
59
  set startX to clientX
84
60
  set startY to clientY
85
61
  repeat until event pointerup from document
86
- wait for pointermove(clientX, clientY) or pointerup from document
87
- js(startWidth, startHeight, clientX, clientY, startX, startY, minWidth, maxWidth, minHeight, maxHeight, me)
88
- var nw = Math.max(minWidth, Math.min(maxWidth, startWidth + (clientX - startX)));
89
- var nh = Math.max(minHeight, Math.min(maxHeight, startHeight + (clientY - startY)));
90
- me.style.width = nw + 'px';
91
- me.style.height = nh + 'px';
92
- end
62
+ wait for pointermove(clientX, clientY) from document
63
+ set newWidth to startWidth + clientX - startX
64
+ set newHeight to startHeight + clientY - startY
65
+ if newWidth < minWidth then set newWidth to minWidth end
66
+ if newWidth > maxWidth then set newWidth to maxWidth end
67
+ if newHeight < minHeight then set newHeight to minHeight end
68
+ if newHeight > maxHeight then set newHeight to maxHeight end
69
+ set my style.width to newWidth + "px"
70
+ set my style.height to newHeight + "px"
93
71
  trigger resizable:resize
94
72
  end
95
73
  trigger resizable:end
@@ -17,13 +17,6 @@ export const sortableSchema: BehaviorSchema = {
17
17
  version: '1.0.0',
18
18
  description: 'Makes child elements reorderable via drag-and-drop',
19
19
  parameters: [
20
- {
21
- name: 'handle',
22
- type: 'selector',
23
- optional: true,
24
- default: 'none',
25
- description: 'CSS selector for drag handles within items',
26
- },
27
20
  {
28
21
  name: 'dragClass',
29
22
  type: 'string',
@@ -42,32 +35,25 @@ export const sortableSchema: BehaviorSchema = {
42
35
  ],
43
36
  requirements: ['Users must handle DOM reordering in sortable:move event handlers'],
44
37
  source: `
45
- behavior Sortable(handle, dragClass)
38
+ behavior Sortable(dragClass)
46
39
  init
47
40
  if dragClass is undefined
48
41
  set dragClass to "sorting"
49
42
  end
50
43
  end
51
44
  on pointerdown(clientY) from me
52
- js(me, handle, event)
53
- var target = event.target;
54
- var item = target.closest("li");
55
- if (!item || !me.contains(item)) return false;
56
- if (handle && !target.closest(handle)) return false;
57
- event.preventDefault();
58
- event.stopPropagation();
59
- return true;
60
- end
61
- if it is false
45
+ set item to the closest <li/> to the target
46
+ if item is null
62
47
  exit
63
48
  end
64
- add .{dragClass} to me
49
+ halt the event
50
+ add .{dragClass} to item
65
51
  trigger sortable:start on me
66
52
  repeat until event pointerup from document
67
53
  wait for pointermove(clientY) from document
68
54
  trigger sortable:move on me
69
55
  end
70
- remove .{dragClass} from me
56
+ remove .{dragClass} from item
71
57
  trigger sortable:end on me
72
58
  end
73
59
  end`.trim(),
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/schemas/sortable.schema.ts"],"sourcesContent":["import type { BehaviorSchema } from './types';\n\n/**\n * Sortable Behavior Schema\n *\n * Drag-and-drop reordering of list items.\n * Apply to a container element; children become sortable.\n *\n * Note: This behavior fires lifecycle events but does NOT automatically\n * reorder DOM elements. Users must handle actual reordering in their\n * `sortable:move` event handlers.\n */\nexport const sortableSchema: BehaviorSchema = {\n name: 'Sortable',\n category: 'ui',\n tier: 'common',\n version: '1.0.0',\n description: 'Makes child elements reorderable via drag-and-drop',\n parameters: [\n {\n name: 'handle',\n type: 'selector',\n optional: true,\n default: 'none',\n description: 'CSS selector for drag handles within items',\n },\n {\n name: 'dragClass',\n type: 'string',\n optional: true,\n default: 'sorting',\n description: 'CSS class added to item during drag',\n },\n ],\n events: [\n { name: 'sortable:start', description: 'Fired when drag begins' },\n {\n name: 'sortable:move',\n description: 'Fired during drag — handle this event to reorder DOM elements',\n },\n { name: 'sortable:end', description: 'Fired when drag completes' },\n ],\n requirements: ['Users must handle DOM reordering in sortable:move event handlers'],\n source: `\nbehavior Sortable(handle, dragClass)\n init\n if dragClass is undefined\n set dragClass to \"sorting\"\n end\n end\n on pointerdown(clientY) from me\n js(me, handle, event)\n var target = event.target;\n var item = target.closest(\"li\");\n if (!item || !me.contains(item)) return false;\n if (handle && !target.closest(handle)) return false;\n event.preventDefault();\n event.stopPropagation();\n return true;\n end\n if it is false\n exit\n end\n add .{dragClass} to me\n trigger sortable:start on me\n repeat until event pointerup from document\n wait for pointermove(clientY) from document\n trigger sortable:move on me\n end\n remove .{dragClass} from me\n trigger sortable:end on me\n end\nend`.trim(),\n};\n"],"mappings":";AAYO,IAAM,iBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAM;AAAA,EACN,SAAS;AAAA,EACT,aAAa;AAAA,EACb,YAAY;AAAA,IACV;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,EAAE,MAAM,kBAAkB,aAAa,yBAAyB;AAAA,IAChE;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,EAAE,MAAM,gBAAgB,aAAa,4BAA4B;AAAA,EACnE;AAAA,EACA,cAAc,CAAC,kEAAkE;AAAA,EACjF,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KA6BL,KAAK;AACV;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/schemas/resizable.schema.ts"],"sourcesContent":["import type { BehaviorSchema } from './types';\n\n/**\n * Resizable Behavior Schema\n *\n * Makes elements resizable by dragging edges or corners.\n * Supports minimum/maximum dimensions and resize handles.\n */\nexport const resizableSchema: BehaviorSchema = {\n name: 'Resizable',\n category: 'ui',\n tier: 'optional',\n version: '1.0.0',\n description: 'Makes elements resizable by dragging',\n parameters: [\n {\n name: 'handle',\n type: 'selector',\n optional: true,\n default: 'me',\n description: 'CSS selector for the resize handle (defaults to the element itself)',\n },\n {\n name: 'minWidth',\n type: 'number',\n optional: true,\n default: 50,\n description: 'Minimum width in pixels',\n },\n {\n name: 'minHeight',\n type: 'number',\n optional: true,\n default: 50,\n description: 'Minimum height in pixels',\n },\n {\n name: 'maxWidth',\n type: 'number',\n optional: true,\n default: 9999,\n description: 'Maximum width in pixels',\n },\n {\n name: 'maxHeight',\n type: 'number',\n optional: true,\n default: 9999,\n description: 'Maximum height in pixels',\n },\n ],\n events: [\n { name: 'resizable:start', description: 'Fired when resize begins' },\n { name: 'resizable:resize', description: 'Fired during resize' },\n { name: 'resizable:end', description: 'Fired when resize completes' },\n ],\n source: `\nbehavior Resizable(handle, minWidth, minHeight, maxWidth, maxHeight)\n init\n if handle is undefined\n set handle to me\n end\n if minWidth is undefined\n set minWidth to 50\n end\n if minHeight is undefined\n set minHeight to 50\n end\n if maxWidth is undefined\n set maxWidth to 9999\n end\n if maxHeight is undefined\n set maxHeight to 9999\n end\n end\n on pointerdown(clientX, clientY) from handle\n halt the event\n trigger resizable:start\n measure width\n set startWidth to it\n measure height\n set startHeight to it\n set startX to clientX\n set startY to clientY\n repeat until event pointerup from document\n wait for pointermove(clientX, clientY) or pointerup from document\n js(startWidth, startHeight, clientX, clientY, startX, startY, minWidth, maxWidth, minHeight, maxHeight, me)\n var nw = Math.max(minWidth, Math.min(maxWidth, startWidth + (clientX - startX)));\n var nh = Math.max(minHeight, Math.min(maxHeight, startHeight + (clientY - startY)));\n me.style.width = nw + 'px';\n me.style.height = nh + 'px';\n end\n trigger resizable:resize\n end\n trigger resizable:end\n end\nend\n`.trim(),\n};\n"],"mappings":";AAQO,IAAM,kBAAkC;AAAA,EAC7C,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAM;AAAA,EACN,SAAS;AAAA,EACT,aAAa;AAAA,EACb,YAAY;AAAA,IACV;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,EAAE,MAAM,mBAAmB,aAAa,2BAA2B;AAAA,IACnE,EAAE,MAAM,oBAAoB,aAAa,sBAAsB;AAAA,IAC/D,EAAE,MAAM,iBAAiB,aAAa,8BAA8B;AAAA,EACtE;AAAA,EACA,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAyCR,KAAK;AACP;","names":[]}