Common UI Components

Pink-Cupcake gives you a set of pre-built Vue components, styled with UIkit classes, that handle the most common app interface patterns. For example, instead of building a navbar from scratch, you can use UFNavBar. Instead of writing your own paginated data table, you can use the Sprunje component set.

One common point of confusion is the difference between Pink-Cupcake components and UIkit classes. They're both part of your UI, but they play different roles:

  • Pink-Cupcake components are Vue components you use as tags in your templates — <UFNavBar />, <UFSideBarItem />, <UFAlert />. They are styled with UIkit but also include built-in structure, behavior, and API for common UI patterns.
  • UIkit classes are CSS utility classes you apply directly to HTML elements — class="uk-card uk-grid-small uk-margin".

Pink-Cupcake Components

These are the components exported and globally registered by the installed theme package. They're organized into three groups: layout and navigation, feedback, and data tables.

Layout and Navigation

UFNavBar

The main navigation bar at the top of the page. Sticks to the top on scroll, shows a logo/title link on the left, and navigation items on the right. On mobile, it renders a hamburger button that toggles the sidebar panel.

Props:

Prop Type Default Description
title string '' Brand text or logo label
to string | object '' Route destination for the logo

Slots:

Slot Description
title Overrides the title prop with custom content. Use it to display a logo or other custom elements.
default Navigation items displayed on the right (desktop)
<UFNavBar title="My App" :to="{ name: 'home' }">
    <UFNavBarItem :to="{ name: 'about' }" label="About" />
</UFNavBar>

UFNavBarItem

A single link inside UFNavBar. Handles both internal router links and external URLs. Automatically adds an active class when the current route matches.

Props:

Prop Type Default Description
label string '' Link text
to string | object '' Route object or external URL

Slots:

Slot Description
default Overrides the label prop
<UFNavBarItem :to="{ name: 'dashboard' }" label="Dashboard" />
<UFNavBarItem to="https://userfrosting.com" label="UserFrosting" />

UFNavBarDropdown

A navbar item with a dropdown panel. Useful for grouping sub-links or embedding content like a login form directly in the navbar.

Props:

Prop Type Default Description
label string '' Trigger button text

Slots:

Slot Description
label Overrides the trigger label
default Dropdown content, typically UFNavBarItem elements
<UFNavBarDropdown label="Account">
    <UFNavBarItem :to="{ name: 'account.settings' }" label="Settings" />
</UFNavBarDropdown>

UFSideBar

The sidebar navigation container. On desktop it renders as a fixed-position panel on the side. On mobile it becomes an off-canvas drawer toggled by the UFNavBar hamburger button. No props needed — just fill it with items.

Slots:

Slot Description
default Sidebar content (items, dropdowns, labels)
<UFSideBar>
    <UFSideBarItem :to="{ name: 'dashboard' }" label="Dashboard" icon="home" />
</UFSideBar>

UFSideBarItem

A sidebar navigation link. Supports UIkit icons and FontAwesome icons side by side. Highlights automatically when its route is active, and closes the mobile off-canvas panel on click.

Props:

Prop Type Default Description
label string '' Item text
to string | object '' Route object or external URL
icon string '' UIkit icon name (e.g. 'home')
faIcon string '' FontAwesome icon name (e.g. 'gauge-high')

Slots:

Slot Description
default Overrides the label prop
<UFSideBarItem :to="{ name: 'admin.users' }" label="Users" faIcon="users" />
<UFSideBarItem :to="{ name: 'reports' }" label="Reports" icon="album" />

UFSideBarDropdown

A collapsible section inside the sidebar. Expands automatically when any child route is active. Use it to group related pages under a single heading.

Props:

Prop Type Default Description
label string '' Section title
to string | object '' Route used to determine if the group should open
icon string '' UIkit icon name
faIcon string '' FontAwesome icon name
hideCaret boolean false Hide the expand/collapse triangle

Slots:

Slot Description
label Overrides the label text
default Sub-items (typically UFSideBarItem elements)
<UFSideBarDropdown label="Reports" faIcon="chart-bar">
    <UFSideBarItem :to="{ name: 'reports.daily' }" label="Daily" />
    <UFSideBarItem :to="{ name: 'reports.monthly' }" label="Monthly" />
</UFSideBarDropdown>

UFSideBarLabel

A non-clickable section heading used to visually separate groups of items in the sidebar.

Props:

Prop Type Required Description
label string The text to display
<UFSideBarLabel label="Administration" />
<UFSideBarItem :to="{ name: 'admin.users' }" label="Users" />

UFHeaderPage

Renders the current page title, description, and breadcrumb trail at the top of the content area. It reads everything automatically from the route's meta fields via usePageMeta() — no props needed. If the route has no title or meaningful breadcrumbs, the component hides itself entirely.

