Files
Bubberstation/tgui/docs/chat-embedded-components.md
LemonInTheDark 12a90800c5 Adds tooltips to /tg/c keywords. Adds support for chat embedded tgui components (#65383)
* Refactors tcg code a bit. Adds support for "keywords"

Idea is to allow card makers to embed tooltips in their card
descriptions.
These tooltips are defined in the keywords.json file
They can be referenced using {$keyword_name}

I've also done some refactoring to move more logic and state onto the
subsystem, and implemented a few keywords from the wiki

* New keywords, applies the old ones to the second card set

* Adds support for embedding react components in tgui chat

This is done by adding the data-component attribute to an html element
The value of that attibute is the component you want to use.
New components can be added by modifying the TGUI_CHAT_COMPONENTS list
in tgui-panel/chat/renderer.js.

Props can also be passed in in a limited capacity.
Any props you wish to pass must be added to
TGUI_CHAT_ATTRIBUTES_TO_PROPS.
This is due to a style restriction of html attributes, they cannot
contain an upper case char.
Use this list to convert between attibute compatible text and the prop's
name.

Props support 3 datatypes.
true and false can be passed by wrapping them in ""s. (Note to self add
a special char here to prevent colison with people just passing the
string true.
Numbers are supported in a limited capacity. Whitespace is not allowed,
but floats and ints are fair game.
And of course, strings are fully supported.

I've currently added support for Tooltip, since that's what I'm using
this for. Also added some tooltip html styles to the chat css.

* Implements the embedded component system to make tcg cards have nice pretty tooltips so people don't need to have the wiki open on one screen

* Adds documentation for embedding tgui components in chat, adds some protection against accidentially sending true as a bool

* Adds italitcs to the tooltips, moves the span stuff to a macro

* tGUI -> tgui, thank fikou

Co-authored-by: Fikou <23585223+Fikou@users.noreply.github.com>

* Style suggestions

Co-authored-by: Aleksej Komarov <stylemistake@gmail.com>

* Removes unneeded key from the components list

Co-authored-by: Aleksej Komarov <stylemistake@gmail.com>

* Removes needless span

* Actually adds the tooltip, oops

Co-authored-by: Fikou <23585223+Fikou@users.noreply.github.com>
Co-authored-by: Aleksej Komarov <stylemistake@gmail.com>
2022-03-15 11:36:31 +02:00

3.2 KiB

Chat Embedded Components

Have you ever embedded html into tgui chat? Maybe just css stuff like <span class='alien'> </span>? Have you ever wanted to embed tgui components instead? For styling or ease of use of course.

Well we have a system for that! You can pass component information in via html attributes, and it'll be rendered in chat. How? Let's get into it.

How it works

Here's a sample span that embeds a tooltip around the wrapped text.

<span data-component=\"Tooltip\" data-content=\"Hey it works!\">Does it work?</span>

There's two components here, let's break them down.

Targeting a component

Telling tgui chat what component you want to render is really simple. You just embed its name in the data-component attribute.

You saw it before, but for reference, <div data-component=\"Tooltip\"></div> this tells the div to render a tooltip.

There is a bit of nuance here however.

We can't embed components that haven't been prewhitelisted.

This isn't because of security concerns or anything, we just can't lookup components by their name without creating a lookup table. You can find that in tgui chat's renderer under the name TGUI_CHAT_COMPONENTS

Adding a new component is simple, just add it's name to the dictionary, and import it into the file.

Sending props

Ok, so we know how to render a component, but that's nearly useless unless we also know how to send extra info alongside it.

So how's that work?

The syntax is similar to sending a component, but has a bit more caveats. We have two bits of info to contend with. The name of the prop, and it's value. First then, how do you send the name of a prop?

Sending a prop's name

<span {component setting} data-content={value}></span

It's really simple, just another data attribute, with the name you want to refer to the property by.

Something important to note here, data attribute names cannot contain any upper case chars, or anything that isn't XML compatible.

Because of this, we need to do another map of sent name -> intended name. This can also be found in the renderer file with the name TGUI_CHAT_ATTRIBUTES_TO_PROPS

Sending a prop's value

Setting a prop's value is as simple as giving the data-content attribute a string value.

This does mean that we can only send strings to javascript. Because of this, we do some parsing js side to pull out other values you may want to send.

There's three supported datatypes.

Booleans

Booleans are send by sending a string in the form data-bool=\"$true\" and "data-bool=\"$false\" The $ char is included to allow you to send the string "true" without breaking anything.

Please keep this restriction in mind.

Numbers

Numbers are simpler then the above. If you send a string with no whitespace that can be parsed as an int or float, it will be.

So data-int=\"-10\" will be parsed as -10

data-float=\"10.2\" will also be correctly handled, treated as 10.2

Strings

Strings are the most simple. If a value is passed to an html attribute, and it doesn't meet any of the above requirements, it will be

data-string=\"hey man, it works!\"