Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

User API: communicate with the library #13

Closed
humitos opened this issue Mar 20, 2023 · 6 comments
Closed

User API: communicate with the library #13

humitos opened this issue Mar 20, 2023 · 6 comments

Comments

@humitos
Copy link
Member

humitos commented Mar 20, 2023

There are many integrations that will require some user configuration. For example:

  • HTML templates: there are some integrations that use HTML templates to render (e.g. flyout, non latest version warning, external version warning). We need to design a way users can tell the library what HTML template to use or giving them a way to replace ours completely (as flyout is doing via #readthedocs-embed-flyout) 1
  • Functions with logic: we are using semver to decide if the current version is the highest. However, the user may be using CalVer or a custom versioning pattern. We should allow users to tell us what's the "function that returns the highest version from a list of versions" that we should execute.
  • Element query selectors:
    • what's the selector for the main content?
    • what's the content selector to apply tooltips to the inner links?
    • what's the selector for the search-as-you-type be triggered?
    • etc
  • Data for functions:
    • default filter for search
    • extra filters for search
  • Tooltips:
    • should we apply them to all the content?
    • should we only apply them on a specific selector? (as we currently do with .hoverxref class)
    • should the doctool generate HTML tags with this specific selector?
    • should we try a defined selector and fallback to the main content if not found?

Note there may be more things to consider here, but I wanted to mentioned the ones that I found while working on this library. I'd like to define the pattern first, since once we have that defined we can easily add more. I'm looking for "the standard pattern to communicate with a js library from the browser", basically.

Also, it's worth to mention that some of them can be converted to conventions (e.g. some selectors) but we need to discuss and agree on them anyways.

Footnotes

  1. this work may require writing a policy that users should follow since they can overwrite our templates completely. We may want to "enforce" projects to show "Hosted by Read the Docs" or similar in the flyout, for example.

@humitos
Copy link
Member Author

humitos commented Apr 6, 2023

There were some progress in this direction. I'd say, mainly in my understand of what we need from the user and how this could work in the js world. With the addition of WebComponens, CSS variables and others it's a lot more clear to me how people will interact with this library in some of the required ways. There is no decided made already about this, but I guess that:

  • we will expose some CSS variables
  • users can define CSS variables if they want to change a particular style from the UI
  • users will use data- attributes or specific CSS classes to specify pre-defined styles for our addons
  • we will define some custom WebComponents
  • people can place the HTML component whenever they want in the HTML; if there is one present, we won't include "the default one"
  • to customize HTML structure for those WebComponents we will probably use <slots> that users can override with the content they prefer
  • to customize "logic" of the webcomponents we could use data- attributes 1 to override some "exposed functions"

This my mental map currently. Does this make sense to you @agjohnson?

If possible, addons will always have "nice defaults" and conventions. However, there are some that may require specific selectors (e.g. docdiff needs to know the "main" tag where the content is). Would these also be data- attributes? In the specific case of docdiff, it may not make sense since it does not require a HTML tag to be inserted, so it may need to be a js call? Like readthedocs.addons.docdiff.init({selector: "[role=main]"})?

Footnotes

  1. is there a better way to communicate this logic customization? I image something like <readthedocs-version-banner data-versioning-type="semver"></readthedocs-version-banner>

@agjohnson
Copy link
Contributor

For the most part, that is what I'm aiming for as well 👍

Some minors notes:

to customize HTML structure for those WebComponents we will probably use

I've only played lightly with a pattern to customize the template, and haven't yet experimented with slots yet. So, this is a bit of a gap in my understanding, but I think it seems like a path forward.

For now, we can also take the position that we're not providing this level of customization and users would have to roll their own implementations if ours don't fit their needs exactly.

I haven't yet determined if it's possible, but this would be nice from an author's aspect:

<readthedocs-notification>
  <!-- template goes here -->
  <div class="bootstrap-classes etc">
    <h1>${this.title}</h1>
    <p>${this.message}</p>
  </div>
</readthedocs-notification>

to customize "logic" of the webcomponents we could use data- attributes

Web components don't need to use data attributes even, as the reason for data attributes in the first place is to avoid collision with native element attributes, or at least to provide some distinction between native/custom attributes.

For a web component, all attributes are custom, so we'd instead have something like <readthedocs-notification version-pattern="semver"></readthedocs-notification>

However, there are some that may require specific selectors (e.g. docdiff needs to know the "main" tag where the content is).

Great points. I haven't had time to reason about on this question/pattern yet, so have to focus on this at some point next.

One thing I'm considering for some amount of configuration for these features is that some of the individual component configuration will come from perhaps the dashboard UI. I'd agree that a web component isn't a good fit for doc diff, as it affects the whole page and not one element.

I could see us having a project settings tab for "Pull requests", and the option to enable pull requests is moved there, but also the doc diff configuration is moved into the same view. This feels intuitive. For example, it would have a form:

☑️ Enable pull request builds
☑️ Show documentation diff by default on pull request builds
☑️ Hide removed content on documentation diff by default

But the programmatic approach in addition to this is also probably something we want -- though I'm less certain of the pattern there just yet.

@humitos
Copy link
Member Author

humitos commented Apr 17, 2023

This issue is also related to #51

humitos added a commit that referenced this issue Apr 19, 2023
By default the search modal is shown when pressing `/`.
However, we want this to be configurable by the user.
This can be achieved by passing `show-modal-keycode` attribute to the web
component as follows:

```html
<readthedocs-search show-modal-keycode="220">
</readthedocs-search>
```

In this case, it will be shown when pressing `\`.

I think this is a good pattern for static values that won't be changed from the
dashboard or similar in a dynamic way.

Related #13
@humitos
Copy link
Member Author

humitos commented Apr 19, 2023

For a web component, all attributes are custom, so we'd instead have something like <readthedocs-notification version-pattern="semver"></readthedocs-notification>

I did an initial test for this at #56 and I'm happy with the results. Seems pretty straightforward and easy to understand with pretty basic knowledge of HTML 👍🏼

humitos added a commit that referenced this issue Apr 19, 2023
By default the search modal is shown when pressing `/`. However, we want
this to be configurable by the user. This can be achieved by passing
`show-modal-keycode` attribute to the web component as follows:

```html
<readthedocs-search show-modal-keycode="220">
</readthedocs-search>
```

In this case, it will be shown when pressing `\`.

I think this is a good pattern for static values that won't be changed
from the dashboard or similar in a dynamic way.

Related #13
@agjohnson
Copy link
Contributor

Can this issue be closed maybe? We have some minor configuration elements we want to add, but maybe those should be individual issues or issues for later, as we take the work on?

@humitos
Copy link
Member Author

humitos commented Mar 4, 2024

I think it's fine to close it. We have discussed a lot about this and we are moving towards being able to configure each of the addons via the WebUI from project's settings. We have done some work there and we currently can enable/disable them --but we will also have some per-addon configuration as exposes the PR: readthedocs/readthedocs.org#11069

@humitos humitos closed this as completed Mar 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

No branches or pull requests

2 participants