Page MenuHomePhabricator

Provide tiny JS library for CSS-only Codex components
Open, Needs TriagePublic

Description

Some users of Codex are unable to use Vue and must use CSS-only components. The docs are great as explaining how to accomplish this. However, the markup structure can be quite complex. For a JavaScript application that needs to dynamically create CSS-only Codex components, we are forced into much tedious manual HTML construction, i.e.:

const wrapper = document.createElement( 'span' );
wrapper.className = 'cdx-checkbox cdx-checkbox--inline';
const input = document.createElement( 'input' );
input.className = 'cdx-checkbox__input';
input.id = `cm-mw-panel--checkbox-mycheckbox`;
input.type = 'checkbox';
input.name = name;
input.checked = checked;
wrapper.appendChild( input );
const emptyIcon = document.createElement( 'span' );
emptyIcon.className = 'cdx-checkbox__icon';
wrapper.appendChild( emptyIcon );
const labelWrapper = document.createElement( 'div' );
labelWrapper.className = 'cdx-checkbox__label cdx-label';
const labelElement = document.createElement( 'label' );
labelElement.className = 'cdx-label__label';
labelElement.htmlFor = input.id;
const innerSpan = document.createElement( 'span' );
innerSpan.className = 'cdx-label__label__text';
innerSpan.textContent = mw.msg( 'my-checkbox' );
labelElement.appendChild( innerSpan );
labelWrapper.appendChild( labelElement );
wrapper.appendChild( labelWrapper );

All of that for a single checkbox!

MediaWiki-extensions-CodeMirror is one such example. In an effort to reduce repetition, we have essentially made a tiny wrapper for Codex components. The next JS application that can't use Vue but wants to use Codex will presumably have to do the same all over again. I think a library would be beneficial for this purpose.

CodeMirror currently implements:

The library would ensure the markup is always correct according to Codex specifications, perhaps giving more freedom to DST to make what would otherwise be breaking changes.

It could also implement Dialog (example), which I understand is not currently advertised as a CSS-only component. If we can offer users of Codex the JS to use, then Dialog can "officially" be offered for non-Vue users (though I guess you couldn't call it "CSS-only").

Event Timeline

I had this as a sub-task of T375220 since my helper methods are using mw.msg, but I guess there's no real reason to make this exclusive for use in MediaWiki. Removing parent task.

Anyway, I think it's reasonable to assume the MediaWiki frontend will not ever be written exclusively in Vue. Codex PHP will do the job for a lot of situations where we can't or don't wish to use Vue, but not for dynamically created elements.

Have you considered using mustache templates to simplify this? ResourceLoader already has some tools for working with client-side mustache templates. This would let you write much more legible code. Vue templates are similar to mustache but not 100% compatible – however, it would be very easy to adapt things. You probably wouldn't need all the logic from the original component template anyway, just a subset of whatever is relevant for your feature.

If you had a bunch of small templates (one for Checkbox, one for Input, etc) then you could load them with arbitrary data on the fly to populate your page. You could probably even defer loading particular Codex component styles until the first time you called a particular mustache template to keep the initial payload size down.

Ooh! I had forgotten we still have Mustache! That does seem more appropriate here. Thanks :)

I guess it's still the same situation, though. I built what I needed for CodeMirror, but I'm assuming other use cases will pop up over the years. The mustache templates could be part of this proposed library, I suppose.

Anyway, if no one else has a use for this hypothetical lib, there's no need to pursue this. Feel free to remove Design-System-Team or whatever you feel is appropriate.

Thanks @MusikAnimal, I think we can keep this open but we'll just backlog it for now.