# `Kino.Shorts`
[🔗](https://github.com/livebook-dev/kino/blob/v0.19.0/lib/kino/shorts.ex#L1)

Shortcuts for building Kinos.

This module provides an easy to use Kino API and is meant to
be imported into your notebooks:

    import Kino.Shorts

# `audio`

```elixir
@spec audio(binary(), Kino.Audio.common_audio_type() | Kino.Audio.mime_type()) ::
  Kino.Audio.t()
```

Renders an audio of any given format.

It is a wrapper around `Kino.Audio.new/2`.

## Examples

    import Kino.Shorts
    content = File.read!("/path/to/audio.wav")
    audio(content, :wav)

# `data_table`

```elixir
@spec data_table(
  Table.Reader.t(),
  keyword()
) :: Kino.DataTable.t()
```

Renders a data table output for user-provided tabular data.

The data must implement the `Table.Reader` protocol. This
function is a wrapper around `Kino.DataTable.new/1`.

## Examples

    import Kino.Shorts

    data = [
      %{id: 1, name: "Elixir", website: "https://elixir-lang.org"},
      %{id: 2, name: "Erlang", website: "https://www.erlang.org"}
    ]

    data_table(data)

# `download`

```elixir
@spec download(
  (-&gt; binary()),
  keyword()
) :: Kino.Download.t()
```

Renders a file download button.

The given function is invoked to generate the file content whenever
a download is requested.

It is a wrapper around `Kino.Download.new/2`.

## Options

  * `:filename` - the default filename suggested for download.
    Defaults to `"download"`

  * `:label` - the button text. Defaults to the value of `:filename`
    if present and `"Download"` otherwise

## Examples

    download(fn ->
      "Example text"
    end)

    download(
      fn -> Jason.encode!(%{"foo" => "bar"}) end,
      filename: "data.json"
    )

    download(
      fn -> <<0, 1>> end,
      filename: "data.bin",
      label: "Binary data"
    )

# `frame`

```elixir
@spec frame(keyword()) :: Kino.Frame.t()
```

A placeholder for static outputs that can be dynamically updated.

The frame can be updated with the `Kino.Frame` module API.
Also see `Kino.animate/3`.

## Examples

    import Kino.Shorts
    frame = frame() |> Kino.render()

    for i <- 1..100 do
      Kino.Frame.render(frame, i)
      Process.sleep(50)
    end

# `grid`

```elixir
@spec grid(
  [term()],
  keyword()
) :: Kino.Layout.t()
```

Arranges outputs into a grid.

Note that the grid does not support scrolling, it always squeezes
the content, such that it does not exceed the page width.

It is a wrapper around `Kino.Layout.grid/2`. See the linked function
for all supported options.

## Options

  * `:columns` - the number of columns in the grid. Defaults to `1`

  * `:boxed` - whether the grid should be wrapped in a bordered box.
    Defaults to `false`

  * `:gap` - the amount of spacing between grid items in pixels.
    Defaults to `8`

## Examples

    import Kino.Shorts

    images =
      for path <- paths do
        path |> File.read!() |> image(:jpeg)
      end

    grid(images, columns: 3)

# `html`

```elixir
@spec html(String.t()) :: Kino.HTML.t()
```

Displays arbitrary static HTML.

It is a wrapper around `Kino.HTML.new/1`.

## Examples

    import Kino.Shorts

    html("""
    <h3>Look!</h3>

    <p>I wrote this HTML from <strong>Kino</strong>!</p>
    """)

# `image`

```elixir
@spec image(binary(), Kino.Image.common_image_type() | Kino.Image.mime_type()) ::
  Kino.Image.t()
```

Renders an image of any given format.

It is a wrapper around `Kino.Image.new/2`.

## Examples

    import Kino.Shorts
    content = File.read!("/path/to/image.jpeg")
    image(content, "image/jpeg")

# `markdown`

```elixir
@spec markdown(String.t()) :: Kino.Markdown.t()
```

Renders Markdown content, in case you need richer text.

It is a wrapper around `Kino.Markdown.new/1`.

## Examples

    import Kino.Shorts

    markdown("""
    # Example

    A regular Markdown file.

    ## Code

    ```elixir
    "Elixir" |> String.graphemes() |> Enum.frequencies()
    ```

    ## Table

    | ID | Name   | Website                 |
    | -- | ------ | ----------------------- |
    | 1  | Elixir | https://elixir-lang.org |
    | 2  | Erlang | https://www.erlang.org  |
    """)

# `mermaid`

```elixir
@spec mermaid(
  String.t(),
  keyword()
) :: Kino.Mermaid.t()
```

Renders Mermaid diagrams.

It is a wrapper around `Kino.Mermaid.new/1`.

## Examples

    import Kino.Shorts

    mermaid("""
    graph TD;
      A-->B;
      A-->C;
      B-->D;
      C-->D;
    """)

# `read_audio`

```elixir
@spec read_audio(
  String.t(),
  keyword()
) ::
  %{
    file_ref: term(),
    num_channels: pos_integer(),
    sampling_rate: pos_integer(),
    format: :pcm_f32 | :wav
  }
  | nil
```

Renders and reads a new audio input.

See `Kino.Input.audio/2` for all supported formats and options.

> #### Warning {: .warning}
>
> The audio input is shared by default: once you upload an audio,
> the audio will be replicated to all users reading the notebook.
> Use `Kino.Control.form/2` if you want each user to have a distinct
> audio upload with an explicit submission button.

# `read_checkbox`

```elixir
@spec read_checkbox(
  String.t(),
  keyword()
) :: boolean()
```

Renders and reads a new checkbox.

## Options

  * `:default` - the initial input value. Defaults to `false`

# `read_color`

```elixir
@spec read_color(
  String.t(),
  keyword()
) :: String.t() | nil
```

Renders and reads a new color input.

## Options

  * `:default` - the initial input value. Defaults to `#6583FF`

# `read_date`

```elixir
@spec read_date(
  String.t(),
  keyword()
) :: Date.t() | nil
```

Renders and reads a new date input.

## Options

  * `:default` - the initial input value. Defaults to `nil`

  * `:min` - the minimum date value

  * `:max` - the maximum date value

# `read_file`

```elixir
@spec read_file(
  String.t(),
  keyword()
) :: %{file_ref: String.t(), client_name: String.t()} | nil
```

Renders and reads a new file input.

The file path can then be accessed using `Kino.Input.file_path/1`.
See `Kino.Input.file/2` for additional considerations.

> #### Warning {: .warning}
>
> The file input is shared by default: once you upload a file,
> the file will be replicated to all users reading the notebook.
> Use `Kino.Control.form/2` if you want each user to have a distinct
> file upload with an explicit submission button.

## Options

  * `:accept` - the list of accepted file types (either extensions
    or MIME types) or `:any`. Defaults to `:any`

# `read_image`

```elixir
@spec read_image(
  String.t(),
  keyword()
) ::
  %{
    file_ref: term(),
    height: pos_integer(),
    width: pos_integer(),
    format: :rgb | :png | :jpeg
  }
  | nil
```

Renders and reads a new image input.

See `Kino.Input.image/2` for all supported formats and options.

> #### Warning {: .warning}
>
> The image input is shared by default: once you upload an image,
> the image will be replicated to all users reading the notebook.
> Use `Kino.Control.form/2` if you want each user to have a distinct
> image upload with an explicit submission button.

# `read_number`

```elixir
@spec read_number(
  String.t(),
  keyword()
) :: number() | nil
```

Renders and reads a new number input.

## Options

  * `:default` - the initial input value. Defaults to `nil`

# `read_password`

```elixir
@spec read_password(
  String.t(),
  keyword()
) :: String.t() | nil
```

Renders and reads a new password input.

## Options

  * `:default` - the initial input value. Defaults to `""`

# `read_range`

```elixir
@spec read_range(
  String.t(),
  keyword()
) :: float()
```

Renders and reads a new slider input.

## Options

  * `:default` - the initial input value. Defaults to the
    minimum value

  * `:min` - the minimum value

  * `:max` - the maximum value

  * `:step` - the slider increment

# `read_select`

```elixir
@spec read_select(String.t(), [{value :: term(), label :: String.t()}], keyword()) ::
  String.t()
```

Renders and reads a new select input.

The input expects a list of options in the form `[{value, label}]`,
where `value` is an arbitrary term and `label` is a descriptive
string.

## Options

  * `:default` - the initial input value. Defaults to the first
    value from the given list of options

## Examples

    read_select("Language", [en: "English", fr: "Français"])

    read_select("Language", [{1, "One"}, {2, "Two"}, {3, "Three"}])

# `read_text`

```elixir
@spec read_text(
  String.t(),
  keyword()
) :: String.t() | nil
```

Renders and reads a new text input.

## Options

  * `:default` - the initial input value. Defaults to `""`

# `read_textarea`

```elixir
@spec read_textarea(
  String.t(),
  keyword()
) :: String.t() | nil
```

Renders and reads a new multiline text input.

## Options

  * `:default` - the initial input value. Defaults to `""`

  * `:monospace` - whether to use a monospace font inside the textarea.
    Defaults to `false`

# `read_url`

```elixir
@spec read_url(
  String.t(),
  keyword()
) :: String.t() | nil
```

Renders and reads a new URL input.

## Options

  * `:default` - the initial input value. Defaults to `nil`

# `read_utc_datetime`

```elixir
@spec read_utc_datetime(
  String.t(),
  keyword()
) :: NaiveDateTime.t() | nil
```

Renders and reads a new datetime input.

## Options

  * `:default` - the initial input value. Defaults to `nil`

  * `:min` - the minimum datetime value (in UTC)

  * `:max` - the maximum datetime value (in UTC)

# `read_utc_time`

```elixir
@spec read_utc_time(
  String.t(),
  keyword()
) :: Time.t() | nil
```

Renders and reads a new time input.

## Options

  * `:default` - the initial input value. Defaults to `nil`

  * `:min` - the minimum time value (in UTC)

  * `:max` - the maximum time value (in UTC)

# `tabs`

```elixir
@spec tabs([{String.t() | atom(), term()}]) :: Kino.Layout.t()
```

Arranges outputs into separate tabs.

It is a wrapper around `Kino.Layout.tabs/1`.

## Examples

    import Kino.Shorts

    data = [
      %{id: 1, name: "Elixir", website: "https://elixir-lang.org"},
      %{id: 2, name: "Erlang", website: "https://www.erlang.org"}
    ]

    tabs([
      Table: data_table(data),
      Raw: data
    ])

# `text`

```elixir
@spec text(String.t()) :: Kino.Text.t()
```

Renders plain text content.

It is similar to `markdown/1`, however doesn't interpret any markup.

It is a wrapper around `Kino.Text.new/1`.

## Examples

    import Kino.Shorts
    text("Hello!")

# `tree`

```elixir
@spec tree(term()) :: Kino.Layout.t()
```

Displays arbitrarily nested data structure as a tree view.

It is a wrapper around `Kino.Tree.new/1`.

## Examples

    import Kino.Shorts
    tree(Process.info(self()))

# `video`

```elixir
@spec video(binary(), Kino.Video.common_video_type() | Kino.Video.mime_type()) ::
  Kino.Video.t()
```

Renders a video of any given format.

It is a wrapper around `Kino.Video.new/2`.

## Examples

    import Kino.Shorts
    content = File.read!("/path/to/video.mp4")
    video(content, :mp4)

---

*Consult [api-reference.md](api-reference.md) for complete listing*
