Date & time
These components use Reka’s date values and render their controls in the document. They do not open native date or time popups. Each example starts with an empty selection, uses the current calendar view and has its own SbProvider with an explicit locale.
All roots accept merged class (HTMLAttributes['class'], unset), extend the corresponding Reka *RootProps, and forward the remaining props and declared emits. v-model listens to update:modelValue. Tables include wrapper overrides, theme defaults and the most useful forwarded props; they are not an exhaustive copy of Reka’s root interfaces.
Date values are DateValue objects from @internationalized/date, rather than JS Date or ISO strings. CalendarDate is suitable for a date without time. TimeValue accepts Reka’s supported time values, including Time. A DateRange has start and end date values (either may be undefined while incomplete); a TimeRange has the same shape with time values. Install @internationalized/date in your own app if you import its constructors. Preserve these values with shallowRef when controlling a model.
The anatomy blocks show the parts supplied by the wrapper’s default slot. They describe nesting, rather than complete custom implementations: custom grids also need the root slot’s dates, rows, segment values and event bindings.
SbCalendar
Section titled “SbCalendar”SbCalendar wraps Reka CalendarRoot and supplies a header, weekday row and date grid. Use it when the calendar should stay visible.
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 1 | 2 | 3 | 4 | 5 |
<script setup lang="ts">import { SbCalendar, SbProvider } from '@static-bloom/vue'</script>
<template> <SbProvider locale="en-US"> <SbCalendar calendar-label="Available dispatch dates" /> </SbProvider></template>Anatomy
Section titled “Anatomy”<SbCalendar> <SbCalendarHeader> <SbCalendarPrev /><SbCalendarHeading /><SbCalendarNext /> </SbCalendarHeader> <SbCalendarGrid> <SbCalendarGridHead><SbCalendarGridRow><SbCalendarHeadCell /></SbCalendarGridRow></SbCalendarGridHead> <SbCalendarGridBody><SbCalendarGridRow> <SbCalendarCell><SbCalendarCellTrigger /></SbCalendarCell> </SbCalendarGridRow></SbCalendarGridBody> </SbCalendarGrid></SbCalendar>| Prop | Type | Default | Effect |
|---|---|---|---|
disableDaysOutsideCurrentView |
boolean |
true |
Disables dates outside the displayed month |
modelValue |
DateValue | DateValue[] | null |
unset | Selected date(s) |
defaultValue |
DateValue |
unset | Initial selection |
multiple |
boolean |
false |
Multiple selected dates |
numberOfMonths |
number |
1 |
Visible months |
calendarLabel |
string |
unset | Accessible calendar label |
minValue, maxValue |
DateValue |
unset | Selectable bounds |
isDateDisabled, isDateUnavailable |
(date: DateValue) => boolean |
unset | Date restrictions |
disabled, readonly, initialFocus |
boolean |
false |
Interaction lock / read-only / focus on mount |
Remaining CalendarRootProps and emits pass through. placeholder controls the visible date independently of selection; defaultPlaceholder initializes it. The wrapper also exports the uncomposed SbCalendarRoot.
ArrowLeft/Right move a day, ArrowUp/Down a week, PageUp/Down a month, and Home/End to week boundaries. Min/max and unavailable dates cannot be selected. Calendar labels, provider locale and today’s marker are covered by the component tests. In-game calendars use these DOM cells instead of a native date input.
SbRangeCalendar
Section titled “SbRangeCalendar”SbRangeCalendar wraps Reka RangeCalendarRoot with the same day-grid composition, selecting start and end dates.
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 1 | 2 | 3 | 4 | 5 |
<script setup lang="ts">import { SbProvider, SbRangeCalendar } from '@static-bloom/vue'</script>
<template> <SbProvider locale="en-US"> <SbRangeCalendar calendar-label="Contract date window" /> </SbProvider></template>Anatomy
Section titled “Anatomy”<SbRangeCalendar> <SbRangeCalendarHeader> <SbRangeCalendarPrev /><SbRangeCalendarHeading /><SbRangeCalendarNext /> </SbRangeCalendarHeader> <SbRangeCalendarGrid> <SbRangeCalendarGridHead><SbRangeCalendarGridRow><SbRangeCalendarHeadCell /></SbRangeCalendarGridRow></SbRangeCalendarGridHead> <SbRangeCalendarGridBody><SbRangeCalendarGridRow> <SbRangeCalendarCell><SbRangeCalendarCellTrigger /></SbRangeCalendarCell> </SbRangeCalendarGridRow></SbRangeCalendarGridBody> </SbRangeCalendarGrid></SbRangeCalendar>| Prop | Type | Default | Effect |
|---|---|---|---|
disableDaysOutsideCurrentView |
boolean |
true |
Disables outside-month dates |
modelValue |
DateRange | null |
uncontrolled | Controlled range |
defaultValue |
DateRange |
{ start: undefined, end: undefined } |
Initial range |
numberOfMonths |
number |
1 |
Visible month count |
calendarLabel |
string |
unset | Accessible name |
allowNonContiguousRanges |
boolean |
false |
Allows ranges containing unavailable dates |
maximumDays |
number |
unset | Maximum range length |
fixedDate |
'start' | 'end' |
unset | Fixed endpoint |
minValue, maxValue |
DateValue |
unset | Selectable bounds |
Remaining RangeCalendarRootProps and emits pass through, including date restrictions and disabled/readonly state. The tests verify range endpoint emission and accessible selected-range rendering. The calendar uses Reka’s day-grid keyboard navigation; keep its header controls and grid parts together when composing it yourself. In-game pages need WebUI focus before those keys reach the grid.
SbDateField
Section titled “SbDateField”SbDateField wraps Reka DateFieldRoot, rendering one SbDateFieldInput for each locale-ordered segment.
<script setup lang="ts">import { SbDateField, SbProvider } from '@static-bloom/vue'</script>
<template> <SbProvider locale="en-US"> <SbDateField aria-label="Contract date" /> </SbProvider></template>Anatomy
Section titled “Anatomy”<SbDateField> <SbDateFieldInput /> <!-- repeated for each segment, using its part and value --></SbDateField>| Prop | Type | Default | Effect |
|---|---|---|---|
size |
'sm' | 'md' | 'lg' |
'md' |
Field dimensions |
invalid |
boolean |
false |
Invalid appearance and aria-invalid |
modelValue |
DateValue | null |
unset | Controlled date |
defaultValue |
DateValue |
unset | Initial date |
minValue, maxValue |
DateValue |
unset | Valid bounds |
disabled, readonly |
boolean |
false |
Prevent interaction / editing |
Remaining DateFieldRootProps and emits pass through. Supply aria-label or a connected label. ArrowUp increments the focused segment and numeric typing edits it. Locale changes segment ordering; disabled segments are not editable. It renders editable DOM segments, so no native popup is involved in-game.
SbDateRangeField
Section titled “SbDateRangeField”SbDateRangeField wraps Reka DateRangeFieldRoot and renders start/end segment sets separated by an en dash.
<script setup lang="ts">import { SbDateRangeField, SbProvider } from '@static-bloom/vue'</script>
<template> <SbProvider locale="en-US"> <SbDateRangeField aria-label="Contract start and end dates" /> </SbProvider></template>Anatomy
Section titled “Anatomy”<SbDateRangeField> <SbDateRangeFieldInput type="start" /> <!-- start segments --> <SbDateRangeFieldInput type="end" /> <!-- end segments --></SbDateRangeField>| Prop | Type | Default | Effect |
|---|---|---|---|
size |
'sm' | 'md' | 'lg' |
'md' |
Field dimensions |
invalid |
boolean |
false |
Invalid appearance and aria-invalid |
modelValue |
DateRange | null |
uncontrolled | Controlled endpoints |
defaultValue |
DateRange |
unset (empty endpoints internally) | Initial range |
minValue, maxValue |
DateValue |
unset | Date bounds |
disabled, readonly |
boolean |
false |
Interaction / editing lock |
Remaining DateRangeFieldRootProps and emits pass through. Each endpoint is independently editable; the tests change the end date while preserving the start. Name the range as a whole, keep endpoint segment types when composing, and let Reka manage segment focus. These are DOM controls in OPEN//77 too.
SbTimeField
Section titled “SbTimeField”SbTimeField wraps Reka TimeFieldRoot, rendering SbTimeFieldInput parts for the formatted time segments.
<script setup lang="ts">import { SbProvider, SbTimeField } from '@static-bloom/vue'</script>
<template> <SbProvider locale="en-US"> <SbTimeField :hour-cycle="24" aria-label="Dispatch time" /> </SbProvider></template>Anatomy
Section titled “Anatomy”<SbTimeField> <SbTimeFieldInput /> <!-- repeated for each segment --></SbTimeField>| Prop | Type | Default | Effect |
|---|---|---|---|
size |
'sm' | 'md' | 'lg' |
'md' |
Field dimensions |
invalid |
boolean |
false |
Invalid appearance and aria-invalid |
modelValue |
TimeValue | null |
unset | Controlled time |
defaultValue |
TimeValue |
unset | Initial time |
hourCycle |
12 | 24 |
locale preference | Hour display |
granularity |
'hour' | 'minute' | 'second' |
'minute' |
Last displayed segment |
minValue, maxValue |
TimeValue |
unset | Time bounds |
disabled, readonly |
boolean |
false |
Interaction / editing lock |
Remaining TimeFieldRootProps and emits pass through. Name the field with aria-label. ArrowUp increments the focused minute segment, as verified by the tests. The example explicitly uses 24-hour entry. For in-game schedules, define whether values mean server time or local time before persisting them; the component does not decide that policy.
SbTimeRangeField
Section titled “SbTimeRangeField”SbTimeRangeField wraps Reka TimeRangeFieldRoot for separate start and end times.
<script setup lang="ts">import { SbProvider, SbTimeRangeField } from '@static-bloom/vue'</script>
<template> <SbProvider locale="en-US"> <SbTimeRangeField :hour-cycle="24" aria-label="Patrol start and end times" /> </SbProvider></template>Anatomy
Section titled “Anatomy”<SbTimeRangeField> <SbTimeRangeFieldInput type="start" /> <!-- start segments --> <SbTimeRangeFieldInput type="end" /> <!-- end segments --></SbTimeRangeField>| Prop | Type | Default | Effect |
|---|---|---|---|
size |
'sm' | 'md' | 'lg' |
'md' |
Field dimensions |
invalid |
boolean |
false |
Invalid appearance and aria-invalid |
modelValue |
TimeRange | null |
uncontrolled | Controlled endpoints |
defaultValue |
TimeRange |
unset | Initial range |
hourCycle |
12 | 24 |
locale preference | Hour display |
granularity |
'hour' | 'minute' | 'second' |
'minute' |
Last displayed segment |
disabled, readonly |
boolean |
false |
Interaction / editing lock |
Remaining TimeRangeFieldRootProps and emits pass through. The tests decrement an end hour with ArrowDown while preserving the start. Name the whole range and preserve type="start"/type="end" when composing. It uses editable DOM segments; keep a visible alternative to platform-level shortcuts in-game.
SbDatePicker
Section titled “SbDatePicker”SbDatePicker wraps Reka DatePickerRoot, supplying a segmented field, calendar trigger and portalled calendar dialog.
<script setup lang="ts">import { SbDatePicker, SbProvider } from '@static-bloom/vue'</script>
<template> <SbProvider locale="en-US"> <SbDatePicker label="Dispatch date" trigger-label="Choose dispatch date" close-on-select /> </SbProvider></template>Anatomy
Section titled “Anatomy”<SbDatePicker> <SbDatePickerAnchor> <SbDatePickerField> <SbDatePickerInput /> <SbDatePickerTrigger /> </SbDatePickerField> </SbDatePickerAnchor> <SbDatePickerContent> <SbDatePickerCalendar> <SbDatePickerHeader><SbDatePickerPrev /><SbDatePickerHeading /><SbDatePickerNext /></SbDatePickerHeader> <SbDatePickerGrid> <SbDatePickerGridHead><SbDatePickerGridRow><SbDatePickerHeadCell /></SbDatePickerGridRow></SbDatePickerGridHead> <SbDatePickerGridBody><SbDatePickerGridRow> <SbDatePickerCell><SbDatePickerCellTrigger /></SbDatePickerCell> </SbDatePickerGridRow></SbDatePickerGridBody> </SbDatePickerGrid> </SbDatePickerCalendar> </SbDatePickerContent></SbDatePicker>| Prop | Type | Default | Effect |
|---|---|---|---|
size |
'sm' | 'md' | 'lg' |
'md' |
Field dimensions |
invalid |
boolean |
false |
Field aria-invalid and styling |
label |
string |
'Date' |
Field and dialog name |
triggerLabel |
string |
'Open calendar' |
Trigger name |
modelValue, defaultValue |
DateValue |
unset | Controlled / initial selection |
closeOnSelect |
boolean |
false |
Close after selection |
defaultOpen, modal |
boolean |
false |
Initial popup state / modal behavior |
numberOfMonths |
number |
1 |
Calendar month count |
Remaining DatePickerRootProps/emits pass through, including v-model:open, bounds and unavailable-date matchers. The default calendar disables days outside its current view. SbDatePickerRoot, Arrow and Close parts are also exported with the same prefix.
The trigger opens a portalled dialog. Escape closes and restores trigger focus; selecting with close-on-select emits a date and closes. Field segments remain directly editable. The popup is DOM-rendered for OPEN//77; the platform may swallow Escape, so a custom in-game composition can include SbDatePickerClose. Popups outside a scoped provider inherit the page flavor.
SbDateRangePicker
Section titled “SbDateRangePicker”SbDateRangePicker wraps Reka DateRangePickerRoot with a two-endpoint field and portalled range calendar.
<script setup lang="ts">import { SbDateRangePicker, SbProvider } from '@static-bloom/vue'</script>
<template> <SbProvider locale="en-US"> <SbDateRangePicker label="Contract window" trigger-label="Choose contract window" close-on-select /> </SbProvider></template>Anatomy
Section titled “Anatomy”<SbDateRangePicker> <SbDateRangePickerAnchor> <SbDateRangePickerField> <SbDateRangePickerInput type="start" /> <SbDateRangePickerInput type="end" /> <SbDateRangePickerTrigger /> </SbDateRangePickerField> </SbDateRangePickerAnchor> <SbDateRangePickerContent> <SbDateRangePickerCalendar> <SbDateRangePickerHeader><SbDateRangePickerPrev /><SbDateRangePickerHeading /><SbDateRangePickerNext /></SbDateRangePickerHeader> <SbDateRangePickerGrid> <SbDateRangePickerGridHead><SbDateRangePickerGridRow><SbDateRangePickerHeadCell /></SbDateRangePickerGridRow></SbDateRangePickerGridHead> <SbDateRangePickerGridBody><SbDateRangePickerGridRow> <SbDateRangePickerCell><SbDateRangePickerCellTrigger /></SbDateRangePickerCell> </SbDateRangePickerGridRow></SbDateRangePickerGridBody> </SbDateRangePickerGrid> </SbDateRangePickerCalendar> </SbDateRangePickerContent></SbDateRangePicker>| Prop | Type | Default | Effect |
|---|---|---|---|
size |
'sm' | 'md' | 'lg' |
'md' |
Field dimensions |
invalid |
boolean |
false |
Field aria-invalid and styling |
label |
string |
'Date range' |
Field and dialog name |
triggerLabel |
string |
'Open calendar' |
Trigger name |
modelValue |
DateRange |
uncontrolled | Selected endpoints |
defaultValue |
DateRange |
{ start: undefined, end: undefined } |
Initial endpoints |
closeOnSelect |
boolean |
false |
Close on completed selection |
numberOfMonths |
number |
1 |
Visible months |
defaultOpen, modal |
boolean |
false |
Initial popup state / modal behavior |
Remaining DateRangePickerRootProps and emits pass through. The default calendar disables outside-view dates. Tests verify the dialog portal, Escape closure, restored trigger focus and open-popup accessibility. Keep endpoint segment types when composing; SbDateRangePickerClose provides an explicit close action for game pages whose Escape key is unavailable. On narrow HUDs, keep the month count at one unless there is room for a wider calendar.
SbMonthPicker
Section titled “SbMonthPicker”SbMonthPicker wraps Reka MonthPickerRoot, displaying months in a year with previous/next year navigation.
Jan | Feb | Mar | Apr |
May | Jun | Jul | Aug |
Sep | Oct | Nov | Dec |
<script setup lang="ts">import { SbMonthPicker, SbProvider } from '@static-bloom/vue'</script>
<template> <SbProvider locale="en-US"> <SbMonthPicker calendar-label="Patrol month" /> </SbProvider></template>Anatomy
Section titled “Anatomy”<SbMonthPicker> <SbMonthPickerHeader><SbMonthPickerPrev /><SbMonthPickerHeading /><SbMonthPickerNext /></SbMonthPickerHeader> <SbMonthPickerGrid><SbMonthPickerGridBody><SbMonthPickerGridRow> <SbMonthPickerCell><SbMonthPickerCellTrigger /></SbMonthPickerCell> </SbMonthPickerGridRow></SbMonthPickerGridBody></SbMonthPickerGrid></SbMonthPicker>| Prop | Type | Default | Effect |
|---|---|---|---|
modelValue |
DateValue | DateValue[] | null |
unset | Selected month(s) |
defaultValue |
DateValue |
unset | Initial selection |
calendarLabel |
string |
unset | Accessible calendar name |
multiple, preventDeselect |
boolean |
false |
Multiple selection / prevent deselection |
minValue, maxValue |
DateValue |
unset | Selection bounds |
isMonthDisabled, isMonthUnavailable |
(date: DateValue) => boolean |
unset | Month restrictions |
disabled, readonly, initialFocus |
boolean |
false |
Interaction lock / read-only / focus on mount |
Remaining MonthPickerRootProps and emits pass through. Month selection emits a date value, as verified in the tests. Preserve Reka’s cell triggers and named navigation controls for keyboard operation; this is a persistent grid, so it has no popup Escape behavior. It renders in the document for in-game use.
SbMonthRangePicker
Section titled “SbMonthRangePicker”SbMonthRangePicker wraps Reka MonthRangePickerRoot for a start and end month.
Jan | Feb | Mar | Apr |
May | Jun | Jul | Aug |
Sep | Oct | Nov | Dec |
<script setup lang="ts">import { SbMonthRangePicker, SbProvider } from '@static-bloom/vue'</script>
<template> <SbProvider locale="en-US"> <SbMonthRangePicker calendar-label="Contract months" /> </SbProvider></template>Anatomy
Section titled “Anatomy”<SbMonthRangePicker> <SbMonthRangePickerHeader><SbMonthRangePickerPrev /><SbMonthRangePickerHeading /><SbMonthRangePickerNext /></SbMonthRangePickerHeader> <SbMonthRangePickerGrid><SbMonthRangePickerGridBody><SbMonthRangePickerGridRow> <SbMonthRangePickerCell><SbMonthRangePickerCellTrigger /></SbMonthRangePickerCell> </SbMonthRangePickerGridRow></SbMonthRangePickerGridBody></SbMonthRangePickerGrid></SbMonthRangePicker>| Prop | Type | Default | Effect |
|---|---|---|---|
modelValue |
DateRange | null |
uncontrolled | Selected month endpoints |
defaultValue |
DateRange |
{ start: undefined, end: undefined } |
Initial endpoints |
calendarLabel |
string |
unset | Accessible name |
maximumMonths |
number |
unset | Range length limit |
allowNonContiguousRanges, preventDeselect |
boolean |
false |
Unavailable-month ranges / deselection policy |
fixedDate |
'start' | 'end' |
unset | Fixed endpoint |
disabled, readonly, initialFocus |
boolean |
false |
Interaction lock / read-only / focus on mount |
Remaining MonthRangePickerRootProps and emits pass through, including month matchers and bounds. The tests select two endpoints and verify the emitted range. Keep its focusable Reka cell triggers when customizing; give the calendar a meaningful label. This persistent DOM grid needs no native month popup in-game.
SbYearPicker
Section titled “SbYearPicker”SbYearPicker wraps Reka YearPickerRoot for archive years or other year-level values.
2020 | 2021 | 2022 | 2023 |
2024 | 2025 | 2026 | 2027 |
2028 | 2029 | 2030 | 2031 |
<script setup lang="ts">import { SbProvider, SbYearPicker } from '@static-bloom/vue'</script>
<template> <SbProvider locale="en-US"> <SbYearPicker calendar-label="Archive year" /> </SbProvider></template>Anatomy
Section titled “Anatomy”<SbYearPicker> <SbYearPickerHeader><SbYearPickerPrev /><SbYearPickerHeading /><SbYearPickerNext /></SbYearPickerHeader> <SbYearPickerGrid><SbYearPickerGridBody><SbYearPickerGridRow> <SbYearPickerCell><SbYearPickerCellTrigger /></SbYearPickerCell> </SbYearPickerGridRow></SbYearPickerGridBody></SbYearPickerGrid></SbYearPicker>| Prop | Type | Default | Effect |
|---|---|---|---|
modelValue |
DateValue | DateValue[] | null |
unset | Selected year(s) |
defaultValue |
DateValue |
unset | Initial selection |
yearsPerPage |
number |
12 |
Years in a view |
calendarLabel |
string |
unset | Accessible name |
multiple, preventDeselect |
boolean |
false |
Multiple selection / deselection policy |
isYearDisabled, isYearUnavailable |
(date: DateValue) => boolean |
unset | Year restrictions |
disabled, readonly, initialFocus |
boolean |
false |
Interaction lock / read-only / focus on mount |
Remaining YearPickerRootProps and emits pass through, including date bounds. The tests verify that choosing a year emits a date value. Keep the provided Reka triggers for focus and keyboard handling; previous/next controls have accessible names. The DOM grid works in the game compositor.
SbYearRangePicker
Section titled “SbYearRangePicker”SbYearRangePicker wraps Reka YearRangePickerRoot for a pair of year endpoints.
2020 | 2021 | 2022 | 2023 |
2024 | 2025 | 2026 | 2027 |
2028 | 2029 | 2030 | 2031 |
<script setup lang="ts">import { SbProvider, SbYearRangePicker } from '@static-bloom/vue'</script>
<template> <SbProvider locale="en-US"> <SbYearRangePicker calendar-label="Service years" /> </SbProvider></template>Anatomy
Section titled “Anatomy”<SbYearRangePicker> <SbYearRangePickerHeader><SbYearRangePickerPrev /><SbYearRangePickerHeading /><SbYearRangePickerNext /></SbYearRangePickerHeader> <SbYearRangePickerGrid><SbYearRangePickerGridBody><SbYearRangePickerGridRow> <SbYearRangePickerCell><SbYearRangePickerCellTrigger /></SbYearRangePickerCell> </SbYearRangePickerGridRow></SbYearRangePickerGridBody></SbYearRangePickerGrid></SbYearRangePicker>| Prop | Type | Default | Effect |
|---|---|---|---|
modelValue |
DateRange | null |
uncontrolled | Selected year endpoints |
defaultValue |
DateRange |
{ start: undefined, end: undefined } |
Initial endpoints |
yearsPerPage |
number |
12 |
Years per view |
maximumYears |
number |
unset | Range length limit |
calendarLabel |
string |
unset | Accessible name |
allowNonContiguousRanges, preventDeselect |
boolean |
false |
Unavailable-year ranges / deselection policy |
fixedDate |
'start' | 'end' |
unset | Fixed endpoint |
disabled, readonly, initialFocus |
boolean |
false |
Interaction lock / read-only / focus on mount |
Remaining YearRangePickerRootProps and emits pass through, including year matchers and bounds. The tests verify selecting and emitting both endpoints. Preserve the cell trigger semantics for keyboard access and keep the calendar named. A game HUD can place this inline without opening a native control.
For all game date/time controls, define the server’s scheduling policy, keep keyboard focus on the WebUI while editing, and use the page’s flavor for portalled content or configure an appropriate teleport destination. In-game UIs covers CEF restrictions and the ready/focus lifecycle.