fix(DimensionFilter): proper flex layout - fixed search+horizontal bar, filler content area with VScrollPanel display

- SearchBar + horizontal bar: flexShrink:0 for fixed height
- Content area: flexGrow:1 to fill remaining space
- Vertical sidebar: fixed 160px width, flexShrink:0
- Display: VScrollPanel with id + width:100% height:100%
This commit is contained in:
yumoqing 2026-07-30 18:27:24 +08:00
parent 09a07904fc
commit 57575d90f0

View File

@ -7,7 +7,8 @@ bricks.DimensionFilter = class extends bricks.VBox {
h_data_url: URL to fetch horizontal dimension labels/values, h_data_url: URL to fetch horizontal dimension labels/values,
v_measure_url: URL to fetch vertical dimension labels/values, v_measure_url: URL to fetch vertical dimension labels/values,
show_data_url: base URL to fetch display data, show_data_url: base URL to fetch display data,
search_placeholder: placeholder text for search input search_placeholder: placeholder text for search input,
h_param_name / v_param_name / keyword_param_name: optional param name overrides
} }
events: events:
filter_changed: {h_id: string, v_id: string, keyword: string} filter_changed: {h_id: string, v_id: string, keyword: string}
@ -15,7 +16,6 @@ bricks.DimensionFilter = class extends bricks.VBox {
constructor(opts){ constructor(opts){
opts.width = '100%'; opts.width = '100%';
opts.height = '100%'; opts.height = '100%';
opts.overflow = 'hidden';
super(opts); super(opts);
this.selected_h_id = 'all'; this.selected_h_id = 'all';
this.selected_v_id = 'all'; this.selected_v_id = 'all';
@ -41,37 +41,31 @@ bricks.DimensionFilter = class extends bricks.VBox {
search_label: this.opts.search_label || '搜索', search_label: this.opts.search_label || '搜索',
clear_label: this.opts.clear_label || '清除' clear_label: this.opts.clear_label || '清除'
}); });
this.searchbar.set_style('flexShrink', '0');
this.searchbar.bind('search', this.search_handle.bind(this)); this.searchbar.bind('search', this.search_handle.bind(this));
this.add_widget(this.searchbar); this.add_widget(this.searchbar);
} }
build_horizontal_bar(){ build_horizontal_bar(){
var bar = new bricks.HBox({width: '100%', height: 'auto', flexShrink: 0}); var bar = new bricks.HBox({width: '100%', height: 'auto'});
bar.set_style('flexShrink', '0');
bar.set_style('alignItems', 'center'); bar.set_style('alignItems', 'center');
this.left_arrow = new bricks.Button({ this.left_arrow = new bricks.Button({
label: '◀', label: '◀', width: 'auto', height: 'auto',
width: 'auto', flexShrink: 0, nonepack: true
height: 'auto',
flexShrink: 0,
nonepack: true
}); });
this.left_arrow.bind('click', this.scroll_left.bind(this)); this.left_arrow.bind('click', this.scroll_left.bind(this));
bar.add_widget(this.left_arrow); bar.add_widget(this.left_arrow);
this.h_scroll = new bricks.HBox({ this.h_scroll = new bricks.HBox({
width: '100%', width: '100%', flexGrow: 1, overflow: 'hidden'
flexGrow: 1,
overflow: 'hidden'
}); });
bar.add_widget(this.h_scroll); bar.add_widget(this.h_scroll);
this.right_arrow = new bricks.Button({ this.right_arrow = new bricks.Button({
label: '▶', label: '▶', width: 'auto', height: 'auto',
width: 'auto', flexShrink: 0, nonepack: true
height: 'auto',
flexShrink: 0,
nonepack: true
}); });
this.right_arrow.bind('click', this.scroll_right.bind(this)); this.right_arrow.bind('click', this.scroll_right.bind(this));
bar.add_widget(this.right_arrow); bar.add_widget(this.right_arrow);
@ -80,31 +74,40 @@ bricks.DimensionFilter = class extends bricks.VBox {
} }
build_content_area(){ build_content_area(){
// Filler area: fills remaining vertical space
var content = new bricks.HBox({width: '100%', height: '100%'}); var content = new bricks.HBox({width: '100%', height: '100%'});
content.set_style('flexGrow', '1');
/* Left: vertical measure buttons in a scroll panel */ // Left: vertical measure buttons in scroll panel (fixed width)
this.v_scroll = new bricks.VScrollPanel({width: 'auto', height: '100%'}); this.v_scroll = new bricks.VScrollPanel({width: 'auto', height: '100%'});
this.v_scroll.set_style('maxWidth', '200px'); this.v_scroll.set_style('flexShrink', '0');
this.v_scroll.set_style('minWidth', '80px'); this.v_scroll.set_style('width', '160px');
this.v_scroll.set_style('minWidth', '120px');
content.add_widget(this.v_scroll); content.add_widget(this.v_scroll);
/* Right: display area for show_data_url results */ // Right: display area — VScrollPanel with id so content can scroll
this.display_filler = new bricks.Filler({flexGrow: 1}); var filler = new bricks.Filler({flexGrow: 1, width: '100%', height: '100%'});
this.display_w = new bricks.VBox({width: '100%', height: '100%'}); this.display_scroll = new bricks.VScrollPanel({
this.display_filler.add_widget(this.display_w); id: this.opts.display_id || 'dim_display',
content.add_widget(this.display_filler); width: '100%',
height: '100%',
css: 'filler'
});
filler.add_widget(this.display_scroll);
this.display_w = this.display_scroll;
content.add_widget(filler);
this.add_widget(content); this.add_widget(content);
} }
scroll_left(){ scroll_left(){
var el = this.h_scroll.dom_element; var el = this.h_scroll.dom_element;
el.scrollLeft -= 150; if(el) el.scrollLeft -= 150;
} }
scroll_right(){ scroll_right(){
var el = this.h_scroll.dom_element; var el = this.h_scroll.dom_element;
el.scrollLeft += 150; if(el) el.scrollLeft += 150;
} }
async load_dimensions_data(){ async load_dimensions_data(){
@ -232,7 +235,9 @@ bricks.DimensionFilter = class extends bricks.VBox {
options: { options: {
url: this.opts.show_data_url, url: this.opts.show_data_url,
params: params, params: params,
method: this.opts.show_data_method || 'GET' method: this.opts.show_data_method || 'GET',
width: '100%',
height: '100%'
} }
}; };
var w = await bricks.widgetBuild(desc, this); var w = await bricks.widgetBuild(desc, this);