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

HTML labels for radio/checkbox options #412

Merged
merged 8 commits into from
Nov 4, 2024
Merged

Conversation

ianroberts
Copy link
Member

@ianroberts ianroberts commented Nov 3, 2024

Summary

Add the ability to specify an htmlLabel instead of a plain text label for radio and checkbox options. The motivating use case was a feature request from a user within the GATE team who wanted to be able to add colours to their checkbox labels, e.g. green for positive sentiment, red for negative, but HTML labels would open up other possibilities, e.g. adding margin-bottom to certain options to separate a long list of radio choices into logical groups (#404).

Implementation

I've added handling for htmlLabel to the generateBVOptions function, whereby if htmlLabel is set in an option in the project config (or a fromDocument field) then it adds an html property to the generated option object. CheckboxInput and RadioInput look for this html property, and if found they render it into a span with v-html and ignore the usual text. If there is no HTML label then the text label is rendered in the normal way.

I've also added some special CSS classes tw-space-(above|below)-[1-5] that you can apply to an element inside the htmlLabel that do the equivalent of adding the Bootstrap margin classes mt-[1-5] or mb-[1-5] to the containing div that holds that label and its associated checkbox. These can be used to visually separate groups of logically-related options.

Examples

Coloured option labels

{
    "name": "sentiment",
    "type": "checkbox",
    "title": "Sentiment",
    "options": [
        {"value": "positive", "htmlLabel": "<span style='color: green'>Positive</span>"},
        {"value": "neutral", "htmlLabel": "<span style='font-style: italic'>Neutral</span> or uncertain"},
        {"value": "positive", "htmlLabel": "<span style='color: red'>Negative</span>"}
    ]
}

Separating options into groups

{
  "name": "longlist",
  "type": "radio",
  "options": [
    {"value": "group1optA", "label": "Option 1a"},
    {"value": "group1optB", "label": "Option 1b"},
    {"value": "group1optC", "htmlLabel": "<span class='tw-space-below-4'>Option 1c</span>"},
    {"value": "group2optA", "label": "Option 2a"},
    {"value": "group2optB", "label": "Option 2b"},
    {"value": "group2optC", "label": "Option 2c"}
  ]
}

@ianroberts ianroberts requested a review from twinkarma November 3, 2024 00:47
@ianroberts ianroberts changed the base branch from master to dev November 3, 2024 00:49
@ianroberts ianroberts force-pushed the feat/html-radio-labels branch from 2240ec3 to 445cc8e Compare November 3, 2024 10:47
Copy link

github-actions bot commented Nov 3, 2024

Jest Coverage

File % Stmts % Branch % Funcs % Lines Uncovered Line #s
All files 83.83 83.17 64 83.83
File % Stmts % Branch % Funcs % Lines Uncovered Line #s
All files 83.83 83.17 64 83.83
_jrpc 94.11 91.66 83.33 94.11
_ index.js 94.11 91.66 83.33 94.11 29-30,38-40
_utils 82 82.1 57.89 82
_ annotations.js 97.75 70.83 100 97.75 35-36
_ dict.js 88.88 83.33 100 88.88 3-4
_ expressions.js 80.08 82.35 80 80.08 ...,188-190,201-218
_ index.js 73.6 100 14.28 73.6 ...4-65,76-82,93-94

@ianroberts
Copy link
Member Author

This PR also includes various changes to the workflows and test harness to make them compatible with the current ubuntu-latest actions runner, which has been upgraded since we last used it and now uses compose v2 (i.e. docker compose with a space) instead of v1 (docker-compose as a separate command from docker). The deploy.sh script has borrowed the logic I was already using in get-teamware.sh so should be compatible with either - it uses docker compose if available, falling back to docker-compose if v2 is not found.

@ianroberts ianroberts marked this pull request as draft November 4, 2024 12:04
…adios

If a checkbox or radio option specifies "htmlLabel" then this will be rendered _as HTML_ instead of the regular "label" being rendered as text.  Use cases for this could be

- showing the labels in differnt colours `<span style='color:red'>Negative</span>`
- adding emphasis to particular parts of the label `<b>Reasonably</b> confident`
- adding margin to the bottom of an option to separate groups of related choices `<div style='margin-bottom: 1.5em'>Last option in this group</div>`
In newer docker versions, compose is a plugin to the docker command rather than a command in its own right.
Use inline-flex for the checkbox/radio `<label>` so that even if the label includes something like a div with bottom margin, the helptext popup still appears beside the label rather than underneath it
Added special classes to the CSS that users can add to a span or something inside an option's htmlLabel to affect the margin above or below the option as a whole (as opposed to just above or below the label).
@ianroberts ianroberts force-pushed the feat/html-radio-labels branch from 29ef3ca to 6d7ce11 Compare November 4, 2024 13:08
@ianroberts ianroberts marked this pull request as ready for review November 4, 2024 13:09
Comment on lines -14 to +15
{{ option.text }}
<span v-if="option.html" v-html="option.html"></span>
<span v-else>{{ option.text }}</span>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the core of the changes - if there's an HTML label then bind that with v-html, otherwise use the text label as before.

Comment on lines -17 to +22

// Import Bootstrap an BootstrapVue CSS files (order is important)
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'


//Importing scss assets needs an @/ in front of it

import "@/assets/sass/app.scss"

// Import Bootstrap an BootstrapVue CSS files (after app.scss, which includes bootstrap)
import 'bootstrap-vue/dist/bootstrap-vue.css'
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've changed app.scss to import the bootstrap sass directly, so we don't need to import the pre-compiled CSS as well.

// is equivalent to putting 'mb-4' on the option div itself.
@each $size, $length in $spacers {
@each $dir, $edge in (above:top, below:bottom) {
:is(.custom-checkbox, .custom-radio):has(.tw-space-#{$dir}-#{$size}) {
Copy link
Member Author

@ianroberts ianroberts Nov 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes use of the :has selector (supported since late 2022 in Chrome and relatives but only since the end of 2023 in Firefox) - I've introduced classes that you can put on an element inside the htmlLabel to influence the margins of the containing div for that option.

Copy link
Collaborator

@twinkarma twinkarma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes looks good to me!

@ianroberts ianroberts merged commit fa7b3b0 into dev Nov 4, 2024
7 checks passed
@ianroberts ianroberts deleted the feat/html-radio-labels branch November 4, 2024 15:54
This was referenced Nov 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants