PlanTempusApp/PlanTempus.Application/wwwroot/css/COMPONENT-CATALOG.md
Janus C. H. Knudsen a1059adf06 Adds salary specifications with detailed accordion view
Introduces new salary specification feature with interactive accordion component

Implements detailed salary breakdown including:
- Salary specification JSON data model
- Salary specification page with printable view
- Accordion component for expanding/collapsing salary details
- Localization support for new salary labels

Enhances employee salary transparency and detail presentation
2026-01-23 20:03:24 +01:00

16 KiB
Raw Blame History

SWP Design System - Component Catalog

Reference for alle genbrugelige komponenter. LAV ALDRIG EN NY KOMPONENT HVIS DEN ALLEREDE EKSISTERER HER.


Base Patterns (components.css)

VIGTIGT: Disse base patterns skal ALTID bruges som foundation for nye features.

Data Table Pattern (ANBEFALET)

Alle nye tabeller skal bruge swp-data-table fra components.css:

<swp-card class="feature-context">
    <swp-data-table>
        <swp-data-table-header>
            <swp-data-table-cell>Kolonne 1</swp-data-table-cell>
            <swp-data-table-cell>Kolonne 2</swp-data-table-cell>
        </swp-data-table-header>
        <swp-data-table-row>
            <swp-data-table-cell>Data 1</swp-data-table-cell>
            <swp-data-table-cell>Data 2</swp-data-table-cell>
        </swp-data-table-row>
    </swp-data-table>
</swp-card>

CSS Pattern:

/* I feature CSS - definer kun kolonner via context class */
swp-card.feature-context swp-data-table {
  grid-template-columns: 1fr 120px 80px;
}

/* Kolonne-specifik styling med nth-child */
swp-card.feature-context swp-data-table-cell:nth-child(2) {
  font-family: var(--font-mono);
}

VIGTIGT: Context class skal være på swp-card, IKKE en wrapper div!

List Item Pattern

Alle lister (notifikationer, bookinger, attentions) bruger:

<swp-feature-list> <!-- display: contents -->
  <swp-feature-item> <!-- extends swp-list-item-base -->
    <!-- content -->
  </swp-feature-item>
</swp-feature-list>

Icon Container Pattern

Standard icon wrapper (40×40px cirkel):

<swp-icon-container>
  <i class="ph ph-icon"></i>
</swp-icon-container>

Page Structure (page.css)

Element Beskrivelse Eksempel
swp-page-container Hovedcontainer for side <swp-page-container>...</swp-page-container>
swp-page-header Side header med titel og actions Flex, space-between
swp-page-title Titel-wrapper med h1 og p h1 + subtitle
swp-page-actions Action buttons i header Flex gap
swp-card Standard card wrapper Border, padding, rounded
swp-card-header Card header wrapper Flex, space-between, border-bottom
swp-card-title Card title med ikon Flex, icon + text
swp-section-action Action link i header Teal, clickable
swp-section-label Subsection label (KUN til sekundære sektioner inde i card, ALDRIG som card header) Uppercase, 11px, border-bottom
swp-card-content Card indhold Block

Card Header Eksempler

VIGTIGT: Brug ALTID swp-card-header + swp-card-title som første element i et card.

FORKERT - brug IKKE swp-section-label som card header:

<swp-card>
    <swp-section-label>Kontaktoplysninger</swp-section-label>
    <!-- content -->
</swp-card>

KORREKT - brug swp-card-header + swp-card-title:

<swp-card>
    <swp-card-header>
        <swp-card-title>Kontaktoplysninger</swp-card-title>
    </swp-card-header>
    <!-- content -->
</swp-card>

Card header med ikon:

<swp-card>
    <swp-card-header>
        <swp-card-title>
            <i class="ph ph-envelope"></i>
            Email
        </swp-card-title>
    </swp-card-header>
    <!-- content -->
</swp-card>

Card header med action:

<swp-card>
    <swp-card-header>
        <swp-card-title>Dagens bookinger</swp-card-title>
        <swp-section-action>Se alle</swp-section-action>
    </swp-card-header>
    <!-- content -->
</swp-card>

Subsection label (KUN til sekundære sektioner inde i card):

<swp-card>
    <swp-card-header>
        <swp-card-title>Grundlæggende</swp-card-title>
    </swp-card-header>
    <!-- first section content -->

    <swp-section-label class="spaced">Interne noter</swp-section-label>
    <!-- second section content -->
</swp-card>

HUSK: swp-section-label må ALDRIG bruges som erstatning for swp-card-header!


Stats Components (stats.css)

Containers

Element Kolonner Brug
swp-stats-bar 4 kolonner Dashboard stats
swp-stats-grid 4 kolonner Grid layout
swp-stats-row 3 kolonner Feature pages (Employees, etc.)

Stat Card

<swp-stat-card class="[variant]">
    <swp-stat-value>42</swp-stat-value>
    <swp-stat-label>Aktive brugere</swp-stat-label>
</swp-stat-card>

Varianter (class):

  • highlight / teal - Teal farve
  • success - Grøn
  • warning / amber - Amber/orange
  • danger / negative / red - Rød
  • purple - Lilla
  • highlight filled - Filled teal baggrund

VIGTIGT: swp-stat-value bruger font-family: var(--font-mono) automatisk!


Tabs (tabs.css)

<swp-tab-bar>
    <swp-tab class="active" data-tab="users">
        <i class="ph ph-users"></i>
        <span>Brugere</span>
    </swp-tab>
    <swp-tab data-tab="roles">
        <i class="ph ph-shield-check"></i>
        <span>Roller</span>
    </swp-tab>
</swp-tab-bar>

<swp-tab-content data-tab="users" class="active">
    <!-- Content -->
</swp-tab-content>

<swp-tab-content data-tab="roles">
    <!-- Content -->
</swp-tab-content>

VIGTIGT:

  • Aktiv tab: class="active" (IKKE data-active="true")
  • Tab content: class="active" for at vise

Buttons (cash.css)

<swp-btn class="primary">
    <i class="ph ph-plus"></i>
    Tilføj
</swp-btn>

Varianter:

  • primary - Teal baggrund, hvid tekst
  • secondary - Hvid baggrund, border
  • ghost - Transparent

Badges (cash.css)

ALLE badges bruger swp-status-badge - kun farve og indhold ændres.

<swp-status-badge class="[variant]">Tekst</swp-status-badge>

Varianter:

Class Farve Brug
approved Grøn Godkendt status
active Grøn Aktiv status
paid Grøn Betalt status
draft Amber Kladde status
invited Amber Invitation sendt
pending Amber Afventer status
owner Teal Ejer rolle
admin Purple Admin rolle
leader Blue Leder rolle
employee Grå Medarbejder rolle

Automatisk dot via ::before pseudo-element.


Tables - swp-data-table Pattern

BRUG ALTID swp-data-table for nye tabeller. Den generiske komponent er defineret i components.css.

Struktur

<swp-card class="context-class">
    <swp-data-table>
        <swp-data-table-header>
            <swp-data-table-cell>Kolonne 1</swp-data-table-cell>
            <swp-data-table-cell>Kolonne 2</swp-data-table-cell>
        </swp-data-table-header>
        <swp-data-table-row>
            <swp-data-table-cell>Data 1</swp-data-table-cell>
            <swp-data-table-cell>Data 2</swp-data-table-cell>
        </swp-data-table-row>
    </swp-data-table>
</swp-card>

CSS Pattern

/* Definer kolonner via context class på swp-card */
swp-card.context-class swp-data-table {
  grid-template-columns: 1fr 120px 80px;
}

/* Kolonne-specifik styling med nth-child */
swp-card.context-class swp-data-table-cell:nth-child(2) {
  font-family: var(--font-mono);
}

Eksisterende tabeller

Feature Card Class CSS fil
Employees list swp-card.employees-list employees.css
Salary history swp-card.salary-history employees.css
Invoice history swp-card.invoice-history account.css
Stats bookings swp-card.stats-bookings employees.css
Cash swp-cash-table (kompleks) cash.css

Lister (ikke tabeller):

Feature Container Item CSS fil
Bookings swp-booking-list swp-booking-item bookings.css
Notifications swp-notification-list swp-notification-item notifications.css
Attentions swp-attention-list swp-attention-item attentions.css

Table Cells - Standard Styling

Base styling er i components.css. Tilpas kun via context class:

