juxscript 1.0.132 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/README.md +1 -32
  2. package/bin/cli.js +4 -2
  3. package/index.d.ts +200 -0
  4. package/index.js +96 -22
  5. package/juxconfig.example.js +58 -63
  6. package/lib/components/alert.ts +200 -0
  7. package/lib/components/app.ts +247 -0
  8. package/lib/components/badge.ts +101 -0
  9. package/lib/components/base/BaseComponent.ts +421 -0
  10. package/lib/components/base/FormInput.ts +227 -0
  11. package/lib/components/button.ts +178 -0
  12. package/lib/components/card.ts +173 -0
  13. package/lib/components/chart.ts +231 -0
  14. package/lib/components/checkbox.ts +242 -0
  15. package/lib/components/code.ts +123 -0
  16. package/lib/components/container.ts +140 -0
  17. package/lib/components/data.ts +135 -0
  18. package/lib/components/datepicker.ts +234 -0
  19. package/lib/components/dialog.ts +172 -0
  20. package/lib/components/divider.ts +100 -0
  21. package/lib/components/dropdown.ts +186 -0
  22. package/lib/components/element.ts +267 -0
  23. package/lib/components/fileupload.ts +309 -0
  24. package/lib/components/grid.ts +291 -0
  25. package/lib/components/guard.ts +92 -0
  26. package/lib/components/heading.ts +96 -0
  27. package/lib/components/helpers.ts +41 -0
  28. package/lib/components/hero.ts +224 -0
  29. package/lib/components/icon.ts +178 -0
  30. package/lib/components/icons.ts +464 -0
  31. package/lib/components/include.ts +410 -0
  32. package/lib/components/input.ts +457 -0
  33. package/lib/components/list.ts +419 -0
  34. package/lib/components/loading.ts +100 -0
  35. package/lib/components/menu.ts +275 -0
  36. package/lib/components/modal.ts +284 -0
  37. package/lib/components/nav.ts +257 -0
  38. package/lib/components/paragraph.ts +97 -0
  39. package/lib/components/progress.ts +159 -0
  40. package/lib/components/radio.ts +278 -0
  41. package/lib/components/req.ts +303 -0
  42. package/lib/components/script.ts +41 -0
  43. package/lib/components/select.ts +252 -0
  44. package/lib/components/sidebar.ts +275 -0
  45. package/lib/components/style.ts +41 -0
  46. package/lib/components/switch.ts +246 -0
  47. package/lib/components/table.ts +1249 -0
  48. package/lib/components/tabs.ts +250 -0
  49. package/lib/components/theme-toggle.ts +293 -0
  50. package/lib/components/tooltip.ts +144 -0
  51. package/lib/components/view.ts +190 -0
  52. package/lib/components/write.ts +272 -0
  53. package/lib/globals.d.ts +19 -5
  54. package/lib/layouts/default.css +260 -0
  55. package/lib/layouts/figma.css +334 -0
  56. package/lib/reactivity/state.ts +78 -0
  57. package/lib/utils/{fetch.js → fetch.ts} +206 -81
  58. package/machinery/ast.js +347 -0
  59. package/machinery/build.js +466 -0
  60. package/machinery/compiler3.js +6 -66
  61. package/machinery/config.js +6 -93
  62. package/machinery/doc-generator.js +136 -0
  63. package/machinery/imports.js +155 -0
  64. package/machinery/server.js +166 -0
  65. package/machinery/ts-shim.js +46 -0
  66. package/machinery/watcher.js +162 -50
  67. package/package.json +9 -30
  68. package/create/index.jux +0 -77
  69. package/create/layout.jux +0 -18
  70. package/create/style.css +0 -57
  71. package/create/themes/assets/jux.svg +0 -34
  72. package/create/themes/base.css +0 -197
  73. package/create/themes/base2.css +0 -54
  74. package/create/themes/layouts/base.jux +0 -16
  75. package/create/themes/layouts/base_marketing.jux +0 -0
  76. package/create/themes/layouts/base_saas.jux +0 -0
  77. package/lib/componentsv2/base/BaseEngine.d.ts +0 -112
  78. package/lib/componentsv2/base/BaseEngine.js +0 -279
  79. package/lib/componentsv2/base/BaseSkin.d.ts +0 -74
  80. package/lib/componentsv2/base/BaseSkin.js +0 -130
  81. package/lib/componentsv2/base/Neighborhood.d.ts +0 -22
  82. package/lib/componentsv2/base/Neighborhood.js +0 -56
  83. package/lib/componentsv2/base/OptionsContract.d.ts +0 -20
  84. package/lib/componentsv2/base/OptionsContract.js +0 -107
  85. package/lib/componentsv2/base/State.d.ts +0 -18
  86. package/lib/componentsv2/base/State.js +0 -68
  87. package/lib/componentsv2/element/Element.d.ts +0 -30
  88. package/lib/componentsv2/element/Element.js +0 -50
  89. package/lib/componentsv2/element/ElementEngine.d.ts +0 -59
  90. package/lib/componentsv2/element/ElementEngine.js +0 -118
  91. package/lib/componentsv2/element/ElementSkin.d.ts +0 -10
  92. package/lib/componentsv2/element/ElementSkin.js +0 -56
  93. package/lib/componentsv2/element/structure.css +0 -261
  94. package/lib/componentsv2/grid/Grid.d.ts +0 -13
  95. package/lib/componentsv2/grid/Grid.js +0 -27
  96. package/lib/componentsv2/grid/GridEngine.d.ts +0 -77
  97. package/lib/componentsv2/grid/GridEngine.js +0 -153
  98. package/lib/componentsv2/grid/GridSkin.d.ts +0 -11
  99. package/lib/componentsv2/grid/GridSkin.js +0 -84
  100. package/lib/componentsv2/grid/structure.css +0 -27
  101. package/lib/componentsv2/input/Input.d.ts +0 -6
  102. package/lib/componentsv2/input/Input.js +0 -21
  103. package/lib/componentsv2/input/InputEngine.d.ts +0 -70
  104. package/lib/componentsv2/input/InputEngine.js +0 -143
  105. package/lib/componentsv2/input/InputSkin.d.ts +0 -11
  106. package/lib/componentsv2/input/InputSkin.js +0 -89
  107. package/lib/componentsv2/input/structure.css +0 -47
  108. package/lib/componentsv2/list/List.d.ts +0 -49
  109. package/lib/componentsv2/list/List.js +0 -105
  110. package/lib/componentsv2/list/ListEngine.d.ts +0 -121
  111. package/lib/componentsv2/list/ListEngine.js +0 -322
  112. package/lib/componentsv2/list/ListSkin.d.ts +0 -20
  113. package/lib/componentsv2/list/ListSkin.js +0 -345
  114. package/lib/componentsv2/list/structure.css +0 -359
  115. package/lib/componentsv2/plugins/ClientSQLitePlugin.d.ts +0 -21
  116. package/lib/componentsv2/plugins/ClientSQLitePlugin.js +0 -130
  117. package/lib/componentsv2/plugins/IndexedDBPlugin.d.ts +0 -18
  118. package/lib/componentsv2/plugins/IndexedDBPlugin.js +0 -75
  119. package/lib/componentsv2/plugins/LocalStoragePlugin.d.ts +0 -20
  120. package/lib/componentsv2/plugins/LocalStoragePlugin.js +0 -65
  121. package/lib/componentsv2/plugins/ServerSQLitePlugin.d.ts +0 -25
  122. package/lib/componentsv2/plugins/ServerSQLitePlugin.js +0 -70
  123. package/lib/componentsv2/stubs/ComponentComposition.ts.stub +0 -32
  124. package/lib/componentsv2/stubs/ComponentEngine.ts.stub +0 -36
  125. package/lib/componentsv2/stubs/ComponentSkin.ts.stub +0 -35
  126. package/lib/componentsv2/stubs/ComponentStructure.css.d.ts.stub +0 -2
  127. package/lib/componentsv2/stubs/ComponentStructure.css.stub +0 -13
  128. package/lib/utils/fetch.d.ts +0 -176
  129. package/machinery/serve.js +0 -255
  130. package/types/css.d.ts +0 -10
  131. /package/{create/themes/layouts/base_blog.jux → machinery/bundleAssets.js} +0 -0
  132. /package/{create/themes/layouts/base_docs.jux → machinery/bundleJux.js} +0 -0
  133. /package/{create/themes/layouts/base_login.jux → machinery/bundleVendors.js} +0 -0
