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.
- package/README.md +1 -32
- package/bin/cli.js +4 -2
- package/index.d.ts +200 -0
- package/index.js +96 -22
- package/juxconfig.example.js +58 -63
- package/lib/components/alert.ts +200 -0
- package/lib/components/app.ts +247 -0
- package/lib/components/badge.ts +101 -0
- package/lib/components/base/BaseComponent.ts +421 -0
- package/lib/components/base/FormInput.ts +227 -0
- package/lib/components/button.ts +178 -0
- package/lib/components/card.ts +173 -0
- package/lib/components/chart.ts +231 -0
- package/lib/components/checkbox.ts +242 -0
- package/lib/components/code.ts +123 -0
- package/lib/components/container.ts +140 -0
- package/lib/components/data.ts +135 -0
- package/lib/components/datepicker.ts +234 -0
- package/lib/components/dialog.ts +172 -0
- package/lib/components/divider.ts +100 -0
- package/lib/components/dropdown.ts +186 -0
- package/lib/components/element.ts +267 -0
- package/lib/components/fileupload.ts +309 -0
- package/lib/components/grid.ts +291 -0
- package/lib/components/guard.ts +92 -0
- package/lib/components/heading.ts +96 -0
- package/lib/components/helpers.ts +41 -0
- package/lib/components/hero.ts +224 -0
- package/lib/components/icon.ts +178 -0
- package/lib/components/icons.ts +464 -0
- package/lib/components/include.ts +410 -0
- package/lib/components/input.ts +457 -0
- package/lib/components/list.ts +419 -0
- package/lib/components/loading.ts +100 -0
- package/lib/components/menu.ts +275 -0
- package/lib/components/modal.ts +284 -0
- package/lib/components/nav.ts +257 -0
- package/lib/components/paragraph.ts +97 -0
- package/lib/components/progress.ts +159 -0
- package/lib/components/radio.ts +278 -0
- package/lib/components/req.ts +303 -0
- package/lib/components/script.ts +41 -0
- package/lib/components/select.ts +252 -0
- package/lib/components/sidebar.ts +275 -0
- package/lib/components/style.ts +41 -0
- package/lib/components/switch.ts +246 -0
- package/lib/components/table.ts +1249 -0
- package/lib/components/tabs.ts +250 -0
- package/lib/components/theme-toggle.ts +293 -0
- package/lib/components/tooltip.ts +144 -0
- package/lib/components/view.ts +190 -0
- package/lib/components/write.ts +272 -0
- package/lib/globals.d.ts +19 -5
- package/lib/layouts/default.css +260 -0
- package/lib/layouts/figma.css +334 -0
- package/lib/reactivity/state.ts +78 -0
- package/lib/utils/{fetch.js → fetch.ts} +206 -81
- package/machinery/ast.js +347 -0
- package/machinery/build.js +466 -0
- package/machinery/compiler3.js +6 -66
- package/machinery/config.js +6 -93
- package/machinery/doc-generator.js +136 -0
- package/machinery/imports.js +155 -0
- package/machinery/server.js +166 -0
- package/machinery/ts-shim.js +46 -0
- package/machinery/watcher.js +162 -50
- package/package.json +9 -30
- package/create/index.jux +0 -77
- package/create/layout.jux +0 -18
- package/create/style.css +0 -57
- package/create/themes/assets/jux.svg +0 -34
- package/create/themes/base.css +0 -197
- package/create/themes/base2.css +0 -54
- package/create/themes/layouts/base.jux +0 -16
- package/create/themes/layouts/base_marketing.jux +0 -0
- package/create/themes/layouts/base_saas.jux +0 -0
- package/lib/componentsv2/base/BaseEngine.d.ts +0 -112
- package/lib/componentsv2/base/BaseEngine.js +0 -279
- package/lib/componentsv2/base/BaseSkin.d.ts +0 -74
- package/lib/componentsv2/base/BaseSkin.js +0 -130
- package/lib/componentsv2/base/Neighborhood.d.ts +0 -22
- package/lib/componentsv2/base/Neighborhood.js +0 -56
- package/lib/componentsv2/base/OptionsContract.d.ts +0 -20
- package/lib/componentsv2/base/OptionsContract.js +0 -107
- package/lib/componentsv2/base/State.d.ts +0 -18
- package/lib/componentsv2/base/State.js +0 -68
- package/lib/componentsv2/element/Element.d.ts +0 -30
- package/lib/componentsv2/element/Element.js +0 -50
- package/lib/componentsv2/element/ElementEngine.d.ts +0 -59
- package/lib/componentsv2/element/ElementEngine.js +0 -118
- package/lib/componentsv2/element/ElementSkin.d.ts +0 -10
- package/lib/componentsv2/element/ElementSkin.js +0 -56
- package/lib/componentsv2/element/structure.css +0 -261
- package/lib/componentsv2/grid/Grid.d.ts +0 -13
- package/lib/componentsv2/grid/Grid.js +0 -27
- package/lib/componentsv2/grid/GridEngine.d.ts +0 -77
- package/lib/componentsv2/grid/GridEngine.js +0 -153
- package/lib/componentsv2/grid/GridSkin.d.ts +0 -11
- package/lib/componentsv2/grid/GridSkin.js +0 -84
- package/lib/componentsv2/grid/structure.css +0 -27
- package/lib/componentsv2/input/Input.d.ts +0 -6
- package/lib/componentsv2/input/Input.js +0 -21
- package/lib/componentsv2/input/InputEngine.d.ts +0 -70
- package/lib/componentsv2/input/InputEngine.js +0 -143
- package/lib/componentsv2/input/InputSkin.d.ts +0 -11
- package/lib/componentsv2/input/InputSkin.js +0 -89
- package/lib/componentsv2/input/structure.css +0 -47
- package/lib/componentsv2/list/List.d.ts +0 -49
- package/lib/componentsv2/list/List.js +0 -105
- package/lib/componentsv2/list/ListEngine.d.ts +0 -121
- package/lib/componentsv2/list/ListEngine.js +0 -322
- package/lib/componentsv2/list/ListSkin.d.ts +0 -20
- package/lib/componentsv2/list/ListSkin.js +0 -345
- package/lib/componentsv2/list/structure.css +0 -359
- package/lib/componentsv2/plugins/ClientSQLitePlugin.d.ts +0 -21
- package/lib/componentsv2/plugins/ClientSQLitePlugin.js +0 -130
- package/lib/componentsv2/plugins/IndexedDBPlugin.d.ts +0 -18
- package/lib/componentsv2/plugins/IndexedDBPlugin.js +0 -75
- package/lib/componentsv2/plugins/LocalStoragePlugin.d.ts +0 -20
- package/lib/componentsv2/plugins/LocalStoragePlugin.js +0 -65
- package/lib/componentsv2/plugins/ServerSQLitePlugin.d.ts +0 -25
- package/lib/componentsv2/plugins/ServerSQLitePlugin.js +0 -70
- package/lib/componentsv2/stubs/ComponentComposition.ts.stub +0 -32
- package/lib/componentsv2/stubs/ComponentEngine.ts.stub +0 -36
- package/lib/componentsv2/stubs/ComponentSkin.ts.stub +0 -35
- package/lib/componentsv2/stubs/ComponentStructure.css.d.ts.stub +0 -2
- package/lib/componentsv2/stubs/ComponentStructure.css.stub +0 -13
- package/lib/utils/fetch.d.ts +0 -176
- package/machinery/serve.js +0 -255
- package/types/css.d.ts +0 -10
- /package/{create/themes/layouts/base_blog.jux → machinery/bundleAssets.js} +0 -0
- /package/{create/themes/layouts/base_docs.jux → machinery/bundleJux.js} +0 -0
- /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
|