@gradio/core 1.0.0 → 1.0.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/CHANGELOG.md +32 -0
- package/dist/src/Blocks.svelte +59 -42
- package/dist/src/Login.svelte +13 -13
- package/dist/src/Login.svelte.d.ts +1 -0
- package/dist/src/api_docs/Settings.svelte +21 -22
- package/dist/src/api_docs/Settings.svelte.d.ts +6 -21
- package/dist/src/api_docs/SettingsBanner.svelte +2 -4
- package/dist/src/api_docs/SettingsBanner.svelte.d.ts +5 -20
- package/dist/src/dependency.d.ts +10 -6
- package/dist/src/dependency.js +12 -1
- package/dist/src/init.svelte.d.ts +7 -3
- package/dist/src/init.svelte.js +180 -40
- package/dist/src/types.d.ts +2 -0
- package/package.json +34 -34
- package/src/Blocks.svelte +59 -42
- package/src/Login.svelte +13 -13
- package/src/api_docs/Settings.svelte +21 -22
- package/src/api_docs/SettingsBanner.svelte +2 -4
- package/src/dependency.ts +46 -24
- package/src/init.svelte.ts +221 -60
- package/src/init.test.ts +1 -1
- package/src/types.ts +2 -0
package/src/init.svelte.ts
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
} from "./init_utils";
|
|
6
6
|
import { translate_if_needed } from "./i18n";
|
|
7
7
|
import { tick } from "svelte";
|
|
8
|
+
import { dequal } from "dequal";
|
|
8
9
|
|
|
9
10
|
import type {
|
|
10
11
|
ComponentMeta,
|
|
@@ -15,7 +16,7 @@ import type {
|
|
|
15
16
|
AppConfig,
|
|
16
17
|
ServerFunctions
|
|
17
18
|
} from "./types";
|
|
18
|
-
import type
|
|
19
|
+
import { type SharedProps } from "@gradio/utils";
|
|
19
20
|
import { allowed_shared_props } from "@gradio/utils";
|
|
20
21
|
import { Client } from "@gradio/client";
|
|
21
22
|
|
|
@@ -33,6 +34,7 @@ type Tab = {
|
|
|
33
34
|
elem_id: string | undefined;
|
|
34
35
|
scale: number | null;
|
|
35
36
|
order?: number;
|
|
37
|
+
component_id: number;
|
|
36
38
|
};
|
|
37
39
|
|
|
38
40
|
const type_map = {
|
|
@@ -54,6 +56,7 @@ export class AppTree {
|
|
|
54
56
|
|
|
55
57
|
/** the root node of the processed layout tree */
|
|
56
58
|
root = $state<ProcessedComponentMeta>();
|
|
59
|
+
root_untracked: ProcessedComponentMeta;
|
|
57
60
|
|
|
58
61
|
/** a set of all component IDs that are inputs to dependencies */
|
|
59
62
|
#input_ids: Set<number> = new Set();
|
|
@@ -65,6 +68,7 @@ export class AppTree {
|
|
|
65
68
|
|
|
66
69
|
#get_callbacks = new Map<number, get_data_type>();
|
|
67
70
|
#set_callbacks = new Map<number, set_data_type>();
|
|
71
|
+
#event_dispatcher: (id: number, event: string, data: unknown) => void;
|
|
68
72
|
component_ids: number[];
|
|
69
73
|
initial_tabs: Record<number, Tab[]> = {};
|
|
70
74
|
|
|
@@ -72,21 +76,25 @@ export class AppTree {
|
|
|
72
76
|
ready: Promise<void>;
|
|
73
77
|
ready_resolve!: () => void;
|
|
74
78
|
resolved: boolean = false;
|
|
79
|
+
#hidden_on_startup: Set<number> = new Set();
|
|
75
80
|
|
|
76
81
|
constructor(
|
|
77
82
|
components: ComponentMeta[],
|
|
78
83
|
layout: LayoutNode,
|
|
79
84
|
dependencies: Dependency[],
|
|
80
|
-
config: AppConfig,
|
|
85
|
+
config: Omit<AppConfig, "api_url">,
|
|
81
86
|
app: client_return,
|
|
82
|
-
reactive_formatter: (str: string) => string
|
|
87
|
+
reactive_formatter: (str: string) => string,
|
|
88
|
+
event_dispatcher: (id: number, event: string, data: unknown) => void
|
|
83
89
|
) {
|
|
84
90
|
this.ready = new Promise<void>((resolve) => {
|
|
85
91
|
this.ready_resolve = resolve;
|
|
86
92
|
});
|
|
87
93
|
this.reactive_formatter = reactive_formatter;
|
|
88
|
-
|
|
89
|
-
|
|
94
|
+
this.#config = {
|
|
95
|
+
...config,
|
|
96
|
+
api_url: new URL(config.api_prefix, config.root).toString()
|
|
97
|
+
};
|
|
90
98
|
this.#component_payload = components;
|
|
91
99
|
this.#layout_payload = layout;
|
|
92
100
|
this.#dependency_payload = dependencies;
|
|
@@ -123,17 +131,22 @@ export class AppTree {
|
|
|
123
131
|
this.initial_tabs = {};
|
|
124
132
|
gather_initial_tabs(this.root!, this.initial_tabs);
|
|
125
133
|
this.postprocess(this.root!);
|
|
134
|
+
this.#event_dispatcher = event_dispatcher;
|
|
135
|
+
this.root_untracked = this.root;
|
|
126
136
|
}
|
|
127
137
|
|
|
128
138
|
reload(
|
|
129
139
|
components: ComponentMeta[],
|
|
130
140
|
layout: LayoutNode,
|
|
131
141
|
dependencies: Dependency[],
|
|
132
|
-
config: AppConfig
|
|
142
|
+
config: Omit<AppConfig, "api_url">
|
|
133
143
|
) {
|
|
134
144
|
this.#layout_payload = layout;
|
|
135
145
|
this.#component_payload = components;
|
|
136
|
-
this.#config =
|
|
146
|
+
this.#config = {
|
|
147
|
+
...config,
|
|
148
|
+
api_url: new URL(config.api_prefix, config.root).toString()
|
|
149
|
+
};
|
|
137
150
|
this.#dependency_payload = dependencies;
|
|
138
151
|
|
|
139
152
|
this.root = this.create_node(
|
|
@@ -203,22 +216,22 @@ export class AppTree {
|
|
|
203
216
|
|
|
204
217
|
postprocess(tree: ProcessedComponentMeta) {
|
|
205
218
|
this.root = this.traverse(tree, [
|
|
206
|
-
(node) => handle_visibility(node, this.#config.
|
|
219
|
+
(node) => handle_visibility(node, this.#config.api_url),
|
|
207
220
|
(node) =>
|
|
208
221
|
untrack_children_of_invisible_parents(
|
|
209
222
|
node,
|
|
210
|
-
this.#config.root,
|
|
211
223
|
this.components_to_register
|
|
212
224
|
),
|
|
225
|
+
(node) => handle_empty_forms(node, this.components_to_register),
|
|
226
|
+
(node) => translate_props(node),
|
|
227
|
+
(node) => apply_initial_tabs(node, this.initial_tabs),
|
|
228
|
+
(node) => this.find_attached_events(node, this.#dependency_payload),
|
|
213
229
|
(node) =>
|
|
214
|
-
|
|
230
|
+
untrack_children_of_closed_accordions_or_inactive_tabs(
|
|
215
231
|
node,
|
|
216
|
-
this
|
|
217
|
-
this
|
|
218
|
-
)
|
|
219
|
-
(node) => translate_props(node, this.#config.root),
|
|
220
|
-
(node) => apply_initial_tabs(node, this.#config.root, this.initial_tabs),
|
|
221
|
-
(node) => this.find_attached_events(node, this.#dependency_payload)
|
|
232
|
+
this.components_to_register,
|
|
233
|
+
this.#hidden_on_startup
|
|
234
|
+
)
|
|
222
235
|
]);
|
|
223
236
|
}
|
|
224
237
|
|
|
@@ -317,6 +330,7 @@ export class AppTree {
|
|
|
317
330
|
component.props,
|
|
318
331
|
[this.#input_ids, this.#output_ids],
|
|
319
332
|
this.client,
|
|
333
|
+
this.#config.api_url,
|
|
320
334
|
{ ...this.#config }
|
|
321
335
|
);
|
|
322
336
|
|
|
@@ -335,14 +349,14 @@ export class AppTree {
|
|
|
335
349
|
? get_component(
|
|
336
350
|
component.type,
|
|
337
351
|
component.component_class_id,
|
|
338
|
-
this.#config.
|
|
352
|
+
this.#config.api_url || ""
|
|
339
353
|
)
|
|
340
354
|
: null,
|
|
341
355
|
key: component.key,
|
|
342
356
|
rendered_in: component.rendered_in,
|
|
343
|
-
documentation: component.documentation
|
|
357
|
+
documentation: component.documentation,
|
|
358
|
+
original_visibility: processed_props.shared_props.visible
|
|
344
359
|
};
|
|
345
|
-
|
|
346
360
|
return node;
|
|
347
361
|
}
|
|
348
362
|
|
|
@@ -369,6 +383,19 @@ export class AppTree {
|
|
|
369
383
|
n.children = subtree.children;
|
|
370
384
|
}
|
|
371
385
|
|
|
386
|
+
async update_visibility(
|
|
387
|
+
node: ProcessedComponentMeta,
|
|
388
|
+
new_state: any
|
|
389
|
+
): Promise<void> {
|
|
390
|
+
node.children.forEach((child) => {
|
|
391
|
+
const _set_data = this.#set_callbacks.get(child.id);
|
|
392
|
+
if (_set_data) {
|
|
393
|
+
_set_data(new_state);
|
|
394
|
+
}
|
|
395
|
+
this.update_visibility(child, new_state);
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
|
|
372
399
|
/*
|
|
373
400
|
* Updates the state of a component by its ID
|
|
374
401
|
* @param id the ID of the component to update
|
|
@@ -391,20 +418,42 @@ export class AppTree {
|
|
|
391
418
|
this.root = this.traverse(this.root!, [
|
|
392
419
|
//@ts-ignore
|
|
393
420
|
(n) => set_visibility_for_updated_node(n, id, new_state.visible),
|
|
394
|
-
|
|
421
|
+
//@ts-ignore
|
|
422
|
+
(n) => update_parent_visibility(n, id, new_state.visible),
|
|
423
|
+
(n) => handle_visibility(n, this.#config.api_url)
|
|
395
424
|
]);
|
|
425
|
+
await tick();
|
|
396
426
|
already_updated_visibility = true;
|
|
397
427
|
}
|
|
398
428
|
const _set_data = this.#set_callbacks.get(id);
|
|
399
|
-
if (!_set_data)
|
|
400
|
-
|
|
429
|
+
if (!_set_data) {
|
|
430
|
+
const old_value = node?.props.props.value;
|
|
431
|
+
// @ts-ignore
|
|
432
|
+
const new_props = create_props_shared_props(new_state);
|
|
433
|
+
node!.props.shared_props = {
|
|
434
|
+
...node?.props.shared_props,
|
|
435
|
+
...new_props.shared_props
|
|
436
|
+
};
|
|
437
|
+
node!.props.props = { ...node?.props.props, ...new_props.props };
|
|
438
|
+
if ("value" in new_state && !dequal(old_value, new_state.value)) {
|
|
439
|
+
this.#event_dispatcher(id, "change", null);
|
|
440
|
+
}
|
|
441
|
+
} else if (_set_data) {
|
|
442
|
+
_set_data(new_state);
|
|
443
|
+
}
|
|
401
444
|
if (!check_visibility || already_updated_visibility) return;
|
|
402
445
|
// need to let the UI settle before traversing again
|
|
403
446
|
// otherwise there could be
|
|
404
447
|
await tick();
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
448
|
+
// Update the visibility in a way that does not
|
|
449
|
+
// re-render the root/tree. Doing that would nuke
|
|
450
|
+
// any values currently in the UI.
|
|
451
|
+
// @ts-ignore
|
|
452
|
+
await this.update_visibility(node, new_state);
|
|
453
|
+
const parent_node = find_parent(this.root!, id);
|
|
454
|
+
if (parent_node)
|
|
455
|
+
// @ts-ignore
|
|
456
|
+
update_parent_visibility(parent_node, id, new_state.visible);
|
|
408
457
|
}
|
|
409
458
|
|
|
410
459
|
/**
|
|
@@ -414,14 +463,39 @@ export class AppTree {
|
|
|
414
463
|
*/
|
|
415
464
|
async get_state(id: number): Promise<Record<string, unknown> | null> {
|
|
416
465
|
const _get_data = this.#get_callbacks.get(id);
|
|
417
|
-
const component = this
|
|
466
|
+
const component = find_node_by_id(this.root!, id);
|
|
418
467
|
if (!_get_data && !component) return null;
|
|
419
468
|
if (_get_data) return await _get_data();
|
|
420
469
|
|
|
421
|
-
if (component)
|
|
470
|
+
if (component)
|
|
471
|
+
return Promise.resolve({ value: component.props.props.value });
|
|
422
472
|
|
|
423
473
|
return null;
|
|
424
474
|
}
|
|
475
|
+
|
|
476
|
+
async render_previously_invisible_children(id: number) {
|
|
477
|
+
this.root = this.traverse(this.root!, [
|
|
478
|
+
(node) => {
|
|
479
|
+
if (node.id === id) {
|
|
480
|
+
make_visible_if_not_rendered(node, this.#hidden_on_startup);
|
|
481
|
+
}
|
|
482
|
+
return node;
|
|
483
|
+
},
|
|
484
|
+
(node) => handle_visibility(node, this.#config.api_url)
|
|
485
|
+
]);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
function make_visible_if_not_rendered(
|
|
490
|
+
node: ProcessedComponentMeta,
|
|
491
|
+
hidden_on_startup: Set<number>
|
|
492
|
+
): void {
|
|
493
|
+
node.props.shared_props.visible = hidden_on_startup.has(node.id)
|
|
494
|
+
? true
|
|
495
|
+
: node.props.shared_props.visible;
|
|
496
|
+
node.children.forEach((child) => {
|
|
497
|
+
make_visible_if_not_rendered(child, hidden_on_startup);
|
|
498
|
+
});
|
|
425
499
|
}
|
|
426
500
|
|
|
427
501
|
/**
|
|
@@ -451,6 +525,27 @@ export function process_server_fn(
|
|
|
451
525
|
}, {} as ServerFunctions);
|
|
452
526
|
}
|
|
453
527
|
|
|
528
|
+
function create_props_shared_props(props: ComponentMeta["props"]): {
|
|
529
|
+
shared_props: SharedProps;
|
|
530
|
+
props: Record<string, unknown>;
|
|
531
|
+
} {
|
|
532
|
+
const _shared_props: Partial<SharedProps> = {};
|
|
533
|
+
const _props: Record<string, unknown> = {};
|
|
534
|
+
for (const key in props) {
|
|
535
|
+
// For Tabs (or any component that already has an id prop)
|
|
536
|
+
// Set the id to the props so that it doesn't get overwritten
|
|
537
|
+
if (key === "id" || key === "autoscroll") {
|
|
538
|
+
_props[key] = props[key];
|
|
539
|
+
} else if (allowed_shared_props.includes(key as keyof SharedProps)) {
|
|
540
|
+
const _key = key as keyof SharedProps;
|
|
541
|
+
_shared_props[_key] = props[key];
|
|
542
|
+
} else {
|
|
543
|
+
_props[key] = props[key];
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
return { shared_props: _shared_props as SharedProps, props: _props };
|
|
547
|
+
}
|
|
548
|
+
|
|
454
549
|
/**
|
|
455
550
|
* Gathers the props for a component
|
|
456
551
|
* @param id the ID of the component
|
|
@@ -464,28 +559,15 @@ function gather_props(
|
|
|
464
559
|
props: ComponentMeta["props"],
|
|
465
560
|
dependencies: [Set<number>, Set<number>],
|
|
466
561
|
client: client_return,
|
|
562
|
+
api_url: string,
|
|
467
563
|
additional: Record<string, unknown> = {}
|
|
468
564
|
): {
|
|
469
565
|
shared_props: SharedProps;
|
|
470
566
|
props: Record<string, unknown>;
|
|
471
567
|
} {
|
|
472
|
-
const _shared_props:
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
// For Tabs (or any component that already has an id prop)
|
|
476
|
-
// Set the id to the props so that it doesn't get overwritten
|
|
477
|
-
if (key === "id" || key === "autoscroll") {
|
|
478
|
-
_props[key] = props[key];
|
|
479
|
-
} else if (allowed_shared_props.includes(key as keyof SharedProps)) {
|
|
480
|
-
const _key = key as keyof SharedProps;
|
|
481
|
-
_shared_props[_key] = props[key];
|
|
482
|
-
if (_key === "server_fns") {
|
|
483
|
-
_shared_props.server = process_server_fn(id, props.server_fns, client);
|
|
484
|
-
}
|
|
485
|
-
} else {
|
|
486
|
-
_props[key] = props[key];
|
|
487
|
-
}
|
|
488
|
-
}
|
|
568
|
+
const { shared_props: _shared_props, props: _props } =
|
|
569
|
+
create_props_shared_props(props);
|
|
570
|
+
_shared_props.server = process_server_fn(id, props.server_fns, client);
|
|
489
571
|
|
|
490
572
|
for (const key in additional) {
|
|
491
573
|
if (allowed_shared_props.includes(key as keyof SharedProps)) {
|
|
@@ -508,13 +590,7 @@ function gather_props(
|
|
|
508
590
|
_shared_props.load_component = (
|
|
509
591
|
name: string,
|
|
510
592
|
variant: "base" | "component" | "example"
|
|
511
|
-
) =>
|
|
512
|
-
get_component(
|
|
513
|
-
name,
|
|
514
|
-
"",
|
|
515
|
-
_shared_props.root || "",
|
|
516
|
-
variant
|
|
517
|
-
) as LoadingComponent;
|
|
593
|
+
) => get_component(name, "", api_url, variant) as LoadingComponent;
|
|
518
594
|
|
|
519
595
|
_shared_props.visible =
|
|
520
596
|
_shared_props.visible === undefined ? true : _shared_props.visible;
|
|
@@ -525,19 +601,19 @@ function gather_props(
|
|
|
525
601
|
|
|
526
602
|
function handle_visibility(
|
|
527
603
|
node: ProcessedComponentMeta,
|
|
528
|
-
|
|
604
|
+
api_url: string
|
|
529
605
|
): ProcessedComponentMeta {
|
|
530
606
|
// Check if the node is visible
|
|
531
607
|
if (node.props.shared_props.visible && !node.component) {
|
|
532
608
|
const result: ProcessedComponentMeta = {
|
|
533
609
|
...node,
|
|
534
|
-
component: get_component(node.type, node.component_class_id,
|
|
610
|
+
component: get_component(node.type, node.component_class_id, api_url),
|
|
535
611
|
children: []
|
|
536
612
|
};
|
|
537
613
|
|
|
538
614
|
if (node.children) {
|
|
539
615
|
result.children = node.children.map((child) =>
|
|
540
|
-
handle_visibility(child,
|
|
616
|
+
handle_visibility(child, api_url)
|
|
541
617
|
);
|
|
542
618
|
}
|
|
543
619
|
return result;
|
|
@@ -570,7 +646,6 @@ function _untrack(
|
|
|
570
646
|
|
|
571
647
|
function untrack_children_of_invisible_parents(
|
|
572
648
|
node: ProcessedComponentMeta,
|
|
573
|
-
root: string,
|
|
574
649
|
components_to_register: Set<number>
|
|
575
650
|
): ProcessedComponentMeta {
|
|
576
651
|
// Check if the node is visible
|
|
@@ -580,9 +655,51 @@ function untrack_children_of_invisible_parents(
|
|
|
580
655
|
return node;
|
|
581
656
|
}
|
|
582
657
|
|
|
658
|
+
function mark_component_invisible_if_visible(
|
|
659
|
+
node: ProcessedComponentMeta,
|
|
660
|
+
hidden_on_startup: Set<number>
|
|
661
|
+
): ProcessedComponentMeta {
|
|
662
|
+
if (node.props.shared_props.visible === true) {
|
|
663
|
+
hidden_on_startup.add(node.id);
|
|
664
|
+
node.props.shared_props.visible = false;
|
|
665
|
+
}
|
|
666
|
+
node.children.forEach((child) => {
|
|
667
|
+
mark_component_invisible_if_visible(child, hidden_on_startup);
|
|
668
|
+
});
|
|
669
|
+
return node;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
function untrack_children_of_closed_accordions_or_inactive_tabs(
|
|
673
|
+
node: ProcessedComponentMeta,
|
|
674
|
+
components_to_register: Set<number>,
|
|
675
|
+
hidden_on_startup: Set<number>
|
|
676
|
+
): ProcessedComponentMeta {
|
|
677
|
+
// Check if the node is an accordion or tabs
|
|
678
|
+
if (node.type === "accordion" && node.props.props.open === false) {
|
|
679
|
+
_untrack(node, components_to_register);
|
|
680
|
+
if (node.children) {
|
|
681
|
+
node.children.forEach((child) => {
|
|
682
|
+
mark_component_invisible_if_visible(child, hidden_on_startup);
|
|
683
|
+
});
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
if (node.type === "tabs") {
|
|
687
|
+
node.children.forEach((child) => {
|
|
688
|
+
if (
|
|
689
|
+
child.type === "tabitem" &&
|
|
690
|
+
child.props.props.id !==
|
|
691
|
+
(node.props.props.selected || node.props.props.initial_tabs[0].id)
|
|
692
|
+
) {
|
|
693
|
+
_untrack(child, components_to_register);
|
|
694
|
+
mark_component_invisible_if_visible(child, hidden_on_startup);
|
|
695
|
+
}
|
|
696
|
+
});
|
|
697
|
+
}
|
|
698
|
+
return node;
|
|
699
|
+
}
|
|
700
|
+
|
|
583
701
|
function handle_empty_forms(
|
|
584
702
|
node: ProcessedComponentMeta,
|
|
585
|
-
root: string,
|
|
586
703
|
components_to_register: Set<number>
|
|
587
704
|
): ProcessedComponentMeta {
|
|
588
705
|
// Check if the node is visible
|
|
@@ -601,10 +718,34 @@ function handle_empty_forms(
|
|
|
601
718
|
return node;
|
|
602
719
|
}
|
|
603
720
|
|
|
604
|
-
function
|
|
721
|
+
function update_parent_visibility(
|
|
605
722
|
node: ProcessedComponentMeta,
|
|
606
|
-
|
|
723
|
+
child_made_visible: number,
|
|
724
|
+
visibility_state: boolean | "hidden"
|
|
607
725
|
): ProcessedComponentMeta {
|
|
726
|
+
// This function was added to address a tricky situation:
|
|
727
|
+
// Form components are wrapped in a Form component automatically.
|
|
728
|
+
// If all the children of the Form are invisible, the Form itself is marked invisible.
|
|
729
|
+
// in AppTree.postprocess -> handle_empty_forms
|
|
730
|
+
// This is to avoid rendering empty forms in the UI. They look ugly.
|
|
731
|
+
// So what happens when a child inside the Form is made visible again?
|
|
732
|
+
// The Form needs to become visible again too.
|
|
733
|
+
// If the child is made invisible, the form should be too if all other children are invisible.
|
|
734
|
+
// However, we are not doing this now since what we want to do is fetch the latest visibility of all
|
|
735
|
+
// the children from the UI. However, get_data only returns the props, not the shared props.
|
|
736
|
+
if (
|
|
737
|
+
node.type === "form" &&
|
|
738
|
+
node.children.length &&
|
|
739
|
+
node.children.some((child) => child.id === child_made_visible)
|
|
740
|
+
) {
|
|
741
|
+
if (visibility_state === true) node.props.shared_props.visible = true;
|
|
742
|
+
else if (!visibility_state && node.children.length === 1)
|
|
743
|
+
node.props.shared_props.visible = "hidden";
|
|
744
|
+
}
|
|
745
|
+
return node;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
function translate_props(node: ProcessedComponentMeta): ProcessedComponentMeta {
|
|
608
749
|
const supported_props = [
|
|
609
750
|
"description",
|
|
610
751
|
"info",
|
|
@@ -631,12 +772,13 @@ function translate_props(
|
|
|
631
772
|
|
|
632
773
|
function apply_initial_tabs(
|
|
633
774
|
node: ProcessedComponentMeta,
|
|
634
|
-
root: string,
|
|
635
775
|
initial_tabs: Record<number, Tab[]>
|
|
636
776
|
): ProcessedComponentMeta {
|
|
637
777
|
if (node.type === "tabs" && node.id in initial_tabs) {
|
|
638
778
|
const tabs = initial_tabs[node.id].sort((a, b) => a.order! - b.order!);
|
|
639
779
|
node.props.props.initial_tabs = tabs;
|
|
780
|
+
} else if (node.type === "tabitem") {
|
|
781
|
+
node.props.props.component_id = node.id;
|
|
640
782
|
}
|
|
641
783
|
return node;
|
|
642
784
|
}
|
|
@@ -660,7 +802,8 @@ function _gather_initial_tabs(
|
|
|
660
802
|
elem_id: node.props.shared_props.elem_id,
|
|
661
803
|
visible: node.props.shared_props.visible as boolean,
|
|
662
804
|
interactive: node.props.shared_props.interactive,
|
|
663
|
-
scale: node.props.shared_props.scale || null
|
|
805
|
+
scale: node.props.shared_props.scale || null,
|
|
806
|
+
component_id: node.id
|
|
664
807
|
});
|
|
665
808
|
node.props.props.order = order;
|
|
666
809
|
}
|
|
@@ -715,3 +858,21 @@ function find_node_by_id(
|
|
|
715
858
|
|
|
716
859
|
return null;
|
|
717
860
|
}
|
|
861
|
+
|
|
862
|
+
function find_parent(
|
|
863
|
+
tree: ProcessedComponentMeta,
|
|
864
|
+
id: number
|
|
865
|
+
): ProcessedComponentMeta | null {
|
|
866
|
+
if (tree.children) {
|
|
867
|
+
for (const child of tree.children) {
|
|
868
|
+
if (child.id === id) {
|
|
869
|
+
return tree;
|
|
870
|
+
}
|
|
871
|
+
const result = find_parent(child, id);
|
|
872
|
+
if (result) {
|
|
873
|
+
return result;
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
return null;
|
|
878
|
+
}
|
package/src/init.test.ts
CHANGED
package/src/types.ts
CHANGED
|
@@ -32,6 +32,7 @@ export interface ProcessedComponentMeta {
|
|
|
32
32
|
component_class_id: string; // ?;
|
|
33
33
|
key: string | number | null; // ?;
|
|
34
34
|
rendered_in?: number; // ?;
|
|
35
|
+
original_visibility: boolean | "hidden";
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
/** Dictates whether a dependency is continous and/or a generator */
|
|
@@ -126,4 +127,5 @@ export interface AppConfig {
|
|
|
126
127
|
max_file_size?: number;
|
|
127
128
|
autoscroll: boolean;
|
|
128
129
|
api_prefix: string;
|
|
130
|
+
api_url: string;
|
|
129
131
|
}
|