def variable_size_header_part(platform, company, searchbar, searchbar_position): return hg.BaseElement( hg.A( logo(), platform, _class="bx--header__name", style="font-weight: 400", # override carbon design href=hg.F(lambda c: c["request"].META["SCRIPT_NAME"] or "/"), ), hg.If( searchbar, hg.SPAN( searchbar, style=f"position: absolute; left: {searchbar_position}", _class="theme-gray-100", ), "", ), hg.A( hg.SPAN( company, style=hg.format( "position: absolute; left: {}", hg.If(searchbar, "50%", searchbar_position), ), ), _class="bx--header__name", style="font-weight: 400", # override carbon design href=hg.F(lambda c: c["request"].META["SCRIPT_NAME"] or "/"), ), )
def get_layout(self): return auth_page( layout.forms.Form( hg.C("form"), hg.A( _("Lost password?"), href=reverse("password_reset"), style="display: block; text-align: right; font-size: 0.75rem", ), layout.forms.FormField( fieldname="username", form="form", inputelement_attrs={"_class": "field-02-background"}, style="width: 100%", ), layout.forms.FormField( fieldname="password", form="form", inputelement_attrs={"_class": "field-02-background"}, style="width: 100%", ), id="authform", ), _("Login"), )
def __init__(self, platform, company, searchbar, actions=(), *args, **kwargs): super().__init__( hg.If( HasBreadCookieValue("sidenav-hidden", "true"), variable_size_header_part(hg.BaseElement(), company, searchbar, "5rem"), variable_size_header_part( hg.SPAN(platform, _class="bx--header__name--prefix"), company, searchbar, "18rem", ), ), hg.DIV( hg.If( hg.F(lambda c: c["request"].user.is_authenticated), hg.A( hg.SPAN( hg.C("request.user.get_username"), _class="bx--header__name--prefix", ), _class="bx--header__name", href=reverse("userprofile"), title=hg.C("request.user.get_username"), style="padding: 0; margin-right: 1rem", ), ), hg.If( hg.F(lambda c: c["request"].user.is_authenticated), hg.BUTTON( Icon( "logout", size=20, _class="bx--navigation-menu-panel-expand-icon", aria_hidden="true", ), Icon( "logout", size=20, _class="bx--navigation-menu-panel-collapse-icon", aria_hidden="true", ), _class="bx--header__menu-trigger bx--header__action", title=_("Logout"), data_navigation_menu_panel_label_expand=_("Logout"), data_navigation_menu_panel_label_collapse=_("Close"), onclick=f"document.location = '{reverse('logout')}'", ), ), _class="bx--header__global", ), _class="bx--header", data_header=True, )
def profile_field_password(fieldname): ret = profile_field(fieldname) ret[1] = C( hg.BaseElement( "●●●●●●●●●●●●", hg.A( _("Request reset"), href=reverse("userprofile.password_reset"), style="float: right", ), )) return ret
def asoverflowbutton(context): link = context["link"] return hg.A( hg.DIV( hg.If( link.iconname, Icon(link.iconname, size=16), ), link.label, _class="bx--overflow-menu-options__option-content", ), _class="bx--overflow-menu-options__btn", role="menuitem", title=link.label, href=link.href, **link.attributes, )
def as_download(value, label=None): if not value: return CONSTANTS[None] if not value.storage.exists(value.name): return hg.SMALL(hg.EM(_("File not found"))) if label is None: label = hg.SPAN(os.path.basename(value.name)) return hg.A( layout.icon.Icon( "launch", size=16, style="vertical-align: middle; margin-right: 0.25rem;", ), label, newtab=True, href=value.url, style="margin-right: 0.5rem; margin-left: 0.5rem", onclick="event.stopPropagation();", )
def get_layout(self): return auth_page( layout.forms.Form( hg.C("form"), hg.A( _("Lost password?"), href=reverse("password_reset"), style="float: right; font-size: 0.75rem", ), layout.forms.FormField( "email", inputelement_attrs={ "_class": "field-02-background", }, style="width: 100%", ), id="authform", ), _("Reset password"), show_cancelbutton=True, )
def __init__(self, label, tabid, panelid, selected): super().__init__( hg.A( label, tabindex="0", id=tabid, _class="bx--tabs__nav-link", href="javascript:void(0)", aria_controls=panelid, aria_selected=hg.If(selected, "true", "false"), role="tab", ), _class=hg.BaseElement( "bx--tabs__nav-item", hg.If(selected, " bx--tabs__nav-item--selected"), ), data_target="#" + panelid, aria_selected=hg.If(selected, "true", "false"), role="tab", onclick=hg.BaseElement("setBreadCookie('selected-tab', '", tabid, "')"), )
def __init__( self, *tabs, container=False, tabpanel_attributes=None, labelcontainer_attributes=None, **attributes, ): tabpanel_attributes = collections.defaultdict( str, tabpanel_attributes or {}) labelcontainer_attributes = collections.defaultdict( str, labelcontainer_attributes or {}) self.tablabels = hg.UL(_class="bx--tabs__nav bx--tabs__nav--hidden", style="flex-wrap: wrap;") labelcontainer_attributes["_class"] += " bx--tabs" + ( " bx--tabs--container" if container else "") self.labelcontainer = hg.DIV( hg.DIV( hg.A( href="javascript:void(0)", _class="bx--tabs-trigger-text", tabindex=-1, ), _class="bx--tabs-trigger", style="display: none", tabindex=0, ), self.tablabels, data_tabs=True, **hg.merge_html_attrs( { "onload": "if( $('.bx--tabs__nav-item--selected', this) == null ) " "(new CarbonComponents.Tab(this)).setActive($('.bx--tabs__nav-item', this))", }, labelcontainer_attributes, ), ) tabpanel_attributes["_class"] += " bx--tab-content" self.tabpanels = hg.DIV(**tabpanel_attributes) firsttab = None for i, (label, content) in enumerate(tabs): tabid = f"tab-{slugify(label)}-{i}" panelid = f"panel-{slugify(label)}-{i}" if firsttab is None: firsttab = tabid self.tablabels.append( TabLabel( label, tabid, panelid, HasBreadCookieValue("selected-tab", tabid, firsttab), )) self.tabpanels.append( TabPanel( content, panelid, tabid, HasBreadCookieValue("selected-tab", tabid, firsttab), )) super().__init__( self.labelcontainer, self.tabpanels, )
def as_url(value): return hg.A(value, href=value, target="_blank", rel="noopener noreferrer")
def as_email(value): return hg.A(value, href=hg.format("mailto: {}", value))
def as_href(self, href): return hg.A(*self, **{**self.attributes, "href": href})
def __init__( self, label=None, help_text=None, errors=None, inputelement_attrs=None, boundfield=None, **attributes, ): inputelement_attrs = inputelement_attrs or {} uploadbutton = hg.LABEL( hg.SPAN(_("Select file"), role="button"), tabindex=0, _class=hg.BaseElement( "bx--btn bx--btn--tertiary", hg.If(inputelement_attrs.get("disabled"), " bx--btn--disabled"), ), data_file_drop_container=True, disabled=inputelement_attrs.get("disabled"), data_invalid=hg.If(getattr(errors, "condition", False), True), _for=inputelement_attrs.get("id"), ) input = self.get_input_element( inputelement_attrs, errors, onload=""" that = this; document.addEventListener('change', (e) => { that.parentElement.querySelector('[data-file-container]').innerHTML = ''; var widget = new CarbonComponents.FileUploader(that.parentElement); widget._displayFilenames(); widget.setState('edit'); }); """, ) # we can only clear the field if it originates form a django field # otherwise it has no use clearbox = None if boundfield: checkbox_name = hg.F( lambda c: hg.resolve_lazy(boundfield, c).field.widget. clear_checkbox_name(hg.resolve_lazy(boundfield, c).html_name)) checkbox_id = hg.F( lambda c: hg.resolve_lazy(boundfield, c).field.widget. clear_checkbox_id(hg.resolve_lazy(checkbox_name, c))) clearbox = hg.If( self.clearable, hg.INPUT( type="checkbox", name=checkbox_name, id=checkbox_id, style="display: none", ), ) # clearbutton is always used, to allow clearing a just selected field in the browser clearbutton = hg.If( self.clearable, hg.SPAN( hg.BUTTON( Icon("close", size=16), _class="bx--file-close", type="button", aria_label="close", onclick=hg.If( clearbox, hg.format("$('#{}').checked = 'checked';", checkbox_id), ), ), data_for=inputelement_attrs.get("id"), _class="bx--file__state-container", ), ) super().__init__( label, hg.DIV( uploadbutton, input, clearbox, hg.DIV( hg.If( inputelement_attrs.get("value"), hg.SPAN( hg.P( hg.If( hg.F(lambda c: hasattr( hg.resolve_lazy(inputelement_attrs, c). get("value").file, "name", )), hg.A( hg.F(lambda c: os.path.basename( hg.resolve_lazy( inputelement_attrs, c).get( "value").name)), href=hg.F(lambda c: settings.MEDIA_URL + hg.resolve_lazy( inputelement_attrs, c ).get("value").name), ), hg.F(lambda c: os.path.basename( hg.resolve_lazy(inputelement_attrs, c). get("value").name)), ), _class="bx--file-filename", ), clearbutton, _class="bx--file__selected-file", ), ), data_file_container=True, _class="bx--file-container", ), help_text, errors, _class="bx--file", data_file=True, ), **attributes, )
def __init__( self, label: Any, body: Any, heading: Optional[Any] = None, link: Optional[Link] = None, button: Optional[Button] = None, icon: Union[Icon, str] = "information", menudirection: str = "bottom", **attributes, ): """ Parameters ---------- label : Any Label for a tooltip body : Any The content inside a tooltip heading : Any, optional A heading for a tooltip. link : Link, optional Bread's Link NamedTuple in case you want to bring users to a specific webpage. button : Button, optional Insert the Bread's Button onto the tooltip. icon : Icon, str, optional Specify an icon for the tooltip The default value is "information". menudirection : str Where should the tooltip appear besides the tooltip icon. It can be either top, left, right, or bottom. The default value is "bottom". """ base_class = "bx--tooltip" footer_elements: typing.List[hg.BaseElement] = [] if link: footer_elements.append(hg.A(link.label, href=link.href, _class="bx--link")) if button: footer_elements.append(button) base_id = hg.html_id(self, base_class + "-id") label_id = f"{base_id}-label" trigger_attributes = { "_class": base_class + "__trigger", "aria_controls": base_id, "aria_expanded": "false", "aria_haspopup": "true", "aria_labelledby": label_id, "data_tooltip_target": "#" + base_id, "data_tooltip_trigger": True, } tooltip_attributes = { "_class": base_class, "aria_hidden": "true", "data_floating_menu_direction": menudirection, "id": base_id, } tooltip_content_attributes = { "_class": base_class + "__content", "aria_describedby": base_id + "-body", "aria_labelledby": label_id, "role": "dialog", "tabindex": "-1", } tooltip_attributes = hg.merge_html_attrs(tooltip_attributes, attributes) icon = _get_icon(icon) super().__init__( # tooltip label hg.DIV( label, # cannot use bread's Button class because # only the class bx--tooltip__trigger can be used hg.DIV( icon, **trigger_attributes, ), id=label_id, _class=base_class + "__label", ), # the real tooltip goes here hg.DIV( hg.SPAN(_class=base_class + "__caret"), hg.DIV( hg.If( bool(heading), hg.H4( heading, id=base_id + "-heading", _class=base_class + "__heading", ), ), hg.P(body, id=base_id + "-body"), hg.If( len(footer_elements) > 0, hg.DIV( *footer_elements, _class=base_class + "__footer", ), ), **tooltip_content_attributes, ), hg.SPAN(tabindex="0"), **tooltip_attributes, ), )
def __init__(self, menu: "bread.menu.Menu", **kwargs): kwargs["_class"] = hg.BaseElement( kwargs.get("_class", ""), " bx--side-nav bx--side-nav--rail", hg.If( HasBreadCookieValue("sidenav-hidden", "true"), "", " bx--side-nav--expanded", ), ) kwargs["data_side_nav"] = True super().__init__( hg.NAV( hg.UL( hg.Iterator( hg.F(lambda c: (i for i in sorted( hg.resolve_lazy(menu, c)._registry.values()) if i.has_permission(c["request"]))), "menugroup", hg.LI( hg.If( hg.F(lambda c: len(c["menugroup"].items) > 1 or c["menugroup"].force_show), hg.BaseElement( hg.BUTTON( hg.DIV( Icon(hg.C("menugroup.iconname"), size=16), _class="bx--side-nav__icon", ), hg.SPAN( hg.C("menugroup.label"), _class= "bx--side-nav__submenu-title", ), hg.DIV( Icon("chevron--down", size=16), _class= "bx--side-nav__icon bx--side-nav__submenu-chevron", ), _class="bx--side-nav__submenu", type="button", aria_haspopup="true", aria_expanded=hg.If( isactive("menugroup"), "true"), ), hg.UL( hg.Iterator( hg.F(lambda c: (i for i in sorted( c["menugroup"].items) if i. has_permission(c[ "request"]))), "menuitem", hg.LI( hg.A( hg.SPAN( hg. C("menuitem.link.label" ), _class= "bx--side-nav__link-text", ), _class=hg.BaseElement( "bx--side-nav__link", hg.If( isactive( "menuitem"), " bx--side-nav__link--current", ), ), href=hg.C( "menuitem.link.href"), ), _class=hg.BaseElement( "bx--side-nav__menu-item", hg.If( isactive("menuitem"), " bx--side-nav__menu-item--current", ), ), ), ), _class="bx--side-nav__menu", ), ), hg.A( hg.DIV( Icon( hg. C("menugroup.items.0.link.iconname" ), size=16, ), _class="bx--side-nav__icon", ), hg.SPAN( hg.C("menugroup.items.0.link.label"), _class="bx--side-nav__link-text", ), _class=hg.BaseElement( "bx--side-nav__link", hg.If( isactive("menugroup"), " bx--side-nav__link--current", ), ), href=hg.C("menugroup.items.0.link.href"), ), ), _class=hg.BaseElement( "bx--side-nav__item", hg.If(isactive("menugroup"), " bx--side-nav__item--active"), ), ), ), _class="bx--side-nav__items", ), hg.FOOTER( hg.BUTTON( hg.DIV( Icon( "close", size=20, _class= "bx--side-nav__icon--collapse bx--side-nav-collapse-icon", aria_hidden="true", ), Icon( "chevron--right", size=20, _class= "bx--side-nav__icon--expand bx--side-nav-expand-icon", aria_hidden="true", ), _class="bx--side-nav__icon", ), hg.SPAN( "Toggle the expansion state of the navigation", _class="bx--assistive-text", ), _class="bx--side-nav__toggle", onclick= "setBreadCookie('sidenav-hidden', getBreadCookie('sidenav-hidden', 'false') != 'true');", ), _class="bx--side-nav__footer", ), _class="bx--side-nav__navigation", ), **kwargs, )