/* Header cells (automatisk fra components.css) */
swp-data-table-header swp-data-table-cell {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  color: var(--color-text-secondary);
}

/* Body cells (automatisk fra components.css) */
swp-data-table-cell {
  padding: var(--spacing-4);
  font-size: var(--font-size-base);
  color: var(--color-text);
}

/* Feature-specifik tilpasning via context */
swp-card.my-feature swp-data-table-cell:nth-child(3) {
  text-align: right;
}

Icon Buttons (employees.css)

<swp-table-actions>
    <swp-icon-btn title="Rediger">
        <i class="ph ph-pencil"></i>
    </swp-icon-btn>
    <swp-icon-btn class="danger" title="Slet">
        <i class="ph ph-trash"></i>
    </swp-icon-btn>
</swp-table-actions>

Edit Forms (employees.css)

Key-value display med valgfri redigering. Bruger Grid + Subgrid for alignment.

Basis struktur

<swp-edit-section>
    <swp-edit-row>
        <swp-edit-label>Label tekst</swp-edit-label>
        <swp-edit-value>Værdi</swp-edit-value>
    </swp-edit-row>
    <swp-edit-row>
        <swp-edit-label>Med redigering</swp-edit-label>
        <swp-edit-value contenteditable="true">Redigerbar værdi</swp-edit-value>
    </swp-edit-row>
</swp-edit-section>

Med select dropdown

<swp-edit-section>
    <swp-edit-row>
        <swp-edit-label>Vælg type</swp-edit-label>
        <swp-edit-select>
            <select>
                <option>Option 1</option>
                <option>Option 2</option>
            </select>
        </swp-edit-select>
    </swp-edit-row>
</swp-edit-section>

Mono-font for tal

<swp-edit-value class="mono">131,49 kr</swp-edit-value>

User Info Pattern (employees.css)

<swp-user-info>
    <swp-user-avatar class="[color]">MJ</swp-user-avatar>
    <swp-user-details>
        <swp-user-name>Maria Jensen</swp-user-name>
        <swp-user-email>maria@example.com</swp-user-email>
    </swp-user-details>
</swp-user-info>

Avatar farver: (ingen class = teal), purple, blue, amber


Document List (employees.css)

Genbruges til dokumenter, certificeringer, kurser og lignende lister.

<swp-document-list>
    <swp-document-item>
        <i class="ph ph-file-pdf"></i>
        <swp-document-info>
            <swp-document-name>Ansættelseskontrakt.pdf</swp-document-name>
            <swp-document-meta>Uploadet 1. aug 2019</swp-document-meta>
        </swp-document-info>
        <swp-document-actions>
            <swp-btn class="secondary sm">Vis</swp-btn>
        </swp-document-actions>
    </swp-document-item>
</swp-document-list>

Med badge i stedet for knap:

<swp-document-item>
    <i class="ph ph-certificate"></i>
    <swp-document-info>
        <swp-document-name>Balayage Specialist</swp-document-name>
        <swp-document-meta>Udløber: 15. juni 2026</swp-document-meta>
    </swp-document-info>
    <swp-document-actions>
        <swp-status-badge class="valid">Gyldig</swp-status-badge>
    </swp-document-actions>
</swp-document-item>

Subsection (employees.css)

Til gruppering af lister (f.eks. "Gennemførte kurser" / "Planlagte kurser").

<swp-subsection>
    <swp-subsection-title>Gennemførte kurser</swp-subsection-title>
    <swp-document-list>
        <!-- items -->
    </swp-document-list>
</swp-subsection>

Simple List (employees.css)

Simpel liste med tekst + badge (f.eks. planlagt fravær).

<swp-simple-list>
    <swp-simple-item>
        <swp-simple-item-text>23. dec  2. jan 2026</swp-simple-item-text>
        <swp-status-badge class="ferie">Ferie</swp-status-badge>
    </swp-simple-item>
</swp-simple-list>

Salary History Table (employees.css)

Bruger swp-data-table med .salary-history context class.

