Neura UI

Loading…

 Logo

Time Grid

Draw time ranges over a typical week with the mouse, the keyboard or a finger. Built for dayparts, opening hours and availability.

Basic Usage

Drag a rectangle to fill it: Monday to Friday, 09:00 to 18:00 in one stroke. Starting on a filled cell erases instead, and a click on a day or an hour fills or clears its whole line. The value is a list of `day`, `start` and `end` ranges, the same shape as `time-picker range multiple` with a `day` key.
blade

12a
1a
2a
3a
4a
5a
6a
7a
8a
9a
10a
11a
12p
1p
2p
3p
4p
5p
6p
7p
8p
9p
10p
11p
Sun
Mon
Tue
Wed
Thu
Fri
Sat
[
    {
        "day": "mon",
        "start": "09:00",
        "end": "12:00"
    },
    {
        "day": "mon",
        "start": "14:00",
        "end": "18:00"
    },
    {
        "day": "tue",
        "start": "09:00",
        "end": "12:00"
    },
    {
        "day": "tue",
        "start": "14:00",
        "end": "18:00"
    },
    {
        "day": "wed",
        "start": "09:00",
        "end": "12:00"
    },
    {
        "day": "wed",
        "start": "14:00",
        "end": "18:00"
    },
    {
        "day": "thu",
        "start": "09:00",
        "end": "12:00"
    },
    {
        "day": "thu",
        "start": "14:00",
        "end": "18:00"
    },
    {
        "day": "fri",
        "start": "09:00",
        "end": "12:00"
    },
    {
        "day": "fri",
        "start": "14:00",
        "end": "18:00"
    }
]
<neura::time-grid wire:model.live="dayparts" />
<!-- $dayparts will be [['day' => 'mon', 'start' => '09:00', 'end' => '12:00'], …] -->

Deferred Binding

Without `.live`, painting stays in the browser and the value travels with the next request. Renders of the page leave the painted cells alone.
blade

8a
9a
10a
11a
12p
1p
2p
3p
4p
5p
6p
7p
Sun
Mon
Tue
Wed
Thu
Fri
Sat
[]
<neura::time-grid wire:model="availability" start="08:00" end="20:00" />
<neura::button wire:click="save">Save</neura::button>

Step and Hours

`step` sets the minutes per cell (60, 30 or 15), `start` and `end` the hours shown. Ranges outside them, or off the step, are kept as they are until their own cells are touched.
blade

8a
9a
10a
11a
12p
1p
2p
3p
4p
5p
6p
7p
Sun
Mon
Tue
Wed
Thu
Fri
Sat
<neura::time-grid :step="30" start="08:00" end="20:00" wire:model="shifts" />

Orientation

Days run down the grid in `rows` and across it in `columns`. The default, `auto`, turns days into columns past 24 cells a day, so quarter hours stay readable.
blade

Sun
Mon
Tue
Wed
Thu
Fri
Sat
8 AM
9 AM
10 AM
11 AM
12 PM
1 PM
2 PM
3 PM
4 PM
5 PM
<neura::time-grid orientation="columns" :step="30" start="08:00" end="18:00" />

Custom Columns

`days` takes weekday keys (`['mon', 'tue', 'wed', 'thu', 'fri']`), kept in week order from `first-day`, or any list of keys and labels: rooms, people, channels. With a free list the value uses `column` instead of `day`.
blade

8a
9a
10a
11a
12p
1p
2p
3p
4p
5p
6p
7p
Room A
Room B
Studio
<neura::time-grid :days="['a' => 'Room A', 'b' => 'Room B', 'studio' => 'Studio']" wire:model="bookings" />
<!-- $bookings will be [['column' => 'a', 'start' => '09:00', 'end' => '11:00'], …] -->

<neura::time-grid :days="['mon', 'tue', 'wed', 'thu', 'fri']" first-day="mon" />

Paint Mode

`selection="paint"` fills every cell the pointer passes over, for shapes a rectangle can't draw.
blade

12a
1a
2a
3a
4a
5a
6a
7a
8a
9a
10a
11a
12p
1p
2p
3p
4p
5p
6p
7p
8p
9p
10p
11p
Sun
Mon
Tue
Wed
Thu
Fri
Sat
<neura::time-grid selection="paint" wire:model="slots" />

Levels

`levels` adds brushes, picked above the grid. Each takes a design-system colour (`primary`, `warning`, `success-600`…); the first defaults to the configured colour. Every range then carries its `level`.
javascript

