flask-construct-ui 0.12.1__tar.gz → 0.12.2__tar.gz
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.
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/PKG-INFO +1 -1
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/grid.py +9 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/schema.py +67 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/static/css/whitelabel.css +6 -0
- flask_construct_ui-0.12.2/flask_construct_ui/static/js/prosemirror-bundle.min.js +35 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/crud/_macros.html +10 -3
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/crud/listindex.html +5 -2
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/crud/related_crud_tab_list.html +5 -2
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui.egg-info/PKG-INFO +1 -1
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/pyproject.toml +1 -1
- flask_construct_ui-0.12.1/flask_construct_ui/static/js/prosemirror-bundle.min.js +0 -34
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/LICENSE +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/README.md +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/__init__.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/app_hooks.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/auth.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/base.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/capabilities.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/cli.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/components/__init__.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/components/calendar.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/components/chart.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/components/chart_native.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/components/content.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/components/core.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/components/grid.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/components/kanban.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/components/layout.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/components/live.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/components/period.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/components/pivot.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/contrast.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/crud.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/crud_forms.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/csrf.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/data.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/data_sqlalchemy.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/dragdrop.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/errors.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/flashes.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/forms.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/headless.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/icons.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/l10n/en/main.flt +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/l10n/sv/main.flt +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/language.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/layout.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/live.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/menu.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/navbar.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/navigation.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/orgmode.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/pagination.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/py.typed +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/rcrud.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/resume.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/sanitize.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/static/css/grid.css +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/static/css/prosemirror-bundle.min.css +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/static/css/unpoly.min.css +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/static/designs/adminlte.css +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/static/designs/sandstone.css +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/static/fonts/bootstrap-icons/LICENSE.txt +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/static/fonts/bootstrap-icons/bootstrap-icons.min.css +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/static/fonts/bootstrap-icons/fonts/bootstrap-icons.woff +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/static/fonts/bootstrap-icons/fonts/bootstrap-icons.woff2 +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/static/fonts/material-symbols/LICENSE.txt +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/static/fonts/material-symbols/material-symbols-outlined.woff2 +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/static/fonts/material-symbols/material-symbols.css +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/static/fonts/material-symbols/names.txt +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/static/js/construct-core.min.js +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/static/js/construct-grid.min.js +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/static/js/kanban-dnd.js +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/static/js/unpoly.min.js +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/components/_form_field.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/components/button.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/components/calendar.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/components/calendarmini.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/components/card.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/components/chart.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/components/chart_native.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/components/form.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/components/grid.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/components/grid_layout.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/components/grid_notice.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/components/horizontal_layout.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/components/kanban.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/components/live.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/components/live_refresh.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/components/main.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/components/markup.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/components/period_nav.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/components/pivot_form.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/components/rich_text.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/components/table.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/components/tabs.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/components/text.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/components/vertical_layout.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/crud/_many_related_options.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/crud/_related_options.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/crud/create.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/crud/edit.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/crud/related_crud_tab_form.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/crud/tab_view.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/crud/view.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/errors/error.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/errors/forbidden.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/navbar/notifications.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/navbar/search_results.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/structure/base.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/structure/public.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/style/_flashes.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/style/_footer.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/style/_menu.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/style/base_full.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/templates/style/base_partial.html +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/testing.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/urls.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/validation.py +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui.egg-info/SOURCES.txt +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui.egg-info/dependency_links.txt +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui.egg-info/requires.txt +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui.egg-info/top_level.txt +0 -0
- {flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/setup.cfg +0 -0
|
@@ -36,6 +36,8 @@ import decimal
|
|
|
36
36
|
import enum
|
|
37
37
|
from typing import Any
|
|
38
38
|
|
|
39
|
+
import markupsafe
|
|
40
|
+
|
|
39
41
|
from . import schema as schema_mod
|
|
40
42
|
from .data import query as data_query
|
|
41
43
|
from .forms import validate_form_data
|
|
@@ -365,6 +367,13 @@ def cell_text(field, name, row):
|
|
|
365
367
|
"""The text a cell displays. Always plain text — never markup: a cell
|
|
366
368
|
holds user data, and rendering it as markup would be stored XSS on every
|
|
367
369
|
page that embeds the grid."""
|
|
370
|
+
if field.has_display_filter():
|
|
371
|
+
value = field.display_value(name, row, "grid")
|
|
372
|
+
if isinstance(value, markupsafe.Markup):
|
|
373
|
+
# A filter's markup is meant for HTML surfaces; a grid cell keeps
|
|
374
|
+
# only its text.
|
|
375
|
+
return value.striptags()
|
|
376
|
+
return "" if value is None else str(value)
|
|
368
377
|
if field.field_type == "bool":
|
|
369
378
|
return "✓" if getattr(row, name, None) else ""
|
|
370
379
|
value = field.format_value(name, row)
|
|
@@ -3,6 +3,27 @@ import datetime
|
|
|
3
3
|
from .validation import ValidationError, parse_rule
|
|
4
4
|
|
|
5
5
|
|
|
6
|
+
class DisplayContext:
|
|
7
|
+
"""What a display filter gets alongside the value it is formatting.
|
|
8
|
+
|
|
9
|
+
One object rather than more positional arguments, so later additions
|
|
10
|
+
don't break filters apps have already written.
|
|
11
|
+
|
|
12
|
+
``surface`` says where the value is being shown: ``"list"`` (the CRUD
|
|
13
|
+
list), ``"related"`` (a related-records tab), ``"view"`` (a read-only
|
|
14
|
+
field on the view or edit page), ``"inline"`` (a row of a list field) or
|
|
15
|
+
``"grid"`` (a data grid cell, which is plain text only).
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
__slots__ = ("row", "name", "field", "surface")
|
|
19
|
+
|
|
20
|
+
def __init__(self, row, name, field, surface):
|
|
21
|
+
self.row = row
|
|
22
|
+
self.name = name
|
|
23
|
+
self.field = field
|
|
24
|
+
self.surface = surface
|
|
25
|
+
|
|
26
|
+
|
|
6
27
|
class SchemaField:
|
|
7
28
|
def __init__(self, field_type, name, **kwargs):
|
|
8
29
|
self.field_type = field_type
|
|
@@ -26,6 +47,8 @@ class SchemaField:
|
|
|
26
47
|
# only replaces the generic "Enter <field>" hint and vanishes on input.
|
|
27
48
|
self.placeholder = kwargs.get("placeholder", None)
|
|
28
49
|
self.help = kwargs.get("help", None)
|
|
50
|
+
# Display-only filter, ``fn(value, ctx)`` — see ``display_value``.
|
|
51
|
+
self.display = kwargs.get("display", None)
|
|
29
52
|
self.kwargs = kwargs
|
|
30
53
|
matches = kwargs.get("matches", None)
|
|
31
54
|
self._matches_fn = None
|
|
@@ -61,8 +84,52 @@ class SchemaField:
|
|
|
61
84
|
return 'required aria-required="true"' if self.required else ""
|
|
62
85
|
|
|
63
86
|
def format_value(self, field, row):
|
|
87
|
+
"""The stored value, as a form control or editor is filled with it.
|
|
88
|
+
|
|
89
|
+
This feeds ``value="…"`` attributes as well as read-only text, so it
|
|
90
|
+
must never return markup. To change only how a value *reads*, use a
|
|
91
|
+
display filter — see ``display_value``.
|
|
92
|
+
"""
|
|
64
93
|
return getattr(row, field)
|
|
65
94
|
|
|
95
|
+
def _display_filter(self):
|
|
96
|
+
if self.display is not None:
|
|
97
|
+
return self.display
|
|
98
|
+
from flask import has_app_context, current_app
|
|
99
|
+
|
|
100
|
+
if has_app_context():
|
|
101
|
+
filters = current_app.config.get("CONSTRUCT_DISPLAY_FILTERS") or {}
|
|
102
|
+
return filters.get(self.field_type)
|
|
103
|
+
return None
|
|
104
|
+
|
|
105
|
+
def has_display_filter(self):
|
|
106
|
+
"""Whether ``display_value`` differs from ``format_value`` here.
|
|
107
|
+
|
|
108
|
+
Templates check this before their built-in per-type rendering (check
|
|
109
|
+
icons, badges, …), so a filter can restyle any field type, while
|
|
110
|
+
fields without one render exactly as before.
|
|
111
|
+
"""
|
|
112
|
+
if type(self).display_value is not SchemaField.display_value:
|
|
113
|
+
return True
|
|
114
|
+
return self._display_filter() is not None
|
|
115
|
+
|
|
116
|
+
def display_value(self, field, row, surface="list"):
|
|
117
|
+
"""The value as it is shown — never typed — in lists, related tabs,
|
|
118
|
+
read-only views and grid cells.
|
|
119
|
+
|
|
120
|
+
Resolved, most specific first: the field's ``display=`` callable, the
|
|
121
|
+
app's ``CONSTRUCT_DISPLAY_FILTERS[field_type]``, then ``format_value``
|
|
122
|
+
unchanged. A filter is called as ``fn(value, ctx)`` with the
|
|
123
|
+
``format_value`` result and a :class:`DisplayContext`. It may return
|
|
124
|
+
``markupsafe.Markup`` for intentional HTML; anything else is escaped.
|
|
125
|
+
Subclasses may override this for full control.
|
|
126
|
+
"""
|
|
127
|
+
value = self.format_value(field, row)
|
|
128
|
+
fn = self._display_filter()
|
|
129
|
+
if fn is None:
|
|
130
|
+
return value
|
|
131
|
+
return fn(value, DisplayContext(row, field, self, surface))
|
|
132
|
+
|
|
66
133
|
def parse_value(self, value):
|
|
67
134
|
return value
|
|
68
135
|
|
{flask_construct_ui-0.12.1 → flask_construct_ui-0.12.2}/flask_construct_ui/static/css/whitelabel.css
RENAMED
|
@@ -820,6 +820,12 @@ a:hover {
|
|
|
820
820
|
padding: var(--fcu-table-cell-padding-y) var(--fcu-table-cell-padding-x);
|
|
821
821
|
border-bottom: 1px solid var(--fcu-border);
|
|
822
822
|
}
|
|
823
|
+
/* List cells carry fcu-cell--<field_type> and data-field="<name>", so an app
|
|
824
|
+
can style a column without a display filter. A date breaking at its hyphens
|
|
825
|
+
in a narrow column reads as two values. */
|
|
826
|
+
.fcu-cell--date, .fcu-cell--datetime {
|
|
827
|
+
white-space: nowrap;
|
|
828
|
+
}
|
|
823
829
|
.fcu-table th {
|
|
824
830
|
background-color: var(--fcu-table-header-bg);
|
|
825
831
|
font-weight: var(--fcu-font-weight-semibold);
|