@hyperfixi/behaviors 2.2.1 → 2.3.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.
- package/dist/all.browser.global.js +316 -54
- package/dist/all.browser.global.js.map +1 -1
- package/dist/autodismiss.browser.global.js +54 -2
- package/dist/autodismiss.browser.global.js.map +1 -1
- package/dist/behaviors/autodismiss.cjs +54 -18
- package/dist/behaviors/autodismiss.cjs.map +1 -1
- package/dist/behaviors/autodismiss.js +2 -2
- package/dist/behaviors/clickoutside.cjs +23 -4
- package/dist/behaviors/clickoutside.cjs.map +1 -1
- package/dist/behaviors/clickoutside.js +2 -2
- package/dist/behaviors/clipboard.cjs +43 -21
- package/dist/behaviors/clipboard.cjs.map +1 -1
- package/dist/behaviors/clipboard.js +2 -2
- package/dist/behaviors/focustrap.cjs +44 -3
- package/dist/behaviors/focustrap.cjs.map +1 -1
- package/dist/behaviors/focustrap.js +2 -2
- package/dist/behaviors/removable.cjs +7 -4
- package/dist/behaviors/removable.cjs.map +1 -1
- package/dist/behaviors/removable.js +2 -2
- package/dist/behaviors/resizable.cjs +22 -14
- package/dist/behaviors/resizable.cjs.map +1 -1
- package/dist/behaviors/resizable.js +2 -2
- package/dist/behaviors/scrollreveal.cjs +25 -13
- package/dist/behaviors/scrollreveal.cjs.map +1 -1
- package/dist/behaviors/scrollreveal.js +2 -2
- package/dist/behaviors/sortable.cjs +18 -12
- package/dist/behaviors/sortable.cjs.map +1 -1
- package/dist/behaviors/sortable.js +2 -2
- package/dist/behaviors/tabs.cjs +80 -11
- package/dist/behaviors/tabs.cjs.map +1 -1
- package/dist/behaviors/tabs.js +2 -2
- package/dist/behaviors/toggleable.cjs +5 -2
- package/dist/behaviors/toggleable.cjs.map +1 -1
- package/dist/behaviors/toggleable.js +2 -2
- package/dist/chunk-66U2RSYJ.js +100 -0
- package/dist/chunk-66U2RSYJ.js.map +1 -0
- package/dist/{chunk-2NSKQMNM.js → chunk-7O7UOSBH.js} +2 -2
- package/dist/{chunk-244WSZOL.js → chunk-EKKJVXDZ.js} +2 -2
- package/dist/{chunk-AFGA54SA.js → chunk-F3CASJ7Q.js} +2 -2
- package/dist/{chunk-YHQRFUWV.js → chunk-GALKOMJ5.js} +2 -2
- package/dist/{chunk-272NKUJ3.js → chunk-HMU342XE.js} +8 -5
- package/dist/chunk-HMU342XE.js.map +1 -0
- package/dist/chunk-HQDYH45I.js +137 -0
- package/dist/chunk-HQDYH45I.js.map +1 -0
- package/dist/{chunk-WTUVPVSD.js → chunk-IQM32TEY.js} +2 -2
- package/dist/{chunk-H5Y5ARYG.js → chunk-L52AGCMP.js} +2 -2
- package/dist/{chunk-H2MCHR5A.js → chunk-LQJOQTBZ.js} +2 -2
- package/dist/{chunk-7JDV2THA.js → chunk-MVNHMYIK.js} +11 -11
- package/dist/{chunk-BWZ6EGII.js → chunk-NC6I6T7T.js} +19 -13
- package/dist/{chunk-BWZ6EGII.js.map → chunk-NC6I6T7T.js.map} +1 -1
- package/dist/chunk-OJ3YWO3W.js +92 -0
- package/dist/chunk-OJ3YWO3W.js.map +1 -0
- package/dist/{chunk-64DIQGQI.js → chunk-SLOXO6IY.js} +24 -5
- package/dist/chunk-SLOXO6IY.js.map +1 -0
- package/dist/{chunk-RPERQTFU.js → chunk-TLLGH5KX.js} +2 -2
- package/dist/{chunk-V5IWDPDP.js → chunk-U5GNXZUF.js} +23 -15
- package/dist/{chunk-V5IWDPDP.js.map → chunk-U5GNXZUF.js.map} +1 -1
- package/dist/{chunk-GPTHAUWN.js → chunk-URZGNPTQ.js} +26 -14
- package/dist/chunk-URZGNPTQ.js.map +1 -0
- package/dist/chunk-WOTZO7K4.js +92 -0
- package/dist/chunk-WOTZO7K4.js.map +1 -0
- package/dist/{chunk-JKBWIJFI.js → chunk-WPOQIMCC.js} +2 -2
- package/dist/{chunk-WUHHMDAA.js → chunk-XYZ7FOXJ.js} +6 -3
- package/dist/{chunk-WUHHMDAA.js.map → chunk-XYZ7FOXJ.js.map} +1 -1
- package/dist/{chunk-DYHBKDKB.js → chunk-ZZ2WSAX3.js} +2 -2
- package/dist/clickoutside.browser.global.js +16 -5
- package/dist/clickoutside.browser.global.js.map +1 -1
- package/dist/clipboard.browser.global.js +43 -2
- package/dist/clipboard.browser.global.js.map +1 -1
- package/dist/core.browser.global.js +5 -2
- package/dist/core.browser.global.js.map +1 -1
- package/dist/focustrap.browser.global.js +46 -5
- package/dist/focustrap.browser.global.js.map +1 -1
- package/dist/index.cjs +321 -102
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +21 -21
- package/dist/loaders.cjs +321 -102
- package/dist/loaders.cjs.map +1 -1
- package/dist/loaders.js +11 -11
- package/dist/removable.browser.global.js +8 -5
- package/dist/removable.browser.global.js.map +1 -1
- package/dist/resizable.browser.global.js +24 -16
- package/dist/resizable.browser.global.js.map +1 -1
- package/dist/resolver.browser.global.js +407 -0
- package/dist/resolver.browser.global.js.map +1 -0
- package/dist/schemas/index.cjs +321 -102
- package/dist/schemas/index.cjs.map +1 -1
- package/dist/schemas/index.js +10 -10
- package/dist/scrollreveal.browser.global.js +27 -8
- package/dist/scrollreveal.browser.global.js.map +1 -1
- package/dist/sortable.browser.global.js +19 -13
- package/dist/sortable.browser.global.js.map +1 -1
- package/dist/tabs.browser.global.js +80 -2
- package/dist/tabs.browser.global.js.map +1 -1
- package/dist/toggleable.browser.global.js +6 -3
- package/dist/toggleable.browser.global.js.map +1 -1
- package/package.json +1 -1
- package/src/behavior-resolver.ts +91 -0
- package/src/browser-resolver-bundle.ts +42 -0
- package/src/schemas/autodismiss.schema.ts +54 -18
- package/src/schemas/clickoutside.schema.ts +22 -3
- package/src/schemas/clipboard.schema.ts +43 -21
- package/src/schemas/focustrap.schema.ts +44 -3
- package/src/schemas/removable.schema.ts +7 -4
- package/src/schemas/resizable.schema.ts +22 -14
- package/src/schemas/scrollreveal.schema.ts +25 -13
- package/src/schemas/sortable.schema.ts +18 -12
- package/src/schemas/tabs.schema.ts +80 -11
- package/src/schemas/toggleable.schema.ts +5 -2
- package/dist/chunk-272NKUJ3.js.map +0 -1
- package/dist/chunk-64DIQGQI.js.map +0 -1
- package/dist/chunk-GPTHAUWN.js.map +0 -1
- package/dist/chunk-GVJPA2EK.js +0 -68
- package/dist/chunk-GVJPA2EK.js.map +0 -1
- package/dist/chunk-QKDYW4VM.js +0 -70
- package/dist/chunk-QKDYW4VM.js.map +0 -1
- package/dist/chunk-RB7OB6OD.js +0 -51
- package/dist/chunk-RB7OB6OD.js.map +0 -1
- package/dist/chunk-ZQQZTMCJ.js +0 -64
- package/dist/chunk-ZQQZTMCJ.js.map +0 -1
- /package/dist/{chunk-2NSKQMNM.js.map → chunk-7O7UOSBH.js.map} +0 -0
- /package/dist/{chunk-244WSZOL.js.map → chunk-EKKJVXDZ.js.map} +0 -0
- /package/dist/{chunk-AFGA54SA.js.map → chunk-F3CASJ7Q.js.map} +0 -0
- /package/dist/{chunk-YHQRFUWV.js.map → chunk-GALKOMJ5.js.map} +0 -0
- /package/dist/{chunk-WTUVPVSD.js.map → chunk-IQM32TEY.js.map} +0 -0
- /package/dist/{chunk-H5Y5ARYG.js.map → chunk-L52AGCMP.js.map} +0 -0
- /package/dist/{chunk-H2MCHR5A.js.map → chunk-LQJOQTBZ.js.map} +0 -0
- /package/dist/{chunk-7JDV2THA.js.map → chunk-MVNHMYIK.js.map} +0 -0
- /package/dist/{chunk-RPERQTFU.js.map → chunk-TLLGH5KX.js.map} +0 -0
- /package/dist/{chunk-JKBWIJFI.js.map → chunk-WPOQIMCC.js.map} +0 -0
- /package/dist/{chunk-DYHBKDKB.js.map → chunk-ZZ2WSAX3.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/behaviors/focustrap.ts","../../src/schemas/focustrap.schema.ts","../../src/schemas/types.ts"],"sourcesContent":["/**\n * FocusTrap Behavior — Imperative Implementation\n *\n * Confines Tab navigation inside an element, manages aria-modal,\n * and restores focus on deactivation.\n */\n\nimport { focusTrapSchema } from '../schemas/focustrap.schema';\nimport type { LokaScriptInstance } from '../schemas/types';\nimport { resolveRuntime } from '../schemas/types';\n\n// Re-export schema-derived values\nexport const focusTrapSource = focusTrapSchema.source;\nexport const focusTrapMetadata = focusTrapSchema;\n\nconst FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'button:not(:disabled)',\n 'input:not(:disabled)',\n 'select:not(:disabled)',\n 'textarea:not(:disabled)',\n '[tabindex]:not([tabindex=\"-1\"])',\n].join(', ');\n\n/**\n * Resolve a selector parameter to an HTMLElement within the container.\n */\nfunction resolveElement(container: HTMLElement, param: unknown): HTMLElement | null {\n if (!param) return null;\n if (param instanceof HTMLElement) return param;\n if (typeof param === 'string') {\n return (\n (container.querySelector(param) as HTMLElement) ||\n (document.querySelector(param) as HTMLElement) ||\n null\n );\n }\n return null;\n}\n\n/**\n * Imperative installer for FocusTrap behavior.\n */\nfunction installFocusTrap(element: HTMLElement, params: Record<string, any>): void {\n const returnFocus = params.returnFocus !== false;\n let isActive = false;\n let previouslyFocused: Element | null = null;\n\n function getFocusableElements(): HTMLElement[] {\n return Array.from(element.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR));\n }\n\n function onKeyDown(e: KeyboardEvent) {\n if (!isActive || e.key !== 'Tab') return;\n\n const focusable = getFocusableElements();\n if (focusable.length === 0) {\n e.preventDefault();\n return;\n }\n\n // Always prevent default Tab and manually manage focus.\n // This ensures focus never escapes to elements outside the trap,\n // even when the modal is embedded in a page with other focusable elements.\n e.preventDefault();\n\n const currentIndex = focusable.indexOf(document.activeElement as HTMLElement);\n\n if (e.shiftKey) {\n const prevIndex = currentIndex <= 0 ? focusable.length - 1 : currentIndex - 1;\n focusable[prevIndex].focus();\n } else {\n const nextIndex = currentIndex >= focusable.length - 1 ? 0 : currentIndex + 1;\n focusable[nextIndex].focus();\n }\n }\n\n function activate() {\n if (isActive) return;\n isActive = true;\n previouslyFocused = document.activeElement;\n\n element.setAttribute('aria-modal', 'true');\n\n // Focus initialFocus element or first focusable\n const initialEl = resolveElement(element, params.initialFocus);\n if (initialEl) {\n initialEl.focus();\n } else {\n const focusable = getFocusableElements();\n if (focusable.length > 0) {\n focusable[0].focus();\n }\n }\n\n element.dispatchEvent(new CustomEvent('focustrap:activated', { bubbles: true }));\n }\n\n function deactivate() {\n if (!isActive) return;\n isActive = false;\n\n element.removeAttribute('aria-modal');\n\n if (returnFocus && previouslyFocused instanceof HTMLElement) {\n previouslyFocused.focus();\n }\n previouslyFocused = null;\n\n element.dispatchEvent(new CustomEvent('focustrap:deactivated', { bubbles: true }));\n }\n\n // Keydown handler for Tab trapping\n element.addEventListener('keydown', onKeyDown);\n\n // Programmatic activation/deactivation via custom events\n element.addEventListener('focustrap:activate', () => activate());\n element.addEventListener('focustrap:deactivate', () => deactivate());\n\n // Activate immediately if requested\n if (params.active !== false) {\n activate();\n }\n}\n\n/**\n * Register the FocusTrap behavior with LokaScript.\n */\nexport async function registerFocusTrap(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: 'FocusTrap',\n parameters: ['active', 'initialFocus', 'returnFocus'],\n eventHandlers: [],\n imperativeInstaller: installFocusTrap,\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 registerFocusTrap().catch(console.error);\n}\n\nexport default {\n source: focusTrapSchema.source,\n metadata: focusTrapSchema,\n register: registerFocusTrap,\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 set active to true\n if returnFocus is undefined set returnFocus to true\n end\n -- Imperative installer handles Tab key trapping and focus management\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":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/behaviors/focustrap.ts","../../src/schemas/focustrap.schema.ts","../../src/schemas/types.ts"],"sourcesContent":["/**\n * FocusTrap Behavior — Imperative Implementation\n *\n * Confines Tab navigation inside an element, manages aria-modal,\n * and restores focus on deactivation.\n */\n\nimport { focusTrapSchema } from '../schemas/focustrap.schema';\nimport type { LokaScriptInstance } from '../schemas/types';\nimport { resolveRuntime } from '../schemas/types';\n\n// Re-export schema-derived values\nexport const focusTrapSource = focusTrapSchema.source;\nexport const focusTrapMetadata = focusTrapSchema;\n\nconst FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'button:not(:disabled)',\n 'input:not(:disabled)',\n 'select:not(:disabled)',\n 'textarea:not(:disabled)',\n '[tabindex]:not([tabindex=\"-1\"])',\n].join(', ');\n\n/**\n * Resolve a selector parameter to an HTMLElement within the container.\n */\nfunction resolveElement(container: HTMLElement, param: unknown): HTMLElement | null {\n if (!param) return null;\n if (param instanceof HTMLElement) return param;\n if (typeof param === 'string') {\n return (\n (container.querySelector(param) as HTMLElement) ||\n (document.querySelector(param) as HTMLElement) ||\n null\n );\n }\n return null;\n}\n\n/**\n * Imperative installer for FocusTrap behavior.\n */\nfunction installFocusTrap(element: HTMLElement, params: Record<string, any>): void {\n const returnFocus = params.returnFocus !== false;\n let isActive = false;\n let previouslyFocused: Element | null = null;\n\n function getFocusableElements(): HTMLElement[] {\n return Array.from(element.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR));\n }\n\n function onKeyDown(e: KeyboardEvent) {\n if (!isActive || e.key !== 'Tab') return;\n\n const focusable = getFocusableElements();\n if (focusable.length === 0) {\n e.preventDefault();\n return;\n }\n\n // Always prevent default Tab and manually manage focus.\n // This ensures focus never escapes to elements outside the trap,\n // even when the modal is embedded in a page with other focusable elements.\n e.preventDefault();\n\n const currentIndex = focusable.indexOf(document.activeElement as HTMLElement);\n\n if (e.shiftKey) {\n const prevIndex = currentIndex <= 0 ? focusable.length - 1 : currentIndex - 1;\n focusable[prevIndex].focus();\n } else {\n const nextIndex = currentIndex >= focusable.length - 1 ? 0 : currentIndex + 1;\n focusable[nextIndex].focus();\n }\n }\n\n function activate() {\n if (isActive) return;\n isActive = true;\n previouslyFocused = document.activeElement;\n\n element.setAttribute('aria-modal', 'true');\n\n // Focus initialFocus element or first focusable\n const initialEl = resolveElement(element, params.initialFocus);\n if (initialEl) {\n initialEl.focus();\n } else {\n const focusable = getFocusableElements();\n if (focusable.length > 0) {\n focusable[0].focus();\n }\n }\n\n element.dispatchEvent(new CustomEvent('focustrap:activated', { bubbles: true }));\n }\n\n function deactivate() {\n if (!isActive) return;\n isActive = false;\n\n element.removeAttribute('aria-modal');\n\n if (returnFocus && previouslyFocused instanceof HTMLElement) {\n previouslyFocused.focus();\n }\n previouslyFocused = null;\n\n element.dispatchEvent(new CustomEvent('focustrap:deactivated', { bubbles: true }));\n }\n\n // Keydown handler for Tab trapping\n element.addEventListener('keydown', onKeyDown);\n\n // Programmatic activation/deactivation via custom events\n element.addEventListener('focustrap:activate', () => activate());\n element.addEventListener('focustrap:deactivate', () => deactivate());\n\n // Activate immediately if requested\n if (params.active !== false) {\n activate();\n }\n}\n\n/**\n * Register the FocusTrap behavior with LokaScript.\n */\nexport async function registerFocusTrap(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: 'FocusTrap',\n parameters: ['active', 'initialFocus', 'returnFocus'],\n eventHandlers: [],\n imperativeInstaller: installFocusTrap,\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 registerFocusTrap().catch(console.error);\n}\n\nexport default {\n source: focusTrapSchema.source,\n metadata: focusTrapSchema,\n register: registerFocusTrap,\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","/**\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":"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","names":[]}
|
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
focusTrapSource,
|
|
4
4
|
focustrap_default,
|
|
5
5
|
registerFocusTrap
|
|
6
|
-
} from "../chunk-
|
|
7
|
-
import "../chunk-
|
|
6
|
+
} from "../chunk-F3CASJ7Q.js";
|
|
7
|
+
import "../chunk-OJ3YWO3W.js";
|
|
8
8
|
import "../chunk-6TJXDCAQ.js";
|
|
9
9
|
export {
|
|
10
10
|
focustrap_default as default,
|
|
@@ -43,7 +43,7 @@ var removableSchema = {
|
|
|
43
43
|
description: "Element that triggers removal (e.g., a close button)"
|
|
44
44
|
},
|
|
45
45
|
{
|
|
46
|
-
name: "
|
|
46
|
+
name: "confirmRemoval",
|
|
47
47
|
type: "boolean",
|
|
48
48
|
optional: true,
|
|
49
49
|
default: false,
|
|
@@ -63,15 +63,18 @@ var removableSchema = {
|
|
|
63
63
|
{ name: "removable:removed", description: "Fired after removal" }
|
|
64
64
|
],
|
|
65
65
|
source: `
|
|
66
|
-
behavior Removable(triggerEl,
|
|
66
|
+
behavior Removable(triggerEl, confirmRemoval, effect)
|
|
67
67
|
init
|
|
68
68
|
if triggerEl is undefined
|
|
69
69
|
set triggerEl to me
|
|
70
70
|
end
|
|
71
71
|
end
|
|
72
72
|
on click from triggerEl
|
|
73
|
-
if
|
|
74
|
-
|
|
73
|
+
if confirmRemoval
|
|
74
|
+
js(me)
|
|
75
|
+
if (!window.confirm("Are you sure?")) return "cancel";
|
|
76
|
+
end
|
|
77
|
+
if it is "cancel"
|
|
75
78
|
halt
|
|
76
79
|
end
|
|
77
80
|
end
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/behaviors/removable.ts","../../src/schemas/removable.schema.ts","../../src/schemas/types.ts"],"sourcesContent":["/**\n * Removable Behavior\n *\n * A behavior that removes an element when a trigger is clicked.\n * Supports optional confirmation and transition effects.\n *\n * @example\n * ```html\n * <div _=\"install Removable\">Click to remove</div>\n *\n * <div _=\"install Removable(confirm: true)\">With confirmation</div>\n * ```\n */\n\nimport { removableSchema } from '../schemas/removable.schema';\nimport type { LokaScriptInstance } from '../schemas/types';\nimport { resolveRuntime } from '../schemas/types';\n\n// Re-export schema-derived values for backwards compatibility\nexport const removableSource = removableSchema.source;\nexport const removableMetadata = removableSchema;\n\n/**\n * Register the Removable behavior with LokaScript.\n */\nexport async function registerRemovable(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 result = hf.compileSync(removableSchema.source, { traditional: true });\n\n if (!result.ok) {\n throw new Error(`Failed to compile Removable behavior: ${JSON.stringify(result.errors)}`);\n }\n\n const ctx = hf.createContext ? hf.createContext() : { locals: new Map(), globals: new Map() };\n await hf.execute(result.ast, ctx);\n}\n\n// Auto-register when loaded as a script tag\nif (resolveRuntime()) {\n registerRemovable().catch(console.error);\n}\n\nexport default {\n source: removableSchema.source,\n metadata: removableSchema,\n register: registerRemovable,\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: '
|
|
1
|
+
{"version":3,"sources":["../../src/behaviors/removable.ts","../../src/schemas/removable.schema.ts","../../src/schemas/types.ts"],"sourcesContent":["/**\n * Removable Behavior\n *\n * A behavior that removes an element when a trigger is clicked.\n * Supports optional confirmation and transition effects.\n *\n * @example\n * ```html\n * <div _=\"install Removable\">Click to remove</div>\n *\n * <div _=\"install Removable(confirm: true)\">With confirmation</div>\n * ```\n */\n\nimport { removableSchema } from '../schemas/removable.schema';\nimport type { LokaScriptInstance } from '../schemas/types';\nimport { resolveRuntime } from '../schemas/types';\n\n// Re-export schema-derived values for backwards compatibility\nexport const removableSource = removableSchema.source;\nexport const removableMetadata = removableSchema;\n\n/**\n * Register the Removable behavior with LokaScript.\n */\nexport async function registerRemovable(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 result = hf.compileSync(removableSchema.source, { traditional: true });\n\n if (!result.ok) {\n throw new Error(`Failed to compile Removable behavior: ${JSON.stringify(result.errors)}`);\n }\n\n const ctx = hf.createContext ? hf.createContext() : { locals: new Map(), globals: new Map() };\n await hf.execute(result.ast, ctx);\n}\n\n// Auto-register when loaded as a script tag\nif (resolveRuntime()) {\n registerRemovable().catch(console.error);\n}\n\nexport default {\n source: removableSchema.source,\n metadata: removableSchema,\n register: registerRemovable,\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","/**\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":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACYO,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,MAAM,CAAC,QAAQ,MAAM;AAAA,MACrB,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,EAAE,MAAM,oBAAoB,aAAa,oCAAoC;AAAA,IAC7E,EAAE,MAAM,qBAAqB,aAAa,sBAAsB;AAAA,EAClE;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,EAwBR,KAAK;AACP;;;AC2CO,SAAS,iBAA4C;AAC1D,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,QAAM,MAAM;AACZ,SAAO,IAAI,cAAc,IAAI,aAAa;AAC5C;;;AFnGO,IAAM,kBAAkB,gBAAgB;AACxC,IAAM,oBAAoB;AAKjC,eAAsB,kBAAkB,WAA+C;AACrF,QAAM,KAAK,aAAa,eAAe;AAEvC,MAAI,CAAC,IAAI;AACP,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,GAAG,YAAY,gBAAgB,QAAQ,EAAE,aAAa,KAAK,CAAC;AAE3E,MAAI,CAAC,OAAO,IAAI;AACd,UAAM,IAAI,MAAM,yCAAyC,KAAK,UAAU,OAAO,MAAM,CAAC,EAAE;AAAA,EAC1F;AAEA,QAAM,MAAM,GAAG,gBAAgB,GAAG,cAAc,IAAI,EAAE,QAAQ,oBAAI,IAAI,GAAG,SAAS,oBAAI,IAAI,EAAE;AAC5F,QAAM,GAAG,QAAQ,OAAO,KAAK,GAAG;AAClC;AAGA,IAAI,eAAe,GAAG;AACpB,oBAAkB,EAAE,MAAM,QAAQ,KAAK;AACzC;AAEA,IAAO,oBAAQ;AAAA,EACb,QAAQ,gBAAgB;AAAA,EACxB,UAAU;AAAA,EACV,UAAU;AACZ;","names":[]}
|
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
removableMetadata,
|
|
4
4
|
removableSource,
|
|
5
5
|
removable_default
|
|
6
|
-
} from "../chunk-
|
|
7
|
-
import "../chunk-
|
|
6
|
+
} from "../chunk-L52AGCMP.js";
|
|
7
|
+
import "../chunk-HMU342XE.js";
|
|
8
8
|
import "../chunk-6TJXDCAQ.js";
|
|
9
9
|
export {
|
|
10
10
|
removable_default as default,
|
|
@@ -79,11 +79,21 @@ var resizableSchema = {
|
|
|
79
79
|
source: `
|
|
80
80
|
behavior Resizable(handle, minWidth, minHeight, maxWidth, maxHeight)
|
|
81
81
|
init
|
|
82
|
-
if
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
if
|
|
86
|
-
|
|
82
|
+
if handle is undefined
|
|
83
|
+
set handle to me
|
|
84
|
+
end
|
|
85
|
+
if minWidth is undefined
|
|
86
|
+
set minWidth to 50
|
|
87
|
+
end
|
|
88
|
+
if minHeight is undefined
|
|
89
|
+
set minHeight to 50
|
|
90
|
+
end
|
|
91
|
+
if maxWidth is undefined
|
|
92
|
+
set maxWidth to 9999
|
|
93
|
+
end
|
|
94
|
+
if maxHeight is undefined
|
|
95
|
+
set maxHeight to 9999
|
|
96
|
+
end
|
|
87
97
|
end
|
|
88
98
|
on pointerdown(clientX, clientY) from handle
|
|
89
99
|
halt the event
|
|
@@ -95,15 +105,13 @@ behavior Resizable(handle, minWidth, minHeight, maxWidth, maxHeight)
|
|
|
95
105
|
set startX to clientX
|
|
96
106
|
set startY to clientY
|
|
97
107
|
repeat until event pointerup from document
|
|
98
|
-
wait for pointermove(clientX, clientY) or
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
if newHeight > maxHeight set newHeight to maxHeight
|
|
106
|
-
add { width: \${newWidth}px; height: \${newHeight}px; }
|
|
108
|
+
wait for pointermove(clientX, clientY) or pointerup from document
|
|
109
|
+
js(startWidth, startHeight, clientX, clientY, startX, startY, minWidth, maxWidth, minHeight, maxHeight, me)
|
|
110
|
+
var nw = Math.max(minWidth, Math.min(maxWidth, startWidth + (clientX - startX)));
|
|
111
|
+
var nh = Math.max(minHeight, Math.min(maxHeight, startHeight + (clientY - startY)));
|
|
112
|
+
me.style.width = nw + 'px';
|
|
113
|
+
me.style.height = nh + 'px';
|
|
114
|
+
end
|
|
107
115
|
trigger resizable:resize
|
|
108
116
|
end
|
|
109
117
|
trigger resizable:end
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/behaviors/resizable.ts","../../src/schemas/resizable.schema.ts","../../src/schemas/types.ts"],"sourcesContent":["/**\n * Resizable Behavior — Imperative Implementation\n *\n * Makes elements resizable by dragging edges or corners.\n * Supports minimum/maximum dimensions and resize handles.\n *\n * @example\n * ```html\n * <div _=\"install Resizable\" style=\"width: 200px; height: 150px;\">\n * Resize me!\n * </div>\n * ```\n */\n\nimport { resizableSchema } from '../schemas/resizable.schema';\nimport type { LokaScriptInstance } from '../schemas/types';\nimport { resolveRuntime } from '../schemas/types';\n\n// Re-export schema-derived values for backwards compatibility\nexport const resizableSource = resizableSchema.source;\nexport const resizableMetadata = resizableSchema;\n\n/**\n * Imperative installer for Resizable behavior.\n */\nfunction installResizable(element: HTMLElement, params: Record<string, any>): void {\n // Resolve handle element\n let handleEl: HTMLElement = element;\n if (params.handle && params.handle !== 'me') {\n if (typeof params.handle === 'string') {\n const found = element.querySelector(params.handle);\n if (found instanceof HTMLElement) handleEl = found;\n } else if (params.handle instanceof HTMLElement) {\n handleEl = params.handle;\n }\n }\n\n const minW = params.minWidth ?? 50;\n const minH = params.minHeight ?? 50;\n const maxW = params.maxWidth ?? 9999;\n const maxH = params.maxHeight ?? 9999;\n\n handleEl.addEventListener('pointerdown', (e: PointerEvent) => {\n e.preventDefault();\n element.dispatchEvent(new CustomEvent('resizable:start', { bubbles: true }));\n\n const startWidth = element.offsetWidth;\n const startHeight = element.offsetHeight;\n const startX = e.clientX;\n const startY = e.clientY;\n\n function onMove(ev: PointerEvent) {\n const newWidth = Math.max(minW, Math.min(maxW, startWidth + (ev.clientX - startX)));\n const newHeight = Math.max(minH, Math.min(maxH, startHeight + (ev.clientY - startY)));\n\n element.style.width = `${newWidth}px`;\n element.style.height = `${newHeight}px`;\n element.dispatchEvent(new CustomEvent('resizable:resize', { bubbles: true }));\n }\n\n function onUp() {\n document.removeEventListener('pointermove', onMove);\n document.removeEventListener('pointerup', onUp);\n element.dispatchEvent(new CustomEvent('resizable:end', { bubbles: true }));\n }\n\n document.addEventListener('pointermove', onMove);\n document.addEventListener('pointerup', onUp);\n });\n}\n\n/**\n * Register the Resizable behavior with LokaScript.\n */\nexport async function registerResizable(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: 'Resizable',\n parameters: ['handle', 'minWidth', 'minHeight', 'maxWidth', 'maxHeight'],\n eventHandlers: [],\n imperativeInstaller: installResizable,\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 registerResizable().catch(console.error);\n}\n\nexport default {\n source: resizableSchema.source,\n metadata: resizableSchema,\n register: registerResizable,\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 no handle set handle to me\n if no minWidth set minWidth to 50\n if no minHeight set minHeight to 50\n if no maxWidth set maxWidth to 9999\n if no maxHeight set maxHeight to 9999\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\n pointerup from document\n set newWidth to startWidth + (clientX - startX)\n set newHeight to startHeight + (clientY - startY)\n if newWidth < minWidth set newWidth to minWidth\n if newWidth > maxWidth set newWidth to maxWidth\n if newHeight < minHeight set newHeight to minHeight\n if newHeight > maxHeight set newHeight to maxHeight\n add { width: \\${newWidth}px; height: \\${newHeight}px; }\n trigger resizable:resize\n end\n trigger resizable:end\n end\nend\n`.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":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/behaviors/resizable.ts","../../src/schemas/resizable.schema.ts","../../src/schemas/types.ts"],"sourcesContent":["/**\n * Resizable Behavior — Imperative Implementation\n *\n * Makes elements resizable by dragging edges or corners.\n * Supports minimum/maximum dimensions and resize handles.\n *\n * @example\n * ```html\n * <div _=\"install Resizable\" style=\"width: 200px; height: 150px;\">\n * Resize me!\n * </div>\n * ```\n */\n\nimport { resizableSchema } from '../schemas/resizable.schema';\nimport type { LokaScriptInstance } from '../schemas/types';\nimport { resolveRuntime } from '../schemas/types';\n\n// Re-export schema-derived values for backwards compatibility\nexport const resizableSource = resizableSchema.source;\nexport const resizableMetadata = resizableSchema;\n\n/**\n * Imperative installer for Resizable behavior.\n */\nfunction installResizable(element: HTMLElement, params: Record<string, any>): void {\n // Resolve handle element\n let handleEl: HTMLElement = element;\n if (params.handle && params.handle !== 'me') {\n if (typeof params.handle === 'string') {\n const found = element.querySelector(params.handle);\n if (found instanceof HTMLElement) handleEl = found;\n } else if (params.handle instanceof HTMLElement) {\n handleEl = params.handle;\n }\n }\n\n const minW = params.minWidth ?? 50;\n const minH = params.minHeight ?? 50;\n const maxW = params.maxWidth ?? 9999;\n const maxH = params.maxHeight ?? 9999;\n\n handleEl.addEventListener('pointerdown', (e: PointerEvent) => {\n e.preventDefault();\n element.dispatchEvent(new CustomEvent('resizable:start', { bubbles: true }));\n\n const startWidth = element.offsetWidth;\n const startHeight = element.offsetHeight;\n const startX = e.clientX;\n const startY = e.clientY;\n\n function onMove(ev: PointerEvent) {\n const newWidth = Math.max(minW, Math.min(maxW, startWidth + (ev.clientX - startX)));\n const newHeight = Math.max(minH, Math.min(maxH, startHeight + (ev.clientY - startY)));\n\n element.style.width = `${newWidth}px`;\n element.style.height = `${newHeight}px`;\n element.dispatchEvent(new CustomEvent('resizable:resize', { bubbles: true }));\n }\n\n function onUp() {\n document.removeEventListener('pointermove', onMove);\n document.removeEventListener('pointerup', onUp);\n element.dispatchEvent(new CustomEvent('resizable:end', { bubbles: true }));\n }\n\n document.addEventListener('pointermove', onMove);\n document.addEventListener('pointerup', onUp);\n });\n}\n\n/**\n * Register the Resizable behavior with LokaScript.\n */\nexport async function registerResizable(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: 'Resizable',\n parameters: ['handle', 'minWidth', 'minHeight', 'maxWidth', 'maxHeight'],\n eventHandlers: [],\n imperativeInstaller: installResizable,\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 registerResizable().catch(console.error);\n}\n\nexport default {\n source: resizableSchema.source,\n metadata: resizableSchema,\n register: registerResizable,\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","/**\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":"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","names":[]}
|
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
resizableMetadata,
|
|
4
4
|
resizableSource,
|
|
5
5
|
resizable_default
|
|
6
|
-
} from "../chunk-
|
|
7
|
-
import "../chunk-
|
|
6
|
+
} from "../chunk-IQM32TEY.js";
|
|
7
|
+
import "../chunk-U5GNXZUF.js";
|
|
8
8
|
import "../chunk-6TJXDCAQ.js";
|
|
9
9
|
export {
|
|
10
10
|
resizable_default as default,
|
|
@@ -55,13 +55,6 @@ var scrollRevealSchema = {
|
|
|
55
55
|
optional: true,
|
|
56
56
|
default: true,
|
|
57
57
|
description: "If true, disconnect observer after first intersection"
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
name: "rootMargin",
|
|
61
|
-
type: "string",
|
|
62
|
-
optional: true,
|
|
63
|
-
default: "0px",
|
|
64
|
-
description: "CSS margin around the viewport for triggering earlier or later"
|
|
65
58
|
}
|
|
66
59
|
],
|
|
67
60
|
events: [
|
|
@@ -70,14 +63,33 @@ var scrollRevealSchema = {
|
|
|
70
63
|
],
|
|
71
64
|
requirements: ["Uses IntersectionObserver API (supported in all modern browsers)"],
|
|
72
65
|
source: `
|
|
73
|
-
behavior ScrollReveal(cls, threshold, once
|
|
66
|
+
behavior ScrollReveal(cls, threshold, once)
|
|
74
67
|
init
|
|
75
|
-
if cls is undefined
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if
|
|
68
|
+
if cls is undefined
|
|
69
|
+
set cls to "revealed"
|
|
70
|
+
end
|
|
71
|
+
if threshold is undefined
|
|
72
|
+
set threshold to 0.1
|
|
73
|
+
end
|
|
74
|
+
if once is undefined
|
|
75
|
+
set once to true
|
|
76
|
+
end
|
|
77
|
+
js(me, cls, threshold, once)
|
|
78
|
+
var obs = new IntersectionObserver(function(entries) {
|
|
79
|
+
for (var i = 0; i < entries.length; i++) {
|
|
80
|
+
if (entries[i].isIntersecting) {
|
|
81
|
+
me.classList.add(cls);
|
|
82
|
+
me.dispatchEvent(new CustomEvent('scrollreveal:enter', { bubbles: true }));
|
|
83
|
+
if (once) obs.disconnect();
|
|
84
|
+
} else if (!once) {
|
|
85
|
+
me.classList.remove(cls);
|
|
86
|
+
me.dispatchEvent(new CustomEvent('scrollreveal:exit', { bubbles: true }));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}, { threshold: threshold });
|
|
90
|
+
obs.observe(me);
|
|
91
|
+
end
|
|
79
92
|
end
|
|
80
|
-
-- Imperative installer handles IntersectionObserver setup
|
|
81
93
|
end`.trim()
|
|
82
94
|
};
|
|
83
95
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/behaviors/scrollreveal.ts","../../src/schemas/scrollreveal.schema.ts","../../src/schemas/types.ts"],"sourcesContent":["/**\n * ScrollReveal Behavior — Imperative Implementation\n *\n * Adds a class or fires events when the element enters or exits the viewport.\n * Uses the IntersectionObserver web standard API.\n */\n\nimport { scrollRevealSchema } from '../schemas/scrollreveal.schema';\nimport type { LokaScriptInstance } from '../schemas/types';\nimport { resolveRuntime } from '../schemas/types';\n\n// Re-export schema-derived values\nexport const scrollRevealSource = scrollRevealSchema.source;\nexport const scrollRevealMetadata = scrollRevealSchema;\n\n/**\n * Imperative installer for ScrollReveal behavior.\n */\nfunction installScrollReveal(element: HTMLElement, params: Record<string, any>): void {\n const cls = typeof params.cls === 'string' ? params.cls : 'revealed';\n const threshold = typeof params.threshold === 'number' ? params.threshold : 0.1;\n const once = params.once !== false;\n const rootMargin = typeof params.rootMargin === 'string' ? params.rootMargin : '0px';\n\n const observer = new IntersectionObserver(\n entries => {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n element.classList.add(cls);\n element.dispatchEvent(new CustomEvent('scrollreveal:enter', { bubbles: true }));\n if (once) {\n observer.disconnect();\n }\n } else if (!once) {\n element.classList.remove(cls);\n element.dispatchEvent(new CustomEvent('scrollreveal:exit', { bubbles: true }));\n }\n }\n },\n { threshold, rootMargin }\n );\n\n observer.observe(element);\n}\n\n/**\n * Register the ScrollReveal behavior with LokaScript.\n */\nexport async function registerScrollReveal(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: 'ScrollReveal',\n parameters: ['cls', 'threshold', 'once', 'rootMargin'],\n eventHandlers: [],\n imperativeInstaller: installScrollReveal,\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 registerScrollReveal().catch(console.error);\n}\n\nexport default {\n source: scrollRevealSchema.source,\n metadata: scrollRevealSchema,\n register: registerScrollReveal,\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 name: 'rootMargin',\n type: 'string',\n optional: true,\n default: '0px',\n description: 'CSS margin around the viewport for triggering earlier or later',\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, rootMargin)\n init\n if cls is undefined set cls to \"revealed\"\n if threshold is undefined set threshold to 0.1\n if once is undefined set once to true\n if rootMargin is undefined set rootMargin to \"0px\"\n end\n -- Imperative installer handles IntersectionObserver setup\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":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACQO,IAAM,qBAAqC;AAAA,EAChD,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,EACF;AAAA,EACA,QAAQ;AAAA,IACN,EAAE,MAAM,sBAAsB,aAAa,6CAA6C;AAAA,IACxF,EAAE,MAAM,qBAAqB,aAAa,4CAA4C;AAAA,EACxF;AAAA,EACA,cAAc,CAAC,kEAAkE;AAAA,EACjF,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KASL,KAAK;AACV;;;ACuDO,SAAS,iBAA4C;AAC1D,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,QAAM,MAAM;AACZ,SAAO,IAAI,cAAc,IAAI,aAAa;AAC5C;;;AF1GO,IAAM,qBAAqB,mBAAmB;AAC9C,IAAM,uBAAuB;AAKpC,SAAS,oBAAoB,SAAsB,QAAmC;AACpF,QAAM,MAAM,OAAO,OAAO,QAAQ,WAAW,OAAO,MAAM;AAC1D,QAAM,YAAY,OAAO,OAAO,cAAc,WAAW,OAAO,YAAY;AAC5E,QAAM,OAAO,OAAO,SAAS;AAC7B,QAAM,aAAa,OAAO,OAAO,eAAe,WAAW,OAAO,aAAa;AAE/E,QAAM,WAAW,IAAI;AAAA,IACnB,aAAW;AACT,iBAAW,SAAS,SAAS;AAC3B,YAAI,MAAM,gBAAgB;AACxB,kBAAQ,UAAU,IAAI,GAAG;AACzB,kBAAQ,cAAc,IAAI,YAAY,sBAAsB,EAAE,SAAS,KAAK,CAAC,CAAC;AAC9E,cAAI,MAAM;AACR,qBAAS,WAAW;AAAA,UACtB;AAAA,QACF,WAAW,CAAC,MAAM;AAChB,kBAAQ,UAAU,OAAO,GAAG;AAC5B,kBAAQ,cAAc,IAAI,YAAY,qBAAqB,EAAE,SAAS,KAAK,CAAC,CAAC;AAAA,QAC/E;AAAA,MACF;AAAA,IACF;AAAA,IACA,EAAE,WAAW,WAAW;AAAA,EAC1B;AAEA,WAAS,QAAQ,OAAO;AAC1B;AAKA,eAAsB,qBAAqB,WAA+C;AACxF,QAAM,KAAK,aAAa,eAAe;AAEvC,MAAI,CAAC,IAAI;AACP,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,gBAAgB;AAAA,IACpB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,YAAY,CAAC,OAAO,aAAa,QAAQ,YAAY;AAAA,IACrD,eAAe,CAAC;AAAA,IAChB,qBAAqB;AAAA,EACvB;AACA,QAAM,MAAM,GAAG,gBAAgB,GAAG,cAAc,IAAI,EAAE,QAAQ,oBAAI,IAAI,GAAG,SAAS,oBAAI,IAAI,EAAE;AAC5F,QAAM,GAAG,QAAQ,eAAe,GAAG;AACrC;AAGA,IAAI,eAAe,GAAG;AACpB,uBAAqB,EAAE,MAAM,QAAQ,KAAK;AAC5C;AAEA,IAAO,uBAAQ;AAAA,EACb,QAAQ,mBAAmB;AAAA,EAC3B,UAAU;AAAA,EACV,UAAU;AACZ;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/behaviors/scrollreveal.ts","../../src/schemas/scrollreveal.schema.ts","../../src/schemas/types.ts"],"sourcesContent":["/**\n * ScrollReveal Behavior — Imperative Implementation\n *\n * Adds a class or fires events when the element enters or exits the viewport.\n * Uses the IntersectionObserver web standard API.\n */\n\nimport { scrollRevealSchema } from '../schemas/scrollreveal.schema';\nimport type { LokaScriptInstance } from '../schemas/types';\nimport { resolveRuntime } from '../schemas/types';\n\n// Re-export schema-derived values\nexport const scrollRevealSource = scrollRevealSchema.source;\nexport const scrollRevealMetadata = scrollRevealSchema;\n\n/**\n * Imperative installer for ScrollReveal behavior.\n */\nfunction installScrollReveal(element: HTMLElement, params: Record<string, any>): void {\n const cls = typeof params.cls === 'string' ? params.cls : 'revealed';\n const threshold = typeof params.threshold === 'number' ? params.threshold : 0.1;\n const once = params.once !== false;\n const rootMargin = typeof params.rootMargin === 'string' ? params.rootMargin : '0px';\n\n const observer = new IntersectionObserver(\n entries => {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n element.classList.add(cls);\n element.dispatchEvent(new CustomEvent('scrollreveal:enter', { bubbles: true }));\n if (once) {\n observer.disconnect();\n }\n } else if (!once) {\n element.classList.remove(cls);\n element.dispatchEvent(new CustomEvent('scrollreveal:exit', { bubbles: true }));\n }\n }\n },\n { threshold, rootMargin }\n );\n\n observer.observe(element);\n}\n\n/**\n * Register the ScrollReveal behavior with LokaScript.\n */\nexport async function registerScrollReveal(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: 'ScrollReveal',\n parameters: ['cls', 'threshold', 'once', 'rootMargin'],\n eventHandlers: [],\n imperativeInstaller: installScrollReveal,\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 registerScrollReveal().catch(console.error);\n}\n\nexport default {\n source: scrollRevealSchema.source,\n metadata: scrollRevealSchema,\n register: registerScrollReveal,\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","/**\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":"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","names":[]}
|
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
scrollRevealMetadata,
|
|
4
4
|
scrollRevealSource,
|
|
5
5
|
scrollreveal_default
|
|
6
|
-
} from "../chunk-
|
|
7
|
-
import "../chunk-
|
|
6
|
+
} from "../chunk-EKKJVXDZ.js";
|
|
7
|
+
import "../chunk-URZGNPTQ.js";
|
|
8
8
|
import "../chunk-6TJXDCAQ.js";
|
|
9
9
|
export {
|
|
10
10
|
scrollreveal_default as default,
|
|
@@ -62,27 +62,33 @@ var sortableSchema = {
|
|
|
62
62
|
source: `
|
|
63
63
|
behavior Sortable(handle, dragClass)
|
|
64
64
|
init
|
|
65
|
-
if
|
|
65
|
+
if dragClass is undefined
|
|
66
|
+
set dragClass to "sorting"
|
|
67
|
+
end
|
|
66
68
|
end
|
|
67
|
-
on pointerdown(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
if
|
|
69
|
+
on pointerdown(clientY) from me
|
|
70
|
+
js(me, handle, event)
|
|
71
|
+
var target = event.target;
|
|
72
|
+
var item = target.closest("li");
|
|
73
|
+
if (!item || !me.contains(item)) return false;
|
|
74
|
+
if (handle && !target.closest(handle)) return false;
|
|
75
|
+
event.preventDefault();
|
|
76
|
+
event.stopPropagation();
|
|
77
|
+
return true;
|
|
78
|
+
end
|
|
79
|
+
if it is false
|
|
80
|
+
exit
|
|
73
81
|
end
|
|
74
|
-
|
|
75
|
-
add dragClass to item
|
|
82
|
+
add .{dragClass} to me
|
|
76
83
|
trigger sortable:start on me
|
|
77
84
|
repeat until event pointerup from document
|
|
78
85
|
wait for pointermove(clientY) from document
|
|
79
86
|
trigger sortable:move on me
|
|
80
87
|
end
|
|
81
|
-
remove dragClass from
|
|
88
|
+
remove .{dragClass} from me
|
|
82
89
|
trigger sortable:end on me
|
|
83
90
|
end
|
|
84
|
-
end
|
|
85
|
-
`.trim()
|
|
91
|
+
end`.trim()
|
|
86
92
|
};
|
|
87
93
|
|
|
88
94
|
// src/schemas/types.ts
|
|
@@ -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 no dragClass set dragClass to \"sorting\"\n end\n on pointerdown(target, clientY) from me\n set item to closest <li/> in target\n if no item exit\n if handle\n set handleEl to target.closest(handle)\n if no handleEl 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\n`.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":"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","names":[]}
|
|
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":"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","names":[]}
|
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
sortableMetadata,
|
|
4
4
|
sortableSource,
|
|
5
5
|
sortable_default
|
|
6
|
-
} from "../chunk-
|
|
7
|
-
import "../chunk-
|
|
6
|
+
} from "../chunk-TLLGH5KX.js";
|
|
7
|
+
import "../chunk-NC6I6T7T.js";
|
|
8
8
|
import "../chunk-6TJXDCAQ.js";
|
|
9
9
|
export {
|
|
10
10
|
sortable_default as default,
|