### Basic Setup for Surface Component Testing Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Provides the basic setup for testing Surface components using `Surface.LiveViewTest` and `Phoenix.LiveViewTest`. It includes necessary imports and defines the default endpoint. ```elixir defmodule MyAppWeb.ButtonTest do use MyAppWeb.ConnCase import Phoenix.LiveViewTest import Surface.LiveViewTest # Import Surface macros # Default endpoint for tests @endpoint MyAppWeb.Endpoint end ``` -------------------------------- ### JSON: Bulma CSS NPM Setup Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Shows the `package.json` dependency configuration for installing the Bulma CSS framework via NPM. ```JSON { "dependencies": { "bulma": "^0.9.3" } } ``` -------------------------------- ### Install Surface UI Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Instructions for adding the Surface UI dependency to a Phoenix project's mix.exs file and fetching dependencies. ```elixir def deps do [ {:surface, "~> 0.12.1"} ] end ``` -------------------------------- ### Configure Web Module Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Example of importing Surface into the web module configuration in lib/my_app_web.ex. ```elixir # lib/my_app_web.ex def view do quote do # ... other imports import Surface end end ``` -------------------------------- ### Elixir: Render Home Page with Surface Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Defines the `home` function in `MyAppWeb.PageHTML` module to render a hero section with a welcome message and a 'Get Started' button using Surface's templating. ```Elixir defmodule MyAppWeb.PageHTML do use MyAppWeb, :html import Surface def home(assigns) do ~F"""
""" end end ``` -------------------------------- ### HTML: Bulma CSS CDN Setup Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Provides the HTML link tag to include the Bulma CSS framework via a CDN, enabling styling for UI elements. ```HTML ``` -------------------------------- ### Configure Hooks Output Directory Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Provides an Elixir configuration example to set a custom output directory for compiled component JavaScript files. ```elixir # config/config.exs config :surface, :compiler, hooks_output_dir: "assets/js/surface" ``` -------------------------------- ### Embed Surface Components in Layouts Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md An Elixir example demonstrating how to embed Surface components (`.sface` files) within a Phoenix project's layout module. ```elixir # lib/my_app_web/components/layouts.ex defmodule MyAppWeb.Layouts do use MyAppWeb, :html import Surface embed_sface "layouts/root.sface" embed_sface "layouts/app.sface" end ``` -------------------------------- ### Surface UI Component Usage Examples Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Demonstrates the usage of various Surface UI components, including Button, Table, and Tabs, within a Surface template. Shows how to pass props and define slots for dynamic content. ```surface <:column title="Name"> {@row.name} <:column title="Email"> {@row.email}
<:tab title="Profile"> <:tab title="Settings"> ``` -------------------------------- ### Animation Hook Example (Fade In) Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md An example of a JavaScript hook that implements a fade-in animation on component mount by manipulating element opacity and transitions. ```javascript // components/fade_in.hooks.js let FadeIn = { mounted(){ this.el.style.opacity = "0" this.el.style.transition = "opacity 0.3s ease" requestAnimationFrame(() => { this.el.style.opacity = "1" }) } } export {FadeIn} ``` -------------------------------- ### Configure CSS Output Directory Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md An Elixir configuration example to specify the output directory for automatically generated scoped CSS files. ```elixir # config/config.exs config :surface, :compiler, css_output_dir: "assets/css/surface" ``` -------------------------------- ### Testing Stateless Components in Surface Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Demonstrates how to test stateless Surface components by rendering them and asserting the resulting HTML structure. This example tests a Button component with a class attribute. ```surface test "creates a button with class" do html = render_surface do ~F''' ''' end assert html =~ """ """ end ``` -------------------------------- ### Clipboard Hook Example Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md A practical example of a JavaScript hook for a clipboard functionality. It attaches a click listener to copy text to the clipboard and pushes an event upon successful copy. ```javascript // components/copy_button.hooks.js let CopyButton = { mounted(){ this.el.addEventListener("click", () => { const text = this.el.dataset.text navigator.clipboard.writeText(text).then(() => { this.pushEvent("copied", {text}) }) }) } } export {CopyButton} ``` -------------------------------- ### CSS Variants Configuration in Surface Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md An Elixir example defining a Surface component with props that act as CSS variants, allowing for dynamic styling based on prop values. ```elixir defmodule Button do use Surface.Component prop variant, :string, default: "primary", values: ["primary", "secondary", "danger"], css_variant: true prop size, :string, default: "medium", values: ["small", "medium", "large"], css_variant: true def render(assigns) do ~F""" """ end end ``` -------------------------------- ### Surface Template Interpolation Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Examples of interpolating values and expressions within Surface templates for dynamic content and attributes. ```surface
Hello, {@name}!
Content
Button
Content
``` -------------------------------- ### Testing Slots in Surface Components Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Illustrates testing Surface components that utilize slots. This example renders a Card component with header, default, and footer slots and asserts the presence of content within each slot. ```surface test "renders with slots" do html = render_surface do ~F''' <:header>

Title

Content

<:footer>
''' end assert html =~ "

Title

" assert html =~ "

Content

" assert html =~ "" end ``` -------------------------------- ### Elixir Surface Component Definition Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Provides a basic example of defining a Surface component in Elixir. It shows how to use `use Surface.Component`, define properties (`prop`), slots, and the `render/1` function using the `~F` sigil. ```elixir defmodule Button do use Surface.Component @doc "The button type (color)" prop type, :string, values: ["primary", "success", "info"] @doc "The button is expanded (full width)" prop expanded, :boolean, default: false @doc "Triggered on click" prop click, :event @doc "Triggered on focus" prop focus, :event @doc "The button content" slot default, required: true def render(assigns) do ~F""" """ end end ``` -------------------------------- ### Surface Component with Slots Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md An Elixir example defining a Surface component that uses slots for header content and default content, rendering them within a structured layout. ```elixir # components/card.ex defmodule Card do use Surface.Component slot header slot default, required: true def render(assigns) do ~F"""
<#slot {@header} />
<#slot />
""" end end ``` -------------------------------- ### Define Multiple Named Slots with Arguments (Elixir) Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Provides an example of defining multiple named slots that accept arguments in Surface using Elixir. The `slot` macro is used for each named slot, specifying the argument structure. ```elixir slot column, arg: %{row: :map} # Usage: <:column :let={row: row}> {@row.name} <:column :let={row: row}> {@row.email} ``` -------------------------------- ### Elixir Surface Data Declaration for LiveComponent Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Provides an example of declaring data assigns for a Surface LiveComponent in Elixir. It shows how to define state variables (`data`), properties (`prop`), and implement `mount/1` and `handle_event/3` for state management. ```elixir defmodule Counter do use Surface.LiveComponent # Data assigns represent component state data count, :integer, default: 0 data step, :integer, default: 1 data max_count, :integer # Properties are still used for external input prop initial_value, :integer, default: 0 def mount(socket) do {:ok, assign(socket, count: socket.assigns.initial_value || 0)} end def handle_event("increment", _, socket) do new_count = socket.assigns.count + socket.assigns.step max = socket.assigns.max_count count = if max && new_count > max, do: max, else: new_count {:noreply, assign(socket, count: count)} end def render(assigns) do ~F"""
{@count}
""" end end ``` -------------------------------- ### Surface Tagged Expressions Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Demonstrates tagged expressions in Surface, which allow the compiler to customize expression behavior. Examples include attribute spreading and special expressions like `{=@form}`. ```surface
Content
``` -------------------------------- ### Handle Events in Parent Module (Elixir) Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Provides an example of an Elixir function within a parent module that handles events emitted from child components. It matches the event name and updates the socket. ```elixir # In parent module def handle_event("handle_button_click", _params, socket) do # handle the event {:noreply, socket} end ``` -------------------------------- ### Initialize Surface UI Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Command to run the Surface UI initialization task. ```bash mix surface.init ``` -------------------------------- ### Initialize LiveView with Surface Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Demonstrates initializing Surface within a Phoenix LiveView's mount function using Surface.init/1. ```elixir # A LiveView using Surface templates defmodule PageLive do use Phoenix.LiveView import Surface def mount(_params, _session, socket) do socket = Surface.init(socket) # ... {:ok, socket} end def render(assigns) do ~F""" ... """ end end ``` -------------------------------- ### Fetch Dependencies Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Command to fetch project dependencies after adding Surface UI. ```bash mix deps.get ``` -------------------------------- ### Surface: Home Page Template Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md A Surface template file (`.sface`) for the home page, defining the structure of the hero section with a title, subtitle, and a button. ```Surface
``` -------------------------------- ### Surface: Dynamic Component Rendering Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Illustrates how to render Surface components dynamically using the `Component` component, passing the module and props as assigns. ```Surface ``` -------------------------------- ### LiveView Integration with Surface Hooks Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Demonstrates how to integrate Surface hooks into a LiveView application by importing hooks and passing them to the `LiveSocket` configuration. ```javascript import {Card} from "./_hooks/card" let Hooks = {Card} let liveSocket = new LiveSocket("/live", Socket, { hooks: Hooks, params: {_csrf_token: csrfToken} }) ``` -------------------------------- ### Testing Surface Components with Dynamic Assigns Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Shows how to test Surface components that use dynamic assigns. It involves defining assigns, rendering the component with these assigns, and asserting the output. ```surface test "renders with dynamic assigns" do assigns = %{class: "btn", label: "Submit"} html = render_surface do ~F''' ''' end assert html =~ ~r/class="btn"/ assert html =~ "Submit" end ``` -------------------------------- ### Surface: Raw HTML Component Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Shows how to render raw HTML content using the `Raw` component in Surface. It's recommended to use this with caution. ```Surface ``` -------------------------------- ### Surface Event Bindings Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Demonstrates how to bind events in Surface components using the `:on-[event]` syntax. This allows components to react to user interactions like clicks, changes, and form submissions. ```surface
``` -------------------------------- ### Surface: Markdown Component Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Demonstrates rendering Markdown content using the `Markdown` component in Surface. It shows rendering from a variable and directly within the template using a slot. ```Surface # Hello World This is **markdown** content! ``` -------------------------------- ### App Layout Structure Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md A Surface template (`.sface`) defining the main application layout, including a navigation area and content rendering. ```surface
<.flash_group flash={@flash} /> <%= @inner_content %>
``` -------------------------------- ### Create Colocated Hooks File Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Demonstrates creating a colocated `.hooks.js` file for a component. It shows how to define lifecycle functions like `mounted` and `updated`, and how to access element attributes and push events. ```javascript // components/card.hooks.js let Card = { mounted(){ console.log("Card mounted", this.el) // Access attributes const title = this.el.dataset.title // Event listeners this.el.addEventListener("click", (e) => { this.pushEvent("card_clicked", {id: this.el.id}) }) }, updated(){ console.log("Card updated") } } export {Card} ``` -------------------------------- ### Full Integration Test for Surface Components Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Shows a full integration test scenario in Surface, involving a parent LiveView rendering a LiveComponent. It tests the initial state and interaction through events. ```elixir defmodule TestLive do use Surface.LiveView def render(assigns) do ~F''' ''' end end test "full integration test" do {:ok, view, html} = live(build_conn(), "/test") assert html =~ "Count: 0" view |> element("button", "+") |> render_click() assert render(view) =~ "Count: 1" end ``` -------------------------------- ### Stateful LiveComponent in Elixir Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Demonstrates a basic Stateful LiveComponent in Elixir using Surface. It includes props, data assignments, event handling for increment/decrement, and rendering logic. ```elixir defmodule Counter do use Surface.LiveComponent prop id, :string, required: true data count, :integer, default: 0 def handle_event("increment", _, socket) do {:noreply, assign(socket, count: socket.assigns.count + 1)} end def handle_event("decrement", _, socket) do {:noreply, assign(socket, count: socket.assigns.count - 1)} end def render(assigns) do ~F'''
{@count}
''' end end ``` -------------------------------- ### Use Named Slots in Surface Components (Surface) Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Demonstrates the usage of named slots in Surface, allowing specific content to be passed to designated areas like `:header`, default slot, and `:footer`. ```surface <:header>

Card Title

This is the main card content.

<:footer>
``` -------------------------------- ### Surface Dynamic Attributes Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Illustrates how to dynamically set attributes on HTML elements and components in Surface. It covers the recommended spread syntax `{...@attribute}` and the deprecated `:attrs`. ```surface
Content
Content
``` -------------------------------- ### Surface Slot Arguments Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Shows how to define and use slot arguments in Surface, allowing data to be passed into slots. The `:let` directive is used to bind variables within the slot content. ```surface <:slot :let={item}> {@item.name} ``` -------------------------------- ### Use Slots with Arguments in Surface Components (Surface) Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Shows how to use slots that accept arguments in Surface. The `:default` slot is used with `:let` to destructure the passed arguments (`user` and `index`) for rendering. ```surface <:default :let={user: user, index: index}> {index + 1}. {@user.name} - {@user.email} ``` -------------------------------- ### Surface Template Directives: :for Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Illustrates the :for directive for iterating over collections and rendering elements for each item, including support for indices. ```surface
{@item.name}
{index + 1}. {@item.name}
``` -------------------------------- ### Define Slots with Arguments in Surface Components (Elixir) Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Illustrates how to define slots that accept arguments in Surface Components using Elixir. The `slot` macro with the `:arg` option allows passing data like `user` and `index` to the slot. ```elixir defmodule UserList do use Surface.Component prop users, :list, required: true slot default, arg: %{user: :map, index: :integer} def render(assigns) do ~F"""
  • <#slot {user: user, index: index} />
