Skip to main content

azul_layout/widgets/
list_view.rs

1//! Native list view widget with column headers, row selection, and sorting indicators.
2
3use alloc::vec::Vec;
4
5use azul_core::{
6    callbacks::{CoreCallback, CoreCallbackData, Update},
7    dom::{
8        Dom, DomVec, EventFilter, HoverEventFilter, IdOrClass, IdOrClass::Class, IdOrClassVec,
9        TabIndex,
10    },
11    geom::{LogicalPosition, LogicalSize},
12    menu::{Menu, OptionMenu},
13    refany::{OptionRefAny, RefAny},
14};
15#[allow(clippy::wildcard_imports)] // widget/render module pulls in the css property/value types it builds with
16use azul_css::{
17    corety::OptionUsize,
18    dynamic_selector::{CssPropertyWithConditions, CssPropertyWithConditionsVec},
19    props::{
20        basic::*,
21        layout::*,
22        property::{CssProperty, *},
23        style::*,
24    },
25    *,
26};
27use azul_css::css::BoxOrStatic;
28
29use crate::callbacks::{Callback, CallbackInfo};
30
31const STRING_16146701490593874959: AzString = AzString::from_const_str("system:ui");
32const STYLE_BACKGROUND_CONTENT_661302523448178568_ITEMS: &[StyleBackgroundContent] =
33    &[StyleBackgroundContent::Color(ColorU {
34        r: 209,
35        g: 232,
36        b: 255,
37        a: 255,
38    })];
39const STYLE_BACKGROUND_CONTENT_2444935983575427872_ITEMS: &[StyleBackgroundContent] =
40    &[StyleBackgroundContent::Color(ColorU {
41        r: 252,
42        g: 252,
43        b: 252,
44        a: 255,
45    })];
46const STYLE_BACKGROUND_CONTENT_3010057533077499049_ITEMS: &[StyleBackgroundContent] =
47    &[StyleBackgroundContent::Color(ColorU {
48        r: 229,
49        g: 243,
50        b: 251,
51        a: 255,
52    })];
53const STYLE_BACKGROUND_CONTENT_3839348353894170136_ITEMS: &[StyleBackgroundContent] =
54    &[StyleBackgroundContent::Color(ColorU {
55        r: 249,
56        g: 250,
57        b: 251,
58        a: 255,
59    })];
60const STYLE_BACKGROUND_CONTENT_6112684430356720596_ITEMS: &[StyleBackgroundContent] =
61    &[StyleBackgroundContent::LinearGradient(LinearGradient {
62        direction: Direction::FromTo(DirectionCorners {
63            dir_from: DirectionCorner::Top,
64            dir_to: DirectionCorner::Bottom,
65        }),
66        extend_mode: ExtendMode::Clamp,
67        stops: NormalizedLinearColorStopVec::from_const_slice(
68            LINEAR_COLOR_STOP_10827796861537038040_ITEMS,
69        ),
70    })];
71const STYLE_BACKGROUND_CONTENT_7422581697888665934_ITEMS: &[StyleBackgroundContent] =
72    &[StyleBackgroundContent::LinearGradient(LinearGradient {
73        direction: Direction::FromTo(DirectionCorners {
74            dir_from: DirectionCorner::Top,
75            dir_to: DirectionCorner::Bottom,
76        }),
77        extend_mode: ExtendMode::Clamp,
78        stops: NormalizedLinearColorStopVec::from_const_slice(
79            LINEAR_COLOR_STOP_513857305091467054_ITEMS,
80        ),
81    })];
82const STYLE_BACKGROUND_CONTENT_11062356617965867290_ITEMS: &[StyleBackgroundContent] =
83    &[StyleBackgroundContent::Color(ColorU {
84        r: 240,
85        g: 240,
86        b: 240,
87        a: 255,
88    })];
89const STYLE_BACKGROUND_CONTENT_11098930083828139815_ITEMS: &[StyleBackgroundContent] =
90    &[StyleBackgroundContent::Color(ColorU {
91        r: 184,
92        g: 224,
93        b: 243,
94        a: 255,
95    })];
96const STYLE_TRANSFORM_6162542744002865382_ITEMS: &[StyleTransform] =
97    &[StyleTransform::Translate(StyleTransformTranslate2D {
98        x: PixelValue::const_px(7),
99        y: PixelValue::const_px(0),
100    })];
101const STYLE_TRANSFORM_16978981723642914576_ITEMS: &[StyleTransform] =
102    &[StyleTransform::Rotate(AngleValue::const_deg(45))];
103const STYLE_TRANSFORM_17732691695785266054_ITEMS: &[StyleTransform] = &[
104    StyleTransform::Rotate(AngleValue::const_deg(315)),
105    StyleTransform::Translate(StyleTransformTranslate2D {
106        x: PixelValue::const_px(0),
107        y: PixelValue::const_px(2),
108    }),
109];
110const STYLE_FONT_FAMILY_8122988506401935406_ITEMS: &[StyleFontFamily] =
111    &[StyleFontFamily::System(STRING_16146701490593874959)];
112const LINEAR_COLOR_STOP_513857305091467054_ITEMS: &[NormalizedLinearColorStop] = &[
113    NormalizedLinearColorStop {
114        offset: PercentageValue::const_new(0),
115        color: ColorOrSystem::color(ColorU {
116            r: 255,
117            g: 255,
118            b: 255,
119            a: 255,
120        }),
121    },
122    NormalizedLinearColorStop {
123        offset: PercentageValue::const_new(50),
124        color: ColorOrSystem::color(ColorU {
125            r: 255,
126            g: 255,
127            b: 255,
128            a: 255,
129        }),
130    },
131    NormalizedLinearColorStop {
132        offset: PercentageValue::const_new(51),
133        color: ColorOrSystem::color(ColorU {
134            r: 247,
135            g: 248,
136            b: 250,
137            a: 255,
138        }),
139    },
140    NormalizedLinearColorStop {
141        offset: PercentageValue::const_new(100),
142        color: ColorOrSystem::color(ColorU {
143            r: 243,
144            g: 244,
145            b: 246,
146            a: 255,
147        }),
148    },
149];
150const LINEAR_COLOR_STOP_10827796861537038040_ITEMS: &[NormalizedLinearColorStop] = &[
151    NormalizedLinearColorStop {
152        offset: PercentageValue::const_new(0),
153        color: ColorOrSystem::color(ColorU {
154            r: 247,
155            g: 252,
156            b: 254,
157            a: 255,
158        }),
159    },
160    NormalizedLinearColorStop {
161        offset: PercentageValue::const_new(50),
162        color: ColorOrSystem::color(ColorU {
163            r: 247,
164            g: 252,
165            b: 254,
166            a: 255,
167        }),
168    },
169    NormalizedLinearColorStop {
170        offset: PercentageValue::const_new(51),
171        color: ColorOrSystem::color(ColorU {
172            r: 232,
173            g: 246,
174            b: 254,
175            a: 255,
176        }),
177    },
178    NormalizedLinearColorStop {
179        offset: PercentageValue::const_new(100),
180        color: ColorOrSystem::color(ColorU {
181            r: 206,
182            g: 231,
183            b: 244,
184            a: 255,
185        }),
186    },
187];
188
189const CSS_MATCH_1085706216385961159_PROPERTIES: &[CssPropertyWithConditions] = &[
190    // .__azul_native-list-header-arrow-down
191    CssPropertyWithConditions::simple(CssProperty::Transform(StyleTransformVecValue::Exact(
192        StyleTransformVec::from_const_slice(STYLE_TRANSFORM_6162542744002865382_ITEMS),
193    ))),
194    CssPropertyWithConditions::simple(CssProperty::Position(LayoutPositionValue::Exact(
195        LayoutPosition::Absolute,
196    ))),
197    CssPropertyWithConditions::simple(CssProperty::PaddingRight(LayoutPaddingRightValue::Exact(
198        LayoutPaddingRight {
199            inner: PixelValue::const_px(3),
200        },
201    ))),
202    CssPropertyWithConditions::simple(CssProperty::PaddingLeft(LayoutPaddingLeftValue::Exact(
203        LayoutPaddingLeft {
204            inner: PixelValue::const_px(3),
205        },
206    ))),
207    CssPropertyWithConditions::simple(CssProperty::PaddingBottom(LayoutPaddingBottomValue::Exact(
208        LayoutPaddingBottom {
209            inner: PixelValue::const_px(3),
210        },
211    ))),
212    CssPropertyWithConditions::simple(CssProperty::PaddingTop(LayoutPaddingTopValue::Exact(
213        LayoutPaddingTop {
214            inner: PixelValue::const_px(3),
215        },
216    ))),
217    CssPropertyWithConditions::simple(CssProperty::JustifyContent(
218        LayoutJustifyContentValue::Exact(LayoutJustifyContent::Center),
219    )),
220    CssPropertyWithConditions::simple(CssProperty::FlexDirection(LayoutFlexDirectionValue::Exact(
221        LayoutFlexDirection::Row,
222    ))),
223];
224const CSS_MATCH_1085706216385961159: CssPropertyWithConditionsVec =
225    CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_1085706216385961159_PROPERTIES);
226
227const CSS_MATCH_12498280255863106397_PROPERTIES: &[CssPropertyWithConditions] = &[
228    // .__azul_native-list-header-item:hover
229    CssPropertyWithConditions::on_hover(CssProperty::BorderBottomWidth(
230        LayoutBorderBottomWidthValue::Exact(LayoutBorderBottomWidth {
231            inner: PixelValue::const_px(1),
232        }),
233    )),
234    CssPropertyWithConditions::on_hover(CssProperty::BorderBottomStyle(
235        StyleBorderBottomStyleValue::Exact(StyleBorderBottomStyle {
236            inner: BorderStyle::Solid,
237        }),
238    )),
239    CssPropertyWithConditions::on_hover(CssProperty::BorderBottomColor(
240        StyleBorderBottomColorValue::Exact(StyleBorderBottomColor {
241            inner: ColorU {
242                r: 154,
243                g: 223,
244                b: 254,
245                a: 255,
246            },
247        }),
248    )),
249    CssPropertyWithConditions::on_hover(CssProperty::BackgroundContent(
250        StyleBackgroundContentVecValue::Exact(StyleBackgroundContentVec::from_const_slice(
251            STYLE_BACKGROUND_CONTENT_6112684430356720596_ITEMS,
252        )),
253    )),
254    // .__azul_native-list-header-item:active
255    CssPropertyWithConditions::on_active(CssProperty::BoxShadowBottom(StyleBoxShadowValue::Exact(BoxOrStatic::Static(&
256        StyleBoxShadow {
257            offset_x: PixelValueNoPercent {
258                inner: PixelValue::const_px(0),
259            },
260            offset_y: PixelValueNoPercent {
261                inner: PixelValue::const_px(0),
262            },
263            color: ColorU {
264                r: 206,
265                g: 231,
266                b: 244,
267                a: 255,
268            },
269            blur_radius: PixelValueNoPercent {
270                inner: PixelValue::const_px(5),
271            },
272            spread_radius: PixelValueNoPercent {
273                inner: PixelValue::const_px(0),
274            },
275            clip_mode: BoxShadowClipMode::Inset,
276        },
277    )))),
278    CssPropertyWithConditions::on_active(CssProperty::BoxShadowTop(StyleBoxShadowValue::Exact(BoxOrStatic::Static(&
279        StyleBoxShadow {
280            offset_x: PixelValueNoPercent {
281                inner: PixelValue::const_px(0),
282            },
283            offset_y: PixelValueNoPercent {
284                inner: PixelValue::const_px(0),
285            },
286            color: ColorU {
287                r: 206,
288                g: 231,
289                b: 244,
290                a: 255,
291            },
292            blur_radius: PixelValueNoPercent {
293                inner: PixelValue::const_px(5),
294            },
295            spread_radius: PixelValueNoPercent {
296                inner: PixelValue::const_px(0),
297            },
298            clip_mode: BoxShadowClipMode::Inset,
299        },
300    )))),
301    CssPropertyWithConditions::on_active(CssProperty::BoxShadowRight(StyleBoxShadowValue::Exact(BoxOrStatic::Static(&
302        StyleBoxShadow {
303            offset_x: PixelValueNoPercent {
304                inner: PixelValue::const_px(0),
305            },
306            offset_y: PixelValueNoPercent {
307                inner: PixelValue::const_px(0),
308            },
309            color: ColorU {
310                r: 206,
311                g: 231,
312                b: 244,
313                a: 255,
314            },
315            blur_radius: PixelValueNoPercent {
316                inner: PixelValue::const_px(5),
317            },
318            spread_radius: PixelValueNoPercent {
319                inner: PixelValue::const_px(0),
320            },
321            clip_mode: BoxShadowClipMode::Inset,
322        },
323    )))),
324    CssPropertyWithConditions::on_active(CssProperty::BoxShadowLeft(StyleBoxShadowValue::Exact(BoxOrStatic::Static(&
325        StyleBoxShadow {
326            offset_x: PixelValueNoPercent {
327                inner: PixelValue::const_px(0),
328            },
329            offset_y: PixelValueNoPercent {
330                inner: PixelValue::const_px(0),
331            },
332            color: ColorU {
333                r: 206,
334                g: 231,
335                b: 244,
336                a: 255,
337            },
338            blur_radius: PixelValueNoPercent {
339                inner: PixelValue::const_px(5),
340            },
341            spread_radius: PixelValueNoPercent {
342                inner: PixelValue::const_px(0),
343            },
344            clip_mode: BoxShadowClipMode::Inset,
345        },
346    )))),
347    CssPropertyWithConditions::on_active(CssProperty::BorderBottomWidth(
348        LayoutBorderBottomWidthValue::Exact(LayoutBorderBottomWidth {
349            inner: PixelValue::const_px(1),
350        }),
351    )),
352    CssPropertyWithConditions::on_active(CssProperty::BorderLeftWidth(
353        LayoutBorderLeftWidthValue::Exact(LayoutBorderLeftWidth {
354            inner: PixelValue::const_px(1),
355        }),
356    )),
357    CssPropertyWithConditions::on_active(CssProperty::BorderRightWidth(
358        LayoutBorderRightWidthValue::Exact(LayoutBorderRightWidth {
359            inner: PixelValue::const_px(1),
360        }),
361    )),
362    CssPropertyWithConditions::on_active(CssProperty::BorderTopWidth(
363        LayoutBorderTopWidthValue::Exact(LayoutBorderTopWidth {
364            inner: PixelValue::const_px(1),
365        }),
366    )),
367    CssPropertyWithConditions::on_active(CssProperty::BorderBottomStyle(
368        StyleBorderBottomStyleValue::Exact(StyleBorderBottomStyle {
369            inner: BorderStyle::Solid,
370        }),
371    )),
372    CssPropertyWithConditions::on_active(CssProperty::BorderLeftStyle(
373        StyleBorderLeftStyleValue::Exact(StyleBorderLeftStyle {
374            inner: BorderStyle::Solid,
375        }),
376    )),
377    CssPropertyWithConditions::on_active(CssProperty::BorderRightStyle(
378        StyleBorderRightStyleValue::Exact(StyleBorderRightStyle {
379            inner: BorderStyle::Solid,
380        }),
381    )),
382    CssPropertyWithConditions::on_active(CssProperty::BorderTopStyle(
383        StyleBorderTopStyleValue::Exact(StyleBorderTopStyle {
384            inner: BorderStyle::Solid,
385        }),
386    )),
387    CssPropertyWithConditions::on_active(CssProperty::BorderBottomColor(
388        StyleBorderBottomColorValue::Exact(StyleBorderBottomColor {
389            inner: ColorU {
390                r: 194,
391                g: 205,
392                b: 219,
393                a: 255,
394            },
395        }),
396    )),
397    CssPropertyWithConditions::on_active(CssProperty::BorderLeftColor(
398        StyleBorderLeftColorValue::Exact(StyleBorderLeftColor {
399            inner: ColorU {
400                r: 194,
401                g: 205,
402                b: 219,
403                a: 255,
404            },
405        }),
406    )),
407    CssPropertyWithConditions::on_active(CssProperty::BorderRightColor(
408        StyleBorderRightColorValue::Exact(StyleBorderRightColor {
409            inner: ColorU {
410                r: 194,
411                g: 205,
412                b: 219,
413                a: 255,
414            },
415        }),
416    )),
417    CssPropertyWithConditions::on_active(CssProperty::BorderTopColor(
418        StyleBorderTopColorValue::Exact(StyleBorderTopColor {
419            inner: ColorU {
420                r: 194,
421                g: 205,
422                b: 219,
423                a: 255,
424            },
425        }),
426    )),
427    CssPropertyWithConditions::on_active(CssProperty::BackgroundContent(
428        StyleBackgroundContentVecValue::Exact(StyleBackgroundContentVec::from_const_slice(
429            STYLE_BACKGROUND_CONTENT_3839348353894170136_ITEMS,
430        )),
431    )),
432    // .__azul_native-list-header-item
433    CssPropertyWithConditions::simple(CssProperty::Position(LayoutPositionValue::Exact(
434        LayoutPosition::Relative,
435    ))),
436    CssPropertyWithConditions::simple(CssProperty::PaddingLeft(LayoutPaddingLeftValue::Exact(
437        LayoutPaddingLeft {
438            inner: PixelValue::const_px(7),
439        },
440    ))),
441    CssPropertyWithConditions::simple(CssProperty::MinWidth(LayoutMinWidthValue::Exact(
442        LayoutMinWidth {
443            inner: PixelValue::const_px(100),
444        },
445    ))),
446    CssPropertyWithConditions::simple(CssProperty::FlexDirection(LayoutFlexDirectionValue::Exact(
447        LayoutFlexDirection::Column,
448    ))),
449    CssPropertyWithConditions::simple(CssProperty::BorderRightWidth(
450        LayoutBorderRightWidthValue::Exact(LayoutBorderRightWidth {
451            inner: PixelValue::const_px(1),
452        }),
453    )),
454    CssPropertyWithConditions::simple(CssProperty::BorderRightStyle(
455        StyleBorderRightStyleValue::Exact(StyleBorderRightStyle {
456            inner: BorderStyle::Solid,
457        }),
458    )),
459    CssPropertyWithConditions::simple(CssProperty::BorderRightColor(
460        StyleBorderRightColorValue::Exact(StyleBorderRightColor {
461            inner: ColorU {
462                r: 243,
463                g: 244,
464                b: 246,
465                a: 255,
466            },
467        }),
468    )),
469];
470const CSS_MATCH_12498280255863106397: CssPropertyWithConditionsVec =
471    CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_12498280255863106397_PROPERTIES);
472
473const CSS_MATCH_12980082330151137475_PROPERTIES: &[CssPropertyWithConditions] = &[
474    // .__azul_native-list-rows-row-cell
475    CssPropertyWithConditions::simple(CssProperty::PaddingLeft(LayoutPaddingLeftValue::Exact(
476        LayoutPaddingLeft {
477            inner: PixelValue::const_px(7),
478        },
479    ))),
480    CssPropertyWithConditions::simple(CssProperty::MinWidth(LayoutMinWidthValue::Exact(
481        LayoutMinWidth {
482            inner: PixelValue::const_px(100),
483        },
484    ))),
485    CssPropertyWithConditions::simple(CssProperty::FontSize(StyleFontSizeValue::Exact(
486        StyleFontSize {
487            inner: PixelValue::const_px(11),
488        },
489    ))),
490    CssPropertyWithConditions::simple(CssProperty::FontFamily(StyleFontFamilyVecValue::Exact(
491        StyleFontFamilyVec::from_const_slice(STYLE_FONT_FAMILY_8122988506401935406_ITEMS),
492    ))),
493];
494const CSS_MATCH_12980082330151137475: CssPropertyWithConditionsVec =
495    CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_12980082330151137475_PROPERTIES);
496
497const CSS_MATCH_13758717721055992976_PROPERTIES: &[CssPropertyWithConditions] = &[
498    // .__azul_native-list-header-arrow-down-inner
499    CssPropertyWithConditions::simple(CssProperty::Width(LayoutWidthValue::Exact(
500        LayoutWidth::Px(PixelValue::const_px(6)),
501    ))),
502    CssPropertyWithConditions::simple(CssProperty::Transform(StyleTransformVecValue::Exact(
503        StyleTransformVec::from_const_slice(STYLE_TRANSFORM_16978981723642914576_ITEMS),
504    ))),
505    CssPropertyWithConditions::simple(CssProperty::OverflowY(LayoutOverflowValue::Exact(
506        LayoutOverflow::Hidden,
507    ))),
508    CssPropertyWithConditions::simple(CssProperty::OverflowX(LayoutOverflowValue::Exact(
509        LayoutOverflow::Hidden,
510    ))),
511    CssPropertyWithConditions::simple(CssProperty::Height(LayoutHeightValue::Exact(
512        LayoutHeight::Px(PixelValue::const_px(6)),
513    ))),
514];
515const CSS_MATCH_13758717721055992976: CssPropertyWithConditionsVec =
516    CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_13758717721055992976_PROPERTIES);
517
518const CSS_MATCH_15295293133676720691_PROPERTIES: &[CssPropertyWithConditions] = &[
519    // .__azul_native-list-header-dragwidth-drag
520    CssPropertyWithConditions::simple(CssProperty::Width(LayoutWidthValue::Exact(
521        LayoutWidth::Px(PixelValue::const_px(2)),
522    ))),
523    CssPropertyWithConditions::simple(CssProperty::Position(LayoutPositionValue::Exact(
524        LayoutPosition::Absolute,
525    ))),
526];
527const CSS_MATCH_15295293133676720691: CssPropertyWithConditionsVec =
528    CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_15295293133676720691_PROPERTIES);
529
530const CSS_MATCH_15315949193378715186_PROPERTIES: &[CssPropertyWithConditions] = &[
531    // .__azul_native-list-header
532    CssPropertyWithConditions::simple(CssProperty::Height(LayoutHeightValue::Exact(
533        LayoutHeight::Px(PixelValue::const_px(25)),
534    ))),
535    CssPropertyWithConditions::simple(CssProperty::FlexDirection(LayoutFlexDirectionValue::Exact(
536        LayoutFlexDirection::Row,
537    ))),
538    CssPropertyWithConditions::simple(CssProperty::BackgroundContent(
539        StyleBackgroundContentVecValue::Exact(StyleBackgroundContentVec::from_const_slice(
540            STYLE_BACKGROUND_CONTENT_7422581697888665934_ITEMS,
541        )),
542    )),
543];
544const CSS_MATCH_15315949193378715186: CssPropertyWithConditionsVec =
545    CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_15315949193378715186_PROPERTIES);
546
547const CSS_MATCH_15673486787900743642_PROPERTIES: &[CssPropertyWithConditions] = &[
548    // .__azul_native-list-header .__azul_native-list-header-item p
549    CssPropertyWithConditions::simple(CssProperty::FontSize(StyleFontSizeValue::Exact(
550        StyleFontSize {
551            inner: PixelValue::const_px(11),
552        },
553    ))),
554    CssPropertyWithConditions::simple(CssProperty::FontFamily(StyleFontFamilyVecValue::Exact(
555        StyleFontFamilyVec::from_const_slice(STYLE_FONT_FAMILY_8122988506401935406_ITEMS),
556    ))),
557    CssPropertyWithConditions::simple(CssProperty::FlexGrow(LayoutFlexGrowValue::Exact(
558        LayoutFlexGrow {
559            inner: FloatValue::const_new(1),
560        },
561    ))),
562    CssPropertyWithConditions::simple(CssProperty::FlexDirection(LayoutFlexDirectionValue::Exact(
563        LayoutFlexDirection::Column,
564    ))),
565    CssPropertyWithConditions::simple(CssProperty::TextColor(StyleTextColorValue::Exact(
566        StyleTextColor {
567            inner: ColorU {
568                r: 0,
569                g: 0,
570                b: 0,
571                a: 255,
572            },
573        },
574    ))),
575    CssPropertyWithConditions::simple(CssProperty::AlignItems(LayoutAlignItemsValue::Exact(
576        LayoutAlignItems::Center,
577    ))),
578];
579const CSS_MATCH_15673486787900743642: CssPropertyWithConditionsVec =
580    CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_15673486787900743642_PROPERTIES);
581
582const CSS_MATCH_1574792189506859253_PROPERTIES: &[CssPropertyWithConditions] = &[
583    // .__azul_native-list-header-arrow-down-inner-deco
584    CssPropertyWithConditions::simple(CssProperty::Width(LayoutWidthValue::Exact(
585        LayoutWidth::Px(PixelValue::const_px(12)),
586    ))),
587    CssPropertyWithConditions::simple(CssProperty::Transform(StyleTransformVecValue::Exact(
588        StyleTransformVec::from_const_slice(STYLE_TRANSFORM_17732691695785266054_ITEMS),
589    ))),
590    CssPropertyWithConditions::simple(CssProperty::Height(LayoutHeightValue::Exact(
591        LayoutHeight::Px(PixelValue::const_px(12)),
592    ))),
593    CssPropertyWithConditions::simple(CssProperty::BoxShadowBottom(StyleBoxShadowValue::Exact(BoxOrStatic::Static(&
594        StyleBoxShadow {
595            offset_x: PixelValueNoPercent {
596                inner: PixelValue::const_px(3),
597            },
598            offset_y: PixelValueNoPercent {
599                inner: PixelValue::const_px(3),
600            },
601            color: ColorU {
602                r: 60,
603                g: 94,
604                b: 114,
605                a: 255,
606            },
607            blur_radius: PixelValueNoPercent {
608                inner: PixelValue::const_px(10),
609            },
610            spread_radius: PixelValueNoPercent {
611                inner: PixelValue::const_px(0),
612            },
613            clip_mode: BoxShadowClipMode::Inset,
614        },
615    )))),
616    CssPropertyWithConditions::simple(CssProperty::BoxShadowTop(StyleBoxShadowValue::Exact(BoxOrStatic::Static(&
617        StyleBoxShadow {
618            offset_x: PixelValueNoPercent {
619                inner: PixelValue::const_px(3),
620            },
621            offset_y: PixelValueNoPercent {
622                inner: PixelValue::const_px(3),
623            },
624            color: ColorU {
625                r: 60,
626                g: 94,
627                b: 114,
628                a: 255,
629            },
630            blur_radius: PixelValueNoPercent {
631                inner: PixelValue::const_px(10),
632            },
633            spread_radius: PixelValueNoPercent {
634                inner: PixelValue::const_px(0),
635            },
636            clip_mode: BoxShadowClipMode::Inset,
637        },
638    )))),
639    CssPropertyWithConditions::simple(CssProperty::BoxShadowRight(StyleBoxShadowValue::Exact(BoxOrStatic::Static(&
640        StyleBoxShadow {
641            offset_x: PixelValueNoPercent {
642                inner: PixelValue::const_px(3),
643            },
644            offset_y: PixelValueNoPercent {
645                inner: PixelValue::const_px(3),
646            },
647            color: ColorU {
648                r: 60,
649                g: 94,
650                b: 114,
651                a: 255,
652            },
653            blur_radius: PixelValueNoPercent {
654                inner: PixelValue::const_px(10),
655            },
656            spread_radius: PixelValueNoPercent {
657                inner: PixelValue::const_px(0),
658            },
659            clip_mode: BoxShadowClipMode::Inset,
660        },
661    )))),
662    CssPropertyWithConditions::simple(CssProperty::BoxShadowLeft(StyleBoxShadowValue::Exact(BoxOrStatic::Static(&
663        StyleBoxShadow {
664            offset_x: PixelValueNoPercent {
665                inner: PixelValue::const_px(3),
666            },
667            offset_y: PixelValueNoPercent {
668                inner: PixelValue::const_px(3),
669            },
670            color: ColorU {
671                r: 60,
672                g: 94,
673                b: 114,
674                a: 255,
675            },
676            blur_radius: PixelValueNoPercent {
677                inner: PixelValue::const_px(10),
678            },
679            spread_radius: PixelValueNoPercent {
680                inner: PixelValue::const_px(0),
681            },
682            clip_mode: BoxShadowClipMode::Inset,
683        },
684    )))),
685];
686const CSS_MATCH_1574792189506859253: CssPropertyWithConditionsVec =
687    CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_1574792189506859253_PROPERTIES);
688
689const CSS_MATCH_17553577885456905601_PROPERTIES: &[CssPropertyWithConditions] = &[
690    // .__azul_native_list-container
691    CssPropertyWithConditions::simple(CssProperty::FlexGrow(LayoutFlexGrowValue::Exact(
692        LayoutFlexGrow {
693            inner: FloatValue::const_new(1),
694        },
695    ))),
696    CssPropertyWithConditions::simple(CssProperty::BackgroundContent(
697        StyleBackgroundContentVecValue::Exact(StyleBackgroundContentVec::from_const_slice(
698            STYLE_BACKGROUND_CONTENT_2444935983575427872_ITEMS,
699        )),
700    )),
701];
702const CSS_MATCH_17553577885456905601: CssPropertyWithConditionsVec =
703    CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_17553577885456905601_PROPERTIES);
704
705const CSS_MATCH_2883986488332352590_PROPERTIES: &[CssPropertyWithConditions] = &[
706    // body
707    CssPropertyWithConditions::simple(CssProperty::PaddingRight(LayoutPaddingRightValue::Exact(
708        LayoutPaddingRight {
709            inner: PixelValue::const_px(5),
710        },
711    ))),
712    CssPropertyWithConditions::simple(CssProperty::PaddingLeft(LayoutPaddingLeftValue::Exact(
713        LayoutPaddingLeft {
714            inner: PixelValue::const_px(5),
715        },
716    ))),
717    CssPropertyWithConditions::simple(CssProperty::PaddingBottom(LayoutPaddingBottomValue::Exact(
718        LayoutPaddingBottom {
719            inner: PixelValue::const_px(5),
720        },
721    ))),
722    CssPropertyWithConditions::simple(CssProperty::PaddingTop(LayoutPaddingTopValue::Exact(
723        LayoutPaddingTop {
724            inner: PixelValue::const_px(5),
725        },
726    ))),
727    CssPropertyWithConditions::simple(CssProperty::BackgroundContent(
728        StyleBackgroundContentVecValue::Exact(StyleBackgroundContentVec::from_const_slice(
729            STYLE_BACKGROUND_CONTENT_11062356617965867290_ITEMS,
730        )),
731    )),
732];
733const CSS_MATCH_2883986488332352590: CssPropertyWithConditionsVec =
734    CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_2883986488332352590_PROPERTIES);
735
736const CSS_MATCH_4852927511892172364_PROPERTIES: &[CssPropertyWithConditions] = &[
737    // .__azul_native-list-rows
738    CssPropertyWithConditions::simple(CssProperty::FlexDirection(LayoutFlexDirectionValue::Exact(
739        LayoutFlexDirection::Column,
740    ))),
741];
742const CSS_MATCH_4852927511892172364: CssPropertyWithConditionsVec =
743    CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_4852927511892172364_PROPERTIES);
744
745const CSS_MATCH_6002662151290653203_PROPERTIES: &[CssPropertyWithConditions] = &[
746    // .__azul_native-list-header-dragwidth
747    CssPropertyWithConditions::simple(CssProperty::Width(LayoutWidthValue::Exact(
748        LayoutWidth::Px(PixelValue::const_px(0)),
749    ))),
750    CssPropertyWithConditions::simple(CssProperty::Position(LayoutPositionValue::Exact(
751        LayoutPosition::Relative,
752    ))),
753    CssPropertyWithConditions::simple(CssProperty::FlexGrow(LayoutFlexGrowValue::Exact(
754        LayoutFlexGrow {
755            inner: FloatValue::const_new(1),
756        },
757    ))),
758];
759const CSS_MATCH_6002662151290653203: CssPropertyWithConditionsVec =
760    CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_6002662151290653203_PROPERTIES);
761
762const CSS_MATCH_6827198030119836081_PROPERTIES: &[CssPropertyWithConditions] = &[
763    // .__azul_native-list-rows-row.selected
764    CssPropertyWithConditions::simple(CssProperty::BorderBottomWidth(
765        LayoutBorderBottomWidthValue::Exact(LayoutBorderBottomWidth {
766            inner: PixelValue::const_px(1),
767        }),
768    )),
769    CssPropertyWithConditions::simple(CssProperty::BorderLeftWidth(
770        LayoutBorderLeftWidthValue::Exact(LayoutBorderLeftWidth {
771            inner: PixelValue::const_px(1),
772        }),
773    )),
774    CssPropertyWithConditions::simple(CssProperty::BorderRightWidth(
775        LayoutBorderRightWidthValue::Exact(LayoutBorderRightWidth {
776            inner: PixelValue::const_px(1),
777        }),
778    )),
779    CssPropertyWithConditions::simple(CssProperty::BorderTopWidth(
780        LayoutBorderTopWidthValue::Exact(LayoutBorderTopWidth {
781            inner: PixelValue::const_px(1),
782        }),
783    )),
784    CssPropertyWithConditions::simple(CssProperty::BorderBottomStyle(
785        StyleBorderBottomStyleValue::Exact(StyleBorderBottomStyle {
786            inner: BorderStyle::Solid,
787        }),
788    )),
789    CssPropertyWithConditions::simple(CssProperty::BorderLeftStyle(
790        StyleBorderLeftStyleValue::Exact(StyleBorderLeftStyle {
791            inner: BorderStyle::Solid,
792        }),
793    )),
794    CssPropertyWithConditions::simple(CssProperty::BorderRightStyle(
795        StyleBorderRightStyleValue::Exact(StyleBorderRightStyle {
796            inner: BorderStyle::Solid,
797        }),
798    )),
799    CssPropertyWithConditions::simple(CssProperty::BorderTopStyle(
800        StyleBorderTopStyleValue::Exact(StyleBorderTopStyle {
801            inner: BorderStyle::Solid,
802        }),
803    )),
804    CssPropertyWithConditions::simple(CssProperty::BorderBottomColor(
805        StyleBorderBottomColorValue::Exact(StyleBorderBottomColor {
806            inner: ColorU {
807                r: 102,
808                g: 167,
809                b: 232,
810                a: 255,
811            },
812        }),
813    )),
814    CssPropertyWithConditions::simple(CssProperty::BorderLeftColor(
815        StyleBorderLeftColorValue::Exact(StyleBorderLeftColor {
816            inner: ColorU {
817                r: 102,
818                g: 167,
819                b: 232,
820                a: 255,
821            },
822        }),
823    )),
824    CssPropertyWithConditions::simple(CssProperty::BorderRightColor(
825        StyleBorderRightColorValue::Exact(StyleBorderRightColor {
826            inner: ColorU {
827                r: 102,
828                g: 167,
829                b: 232,
830                a: 255,
831            },
832        }),
833    )),
834    CssPropertyWithConditions::simple(CssProperty::BorderTopColor(
835        StyleBorderTopColorValue::Exact(StyleBorderTopColor {
836            inner: ColorU {
837                r: 102,
838                g: 167,
839                b: 232,
840                a: 255,
841            },
842        }),
843    )),
844    CssPropertyWithConditions::simple(CssProperty::BackgroundContent(
845        StyleBackgroundContentVecValue::Exact(StyleBackgroundContentVec::from_const_slice(
846            STYLE_BACKGROUND_CONTENT_661302523448178568_ITEMS,
847        )),
848    )),
849    // .__azul_native-list-rows-row:hover
850    CssPropertyWithConditions::on_hover(CssProperty::BorderBottomWidth(
851        LayoutBorderBottomWidthValue::Exact(LayoutBorderBottomWidth {
852            inner: PixelValue::const_px(1),
853        }),
854    )),
855    CssPropertyWithConditions::on_hover(CssProperty::BorderLeftWidth(
856        LayoutBorderLeftWidthValue::Exact(LayoutBorderLeftWidth {
857            inner: PixelValue::const_px(1),
858        }),
859    )),
860    CssPropertyWithConditions::on_hover(CssProperty::BorderRightWidth(
861        LayoutBorderRightWidthValue::Exact(LayoutBorderRightWidth {
862            inner: PixelValue::const_px(1),
863        }),
864    )),
865    CssPropertyWithConditions::on_hover(CssProperty::BorderTopWidth(
866        LayoutBorderTopWidthValue::Exact(LayoutBorderTopWidth {
867            inner: PixelValue::const_px(1),
868        }),
869    )),
870    CssPropertyWithConditions::on_hover(CssProperty::BorderBottomStyle(
871        StyleBorderBottomStyleValue::Exact(StyleBorderBottomStyle {
872            inner: BorderStyle::Solid,
873        }),
874    )),
875    CssPropertyWithConditions::on_hover(CssProperty::BorderLeftStyle(
876        StyleBorderLeftStyleValue::Exact(StyleBorderLeftStyle {
877            inner: BorderStyle::Solid,
878        }),
879    )),
880    CssPropertyWithConditions::on_hover(CssProperty::BorderRightStyle(
881        StyleBorderRightStyleValue::Exact(StyleBorderRightStyle {
882            inner: BorderStyle::Solid,
883        }),
884    )),
885    CssPropertyWithConditions::on_hover(CssProperty::BorderTopStyle(
886        StyleBorderTopStyleValue::Exact(StyleBorderTopStyle {
887            inner: BorderStyle::Solid,
888        }),
889    )),
890    CssPropertyWithConditions::on_hover(CssProperty::BorderBottomColor(
891        StyleBorderBottomColorValue::Exact(StyleBorderBottomColor {
892            inner: ColorU {
893                r: 101,
894                g: 181,
895                b: 220,
896                a: 255,
897            },
898        }),
899    )),
900    CssPropertyWithConditions::on_hover(CssProperty::BorderLeftColor(
901        StyleBorderLeftColorValue::Exact(StyleBorderLeftColor {
902            inner: ColorU {
903                r: 101,
904                g: 181,
905                b: 220,
906                a: 255,
907            },
908        }),
909    )),
910    CssPropertyWithConditions::on_hover(CssProperty::BorderRightColor(
911        StyleBorderRightColorValue::Exact(StyleBorderRightColor {
912            inner: ColorU {
913                r: 101,
914                g: 181,
915                b: 220,
916                a: 255,
917            },
918        }),
919    )),
920    CssPropertyWithConditions::on_hover(CssProperty::BorderTopColor(
921        StyleBorderTopColorValue::Exact(StyleBorderTopColor {
922            inner: ColorU {
923                r: 101,
924                g: 181,
925                b: 220,
926                a: 255,
927            },
928        }),
929    )),
930    CssPropertyWithConditions::on_hover(CssProperty::BackgroundContent(
931        StyleBackgroundContentVecValue::Exact(StyleBackgroundContentVec::from_const_slice(
932            STYLE_BACKGROUND_CONTENT_3010057533077499049_ITEMS,
933        )),
934    )),
935    // .__azul_native-list-rows-row
936    CssPropertyWithConditions::simple(CssProperty::PaddingRight(LayoutPaddingRightValue::Exact(
937        LayoutPaddingRight {
938            inner: PixelValue::const_px(0),
939        },
940    ))),
941    CssPropertyWithConditions::simple(CssProperty::PaddingLeft(LayoutPaddingLeftValue::Exact(
942        LayoutPaddingLeft {
943            inner: PixelValue::const_px(0),
944        },
945    ))),
946    CssPropertyWithConditions::simple(CssProperty::PaddingBottom(LayoutPaddingBottomValue::Exact(
947        LayoutPaddingBottom {
948            inner: PixelValue::const_px(2),
949        },
950    ))),
951    CssPropertyWithConditions::simple(CssProperty::PaddingTop(LayoutPaddingTopValue::Exact(
952        LayoutPaddingTop {
953            inner: PixelValue::const_px(2),
954        },
955    ))),
956    CssPropertyWithConditions::simple(CssProperty::FlexGrow(LayoutFlexGrowValue::Exact(
957        LayoutFlexGrow {
958            inner: FloatValue::const_new(1),
959        },
960    ))),
961    CssPropertyWithConditions::simple(CssProperty::FlexDirection(LayoutFlexDirectionValue::Exact(
962        LayoutFlexDirection::Row,
963    ))),
964    CssPropertyWithConditions::simple(CssProperty::BorderBottomWidth(
965        LayoutBorderBottomWidthValue::Exact(LayoutBorderBottomWidth {
966            inner: PixelValue::const_px(1),
967        }),
968    )),
969    CssPropertyWithConditions::simple(CssProperty::BorderLeftWidth(
970        LayoutBorderLeftWidthValue::Exact(LayoutBorderLeftWidth {
971            inner: PixelValue::const_px(1),
972        }),
973    )),
974    CssPropertyWithConditions::simple(CssProperty::BorderRightWidth(
975        LayoutBorderRightWidthValue::Exact(LayoutBorderRightWidth {
976            inner: PixelValue::const_px(1),
977        }),
978    )),
979    CssPropertyWithConditions::simple(CssProperty::BorderTopWidth(
980        LayoutBorderTopWidthValue::Exact(LayoutBorderTopWidth {
981            inner: PixelValue::const_px(1),
982        }),
983    )),
984    CssPropertyWithConditions::simple(CssProperty::BorderBottomStyle(
985        StyleBorderBottomStyleValue::Exact(StyleBorderBottomStyle {
986            inner: BorderStyle::Solid,
987        }),
988    )),
989    CssPropertyWithConditions::simple(CssProperty::BorderLeftStyle(
990        StyleBorderLeftStyleValue::Exact(StyleBorderLeftStyle {
991            inner: BorderStyle::Solid,
992        }),
993    )),
994    CssPropertyWithConditions::simple(CssProperty::BorderRightStyle(
995        StyleBorderRightStyleValue::Exact(StyleBorderRightStyle {
996            inner: BorderStyle::Solid,
997        }),
998    )),
999    CssPropertyWithConditions::simple(CssProperty::BorderTopStyle(
1000        StyleBorderTopStyleValue::Exact(StyleBorderTopStyle {
1001            inner: BorderStyle::Solid,
1002        }),
1003    )),
1004    CssPropertyWithConditions::simple(CssProperty::BorderBottomColor(
1005        StyleBorderBottomColorValue::Exact(StyleBorderBottomColor {
1006            inner: ColorU {
1007                r: 255,
1008                g: 255,
1009                b: 255,
1010                a: 0,
1011            },
1012        }),
1013    )),
1014    CssPropertyWithConditions::simple(CssProperty::BorderLeftColor(
1015        StyleBorderLeftColorValue::Exact(StyleBorderLeftColor {
1016            inner: ColorU {
1017                r: 255,
1018                g: 255,
1019                b: 255,
1020                a: 0,
1021            },
1022        }),
1023    )),
1024    CssPropertyWithConditions::simple(CssProperty::BorderRightColor(
1025        StyleBorderRightColorValue::Exact(StyleBorderRightColor {
1026            inner: ColorU {
1027                r: 255,
1028                g: 255,
1029                b: 255,
1030                a: 0,
1031            },
1032        }),
1033    )),
1034    CssPropertyWithConditions::simple(CssProperty::BorderTopColor(
1035        StyleBorderTopColorValue::Exact(StyleBorderTopColor {
1036            inner: ColorU {
1037                r: 255,
1038                g: 255,
1039                b: 255,
1040                a: 0,
1041            },
1042        }),
1043    )),
1044];
1045const CSS_MATCH_6827198030119836081: CssPropertyWithConditionsVec =
1046    CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_6827198030119836081_PROPERTIES);
1047
1048const CSS_MATCH_7894335449545988724_PROPERTIES: &[CssPropertyWithConditions] = &[
1049    // .__azul_native-list-rows-row.focused
1050    CssPropertyWithConditions::on_focus(CssProperty::BorderBottomWidth(
1051        LayoutBorderBottomWidthValue::Exact(LayoutBorderBottomWidth {
1052            inner: PixelValue::const_px(1),
1053        }),
1054    )),
1055    CssPropertyWithConditions::on_focus(CssProperty::BorderLeftWidth(
1056        LayoutBorderLeftWidthValue::Exact(LayoutBorderLeftWidth {
1057            inner: PixelValue::const_px(1),
1058        }),
1059    )),
1060    CssPropertyWithConditions::on_focus(CssProperty::BorderRightWidth(
1061        LayoutBorderRightWidthValue::Exact(LayoutBorderRightWidth {
1062            inner: PixelValue::const_px(1),
1063        }),
1064    )),
1065    CssPropertyWithConditions::on_focus(CssProperty::BorderTopWidth(
1066        LayoutBorderTopWidthValue::Exact(LayoutBorderTopWidth {
1067            inner: PixelValue::const_px(1),
1068        }),
1069    )),
1070    CssPropertyWithConditions::on_focus(CssProperty::BorderBottomStyle(
1071        StyleBorderBottomStyleValue::Exact(StyleBorderBottomStyle {
1072            inner: BorderStyle::Solid,
1073        }),
1074    )),
1075    CssPropertyWithConditions::on_focus(CssProperty::BorderLeftStyle(
1076        StyleBorderLeftStyleValue::Exact(StyleBorderLeftStyle {
1077            inner: BorderStyle::Solid,
1078        }),
1079    )),
1080    CssPropertyWithConditions::on_focus(CssProperty::BorderRightStyle(
1081        StyleBorderRightStyleValue::Exact(StyleBorderRightStyle {
1082            inner: BorderStyle::Solid,
1083        }),
1084    )),
1085    CssPropertyWithConditions::on_focus(CssProperty::BorderTopStyle(
1086        StyleBorderTopStyleValue::Exact(StyleBorderTopStyle {
1087            inner: BorderStyle::Solid,
1088        }),
1089    )),
1090    CssPropertyWithConditions::on_focus(CssProperty::BorderBottomColor(
1091        StyleBorderBottomColorValue::Exact(StyleBorderBottomColor {
1092            inner: ColorU {
1093                r: 38,
1094                g: 160,
1095                b: 218,
1096                a: 255,
1097            },
1098        }),
1099    )),
1100    CssPropertyWithConditions::on_focus(CssProperty::BorderLeftColor(
1101        StyleBorderLeftColorValue::Exact(StyleBorderLeftColor {
1102            inner: ColorU {
1103                r: 38,
1104                g: 160,
1105                b: 218,
1106                a: 255,
1107            },
1108        }),
1109    )),
1110    CssPropertyWithConditions::on_focus(CssProperty::BorderRightColor(
1111        StyleBorderRightColorValue::Exact(StyleBorderRightColor {
1112            inner: ColorU {
1113                r: 38,
1114                g: 160,
1115                b: 218,
1116                a: 255,
1117            },
1118        }),
1119    )),
1120    CssPropertyWithConditions::on_focus(CssProperty::BorderTopColor(
1121        StyleBorderTopColorValue::Exact(StyleBorderTopColor {
1122            inner: ColorU {
1123                r: 38,
1124                g: 160,
1125                b: 218,
1126                a: 255,
1127            },
1128        }),
1129    )),
1130    CssPropertyWithConditions::on_focus(CssProperty::BackgroundContent(
1131        StyleBackgroundContentVecValue::Exact(StyleBackgroundContentVec::from_const_slice(
1132            STYLE_BACKGROUND_CONTENT_11098930083828139815_ITEMS,
1133        )),
1134    )),
1135    // .__azul_native-list-rows-row:hover
1136    CssPropertyWithConditions::on_hover(CssProperty::BorderBottomWidth(
1137        LayoutBorderBottomWidthValue::Exact(LayoutBorderBottomWidth {
1138            inner: PixelValue::const_px(1),
1139        }),
1140    )),
1141    CssPropertyWithConditions::on_hover(CssProperty::BorderLeftWidth(
1142        LayoutBorderLeftWidthValue::Exact(LayoutBorderLeftWidth {
1143            inner: PixelValue::const_px(1),
1144        }),
1145    )),
1146    CssPropertyWithConditions::on_hover(CssProperty::BorderRightWidth(
1147        LayoutBorderRightWidthValue::Exact(LayoutBorderRightWidth {
1148            inner: PixelValue::const_px(1),
1149        }),
1150    )),
1151    CssPropertyWithConditions::on_hover(CssProperty::BorderTopWidth(
1152        LayoutBorderTopWidthValue::Exact(LayoutBorderTopWidth {
1153            inner: PixelValue::const_px(1),
1154        }),
1155    )),
1156    CssPropertyWithConditions::on_hover(CssProperty::BorderBottomStyle(
1157        StyleBorderBottomStyleValue::Exact(StyleBorderBottomStyle {
1158            inner: BorderStyle::Solid,
1159        }),
1160    )),
1161    CssPropertyWithConditions::on_hover(CssProperty::BorderLeftStyle(
1162        StyleBorderLeftStyleValue::Exact(StyleBorderLeftStyle {
1163            inner: BorderStyle::Solid,
1164        }),
1165    )),
1166    CssPropertyWithConditions::on_hover(CssProperty::BorderRightStyle(
1167        StyleBorderRightStyleValue::Exact(StyleBorderRightStyle {
1168            inner: BorderStyle::Solid,
1169        }),
1170    )),
1171    CssPropertyWithConditions::on_hover(CssProperty::BorderTopStyle(
1172        StyleBorderTopStyleValue::Exact(StyleBorderTopStyle {
1173            inner: BorderStyle::Solid,
1174        }),
1175    )),
1176    CssPropertyWithConditions::on_hover(CssProperty::BorderBottomColor(
1177        StyleBorderBottomColorValue::Exact(StyleBorderBottomColor {
1178            inner: ColorU {
1179                r: 101,
1180                g: 181,
1181                b: 220,
1182                a: 255,
1183            },
1184        }),
1185    )),
1186    CssPropertyWithConditions::on_hover(CssProperty::BorderLeftColor(
1187        StyleBorderLeftColorValue::Exact(StyleBorderLeftColor {
1188            inner: ColorU {
1189                r: 101,
1190                g: 181,
1191                b: 220,
1192                a: 255,
1193            },
1194        }),
1195    )),
1196    CssPropertyWithConditions::on_hover(CssProperty::BorderRightColor(
1197        StyleBorderRightColorValue::Exact(StyleBorderRightColor {
1198            inner: ColorU {
1199                r: 101,
1200                g: 181,
1201                b: 220,
1202                a: 255,
1203            },
1204        }),
1205    )),
1206    CssPropertyWithConditions::on_hover(CssProperty::BorderTopColor(
1207        StyleBorderTopColorValue::Exact(StyleBorderTopColor {
1208            inner: ColorU {
1209                r: 101,
1210                g: 181,
1211                b: 220,
1212                a: 255,
1213            },
1214        }),
1215    )),
1216    CssPropertyWithConditions::on_hover(CssProperty::BackgroundContent(
1217        StyleBackgroundContentVecValue::Exact(StyleBackgroundContentVec::from_const_slice(
1218            STYLE_BACKGROUND_CONTENT_3010057533077499049_ITEMS,
1219        )),
1220    )),
1221    // .__azul_native-list-rows-row
1222    CssPropertyWithConditions::simple(CssProperty::PaddingRight(LayoutPaddingRightValue::Exact(
1223        LayoutPaddingRight {
1224            inner: PixelValue::const_px(0),
1225        },
1226    ))),
1227    CssPropertyWithConditions::simple(CssProperty::PaddingLeft(LayoutPaddingLeftValue::Exact(
1228        LayoutPaddingLeft {
1229            inner: PixelValue::const_px(0),
1230        },
1231    ))),
1232    CssPropertyWithConditions::simple(CssProperty::PaddingBottom(LayoutPaddingBottomValue::Exact(
1233        LayoutPaddingBottom {
1234            inner: PixelValue::const_px(2),
1235        },
1236    ))),
1237    CssPropertyWithConditions::simple(CssProperty::PaddingTop(LayoutPaddingTopValue::Exact(
1238        LayoutPaddingTop {
1239            inner: PixelValue::const_px(2),
1240        },
1241    ))),
1242    CssPropertyWithConditions::simple(CssProperty::FlexGrow(LayoutFlexGrowValue::Exact(
1243        LayoutFlexGrow {
1244            inner: FloatValue::const_new(1),
1245        },
1246    ))),
1247    CssPropertyWithConditions::simple(CssProperty::FlexDirection(LayoutFlexDirectionValue::Exact(
1248        LayoutFlexDirection::Row,
1249    ))),
1250    CssPropertyWithConditions::simple(CssProperty::BorderBottomWidth(
1251        LayoutBorderBottomWidthValue::Exact(LayoutBorderBottomWidth {
1252            inner: PixelValue::const_px(1),
1253        }),
1254    )),
1255    CssPropertyWithConditions::simple(CssProperty::BorderLeftWidth(
1256        LayoutBorderLeftWidthValue::Exact(LayoutBorderLeftWidth {
1257            inner: PixelValue::const_px(1),
1258        }),
1259    )),
1260    CssPropertyWithConditions::simple(CssProperty::BorderRightWidth(
1261        LayoutBorderRightWidthValue::Exact(LayoutBorderRightWidth {
1262            inner: PixelValue::const_px(1),
1263        }),
1264    )),
1265    CssPropertyWithConditions::simple(CssProperty::BorderTopWidth(
1266        LayoutBorderTopWidthValue::Exact(LayoutBorderTopWidth {
1267            inner: PixelValue::const_px(1),
1268        }),
1269    )),
1270    CssPropertyWithConditions::simple(CssProperty::BorderBottomStyle(
1271        StyleBorderBottomStyleValue::Exact(StyleBorderBottomStyle {
1272            inner: BorderStyle::Solid,
1273        }),
1274    )),
1275    CssPropertyWithConditions::simple(CssProperty::BorderLeftStyle(
1276        StyleBorderLeftStyleValue::Exact(StyleBorderLeftStyle {
1277            inner: BorderStyle::Solid,
1278        }),
1279    )),
1280    CssPropertyWithConditions::simple(CssProperty::BorderRightStyle(
1281        StyleBorderRightStyleValue::Exact(StyleBorderRightStyle {
1282            inner: BorderStyle::Solid,
1283        }),
1284    )),
1285    CssPropertyWithConditions::simple(CssProperty::BorderTopStyle(
1286        StyleBorderTopStyleValue::Exact(StyleBorderTopStyle {
1287            inner: BorderStyle::Solid,
1288        }),
1289    )),
1290    CssPropertyWithConditions::simple(CssProperty::BorderBottomColor(
1291        StyleBorderBottomColorValue::Exact(StyleBorderBottomColor {
1292            inner: ColorU {
1293                r: 255,
1294                g: 255,
1295                b: 255,
1296                a: 0,
1297            },
1298        }),
1299    )),
1300    CssPropertyWithConditions::simple(CssProperty::BorderLeftColor(
1301        StyleBorderLeftColorValue::Exact(StyleBorderLeftColor {
1302            inner: ColorU {
1303                r: 255,
1304                g: 255,
1305                b: 255,
1306                a: 0,
1307            },
1308        }),
1309    )),
1310    CssPropertyWithConditions::simple(CssProperty::BorderRightColor(
1311        StyleBorderRightColorValue::Exact(StyleBorderRightColor {
1312            inner: ColorU {
1313                r: 255,
1314                g: 255,
1315                b: 255,
1316                a: 0,
1317            },
1318        }),
1319    )),
1320    CssPropertyWithConditions::simple(CssProperty::BorderTopColor(
1321        StyleBorderTopColorValue::Exact(StyleBorderTopColor {
1322            inner: ColorU {
1323                r: 255,
1324                g: 255,
1325                b: 255,
1326                a: 0,
1327            },
1328        }),
1329    )),
1330];
1331const CSS_MATCH_7894335449545988724: CssPropertyWithConditionsVec =
1332    CssPropertyWithConditionsVec::from_const_slice(CSS_MATCH_7894335449545988724_PROPERTIES);
1333
1334const IDS_AND_CLASSES_790316832563530605: &[IdOrClass] = &[Class(AzString::from_const_str(
1335    "__azul_native-list-rows-row",
1336))];
1337const ROW_CLASS: IdOrClassVec = IdOrClassVec::from_const_slice(IDS_AND_CLASSES_790316832563530605);
1338
1339const IDS_AND_CLASSES_3034181810805097699: &[IdOrClass] = &[Class(AzString::from_const_str(
1340    "__azul_native-list-rows-row-cell",
1341))];
1342const CELL_CLASS: IdOrClassVec =
1343    IdOrClassVec::from_const_slice(IDS_AND_CLASSES_3034181810805097699);
1344
1345const IDS_AND_CLASSES_6012478019077291002: &[IdOrClass] =
1346    &[Class(AzString::from_const_str("__azul_native-list-rows"))];
1347const ROW_CONTAINER_CLASS: IdOrClassVec =
1348    IdOrClassVec::from_const_slice(IDS_AND_CLASSES_6012478019077291002);
1349
1350const IDS_AND_CLASSES_10742579426112804392: &[IdOrClass] =
1351    &[Class(AzString::from_const_str("__azul_native-list-header"))];
1352const HEADER_CONTAINER_CLASS: IdOrClassVec =
1353    IdOrClassVec::from_const_slice(IDS_AND_CLASSES_10742579426112804392);
1354
1355const IDS_AND_CLASSES_9205819539370539587: &[IdOrClass] = &[Class(AzString::from_const_str(
1356    "__azul_native_list-container",
1357))];
1358const LIST_VIEW_CONTAINER_CLASS: IdOrClassVec =
1359    IdOrClassVec::from_const_slice(IDS_AND_CLASSES_9205819539370539587);
1360
1361const IDS_AND_CLASSES_18330792117162403422: &[IdOrClass] = &[Class(AzString::from_const_str(
1362    "__azul_native-list-header-item",
1363))];
1364const COLUMN_NAME_CLASS: IdOrClassVec =
1365    IdOrClassVec::from_const_slice(IDS_AND_CLASSES_18330792117162403422);
1366
1367pub type ListViewOnLazyLoadScrollCallbackType =
1368    extern "C" fn(RefAny, CallbackInfo, ListViewState) -> Update;
1369impl_widget_callback!(
1370    ListViewOnLazyLoadScroll,
1371    OptionListViewOnLazyLoadScroll,
1372    ListViewOnLazyLoadScrollCallback,
1373    ListViewOnLazyLoadScrollCallbackType
1374);
1375
1376azul_core::impl_managed_callback! {
1377    wrapper:        ListViewOnLazyLoadScrollCallback,
1378    info_ty:        CallbackInfo,
1379    return_ty:      Update,
1380    default_ret:    Update::DoNothing,
1381    invoker_static: LIST_VIEW_ON_LAZY_LOAD_SCROLL_INVOKER,
1382    invoker_ty:     AzListViewOnLazyLoadScrollCallbackInvoker,
1383    thunk_fn:       az_list_view_on_lazy_load_scroll_callback_thunk,
1384    setter_fn:      AzApp_setListViewOnLazyLoadScrollCallbackInvoker,
1385    from_handle_fn: AzListViewOnLazyLoadScrollCallback_createFromHostHandle,
1386    extra_args:     [ state: ListViewState ],
1387}
1388
1389pub type ListViewOnColumnClickCallbackType =
1390    extern "C" fn(RefAny, CallbackInfo, ListViewState, column_clicked: usize) -> Update;
1391impl_widget_callback!(
1392    ListViewOnColumnClick,
1393    OptionListViewOnColumnClick,
1394    ListViewOnColumnClickCallback,
1395    ListViewOnColumnClickCallbackType
1396);
1397
1398azul_core::impl_managed_callback! {
1399    wrapper:        ListViewOnColumnClickCallback,
1400    info_ty:        CallbackInfo,
1401    return_ty:      Update,
1402    default_ret:    Update::DoNothing,
1403    invoker_static: LIST_VIEW_ON_COLUMN_CLICK_INVOKER,
1404    invoker_ty:     AzListViewOnColumnClickCallbackInvoker,
1405    thunk_fn:       az_list_view_on_column_click_callback_thunk,
1406    setter_fn:      AzApp_setListViewOnColumnClickCallbackInvoker,
1407    from_handle_fn: AzListViewOnColumnClickCallback_createFromHostHandle,
1408    extra_args:     [ state: ListViewState, column_clicked: usize ],
1409}
1410
1411pub type ListViewOnRowClickCallbackType =
1412    extern "C" fn(RefAny, CallbackInfo, ListViewState, row_clicked: usize) -> Update;
1413impl_widget_callback!(
1414    ListViewOnRowClick,
1415    OptionListViewOnRowClick,
1416    ListViewOnRowClickCallback,
1417    ListViewOnRowClickCallbackType
1418);
1419
1420azul_core::impl_managed_callback! {
1421    wrapper:        ListViewOnRowClickCallback,
1422    info_ty:        CallbackInfo,
1423    return_ty:      Update,
1424    default_ret:    Update::DoNothing,
1425    invoker_static: LIST_VIEW_ON_ROW_CLICK_INVOKER,
1426    invoker_ty:     AzListViewOnRowClickCallbackInvoker,
1427    thunk_fn:       az_list_view_on_row_click_callback_thunk,
1428    setter_fn:      AzApp_setListViewOnRowClickCallbackInvoker,
1429    from_handle_fn: AzListViewOnRowClickCallback_createFromHostHandle,
1430    extra_args:     [ state: ListViewState, row_clicked: usize ],
1431}
1432
1433/// State of the `ListView`, but without row data
1434#[derive(Debug, Clone)]
1435#[repr(C)]
1436pub struct ListViewState {
1437    /// Copy of the current column names
1438    pub columns: StringVec,
1439    /// Which column the rows are currently sorted by
1440    pub sorted_by: OptionUsize,
1441    /// Row count of rows currently loaded in the DOM
1442    pub current_row_count: usize,
1443    /// Y-offset currently applied to the rows
1444    pub scroll_offset: PixelValueNoPercent,
1445    /// Current position where the user has scrolled the `ListView` to
1446    pub current_scroll_position: LogicalPosition,
1447    /// Current height of the row container
1448    pub current_content_height: LogicalSize,
1449}
1450
1451/// List view, optionally able to lazy-load data
1452#[derive(Debug, Clone)]
1453#[repr(C)]
1454pub struct ListView {
1455    /// Column names
1456    pub columns: StringVec,
1457    /// Currently rendered rows. Note that the `ListView` does not
1458    /// have to render all rows at once, usually you'd only render
1459    /// the top 100 rows
1460    pub rows: ListViewRowVec,
1461    /// Which column is the list view sorted by (default = None)?
1462    pub sorted_by: OptionUsize,
1463    /// Offset to add to the rows used when layouting row positions
1464    /// during lazy-loaded scrolling. Also affects the scroll position
1465    pub scroll_offset: PixelValueNoPercent,
1466    /// Height of the content, if not all rows are loaded
1467    pub content_height: OptionPixelValueNoPercent,
1468    /// Context menu for the columns (usually opens a context menu
1469    /// to select which columns to show)
1470    pub column_context_menu: OptionMenu,
1471    /// Indicates that this `ListView` is being lazily loaded, allows
1472    /// control over what happens when the user scrolls the `ListView`.
1473    pub on_lazy_load_scroll: OptionListViewOnLazyLoadScroll,
1474    /// What to do when the user left-clicks the column
1475    /// (usually used for storing which column to sort by)
1476    pub on_column_click: OptionListViewOnColumnClick,
1477    /// What to do when the user left-clicks a row
1478    /// (usually used for selecting the row depending on the state)
1479    pub on_row_click: OptionListViewOnRowClick,
1480}
1481
1482impl Default for ListView {
1483    fn default() -> Self {
1484        Self {
1485            columns: StringVec::from_const_slice(&[]),
1486            rows: ListViewRowVec::from_const_slice(&[]),
1487            sorted_by: None.into(),
1488            scroll_offset: PixelValueNoPercent {
1489                inner: PixelValue::const_px(0),
1490            },
1491            content_height: None.into(),
1492            column_context_menu: None.into(),
1493            on_lazy_load_scroll: None.into(),
1494            on_column_click: None.into(),
1495            on_row_click: None.into(),
1496        }
1497    }
1498}
1499
1500/// Row of the `ListView`
1501#[derive(Debug, Clone)]
1502#[repr(C)]
1503pub struct ListViewRow {
1504    /// Each cell is an opaque Dom object
1505    pub cells: DomVec,
1506    /// Height of the row, if known beforehand
1507    pub height: OptionPixelValueNoPercent,
1508}
1509
1510impl_option!(ListViewRow, OptionListViewRow, copy = false, [Debug, Clone]);
1511impl_vec!(ListViewRow, ListViewRowVec, ListViewRowVecDestructor, ListViewRowVecDestructorType, ListViewRowVecSlice, OptionListViewRow);
1512impl_vec_clone!(ListViewRow, ListViewRowVec, ListViewRowVecDestructor);
1513impl_vec_mut!(ListViewRow, ListViewRowVec);
1514impl_vec_debug!(ListViewRow, ListViewRowVec);
1515
1516impl ListView {
1517    #[must_use] pub fn create(columns: StringVec) -> Self {
1518        Self {
1519            columns,
1520            ..Default::default()
1521        }
1522    }
1523
1524    #[must_use]
1525    pub fn swap_with_default(&mut self) -> Self {
1526        let mut m = Self::default();
1527        core::mem::swap(&mut m, self);
1528        m
1529    }
1530
1531    #[must_use] pub fn with_columns(mut self, columns: StringVec) -> Self {
1532        self.set_columns(columns);
1533        self
1534    }
1535
1536    pub fn set_columns(&mut self, columns: StringVec) {
1537        self.columns = columns;
1538    }
1539
1540    #[must_use] pub fn with_rows(mut self, rows: ListViewRowVec) -> Self {
1541        self.set_rows(rows);
1542        self
1543    }
1544
1545    pub fn set_rows(&mut self, rows: ListViewRowVec) {
1546        self.rows = rows;
1547    }
1548
1549    /// The half-open range `[first, last)` of row indices visible in a
1550    /// vertically-scrolled, fixed-row-height list — the windowing core for
1551    /// virtualizing a long `ListView` (render only these rows instead of all of
1552    /// them, the way the `MapWidget`'s `VirtualView` renders only visible tiles).
1553    /// `scroll_y` is pixels scrolled past the top, `viewport_height` the visible
1554    /// height; one extra row is included so a row straddling the bottom edge
1555    /// still renders. Returns `(0, 0)` for degenerate input (no rows, a
1556    /// non-positive/non-finite height, or non-finite scroll), and an empty range
1557    /// `(total, total)` once scrolled past the end.
1558    #[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)] // bounded layout/render numeric cast
1559    #[must_use] pub fn visible_row_range(
1560        scroll_y: f32,
1561        viewport_height: f32,
1562        row_height: f32,
1563        total_rows: usize,
1564    ) -> (usize, usize) {
1565        if total_rows == 0
1566            || !row_height.is_finite()
1567            || row_height <= 0.0
1568            || !viewport_height.is_finite()
1569            || viewport_height <= 0.0
1570            || !scroll_y.is_finite()
1571        {
1572            return (0, 0);
1573        }
1574        let first = (scroll_y.max(0.0) / row_height).floor() as usize;
1575        if first >= total_rows {
1576            return (total_rows, total_rows);
1577        }
1578        let visible = (viewport_height / row_height).ceil() as usize + 1;
1579        let last = (first + visible).min(total_rows);
1580        (first, last)
1581    }
1582
1583    #[must_use] pub const fn with_sorted_by(mut self, sorted_by: OptionUsize) -> Self {
1584        self.set_sorted_by(sorted_by);
1585        self
1586    }
1587
1588    pub const fn set_sorted_by(&mut self, sorted_by: OptionUsize) {
1589        self.sorted_by = sorted_by;
1590    }
1591
1592    #[must_use] pub const fn with_scroll_offset(mut self, scroll_offset: PixelValueNoPercent) -> Self {
1593        self.set_scroll_offset(scroll_offset);
1594        self
1595    }
1596
1597    pub const fn set_scroll_offset(&mut self, scroll_offset: PixelValueNoPercent) {
1598        self.scroll_offset = scroll_offset;
1599    }
1600
1601    #[must_use] pub fn with_content_height(mut self, content_height: PixelValueNoPercent) -> Self {
1602        self.set_content_height(content_height);
1603        self
1604    }
1605
1606    pub fn set_content_height(&mut self, content_height: PixelValueNoPercent) {
1607        self.content_height = Some(content_height).into();
1608    }
1609
1610    #[must_use] pub fn with_column_context_menu(mut self, context_menu: Menu) -> Self {
1611        self.set_column_context_menu(context_menu);
1612        self
1613    }
1614
1615    pub fn set_column_context_menu(&mut self, column_context_menu: Menu) {
1616        self.column_context_menu = Some(column_context_menu).into();
1617    }
1618
1619    #[must_use]
1620    pub fn with_on_column_click<C: Into<ListViewOnColumnClickCallback>>(
1621        mut self,
1622        refany: RefAny,
1623        on_column_click: C,
1624    ) -> Self {
1625        self.set_on_column_click(refany, on_column_click);
1626        self
1627    }
1628
1629    pub fn set_on_column_click<C: Into<ListViewOnColumnClickCallback>>(
1630        &mut self,
1631        refany: RefAny,
1632        on_column_click: C,
1633    ) {
1634        self.on_column_click = Some(ListViewOnColumnClick {
1635            refany,
1636            callback: on_column_click.into(),
1637        })
1638        .into();
1639    }
1640
1641    #[must_use]
1642    pub fn with_on_row_click<C: Into<ListViewOnRowClickCallback>>(
1643        mut self,
1644        refany: RefAny,
1645        on_row_click: C,
1646    ) -> Self {
1647        self.set_on_row_click(refany, on_row_click);
1648        self
1649    }
1650
1651    pub fn set_on_row_click<C: Into<ListViewOnRowClickCallback>>(
1652        &mut self,
1653        refany: RefAny,
1654        on_row_click: C,
1655    ) {
1656        self.on_row_click = Some(ListViewOnRowClick {
1657            refany,
1658            callback: on_row_click.into(),
1659        })
1660        .into();
1661    }
1662
1663    #[must_use] pub fn dom(self) -> Dom {
1664        // Snapshot the state handed to row/column click callbacks. Runtime-only
1665        // fields (scroll position / content height) aren't known at build time,
1666        // so they default to zero; columns/sorted_by/row-count/scroll-offset are.
1667        let state = ListViewState {
1668            columns: self.columns.clone(),
1669            sorted_by: self.sorted_by,
1670            current_row_count: self.rows.as_ref().len(),
1671            scroll_offset: self.scroll_offset,
1672            current_scroll_position: LogicalPosition::zero(),
1673            current_content_height: LogicalSize::zero(),
1674        };
1675        let on_column_click = self.on_column_click.clone();
1676        let on_row_click = self.on_row_click.clone();
1677
1678        Dom::create_div()
1679            .with_css_props(CSS_MATCH_17553577885456905601)
1680            .with_ids_and_classes(LIST_VIEW_CONTAINER_CLASS)
1681            .with_children(DomVec::from_vec(vec![
1682                // header
1683                Dom::create_div()
1684                    .with_css_props(CSS_MATCH_15315949193378715186)
1685                    .with_ids_and_classes(HEADER_CONTAINER_CLASS)
1686                    .with_children(
1687                        self.columns
1688                            .iter()
1689                            .enumerate()
1690                            .map(|(col_index, col)| {
1691                                let col_dom = Dom::create_div()
1692                                    .with_css_props(CSS_MATCH_12498280255863106397)
1693                                    .with_ids_and_classes(COLUMN_NAME_CLASS)
1694                                    .with_child({
1695                                        Dom::create_text(col.clone())
1696                                            .with_css_props(CSS_MATCH_15673486787900743642)
1697                                    });
1698                                // Wire the click only when the app set a handler.
1699                                match &on_column_click {
1700                                    OptionListViewOnColumnClick::Some(_) => col_dom.with_callbacks(
1701                                        vec![CoreCallbackData {
1702                                            event: EventFilter::Hover(HoverEventFilter::MouseUp),
1703                                            refany: RefAny::new(ColumnClickData {
1704                                                col_index,
1705                                                state: state.clone(),
1706                                                on_column_click: on_column_click.clone(),
1707                                            }),
1708                                            callback: CoreCallback {
1709                                                cb: on_list_view_column_click as usize,
1710                                                ctx: OptionRefAny::None,
1711                                            },
1712                                        }]
1713                                        .into(),
1714                                    ),
1715                                    OptionListViewOnColumnClick::None => col_dom,
1716                                }
1717                            })
1718                            .collect::<Vec<_>>()
1719                            .into(),
1720                    ),
1721                // rows
1722                Dom::create_div()
1723                    .with_css_props(CSS_MATCH_4852927511892172364)
1724                    .with_ids_and_classes(ROW_CONTAINER_CLASS)
1725                    .with_children(
1726                        self.rows
1727                            .into_iter()
1728                            .enumerate()
1729                            .map(|(row_index, row)| {
1730                                let row_dom = Dom::create_div()
1731                                    .with_css_props(CSS_MATCH_7894335449545988724)
1732                                    .with_ids_and_classes(ROW_CLASS)
1733                                    .with_tab_index(TabIndex::Auto)
1734                                    .with_children(
1735                                        row.cells
1736                                            .as_ref()
1737                                            .iter()
1738                                            .map(|cell| {
1739                                                Dom::create_div()
1740                                                    .with_css_props(CSS_MATCH_12980082330151137475)
1741                                                    .with_ids_and_classes(CELL_CLASS)
1742                                                    .with_child(cell.clone())
1743                                            })
1744                                            .collect::<Vec<_>>()
1745                                            .into(),
1746                                    );
1747                                match &on_row_click {
1748                                    OptionListViewOnRowClick::Some(_) => row_dom.with_callbacks(
1749                                        vec![CoreCallbackData {
1750                                            event: EventFilter::Hover(HoverEventFilter::MouseUp),
1751                                            refany: RefAny::new(RowClickData {
1752                                                row_index,
1753                                                state: state.clone(),
1754                                                on_row_click: on_row_click.clone(),
1755                                            }),
1756                                            callback: CoreCallback {
1757                                                cb: on_list_view_row_click as usize,
1758                                                ctx: OptionRefAny::None,
1759                                            },
1760                                        }]
1761                                        .into(),
1762                                    ),
1763                                    OptionListViewOnRowClick::None => row_dom,
1764                                }
1765                            })
1766                            .collect::<Vec<_>>()
1767                            .into(),
1768                    ),
1769            ]))
1770    }
1771}
1772
1773/// Per-row data carried to the internal `MouseUp` handler (the row index plus a
1774/// snapshot of the list state and the app's `on_row_click` hook).
1775struct RowClickData {
1776    row_index: usize,
1777    state: ListViewState,
1778    on_row_click: OptionListViewOnRowClick,
1779}
1780
1781/// Per-column equivalent of [`RowClickData`].
1782struct ColumnClickData {
1783    col_index: usize,
1784    state: ListViewState,
1785    on_column_click: OptionListViewOnColumnClick,
1786}
1787
1788/// `MouseUp` on a row → invoke the app's `on_row_click(state, row_index)`.
1789extern "C" fn on_list_view_row_click(mut refany: RefAny, info: CallbackInfo) -> Update {
1790    let Some(data) = refany.downcast_ref::<RowClickData>() else {
1791        return Update::DoNothing;
1792    };
1793    match data.on_row_click.as_ref() {
1794        Some(ListViewOnRowClick { refany: user_data, callback }) => {
1795            (callback.cb)(user_data.clone(), info, data.state.clone(), data.row_index)
1796        }
1797        None => Update::DoNothing,
1798    }
1799}
1800
1801/// `MouseUp` on a column header → invoke the app's `on_column_click(state, col_index)`.
1802extern "C" fn on_list_view_column_click(mut refany: RefAny, info: CallbackInfo) -> Update {
1803    let Some(data) = refany.downcast_ref::<ColumnClickData>() else {
1804        return Update::DoNothing;
1805    };
1806    match data.on_column_click.as_ref() {
1807        Some(ListViewOnColumnClick { refany: user_data, callback }) => {
1808            (callback.cb)(user_data.clone(), info, data.state.clone(), data.col_index)
1809        }
1810        None => Update::DoNothing,
1811    }
1812}
1813
1814#[cfg(test)]
1815mod list_view_click_tests {
1816    use super::*;
1817
1818    /// The windowing core for `ListView` virtualization: only the visible rows
1819    /// (+1 straddling the bottom) are in range, the range tracks scroll, clamps
1820    /// to the row count, and degenerate input yields an empty range.
1821    #[test]
1822    fn visible_row_range_windows_correctly() {
1823        // 100 rows x 20px, 200px viewport → 10 full rows + 1 partial.
1824        assert_eq!(ListView::visible_row_range(0.0, 200.0, 20.0, 100), (0, 11));
1825        // Scrolled 50px → first row = floor(50/20) = 2.
1826        assert_eq!(ListView::visible_row_range(50.0, 200.0, 20.0, 100), (2, 13));
1827        // Near the end → clamped to the row count.
1828        assert_eq!(ListView::visible_row_range(1900.0, 200.0, 20.0, 100), (95, 100));
1829        // Scrolled past the end → empty range at the tail.
1830        assert_eq!(ListView::visible_row_range(5000.0, 200.0, 20.0, 100), (100, 100));
1831        // Degenerate inputs → empty.
1832        assert_eq!(ListView::visible_row_range(0.0, 200.0, 20.0, 0), (0, 0));
1833        assert_eq!(ListView::visible_row_range(0.0, 200.0, 0.0, 100), (0, 0));
1834        assert_eq!(ListView::visible_row_range(f32::NAN, 200.0, 20.0, 100), (0, 0));
1835    }
1836
1837    extern "C" fn noop_row(_: RefAny, _: CallbackInfo, _: ListViewState, _: usize) -> Update {
1838        Update::DoNothing
1839    }
1840
1841    fn empty_row() -> ListViewRow {
1842        ListViewRow {
1843            cells: DomVec::from_const_slice(&[]),
1844            height: None.into(),
1845        }
1846    }
1847
1848    /// Rows must carry a click callback exactly when `on_row_click` is set —
1849    /// previously `dom()` wired nothing, so the hook was dead.
1850    #[test]
1851    #[allow(clippy::field_reassign_with_default)] // struct built incrementally / test setup; a struct literal is not clearer here
1852    fn rows_get_a_click_callback_only_when_on_row_click_is_set() {
1853        let mut lv = ListView::default();
1854        lv.rows = ListViewRowVec::from_vec(vec![empty_row(), empty_row()]);
1855        let on_row_click: ListViewOnRowClickCallbackType = noop_row;
1856        lv.set_on_row_click(RefAny::new(()), on_row_click);
1857        let dom = lv.dom();
1858        // children = [header, rows]; each row div carries the MouseUp callback.
1859        let rows = dom.children.as_ref()[1].children.as_ref();
1860        assert_eq!(rows.len(), 2);
1861        for row in rows {
1862            assert_eq!(
1863                row.root.callbacks.as_ref().len(),
1864                1,
1865                "row must carry the click callback when on_row_click is set"
1866            );
1867        }
1868
1869        // Without the hook → no callbacks (opt-in, no wasted dispatch).
1870        let mut bare = ListView::default();
1871        bare.rows = ListViewRowVec::from_vec(vec![empty_row()]);
1872        let dom2 = bare.dom();
1873        let rows2 = dom2.children.as_ref()[1].children.as_ref();
1874        assert_eq!(rows2.len(), 1);
1875        assert!(
1876            rows2[0].root.callbacks.as_ref().is_empty(),
1877            "no callback when on_row_click is unset"
1878        );
1879    }
1880}