Skip to main content

Period

Display a single class period with optional progress indicator. Source: src/components/Period.vue

Props

period
string
required
Period name/number to display (periods starting with ’!’ have the ’!’ removed)
start
string
required
Start time in military time format (e.g., ‘08:00’)
end
string
required
End time in military time format (e.g., ‘09:00’)
invert
boolean
default:"false"
Use inverted color scheme (secondary background with accent border)
forceMobileLayout
boolean
default:"false"
Force mobile layout even on desktop
disableProgressBar
boolean
default:"false"
Disable the circular progress bar for current period
tvSpace
boolean
default:"false"
Use compact sizing optimized for TV/large displays

Features

  • Progress Indicator: Shows circular progress bar when period is currently active (1-2 character period names)
  • Responsive Layout: Changes from horizontal pill to vertical card on desktop
  • Time Conversion: Automatically converts military time to 12-hour format
  • Dynamic Sizing: Adjusts font size based on period name length

Usage

<template>
  <Period
    period="1"
    start="08:00"
    end="09:00"
    :invert="false"
  />
</template>

<script setup lang="ts">
import Period from '@/components/Period.vue';
</script>

Time Format

Period times are displayed in 12-hour format with AM/PM:
  • Desktop: Times shown vertically (separated by dash hidden)
  • Mobile/Tablet: Times shown horizontally (e.g., “8:00 AM – 9:00 AM”)

ScrollablePeriodList

Scrollable list of periods with automatic scrolling to current period. Source: src/components/ScrollablePeriodList.vue

Props

schedule
Record<string, any> | null
default:"null"
Custom schedule object with start, end, and periods arrays. If null, uses today’s schedule from the clock store.
maxHeight
string | null
default:"null"
Maximum height for the scrollable container (CSS value like ‘400px’)
tvSpace
boolean
default:"false"
Use compact spacing optimized for TV/large displays

Features

  • Auto-scroll: Automatically scrolls to center the current period on mount and when bell changes
  • Up Next Indicator: Shows “Up Next” divider during passing periods
  • Current Period Highlight: Highlights current period with non-inverted colors
  • Empty State: Shows empty list when not a school day

Exposed Methods

  • scrollToCurrentPeriod() - Manually trigger scroll to current period

Usage

<template>
  <!-- Automatically loads today's schedule -->
  <ScrollablePeriodList maxHeight="500px" />
</template>

<script setup lang="ts">
import ScrollablePeriodList from '@/components/ScrollablePeriodList.vue';
</script>

Schedule Object Format

When providing a custom schedule, use this format:
{
  periods: string[];  // Array of period names
  start: string[];    // Array of start times (military time)
  end: string[];      // Array of end times (military time)
}
All three arrays must have the same length, with corresponding indices representing the same period.

EventChip

Display an event with name and date in a chip format. Source: src/components/EventChip.vue

Props

date
Date | null
default:"null"
Event date to display
name
string
default:"''"
Event name/title
direction
'left' | 'right'
default:"'left'"
Which side the event name extends from the date circle

Features

  • Date Circle: Circular badge displaying month abbreviation and day number
  • Event Name: Colored bar extending from date circle with event name
  • Text Overflow: Automatically truncates long event names with ellipsis
  • Flexible Direction: Event name can extend left or right from date

Usage

<template>
  <EventChip
    :date="new Date('2026-03-15')"
    name="Spring Break"
    direction="left"
  />
</template>

<script setup lang="ts">
import EventChip from '@/components/EventChip.vue';
</script>

Styling

The component uses:
  • Accent Color: Event name bar uses --accent CSS variable
  • Shadow: Date circle and name bar have drop shadows
  • Responsive Width: Event name bar takes 50% width plus circle radius
  • Circular Date: Fixed-size circular badge (36px diameter by default)

Integration Example

Here’s how these schedule components work together:
<template>
  <Card>
    <h2>Today's Schedule</h2>
    
    <!-- Display all periods for today -->
    <ScrollablePeriodList maxHeight="400px" />
    
    <h3>Upcoming Events</h3>
    
    <!-- Display upcoming events -->
    <div class="events-list">
      <EventChip
        v-for="event in upcomingEvents"
        :key="event.id"
        :date="event.date"
        :name="event.name"
        :direction="event.id % 2 === 0 ? 'left' : 'right'"
      />
    </div>
  </Card>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import Card from '@/components/Card.vue';
import ScrollablePeriodList from '@/components/ScrollablePeriodList.vue';
import EventChip from '@/components/EventChip.vue';

const upcomingEvents = ref([
  { id: 1, date: new Date('2026-03-15'), name: 'Spring Break' },
  { id: 2, date: new Date('2026-04-01'), name: 'Return to School' }
]);
</script>

<style scoped>
.events-list {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-top: 16px;
}
</style>

Build docs developers (and LLMs) love