TiddlyWiki / TiddlyWiki5

A self-contained JavaScript wiki for the browser, Node.js, AWS Lambda etc.
https://tiddlywiki.com/
Other
8.09k stars 1.19k forks source link

[IDEA] custom $$checkbox widget with user controlled HTML output #7255

Open pmario opened 1 year ago

pmario commented 1 year ago

This idea is related to #6666 Parameterised transclusions and the closed issue: [IDEA] The checkbox widget should get a second class for the "inner text" #7229

I did try the following code with this wiki https://tiddlywiki5-55syo9i24-jermolene.vercel.app/ trying to make the checkbox-widget more flexible according to the DOM structure created. Mainly because of accessibility concerns mentioned in relation to the LABEL element.

The current checkbox-widget in v5.2.5 creates the following DOM structure, which is OK, but has some flexibility problems. The main reason to have the LABEL element as a wrapper is, that users can click the label-text or the checkbox. Both actions will trigger the check-event.

<label>
  Do you like peas?
  <input type="checkbox" name="peas" />
</label>

I did try to create a more flexible version of the checkbox widget by reusing the current implementation and a custom-widget $$checkbox with largely simplified interface (only tiddler and tag for testing)

This code works with code from #6666 ... but ... the tc-checkbox-checked class is assigned to the wrong element, since it is hardcoded in the JS-code.

To be useful with #6666 the core checkbox-widget would need a parameter eg: checkedSelector with which the element that should get the class can be identified.

\widget $$checkbox(tiddler, tag)
<!-- the element with class="lets-check" should get the class="tc-checkbox-checked" if checked -->
<div class="wrapper-if-needed">
    <$checkbox tiddler={{{ [<tiddler>!match[]else<currentTiddler>] }}} tag=<<tag>> checkedSelector=".lets-check" labelTemplate="label-template-tiddler">
        <label class="lets-check">
            <$slot $name="ts-raw"/>
        </label>
    </$checkbox> - tiddler: {{{ [<tiddler>!match[]else<currentTiddler>] }}} 
</div>
\end

Test it with:

<$$checkbox tiddler=hugo tag=done>label 1</$$checkbox>

<$$checkbox  tag=done>label 2</$$checkbox>

Since we do not want to expose the ID attribute, with the following wikitext and a checkedSelector it will be possible to create a DOM structure that looks like this. The JS code has enough information to know where the ID and the FOR parameters have to be assigned, without the need to expose them to the users.

<div class="wrapper-if-needed">
    <input type="checkbox" id="random-number">
    <label class="lets-check" for="random-number">
        label 1
    </label>
     - tiddler: <span><a class="tc-tiddlylink tc-tiddlylink-missing" href="#hugo">hugo</a></span> 
</div>

@Jermolene ...

your thoughts?

Jermolene commented 1 year ago

Thanks @pmario

your thoughts?

Fundamentally, I see this as being about being able to support IDs within generated wikitext in a flexible way. There are quite a few scenarios where it would be helpful to be able to work with IDs:

With the respect to the checkbox problem at hand, the ideal solution would be extensible to cover these other scenarios, and not just restricted to this specific use case. Having said that, these cases where the IDs are only needed within a self-contained subtree of the DOM are clearly amenable to solutions that wouldn't work across subtrees.

In the very early days of TW5, back in 2011/12, I spent quite a lot of time working on this. I was mainly interested in being able to use complex fills within our embedded SVG icons. I'll have to have a dig back through the code to remember exactly where things got to.

pmario commented 1 year ago

One of a later discussions about SVGs and IDs: [IDEA] Enhance SVG support #6758

I think I can vaguely remember a discussion about SVGs and ID using the SVG "use" option, which I did want to have very early on after using something similar in TWClassic for custom buttons.

pmario commented 1 year ago

Just some notes ... (that may only make sense for me ;)

While for the ID in the OP it's perfectly OK to be completely random, since it does not need to be reused. ..

On the other hand for dynamically created SVGs, based on predefined fragments, like in "use", the IDs need to be "random" to avoid name clashes, but they need to be "predictable" too. Because the creation time of the fragments is completely different to the SVGs. But they still need to know the fragments by ID :/

So the whole "random tiddler" discussion is somewhat related here too.