1+
12# Copyright (c) Jupyter Development Team.
23# Distributed under the terms of the Modified BSD License.
34
78group other widgets together and control their
89relative layouts.
910"""
11+ from __future__ import annotations
12+
13+ import typing
14+
15+ from traitlets import CaselessStrEnum , TraitError , TraitType , Unicode
1016
11- from .widget import register , widget_serialization , Widget
17+ from .docutils import doc_subst
1218from .domwidget import DOMWidget
19+ from .widget import Widget , register , widget_serialization
1320from .widget_core import CoreWidget
14- from .docutils import doc_subst
15- from .trait_types import TypedTuple
16- from traitlets import Unicode , CaselessStrEnum , Instance
17-
1821
1922_doc_snippets = {}
2023_doc_snippets ['box_params' ] = """
2528 one of 'success', 'info', 'warning' or 'danger', or ''.
2629 Applies a predefined style to the box. Defaults to '',
2730 which applies no pre-defined style.
31+
32+ validate_mode: str
33+ one of 'raise', 'warning', error'.
34+ How invalid children will be treated.
35+ 'raise' will raise a trait error.
36+ 'warning' and 'error' will log an error using box.log dropping
37+ the invalid items from children.
2838"""
2939
40+ class Children (TraitType ['tuple[Widget,...]' , typing .Iterable [Widget ]]):
41+ default_value = ()
42+
43+ def validate (self , obj : Box , value : typing .Iterable [Widget ]):
44+ valid , invalid = [], []
45+ for v in value :
46+ if isinstance (v , Widget ) and v ._repr_mimebundle_ :
47+ valid .append (v )
48+ else :
49+ invalid .append (v )
50+ if invalid :
51+ msg = f'Invalid or closed items found: { invalid } '
52+ if obj .validate_mode == 'log_warning' :
53+ obj .log .warning (msg )
54+ elif obj .validate_mode == 'log_error' :
55+ obj .log .error (msg )
56+ else :
57+ raise TraitError (msg )
58+ return tuple (valid )
59+
3060
3161@register
3262@doc_subst (_doc_snippets )
@@ -48,19 +78,23 @@ class Box(DOMWidget, CoreWidget):
4878 """
4979 _model_name = Unicode ('BoxModel' ).tag (sync = True )
5080 _view_name = Unicode ('BoxView' ).tag (sync = True )
81+ tooltip = Unicode ('' , allow_none = True , help = 'A tooltip caption.' ).tag (sync = True )
82+ validate_mode = CaselessStrEnum (['raise' , 'log_warning' , 'log_error' ], 'raise' )
5183
5284 # Child widgets in the container.
5385 # Using a tuple here to force reassignment to update the list.
5486 # When a proper notifying-list trait exists, use that instead.
55- children = TypedTuple (trait = Instance (Widget ), help = "List of widget children" ).tag (
56- sync = True , ** widget_serialization )
87+ children = Children (help = 'List of widget children' ).tag (
88+ sync = True , ** widget_serialization
89+ )
5790
5891 box_style = CaselessStrEnum (
5992 values = ['success' , 'info' , 'warning' , 'danger' , '' ], default_value = '' ,
6093 help = """Use a predefined styling for the box.""" ).tag (sync = True )
61-
94+
6295 def __init__ (self , children = (), ** kwargs ):
63- kwargs ['children' ] = children
96+ if children :
97+ kwargs ['children' ] = children
6498 super ().__init__ (** kwargs )
6599
66100@register
0 commit comments