Next: , Previous: , Up: API  


1.26 (hygguile components utility)

1.26.1 Procedures

Procedure: bdi content KEY: #:classes

Isolate an inline run whose direction the browser should decide.

A username, a file name, a number next to a currency symbol: anything a page does not control the script of. <bdi> keeps it from rearranging the sentence around it.

content

The inline content.

classes

Extra classes.

(p (list "Signed in as " (bdi "@ada")))
Procedure: bdo content KEY: #:dir #:classes

Override the bidirectional algorithm for content.

This is deliberately explicit: it is for displaying a string in the direction opposite to its own, not for laying out a page. Pages that need a whole region mirrored want locale instead.

content

The inline content.

dir

'ltr or 'rtl. Defaults to 'rtl.

classes

Extra classes.

(bdo "abc" #:dir 'rtl)
Procedure: collapse KEY: #:summary #:content #:open #:classes

A disclosure whose body animates open and closed.

This is a native <details> with its content in a grid track that moves between zero and one fraction of its height, so the browser animates the real height without a measuring script. The reduced-motion block in the companion stylesheet sets the transition off, and the disclosure still opens instantly – the behaviour was never the animation.

summary

The always-visible caption.

content

The collapsible body, as a list of nodes.

open

Whether it starts open.

classes

Extra classes for the <details>.

(collapse #:summary "Advanced" #:content (list (input #:label "Pattern" #:name "p")))
Procedure: copy-button KEY: #:text #:label #:copied-label #:show-text? #:classes

Render a button that copies text to the clipboard.

The button is a progressive enhancement and says so: it carries js-only, so the no-script stylesheet hides it, and a <noscript> beside it shows the value as selectable text instead. A control that silently does nothing is worse than no control at all.

The value lives in a data-hg-copy attribute, not in an inline handler, so the same script serves every copy button on the page and a page with a Content Security Policy does not have to allow inline JavaScript.

text

The value to copy.

label

The accessible label, shown as text only when show-text? is true.

copied-label

The accessible label after a successful copy. Defaults to "Copied".

show-text?

Whether the label is visible beside the icon. Defaults to false.

classes

Extra classes for the button.

(copy-button #:text "(use-modules (hygguile hygguile))")
Procedure: density-toggle KEY: #:current #:label #:classes

Render the control that switches a page between comfortable and compact density.

The control is a progressive enhancement: it carries js-only, and the no-script stylesheet hides it, because a density preference that cannot be remembered is a button that lies. The script stores the choice and sets data-density on the root element before the page is drawn, so a reader never sees one density and then the other.

A page opts in by reading the same attribute in its own stylesheet; the framework’s data grid, field shell and sidebar already do.

current

The density the server rendered the page in. Defaults to 'comfortable.

label

The accessible label of the control.

classes

Extra classes for the button.

(density-toggle #:current 'comfortable)
Procedure: fade-in content KEY: #:duration #:delay #:tag #:classes #:attributes

Fade content in, and do nothing at all when motion is reduced.

The duration is read from the design tokens, so the reduced-motion block that sets every token to zero turns the animation off without a second media query here. That is the whole point of the primitive: motion is a token, not a commitment sprinkled through the markup.

content

The children, as a list of nodes.

duration

A motion token: 'fast, 'base (default), 'slow or 'slower.

delay

An optional delay token or CSS time.

tag

The element to build. Defaults to div.

classes

Extra classes for the wrapper.

attributes

Extra attributes, as pairs of name and value.

(fade-in (list (alert ...)))
Procedure: hide content KEY: #:from #:tag #:classes #:attributes

Hide content from a breakpoint up.

Olive’s responsive utilities are min-width, so there is no plain utility that means "gone above this width"; the companion stylesheet names the five classes this needs (hg-hidden-from-sm and friends), and this component is the name a page uses instead of remembering them.

content

The children, as a list of nodes.

from

The breakpoint: 'sm, 'md (default), 'lg, 'xl or '2xl.

tag

The element to build. Defaults to div.

classes

Extra classes for the wrapper.

attributes

Extra attributes, as pairs of name and value.

(hide (list (toolbar ...)) #:from 'md)
Procedure: layer content KEY: #:level #:id #:tag #:classes #:attributes

Place content in one of the framework’s named layers.

Every overlay has to answer the same question – which of us is on top – and the answer stops being obvious the moment a page has a modal, a dropdown and a toast at once. Naming a level reads the framework’s own scale (sticky, dropdown, overlay, modal, popover, toast, tooltip) through a custom property, so a page can raise or lower a whole layer without hunting for a component’s z-index.

content

The children, as a list of nodes.

level

A layer name. Defaults to 'modal.

id

An optional HTML identifier, for a portal target a script fills.

tag

The element to build. Defaults to div.

classes

Extra classes for the element.

attributes

Extra attributes, as pairs of name and value.

(layer (list (drawer ...)) #:level 'modal)
Procedure: layer-root KEY: #:id #:content #:classes

The single mount point a page gives its overlays.

Rendered once, near the end of the body, this is where scripts append a toast or a command palette. In a server-rendered page it is mostly a declaration of intent: overlays rendered by the server can sit here too, so they all share one stacking context and one place to look for them.

id

The identifier scripts use to find the root.

content

Any overlays rendered by the server, as a list of nodes.

classes

Extra classes for the root.

(layer-root)
Procedure: line-clamp content KEY: #:lines #:title #:tag #:classes

Clamp text to a number of lines, with an ellipsis.

This is truncate-text under the name the CSS property has, for a page that would rather read line-clamp at the call site. The full text stays in the DOM, so assistive technology and find-in-page still reach it.

content

The text or inline nodes.

lines

How many lines to keep. Defaults to 2.

title

An optional title attribute carrying the untruncated text.

tag

The element to build. Defaults to p.

classes

Extra classes for the text.

(line-clamp "A long summary" #:lines 3)
Procedure: locale content KEY: #:lang #:dir #:tag #:classes #:attributes

Mark a region’s language and writing direction.

Both attributes are inherited, so wrapping the part of a page that is in another language – or in a right-to-left script – is enough for browsers, screen readers, hyphenation and the CSS logical properties the components are written with. The framework’s own layout primitives use logical spacing, so a split or a drawer mirrors itself when it is told to.

content

The children, as a list of nodes.

lang

A BCP 47 language tag, such as "ar" or "pt-BR".

dir

'ltr, 'rtl or 'auto.

tag

The element to build. Defaults to div.

classes

Extra classes for the element.

attributes

Extra attributes, as pairs of name and value.

(locale (list (p "مرحبا")) #:lang "ar" #:dir 'rtl)
Procedure: show content KEY: #:from #:display #:tag #:classes #:attributes

Show content only from a breakpoint up.

The markup is hidden plus the breakpoint’s display utility, so the hiding is done by the same stylesheet as everything else and the content is not fetched twice. Below the breakpoint the element is not rendered at all (display: none), which is the correct behaviour for a control that only makes sense on a wide screen.

content

The children, as a list of nodes.

from

The breakpoint: 'sm, 'md (default), 'lg, 'xl or '2xl.

display

The display value above the breakpoint, e.g. 'block, 'flex, 'grid or 'inline-block.

tag

The element to build. Defaults to div.

classes

Extra classes for the wrapper.

attributes

Extra attributes, as pairs of name and value.

(show (list (table ...)) #:from 'lg)

Render the first focusable control on a page: a link that jumps past the navigation straight to the content.

A skip link is the cheapest accessibility win there is and the most often forgotten. It sits off-screen until a keyboard reader tabs to it, then appears at the top of the page; following it moves focus to target, which should be the id of the page’s <main>.

target

The fragment the link points at, including the leading #. Defaults to "#main".

label

The link text. Defaults to "Skip to content".

classes

Extra classes for the link.

(skip-link #:target "#main")
Procedure: slide-in content KEY: #:from #:duration #:tag #:classes #:attributes

Slide content in from an edge, or not at all when motion is reduced.

content

The children, as a list of nodes.

from

'up (default), 'down, 'start or 'end.

duration

A motion token. Defaults to 'base.

tag

The element to build. Defaults to div.

classes

Extra classes for the wrapper.

attributes

Extra attributes, as pairs of name and value.

(slide-in (list (card ...)) #:from 'down)
Procedure: truncate-text content KEY: #:lines #:title #:tag #:classes

Cut text off after a number of lines, with an ellipsis.

One line uses Olive’s truncate utility; several lines use its line-clamp-* utilities, which is a real, painted clamp rather than a character count, so it follows the rendered width of the type. The full text stays in the DOM, so assistive technology and find-in-page still reach it; a title is available for the mouse reader, but it is off by default because it would make a second copy of the text for anyone who can already see it.

content

The text or inline nodes.

lines

How many lines to keep. Defaults to 1.

title

An optional title attribute carrying the untruncated text.

tag

The element to build. Defaults to p.

classes

Extra classes for the text.

(truncate-text "A very long description indeed" #:lines 2)
Procedure: visually-hidden content KEY: #:tag #:focusable? #:classes

Hide content visually while leaving it available to assistive technology.

This is the framework’s ‘sr-only’ class with a name, so a page does not have to remember which utility it is. Use it for the label of an icon-only control, a section heading that would repeat what is already visible, or an instruction that only makes sense to a screen reader.

Pass #:focusable? #t for the rarer case of content that should be hidden until it takes focus – a skip link, or a control that appears when tabbed to. That one needs to be an element that can hold focus, so the default tag is a <span> and callers pass #'a or #'button as appropriate.

content

The text or nodes to hide.

tag

The element to build. Defaults to span.

focusable?

Whether the content becomes visible when focused. Defaults to false.

classes

Extra classes for the wrapper.

(visually-hidden "Loading search results")
(visually-hidden "Skip to content" #:tag 'a #:focusable? #t)

Next: (hygguile css), Previous: (hygguile components typography), Up: API