@squareetlabs/weekly-availability-picker
v1.2.0
Published
Angular 20+ component to pick weekly availability (time slots per day)
Maintainers
Readme
@squareetlabs/weekly-availability-picker
Enterprise‑ready weekly availability picker for Angular A lightweight, dependency‑free component to manage weekly availability or unavailability using an intuitive days × hours grid with drag, resize, and full keyboard accessibility.
Overview
@squareetlabs/weekly-availability-picker is a standalone Angular component designed for professional scheduling use cases (HR, booking systems, workforce planning, SaaS back offices).
It provides:
- A clear weekly grid (days × hours)
- Click & drag to add or remove time ranges
- Edge resize for fine‑grained control
- Keyboard and ARIA accessibility
- Full theming via CSS variables
- Output data ready to persist (no overnight slots)
Requirements: Angular ^20.0.0 Node ^20.19.0 || ^22.12.0 || ^24.0.0
Installation
npm install @squareetlabs/weekly-availability-pickerUsage
Import the standalone component and bind slots with slotsChange:
import { WeeklyAvailabilityPickerComponent, type WeekSlot } from '@squareetlabs/weekly-availability-picker';
@Component({
imports: [WeeklyAvailabilityPickerComponent],
})
export class MyComponent {
slots = signal<WeekSlot[]>([]);
}<ngx-weekly-availability-picker
title="Unavailability"
[days]="['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']"
[slots]="slots()"
(slotsChange)="slots.set($event)"
[startHour]="0"
[endHour]="24"
[stepMinutes]="15"
/>API
Inputs
| Input | Type | Default | Description | |
| ---------------------- | -------------------------------- | --------------------- | --------------------------------------------- | ----------- |
| title | string | 'Unavailability' | Block title | |
| days | string[] | Sunday..Saturday (EN) | Names of the 7 days (row order) | |
| slots | WeekSlot[] | [] | Current time ranges | |
| startHour | number | 0 | Start hour (0–23) | |
| endHour | number | 24 | End hour (1–24) | |
| stepMinutes | number | 15 | Step in minutes (5, 10, 15, 30, 60…) | |
| readonly | boolean | false | Disables drag and editing | |
| resizeDisabled | boolean | false | Disables edge resizing | |
| minSlotMinutes | number | 0 | Minimum minutes per slot (0 = stepMinutes) | |
| maxSlotsPerDay | number | 0 | Maximum slots per day (0 = unlimited) | |
| showInfoIcon | boolean | true | Shows help icon (?) | |
| infoTooltip | string | (default text) | Tooltip text | |
| showSlotRemoveButton | boolean | true | Show remove button on slot hover | |
| timeFormat | '24h' | '12h' | '24h' | Time format |
| slotLabelSeparator | string | ' – ' | Separator in block label | |
| layout | 'auto' \| 'grid' \| 'compact' | 'auto' | Responsive layout (see Mobile) | |
| compactBreakpoint | number | 640 | Max width (px) for compact layout when auto | |
| ariaLabel | string | (default) | Component aria-label | |
| infoAriaLabel | string | (uses infoTooltip) | Help icon aria-label | |
| hostClass | string | '' | Extra CSS classes on host | |
| validate | (slots: WeekSlot[]) => boolean | — | If returns false, the change is not applied | |
Outputs
| Output | Description |
| ------------- | ---------------------------------- |
| slotsChange | New time ranges (ready to persist) |
| dragStart | Drag start (add/cut) |
| dragEnd | Drag end |
| resizeEnd | Resize end (edge drag) |
WeekSlot Type
interface WeekSlot {
day: number; // 0–6 (index in `days`)
time_start: string; // "HH:mm" or "HH:mm:ss"
time_end: string;
}Behavior
- Drag on a row creates a time range or removes it if it overlaps an existing one (toggle).
- Block edges can be dragged to resize (unless
resizeDisabled). - Remove button (hover on block) deletes that time range.
- Escape key cancels the current drag or resize action.
All emitted slots are normalized (no overnight ranges).
Mobile layout
On viewports narrower than compactBreakpoint (default 640px), the component switches to a compact layout when layout="auto":
- Horizontal day tabs to select one day at a time
- Full-width hour axis and track (no overlapping labels)
- Same drag, resize, and remove interactions
- Remove button always visible on touch devices
Force a layout with layout="grid" (desktop grid always) or layout="compact" (tabs always).
<ngx-weekly-availability-picker
[layout]="'auto'"
[compactBreakpoint]="640"
...
/>Theming
The component is fully themeable using CSS variables prefixed with --wap-.
Variables ending in -px accept numbers without units.
Example:
ngx-weekly-availability-picker {
--wap-block-bg-color: #2c5282;
--wap-track-height-px: 32;
--wap-title-color: #1a202c;
}(See source for the full list of supported variables.)
Development
# Build
ng build weekly-availability-picker
# Tests
ng test weekly-availability-picker
# Publish (from repo root)
npm run build && cd dist/weekly-availability-picker && npm publish --access public