sphinx-book-theme icon indicating copy to clipboard operation
sphinx-book-theme copied to clipboard

Pluggable infrastructure for top-bar widgets

Open chrisjsewell opened this issue 4 years ago • 10 comments

Currently, these are essentially hardcoded into sphinx-book-theme, and thus difficult for users to modify/extend.

With https://furo-topbar.readthedocs.io I've started to develop a pluggable "widget" bar for furo, but it should be possible for this to fit into https://github.com/pradyunsg/sphinx-basic-ng

chrisjsewell avatar Jan 19 '22 13:01 chrisjsewell

Related issues #462, #449, #114, #282, #360, #334, #326, #209, #119 (basically half the issues lol)

chrisjsewell avatar Jan 19 '22 13:01 chrisjsewell

Agree that this would be great. Perhaps a generalization of #462. In my opinion all of the "launch button" stuff should be inside of MyST NB and re-used here (and elsewhere).

What are the major components of a widget? Something like:

  • An icon
  • Text that is optionally displayed next to the icon (at different viewport widths)
  • More descriptive that is displayed with a hover
  • One of - A link, we redirect when you click it - A JS hook, it fires when you click it - A list of items inside, displayed when you click it or hover (can be the theme's decision)

choldgraf avatar Jan 21 '22 02:01 choldgraf

Here's one way to do all of those, as a list of dictionaries that the user can provide in their theme configuration.

[
    # Page
    {
        "label": "Page",
        "page": "page-one",
    },
    # Icon
    {
        "href": "https://github.com",
        "icon": '<svg><use href="#svg-github"></use></svg>',
    },
    # Icon with Label
    {
        "label": "Discord",
        "href": "https://discord.com",
        "icon": '<svg><use href="#svg-discord"></use></svg>',
    },
    # Icon with JS
    {
        "icon": '<svg><use href="#svg-fullscreen"></use></svg>',
        "onClick": "javascript:toggleFullScreen()",
        "tooltip": "Toggle full screen",
    },
    # Dropdown
    {
        "label": "Dropdown",
        "dropdown": [
            {
                "label": "Page",
                "page": "page-two",
            },
        ],
    },
]

I'm not sure how this would fit into sphinx-basic-ng (since this sort of thing would need additional Python-size validation + logic, which I don't want to add there -- keeping it limited to only injecting the right variables into templates and not dealing with any incoming configuration shenanigans). I guess, it could provide a validator for such a structure; leaving it upto themes to figure out how to convert this into HTML that works in their spaces?

pradyunsg avatar Jan 21 '22 13:01 pradyunsg

Guys have you actually read https://furo-topbar.readthedocs.io/? You seem to be quoting back to me what I've already written in there

chrisjsewell avatar Jan 21 '22 13:01 chrisjsewell

I have.

You have an explicit list of widgets there, each of which is special-cased in the actual logic as well. We're discussing a more general way to do things; that doesn't involve an explicit known set of widgets (which is literally q2).

There is:

{
"button_class": "clickable",
"button_title": "Scroll to top",
"button_onclick": "location.href='#top'",
"button": '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M4.97 12.97a.75.75 0 101.06 1.06L11 9.06v12.19a.75.75 0 001.5 0V9.06l4.97 4.97a.75.75 0 101.06-1.06l-6.25-6.25a.75.75 0 00-1.06 0l-6.25 6.25zM4.75 3.5a.75.75 0 010-1.5h14.5a.75.75 0 010 1.5H4.75z"></path></svg>',
}

Which... I'm proposing an alternative way to do above. :)

pradyunsg avatar Jan 21 '22 14:01 pradyunsg

As I say in the documentation, they are special cases at present, because it was the quickest way to it. But they should be pluggable e.g. via entry point, that other packages can provide, not just the theme itself, or users. For example, myst-nb would supply the entry-points for generation widgets to launch notebooks on binder. Your way does not appear to allow for this

chrisjsewell avatar Jan 21 '22 14:01 chrisjsewell

There will certainly be python logic required for anything other than basic buttons, and generally there will be a distinct set of these that users will want, that can be pre-defined (likely via entry-points)

chrisjsewell avatar Jan 21 '22 14:01 chrisjsewell

FYI I'm sure there is a middle ground, but we shouldn't over simplify, the onus should not be on the user to specify the HTMl for every widget

chrisjsewell avatar Jan 22 '22 07:01 chrisjsewell