<swp-card class="salary-history">
    <swp-card-header>
        <swp-card-title>Lønhistorik</swp-card-title>
    </swp-card-header>
    <swp-data-table>
        <swp-data-table-header>
            <swp-data-table-cell>Periode</swp-data-table-cell>
            <swp-data-table-cell>Bruttoløn</swp-data-table-cell>
            <swp-data-table-cell></swp-data-table-cell>
        </swp-data-table-header>
        <swp-data-table-row>
            <swp-data-table-cell>Januar 2026</swp-data-table-cell>
            <swp-data-table-cell class="mono">34.063,50 kr</swp-data-table-cell>
            <swp-data-table-cell><i class="ph ph-caret-right"></i></swp-data-table-cell>
        </swp-data-table-row>
    </swp-data-table>
</swp-card>

Rækker har hover-effekt og chevron bliver teal ved hover.


Add Button (components.css)

Dashed border knap til tilføjelse af elementer.

<swp-add-button>+ Upload dokument</swp-add-button>
<swp-add-button>+ Tilføj certificering</swp-add-button>

Styling: Dashed border, centreret, hover → teal border og tekst.


Design Tokens (design-tokens.css)

Farver

Token Brug
--color-teal Primary brand, success
--color-green Success, positive
--color-amber Warning, pending
--color-red Error, danger
--color-purple Special, AI
--color-blue Info

Spacing

--spacing-1: 2px;
--spacing-2: 4px;
--spacing-3: 6px;
--spacing-4: 8px;
--spacing-5: 10px;
--spacing-6: 12px;
--spacing-7: 14px;
--spacing-8: 16px;
--spacing-10: 20px;
--spacing-12: 24px;

Font Sizes

--font-size-xs: 11px;
--font-size-sm: 12px;
--font-size-md: 13px;
--font-size-base: 14px;  /* Standard body text */
--font-size-lg: 16px;
--font-size-xl: 18px;
--font-size-2xl: 20px;
--font-size-3xl: 22px;

Font Families

--font-family: 'Poppins', sans-serif;
--font-mono: 'JetBrains Mono', monospace;  /* Til tal/værdier */

Checklist for Ny Side

  1. Læs denne fil
  2. List UI elementer der skal bruges
  3. Match hver element med eksisterende komponent
  4. Dokumenter kun NYE elementer der skal oprettes
  5. Opret feature CSS med header der angiver genbrugte komponenter
  6. Brug var(--font-size-base) for body text
  7. Brug var(--font-mono) kun for tal/værdier

Accordion (accordion.css)

Genbrugeligt accordion component med expand/collapse animation og single-open behavior.

<swp-accordion>
    <swp-accordion-item>
        <swp-accordion-header>
            <swp-accordion-info>
                <swp-accordion-title>Titel</swp-accordion-title>
                <swp-accordion-meta>Subtitle</swp-accordion-meta>
            </swp-accordion-info>
            <swp-accordion-summary>
                <swp-summary-item>
                    <swp-summary-value>1.234 kr</swp-summary-value>
                    <swp-summary-label>Label</swp-summary-label>
                </swp-summary-item>
                <swp-accordion-toggle>
                    <i class="ph ph-caret-down"></i>
                </swp-accordion-toggle>
            </swp-accordion-summary>
        </swp-accordion-header>
        <swp-accordion-content>
            <!-- Content shown when expanded -->
        </swp-accordion-content>
    </swp-accordion-item>
</swp-accordion>

Features:

  • Single-open behavior (kun en udvidet ad gangen)
  • Smooth expand/collapse animation (250ms/200ms)
  • Caret icon roterer 180 ved expand
  • Config row (swp-config-row) til key-value info

TypeScript:

import { Accordion } from './modules/accordion';

const accordion = new Accordion('#my-accordion', { singleOpen: true });

Fil Reference

Fil Indhold
design-tokens.css Farver, spacing, fonts, shadows
design-system.css Base resets, typography
page.css Page structure, sticky-header
components.css Buttons, badges, cards, section-label, add-button, avatars, icon-btn, swp-data-table
stats.css Stat cards, stat rows
tabs.css Tab bar, tab content
accordion.css Accordion component (swp-accordion, swp-accordion-item, expand/collapse)
employees.css User info, edit forms, document lists, context styles (.employees-list, .salary-history, .salary-specifications, .stats-bookings)
account.css Account/billing styles, context styles (.invoice-history)
bookings.css Booking list items
notifications.css Notification items
attentions.css Attention items
cash.css Cash register (swp-cash-table - kompleks, ikke migreret)