defmodule KinoCodePen do @moduledoc """ A simple Kino for display CodePen pens on Livebook. """ use Kino.JS def new(username, pen_id, opts \\ []) do height = opts[:height] || "600" click_to_load = opts[:click_to_load] || false preview_path = if click_to_load, do: "preview/", else: "" default_tab = opts[:default_tab] || ["html", "result"] query = %{} |> Map.put("default-tab", Enum.join(default_tab, ",")) |> Map.put("theme-id", opts[:theme]) |> URI.encode_query() src_url = "https://codepen.io/#{username}/embed/#{preview_path}#{pen_id}/?#{query}" iframe = """ """ Kino.JS.new(__MODULE__, iframe) end def url(pen_url, opts \\ []) do case Regex.named_captures(~r{codepen\.io/(?[^/]+)/pen/(?[^/]+)}, pen_url) do %{"username" => username, "pen_id" => pen_id} -> new(username, pen_id, opts) _ -> Kino.JS.new(__MODULE__, "Invalid CodePen URL") end end asset "main.js" do """ export function init(ctx, iframe) { ctx.root.innerHTML = iframe; } """ end end