<main class="uk-container">
    <UFHeaderPage />
    <RouterView />
</main>

Tip

Set title and description in your route's meta field to populate this component automatically.

Feedback

UFAlert

Displays an inline alert message from an AlertInterface object. Typically used to surface API errors or success messages next to a form. Supports multiple severity styles and an optional close button.

Props:

Prop Type Required Description
alert AlertInterface Alert data object

The AlertInterface has the following fields:

Field Type Description
title string Alert heading
description string Body text (rendered as HTML)
style Severity An instance of Severity — e.g. Severity.Success, Severity.Warning, Severity.Danger, Severity.Info
closeBtn boolean Show a dismiss button
hideIcon boolean Hide the automatic severity icon

Slots:

Slot Description
default Overrides the description content

Emits:

Emit Description
close Emitted when the close button is clicked
<!-- Show an API error -->
<UFAlert v-if="apiError" :alert="apiError" @close="apiError = null" />

<!-- Hardcoded severity example -->
<UFAlert :alert="{ title: 'Password updated', style: Severity.Success, closeBtn: true }" />

UFModal

The base modal component. Wraps UIkit's modal system. Can be opened with a uk-toggle attribute or programmatically via UIkit.modal('#id').show(). Use this when the pre-built modal variants don't fit your needs.

Props:

Prop Type Default Description
closable boolean false Show an × close button
escClose boolean true Close with the ESC key
bgClose boolean true Close by clicking the backdrop

Slots:

Slot Description
header Modal header
default Modal body
footer Modal footer
<a href="#my-modal" uk-toggle>Open modal</a>

<UFModal id="my-modal" closable>
    <template #header>Confirm action</template>
    <p>Are you sure you want to continue?</p>
    <template #footer>
        <button class="uk-button uk-modal-close">Cancel</button>
        <button class="uk-button uk-button-danger">Yes, delete</button>
    </template>
</UFModal>

UFModalAlert

A pre-built modal for simple one-action alerts: a title, a message, and a single OK button. No cancel option.

Props:

Prop Type Default Description
title string '' Modal title
prompt string 'Something happened that requires your attention.' Body message
btnLabel string 'Ok' OK button label

Slots:

Slot Description
header Overrides the title
default Overrides the body
footer Overrides the button area
<UFModalAlert id="success-alert" title="Done!" prompt="Your changes were saved." />

UFModalConfirmation

A pre-built confirmation dialog with Accept and Cancel buttons. Emits confirmed or cancelled so you can wire up your logic without managing modal state manually.

Props:

Prop Type Default Description
title string 'CONFIRMATION' i18n key for the title
prompt string 'CONFIRM_ACTION' i18n key for the body message
warning string 'WARNING_CANNOT_UNDONE' i18n key for the warning note (empty string to hide)
acceptLabel string 'CONFIRM' i18n key for the accept button
rejectLabel string 'CANCEL' i18n key for the cancel button
acceptSeverity Severity Severity.Primary Accept button style
rejectSeverity Severity Severity.Default Cancel button style
acceptIcon string | null 'check' FontAwesome icon for the accept button
rejectIcon string | null 'xmark' FontAwesome icon for the cancel button
icon string | null 'triangle-exclamation' Body icon. Pass null to hide
cancelBtn boolean true Show the cancel button
closable boolean false Show × close button
escClose boolean true Close on ESC
bgClose boolean true Close on backdrop click

Slots:

Slot Description
header Overrides the title
prompt Overrides only the body message
warning Overrides only the warning text
default Overrides the entire body
footer Overrides the entire button area

Emits:

Emit Description
confirmed User clicked the accept button
cancelled User clicked the cancel button

Note

Closing via backdrop click or ESC does not emit cancelled. If you need to catch all cancel paths, set bgClose and escClose to false.

<UFModalConfirmation
    id="delete-user"
    title="USER.DELETE"
    prompt="USER.DELETE_CONFIRM"
    warning=""
    acceptLabel="USER.DELETE"
    acceptIcon="trash"
    :rejectIcon="null"
    :acceptSeverity="Severity.Danger"
    @confirmed="deleteUser"
    @cancelled="closeModal" />

UFModalPrompt

A modal with a text input field for collecting user input before an action — like asking for a name or a confirmation phrase. Bind the value with v-model.

Props:

Prop Type Default Description
title string '' Modal title
prompt string '' Input field label (i18n key)
placeholder string '' Input placeholder (i18n key)
btnLabel string 'OK' Submit button label

Slots:

Slot Description
header Overrides the title
default Overrides the entire body
footer Overrides the button area
<UFModalPrompt
    id="rename-modal"
    v-model="newName"
    title="Rename item"
    prompt="New name"
    placeholder="e.g. My Report" />

Sprunje Data Tables

