import { EventEmitter } from '../../stencil-public-runtime'; import { FormHook } from "../../features/form-hook/form-hook"; import { FormElement, FormInputLocalization } from "../../features/form-hook/index"; import { LanguageKeys } from "../../features/multi-lingual/index"; import { BranchSlotDay } from './branch-slot-dropdown'; export interface BranchSlotSelection { /** `2026-08-13` */ date: string; /** Exactly what the API sent, e.g. `2026-08-13 09:00 AM`. */ raw: string; /** `2026-08-13T09:00` — what goes on the wire to the ticket. */ value: string; } type Status = 'idle' | 'loading' | 'ready' | 'empty' | 'error'; /** * Branch-aware booking slot field. * * Presents as a normal dropdown — the same `form-input-select` trigger as every * other select in the form — and portals its panel onto `document.body` through * `shift-portal`, exactly as `shift-select` does. * * Standalone by design: `form` is optional. Drop `` on any * page, in a PWA or in a native WebView, give it the four ids, and listen to * `slotChange`. */ export declare class BranchSlotPicker implements FormElement { /** Field name. Only meaningful when `form` is supplied. */ name: string; /** Optional — omit for standalone use and listen to `slotChange` instead. */ form?: FormHook; /** Full URL of the calendar endpoint, e.g. `https://…/api/public/calendar`. */ calendarApi: string; /** Integration ids. The field stays idle until all four are present. */ companyId: string; branchId: string; departmentId: string; brandId: string; /** How far ahead to ask. The endpoint caps its own response at 15 days. */ daysAhead: number; /** ISO calendar date, read as UTC. Omit it to use the wall clock. */ today?: string; /** * Weekdays the branch never books on, `0` Sunday … `6` Saturday. Accepts an * array or a `"5,6"` string. Matching days stay visible but unselectable — * see `~lib/slot-day-rules` for why they are not simply dropped. */ disabledWeekdays?: string | number[]; /** One-off blackout dates as `YYYY-MM-DD`, same accepted shapes as above. */ disabledDates?: string | string[]; /** Gap between the trigger and the panel, matching shift-select's default. */ gap: number; /** * Floor for the panel width on desktop. The panel is portaled to `` and * positioned fixed, so it is free to be wider than the field — and than the * form around it — which is the point: a two-column form gives the field * ~320px, which squeezed the day strip and the time grid into something that * read as clipped. Capped to the viewport at open time. */ minPanelWidth: number; /** Tallest the panel may get before it scrolls. Also capped to the viewport. */ maxPanelHeight: number; label?: string; wrapperId: string; wrapperClass: string; isRequired: boolean; isDisabled: boolean; language: LanguageKeys; localization?: FormInputLocalization; /** Preselects a slot, in the same `YYYY-MM-DDTHH:mm` form the field emits. */ defaultValue?: string; status: Status; days: BranchSlotDay[]; selectedDate: string; selectedRaw: string; isOpen: boolean; dropdownAncestorClasses: string; /** * The day being browsed in the panel. Kept apart from `selectedDate` so that * opening the panel, scrubbing through days and then dismissing it leaves the * committed selection untouched. */ draftDate: string; /** Fires on every confirmed day+time selection. The standalone contract. */ slotChange: EventEmitter; el: HTMLElement; /** * The response as it arrived, before the disable rules are layered on. Kept so * a rule change re-decorates without a refetch. */ private fetchedDays; private abortController?; private dropdownEl; private lockedScrollY; private boundKeyDown; componentWillLoad(): void; componentDidLoad(): void; disconnectedCallback(): void; onOpenChange(isOpen: boolean): void; /** * Pinning the body position rather than just hiding overflow: on iOS, * `overflow: hidden` alone still lets the page rubber-band behind the sheet. */ private lockScroll; private releaseScroll; onRulesChange(): void; onTargetChange(): void; /** FormElement contract. */ reset(newValue?: unknown): void; getValue(): string; /** Lets a host force a refetch, e.g. after a token refresh. */ refresh(): Promise; openDropdown(): Promise; closeDropdown(): Promise; private get isRtl(); private get copy(); private get intlLocales(); private pad; /** `2026-08-13 09:00 AM` → minutes since midnight. */ private minutesOf; private toFormValue; private displayTime; private formatDay; private queryUrl; /** * Overlapping work periods of equal priority make the endpoint emit the same * slot more than once (branch 45 returns every time twice), and a merged * response is not necessarily ordered. Both are fixed here rather than in the * panel, so anything reading `days` gets clean data. */ private normalise; /** Layers the disable rules over the response without discarding anything. */ private applyDayRules; private firstOpenDay; private load; private setDropdownRef; private getTriggerEl; private isTriggerInView; /** * Below this width the panel is a bottom sheet pinned to the viewport, so it * is not anchored to anything and none of the positioning below applies. Kept * in sync with the media query in branch-slot-dropdown.css. */ private get isSheet(); /** Mirrors shift-select: anchor to the trigger, flip up when space is short. */ private adjustDropdownPosition; private handleResize; private handleScroll; private handleKeyDown; private closeOnOutsideClick; private toggle; private handleDay; private handleTime; /** What the trigger shows: the committed slot, or why it cannot be opened. */ private triggerText; render(): any; } export {};