Add fonts, autotable, autotable examples
This commit is contained in:
@@ -11,14 +11,24 @@ import (
|
||||
)
|
||||
|
||||
// Event is a DOM event passed to handlers. The client provides a concrete
|
||||
// implementation; on the server events are never invoked.
|
||||
// implementation; on the server events are never invoked, and every accessor
|
||||
// returns its zero value.
|
||||
type Event interface {
|
||||
PreventDefault()
|
||||
Value() string // target.value (for inputs)
|
||||
StopPropagation()
|
||||
Value() string // target.value (for inputs)
|
||||
Checked() bool // target.checked (for checkboxes / radios)
|
||||
Key() string // KeyboardEvent.key — compare against the KEY_* constants
|
||||
ClientX() int // pointer position, viewport coordinates
|
||||
ClientY() int //
|
||||
Target() any // the platform DOM handle of event.target; nil on the server
|
||||
SetData(format, data string) // DataTransfer — no-ops off a drag event
|
||||
GetData(format string) string
|
||||
}
|
||||
|
||||
// VNode is a virtual DOM node. Tag == "" is a text node (content in Text). HTML,
|
||||
// if set on an element, is raw innerHTML (children ignored).
|
||||
// if set on an element, is raw innerHTML (children ignored). Tag == TagPortal
|
||||
// renders its children into document.body instead of in place.
|
||||
type VNode struct {
|
||||
Tag string
|
||||
Text string
|
||||
@@ -28,6 +38,9 @@ type VNode struct {
|
||||
Events map[string]func(Event)
|
||||
Children []*VNode
|
||||
|
||||
// Ref, if set, receives the DOM node this VNode renders to (see WithRef).
|
||||
Ref *Ref
|
||||
|
||||
// Runtime holds the wasm reconciler's per-node bookkeeping (DOM handle,
|
||||
// listener wrappers). It's `any` so this package stays platform-neutral; it
|
||||
// is nil on the server.
|
||||
@@ -37,6 +50,13 @@ type VNode struct {
|
||||
// Mod configures a VNode while it is built.
|
||||
type Mod interface{ apply(*VNode) }
|
||||
|
||||
// TagPortal marks a node whose children are mounted into document.body rather
|
||||
// than into its own parent. It is how a floating panel escapes an ancestor's
|
||||
// `overflow: hidden` (menus scroll, modals clip) or `transform` (which would
|
||||
// re-root `position: fixed` onto the modal instead of the viewport). In the tree
|
||||
// it occupies a hidden, zero-size placeholder; the children live at body level.
|
||||
const TagPortal = "#portal"
|
||||
|
||||
// El builds an element VNode.
|
||||
func El(tag string, mods ...Mod) *VNode {
|
||||
n := &VNode{Tag: tag, Attrs: map[string]string{}, Props: map[string]string{}, Events: map[string]func(Event){}}
|
||||
@@ -46,6 +66,17 @@ func El(tag string, mods ...Mod) *VNode {
|
||||
return n
|
||||
}
|
||||
|
||||
// Portal renders its children into document.body. On the server it renders the
|
||||
// placeholder only — floating content is closed during SSR, so there is nothing
|
||||
// to emit, and the placeholder keeps the client's hydration walk aligned.
|
||||
func Portal(children ...*VNode) *VNode {
|
||||
n := El(TagPortal)
|
||||
for _, c := range children {
|
||||
c.apply(n)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// Text builds a text VNode.
|
||||
func Text(s string) *VNode { return &VNode{Text: s} }
|
||||
|
||||
@@ -106,6 +137,13 @@ func writeNode(b *strings.Builder, n *VNode) {
|
||||
b.WriteString(html.EscapeString(n.Text))
|
||||
return
|
||||
}
|
||||
if n.Tag == TagPortal {
|
||||
// Placeholder only — the children belong to document.body, which SSR does
|
||||
// not own. Emitting the same element the client creates keeps hydration's
|
||||
// childNodes lined up.
|
||||
b.WriteString(`<div data-portal="" style="display:none"></div>`)
|
||||
return
|
||||
}
|
||||
b.WriteByte('<')
|
||||
b.WriteString(n.Tag)
|
||||
writeAttrs(b, n.Attrs)
|
||||
|
||||
Reference in New Issue
Block a user