Image

A semantic image surface with optional selection, corner resizing, and text wrapping.

Image

A semantic image surface with automatic sizing and a text alternative.

Green hills, a farmhouse, and sheep beside a winding stream

Code

<link
  rel="component"
  href="@threadlabs/looma/components/ui-image/ui-image.html"
>

<ui-image
  src="/_looma/pastoral.svg"
  alt="Green hills, a farmhouse, and sheep beside a winding stream"
  width="320"
  height="200"
></ui-image>
<script setup>
  import { UiImage } from "@threadlabs/looma";
</script>

<template>
  <UiImage
    src="/_looma/pastoral.svg"
    alt="Green hills, a farmhouse, and sheep beside a winding stream"
    :width="320"
    :height="200"
  />
</template>
import { UiImage } from "@threadlabs/looma";

export default function Example() {
  return <UiImage
    src="/_looma/pastoral.svg"
    alt="Green hills, a farmhouse, and sheep beside a winding stream"
    width={320}
    height={200}
  />;
}
/** @jsxImportSource preact */
import { UiImage } from "@threadlabs/looma";

export default function Example() {
  return <UiImage
    src="/_looma/pastoral.svg"
    alt="Green hills, a farmhouse, and sheep beside a winding stream"
    width={320}
    height={200}
  />;
}
<script>
  import { UiImage } from "@threadlabs/looma";
</script>

<UiImage
  src="/_looma/pastoral.svg"
  alt="Green hills, a farmhouse, and sheep beside a winding stream"
  width={320}
  height={200}
/>
import { Component } from "@angular/core";
import { UiImage } from "@threadlabs/looma";

@Component({
  selector: "example-view",
  standalone: true,
  imports: [UiImage],
  template: `
    <figure
      ui-image
      [src]="'/_looma/pastoral.svg'"
      [alt]="'Green hills, a farmhouse, and sheep beside a winding stream'"
      [width]="320"
      [height]="200"
    ></figure>
  `,
})
export default class Example {}

Selected and resizable

Four corner handles keep the intrinsic ratio while reporting preview, commit, and cancel intent; a consumer persists committed dimensions.

Green hills, a farmhouse, and sheep beside a winding stream

Code

<link
  rel="component"
  href="@threadlabs/looma/components/ui-image/ui-image.html"
>

<ui-image
  src="/_looma/pastoral.svg"
  alt="Green hills, a farmhouse, and sheep beside a winding stream"
  width="320"
  height="200"
  placement="center"
  selected
  resizable
></ui-image>
<script setup>
  import { UiImage } from "@threadlabs/looma";
</script>

<template>
  <UiImage
    src="/_looma/pastoral.svg"
    alt="Green hills, a farmhouse, and sheep beside a winding stream"
    :width="320"
    :height="200"
    placement="center"
    :selected="true"
    :resizable="true"
  />
</template>
import { UiImage } from "@threadlabs/looma";

export default function Example() {
  return <UiImage
    src="/_looma/pastoral.svg"
    alt="Green hills, a farmhouse, and sheep beside a winding stream"
    width={320}
    height={200}
    placement="center"
    selected
    resizable
  />;
}
/** @jsxImportSource preact */
import { UiImage } from "@threadlabs/looma";

export default function Example() {
  return <UiImage
    src="/_looma/pastoral.svg"
    alt="Green hills, a farmhouse, and sheep beside a winding stream"
    width={320}
    height={200}
    placement="center"
    selected
    resizable
  />;
}
<script>
  import { UiImage } from "@threadlabs/looma";
</script>

<UiImage
  src="/_looma/pastoral.svg"
  alt="Green hills, a farmhouse, and sheep beside a winding stream"
  width={320}
  height={200}
  placement="center"
  selected
  resizable
/>
import { Component } from "@angular/core";
import { UiImage } from "@threadlabs/looma";

@Component({
  selector: "example-view",
  standalone: true,
  imports: [UiImage],
  template: `
    <figure
      ui-image
      [src]="'/_looma/pastoral.svg'"
      [alt]="'Green hills, a farmhouse, and sheep beside a winding stream'"
      [width]="320"
      [height]="200"
      [placement]="'center'"
      [selected]="true"
      [resizable]="true"
    ></figure>
  `,
})
export default class Example {}

API

Package: @threadlabs/looma · Native root: figure

Attributes

NameDescriptionPropertyTypeDefaultAllowed values
altA text alternative for the image.altstring—
heightImage height in CSS pixels; resizing preserves the intrinsic aspect ratio.heightinteger——
placementBlock keeps text below; center centers the image; wrap-left and wrap-right let following text flow beside it.placementkeywordblockblock, center, wrap-left, wrap-right
resizableShows four corner handles while selected. Drag to resize, or focus a handle and use arrow keys; Shift uses a larger increment.resizablebooleanfalse—
selectedOutlines the media as the current selection.selectedbooleanfalse—
srcThe image source, used by the default media.srcstring—
widthImage width in CSS pixels; omitted uses intrinsic size in block/center placement or responsive sizing when wrapping.widthinteger——

Framework props

NameTypeDefaultAllowed values
altstring—
heightnumber——
placement"block" | "center" | "wrap-left" | "wrap-right"blockblock, center, wrap-left, wrap-right
resizablebooleanfalse—
selectedbooleanfalse—
srcstring—
widthnumber——

Events

NameDetailDescription
resizeobject
  • width: integer (required)
  • height: integer (required)
  • phase: keyword (required)
  • trigger: keyword (required)
Emitted with the declared detail payload.

Slots

NamePurpose
mediaNamed content for the media region.
controlsNamed content for the controls region.

Design tokens

Set shared theme properties on a theme boundary. Component hooks apply only to their owning component.

Component tokens

No component tokens.

Shared tokens

TokenFallback
--ui-border-width—
--ui-focus-ring—
--ui-focus-width—
--ui-radius-md—
--ui-radius-sm—
--ui-space-3—
--ui-space-4—
--ui-surface—