""" end end ``` -------------------------------- ### Surface: Dynamic LiveComponent Rendering Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Shows dynamic rendering of LiveComponents in Surface by passing the module, ID, and props as assigns to the `LiveComponent` component. ```Surface ``` -------------------------------- ### Create Renderless Slotables in Surface Components (Elixir) Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Demonstrates the creation of renderless slotables in Surface Components using Elixir. The `use Surface.Component, slot: "column"` syntax defines a component that primarily serves to provide slot content without its own rendering logic. ```elixir defmodule Column do use Surface.Component, slot: "column" prop title, :string prop width, :string # No render/1 - it's renderless end ``` -------------------------------- ### Surface Contexts: Storing and Retrieving Values Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Illustrates how to use Surface Contexts to share data between parent and child components without explicit property passing. It covers storing values in `mount` and retrieving them in child components. ```elixir def mount(_params, session, socket) do user = get_user_from_session(session) socket = Context.put(socket, user: user, timezone: "UTC") {:ok, socket} end ``` ```surface defmodule UserProfile do use Surface.Component # Retrieve from context automatically data user, :map, from_context: :user data timezone, :string, from_context: :timezone def render(assigns) do ~F''' ''' end end ``` -------------------------------- ### Handle Events with Surface Components in Elixir Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Shows how to define event handlers for user interactions like clicks and focus events within a Surface Component using Elixir. It utilizes the `:on-click` and `:on-focus` directives. ```elixir defmodule Button do use Surface.Component prop click, :event prop focus, :event def render(assigns) do ~F""" """ end end ``` -------------------------------- ### Colocated CSS File for Component Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Demonstrates creating a colocated CSS file for a component, defining styles for elements within that component. ```css /* components/card.css */ .card { border: 1px solid #ddd; border-radius: 8px; padding: 16px; } .card-header { border-bottom: 1px solid #eee; padding-bottom: 8px; margin-bottom: 16px; } .card-title { font-size: 1.2em; font-weight: bold; margin: 0; } ``` -------------------------------- ### Stateful LiveView with Surface Components (Elixir) Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Shows a stateful LiveView in Surface using Elixir, managing internal state with `data` assigns and handling events to update this state. It also demonstrates rendering a child component (`Dialog`) based on the state. ```elixir defmodule MyLive do use Surface.LiveView data count, :integer, default: 0 data show_modal, :boolean, default: false def handle_event("increment", _, socket) do {:noreply, assign(socket, count: socket.assigns.count + 1)} end def handle_event("show_modal", _, socket) do {:noreply, assign(socket, show_modal: true)} end def render(assigns) do ~F"""

Count: {@count}

""" end end ``` -------------------------------- ### Testing LiveComponents Event Handling in Surface Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Demonstrates testing the event handling capabilities of Surface LiveComponents within a LiveView context. It involves rendering a LiveComponent in isolation and triggering events. ```elixir test "handles events in live component" do {:ok, view, _html} = live_isolated(build_conn(), TestLive) # Test event view |> element("[data-testid=increment]") |> render_click() assert render(view) =~ "Count: 1" end ``` -------------------------------- ### Hooks from Other Components in Surface Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Shows how to reference and use hooks defined in other components within a Surface template, specifying the source component. ```surface
Content
``` -------------------------------- ### Surface: Navigation Link Component Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Demonstrates the usage of the `Link` component in Surface for creating navigation links. It shows basic usage and usage with CSS classes. Note: This component is deprecated in favor of LiveView's `<.link>`. ```Surface Users Users ``` -------------------------------- ### Multiple Hooks Usage in Surface Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Demonstrates the usage of multiple JavaScript hooks within a Surface template, attaching different hooks to nested elements. ```surface
Content
``` -------------------------------- ### CSS Variants Styling Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Shows the corresponding CSS for the `Button` component's variants, demonstrating how attributes like `data-variant` and `data-size` are used to apply styles. ```css /* components/button.css */ .btn { padding: 8px 16px; border-radius: 4px; border: none; cursor: pointer; } /* Variants generated automatically */ .btn[data-variant="primary"] { background: blue; color: white; } .btn[data-variant="secondary"] { background: gray; color: white; } .btn[data-size="small"] { padding: 4px 8px; font-size: 0.8em; } .btn[data-size="large"] { padding: 12px 24px; font-size: 1.2em; } ``` -------------------------------- ### Elixir Surface Property Declaration Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Illustrates various ways to declare properties for a Surface component in Elixir, including simple properties, default values, required properties, value validation, and documentation. ```elixir defmodule MyComponent do use Surface.Component # Simple property prop name, :string # With default value prop type, :string, default: "info" # Required prop id, :string, required: true # With valid values prop size, :string, values: ["small", "medium", "large"] # With documentation @doc "The component title" prop title, :string def render(assigns) do ~F"""

{@title}

Hello, {@name}!

""" end end ``` -------------------------------- ### Define Component Props and Data in Elixir Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Demonstrates how to define public properties (props) and private internal state (data) for a Surface LiveComponent using Elixir. Props are for external input, while data is for internal state. ```elixir defmodule Dialog do use Surface.LiveComponent # Props - public API prop title, :string, required: true prop close_event, :event # Data - internal state data show, :boolean, default: false data animation_class, :string, default: "" # ... end ``` -------------------------------- ### Elixir: Embed Surface Template Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Embeds a Surface template file (`home.sface`) into an Elixir module, allowing the template to be rendered as part of the module's functionality. ```Elixir defmodule MyAppWeb.PageHTML do use MyAppWeb, :html import Surface embed_sface "home.sface" end ``` -------------------------------- ### Surface Template Directives: :show Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Demonstrates the :show directive for conditionally showing or hiding elements using CSS, while keeping them in the DOM. ```surface
This element stays in the DOM but can be hidden with CSS
``` -------------------------------- ### Emit Local Events in Surface LiveComponents (Elixir) Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Demonstrates how to define and emit local events within a Surface LiveComponent using Elixir. The `handle_event` function captures the local event, and the button uses `:on-click` to trigger it. ```elixir defmodule MyLiveComponent do use Surface.LiveComponent def handle_event("local_event", _params, socket) do # This event is handled locally in the component {:noreply, socket} end def render(assigns) do ~F""" """ end end ``` -------------------------------- ### Inter-Component Communication with send_update/2 Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Shows how to communicate between Surface components using the `send_update/2` function. This includes updating a child component from a parent LiveView and defining a public API for a component. ```elixir # In parent LiveView def handle_event("reset_counter", _, socket) do send_update(Counter, id: "my-counter", count: 0) {:noreply, socket} end ``` ```elixir defmodule Dialog do use Surface.LiveComponent data show, :boolean, default: false # Public API def show(id) do send_update(__MODULE__, id: id, show: true) end def hide(id) do send_update(__MODULE__, id: id, show: false) end # ... end # Usage: Dialog.show("my-dialog") ``` -------------------------------- ### Surface Template Directives: :if Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Shows how to use the :if directive for conditional rendering of elements in Surface templates. ```surface
This content will be rendered only if @show_content is true
``` -------------------------------- ### Declare Slots in Surface Components (Elixir) Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Shows how to declare different types of slots (header, default, footer) within a Surface Component using Elixir. The `slot` macro defines placeholders for content, and `:if slot_assigned?` conditionally renders them. ```elixir defmodule Card do use Surface.Component @doc "The card header" slot header @doc "The main card content" slot default, required: true @doc "The card footer" slot footer def render(assigns) do ~F"""
<#slot {@header} />
<#slot />
""" end end ``` -------------------------------- ### Stateless Functional Components in Surface (Elixir) Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Illustrates a stateless functional component in Surface using Elixir. This component defines props and slots but has no internal state, behaving like a pure function. ```elixir defmodule Button do use Surface.Component prop click, :event prop kind, :string, default: "is-info" slot default def render(assigns) do ~F""" """ end end ``` -------------------------------- ### Clipboard Hook Usage in Surface Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Shows the Surface template usage for the Clipboard Hook, attaching it to a button and passing the text to be copied via a data attribute. ```surface ``` -------------------------------- ### Elixir: Surface Table Component Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Implements a flexible `Table` component using Surface for Elixir. It allows defining table data, styling options (striped, bordered, hoverable), and column configurations via slots. Each column can have a title, and the data is rendered row by row. ```Elixir defmodule Components.Table do use Surface.Component @doc "The table data" prop data, :list, required: true @doc "Striped rows" prop striped, :boolean, default: false @doc "Bordered table" prop bordered, :boolean, default: false @doc "Hoverable rows" prop hoverable, :boolean, default: false @doc "Column definitions" slot column, arg: %{row: :map}, required: true def render(assigns) do ~F"""
{col.title}
<#slot {col} {row: row} />
""" end end ``` -------------------------------- ### Elixir Surface CSS Property Declaration Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Shows how to declare a `:css_class` property in Surface, which allows for special syntax when defining CSS classes in the template, combining static and dynamic class names. ```elixir # css_class property allows special syntax prop class, :css_class # In template: # ``` -------------------------------- ### Surface: LivePatch Component (Deprecated) Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Shows the usage of the `LivePatch` component in Surface for creating live patches with CSS classes. This component is deprecated. ```Surface Users ``` -------------------------------- ### Multiple Hooks in Surface Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Illustrates how to define and use multiple JavaScript hooks within a single Surface component. It shows defining separate hook objects and applying them to different elements. ```javascript // components/my_component.hooks.js let MainHook = { mounted(){ console.log("Main hook") } } let SecondaryHook = { mounted(){ console.log("Secondary hook") } } export {MainHook, SecondaryHook} ``` -------------------------------- ### Elixir Tabs Component Definition Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Defines the Surface LiveComponent for the Tabs component in Elixir. It handles tab switching events and renders the tab structure. Requires the `id` prop and accepts `tab` slots. ```elixir defmodule Components.Tabs do use Surface.LiveComponent @doc "Component ID" prop id, :string, required: true @doc "Tab definitions" slot tab, arg: %{active: :boolean} data active_tab, :integer, default: 0 def handle_event("switch_tab", %{"index" => index}, socket) do {:noreply, assign(socket, active_tab: String.to_integer(index))} end def render(assigns) do ~F"""
<#slot {tab} {active: @active_tab == index} />
""" end end ``` -------------------------------- ### Handle Events in Parent Component (Surface) Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Illustrates how to bind a component's event to a handler in the parent component using Surface syntax. The `click` prop is used to specify the event name. ```surface ``` -------------------------------- ### Surface Comments Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Explains the two types of comments in Surface: public comments (``) which are sent to the browser, and private comments (`{!-- --}`) which are not. ```surface {!-- Private comment (not sent to browser) --} ``` -------------------------------- ### Use :hook Directive in Surface Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Shows how to use the `:hook` directive in a Surface template to attach JavaScript hooks to DOM elements. It includes passing data attributes and rendering slots. ```surface
<#slot />
``` -------------------------------- ### Elixir: Surface Button Component Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Defines a reusable `Button` component in Surface for Elixir applications. It supports various props for type, size, styling (outlined, rounded), states (loading, disabled), and click events. It also includes a default slot for button content. ```Elixir defmodule Components.Button do use Surface.Component @doc "The button type (color)" prop type, :string, default: "info", values: ["primary", "info", "success", "warning", "danger"] @doc "The button size" prop size, :string, values: ["small", "normal", "medium", "large"] @doc "Outlined style" prop outlined, :boolean, default: false @doc "Rounded style" prop rounded, :boolean, default: false @doc "Loading state" prop loading, :boolean, default: false @doc "Disabled state" prop disabled, :boolean, default: false @doc "Click event" prop click, :event @doc "The button content" slot default, required: true def render(assigns) do ~F""" """ end end ``` -------------------------------- ### Scoped Context in Surface Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Demonstrates how to use scoped contexts in Surface to prevent naming conflicts when sharing data. It shows storing and retrieving context values with a specific module scope. ```elixir defmodule MyForm do use Surface.LiveComponent def mount(socket) do socket = Context.put(socket, MyForm, form: @form, errors: @errors) {:ok, socket} end end # Retrieving with scope form = Context.get(socket_or_assigns, MyForm, :form) ``` -------------------------------- ### Surface: LiveRedirect Component (Deprecated) Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Illustrates the use of the `LiveRedirect` component in Surface for redirecting to different pages with CSS classes. This component is deprecated. ```Surface Dashboard ``` -------------------------------- ### Elixir Surface Event Property Declaration Source: https://github.com/lucas-stellet/surface-ui-docs/blob/main/docs.md Demonstrates declaring an `:event` property in Surface, which is used to pass event handlers from a parent component to a child component. The event is then bound to an element within the child. ```elixir prop click, :event # In parent template: # # # In component: # ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.