12a
1a
2a
3a
4a
5a
6a
7a
8a
9a
10a
11a
12p
1p
2p
3p
4p
5p
6p
7p
8p
9p
10p
11p
Sun
Mon
Tue
Wed
Thu
Fri
Sat
<neura::time-grid
    :levels="['on' => 'Live', 'boost' => ['label' => 'Boosted', 'color' => 'warning']]"
    wire:model="dayparts"
/>
<!-- [['day' => 'fri', 'start' => '18:00', 'end' => '23:00', 'level' => 'boost'], …] -->

Blocked Slots

`disabled` takes ranges in the value's shape; their cells are hatched over whatever they hold, and a rectangle skips them. `disabled` alone locks the whole grid and keeps its value in view.
blade

8a
9a
10a
11a
12p
1p
2p
3p
4p
5p
6p
7p
Sun
Mon
Tue
Wed
Thu
Fri
Sat
<neura::time-grid :disabled="[
    ['day' => 'sat', 'start' => '00:00', 'end' => '24:00'],
    ['day' => 'mon', 'start' => '12:00', 'end' => '14:00'],
]" />

Read Only

`readonly` shows a week without letting anyone change it, and drops the toolbar.
blade
6a
7a
8a
9a
10a
11a
12p
1p
2p
3p
4p
5p
6p
7p
8p
9p
Sun
Mon
Tue
Wed
Thu
Fri
Sat
<neura::time-grid readonly :value="$openingHours" />

Value Formats

`format="days"` groups the ranges by column, listing every column shown even when empty. Times are always 24-hour `HH:mm`, with `24:00` for the end of the day, whatever clock is shown. Either shape is read coming in, as are `HH:mm:ss` times; overlapping ranges are merged.
javascript

8a
9a
10a
11a
12p
1p
2p
3p
4p
5p
Mon
Tue
Wed
{
    "mon": [
        {
            "start": "09:00",
            "end": "17:00"
        }
    ],
    "wed": [
        {
            "start": "09:00",
            "end": "12:00"
        }
    ]
}
<neura::time-grid format="days" wire:model="week" />
<!-- $week will be ['mon' => [['start' => '09:00', 'end' => '17:00']], 'tue' => [], …] -->

Size and Style

`size` sets the header text, the cell height and the gap; `rounded` the frame's corners; `color` the first level. Without them, the grid follows `config('neura-kit.time-grid')`, whose `rounded` defaults to the global style.
javascript

8a
9a
10a
11a
12p
1p
2p
3p
4p
5p
Mon
Tue
Wed

8a
9a
10a
11a
12p
1p
2p
3p
4p
5p
Mon
Tue
Wed
<neura::time-grid size="sm" />
<neura::time-grid size="lg" rounded="xl" color="success" />

// config/neura-kit.php
'time-grid' => Config::timeGrid([
    'default' => ['size' => 'sm', 'color' => 'success'],
]),

Keyboard and Touch

Arrow keys move between cells, Shift with the arrows draws a rectangle and Space or Enter applies it (or toggles one cell); Escape drops it. On touch screens the page still scrolls over the grid: a tap toggles a cell, a long press then a drag selects.

Props

Prop Type Default Description
days array the 7 weekdays Weekday keys, or key => label for a free list of columns
firstDay mon|sun|… locale First weekday shown
start / end string|int '00:00' / '24:00' Hours shown (8, 08:00 or 08:00:00), snapped to the step
step 60|30|15 60 Minutes per cell
orientation auto|rows|columns auto Days down the grid (rows) or across it (columns); auto switches past 24 cells a day
selection rectangle|paint rectangle Drag a rectangle, or paint cell by cell
levels array one level Brushes: key => label, or key => ['label' => …, 'color' => …]
disabled array|bool [] Blocked ranges in the value's shape, or true to lock the whole grid
readonly boolean false Display only, no toolbar
format ranges|days ranges A list of ranges, or ranges grouped by column
hourCycle 12|24|null null Clock of the labels; null follows the locale
locale string 'en' Weekday names, first day and the default clock
clearable boolean true Show the Clear all button
name string null Hidden inputs for plain form posts (name[0][day], name[0][start] …)
size sm|md|lg config: md Header text, cell height and gap (pack: TimeGrid\Size)
rounded string config: global Corners of the frame
color string config: primary Colour of the first level