Tag
Tags represent a set of interactive keywords that help to label, organize, and categorize objects.
This is the API of the Tag component, all HTML attributes and JS properties correspond to the table below, you can use them to customize how your tag looks.
Passing complex data via HTML attributes
Any properties that aren't Functions
can be given value via HTML attributes,
simply by writing `data-ts.${propertyName}=${encodedValue}`
.
When passing complex data structures as HTML attributes, you need to
JSON.stringify()
the value and then pass it to
encodeURIComponent
to get a string that can be safely used as an attribute.
We supply ts.ui.encode()
as a helper function that does just this.
Now that you know how to pass complex data to components, it's time to go through the different kinds of things the tag can do.
Value-only
Any non-string
passed to data
will be converted into a
Map
, using non-unique keys
will result in
unreliable behavior!
Values are simple descriptors, with lighter font weights and lowercase characters. To
render, use a Map
-like Array
with only a value
and
a falsy key
.
It's also possible to set data
(and all other attributes) later, through the JS
API.
-
<script> ts.ui.ready(() => { ts.ui.get('#tag-roll20', tag => { tag.data = new Map([ [null, 'Roll a d20'] ]); }); }); </script> <figure id="tag-roll20" data-ts="Tag"> </figure>
-
Key-Value
If you need a key
with a value
attached to it, use the
Map
-like Array
structure like before, but with a
key
and a value
this time.
-
<script> const data = ts.ui.encode( [ ['Area of Origin', 'The Sword Coast'] ] ); </script> <figure data-ts="Tag" data-ts.data="%5B%5B%22Area%20of%20Origin%22%2C%22The%20Sword%20Coast%22%5D%5D"> </figure>
-
Key with multiple values
You can have a single key
with multiple values
, just make the
value
part of the Map
-like Array
an
Array
.
-
<script> const data = ts.ui.encode( [ ['The Teeming Hive of Evil', ['Skullport', 'Port of Shadows']] ] ); </script> <figure data-ts="Tag" data-ts.data="%5B%5B%22The%20Teeming%20Hive%20of%20Evil%22%2C%5B%22Skullport%22%2C%22Port%20of%20Shadows%22%5D%5D%5D"> </figure>
-
Multiple keys with single value
Of course you could flip it around and use several
keys
for a single value
.
-
<script> const data = ts.ui.encode( [ [['Facial Tentacles', 'Potent Psionics'], 'Mind Flayer'] ] ); </script> <figure data-ts="Tag" data-ts.data="%5B%5B%5B%22Facial%20Tentacles%22%2C%22Potent%20Psionics%22%5D%2C%22Mind%20Flayer%22%5D%5D"> </figure>
-
Multiple keys with multiple values
It comes naturally that you can have several
keys
together with several values
.
-
<script> const data = ts.ui.encode( [ [['Magic-user', 'Undead'], ['Lich', 'Vampire']] ] ); </script> <figure data-ts="Tag" data-ts.data="%5B%5B%5B%22Magic-user%22%2C%22Undead%22%5D%2C%5B%22Lich%22%2C%22Vampire%22%5D%5D%5D"> </figure>
-
Multiple sets of key-values
If you want to have several key
/value
sets in a single tag, just
have more entries in your Map
-like Array
.
-
<script> const data = ts.ui.encode( [ ['Acererak'], ['Alignment', ['Lawful', 'Evil']], ['Hobbies', 'Building Dungeons'], ] ); </script> <figure data-ts="Tag" data-ts.data="%5B%5B%22Acererak%22%5D%2C%5B%22Alignment%22%2C%5B%22Lawful%22%2C%22Evil%22%5D%5D%2C%5B%22Hobbies%22%2C%22Building%20Dungeons%22%5D%5D"> </figure>
-
Clickable look & click handler
If you want to make your tag look like it can be clicked, once you've initialized your
tag, set the onclick
handler.
-
<script> const data = ts.ui.encode( [ ['Vision', ['Blindsight', 'Truesight', 'Darkvision']] ] ); ts.ui.ready(() => { ts.ui.get('#tag-clickable', tag => { tag.onclick = () => { ts.ui.Notification.success('Do you see?'); }; }); }); </script> <figure id="tag-clickable" data-ts="Tag" data-ts.data="%5B%5B%22Vision%22%2C%5B%22Blindsight%22%2C%22Truesight%22%2C%22Darkvision%22%5D%5D%5D"> </figure>
-
You can use your own click handler if you'd like.
Make sure to set data-ts.clickable="true"
, otherwise your tag won't look
like it's clickable.
-
<script> const data = ts.ui.encode( [ ['Vision', ['Blindsight', 'Truesight', 'Darkvision']] ] ); ts.ui.ready(() => { ts.ui.get('#tag-clickable-ownhandler', tag => { tag.element.addEventListener('click', e => { ts.ui.Notification.success('Do you see?'); }); }); }); </script> <figure id="tag-clickable-ownhandler" data-ts="Tag" data-ts.clickable="true" data-ts.data="%5B%5B%22Vision%22%2C%5B%22Blindsight%22%2C%22Truesight%22%2C%22Darkvision%22%5D%5D%5D"> </figure>
-
Delete button & delete handler
If you want to be able to remove a tag, once you've initialized the tag, set the
ondelete
handler. This will create a DEL
element as the last
child of the tag.
When the DEL
element is clicked, the tag will be removed from the DOM after
a setTimeout
. Don't try to read anything through the DOM at this point.
-
<script> const data = ts.ui.encode( [ ['Languages', ['Sylvan', 'Common', 'Draconic', 'Giant']] ] ); ts.ui.ready(() => { ts.ui.get('#tag-deletable', tag => { tag.ondelete = () => { ts.ui.Notification.info('Tag disintegrated!'); } }); }); </script> <figure id="tag-deletable" data-ts="Tag" data-ts.data="%5B%5B%22Languages%22%2C%5B%22Sylvan%22%2C%22Common%22%2C%22Draconic%22%2C%22Giant%22%5D%5D%5D"> </figure>
-
Just like with click
, you can use your own click handler for deletion if
you'd like.
You have to remember that only react when the user clicks on the
DEL
element by checking for e.target.localName
.
-
<script> const data = ts.ui.encode( [ ['Languages', ['Sylvan', 'Common', 'Draconic', 'Giant']] ] ); ts.ui.ready(() => { ts.ui.get('#tag-deletable-ownhandler', tag => { tag.element.addEventListener('click', e => { if (e.target.localName === 'del') { ts.ui.Notification.info('Tag disintegrated!'); } }); }); }); </script> <figure id="tag-deletable-ownhandler" data-ts="Tag" data-ts.deletable="true" data-ts.data="%5B%5B%22Languages%22%2C%5B%22Sylvan%22%2C%22Common%22%2C%22Draconic%22%2C%22Giant%22%5D%5D%5D"> </figure>
-
Delete & Remove
If you want the user to confirm before you remove the tag from the DOM. You need to set
doremove
to false first, and call remove
on your confirm
callback
-
<script> const data = ts.ui.encode( [ ['Languages', ['Sylvan', 'Common', 'Draconic', 'Giant']] ] ); ts.ui.ready(() => { ts.ui.get('#tag-remove', tag => { tag.doremove = false; tag.ondelete = () => { ts.ui.Dialog.confirm('Do you want to delete the tag?', { onaccept: function() { tag.doremove = true; tag.remove(); ts.ui.Notification.success('Tag removed'); }, oncancel: function() { ts.ui.Notification.success('No, I do not want to delete it'); } }); }; }); }); </script> <figure id="tag-remove" data-ts="Tag" data-ts.data="%5B%5B%22Languages%22%2C%5B%22Sylvan%22%2C%22Common%22%2C%22Draconic%22%2C%22Giant%22%5D%5D%5D"> </figure>
-
Click & delete
In case you want to handle clicks
and have a delete
button on
the same tag, you can do that the same way as above.
-
<script> const data = ts.ui.encode( [ ['Beholder', 'Xanathar'] ] ); ts.ui.ready(() => { ts.ui.get('#tag-delete-click', tag => { tag.onclick = () => { ts.ui.Notification.info('Don\'t poke the beholder!'); }; tag.ondelete = () => { ts.ui.Notification.warning('I hope you know what you\'re doing...'); } }); }); </script> <figure id="tag-delete-click" data-ts="Tag" data-ts.data="%5B%5B%22Beholder%22%2C%22Xanathar%22%5D%5D"> </figure>
-
You can always handle your own clicks
if that's what you're into.
You still have to remember that only handle the delete
click
when the user clicks on the DEL
element by checking for
e.target.localName
.
-
<script> const data = ts.ui.encode( [ ['Beholder', 'Xanathar'] ] ); ts.ui.ready(() => { ts.ui.get('#tag-delete-click-ownhandler', tag => { tag.element.addEventListener('click', e => { if (e.target.localName === 'del') { ts.ui.Notification.warning('I hope you know what you\'re doing...'); } else { ts.ui.Notification.info('Don\'t poke the beholder!'); } }); }); }); </script> <figure id="tag-delete-click-ownhandler" data-ts="Tag" data-ts.clickable="true" data-ts.deletable="true" data-ts.data="%5B%5B%22Beholder%22%2C%22Xanathar%22%5D%5D"> </figure>
-
Locked look
If you want to lock down a tag, use
data-ts.locked="true"
.
A locked tag will have its DEL
button hidden and all
click
-related styling deactivated.
-
<script> const data = ts.ui.encode( [ ['Dungeon', 'Hidden Shrine of Tamoachan'] ] ); </script> <figure data-ts="Tag" data-ts.locked="true" data-ts.data="%5B%5B%22Dungeon%22%2C%22Hidden%20Shrine%20of%20Tamoachan%22%5D%5D"> </figure>
-
If you find a bug or need a feature…