Skip to content
This repository has been archived by the owner on Aug 14, 2021. It is now read-only.

Make docs a single page app #83

Open
BennyHinrichs opened this issue Sep 20, 2019 · 2 comments
Open

Make docs a single page app #83

BennyHinrichs opened this issue Sep 20, 2019 · 2 comments

Comments

@BennyHinrichs
Copy link
Contributor

I don't know much about Handlebars or the TypeDoc build process, but how hard would it be to turn the docs into an SPA? I ask mainly because I've added a dark theme toggle that uses the FilterItem class along with a bunch of CSS variables. The problem is that it flashes white every time you navigate, which is highly unfortunate. I'm pretty sure it's because it has to read from localStorage then set the CSS vars and propagate those down the tree. If it was an SPA, it would only need to read once, which I hope would prevent the flash.

I think the main issue would be doing the routing. I imagine we'd make a new partial called content and switch that out on navigation (probably have to split out .tsd-page-title from header), but the routes would have to be created during the TypeDoc build.

@Gerrit0
Copy link
Contributor

Gerrit0 commented Sep 21, 2019

It shouldn't be too difficult to create a custom theme that is a SPA, but the architecture just isn't there for doing it with the current default/minimal theme setup... the content partial sounds reasonable to me. I'd like to not break existing links to docs though, which could be difficult.

@BennyHinrichs
Copy link
Contributor Author

BennyHinrichs commented Sep 23, 2019

So with the current routes, it exists like base/?[class|enum|interface|module]/[:slug].html#hash. Something like that. Here's how I think the routing would have to work (I'm basing it off this article).

  1. Emit HTML partials instead of whole files; only one fully qualified HTML file is produced
  2. Have a <div id="content"></div> on the page
  3. Set up the router (suggestion: vanilla-router)
  4. Make our routing callback function that requests those HTML partials and puts it into #content mentioned above
  5. Call router.addUriListener() (or implement our own)
  6. Call router.navigateTo(window.location.pathname)
  7. Cache partials?

Then the routes we have to create are

  • router.add(baseLocation + '/', () => routeCb(null, 'index.html'))
  • router.add(baseLocation + '/(:name)', name => routeCb(null, name))
  • router.add(baseLocation + '/enum/(:name)', name => routeCb('enum', name))
  • router.add(baseLocation + '/classes/(:name)', name => routeCb('classes', name))
  • router.add(baseLocation + '/interfaces/(:name)', name => routeCb('interfaces', name))
  • router.add(baseLocation + '/modules/(:name)', name => routeCb('modules', name))

Routing callback sketch:

function routeCb(loc, name) {
  !partials && (partials = {});
  name.includes('#') && (name = name.slice(0, name.indexOf('#'));
  if (partials[`${loc}_${name}`]) {
    (contentDiv.innerHTML = partials[${loc}_${name}]);
  } else {
    fetch(`${baseLocation}/${loc ? `${loc}/` : ''}${name}`)
      .then(response => response.text())
      .then(text => {
        contentDiv.innerHTML = text;
        partials[`${loc}_${name}`] = text;
      )
  }
}

This is all rough, just throwing ideas out there.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants