ElementaryPines
v0.3.000 · 28 components · 11 colors · 35 icons
Under heavy development · early stages

Pines UI rendered from Swift

A type-safe Swift package that renders Pines UI components through Elementary, the HTML renderer for Swift server-side frameworks including Vapor and Hummingbird.

ProductPage.swift
import ElementaryPines

pinesCard {
    div(.class("p-7")) {
        h2 { "Featured" }
        p  { "Rendered server-side." }
        button { "Add to cart" }
            .pinesButtonStyle(.solid)
        span { "New" }
            .pinesBadgeStyle(.light)
        pinesProgress(75)
    }
}

This showcase is hand-written HTML — no Swift server renders it. Every component on this page is a 1:1 reflection of the markup the package produces, copied from elementary-pines so the classes, attributes and Alpine directives match exactly.

Category

Primitives

Building blocks — buttons, badges, icons, cards, progress, quotes, banners, and alerts. Every variant, every color.

Button

button { "..." }.pinesButtonStyle(_:color:)

3 styles × 11 colors
Style
import ElementaryPines

pinesSelect(items: [
    PinesSelectItem(title: "Apple",  value: "apple"),
    PinesSelectItem(title: "Banana", value: "banana"),
    PinesSelectItem(title: "Cherry", value: "cherry"),
    PinesSelectItem(title: "Date",   value: "date", disabled: true),
], placeholder: "Select a fruit")

Accordion

pinesAccordion(items:)

Alpine Collapse
import ElementaryPines

pinesAccordion(items: [
    .init(title: "What is Elementary?", body: "A type-safe HTML renderer."),
    .init(title: "Does it support Alpine?", body: "Yes, through elementary-alpine."),
])

Tabs

pinesTabs(tabs:)

Alpine.js · animated marker

Project overview

Recent activity

Workspace settings

import ElementaryPines

pinesTabs(tabs: [
    PinesTab(title: "Overview") { p { "Project overview" } },
    PinesTab(title: "Activity") { p { "Recent activity" } },
    PinesTab(title: "Settings") { p { "Workspace settings" } },
])

Toast

pinesToast(name:) — window.toast(message, {description, type, position, html})

6 positions · 7 types · html · expanded

Controls use the demo's control options — not a copy of Pines docs buttons. Changing any control updates the next window.toast(title, {description, type, position, html}) call.

import ElementaryPines

pinesToast()

// Type-safe via PinesToastType / PinesToastPosition (see below):
window.toast("", [description: , type: ., position: ., html: customHTML ])

Tooltip

pinesTooltip(text:position:arrow:content:)

hover and focus

Hover for details
import ElementaryPines

pinesTooltip(text: "Rendered on hover", position: .top, arrow: true) {
    button { "Hover for details" }
}

Badge

span { "..." }.pinesBadgeStyle(_:color:)

5 styles × 11 colors
Style
Color
import ElementaryPines

span {  }
    .pinesBadgeStyle(., color: .)

Icon

pinesIcon(_:size:color:)

35 icons × 5 sizes × 11 colors
Icon
Size
Color
import ElementaryPines

pinesIcon(., size: ., color: .)

Card

pinesCard(_:image:content:)

4 variants
Variant
import ElementaryPines

pinesCard(., image: "photo.jpg") {
    // user content
}

Progress

pinesProgress(_:of:color:size:)

3 sizes × 11 colors
Size
Color
import ElementaryPines

  pinesProgress()pinesProgress(, color: ., size: .)

Quote

pinesQuote(quote:author:role:avatar:)

optional avatar

This is a great quote.

Author Name
Role
import ElementaryPines

pinesQuote(
    quote: "This is a great quote.",
    author: "Author Name",
    role: "Role",
    avatar: 
)

Banner

pinesBanner(label:message:href:icon:dismissible:position:)

4 icon presets × dismissible
Icon
Position
Auto-dismiss
Dismissible
Dismiss
import ElementaryPines

pinesBanner(
    label: ,
    message: ,
    href: "#",
    icon: .,
    dismissible: ,
    position: .
)

Alert

pinesAlert(_:icon:content:)

5 variants
Variant
Color
Icon
import ElementaryPines

pinesAlert(.) {
    h5 {  }
    div(.class("text-sm opacity-70")) {
        
    }
}

Category

Forms & controls

Inputs, selects, date pickers, switches, sliders, ratings. Interactive pieces include Alpine.js state for the preview.

DatePicker

pinesDatePicker(labelText:placeholder:format:width:disabled:attributes:)

Alpine.js · readonly input
Disabled
import ElementaryPines

pinesDatePicker(
    labelText: ,
    placeholder: ,
 format: ., width: , disabled: 
)

Input

pinesInput(type:color:placeholder:name:value:id:disabled:)

11 colors
Color
Type
Disabled
Disabled
import ElementaryPines

pinesInput(type: , color: ., placeholder: , disabled: true)

Textarea

pinesTextarea(color:placeholder:name:id:rows:disabled:)

11 colors
Color
import ElementaryPines

pinesTextarea(color: ., placeholder: , rows: )

Select

pinesSelect(items:placeholder:width:)

Alpine.js
import ElementaryPines

pinesSelect(items: [
    PinesSelectItem(title: "Apple",  value: "apple"),
    PinesSelectItem(title: "Banana", value: "banana"),
    PinesSelectItem(title: "Cherry", value: "cherry"),
    PinesSelectItem(title: "Date",   value: "date", disabled: true),
], placeholder: "Select a fruit")

Checkbox

pinesCheckbox(labelText:color:checked:name:id:)

label · card · custom content
Variant
Color
Checked
Checked
import ElementaryPines

pinesCheckbox(
    labelText: "Accept terms",
    color: .,
    checked: ,
    name: "terms",
    id: "terms"
)

Switch

pinesSwitch(labelText:color:size:name:id:disabled:)

2 sizes × 11 colors
Size
Color
On
On
import ElementaryPines

  pinesSwitch(labelText: "On", color: ., size: .small, name: "notifications", id: "notifications")

RadioGroup

pinesRadioGroup(options:name:disabled:)

Disabled-item support
import ElementaryPines

pinesRadioGroup(options: [
    PinesRadioGroupOption(title: "Free",  value: "free"),
    PinesRadioGroupOption(title: "Pro",   value: "pro"),
    PinesRadioGroupOption(title: "Team",  value: "team", disabled: true),
], name: )

RangeSlider

pinesRangeSlider(color:name:id:min:max:value:step:disabled:)

11 colors
0100
Disabled
Color
import ElementaryPines

pinesRangeSlider(
    color: .,
    name: "volume",
    id: "volume",
    min: 0, max: 100,
    value: , step: , disabled: 
)

Rating

pinesRating(icon:color:emptyStyle:maxStars:value:disabled:compactReset:)

2 variants × 2 icons × 2 empty styles
Rated Stars
Rated
Reset mode
Icon
Color
Empty style
Disabled
Disabled
import ElementaryPines

pinesRating(
    icon: .,
    color: .,
    emptyStyle: .,
    maxStars: 5,
    value: ,
    disabled: ,
    compactReset: 
)