Skip to content

Latest commit

 

History

History
134 lines (100 loc) · 4.88 KB

File metadata and controls

134 lines (100 loc) · 4.88 KB

JavaScript

gsx supports JavaScript-valued attributes, script interpolation, and JSON data islands. Use explicit JavaScript literals in attributes so code is distinguishable from ordinary text.

JavaScript-valued attributes {#attribute-local-javascript}

Use a js`...` literal for a handler or JavaScript expression:

Inside the literal, @{ expr } inserts a Go value at a JavaScript value, string, or regular-expression position. Use js"..." when the JavaScript itself contains backticks. See Attributes for literal syntax and Escaping for the trust boundary.

A hole in a JavaScript binding position — an assignment target, or a declaration or member name — must have type gsx.RawJS; it is spliced verbatim. Any other type there is a compile error, since a value would be JSON-quoted and break the code. Wrap the trusted expression in gsx.RawJS(...) to assign to a dynamic path:

::: v-pre

component Bind(path string) {
	<input @change=js`@{gsx.RawJS(path)} = $event.target.value;`/>
}

:::

Keep a js or css literal with @{} holes on the native element that consumes it. A wrapper should accept ordinary parameters and build the contextual literal at that destination:

component SaveButton(id string) {
	<button @click=js`save(@{id})`>Save</button>
}

<SaveButton id={id}/>

On a component tag, an unbraced, hole-free contextual literal may fall through as authored text. The same unbraced form is rejected when it contains holes.

Contextual literals as Go values

In a Go expression, a js literal has type gsx.RawJS and a css literal has type gsx.RawCSS. Store them in a local variable when a contextual value must be assembled before it reaches the native element:

::: v-pre

component Choice(id int, color string) {
	{{
		behavior := js`select(@{id})`
		styles := css`color:@{color}`
	}}
	<button @click={behavior} style={styles}>Select</button>
}

:::

Each hole follows the JavaScript or CSS rules for its position before the typed value is created. Trusted gsx.RawJS and gsx.RawCSS holes retain their documented passthrough; see Escaping. Do not render the literal directly as visible body text.

A component may explicitly accept the trusted type. Use braces so the literal binds the declared parameter as a Go expression:

component Widget(Handler gsx.RawJS, Rule gsx.RawCSS) {
	<button @click={Handler} style={Rule}>Go</button>
}

<Widget Handler={js`open(@{id})`} Rule={css`width:@{width}px`}/>

::: v-pre Because the literal is a Go value, its holes cannot use an error-returning pipeline or renderer. Top-level declarations also cannot use a filter or renderer that takes ctx; component expressions and {{ }} blocks can. :::

Alpine and htmx directives

Alpine directive values are JavaScript expressions, so mark x-data, x-model, x-for, x-text, @click, and :key values with js. The same form works for htmx attributes that contain JavaScript.

JSON attribute values

JSON is a subset of JavaScript, so attributes such as htmx's hx-vals use the same literal:

Go strings, numbers, structs, maps, and slices in value-position holes are encoded as JSON values. The rendered attribute is then HTML-escaped; the browser restores the JSON text before the consumer reads it. Name keys in the literal and place dynamic holes in value positions.

When the entire attribute value is a single hole — data-labels=js@{labels} — gsx JSON-encodes the whole Go value, so chart `data-*` attributes and a whole-value `hx-vals` need no hand-built JSON. A hole that is *not* the whole value and sits before a token (`js`@{x} = 1, js@{x} + 2``) is a binding/operand position and accepts only gsx.RawJS. This applies to `js` attributes; a plain `{ … }` attribute still takes only a string/number/bool.

<script> interpolation

Inside <script>, @{ expr } inserts a Go value in the surrounding JavaScript context:

Value-position interpolation produces JSON notation. String and regular-expression positions receive their matching escapes, including escapes that prevent input from ending the <script> element. gsx.RawJS bypasses those protections and is only for JavaScript you trust; see Escaping.

JSON data islands

Use <script type="application/json"> to expose server data without executing it. Interpolation encodes the Go value as JSON, and client code can read the element's text content and pass it to JSON.parse.