@yuneta/gobj-ui 7.23.158 → 7.23.160
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 +78 -1
- package/dist/gobj-ui.cjs.js +987 -168
- package/dist/gobj-ui.es.js +987 -168
- package/package.json +1 -1
- package/src/c_yui_form.js +52 -1
- package/src/c_yui_treedb_schema.js +134 -10
- package/src/c_yui_treedb_topic_with_form.css +67 -0
- package/src/c_yui_treedb_topic_with_form.js +401 -9
- package/src/c_yui_treedb_topics.js +80 -0
- package/src/yui_asset.css +51 -0
- package/src/yui_asset.js +223 -3
- package/src/yui_asset.test.js +18 -0
- package/src/yui_file_field.css +28 -0
- package/src/yui_file_field.js +45 -1
- package/src/yui_graph_camera.js +64 -0
package/package.json
CHANGED
package/src/c_yui_form.js
CHANGED
|
@@ -61,7 +61,8 @@ import {
|
|
|
61
61
|
yui_file_control
|
|
62
62
|
} from "./yui_file_field.js";
|
|
63
63
|
import {
|
|
64
|
-
yui_asset_id
|
|
64
|
+
yui_asset_id,
|
|
65
|
+
yui_asset_release
|
|
65
66
|
} from "./yui_asset.js";
|
|
66
67
|
|
|
67
68
|
import "./c_yui_form.css";
|
|
@@ -192,6 +193,9 @@ function mt_create(gobj)
|
|
|
192
193
|
************************************************************/
|
|
193
194
|
function mt_destroy(gobj)
|
|
194
195
|
{
|
|
196
|
+
/* A file preview holds blob urls, which keep their bytes alive
|
|
197
|
+
* until revoked -- and removing the DOM revokes nothing. */
|
|
198
|
+
yui_asset_release(gobj_read_attr(gobj, "$container"));
|
|
195
199
|
destroy_ui(gobj);
|
|
196
200
|
}
|
|
197
201
|
|
|
@@ -3155,6 +3159,51 @@ function ac_clear_record(gobj, event, kw, src)
|
|
|
3155
3159
|
return 0;
|
|
3156
3160
|
}
|
|
3157
3161
|
|
|
3162
|
+
/************************************************************
|
|
3163
|
+
* From the host: what it fetched for the asset a `file` column
|
|
3164
|
+
* names -- the `get-asset` answer, or why there is none.
|
|
3165
|
+
* {
|
|
3166
|
+
* name: the column
|
|
3167
|
+
* id: the asset id the answer is for
|
|
3168
|
+
* answer: the get-asset answer, or null
|
|
3169
|
+
* error: why there is no answer, when there is none
|
|
3170
|
+
* }
|
|
3171
|
+
*
|
|
3172
|
+
* Kept on the control and drawn only while the column still names
|
|
3173
|
+
* THAT id: an answer landing after the person picked another file
|
|
3174
|
+
* or cleared the column must not bring the old picture back.
|
|
3175
|
+
************************************************************/
|
|
3176
|
+
function ac_set_file_preview(gobj, event, kw, src)
|
|
3177
|
+
{
|
|
3178
|
+
let $container = gobj_read_attr(gobj, "$container");
|
|
3179
|
+
let $form = $container? $container.querySelector('form'): null;
|
|
3180
|
+
if(!$form) {
|
|
3181
|
+
log_error(`${gobj_short_name(gobj)}: no form to show the file preview in`);
|
|
3182
|
+
return -1;
|
|
3183
|
+
}
|
|
3184
|
+
|
|
3185
|
+
let $file = null;
|
|
3186
|
+
$form.querySelectorAll('.FILE_FIELD').forEach(($el) => {
|
|
3187
|
+
if($el.dataset.treedb_name === kw.name) {
|
|
3188
|
+
$file = $el;
|
|
3189
|
+
}
|
|
3190
|
+
});
|
|
3191
|
+
if(!$file) {
|
|
3192
|
+
log_error(`${gobj_short_name(gobj)}: no file column '${kw.name}' in the form`);
|
|
3193
|
+
return -1;
|
|
3194
|
+
}
|
|
3195
|
+
|
|
3196
|
+
$file.yui_file_stored = {
|
|
3197
|
+
id: kw.id || "",
|
|
3198
|
+
answer: kw.answer || null,
|
|
3199
|
+
error: kw.error || ""
|
|
3200
|
+
};
|
|
3201
|
+
if($file.yui_file_render) {
|
|
3202
|
+
$file.yui_file_render();
|
|
3203
|
+
}
|
|
3204
|
+
return 0;
|
|
3205
|
+
}
|
|
3206
|
+
|
|
3158
3207
|
/************************************************************
|
|
3159
3208
|
* From internal form button for new rows
|
|
3160
3209
|
* or from load_tabulator_data() to load data from backend
|
|
@@ -3390,6 +3439,7 @@ function create_gclass(gclass_name)
|
|
|
3390
3439
|
["EV_RECORD_CHANGED", ac_record_changed, null],
|
|
3391
3440
|
["EV_COPY_RECORD", ac_copy_record, null],
|
|
3392
3441
|
["EV_PASTE_RECORD", ac_paste_record, null],
|
|
3442
|
+
["EV_SET_FILE_PREVIEW", ac_set_file_preview, null],
|
|
3393
3443
|
|
|
3394
3444
|
["EV_WINDOW_MOVED", null, null],
|
|
3395
3445
|
["EV_WINDOW_RESIZED", null, null],
|
|
@@ -3413,6 +3463,7 @@ function create_gclass(gclass_name)
|
|
|
3413
3463
|
["EV_RECORD_CHANGED", 0],
|
|
3414
3464
|
["EV_COPY_RECORD", 0],
|
|
3415
3465
|
["EV_PASTE_RECORD", 0],
|
|
3466
|
+
["EV_SET_FILE_PREVIEW", 0],
|
|
3416
3467
|
|
|
3417
3468
|
["EV_WINDOW_MOVED", 0],
|
|
3418
3469
|
["EV_WINDOW_RESIZED", 0],
|
|
@@ -25,6 +25,12 @@
|
|
|
25
25
|
* via the host-supplied `node_route`). An alternate landing to the
|
|
26
26
|
* topic cards, in the spirit of "every treedb is a graph".
|
|
27
27
|
*
|
|
28
|
+
* The CAMERA is the family's (yui_graph_camera.js): the same
|
|
29
|
+
* toolbar cluster -- zoom in/out, readout, fit, 1:1 -- and the
|
|
30
|
+
* same wheel: it SCROLLS, and Ctrl + wheel zooms, over the cards
|
|
31
|
+
* too (yui_graph_forward_wheel). This view zoomed on a bare wheel
|
|
32
|
+
* and had no toolbar, beside graphs that did neither.
|
|
33
|
+
*
|
|
28
34
|
* Copyright (c) 2026, ArtGins.
|
|
29
35
|
* All Rights Reserved.
|
|
30
36
|
***********************************************************************/
|
|
@@ -49,10 +55,20 @@ import {
|
|
|
49
55
|
gobj_read_str_attr,
|
|
50
56
|
is_object,
|
|
51
57
|
escapeHtml,
|
|
58
|
+
refresh_language,
|
|
52
59
|
} from "@yuneta/gobj-js";
|
|
53
60
|
|
|
54
61
|
import {Graph, NodeEvent} from "@antv/g6";
|
|
55
62
|
|
|
63
|
+
import {yui_toolbar} from "./yui_toolbar.js";
|
|
64
|
+
import {
|
|
65
|
+
yui_graph_camera_items,
|
|
66
|
+
yui_graph_camera_behaviors,
|
|
67
|
+
yui_graph_forward_wheel,
|
|
68
|
+
yui_graph_update_zoom,
|
|
69
|
+
} from "./yui_graph_camera.js";
|
|
70
|
+
import {ensure_pinch_zoom_patch} from "./g6_touch_gestures.js";
|
|
71
|
+
|
|
56
72
|
import {getStrokeColor} from "./lib_graph.js";
|
|
57
73
|
|
|
58
74
|
import {yui_is_dark, yui_watch_theme} from "./yui_theme.js";
|
|
@@ -98,14 +114,17 @@ SDATA(data_type_t.DTP_JSON, "descs", 0, null, "Treedb schema: {top
|
|
|
98
114
|
SDATA(data_type_t.DTP_STRING, "node_route", 0, "", "Hash-route template with a {topic} placeholder: a node click opens that topic (e.g. '#/topics/db/<sel>/{topic}')"),
|
|
99
115
|
SDATA(data_type_t.DTP_BOOLEAN, "with_node_click", 0, false, "With no `node_route`, PUBLISH a node click as EV_NODE_CLICK instead of dropping it. Opt-in, because a subscriber has to DECLARE the event: the hosts that route by hash, and the ones that want nothing, must not have it appear underneath them"),
|
|
100
116
|
SDATA(data_type_t.DTP_BOOLEAN, "system", 0, false, "Include system topics (__*__) too"),
|
|
117
|
+
SDATA(data_type_t.DTP_STRING, "wide", 0, "40px", "Height of the toolbar buttons: the family's (C_YUI_TREEDB_GRAPH, C_YUI_JSON_GRAPH, C_YUI_GOBJ_TREE_JS)"),
|
|
101
118
|
SDATA(data_type_t.DTP_POINTER, "$container", 0, null, "Root HTML element"),
|
|
102
119
|
SDATA_END()
|
|
103
120
|
];
|
|
104
121
|
|
|
105
122
|
let PRIVATE_DATA = {
|
|
106
123
|
$container: null,
|
|
124
|
+
$canvas: null, // the element G6 is mounted in, under the toolbar
|
|
107
125
|
graph: null,
|
|
108
126
|
theme_observer: null, // MutationObserver on <html data-theme>
|
|
127
|
+
unforward_wheel: null, // removes the wheel forwarding of the cards
|
|
109
128
|
};
|
|
110
129
|
|
|
111
130
|
let __gclass__ = null;
|
|
@@ -122,6 +141,9 @@ let __gclass__ = null;
|
|
|
122
141
|
|
|
123
142
|
function mt_create(gobj)
|
|
124
143
|
{
|
|
144
|
+
/* Pinch to zoom on a touch screen, as in the other graphs. */
|
|
145
|
+
ensure_pinch_zoom_patch();
|
|
146
|
+
|
|
125
147
|
build_ui(gobj);
|
|
126
148
|
|
|
127
149
|
/*
|
|
@@ -179,9 +201,31 @@ function mt_destroy(gobj)
|
|
|
179
201
|
************************************************************/
|
|
180
202
|
function build_ui(gobj)
|
|
181
203
|
{
|
|
204
|
+
let priv = gobj.priv;
|
|
205
|
+
let wide = gobj_read_str_attr(gobj, "wide");
|
|
206
|
+
|
|
207
|
+
/* The camera cluster and nothing else: this view has no folding,
|
|
208
|
+
* no layouts and no find -- a schema is a handful of cards. */
|
|
209
|
+
const $toolbar = yui_toolbar({}, [
|
|
210
|
+
['div', {class: 'yui-horizontal-toolbar-section left'}, []],
|
|
211
|
+
['div', {class: 'yui-horizontal-toolbar-section center'},
|
|
212
|
+
yui_graph_camera_items(gobj, null, wide)],
|
|
213
|
+
['div', {class: 'yui-horizontal-toolbar-section right'}, []],
|
|
214
|
+
]);
|
|
215
|
+
refresh_language($toolbar, t);
|
|
216
|
+
|
|
217
|
+
priv.$canvas = createElement2(
|
|
218
|
+
['div', {class: 'TREEDB_SCHEMA_CANVAS',
|
|
219
|
+
style: 'position:relative; flex:1 1 auto; min-height:0;'}, []]
|
|
220
|
+
);
|
|
221
|
+
|
|
182
222
|
let $container = createElement2(
|
|
183
223
|
['div', {class: 'C_YUI_TREEDB_SCHEMA TREEDB_SCHEMA_VIEW',
|
|
184
|
-
style: 'position:relative; height:100%; min-height:0;'
|
|
224
|
+
style: 'position:relative; height:100%; min-height:0; ' +
|
|
225
|
+
'display:flex; flex-direction:column;'}, [
|
|
226
|
+
['div', {class: 'TREEDB_SCHEMA_TOOLBAR', style: 'flex:0 0 auto;'}, [$toolbar]],
|
|
227
|
+
priv.$canvas
|
|
228
|
+
]]
|
|
185
229
|
);
|
|
186
230
|
gobj_write_attr(gobj, "$container", $container);
|
|
187
231
|
}
|
|
@@ -550,7 +594,8 @@ function build_graph(gobj)
|
|
|
550
594
|
{
|
|
551
595
|
let priv = gobj.priv;
|
|
552
596
|
let $container = gobj_read_attr(gobj, "$container");
|
|
553
|
-
if(!$container) {
|
|
597
|
+
if(!$container || !priv.$canvas) {
|
|
598
|
+
log_error(`${gobj_short_name(gobj)}: no UI to draw the schema in`);
|
|
554
599
|
return;
|
|
555
600
|
}
|
|
556
601
|
destroy_graph(gobj);
|
|
@@ -561,7 +606,7 @@ function build_graph(gobj)
|
|
|
561
606
|
['div', {class: 'TREEDB_SCHEMA_EMPTY p-4 yui-text-quiet',
|
|
562
607
|
i18n: 'no topics'}, t('no topics', {defaultValue: 'No topics'})]
|
|
563
608
|
);
|
|
564
|
-
|
|
609
|
+
priv.$canvas.appendChild($empty);
|
|
565
610
|
return;
|
|
566
611
|
}
|
|
567
612
|
|
|
@@ -569,8 +614,9 @@ function build_graph(gobj)
|
|
|
569
614
|
let graph;
|
|
570
615
|
try {
|
|
571
616
|
graph = new Graph({
|
|
572
|
-
container:
|
|
617
|
+
container: priv.$canvas,
|
|
573
618
|
autoResize: true,
|
|
619
|
+
animation: false,
|
|
574
620
|
data: data,
|
|
575
621
|
edge: {
|
|
576
622
|
style: edge_style(dark),
|
|
@@ -581,7 +627,8 @@ function build_graph(gobj)
|
|
|
581
627
|
nodesep: 28,
|
|
582
628
|
ranksep: 90,
|
|
583
629
|
},
|
|
584
|
-
|
|
630
|
+
/* The family's camera: the wheel scrolls, Ctrl + wheel zooms. */
|
|
631
|
+
behaviors: ["drag-canvas", ...yui_graph_camera_behaviors(), "drag-element"],
|
|
585
632
|
});
|
|
586
633
|
} catch(e) {
|
|
587
634
|
log_error(`${gobj_short_name(gobj)}: schema graph create failed: ${e}`);
|
|
@@ -591,6 +638,16 @@ function build_graph(gobj)
|
|
|
591
638
|
|
|
592
639
|
graph.setTheme(dark ? "dark" : "light");
|
|
593
640
|
|
|
641
|
+
/* The readout follows ANY camera change, the wheel included -- a
|
|
642
|
+
* wheel notch passes through no action of ours. */
|
|
643
|
+
graph.on('aftertransform', () => {
|
|
644
|
+
yui_graph_update_zoom($container, priv.graph);
|
|
645
|
+
});
|
|
646
|
+
|
|
647
|
+
/* The cards cover most of this drawing, and a card does not pass
|
|
648
|
+
* the wheel on: without this it works only between them. */
|
|
649
|
+
priv.unforward_wheel = yui_graph_forward_wheel(graph, priv.$canvas);
|
|
650
|
+
|
|
594
651
|
/* A node click opens that topic — a real hash navigation, so it is
|
|
595
652
|
* deep-linkable and Back-friendly like the cards. Crosses the FSM. */
|
|
596
653
|
graph.on(NodeEvent.CLICK, (evt) => {
|
|
@@ -601,7 +658,9 @@ function build_graph(gobj)
|
|
|
601
658
|
/* No fitView: the diagram is drawn at its own scale and stays there.
|
|
602
659
|
* Zooming it to the container the moment it appears rewrites the size
|
|
603
660
|
* the reader just saw, and does it differently for every treedb. */
|
|
604
|
-
graph.render().
|
|
661
|
+
graph.render().then(() => {
|
|
662
|
+
yui_graph_update_zoom($container, priv.graph);
|
|
663
|
+
}).catch((e) => {
|
|
605
664
|
log_error(`${gobj_short_name(gobj)}: schema graph render failed: ${e}`);
|
|
606
665
|
});
|
|
607
666
|
}
|
|
@@ -612,6 +671,10 @@ function build_graph(gobj)
|
|
|
612
671
|
function destroy_graph(gobj)
|
|
613
672
|
{
|
|
614
673
|
let priv = gobj.priv;
|
|
674
|
+
if(priv.unforward_wheel) {
|
|
675
|
+
priv.unforward_wheel();
|
|
676
|
+
priv.unforward_wheel = null;
|
|
677
|
+
}
|
|
615
678
|
if(priv.graph) {
|
|
616
679
|
try {
|
|
617
680
|
priv.graph.destroy();
|
|
@@ -620,10 +683,10 @@ function destroy_graph(gobj)
|
|
|
620
683
|
}
|
|
621
684
|
priv.graph = null;
|
|
622
685
|
}
|
|
623
|
-
|
|
624
|
-
if(
|
|
625
|
-
while(
|
|
626
|
-
|
|
686
|
+
/* The CANVAS only: the toolbar is built once and stays. */
|
|
687
|
+
if(priv.$canvas) {
|
|
688
|
+
while(priv.$canvas.firstChild) {
|
|
689
|
+
priv.$canvas.removeChild(priv.$canvas.firstChild);
|
|
627
690
|
}
|
|
628
691
|
}
|
|
629
692
|
}
|
|
@@ -753,6 +816,59 @@ function ac_theme(gobj, event, kw, src)
|
|
|
753
816
|
return 0;
|
|
754
817
|
}
|
|
755
818
|
|
|
819
|
+
/************************************************************
|
|
820
|
+
* The camera, from the toolbar. Same moves as the family's
|
|
821
|
+
* (C_YUI_GOBJ_TREE_JS): +/- 20%, fit, and actual size at the
|
|
822
|
+
* layout's origin.
|
|
823
|
+
************************************************************/
|
|
824
|
+
function camera_move(gobj, what, promise)
|
|
825
|
+
{
|
|
826
|
+
Promise.resolve(promise).then(() => {
|
|
827
|
+
yui_graph_update_zoom(gobj_read_attr(gobj, "$container"), gobj.priv.graph);
|
|
828
|
+
}).catch((e) => {
|
|
829
|
+
log_error(`${gobj_short_name(gobj)}: schema graph ${what} failed: ${e}`);
|
|
830
|
+
});
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
function ac_zoom_in(gobj, event, kw, src)
|
|
834
|
+
{
|
|
835
|
+
let graph = gobj.priv.graph;
|
|
836
|
+
if(graph) {
|
|
837
|
+
camera_move(gobj, "zoom in", graph.zoomTo(graph.getZoom() * 1.2));
|
|
838
|
+
}
|
|
839
|
+
return 0;
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
function ac_zoom_out(gobj, event, kw, src)
|
|
843
|
+
{
|
|
844
|
+
let graph = gobj.priv.graph;
|
|
845
|
+
if(graph) {
|
|
846
|
+
camera_move(gobj, "zoom out", graph.zoomTo(graph.getZoom() * 0.8));
|
|
847
|
+
}
|
|
848
|
+
return 0;
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
function ac_zoom_reset(gobj, event, kw, src)
|
|
852
|
+
{
|
|
853
|
+
let graph = gobj.priv.graph;
|
|
854
|
+
if(graph && graph.rendered) {
|
|
855
|
+
camera_move(gobj, "actual size",
|
|
856
|
+
Promise.resolve(graph.zoomTo(1)).then(() => graph.translateTo([0, 0])));
|
|
857
|
+
}
|
|
858
|
+
return 0;
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
/* A fit ASKED for is fine: what this view refuses is fitting on its
|
|
862
|
+
* own, the moment it appears (see build_graph). */
|
|
863
|
+
function ac_center(gobj, event, kw, src)
|
|
864
|
+
{
|
|
865
|
+
let graph = gobj.priv.graph;
|
|
866
|
+
if(graph) {
|
|
867
|
+
camera_move(gobj, "fit", graph.fitView());
|
|
868
|
+
}
|
|
869
|
+
return 0;
|
|
870
|
+
}
|
|
871
|
+
|
|
756
872
|
/************************************************************
|
|
757
873
|
* Rebuild from a fresh schema (descs arrived / changed).
|
|
758
874
|
************************************************************/
|
|
@@ -795,6 +911,10 @@ function create_gclass(gclass_name)
|
|
|
795
911
|
["EV_SHOW", ac_show, null],
|
|
796
912
|
["EV_THEME", ac_theme, null],
|
|
797
913
|
["EV_REBUILD", ac_rebuild, null],
|
|
914
|
+
["EV_ZOOM_IN", ac_zoom_in, null],
|
|
915
|
+
["EV_ZOOM_OUT", ac_zoom_out, null],
|
|
916
|
+
["EV_ZOOM_RESET", ac_zoom_reset, null],
|
|
917
|
+
["EV_CENTER", ac_center, null],
|
|
798
918
|
]]
|
|
799
919
|
];
|
|
800
920
|
|
|
@@ -805,6 +925,10 @@ function create_gclass(gclass_name)
|
|
|
805
925
|
["EV_SHOW", 0],
|
|
806
926
|
["EV_THEME", 0],
|
|
807
927
|
["EV_REBUILD", 0],
|
|
928
|
+
["EV_ZOOM_IN", 0],
|
|
929
|
+
["EV_ZOOM_OUT", 0],
|
|
930
|
+
["EV_ZOOM_RESET", 0],
|
|
931
|
+
["EV_CENTER", 0],
|
|
808
932
|
];
|
|
809
933
|
|
|
810
934
|
__gclass__ = gclass_create(
|
|
@@ -141,3 +141,70 @@
|
|
|
141
141
|
font-style: italic;
|
|
142
142
|
opacity: 0.6;
|
|
143
143
|
}
|
|
144
|
+
|
|
145
|
+
/*
|
|
146
|
+
* A file cell that names an asset is a LINK: the click opens it
|
|
147
|
+
* (EV_SHOW_CELL_FILE). Same shape as the JSON cell beside it.
|
|
148
|
+
*/
|
|
149
|
+
.FILE_CELL_LINK {
|
|
150
|
+
white-space: nowrap;
|
|
151
|
+
}
|
|
152
|
+
.FILE_CELL_LINK .FILE_CELL_ICON {
|
|
153
|
+
margin-right: 0.25rem;
|
|
154
|
+
vertical-align: middle;
|
|
155
|
+
}
|
|
156
|
+
.FILE_CELL_LINK .FILE_CELL_ID {
|
|
157
|
+
text-decoration: underline;
|
|
158
|
+
vertical-align: middle;
|
|
159
|
+
}
|
|
160
|
+
.FILE_CELL_LINK .FILE_CELL_MORE {
|
|
161
|
+
margin-left: 0.35rem;
|
|
162
|
+
font-family: inherit;
|
|
163
|
+
opacity: 0.7;
|
|
164
|
+
vertical-align: middle;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/*
|
|
168
|
+
* The file popup: one item per asset the cell names, each the thing
|
|
169
|
+
* itself and a caption (what it is, and a way to open it full size).
|
|
170
|
+
*/
|
|
171
|
+
.TREEDB_CELL_FILE {
|
|
172
|
+
display: flex;
|
|
173
|
+
flex-direction: column;
|
|
174
|
+
gap: 1rem;
|
|
175
|
+
padding: 0.75rem;
|
|
176
|
+
height: 100%;
|
|
177
|
+
overflow: auto;
|
|
178
|
+
}
|
|
179
|
+
.TREEDB_CELL_FILE .CELL_FILE_ITEM {
|
|
180
|
+
display: flex;
|
|
181
|
+
flex-direction: column;
|
|
182
|
+
align-items: center;
|
|
183
|
+
gap: 0.35rem;
|
|
184
|
+
min-width: 0;
|
|
185
|
+
}
|
|
186
|
+
.TREEDB_CELL_FILE img.CELL_FILE_MEDIA,
|
|
187
|
+
.TREEDB_CELL_FILE video.CELL_FILE_MEDIA {
|
|
188
|
+
display: block;
|
|
189
|
+
max-width: 100%;
|
|
190
|
+
max-height: 70vh;
|
|
191
|
+
object-fit: contain;
|
|
192
|
+
}
|
|
193
|
+
.TREEDB_CELL_FILE audio.CELL_FILE_MEDIA {
|
|
194
|
+
width: 100%;
|
|
195
|
+
}
|
|
196
|
+
.TREEDB_CELL_FILE iframe.CELL_FILE_MEDIA {
|
|
197
|
+
min-height: 60vh;
|
|
198
|
+
}
|
|
199
|
+
.TREEDB_CELL_FILE .CELL_FILE_CAPTION {
|
|
200
|
+
display: flex;
|
|
201
|
+
flex-wrap: wrap;
|
|
202
|
+
justify-content: center;
|
|
203
|
+
gap: 0.75rem;
|
|
204
|
+
font-size: 0.8rem;
|
|
205
|
+
opacity: 0.85;
|
|
206
|
+
}
|
|
207
|
+
.TREEDB_CELL_FILE .CELL_FILE_ID {
|
|
208
|
+
font-family: monospace;
|
|
209
|
+
overflow-wrap: anywhere;
|
|
210
|
+
}
|