The Sprunje component set is built around UFSprunjeTable, which fetches paginated data from a Sprunjer API endpoint and distributes it to nested components via Vue's provide/inject. All other Sprunje components must be used inside UFSprunjeTable.

Note

The Sprunje component set is designed to work with the API structure provided by UserFrosting's Sprunjer system. We'll learn more about Sprunje in the next pages. Just remember that these components exists and are available for you to use whenever you need to display paginated server data in a table.

UFSprunjeTable

The root component. Fetches, paginates, sorts, and filters server data from a Sprunjer API endpoint. Exposes a sprunjer object to slot scopes for advanced control.

Props:

Prop Type Default Description
dataUrl string ✅ required API endpoint URL
searchColumn string Enables a search input bound to this column filter
defaultSorts object {} Initial sort state, e.g. { name: 'asc' }
defaultFilters object {} Initial filter state
defaultSize number 10 Initial page size
defaultPage number 0 Initial page (0-indexed)
hidePagination boolean false Hide the paginator
hideFilters boolean false Hide the filter panel toggle

Slots:

Slot Scope Description
actions { sprunjer } Area above the table, left side (e.g. a "Create" button)
filters { sprunjer } Area above the table, right side (custom filter controls)
header { sprunjer } <thead> row — place UFSprunjeHeader components here
body { row, sprunjer } <tbody> row per item — place UFSprunjeColumn components here
filterPanel { sprunjer } Extra content in the filter sidebar panel
paginator { sprunjer } Overrides the default UFSprunjePaginator
<UFSprunjeTable dataUrl="/api/users" searchColumn="name" :defaultSorts="{ name: 'asc' }">
    <template #actions>
        <button class="uk-button uk-button-primary">Add user</button>
    </template>
    <template #header>
        <UFSprunjeHeader sort="name">Name</UFSprunjeHeader>
        <UFSprunjeHeader sort="email">Email</UFSprunjeHeader>
        <UFSprunjeHeader>Actions</UFSprunjeHeader>
    </template>
    <template #body="{ row }">
        <UFSprunjeColumn>{{ row.name }}</UFSprunjeColumn>
        <UFSprunjeColumn>{{ row.email }}</UFSprunjeColumn>
        <UFSprunjeColumn>
            <button class="uk-button uk-button-small">Edit</button>
        </UFSprunjeColumn>
    </template>
</UFSprunjeTable>

UFSprunjeHeader

A <th> cell for the table header. When sort is provided, it renders as a clickable sortable column with automatic direction indicators (ascending / descending / neutral).

Props:

Prop Type Default Description
sort string Column key to sort by. Omit for non-sortable columns

Slots:

Slot Description
default Column label
<UFSprunjeHeader sort="created_at">Created</UFSprunjeHeader>
<UFSprunjeHeader>Actions</UFSprunjeHeader>

UFSprunjeColumn

A <td> cell for table body rows. Accepts standard HTML attributes (like class) via fallthrough.

Slots:

Slot Description
default Cell content
<UFSprunjeColumn class="uk-width-1-4">{{ row.name }}</UFSprunjeColumn>

UFSprunjeSearch

A search input that filters the table by a specific column.

Props:

Prop Type Required Description
column string The column/filter key to search on
label string Placeholder label. Defaults to a translated "Search" string

Tip

For a simple search, you can also use the searchColumn prop directly on UFSprunjeTable instead of adding UFSprunjeSearch manually.

Ready-Made Views

Pink-Cupcake and the admin sprinkle also export pre-built page views you can use directly in your routes:

  • Auth views: PageLogin, PageRegister, PageForgotPassword, and others.
  • Admin views: UFAdminDashboardPage, UFAdminUsersPage, UFAdminRolesPage, and more from @userfrosting/sprinkle-admin. These are used in the admin panel routes defined by the admin sprinkle, but you can also use them directly in your own routes if you want.

You can drop these straight into your route definitions, or study them as solid reference implementations when building similar pages of your own.

A Quick Layout Example

Here's how Pink-Cupcake components and UIkit classes work together in a typical layout:

<template>
    <UFNavBar title="Control Panel">
        <template #default>
            <UFNavBarItem :to="{ name: 'dashboard' }" label="Dashboard" />
        </template>
    </UFNavBar>

    <UFSideBar>
        <UFSideBarItem :to="{ name: 'dashboard' }" label="Dashboard" icon="home" />
        <UFSideBarItem :to="{ name: 'reports' }" label="Reports" faIcon="chart-line" />
    </UFSideBar>

    <main class="uk-container uk-margin-top">
        <UFHeaderPage />
        <RouterView />
    </main>
</template>

UFNavBar, UFSideBar, and UFHeaderPage are Pink-Cupcake components that define the shell structure. uk-container and uk-margin-top are UIkit utility classes that handle spacing and layout. Both are doing their job at the same time.