-
-
Notifications
You must be signed in to change notification settings - Fork 473
/
card.py
129 lines (98 loc) · 4.3 KB
/
card.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
from __future__ import annotations
from typing import (
TYPE_CHECKING, Callable, ClassVar, List, Mapping, Type,
)
import param
from ..io.resources import CDN_DIST
from ..models import Card as BkCard
from .base import Column, Row
if TYPE_CHECKING:
from bokeh.model import Model
from ..viewable import Viewable
class Card(Column):
"""
A `Card` layout allows arranging multiple panel objects in a
collapsible, vertical container with a header bar.
Reference: https://panel.holoviz.org/reference/layouts/Card.html
:Example:
>>> pn.Card(
... some_widget, some_pane, some_python_object,
... title='Card', styles=dict(background='WhiteSmoke'),
... )
"""
active_header_background = param.String(doc="""
A valid CSS color for the header background when not collapsed.""")
button_css_classes = param.List(default=['card-button'], doc="""
CSS classes to apply to the button element.""")
collapsible = param.Boolean(default=True, doc="""
Whether the Card should be expandable and collapsible.""")
collapsed = param.Boolean(default=False, doc="""
Whether the contents of the Card are collapsed.""")
css_classes = param.List(default=['card'], doc="""
CSS classes to apply to the overall Card.""")
header = param.Parameter(doc="""
A Panel component to display in the header bar of the Card.
Will override the given title if defined.""")
header_background = param.String(doc="""
A valid CSS color for the header background.""")
header_color = param.String(doc="""
A valid CSS color to apply to the header text.""")
header_css_classes = param.List(default=['card-header'], doc="""
CSS classes to apply to the header element.""")
hide_header = param.Boolean(default=False, doc="""
Whether to skip rendering the header.""")
title_css_classes = param.List(default=['card-title'], doc="""
CSS classes to apply to the header title.""")
title = param.String(doc="""
A title to be displayed in the Card header, will be overridden
by the header if defined.""")
_bokeh_model: ClassVar[Type[Model]] = BkCard
_rename: ClassVar[Mapping[str, str | None]] = {
'title': None, 'header': None, 'title_css_classes': None
}
_stylesheets: ClassVar[List[str]] = [
f'{CDN_DIST}css/card.css'
]
def __init__(self, *objects, **params):
self._header_layout = Row(css_classes=['card-header-row'], sizing_mode='stretch_width')
super().__init__(*objects, **params)
self._header = None
self.param.watch(self._update_header, ['title', 'header', 'title_css_classes'])
self._update_header()
def select(
self, selector: type | Callable[[Viewable], bool] | None = None
) -> List[Viewable]:
return self._header_layout.select(selector) + super().select(selector)
def _cleanup(self, root: Model | None = None) -> None:
super()._cleanup(root)
self._header_layout._cleanup(root)
def _update_header(self, *events):
from ..pane import HTML, panel
if self.header is None:
params = {
'object': f'<h3>{self.title}</h3>' if self.title else "​",
'css_classes': self.title_css_classes,
'margin': (5, 0),
}
if self.header_color:
params['styles'] = {'color': self.header_color}
if self._header is not None:
self._header.param.update(**params)
return
else:
self._header = item = HTML(**params)
else:
item = panel(self.header)
self._header = None
self._header_layout[:] = [item]
def _get_objects(self, model, old_objects, doc, root, comm=None):
ref = root.ref['id']
models, old_models = super()._get_objects(model, old_objects, doc, root, comm)
if ref in self._header_layout._models:
header = self._header_layout._models[ref][0]
old_models.append(header)
else:
header = self._header_layout._get_model(doc, root, model, comm)
return [header]+models, old_models
def _compute_sizing_mode(self, children, props):
return super()._compute_sizing_mode(children[1:], props)