@hyperfixi/behaviors 2.5.1 → 2.7.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/README.md +100 -0
- package/dist/all.browser.global.js +43 -40
- package/dist/all.browser.global.js.map +1 -1
- package/dist/autodismiss.browser.global.js +2 -2
- package/dist/autodismiss.browser.global.js.map +1 -1
- package/dist/behaviors/autodismiss.cjs +5 -54
- package/dist/behaviors/autodismiss.cjs.map +1 -1
- package/dist/behaviors/autodismiss.d.cts +3 -2
- package/dist/behaviors/autodismiss.d.ts +3 -2
- package/dist/behaviors/autodismiss.js +1 -1
- package/dist/behaviors/clickoutside.cjs +6 -28
- package/dist/behaviors/clickoutside.cjs.map +1 -1
- package/dist/behaviors/clickoutside.d.cts +3 -2
- package/dist/behaviors/clickoutside.d.ts +3 -2
- package/dist/behaviors/clickoutside.js +2 -2
- package/dist/behaviors/clipboard.cjs +30 -86
- package/dist/behaviors/clipboard.cjs.map +1 -1
- package/dist/behaviors/clipboard.d.cts +3 -2
- package/dist/behaviors/clipboard.d.ts +3 -2
- package/dist/behaviors/clipboard.js +2 -2
- package/dist/behaviors/draggable.cjs +6 -41
- package/dist/behaviors/draggable.cjs.map +1 -1
- package/dist/behaviors/draggable.d.cts +3 -3
- package/dist/behaviors/draggable.d.ts +3 -3
- package/dist/behaviors/draggable.js +2 -2
- package/dist/behaviors/focustrap.cjs +5 -81
- package/dist/behaviors/focustrap.cjs.map +1 -1
- package/dist/behaviors/focustrap.d.cts +3 -2
- package/dist/behaviors/focustrap.d.ts +3 -2
- package/dist/behaviors/focustrap.js +1 -1
- package/dist/behaviors/removable.d.cts +1 -1
- package/dist/behaviors/removable.d.ts +1 -1
- package/dist/behaviors/resizable.cjs +9 -49
- package/dist/behaviors/resizable.cjs.map +1 -1
- package/dist/behaviors/resizable.d.cts +3 -2
- package/dist/behaviors/resizable.d.ts +3 -2
- package/dist/behaviors/resizable.js +2 -2
- package/dist/behaviors/scrollreveal.cjs +5 -32
- package/dist/behaviors/scrollreveal.cjs.map +1 -1
- package/dist/behaviors/scrollreveal.d.cts +3 -2
- package/dist/behaviors/scrollreveal.d.ts +3 -2
- package/dist/behaviors/scrollreveal.js +1 -1
- package/dist/behaviors/sortable.cjs +8 -43
- package/dist/behaviors/sortable.cjs.map +1 -1
- package/dist/behaviors/sortable.d.cts +3 -2
- package/dist/behaviors/sortable.d.ts +3 -2
- package/dist/behaviors/sortable.js +2 -2
- package/dist/behaviors/tabs.cjs +5 -120
- package/dist/behaviors/tabs.cjs.map +1 -1
- package/dist/behaviors/tabs.d.cts +3 -2
- package/dist/behaviors/tabs.d.ts +3 -2
- package/dist/behaviors/tabs.js +1 -1
- package/dist/behaviors/toggleable.cjs +5 -27
- package/dist/behaviors/toggleable.cjs.map +1 -1
- package/dist/behaviors/toggleable.d.cts +3 -3
- package/dist/behaviors/toggleable.d.ts +3 -3
- package/dist/behaviors/toggleable.js +1 -1
- package/dist/{chunk-SLOXO6IY.js → chunk-26IX7QU7.js} +2 -2
- package/dist/{chunk-SLOXO6IY.js.map → chunk-26IX7QU7.js.map} +1 -1
- package/dist/chunk-2HUF6RMI.js +40 -0
- package/dist/chunk-2HUF6RMI.js.map +1 -0
- package/dist/{chunk-ZBSWTV6I.js → chunk-5LFOFVZ3.js} +5 -5
- package/dist/chunk-5LFOFVZ3.js.map +1 -0
- package/dist/{chunk-BBIIOGMF.js → chunk-6EG2MNC7.js} +6 -6
- package/dist/chunk-7NGOA3T5.js +40 -0
- package/dist/chunk-7NGOA3T5.js.map +1 -0
- package/dist/{chunk-ZZ2WSAX3.js → chunk-7TPDLB7W.js} +7 -29
- package/dist/chunk-7TPDLB7W.js.map +1 -0
- package/dist/chunk-CR3J7VV6.js +40 -0
- package/dist/chunk-CR3J7VV6.js.map +1 -0
- package/dist/chunk-EDBG2F57.js +40 -0
- package/dist/chunk-EDBG2F57.js.map +1 -0
- package/dist/{chunk-G6WR2AYR.js → chunk-FBQ3X3UY.js} +2 -2
- package/dist/chunk-FBQ3X3UY.js.map +1 -0
- package/dist/chunk-HX663BJ4.js +40 -0
- package/dist/chunk-HX663BJ4.js.map +1 -0
- package/dist/chunk-KROW43CG.js +40 -0
- package/dist/chunk-KROW43CG.js.map +1 -0
- package/dist/chunk-ORBJ7MRW.js +40 -0
- package/dist/chunk-ORBJ7MRW.js.map +1 -0
- package/dist/{chunk-V2M4W3LO.js → chunk-PDMOOWFW.js} +4 -4
- package/dist/chunk-PDMOOWFW.js.map +1 -0
- package/dist/chunk-SLSCZV4A.js +40 -0
- package/dist/chunk-SLSCZV4A.js.map +1 -0
- package/dist/chunk-WKBRZGGL.js +40 -0
- package/dist/chunk-WKBRZGGL.js.map +1 -0
- package/dist/{chunk-WOTZO7K4.js → chunk-YXS27XM6.js} +26 -23
- package/dist/chunk-YXS27XM6.js.map +1 -0
- package/dist/clickoutside.browser.global.js +3 -3
- package/dist/clickoutside.browser.global.js.map +1 -1
- package/dist/clipboard.browser.global.js +27 -24
- package/dist/clipboard.browser.global.js.map +1 -1
- package/dist/core.browser.global.js +3 -3
- package/dist/core.browser.global.js.map +1 -1
- package/dist/draggable.browser.global.js +2 -2
- package/dist/draggable.browser.global.js.map +1 -1
- package/dist/focustrap.browser.global.js +2 -2
- package/dist/focustrap.browser.global.js.map +1 -1
- package/dist/index.cjs +120 -563
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +41 -3
- package/dist/index.d.ts +41 -3
- package/dist/index.js +44 -16
- package/dist/index.js.map +1 -1
- package/dist/loaders.cjs +86 -563
- package/dist/loaders.cjs.map +1 -1
- package/dist/loaders.js +6 -6
- package/dist/registry.d.cts +1 -1
- package/dist/registry.d.ts +1 -1
- package/dist/resizable.browser.global.js +5 -5
- package/dist/resizable.browser.global.js.map +1 -1
- package/dist/resolver.browser.global.js +34 -31
- package/dist/resolver.browser.global.js.map +1 -1
- package/dist/schemas/index.cjs +34 -31
- package/dist/schemas/index.cjs.map +1 -1
- package/dist/schemas/index.d.cts +2 -2
- package/dist/schemas/index.d.ts +2 -2
- package/dist/schemas/index.js +5 -5
- package/dist/scrollreveal.browser.global.js +2 -2
- package/dist/scrollreveal.browser.global.js.map +1 -1
- package/dist/sortable.browser.global.js +4 -4
- package/dist/sortable.browser.global.js.map +1 -1
- package/dist/tabs.browser.global.js +2 -2
- package/dist/tabs.browser.global.js.map +1 -1
- package/dist/toggleable.browser.global.js +2 -2
- package/dist/toggleable.browser.global.js.map +1 -1
- package/dist/{types-BY-jB5FV.d.ts → types-DCCtVQS5.d.cts} +1 -1
- package/dist/{types-BY-jB5FV.d.cts → types-DCCtVQS5.d.ts} +1 -1
- package/package.json +4 -4
- package/src/behaviors/autodismiss.test.ts +15 -9
- package/src/behaviors/autodismiss.ts +15 -70
- package/src/behaviors/clickoutside.test.ts +17 -9
- package/src/behaviors/clickoutside.ts +13 -39
- package/src/behaviors/clipboard.test.ts +16 -10
- package/src/behaviors/clipboard.ts +15 -93
- package/src/behaviors/curated-runtime.test.ts +158 -0
- package/src/behaviors/draggable.ts +15 -59
- package/src/behaviors/experimental-runtime.test.ts +136 -0
- package/src/behaviors/focustrap.test.ts +15 -9
- package/src/behaviors/focustrap.ts +17 -121
- package/src/behaviors/integration.test.ts +9 -64
- package/src/behaviors/optional-runtime.test.ts +251 -0
- package/src/behaviors/resizable.ts +14 -61
- package/src/behaviors/scrollreveal.test.ts +17 -9
- package/src/behaviors/scrollreveal.ts +17 -41
- package/src/behaviors/sortable.ts +15 -58
- package/src/behaviors/tabs.test.ts +16 -10
- package/src/behaviors/tabs.ts +18 -160
- package/src/behaviors/toggleable.ts +14 -41
- package/src/curation.test.ts +45 -0
- package/src/curation.ts +58 -0
- package/src/index.ts +14 -0
- package/src/registry.test.ts +6 -11
- package/src/schemas/clickoutside.schema.ts +1 -1
- package/src/schemas/clipboard.schema.ts +25 -22
- package/src/schemas/draggable.schema.ts +2 -1
- package/src/schemas/resizable.schema.ts +5 -4
- package/src/schemas/sortable.schema.ts +4 -3
- package/dist/chunk-7O7UOSBH.js +0 -99
- package/dist/chunk-7O7UOSBH.js.map +0 -1
- package/dist/chunk-EKKJVXDZ.js +0 -67
- package/dist/chunk-EKKJVXDZ.js.map +0 -1
- package/dist/chunk-F3CASJ7Q.js +0 -116
- package/dist/chunk-F3CASJ7Q.js.map +0 -1
- package/dist/chunk-G6WR2AYR.js.map +0 -1
- package/dist/chunk-GALKOMJ5.js +0 -62
- package/dist/chunk-GALKOMJ5.js.map +0 -1
- package/dist/chunk-IMDFEGIT.js +0 -75
- package/dist/chunk-IMDFEGIT.js.map +0 -1
- package/dist/chunk-IT6TYVMW.js +0 -80
- package/dist/chunk-IT6TYVMW.js.map +0 -1
- package/dist/chunk-LQJOQTBZ.js +0 -89
- package/dist/chunk-LQJOQTBZ.js.map +0 -1
- package/dist/chunk-S4QDV2MH.js +0 -75
- package/dist/chunk-S4QDV2MH.js.map +0 -1
- package/dist/chunk-V2M4W3LO.js.map +0 -1
- package/dist/chunk-WOTZO7K4.js.map +0 -1
- package/dist/chunk-WPOQIMCC.js +0 -155
- package/dist/chunk-WPOQIMCC.js.map +0 -1
- package/dist/chunk-ZBSWTV6I.js.map +0 -1
- package/dist/chunk-ZZ2WSAX3.js.map +0 -1
- /package/dist/{chunk-BBIIOGMF.js.map → chunk-6EG2MNC7.js.map} +0 -0
|
@@ -103,30 +103,6 @@ function resolveRuntime() {
|
|
|
103
103
|
// src/behaviors/scrollreveal.ts
|
|
104
104
|
var scrollRevealSource = scrollRevealSchema.source;
|
|
105
105
|
var scrollRevealMetadata = scrollRevealSchema;
|
|
106
|
-
function installScrollReveal(element, params) {
|
|
107
|
-
const cls = typeof params.cls === "string" ? params.cls : "revealed";
|
|
108
|
-
const threshold = typeof params.threshold === "number" ? params.threshold : 0.1;
|
|
109
|
-
const once = params.once !== false;
|
|
110
|
-
const rootMargin = typeof params.rootMargin === "string" ? params.rootMargin : "0px";
|
|
111
|
-
const observer = new IntersectionObserver(
|
|
112
|
-
(entries) => {
|
|
113
|
-
for (const entry of entries) {
|
|
114
|
-
if (entry.isIntersecting) {
|
|
115
|
-
element.classList.add(cls);
|
|
116
|
-
element.dispatchEvent(new CustomEvent("scrollreveal:enter", { bubbles: true }));
|
|
117
|
-
if (once) {
|
|
118
|
-
observer.disconnect();
|
|
119
|
-
}
|
|
120
|
-
} else if (!once) {
|
|
121
|
-
element.classList.remove(cls);
|
|
122
|
-
element.dispatchEvent(new CustomEvent("scrollreveal:exit", { bubbles: true }));
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
},
|
|
126
|
-
{ threshold, rootMargin }
|
|
127
|
-
);
|
|
128
|
-
observer.observe(element);
|
|
129
|
-
}
|
|
130
106
|
async function registerScrollReveal(hyperfixi) {
|
|
131
107
|
const hf = hyperfixi || resolveRuntime();
|
|
132
108
|
if (!hf) {
|
|
@@ -134,15 +110,12 @@ async function registerScrollReveal(hyperfixi) {
|
|
|
134
110
|
"LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors."
|
|
135
111
|
);
|
|
136
112
|
}
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
eventHandlers: [],
|
|
142
|
-
imperativeInstaller: installScrollReveal
|
|
143
|
-
};
|
|
113
|
+
const result = hf.compileSync(scrollRevealSchema.source, { traditional: true });
|
|
114
|
+
if (!result.ok) {
|
|
115
|
+
throw new Error(`Failed to compile ScrollReveal behavior: ${JSON.stringify(result.errors)}`);
|
|
116
|
+
}
|
|
144
117
|
const ctx = hf.createContext ? hf.createContext() : { locals: /* @__PURE__ */ new Map(), globals: /* @__PURE__ */ new Map() };
|
|
145
|
-
await hf.execute(
|
|
118
|
+
await hf.execute(result.ast, ctx);
|
|
146
119
|
}
|
|
147
120
|
if (resolveRuntime()) {
|
|
148
121
|
registerScrollReveal().catch(console.error);
|
|
@@ -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 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":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/behaviors/scrollreveal.ts","../../src/schemas/scrollreveal.schema.ts","../../src/schemas/types.ts"],"sourcesContent":["/**\n * ScrollReveal Behavior\n *\n * Adds a class or fires events when the element enters or exits the viewport.\n * Uses the IntersectionObserver web standard API (in its hyperscript `source`'s\n * `init`-block `js()` body).\n *\n * Compiled from its hyperscript `source` — the single source of truth shared with\n * the CDN resolver bundle and patterns-reference. This collapses ScrollReveal onto\n * the one runtime path (no more imperative-installer fork between CDN and npm);\n * see docs-internal/BEHAVIORS_CONSOLIDATION_PLAN.md §3d.\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 * Register the ScrollReveal behavior with LokaScript by compiling its\n * hyperscript source and executing the resulting behavior definition.\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 result = hf.compileSync(scrollRevealSchema.source, { traditional: true });\n\n if (!result.ok) {\n throw new Error(`Failed to compile ScrollReveal 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 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":";;;;;;;;;;;;;;;;;;;;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,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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KA4BL,KAAK;AACV;;;AC2CO,SAAS,iBAA4C;AAC1D,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,QAAM,MAAM;AACZ,SAAO,IAAI,cAAc,IAAI,aAAa;AAC5C;;;AFpGO,IAAM,qBAAqB,mBAAmB;AAC9C,IAAM,uBAAuB;AAMpC,eAAsB,qBAAqB,WAA+C;AACxF,QAAM,KAAK,aAAa,eAAe;AAEvC,MAAI,CAAC,IAAI;AACP,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,GAAG,YAAY,mBAAmB,QAAQ,EAAE,aAAa,KAAK,CAAC;AAE9E,MAAI,CAAC,OAAO,IAAI;AACd,UAAM,IAAI,MAAM,4CAA4C,KAAK,UAAU,OAAO,MAAM,CAAC,EAAE;AAAA,EAC7F;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,uBAAqB,EAAE,MAAM,QAAQ,KAAK;AAC5C;AAEA,IAAO,uBAAQ;AAAA,EACb,QAAQ,mBAAmB;AAAA,EAC3B,UAAU;AAAA,EACV,UAAU;AACZ;","names":[]}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { B as BehaviorSchema, L as LokaScriptInstance } from '../types-DCCtVQS5.cjs';
|
|
2
2
|
|
|
3
3
|
declare const scrollRevealSource: string;
|
|
4
4
|
declare const scrollRevealMetadata: BehaviorSchema;
|
|
5
5
|
/**
|
|
6
|
-
* Register the ScrollReveal behavior with LokaScript
|
|
6
|
+
* Register the ScrollReveal behavior with LokaScript by compiling its
|
|
7
|
+
* hyperscript source and executing the resulting behavior definition.
|
|
7
8
|
*/
|
|
8
9
|
declare function registerScrollReveal(hyperfixi?: LokaScriptInstance): Promise<void>;
|
|
9
10
|
declare const _default: {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { B as BehaviorSchema, L as LokaScriptInstance } from '../types-DCCtVQS5.js';
|
|
2
2
|
|
|
3
3
|
declare const scrollRevealSource: string;
|
|
4
4
|
declare const scrollRevealMetadata: BehaviorSchema;
|
|
5
5
|
/**
|
|
6
|
-
* Register the ScrollReveal behavior with LokaScript
|
|
6
|
+
* Register the ScrollReveal behavior with LokaScript by compiling its
|
|
7
|
+
* hyperscript source and executing the resulting behavior definition.
|
|
7
8
|
*/
|
|
8
9
|
declare function registerScrollReveal(hyperfixi?: LokaScriptInstance): Promise<void>;
|
|
9
10
|
declare const _default: {
|
|
@@ -33,7 +33,7 @@ var sortableSchema = {
|
|
|
33
33
|
category: "ui",
|
|
34
34
|
tier: "common",
|
|
35
35
|
version: "1.0.0",
|
|
36
|
-
description: "Makes child elements reorderable via drag-and-drop",
|
|
36
|
+
description: "Makes child elements reorderable via drag-and-drop (EXPERIMENTAL \u2014 stateful async component, beyond the inline-scripting boundary; not part of the curated set)",
|
|
37
37
|
parameters: [
|
|
38
38
|
{
|
|
39
39
|
name: "dragClass",
|
|
@@ -60,7 +60,7 @@ behavior Sortable(dragClass)
|
|
|
60
60
|
end
|
|
61
61
|
end
|
|
62
62
|
on pointerdown(clientY) from me
|
|
63
|
-
set item to the closest
|
|
63
|
+
set item to the target.closest("li")
|
|
64
64
|
if item is null
|
|
65
65
|
exit
|
|
66
66
|
end
|
|
@@ -68,7 +68,7 @@ behavior Sortable(dragClass)
|
|
|
68
68
|
add .{dragClass} to item
|
|
69
69
|
trigger sortable:start on me
|
|
70
70
|
repeat until event pointerup from document
|
|
71
|
-
wait for pointermove(clientY) from document
|
|
71
|
+
wait for pointermove(clientY) or pointerup(clientY) from document
|
|
72
72
|
trigger sortable:move on me
|
|
73
73
|
end
|
|
74
74
|
remove .{dragClass} from item
|
|
@@ -87,38 +87,6 @@ function resolveRuntime() {
|
|
|
87
87
|
// src/behaviors/sortable.ts
|
|
88
88
|
var sortableSource = sortableSchema.source;
|
|
89
89
|
var sortableMetadata = sortableSchema;
|
|
90
|
-
function installSortable(element, params) {
|
|
91
|
-
const dragClass = params.dragClass || "sorting";
|
|
92
|
-
const handleSelector = params.handle || null;
|
|
93
|
-
element.addEventListener("pointerdown", (e) => {
|
|
94
|
-
const target = e.target;
|
|
95
|
-
const item = target.closest("li");
|
|
96
|
-
if (!item || !element.contains(item)) return;
|
|
97
|
-
if (handleSelector) {
|
|
98
|
-
const handleEl = target.closest(handleSelector);
|
|
99
|
-
if (!handleEl) return;
|
|
100
|
-
}
|
|
101
|
-
e.preventDefault();
|
|
102
|
-
item.classList.add(dragClass);
|
|
103
|
-
element.dispatchEvent(new CustomEvent("sortable:start", { bubbles: true, detail: { item } }));
|
|
104
|
-
function onMove(ev) {
|
|
105
|
-
element.dispatchEvent(
|
|
106
|
-
new CustomEvent("sortable:move", {
|
|
107
|
-
bubbles: true,
|
|
108
|
-
detail: { clientY: ev.clientY, item }
|
|
109
|
-
})
|
|
110
|
-
);
|
|
111
|
-
}
|
|
112
|
-
function onUp() {
|
|
113
|
-
document.removeEventListener("pointermove", onMove);
|
|
114
|
-
document.removeEventListener("pointerup", onUp);
|
|
115
|
-
item.classList.remove(dragClass);
|
|
116
|
-
element.dispatchEvent(new CustomEvent("sortable:end", { bubbles: true, detail: { item } }));
|
|
117
|
-
}
|
|
118
|
-
document.addEventListener("pointermove", onMove);
|
|
119
|
-
document.addEventListener("pointerup", onUp);
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
90
|
async function registerSortable(hyperfixi) {
|
|
123
91
|
const hf = hyperfixi || resolveRuntime();
|
|
124
92
|
if (!hf) {
|
|
@@ -126,15 +94,12 @@ async function registerSortable(hyperfixi) {
|
|
|
126
94
|
"LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors."
|
|
127
95
|
);
|
|
128
96
|
}
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
eventHandlers: [],
|
|
134
|
-
imperativeInstaller: installSortable
|
|
135
|
-
};
|
|
97
|
+
const result = hf.compileSync(sortableSchema.source, { traditional: true });
|
|
98
|
+
if (!result.ok) {
|
|
99
|
+
throw new Error(`Failed to compile Sortable behavior: ${JSON.stringify(result.errors)}`);
|
|
100
|
+
}
|
|
136
101
|
const ctx = hf.createContext ? hf.createContext() : { locals: /* @__PURE__ */ new Map(), globals: /* @__PURE__ */ new Map() };
|
|
137
|
-
await hf.execute(
|
|
102
|
+
await hf.execute(result.ast, ctx);
|
|
138
103
|
}
|
|
139
104
|
if (resolveRuntime()) {
|
|
140
105
|
registerSortable().catch(console.error);
|
|
@@ -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: ['dragClass'],\n eventHandlers: [],\n imperativeInstaller: installSortable,\n };\n const ctx = hf.createContext ? hf.createContext() : { locals: new Map(), globals: new Map() };\n await hf.execute(syntheticNode, ctx);\n}\n\n// Auto-register when loaded as a script tag\nif (resolveRuntime()) {\n registerSortable().catch(console.error);\n}\n\nexport default {\n source: sortableSchema.source,\n metadata: sortableSchema,\n register: registerSortable,\n};\n","import type { BehaviorSchema } from './types';\n\n/**\n * Sortable Behavior Schema\n *\n * Drag-and-drop reordering of list items.\n * Apply to a container element; children become sortable.\n *\n * Note: This behavior fires lifecycle events but does NOT automatically\n * reorder DOM elements. Users must handle actual reordering in their\n * `sortable:move` event handlers.\n */\nexport const sortableSchema: BehaviorSchema = {\n name: 'Sortable',\n category: 'ui',\n tier: 'common',\n version: '1.0.0',\n description: 'Makes child elements reorderable via drag-and-drop',\n parameters: [\n {\n name: 'dragClass',\n type: 'string',\n optional: true,\n default: 'sorting',\n description: 'CSS class added to item during drag',\n },\n ],\n events: [\n { name: 'sortable:start', description: 'Fired when drag begins' },\n {\n name: 'sortable:move',\n description: 'Fired during drag — handle this event to reorder DOM elements',\n },\n { name: 'sortable:end', description: 'Fired when drag completes' },\n ],\n requirements: ['Users must handle DOM reordering in sortable:move event handlers'],\n source: `\nbehavior Sortable(dragClass)\n init\n if dragClass is undefined\n set dragClass to \"sorting\"\n end\n end\n on pointerdown(clientY) from me\n set item to the closest <li/> to the target\n if item is null\n exit\n end\n halt the event\n add .{dragClass} to item\n trigger sortable:start on me\n repeat until event pointerup from document\n wait for pointermove(clientY) from document\n trigger sortable:move on me\n end\n remove .{dragClass} from item\n trigger sortable:end on me\n end\nend`.trim(),\n};\n","/**\n * Behavior Schema Types\n *\n * Defines the structure for behavior metadata used for:\n * - Code generation (TypeScript types, documentation)\n * - Runtime categorization and lazy loading\n * - Tooling and IDE integration\n */\n\n/**\n * Behavior categories for organization.\n * - ui: Visual interaction behaviors (drag, resize, sort)\n * - data: Data manipulation behaviors (remove, transform)\n * - animation: Animation and transition behaviors\n * - form: Form-related behaviors (validation, toggle states)\n * - layout: Layout behaviors (sticky, scrollspy)\n */\nexport type BehaviorCategory = 'ui' | 'data' | 'animation' | 'form' | 'layout';\n\n/**\n * Loading tiers for lazy loading optimization.\n * - core: Always loaded (essential behaviors)\n * - common: High usage (loaded for typical apps)\n * - optional: Low usage (loaded on demand)\n */\nexport type BehaviorTier = 'core' | 'common' | 'optional';\n\n/**\n * Schema for a behavior parameter.\n */\nexport interface ParameterSchema {\n name: string;\n type: 'string' | 'number' | 'boolean' | 'selector' | 'element';\n optional?: boolean;\n default?: string | number | boolean;\n /** Allowed values for constrained parameters */\n enum?: string[];\n description: string;\n}\n\n/**\n * Schema for a behavior event.\n */\nexport interface EventSchema {\n name: string;\n description: string;\n}\n\n/**\n * Complete schema for a behavior.\n * This is the source of truth for all behavior metadata.\n */\nexport interface BehaviorSchema {\n /** Behavior name (PascalCase) */\n name: string;\n /** Category for organization */\n category: BehaviorCategory;\n /** Loading tier for lazy loading */\n tier: BehaviorTier;\n /** Semantic version */\n version: string;\n /** Human-readable description */\n description: string;\n /** Parameter definitions */\n parameters: ParameterSchema[];\n /** Event definitions */\n events: EventSchema[];\n /** The hyperscript behavior source code */\n source: string;\n /** Optional requirements or notes */\n requirements?: string[];\n}\n\n/**\n * Runtime behavior module interface.\n * This is what gets registered with the hyperfixi runtime.\n */\nexport interface BehaviorModule {\n source: string;\n metadata: BehaviorSchema;\n register: (hyperfixi?: LokaScriptInstance) => Promise<void>;\n}\n\n/**\n * Minimal LokaScript instance interface for behavior registration.\n */\nexport interface LokaScriptInstance {\n compileSync: (\n code: string,\n options?: { traditional?: boolean; language?: string }\n ) => {\n ok: boolean;\n ast?: unknown;\n errors?: Array<{ message: string; line?: number; column?: number }>;\n };\n execute: (ast: unknown, ctx: unknown) => Promise<unknown>;\n createContext?: () => { locals: Map<string, unknown>; globals: Map<string, unknown> };\n}\n\n/**\n * Typed window interface for behavior auto-registration.\n * Avoids `(window as any)` casts throughout the codebase.\n * Checks both `window.lokascript` and `window.hyperfixi` for the runtime instance.\n */\nexport interface LokaScriptWindow {\n lokascript?: LokaScriptInstance;\n hyperfixi?: LokaScriptInstance;\n __hyperfixi_behaviors_ready?: Promise<void> | undefined;\n}\n\n/**\n * Resolve the LokaScript runtime from window globals.\n * Checks both `window.lokascript` and `window.hyperfixi`.\n */\nexport function resolveRuntime(): LokaScriptInstance | null {\n if (typeof window === 'undefined') return null;\n const win = window as unknown as LokaScriptWindow;\n return win.lokascript || win.hyperfixi || null;\n}\n"],"mappings":"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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\n *\n * Drag-and-drop reordering of list items. Apply to a container element; its\n * `<li>` children become sortable. Compiled from its hyperscript `source` (single\n * source of truth) — no imperative installer.\n *\n * Note: This behavior fires lifecycle events but does NOT automatically reorder\n * DOM elements. Users handle actual reordering in their `sortable:move` 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 * Register the Sortable behavior with LokaScript by compiling its hyperscript\n * source and executing the resulting behavior definition.\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 result = hf.compileSync(sortableSchema.source, { traditional: true });\n\n if (!result.ok) {\n throw new Error(`Failed to compile Sortable 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 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:\n 'Makes child elements reorderable via drag-and-drop (EXPERIMENTAL — stateful async component, beyond the inline-scripting boundary; not part of the curated set)',\n parameters: [\n {\n name: 'dragClass',\n type: 'string',\n optional: true,\n default: 'sorting',\n description: 'CSS class added to item during drag',\n },\n ],\n events: [\n { name: 'sortable:start', description: 'Fired when drag begins' },\n {\n name: 'sortable:move',\n description: 'Fired during drag — handle this event to reorder DOM elements',\n },\n { name: 'sortable:end', description: 'Fired when drag completes' },\n ],\n requirements: ['Users must handle DOM reordering in sortable:move event handlers'],\n source: `\nbehavior Sortable(dragClass)\n init\n if dragClass is undefined\n set dragClass to \"sorting\"\n end\n end\n on pointerdown(clientY) from me\n set item to the target.closest(\"li\")\n if item is null\n exit\n end\n halt the event\n add .{dragClass} to item\n trigger sortable:start on me\n repeat until event pointerup from document\n wait for pointermove(clientY) or pointerup(clientY) from document\n trigger sortable:move on me\n end\n remove .{dragClass} from item\n trigger sortable:end on me\n end\nend`.trim(),\n};\n","/**\n * Behavior Schema Types\n *\n * Defines the structure for behavior metadata used for:\n * - Code generation (TypeScript types, documentation)\n * - Runtime categorization and lazy loading\n * - Tooling and IDE integration\n */\n\n/**\n * Behavior categories for organization.\n * - ui: Visual interaction behaviors (drag, resize, sort)\n * - data: Data manipulation behaviors (remove, transform)\n * - animation: Animation and transition behaviors\n * - form: Form-related behaviors (validation, toggle states)\n * - layout: Layout behaviors (sticky, scrollspy)\n */\nexport type BehaviorCategory = 'ui' | 'data' | 'animation' | 'form' | 'layout';\n\n/**\n * Loading tiers for lazy loading optimization.\n * - core: Always loaded (essential behaviors)\n * - common: High usage (loaded for typical apps)\n * - optional: Low usage (loaded on demand)\n */\nexport type BehaviorTier = 'core' | 'common' | 'optional';\n\n/**\n * Schema for a behavior parameter.\n */\nexport interface ParameterSchema {\n name: string;\n type: 'string' | 'number' | 'boolean' | 'selector' | 'element';\n optional?: boolean;\n default?: string | number | boolean;\n /** Allowed values for constrained parameters */\n enum?: string[];\n description: string;\n}\n\n/**\n * Schema for a behavior event.\n */\nexport interface EventSchema {\n name: string;\n description: string;\n}\n\n/**\n * Complete schema for a behavior.\n * This is the source of truth for all behavior metadata.\n */\nexport interface BehaviorSchema {\n /** Behavior name (PascalCase) */\n name: string;\n /** Category for organization */\n category: BehaviorCategory;\n /** Loading tier for lazy loading */\n tier: BehaviorTier;\n /** Semantic version */\n version: string;\n /** Human-readable description */\n description: string;\n /** Parameter definitions */\n parameters: ParameterSchema[];\n /** Event definitions */\n events: EventSchema[];\n /** The hyperscript behavior source code */\n source: string;\n /** Optional requirements or notes */\n requirements?: string[];\n}\n\n/**\n * Runtime behavior module interface.\n * This is what gets registered with the hyperfixi runtime.\n */\nexport interface BehaviorModule {\n source: string;\n metadata: BehaviorSchema;\n register: (hyperfixi?: LokaScriptInstance) => Promise<void>;\n}\n\n/**\n * Minimal LokaScript instance interface for behavior registration.\n */\nexport interface LokaScriptInstance {\n compileSync: (\n code: string,\n options?: { traditional?: boolean; language?: string }\n ) => {\n ok: boolean;\n ast?: unknown;\n errors?: Array<{ message: string; line?: number; column?: number }>;\n };\n execute: (ast: unknown, ctx: unknown) => Promise<unknown>;\n createContext?: () => { locals: Map<string, unknown>; globals: Map<string, unknown> };\n}\n\n/**\n * Typed window interface for behavior auto-registration.\n * Avoids `(window as any)` casts throughout the codebase.\n * Checks both `window.lokascript` and `window.hyperfixi` for the runtime instance.\n */\nexport interface LokaScriptWindow {\n lokascript?: LokaScriptInstance;\n hyperfixi?: LokaScriptInstance;\n __hyperfixi_behaviors_ready?: Promise<void> | undefined;\n}\n\n/**\n * Resolve the LokaScript runtime from window globals.\n * Checks both `window.lokascript` and `window.hyperfixi`.\n */\nexport function resolveRuntime(): LokaScriptInstance | null {\n if (typeof window === 'undefined') return null;\n const win = window as unknown as LokaScriptWindow;\n return win.lokascript || win.hyperfixi || null;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACYO,IAAM,iBAAiC;AAAA,EAC5C,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAM;AAAA,EACN,SAAS;AAAA,EACT,aACE;AAAA,EACF,YAAY;AAAA,IACV;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,EAAE,MAAM,kBAAkB,aAAa,yBAAyB;AAAA,IAChE;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,EAAE,MAAM,gBAAgB,aAAa,4BAA4B;AAAA,EACnE;AAAA,EACA,cAAc,CAAC,kEAAkE;AAAA,EACjF,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAsBL,KAAK;AACV;;;ACsDO,SAAS,iBAA4C;AAC1D,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,QAAM,MAAM;AACZ,SAAO,IAAI,cAAc,IAAI,aAAa;AAC5C;;;AF9FO,IAAM,iBAAiB,eAAe;AACtC,IAAM,mBAAmB;AAMhC,eAAsB,iBAAiB,WAA+C;AACpF,QAAM,KAAK,aAAa,eAAe;AAEvC,MAAI,CAAC,IAAI;AACP,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,GAAG,YAAY,eAAe,QAAQ,EAAE,aAAa,KAAK,CAAC;AAE1E,MAAI,CAAC,OAAO,IAAI;AACd,UAAM,IAAI,MAAM,wCAAwC,KAAK,UAAU,OAAO,MAAM,CAAC,EAAE;AAAA,EACzF;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,mBAAiB,EAAE,MAAM,QAAQ,KAAK;AACxC;AAEA,IAAO,mBAAQ;AAAA,EACb,QAAQ,eAAe;AAAA,EACvB,UAAU;AAAA,EACV,UAAU;AACZ;","names":[]}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { B as BehaviorSchema, L as LokaScriptInstance } from '../types-DCCtVQS5.cjs';
|
|
2
2
|
|
|
3
3
|
declare const sortableSource: string;
|
|
4
4
|
declare const sortableMetadata: BehaviorSchema;
|
|
5
5
|
/**
|
|
6
|
-
* Register the Sortable behavior with LokaScript
|
|
6
|
+
* Register the Sortable behavior with LokaScript by compiling its hyperscript
|
|
7
|
+
* source and executing the resulting behavior definition.
|
|
7
8
|
*/
|
|
8
9
|
declare function registerSortable(hyperfixi?: LokaScriptInstance): Promise<void>;
|
|
9
10
|
declare const _default: {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { B as BehaviorSchema, L as LokaScriptInstance } from '../types-DCCtVQS5.js';
|
|
2
2
|
|
|
3
3
|
declare const sortableSource: string;
|
|
4
4
|
declare const sortableMetadata: BehaviorSchema;
|
|
5
5
|
/**
|
|
6
|
-
* Register the Sortable behavior with LokaScript
|
|
6
|
+
* Register the Sortable behavior with LokaScript by compiling its hyperscript
|
|
7
|
+
* source and executing the resulting behavior definition.
|
|
7
8
|
*/
|
|
8
9
|
declare function registerSortable(hyperfixi?: LokaScriptInstance): Promise<void>;
|
|
9
10
|
declare const _default: {
|
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
sortableMetadata,
|
|
4
4
|
sortableSource,
|
|
5
5
|
sortable_default
|
|
6
|
-
} from "../chunk-
|
|
7
|
-
import "../chunk-
|
|
6
|
+
} from "../chunk-SLSCZV4A.js";
|
|
7
|
+
import "../chunk-PDMOOWFW.js";
|
|
8
8
|
import "../chunk-6TJXDCAQ.js";
|
|
9
9
|
export {
|
|
10
10
|
sortable_default as default,
|
package/dist/behaviors/tabs.cjs
CHANGED
|
@@ -170,118 +170,6 @@ function resolveRuntime() {
|
|
|
170
170
|
// src/behaviors/tabs.ts
|
|
171
171
|
var tabsSource = tabsSchema.source;
|
|
172
172
|
var tabsMetadata = tabsSchema;
|
|
173
|
-
var idCounter = 0;
|
|
174
|
-
function ensureId(el, prefix) {
|
|
175
|
-
if (!el.id) {
|
|
176
|
-
el.id = `${prefix}-${++idCounter}`;
|
|
177
|
-
}
|
|
178
|
-
return el.id;
|
|
179
|
-
}
|
|
180
|
-
function installTabs(element, params) {
|
|
181
|
-
const orientation = params.orientation === "vertical" ? "vertical" : "horizontal";
|
|
182
|
-
const wrap = params.wrap !== false;
|
|
183
|
-
const activeClass = params.activeClass || "active";
|
|
184
|
-
const initialIndex = typeof params.activeTab === "number" ? params.activeTab : 0;
|
|
185
|
-
const tabs = Array.from(element.querySelectorAll('[role="tab"]'));
|
|
186
|
-
const panels = Array.from(element.querySelectorAll('[role="tabpanel"]'));
|
|
187
|
-
if (tabs.length === 0 || panels.length === 0) return;
|
|
188
|
-
const tablist = element.querySelector('[role="tablist"]') || tabs[0].parentElement;
|
|
189
|
-
if (tablist && !tablist.getAttribute("role")) {
|
|
190
|
-
tablist.setAttribute("role", "tablist");
|
|
191
|
-
}
|
|
192
|
-
if (tablist) {
|
|
193
|
-
tablist.setAttribute("aria-orientation", orientation);
|
|
194
|
-
}
|
|
195
|
-
const count = Math.min(tabs.length, panels.length);
|
|
196
|
-
for (let i = 0; i < count; i++) {
|
|
197
|
-
const tabId = ensureId(tabs[i], "tab");
|
|
198
|
-
const panelId = ensureId(panels[i], "tabpanel");
|
|
199
|
-
tabs[i].setAttribute("aria-controls", panelId);
|
|
200
|
-
panels[i].setAttribute("aria-labelledby", tabId);
|
|
201
|
-
}
|
|
202
|
-
let currentIndex = -1;
|
|
203
|
-
function selectTab(index, previousIndex) {
|
|
204
|
-
if (index === previousIndex || index < 0 || index >= count) return false;
|
|
205
|
-
const detail = {
|
|
206
|
-
tab: tabs[index],
|
|
207
|
-
panel: panels[index],
|
|
208
|
-
index,
|
|
209
|
-
previousIndex
|
|
210
|
-
};
|
|
211
|
-
const changeEvent = new CustomEvent("tabs:change", {
|
|
212
|
-
bubbles: true,
|
|
213
|
-
cancelable: true,
|
|
214
|
-
detail
|
|
215
|
-
});
|
|
216
|
-
element.dispatchEvent(changeEvent);
|
|
217
|
-
if (changeEvent.defaultPrevented) return false;
|
|
218
|
-
if (previousIndex >= 0 && previousIndex < count) {
|
|
219
|
-
tabs[previousIndex].setAttribute("aria-selected", "false");
|
|
220
|
-
tabs[previousIndex].setAttribute("tabindex", "-1");
|
|
221
|
-
tabs[previousIndex].classList.remove(activeClass);
|
|
222
|
-
panels[previousIndex].setAttribute("aria-hidden", "true");
|
|
223
|
-
panels[previousIndex].classList.remove(activeClass);
|
|
224
|
-
}
|
|
225
|
-
tabs[index].setAttribute("aria-selected", "true");
|
|
226
|
-
tabs[index].setAttribute("tabindex", "0");
|
|
227
|
-
tabs[index].classList.add(activeClass);
|
|
228
|
-
panels[index].setAttribute("aria-hidden", "false");
|
|
229
|
-
panels[index].classList.add(activeClass);
|
|
230
|
-
currentIndex = index;
|
|
231
|
-
element.dispatchEvent(new CustomEvent("tabs:changed", { bubbles: true, detail }));
|
|
232
|
-
return true;
|
|
233
|
-
}
|
|
234
|
-
for (let i = 0; i < count; i++) {
|
|
235
|
-
tabs[i].setAttribute("aria-selected", "false");
|
|
236
|
-
tabs[i].setAttribute("tabindex", "-1");
|
|
237
|
-
tabs[i].classList.remove(activeClass);
|
|
238
|
-
panels[i].setAttribute("aria-hidden", "true");
|
|
239
|
-
panels[i].classList.remove(activeClass);
|
|
240
|
-
}
|
|
241
|
-
const clamped = Math.max(0, Math.min(initialIndex, count - 1));
|
|
242
|
-
tabs[clamped].setAttribute("aria-selected", "true");
|
|
243
|
-
tabs[clamped].setAttribute("tabindex", "0");
|
|
244
|
-
tabs[clamped].classList.add(activeClass);
|
|
245
|
-
panels[clamped].setAttribute("aria-hidden", "false");
|
|
246
|
-
panels[clamped].classList.add(activeClass);
|
|
247
|
-
currentIndex = clamped;
|
|
248
|
-
for (let i = 0; i < count; i++) {
|
|
249
|
-
tabs[i].addEventListener("click", () => {
|
|
250
|
-
selectTab(i, currentIndex);
|
|
251
|
-
tabs[i].focus();
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
const keyTarget = tablist || element;
|
|
255
|
-
keyTarget.addEventListener("keydown", (e) => {
|
|
256
|
-
const isHorizontal = orientation === "horizontal";
|
|
257
|
-
const nextKey = isHorizontal ? "ArrowRight" : "ArrowDown";
|
|
258
|
-
const prevKey = isHorizontal ? "ArrowLeft" : "ArrowUp";
|
|
259
|
-
let nextIndex = null;
|
|
260
|
-
if (e.key === nextKey) {
|
|
261
|
-
nextIndex = currentIndex + 1;
|
|
262
|
-
if (nextIndex >= count) nextIndex = wrap ? 0 : null;
|
|
263
|
-
} else if (e.key === prevKey) {
|
|
264
|
-
nextIndex = currentIndex - 1;
|
|
265
|
-
if (nextIndex < 0) nextIndex = wrap ? count - 1 : null;
|
|
266
|
-
} else if (e.key === "Home") {
|
|
267
|
-
nextIndex = 0;
|
|
268
|
-
} else if (e.key === "End") {
|
|
269
|
-
nextIndex = count - 1;
|
|
270
|
-
}
|
|
271
|
-
if (nextIndex !== null) {
|
|
272
|
-
e.preventDefault();
|
|
273
|
-
if (selectTab(nextIndex, currentIndex)) {
|
|
274
|
-
tabs[nextIndex].focus();
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
});
|
|
278
|
-
element.addEventListener("tabs:select", ((e) => {
|
|
279
|
-
const index = e.detail?.index;
|
|
280
|
-
if (typeof index === "number") {
|
|
281
|
-
selectTab(index, currentIndex);
|
|
282
|
-
}
|
|
283
|
-
}));
|
|
284
|
-
}
|
|
285
173
|
async function registerTabs(hyperfixi) {
|
|
286
174
|
const hf = hyperfixi || resolveRuntime();
|
|
287
175
|
if (!hf) {
|
|
@@ -289,15 +177,12 @@ async function registerTabs(hyperfixi) {
|
|
|
289
177
|
"LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors."
|
|
290
178
|
);
|
|
291
179
|
}
|
|
292
|
-
const
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
eventHandlers: [],
|
|
297
|
-
imperativeInstaller: installTabs
|
|
298
|
-
};
|
|
180
|
+
const result = hf.compileSync(tabsSchema.source, { traditional: true });
|
|
181
|
+
if (!result.ok) {
|
|
182
|
+
throw new Error(`Failed to compile Tabs behavior: ${JSON.stringify(result.errors)}`);
|
|
183
|
+
}
|
|
299
184
|
const ctx = hf.createContext ? hf.createContext() : { locals: /* @__PURE__ */ new Map(), globals: /* @__PURE__ */ new Map() };
|
|
300
|
-
await hf.execute(
|
|
185
|
+
await hf.execute(result.ast, ctx);
|
|
301
186
|
}
|
|
302
187
|
if (resolveRuntime()) {
|
|
303
188
|
registerTabs().catch(console.error);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/behaviors/tabs.ts","../../src/schemas/tabs.schema.ts","../../src/schemas/types.ts"],"sourcesContent":["/**\n * Tabs Behavior — Imperative Implementation\n *\n * WAI-ARIA compliant tabs with roving tabindex keyboard navigation.\n * Auto-wires role, aria-selected, aria-controls, and aria-labelledby.\n */\n\nimport { tabsSchema } from '../schemas/tabs.schema';\nimport type { LokaScriptInstance } from '../schemas/types';\nimport { resolveRuntime } from '../schemas/types';\n\nexport const tabsSource = tabsSchema.source;\nexport const tabsMetadata = tabsSchema;\n\nlet idCounter = 0;\n\nfunction ensureId(el: HTMLElement, prefix: string): string {\n if (!el.id) {\n el.id = `${prefix}-${++idCounter}`;\n }\n return el.id;\n}\n\n/**\n * Imperative installer for Tabs behavior.\n */\nfunction installTabs(element: HTMLElement, params: Record<string, any>): void {\n const orientation = params.orientation === 'vertical' ? 'vertical' : 'horizontal';\n const wrap = params.wrap !== false;\n const activeClass = (params.activeClass as string) || 'active';\n const initialIndex = typeof params.activeTab === 'number' ? params.activeTab : 0;\n\n // Discover tabs and panels\n const tabs = Array.from(element.querySelectorAll<HTMLElement>('[role=\"tab\"]'));\n const panels = Array.from(element.querySelectorAll<HTMLElement>('[role=\"tabpanel\"]'));\n\n if (tabs.length === 0 || panels.length === 0) return;\n\n // Find or mark the tablist\n const tablist = element.querySelector<HTMLElement>('[role=\"tablist\"]') || tabs[0].parentElement;\n if (tablist && !tablist.getAttribute('role')) {\n tablist.setAttribute('role', 'tablist');\n }\n if (tablist) {\n tablist.setAttribute('aria-orientation', orientation);\n }\n\n // Wire IDs, aria-controls, aria-labelledby\n const count = Math.min(tabs.length, panels.length);\n for (let i = 0; i < count; i++) {\n const tabId = ensureId(tabs[i], 'tab');\n const panelId = ensureId(panels[i], 'tabpanel');\n tabs[i].setAttribute('aria-controls', panelId);\n panels[i].setAttribute('aria-labelledby', tabId);\n }\n\n let currentIndex = -1;\n\n function selectTab(index: number, previousIndex: number): boolean {\n if (index === previousIndex || index < 0 || index >= count) return false;\n\n const detail = {\n tab: tabs[index],\n panel: panels[index],\n index,\n previousIndex,\n };\n\n // Cancelable before-event\n const changeEvent = new CustomEvent('tabs:change', {\n bubbles: true,\n cancelable: true,\n detail,\n });\n element.dispatchEvent(changeEvent);\n if (changeEvent.defaultPrevented) return false;\n\n // Deactivate previous\n if (previousIndex >= 0 && previousIndex < count) {\n tabs[previousIndex].setAttribute('aria-selected', 'false');\n tabs[previousIndex].setAttribute('tabindex', '-1');\n tabs[previousIndex].classList.remove(activeClass);\n panels[previousIndex].setAttribute('aria-hidden', 'true');\n panels[previousIndex].classList.remove(activeClass);\n }\n\n // Activate new\n tabs[index].setAttribute('aria-selected', 'true');\n tabs[index].setAttribute('tabindex', '0');\n tabs[index].classList.add(activeClass);\n panels[index].setAttribute('aria-hidden', 'false');\n panels[index].classList.add(activeClass);\n\n currentIndex = index;\n\n element.dispatchEvent(new CustomEvent('tabs:changed', { bubbles: true, detail }));\n return true;\n }\n\n // Initialize all tabs as inactive, then activate initial\n for (let i = 0; i < count; i++) {\n tabs[i].setAttribute('aria-selected', 'false');\n tabs[i].setAttribute('tabindex', '-1');\n tabs[i].classList.remove(activeClass);\n panels[i].setAttribute('aria-hidden', 'true');\n panels[i].classList.remove(activeClass);\n }\n\n const clamped = Math.max(0, Math.min(initialIndex, count - 1));\n // Directly activate without firing change event on init\n tabs[clamped].setAttribute('aria-selected', 'true');\n tabs[clamped].setAttribute('tabindex', '0');\n tabs[clamped].classList.add(activeClass);\n panels[clamped].setAttribute('aria-hidden', 'false');\n panels[clamped].classList.add(activeClass);\n currentIndex = clamped;\n\n // Click handler\n for (let i = 0; i < count; i++) {\n tabs[i].addEventListener('click', () => {\n selectTab(i, currentIndex);\n tabs[i].focus();\n });\n }\n\n // Keyboard handler on tablist\n const keyTarget = tablist || element;\n keyTarget.addEventListener('keydown', (e: KeyboardEvent) => {\n const isHorizontal = orientation === 'horizontal';\n const nextKey = isHorizontal ? 'ArrowRight' : 'ArrowDown';\n const prevKey = isHorizontal ? 'ArrowLeft' : 'ArrowUp';\n\n let nextIndex: number | null = null;\n\n if (e.key === nextKey) {\n nextIndex = currentIndex + 1;\n if (nextIndex >= count) nextIndex = wrap ? 0 : null;\n } else if (e.key === prevKey) {\n nextIndex = currentIndex - 1;\n if (nextIndex < 0) nextIndex = wrap ? count - 1 : null;\n } else if (e.key === 'Home') {\n nextIndex = 0;\n } else if (e.key === 'End') {\n nextIndex = count - 1;\n }\n\n if (nextIndex !== null) {\n e.preventDefault();\n if (selectTab(nextIndex, currentIndex)) {\n tabs[nextIndex].focus();\n }\n }\n });\n\n // Programmatic tab selection\n element.addEventListener('tabs:select', ((e: CustomEvent) => {\n const index = e.detail?.index;\n if (typeof index === 'number') {\n selectTab(index, currentIndex);\n }\n }) as EventListener);\n}\n\n/**\n * Register the Tabs behavior with LokaScript.\n */\nexport async function registerTabs(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: 'Tabs',\n parameters: ['orientation', 'activeTab', 'wrap', 'activeClass'],\n eventHandlers: [],\n imperativeInstaller: installTabs,\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 registerTabs().catch(console.error);\n}\n\nexport default {\n source: tabsSchema.source,\n metadata: tabsSchema,\n register: registerTabs,\n};\n","import type { BehaviorSchema } from './types';\n\nexport const tabsSchema: BehaviorSchema = {\n name: 'Tabs',\n category: 'ui',\n tier: 'core',\n version: '1.0.0',\n description:\n 'WAI-ARIA compliant tabs with roving tabindex keyboard navigation. ' +\n 'Auto-wires role, aria-selected, aria-controls, and aria-labelledby attributes.',\n parameters: [\n {\n name: 'orientation',\n type: 'string',\n optional: true,\n default: 'horizontal',\n enum: ['horizontal', 'vertical'],\n description: 'Arrow key direction: horizontal (Left/Right) or vertical (Up/Down)',\n },\n {\n name: 'activeTab',\n type: 'number',\n optional: true,\n default: 0,\n description: 'Initial active tab index (zero-based)',\n },\n {\n name: 'wrap',\n type: 'boolean',\n optional: true,\n default: true,\n description: 'Wrap to first/last tab when navigating past the end',\n },\n {\n name: 'activeClass',\n type: 'string',\n optional: true,\n default: 'active',\n description: 'CSS class applied to the active tab and its panel',\n },\n ],\n events: [\n {\n name: 'tabs:change',\n description: 'Fired before tab selection changes (cancelable via preventDefault)',\n },\n { name: 'tabs:changed', description: 'Fired after tab selection has changed' },\n ],\n requirements: [\n 'Sets role=\"tablist\" on the tab container',\n 'Sets role=\"tab\" on tab buttons and role=\"tabpanel\" on content panels',\n 'Manages aria-selected, aria-controls, aria-labelledby, and tabindex',\n 'Keyboard: Arrow keys navigate, Home/End jump to first/last, Tab exits tablist',\n ],\n source: `\nbehavior Tabs(orientation, activeTab, wrap, activeClass)\n init\n if orientation is undefined\n set orientation to \"horizontal\"\n end\n if activeTab is undefined\n set activeTab to 0\n end\n if wrap is undefined\n set wrap to true\n end\n if activeClass is undefined\n set activeClass to \"active\"\n end\n js(me, orientation, activeTab, wrap, activeClass)\n var tabs = Array.from(me.querySelectorAll('[role=\"tab\"]'));\n var panels = Array.from(me.querySelectorAll('[role=\"tabpanel\"]'));\n if (tabs.length === 0 || panels.length === 0) return;\n var tablist = me.querySelector('[role=\"tablist\"]') || tabs[0].parentElement;\n if (tablist) tablist.setAttribute('aria-orientation', orientation);\n var count = Math.min(tabs.length, panels.length);\n var idN = 0;\n for (var i = 0; i < count; i++) {\n if (!tabs[i].id) tabs[i].id = 'tab-' + (++idN);\n if (!panels[i].id) panels[i].id = 'tabpanel-' + idN;\n tabs[i].setAttribute('aria-controls', panels[i].id);\n panels[i].setAttribute('aria-labelledby', tabs[i].id);\n }\n var cur = Math.max(0, Math.min(activeTab, count - 1));\n function activate(idx, prev) {\n if (idx === prev || idx < 0 || idx >= count) return false;\n var ev = new CustomEvent('tabs:change', { bubbles: true, cancelable: true, detail: { index: idx, previousIndex: prev } });\n me.dispatchEvent(ev);\n if (ev.defaultPrevented) return false;\n if (prev >= 0 && prev < count) {\n tabs[prev].setAttribute('aria-selected', 'false');\n tabs[prev].setAttribute('tabindex', '-1');\n tabs[prev].classList.remove(activeClass);\n panels[prev].setAttribute('aria-hidden', 'true');\n panels[prev].classList.remove(activeClass);\n }\n tabs[idx].setAttribute('aria-selected', 'true');\n tabs[idx].setAttribute('tabindex', '0');\n tabs[idx].classList.add(activeClass);\n panels[idx].setAttribute('aria-hidden', 'false');\n panels[idx].classList.add(activeClass);\n cur = idx;\n me.dispatchEvent(new CustomEvent('tabs:changed', { bubbles: true, detail: { index: idx } }));\n return true;\n }\n for (var j = 0; j < count; j++) {\n tabs[j].setAttribute('aria-selected', 'false');\n tabs[j].setAttribute('tabindex', '-1');\n panels[j].setAttribute('aria-hidden', 'true');\n panels[j].classList.remove(activeClass);\n }\n tabs[cur].setAttribute('aria-selected', 'true');\n tabs[cur].setAttribute('tabindex', '0');\n tabs[cur].classList.add(activeClass);\n panels[cur].setAttribute('aria-hidden', 'false');\n panels[cur].classList.add(activeClass);\n for (var k = 0; k < count; k++) {\n (function(idx) {\n tabs[idx].addEventListener('click', function() { if (activate(idx, cur)) tabs[idx].focus(); });\n })(k);\n }\n (tablist || me).addEventListener('keydown', function(e) {\n var nk = orientation === 'horizontal' ? 'ArrowRight' : 'ArrowDown';\n var pk = orientation === 'horizontal' ? 'ArrowLeft' : 'ArrowUp';\n var next = null;\n if (e.key === nk) { next = cur + 1; if (next >= count) next = wrap ? 0 : null; }\n else if (e.key === pk) { next = cur - 1; if (next < 0) next = wrap ? count - 1 : null; }\n else if (e.key === 'Home') next = 0;\n else if (e.key === 'End') next = count - 1;\n if (next !== null) { e.preventDefault(); if (activate(next, cur)) tabs[next].focus(); }\n });\n end\n end\nend`.trim(),\n};\n","/**\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/tabs.ts","../../src/schemas/tabs.schema.ts","../../src/schemas/types.ts"],"sourcesContent":["/**\n * Tabs Behavior\n *\n * WAI-ARIA compliant tabs with roving tabindex keyboard navigation.\n * Auto-wires role, aria-selected, aria-controls, and aria-labelledby. The ARIA\n * wiring / keyboard-navigation logic lives in the schema's hyperscript `source`\n * (an `init`-block `js()` body).\n *\n * Compiled from its hyperscript `source` — the single source of truth shared with\n * the CDN resolver bundle and patterns-reference. This collapses Tabs onto the one\n * runtime path (no more imperative-installer fork between CDN and npm);\n * see docs-internal/BEHAVIORS_CONSOLIDATION_PLAN.md §3d.\n */\n\nimport { tabsSchema } from '../schemas/tabs.schema';\nimport type { LokaScriptInstance } from '../schemas/types';\nimport { resolveRuntime } from '../schemas/types';\n\nexport const tabsSource = tabsSchema.source;\nexport const tabsMetadata = tabsSchema;\n\n/**\n * Register the Tabs behavior with LokaScript by compiling its\n * hyperscript source and executing the resulting behavior definition.\n */\nexport async function registerTabs(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(tabsSchema.source, { traditional: true });\n\n if (!result.ok) {\n throw new Error(`Failed to compile Tabs 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 registerTabs().catch(console.error);\n}\n\nexport default {\n source: tabsSchema.source,\n metadata: tabsSchema,\n register: registerTabs,\n};\n","import type { BehaviorSchema } from './types';\n\nexport const tabsSchema: BehaviorSchema = {\n name: 'Tabs',\n category: 'ui',\n tier: 'core',\n version: '1.0.0',\n description:\n 'WAI-ARIA compliant tabs with roving tabindex keyboard navigation. ' +\n 'Auto-wires role, aria-selected, aria-controls, and aria-labelledby attributes.',\n parameters: [\n {\n name: 'orientation',\n type: 'string',\n optional: true,\n default: 'horizontal',\n enum: ['horizontal', 'vertical'],\n description: 'Arrow key direction: horizontal (Left/Right) or vertical (Up/Down)',\n },\n {\n name: 'activeTab',\n type: 'number',\n optional: true,\n default: 0,\n description: 'Initial active tab index (zero-based)',\n },\n {\n name: 'wrap',\n type: 'boolean',\n optional: true,\n default: true,\n description: 'Wrap to first/last tab when navigating past the end',\n },\n {\n name: 'activeClass',\n type: 'string',\n optional: true,\n default: 'active',\n description: 'CSS class applied to the active tab and its panel',\n },\n ],\n events: [\n {\n name: 'tabs:change',\n description: 'Fired before tab selection changes (cancelable via preventDefault)',\n },\n { name: 'tabs:changed', description: 'Fired after tab selection has changed' },\n ],\n requirements: [\n 'Sets role=\"tablist\" on the tab container',\n 'Sets role=\"tab\" on tab buttons and role=\"tabpanel\" on content panels',\n 'Manages aria-selected, aria-controls, aria-labelledby, and tabindex',\n 'Keyboard: Arrow keys navigate, Home/End jump to first/last, Tab exits tablist',\n ],\n source: `\nbehavior Tabs(orientation, activeTab, wrap, activeClass)\n init\n if orientation is undefined\n set orientation to \"horizontal\"\n end\n if activeTab is undefined\n set activeTab to 0\n end\n if wrap is undefined\n set wrap to true\n end\n if activeClass is undefined\n set activeClass to \"active\"\n end\n js(me, orientation, activeTab, wrap, activeClass)\n var tabs = Array.from(me.querySelectorAll('[role=\"tab\"]'));\n var panels = Array.from(me.querySelectorAll('[role=\"tabpanel\"]'));\n if (tabs.length === 0 || panels.length === 0) return;\n var tablist = me.querySelector('[role=\"tablist\"]') || tabs[0].parentElement;\n if (tablist) tablist.setAttribute('aria-orientation', orientation);\n var count = Math.min(tabs.length, panels.length);\n var idN = 0;\n for (var i = 0; i < count; i++) {\n if (!tabs[i].id) tabs[i].id = 'tab-' + (++idN);\n if (!panels[i].id) panels[i].id = 'tabpanel-' + idN;\n tabs[i].setAttribute('aria-controls', panels[i].id);\n panels[i].setAttribute('aria-labelledby', tabs[i].id);\n }\n var cur = Math.max(0, Math.min(activeTab, count - 1));\n function activate(idx, prev) {\n if (idx === prev || idx < 0 || idx >= count) return false;\n var ev = new CustomEvent('tabs:change', { bubbles: true, cancelable: true, detail: { index: idx, previousIndex: prev } });\n me.dispatchEvent(ev);\n if (ev.defaultPrevented) return false;\n if (prev >= 0 && prev < count) {\n tabs[prev].setAttribute('aria-selected', 'false');\n tabs[prev].setAttribute('tabindex', '-1');\n tabs[prev].classList.remove(activeClass);\n panels[prev].setAttribute('aria-hidden', 'true');\n panels[prev].classList.remove(activeClass);\n }\n tabs[idx].setAttribute('aria-selected', 'true');\n tabs[idx].setAttribute('tabindex', '0');\n tabs[idx].classList.add(activeClass);\n panels[idx].setAttribute('aria-hidden', 'false');\n panels[idx].classList.add(activeClass);\n cur = idx;\n me.dispatchEvent(new CustomEvent('tabs:changed', { bubbles: true, detail: { index: idx } }));\n return true;\n }\n for (var j = 0; j < count; j++) {\n tabs[j].setAttribute('aria-selected', 'false');\n tabs[j].setAttribute('tabindex', '-1');\n panels[j].setAttribute('aria-hidden', 'true');\n panels[j].classList.remove(activeClass);\n }\n tabs[cur].setAttribute('aria-selected', 'true');\n tabs[cur].setAttribute('tabindex', '0');\n tabs[cur].classList.add(activeClass);\n panels[cur].setAttribute('aria-hidden', 'false');\n panels[cur].classList.add(activeClass);\n for (var k = 0; k < count; k++) {\n (function(idx) {\n tabs[idx].addEventListener('click', function() { if (activate(idx, cur)) tabs[idx].focus(); });\n })(k);\n }\n (tablist || me).addEventListener('keydown', function(e) {\n var nk = orientation === 'horizontal' ? 'ArrowRight' : 'ArrowDown';\n var pk = orientation === 'horizontal' ? 'ArrowLeft' : 'ArrowUp';\n var next = null;\n if (e.key === nk) { next = cur + 1; if (next >= count) next = wrap ? 0 : null; }\n else if (e.key === pk) { next = cur - 1; if (next < 0) next = wrap ? count - 1 : null; }\n else if (e.key === 'Home') next = 0;\n else if (e.key === 'End') next = count - 1;\n if (next !== null) { e.preventDefault(); if (activate(next, cur)) tabs[next].focus(); }\n });\n end\n end\nend`.trim(),\n};\n","/**\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;;;ACEO,IAAM,aAA6B;AAAA,EACxC,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAM;AAAA,EACN,SAAS;AAAA,EACT,aACE;AAAA,EAEF,YAAY;AAAA,IACV;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,MACT,MAAM,CAAC,cAAc,UAAU;AAAA,MAC/B,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;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA,IACA,EAAE,MAAM,gBAAgB,aAAa,wCAAwC;AAAA,EAC/E;AAAA,EACA,cAAc;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,EACA,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KA+EL,KAAK;AACV;;;ACpBO,SAAS,iBAA4C;AAC1D,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,QAAM,MAAM;AACZ,SAAO,IAAI,cAAc,IAAI,aAAa;AAC5C;;;AFpGO,IAAM,aAAa,WAAW;AAC9B,IAAM,eAAe;AAM5B,eAAsB,aAAa,WAA+C;AAChF,QAAM,KAAK,aAAa,eAAe;AAEvC,MAAI,CAAC,IAAI;AACP,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,GAAG,YAAY,WAAW,QAAQ,EAAE,aAAa,KAAK,CAAC;AAEtE,MAAI,CAAC,OAAO,IAAI;AACd,UAAM,IAAI,MAAM,oCAAoC,KAAK,UAAU,OAAO,MAAM,CAAC,EAAE;AAAA,EACrF;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,eAAa,EAAE,MAAM,QAAQ,KAAK;AACpC;AAEA,IAAO,eAAQ;AAAA,EACb,QAAQ,WAAW;AAAA,EACnB,UAAU;AAAA,EACV,UAAU;AACZ;","names":[]}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { B as BehaviorSchema, L as LokaScriptInstance } from '../types-DCCtVQS5.cjs';
|
|
2
2
|
|
|
3
3
|
declare const tabsSource: string;
|
|
4
4
|
declare const tabsMetadata: BehaviorSchema;
|
|
5
5
|
/**
|
|
6
|
-
* Register the Tabs behavior with LokaScript
|
|
6
|
+
* Register the Tabs behavior with LokaScript by compiling its
|
|
7
|
+
* hyperscript source and executing the resulting behavior definition.
|
|
7
8
|
*/
|
|
8
9
|
declare function registerTabs(hyperfixi?: LokaScriptInstance): Promise<void>;
|
|
9
10
|
declare const _default: {
|
package/dist/behaviors/tabs.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { B as BehaviorSchema, L as LokaScriptInstance } from '../types-DCCtVQS5.js';
|
|
2
2
|
|
|
3
3
|
declare const tabsSource: string;
|
|
4
4
|
declare const tabsMetadata: BehaviorSchema;
|
|
5
5
|
/**
|
|
6
|
-
* Register the Tabs behavior with LokaScript
|
|
6
|
+
* Register the Tabs behavior with LokaScript by compiling its
|
|
7
|
+
* hyperscript source and executing the resulting behavior definition.
|
|
7
8
|
*/
|
|
8
9
|
declare function registerTabs(hyperfixi?: LokaScriptInstance): Promise<void>;
|
|
9
10
|
declare const _default: {
|
package/dist/behaviors/tabs.js
CHANGED
|
@@ -84,25 +84,6 @@ function resolveRuntime() {
|
|
|
84
84
|
// src/behaviors/toggleable.ts
|
|
85
85
|
var toggleableSource = toggleableSchema.source;
|
|
86
86
|
var toggleableMetadata = toggleableSchema;
|
|
87
|
-
function installToggleable(element, params) {
|
|
88
|
-
const cls = params.cls || "active";
|
|
89
|
-
let targetEl = element;
|
|
90
|
-
if (params.target && params.target !== "me") {
|
|
91
|
-
if (typeof params.target === "string") {
|
|
92
|
-
const found = document.querySelector(params.target);
|
|
93
|
-
if (found instanceof HTMLElement) targetEl = found;
|
|
94
|
-
} else if (params.target instanceof HTMLElement) {
|
|
95
|
-
targetEl = params.target;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
element.addEventListener("click", () => {
|
|
99
|
-
const wasOn = targetEl.classList.contains(cls);
|
|
100
|
-
targetEl.classList.toggle(cls);
|
|
101
|
-
targetEl.dispatchEvent(
|
|
102
|
-
new CustomEvent(wasOn ? "toggleable:off" : "toggleable:on", { bubbles: true })
|
|
103
|
-
);
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
87
|
async function registerToggleable(hyperfixi) {
|
|
107
88
|
const hf = hyperfixi || resolveRuntime();
|
|
108
89
|
if (!hf) {
|
|
@@ -110,15 +91,12 @@ async function registerToggleable(hyperfixi) {
|
|
|
110
91
|
"LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors."
|
|
111
92
|
);
|
|
112
93
|
}
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
eventHandlers: [],
|
|
118
|
-
imperativeInstaller: installToggleable
|
|
119
|
-
};
|
|
94
|
+
const result = hf.compileSync(toggleableSchema.source, { traditional: true });
|
|
95
|
+
if (!result.ok) {
|
|
96
|
+
throw new Error(`Failed to compile Toggleable behavior: ${JSON.stringify(result.errors)}`);
|
|
97
|
+
}
|
|
120
98
|
const ctx = hf.createContext ? hf.createContext() : { locals: /* @__PURE__ */ new Map(), globals: /* @__PURE__ */ new Map() };
|
|
121
|
-
await hf.execute(
|
|
99
|
+
await hf.execute(result.ast, ctx);
|
|
122
100
|
}
|
|
123
101
|
if (resolveRuntime()) {
|
|
124
102
|
registerToggleable().catch(console.error);
|