FYI I took some of the ideas here and proposed a configuration structure / potential implementation in the pydata theme, since I think that we'd benefit from something like this with the recent "version switcher" stuff that got merged: https://github.com/pydata/pydata-sphinx-theme/issues/601 . It is similar to @chrisjsewell's implementation in the topbar theme, but it uses a list instead of a dictionary so that we could re-use the same widget type in the same area.

Maybe we can use that to prototype a configuration structure and get some feedback from users?

choldgraf avatar Feb 26 '22 22:02 choldgraf

Is there a workaround to customize the topbar with version 0.3 or do we have to wait until some flavour of the changes proposed here is implemented? With versions < 0.3, we made a _templates/topbar/launchbuttons.html file to add custom buttons that contained

<!-- Here, we override the default launchbuttons.html by replacing it with our
     version selection menu, since we do not intend to use the launchbuttons.
     This allows us to add the version selection menu in some unused white space
     that is always visible. -->
<div class="dropdown-buttons-trigger">
    <button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn" style="font-size: 1em;padding-top:0.33rem;">Scipp version
      <i class="fa fa-caret-down"></i>
    </button>

    <div class="dropdown-buttons" style="transform:translate(10%);">
        <a class="dropdown-buttons"
            href="https://scipp.github.io"><button type="button"
                class="btn btn-secondary topbarbtn">latest</button></a>
        <a class="dropdown-buttons"
            href="https://scipp.github.io/release/0.13.1"><button type="button"
                class="btn btn-secondary topbarbtn">v0.13</button></a>
        <a class="dropdown-buttons"
            href="https://scipp.github.io/release/0.12.1"><button type="button"
                class="btn btn-secondary topbarbtn">v0.12</button></a>
        <a class="dropdown-buttons"
            href="https://scipp.github.io/release/0.11.1"><button type="button"
                class="btn btn-secondary topbarbtn">v0.11</button></a>
        <a class="dropdown-buttons"
            href="https://scipp.github.io/release/0.10.1"><button type="button"
                class="btn btn-secondary topbarbtn">v0.10</button></a>
        <a class="dropdown-buttons"
            href="https://scipp.github.io/release/0.9.0"><button type="button"
                class="btn btn-secondary topbarbtn">v0.9</button></a>
        <a class="dropdown-buttons"
            href="https://scipp.github.io/release/0.8.4"><button type="button"
                class="btn btn-secondary topbarbtn">v0.8</button></a>
        <a class="dropdown-buttons"
            href="https://scipp.github.io/release/0.7.1"><button type="button"
                class="btn btn-secondary topbarbtn">v0.7</button></a>
        <a class="dropdown-buttons"
            href="https://scipp.github.io/release/0.6.1"><button type="button"
                class="btn btn-secondary topbarbtn">v0.6</button></a>
        <a class="dropdown-buttons"
            href="https://scipp.github.io/release/0.5.0"><button type="button"
                class="btn btn-secondary topbarbtn">v0.5</button></a>
        <a class="dropdown-buttons"
            href="https://scipp.github.io/release/0.4.0"><button type="button"
                class="btn btn-secondary topbarbtn">v0.4</button></a>
        <a class="dropdown-buttons"
            href="https://scipp.github.io/release/0.3.0"><button type="button"
                class="btn btn-secondary topbarbtn">v0.3</button></a>
    </div>
</div>
<div class="dropdown-buttons-trigger">
    <button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn" style="font-size: 1em;padding-top:0.33rem;">Related projects
      <i class="fa fa-caret-down"></i>
    </button>

    <div class="dropdown-buttons" style="transform:translate(10%);">
        <a class="dropdown-buttons"
            href="https://scipp.github.io"><button type="button"
                class="btn btn-secondary topbarbtn">scipp</button></a>
        <a class="dropdown-buttons"
            href="https://scipp.github.io/scippneutron"><button type="button"
                class="btn btn-secondary topbarbtn">scippneutron</button></a>
        <a class="dropdown-buttons"
            href="https://scipp.github.io/ess"><button type="button"
                class="btn btn-secondary topbarbtn">ess</button></a>
    </div>
</div>

Screenshot at 2022-04-07 11-51-33

Is there a temporary trick we can do to recover that behaviour before the more customizable mechanism is in place? Thanks!

nvaytet avatar Apr 07 '22 09:04 nvaytet