@@ -1,22 +0,0 @@
1
- type GlobalListener = (data: any) => void;
2
- /**
3
- * THE NEIGHBORHOOD (Global Event Mediator)
4
- *
5
- * Acts as the certal nervous system where all components post updates.
6
- * Other components can tune in to specific frequencies (channels) here.
7
- */
8
- export declare class JuxGlobalBus {
9
- private listeners;
10
- on(channel: string, callback: GlobalListener): void;
11
- off(channel: string, callback: GlobalListener): void;
12
- emit(channel: string, data: any): void;
13
- /**
14
- * DEBUG: Read-only Snapshot of active channels and listener identities.
15
- * usage: juxV2.events.registry
16
- * Returns: { "channelName": ["functionName", "(anonymous)"] }
17
- */
18
- get registry(): Record<string, string[]>;
19
- }
20
- export declare const Neighborhood: JuxGlobalBus;
21
- export {};
22
- //# sourceMappingURL=Neighborhood.d.ts.map
@@ -1,56 +0,0 @@
1
- /**
2
- * THE NEIGHBORHOOD (Global Event Mediator)
3
- *
4
- * Acts as the certal nervous system where all components post updates.
5
- * Other components can tune in to specific frequencies (channels) here.
6
- */
7
- export class JuxGlobalBus {
8
- constructor() {
9
- this.listeners = new Map();
10
- }
11
- on(channel, callback) {
12
- if (!this.listeners.has(channel)) {
13
- this.listeners.set(channel, new Set());
14
- }
15
- this.listeners.get(channel).add(callback);
16
- }
17
- off(channel, callback) {
18
- const set = this.listeners.get(channel);
19
- if (set) {
20
- set.delete(callback);
21
- if (set.size === 0) {
22
- this.listeners.delete(channel);
23
- }
24
- }
25
- }
26
- emit(channel, data) {
27
- const set = this.listeners.get(channel);
28
- if (set) {
29
- set.forEach(callback => {
30
- try {
31
- callback(data);
32
- }
33
- catch (e) {
34
- console.error(`Jux GlobalBus Error [${channel}]:`, e);
35
- }
36
- });
37
- }
38
- // Optional: We could have a wildcard '*' listener here for debuggers/loggers
39
- }
40
- /**
41
- * DEBUG: Read-only Snapshot of active channels and listener identities.
42
- * usage: juxV2.events.registry
43
- * Returns: { "channelName": ["functionName", "(anonymous)"] }
44
- */
45
- get registry() {
46
- const snapshot = {};
47
- this.listeners.forEach((set, channel) => {
48
- // Map the Set of functions to their names for easier debugging
49
- snapshot[channel] = Array.from(set).map(fn => fn.name || '(anonymous)');
50
- });
51
- return snapshot;
52
- }
53
- }
54
- // Singleton Instance
55
- export const Neighborhood = new JuxGlobalBus();
56
- //# sourceMappingURL=Neighborhood.js.map
@@ -1,20 +0,0 @@
1
- export interface OptionDefinition {
2
- type: 'string' | 'number' | 'boolean' | 'array' | 'object' | 'function';
3
- required?: boolean;
4
- default?: any;
5
- description?: string;
6
- aliases?: string[];
7
- }
8
- export type OptionsContractSchema = Record<string, OptionDefinition>;
9
- export interface ValidationResult {
10
- valid: boolean;
11
- warnings: string[];
12
- errors: string[];
13
- normalized: Record<string, any>;
14
- }
15
- /**
16
- * Validates user-provided options against a defined contract schema.
17
- * Emits warnings for unknown/misnamed options and errors for type mismatches.
18
- */
19
- export declare function validateOptions<T extends Record<string, any>>(componentName: string, userOptions: Record<string, any>, schema: OptionsContractSchema, debugMode?: boolean): ValidationResult;
20
- //# sourceMappingURL=OptionsContract.d.ts.map
@@ -1,107 +0,0 @@
1
- /**
2
- * Validates user-provided options against a defined contract schema.
3
- * Emits warnings for unknown/misnamed options and errors for type mismatches.
4
- */
5
- export function validateOptions(componentName, userOptions, schema, debugMode = false) {
6
- const result = {
7
- valid: true,
8
- warnings: [],
9
- errors: [],
10
- normalized: {}
11
- };
12
- const validKeys = new Set(Object.keys(schema));
13
- const aliasMap = new Map();
14
- // Build alias lookup
15
- for (const [key, def] of Object.entries(schema)) {
16
- if (def.aliases) {
17
- def.aliases.forEach(alias => aliasMap.set(alias.toLowerCase(), key));
18
- }
19
- }
20
- // Check for unknown or aliased options
21
- for (const [key, value] of Object.entries(userOptions)) {
22
- const lowerKey = key.toLowerCase();
23
- if (validKeys.has(key)) {
24
- // Valid key - validate type
25
- const def = schema[key];
26
- if (!validateType(value, def.type)) {
27
- result.errors.push(`[${componentName}] Option "${key}" expects type "${def.type}", got "${typeof value}".`);
28
- result.valid = false;
29
- }
30
- else {
31
- result.normalized[key] = value;
32
- }
33
- }
34
- else if (aliasMap.has(lowerKey)) {
35
- // Found an alias - warn and normalize
36
- const correctKey = aliasMap.get(lowerKey);
37
- result.warnings.push(`[${componentName}] Option "${key}" is not valid. Did you mean "${correctKey}"?`);
38
- result.normalized[correctKey] = value;
39
- }
40
- else {
41
- // Unknown option
42
- const suggestion = findClosestMatch(key, Array.from(validKeys));
43
- const hint = suggestion ? ` Did you mean "${suggestion}"?` : '';
44
- result.warnings.push(`[${componentName}] Unknown option "${key}".${hint} Valid options: ${Array.from(validKeys).join(', ')}`);
45
- }
46
- }
47
- // Apply defaults for missing required options
48
- for (const [key, def] of Object.entries(schema)) {
49
- if (!(key in result.normalized)) {
50
- if (def.required && def.default === undefined) {
51
- result.errors.push(`[${componentName}] Required option "${key}" is missing.`);
52
- result.valid = false;
53
- }
54
- else if (def.default !== undefined) {
55
- result.normalized[key] = def.default;
56
- }
57
- }
58
- }
59
- // Log warnings/errors in debug mode
60
- if (debugMode || result.warnings.length || result.errors.length) {
61
- result.warnings.forEach(w => console.warn(w));
62
- result.errors.forEach(e => console.error(e));
63
- }
64
- return result;
65
- }
66
- function validateType(value, expectedType) {
67
- if (value === undefined || value === null)
68
- return true; // Allow optional
69
- switch (expectedType) {
70
- case 'string': return typeof value === 'string';
71
- case 'number': return typeof value === 'number';
72
- case 'boolean': return typeof value === 'boolean';
73
- case 'array': return Array.isArray(value);
74
- case 'object': return typeof value === 'object' && !Array.isArray(value);
75
- case 'function': return typeof value === 'function';
76
- default: return true;
77
- }
78
- }
79
- function findClosestMatch(input, candidates) {
80
- const lower = input.toLowerCase();
81
- let best = null;
82
- let bestScore = Infinity;
83
- for (const candidate of candidates) {
84
- const score = levenshtein(lower, candidate.toLowerCase());
85
- if (score < bestScore && score <= 3) { // Max 3 edits
86
- bestScore = score;
87
- best = candidate;
88
- }
89
- }
90
- return best;
91
- }
92
- function levenshtein(a, b) {
93
- const matrix = [];
94
- for (let i = 0; i <= b.length; i++)
95
- matrix[i] = [i];
96
- for (let j = 0; j <= a.length; j++)
97
- matrix[0][j] = j;
98
- for (let i = 1; i <= b.length; i++) {
99
- for (let j = 1; j <= a.length; j++) {
100
- matrix[i][j] = b[i - 1] === a[j - 1]
101
- ? matrix[i - 1][j - 1]
102
- : Math.min(matrix[i - 1][j - 1] + 1, matrix[i][j - 1] + 1, matrix[i - 1][j] + 1);
103
- }
104
- }
105
- return matrix[b.length][a.length];
106
- }
107
- //# sourceMappingURL=OptionsContract.js.map
@@ -1,18 +0,0 @@
1
- /**
2
- * REGINALD'S LEDGER
3
- * A protected reactive container for atomic state management.
4
- */
5
- export declare class State<T> {
6
- #private;
7
- constructor(initialValue: T);
8
- get value(): T;
9
- /**
10
- * Access the timeline of past states (The Ledger).
11
- */
12
- get history(): string[];
13
- set(newValue: T): void;
14
- rollback(): void;
15
- rollforward(): void;
16
- subscribe(callback: (value: T) => void): () => void;
17
- }
18
- //# sourceMappingURL=State.d.ts.map
@@ -1,68 +0,0 @@
1
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2
- if (kind === "m") throw new TypeError("Private method is not writable");
3
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
5
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6
- };
7
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
- };
12
- var _State_instances, _State_value, _State_subscribers, _State_history, _State_future, _State_notify;
13
- /**
14
- * REGINALD'S LEDGER
15
- * A protected reactive container for atomic state management.
16
- */
17
- export class State {
18
- constructor(initialValue) {
19
- _State_instances.add(this);
20
- _State_value.set(this, void 0);
21
- _State_subscribers.set(this, new Set());
22
- _State_history.set(this, []);
23
- _State_future.set(this, []);
24
- __classPrivateFieldSet(this, _State_value, initialValue, "f");
25
- }
26
- get value() {
27
- return JSON.parse(JSON.stringify(__classPrivateFieldGet(this, _State_value, "f")));
28
- }
29
- /**
30
- * Access the timeline of past states (The Ledger).
31
- */
32
- get history() {
33
- return [...__classPrivateFieldGet(this, _State_history, "f")];
34
- }
35
- set(newValue) {
36
- // Snap state serially before change
37
- __classPrivateFieldGet(this, _State_history, "f").push(JSON.stringify(__classPrivateFieldGet(this, _State_value, "f")));
38
- __classPrivateFieldSet(this, _State_future, [], "f"); // Clear future timeline on new divergence
39
- __classPrivateFieldSet(this, _State_value, newValue, "f");
40
- __classPrivateFieldGet(this, _State_instances, "m", _State_notify).call(this);
41
- }
42
- rollback() {
43
- const previous = __classPrivateFieldGet(this, _State_history, "f").pop();
44
- if (previous !== undefined) {
45
- __classPrivateFieldGet(this, _State_future, "f").push(JSON.stringify(__classPrivateFieldGet(this, _State_value, "f"))); // Save current for redo
46
- __classPrivateFieldSet(this, _State_value, JSON.parse(previous), "f");
47
- __classPrivateFieldGet(this, _State_instances, "m", _State_notify).call(this);
48
- }
49
- }
50
- rollforward() {
51
- const next = __classPrivateFieldGet(this, _State_future, "f").pop();
52
- if (next !== undefined) {
53
- __classPrivateFieldGet(this, _State_history, "f").push(JSON.stringify(__classPrivateFieldGet(this, _State_value, "f"))); // Save current for undo
54
- __classPrivateFieldSet(this, _State_value, JSON.parse(next), "f");
55
- __classPrivateFieldGet(this, _State_instances, "m", _State_notify).call(this);
56
- }
57
- }
58
- subscribe(callback) {
59
- __classPrivateFieldGet(this, _State_subscribers, "f").add(callback);
60
- callback(this.value); // Immediate handshake
61
- return () => __classPrivateFieldGet(this, _State_subscribers, "f").delete(callback);
62
- }
63
- }
64
- _State_value = new WeakMap(), _State_subscribers = new WeakMap(), _State_history = new WeakMap(), _State_future = new WeakMap(), _State_instances = new WeakSet(), _State_notify = function _State_notify() {
65
- const currentValue = this.value;
66
- __classPrivateFieldGet(this, _State_subscribers, "f").forEach(callback => callback(currentValue));
67
- };
68
- //# sourceMappingURL=State.js.map
@@ -1,30 +0,0 @@
1
- import { ElementEngine, ElementOptions } from './ElementEngine.js';
2
- export type ElementComponent = ElementEngine & {
3
- render: (targetId: string | HTMLElement) => ElementComponent;
4
- injectCSS: (id: string, cssContent: string) => void;
5
- };
6
- /**
7
- * OPTIONS CONTRACT for Element:
8
- *
9
- * | Option | Type | Default | Aliases |
10
- * |--------------|--------|---------|----------------------------------|
11
- * | tagName | string | 'div' | tag, element, type |
12
- * | content | string | '' | text, html, innerHTML, value |
13
- * | contentType | string | 'text' | type, mode |
14
- * | inlineStyle | string | '' | style, css, styles |
15
- * | attributes | object | {} | attrs, props |
16
- *
17
- * METHODS (match state properties):
18
- * - .tagName(value) - Set HTML tag
19
- * - .content(value, type) - Set content with type
20
- * - .contentType(type) - Set content type
21
- * - .inlineStyle(css) - Set inline styles
22
- *
23
- * CONVENIENCE ALIASES:
24
- * - .tag(value) → .tagName(value)
25
- * - .text(value) → .content(value, 'text')
26
- * - .html(value) → .content(value, 'html')
27
- * - .style(css) → .inlineStyle(css)
28
- */
29
- export declare function Element(id: string, options?: ElementOptions): ElementComponent;
30
- //# sourceMappingURL=Element.d.ts.map
@@ -1,50 +0,0 @@
1
- import { ElementEngine } from './ElementEngine.js';
2
- import { ElementSkin } from './ElementSkin.js';
3
- /**
4
- * OPTIONS CONTRACT for Element:
5
- *
6
- * | Option | Type | Default | Aliases |
7
- * |--------------|--------|---------|----------------------------------|
8
- * | tagName | string | 'div' | tag, element, type |
9
- * | content | string | '' | text, html, innerHTML, value |
10
- * | contentType | string | 'text' | type, mode |
11
- * | inlineStyle | string | '' | style, css, styles |
12
- * | attributes | object | {} | attrs, props |
13
- *
14
- * METHODS (match state properties):
15
- * - .tagName(value) - Set HTML tag
16
- * - .content(value, type) - Set content with type
17
- * - .contentType(type) - Set content type
18
- * - .inlineStyle(css) - Set inline styles
19
- *
20
- * CONVENIENCE ALIASES:
21
- * - .tag(value) → .tagName(value)
22
- * - .text(value) → .content(value, 'text')
23
- * - .html(value) → .content(value, 'html')
24
- * - .style(css) → .inlineStyle(css)
25
- */
26
- export function Element(id, options = {}) {
27
- const engine = new ElementEngine(id, options);
28
- if (typeof window !== 'undefined') {
29
- // @ts-ignore
30
- window.juxEngines = window.juxEngines || {};
31
- // @ts-ignore
32
- window.juxEngines[id] = engine;
33
- }
34
- const skin = new ElementSkin(engine);
35
- // @ts-ignore
36
- engine.render = (targetId) => {
37
- const target = typeof targetId === 'string' ? document.getElementById(targetId) : targetId;
38
- if (target) {
39
- skin.renderSkin(target);
40
- }
41
- else {
42
- console.warn(`Element: Target not found for render - ${targetId}`);
43
- }
44
- return engine;
45
- };
46
- // @ts-ignore
47
- engine.injectCSS = (id, css) => skin.injectCSS(id, css);
48
- return engine;
49
- }
50
- //# sourceMappingURL=Element.js.map
@@ -1,59 +0,0 @@
1
- import { BaseEngine, BaseState } from '../base/BaseEngine.js';
2
- import { OptionsContractSchema } from '../base/OptionsContract.js';
3
- export interface ElementState extends BaseState {
4
- tag: string;
5
- content: string | null;
6
- contentType: 'text' | 'html';
7
- inlineStyle: string;
8
- }
9
- export interface ElementOptions {
10
- tag?: string;
11
- content?: string;
12
- contentType?: 'text' | 'html';
13
- inlineStyle?: string;
14
- attributes?: Record<string, string>;
15
- }
16
- export declare class ElementEngine extends BaseEngine<ElementState, ElementOptions> {
17
- constructor(id: string, options?: ElementOptions);
18
- /**
19
- * OPTIONS CONTRACT
20
- * Defines valid options with types, defaults, and aliases for common mistakes.
21
- */
22
- protected get optionsSchema(): OptionsContractSchema;
23
- protected prepareState(id: string, options: ElementOptions): ElementState;
24
- /**
25
- * Set the HTML tag name (e.g., 'div', 'span', 'h1', 'section')
26
- * Method name matches state property: tag
27
- */
28
- tag(value: string): this;
29
- /**
30
- * Set content with explicit type
31
- * Method name matches state property: content
32
- */
33
- content(value: string, type?: 'text' | 'html'): this;
34
- /**
35
- * Set content type
36
- * Method name matches state property: contentType
37
- */
38
- contentType(type: 'text' | 'html'): this;
39
- /**
40
- * Set inline styles (e.g., "color: red; margin: 10px;")
41
- * Method name matches state property: inlineStyle
42
- */
43
- inlineStyle(cssText: string): this;
44
- /** @alias for content(value, 'html') */
45
- html(value: string): this;
46
- /** @alias for inlineStyle() */
47
- style(cssText: string): this;
48
- /**
49
- * Append raw HTML to existing content
50
- */
51
- appendHtml(value: string): this;
52
- /** @alias for content(value, 'text') */
53
- text(value: string): this;
54
- /**
55
- * Receives RAW DOM events from the Skin and emits them to listeners.
56
- */
57
- handleEvent(eventName: string, content: any): void;
58
- }
59
- //# sourceMappingURL=ElementEngine.d.ts.map
@@ -1,118 +0,0 @@
1
- import { BaseEngine } from '../base/BaseEngine.js';
2
- export class ElementEngine extends BaseEngine {
3
- constructor(id, options = {}) {
4
- super(id, options);
5
- }
6
- /**
7
- * OPTIONS CONTRACT
8
- * Defines valid options with types, defaults, and aliases for common mistakes.
9
- */
10
- get optionsSchema() {
11
- return {
12
- tag: {
13
- type: 'string',
14
- default: 'div',
15
- description: 'HTML tag name (e.g., "div", "span", "h1")',
16
- aliases: ['tag', 'element', 'type']
17
- },
18
- content: {
19
- type: 'string',
20
- default: '',
21
- description: 'Text or HTML content',
22
- aliases: ['text', 'html', 'innerHTML', 'textContent', 'value']
23
- },
24
- contentType: {
25
- type: 'string',
26
- default: 'text',
27
- description: 'Content type: "text" (escaped) or "html" (raw)',
28
- aliases: ['type', 'mode']
29
- },
30
- inlineStyle: {
31
- type: 'string',
32
- default: '',
33
- description: 'Inline CSS styles (e.g., "color: red;")',
34
- aliases: ['style', 'css', 'styles']
35
- },
36
- attributes: {
37
- type: 'object',
38
- default: {},
39
- description: 'Arbitrary HTML attributes',
40
- aliases: ['attrs', 'props']
41
- }
42
- };
43
- }
44
- prepareState(id, options) {
45
- return {
46
- id,
47
- classes: ['jux-element'],
48
- visible: true,
49
- disabled: false,
50
- loading: false,
51
- attributes: options.attributes || {}, // ✅ Mapped from options
52
- tag: options.tag || 'div',
53
- content: options.content || '',
54
- contentType: options.contentType || 'text',
55
- inlineStyle: options.inlineStyle || ''
56
- };
57
- }
58
- /**
59
- * Set the HTML tag name (e.g., 'div', 'span', 'h1', 'section')
60
- * Method name matches state property: tag
61
- */
62
- tag(value) {
63
- this.updateState({ tag: value });
64
- this.emit('config', { tag: value });
65
- return this;
66
- }
67
- /**
68
- * Set content with explicit type
69
- * Method name matches state property: content
70
- */
71
- content(value, type = 'text') {
72
- this.updateState({ content: value, contentType: type });
73
- return this;
74
- }
75
- /**
76
- * Set content type
77
- * Method name matches state property: contentType
78
- */
79
- contentType(type) {
80
- this.updateState({ contentType: type });
81
- return this;
82
- }
83
- /**
84
- * Set inline styles (e.g., "color: red; margin: 10px;")
85
- * Method name matches state property: inlineStyle
86
- */
87
- inlineStyle(cssText) {
88
- this.updateState({ inlineStyle: cssText });
89
- return this;
90
- }
91
- /** @alias for content(value, 'html') */
92
- html(value) {
93
- return this.content(value, 'html');
94
- }
95
- /** @alias for inlineStyle() */
96
- style(cssText) {
97
- return this.inlineStyle(cssText);
98
- }
99
- /**
100
- * Append raw HTML to existing content
101
- */
102
- appendHtml(value) {
103
- const current = this.state.content || '';
104
- this.updateState({ content: current + value, contentType: 'html' });
105
- return this;
106
- }
107
- /** @alias for content(value, 'text') */
108
- text(value) {
109
- return this.content(value, 'text');
110
- }
111
- /**
112
- * Receives RAW DOM events from the Skin and emits them to listeners.
113
- */
114
- handleEvent(eventName, content) {
115
- this.emit(eventName, content);
116
- }
117
- }
118
- //# sourceMappingURL=ElementEngine.js.map
@@ -1,10 +0,0 @@
1
- import { BaseSkin } from '../base/BaseSkin.js';
2
- import { ElementEngine, ElementState } from './ElementEngine.js';
3
- export declare class ElementSkin extends BaseSkin<ElementState, ElementEngine> {
4
- constructor(engine: ElementEngine);
5
- protected get structureCss(): string;
6
- protected createRoot(): HTMLElement;
7
- protected bindEvents(root: HTMLElement): void;
8
- protected updateSkin(state: ElementState): void;
9
- }
10
- //# sourceMappingURL=ElementSkin.d.ts.map
@@ -1,56 +0,0 @@
1
- import { BaseSkin } from '../base/BaseSkin.js';
2
- import structureCss from './structure.css';
3
- export class ElementSkin extends BaseSkin {
4
- constructor(engine) {
5
- super(engine);
6
- }
7
- get structureCss() {
8
- return structureCss;
9
- }
10
- createRoot() {
11
- // Use state.tag (consistent naming)
12
- const tag = this.engine.state.tag || 'div';
13
- return document.createElement(tag);
14
- }
15
- bindEvents(root) {
16
- // ✅ Forward common events to the engine via public handler
17
- // This allows engine.on('click', ...) to work without skin accessing protected 'emit'
18
- const events = ['click', 'mouseenter', 'mouseleave', 'input', 'change', 'focus', 'blur'];
19
- events.forEach(eventName => {
20
- root.addEventListener(eventName, (e) => {
21
- this.engine.handleEvent(eventName, e);
22
- });
23
- });
24
- }
25
- updateSkin(state) {
26
- // 1. Tag Replacement Logic (uses state.tag)
27
- const currentTag = this.root ? this.root.tagName.toLowerCase() : '';
28
- const desiredTag = (state.tag || 'div').toLowerCase();
29
- if (this.root && currentTag !== desiredTag) {
30
- const newRoot = document.createElement(desiredTag);
31
- if (this.root.parentNode) {
32
- this.root.parentNode.replaceChild(newRoot, this.root);
33
- }
34
- this.root = newRoot;
35
- this.bindEvents(this.root);
36
- }
37
- if (!this.root)
38
- return;
39
- // 1. Ensure standard ID is set
40
- this.root.id = state.id;
41
- // 2. Base Attributes
42
- this.applySkinAttributes(this.root, state);
43
- // 3. Content (uses state.content and state.contentType)
44
- if (state.contentType === 'html') {
45
- this.root.innerHTML = state.content || '';
46
- }
47
- else {
48
- this.root.textContent = state.content || '';
49
- }
50
- // 4. Inline Styles (uses state.inlineStyle)
51
- if (state.inlineStyle) {
52
- this.root.style.cssText = state.inlineStyle;
53
- }
54
- }
55
- }
56
- //# sourceMappingURL=ElementSkin.js.map