glamrock-agenda
Version:
Glamrock agenda
487 lines (470 loc) • 17.2 kB
TypeScript
/// <reference types="react" />
import * as React from 'react';
import React__default, { Ref } from 'react';
import { ClassNamesConfig } from 'react-select';
import * as react_jsx_runtime from 'react/jsx-runtime';
import { Locale } from 'date-fns';
type TimeItem = {
program_start: string;
program_end: string;
door_open: string;
ticket_link: string;
price: string;
available: boolean;
status_label: string;
location: string;
free: boolean;
discount: boolean;
};
type Tags = {
interests: {
[key: string]: string;
};
categories: {
[key: string]: string | boolean;
};
};
type DataItem = {
id: number | string;
link: string;
title: string;
storyline: string;
categories: number[];
image: string;
location: number;
times: TimeItem[];
tags: Tags;
};
type DataProps = {
events: DataItem[];
total: number;
hasNextPage?: boolean;
};
type HandleParamsChangeArgs = string | Record<string, string | number | boolean | null | undefined>;
type HandleParamsChange = (params: HandleParamsChangeArgs, forceUpdate?: boolean) => void;
/**
* Represents an option for dropdown/list filters.
*/
interface FilterOption {
/**
* The unique value associated with the filter option.
*/
value: string;
/**
* The display label for the filter option.
*/
label: string;
/**
* Indicates whether the option is currently selected by the user.
*/
isSelected: boolean;
/**
* Indicates whether the option is disabled and cannot be selected.
*/
isDisabled: boolean;
}
interface BaseFilterConfig {
/**
* Unique key for the filter, used to identify the filter in the configuration.
* This key should be unique across all filters.
*/
key: string;
/**
* Display title for the filter, shown to users in the UI.
* This label should be descriptive to help users understand the filter's purpose.
*/
label: string;
/**
* Indicates whether multiple values can be selected for this filter.
* If true, users can select more than one option; if false or not provided, only a single value can be selected.
*/
multiple?: boolean;
}
interface ListFilterConfig extends BaseFilterConfig {
type: 'list';
options: FilterOption[];
}
type CalendarButtons = Array<'today' | 'tomorrow' | 'thisWeekend' | 'thisWeek' | 'thisMonth'>;
/**
* Configuration options for the calendar filter
*/
interface CalendarOptionsProps {
/**
* Optional array of button labels to show on the calendar (e.g., ['today', 'thisWeek']).
* These buttons can be used for quick date selections.
*/
showButtons?: CalendarButtons;
/**
* Render a button with title, and open the calendar on click.
* if not set → show the calendar directly.
* 'inline' – the calendar is always visible
* 'button' – a button is shown, clicking it opens a calendar popup
* 'input' – a text input that shows the calendar when focused (default)
*/
type: 'input' | 'button' | 'inline';
showIcon?: boolean;
inputLabel?: string;
showInputLabelOnly?: boolean;
dateFormat?: string;
}
/**
* Configuration for a calendar filter component.
*/
interface CalendarFilterConfig extends BaseFilterConfig {
type: 'calendar';
/**
* Optional key for specifying the end date in the calendar filter.
* This can be used to identify the end date when working with a range of dates.
*/
endDateKey?: string;
/**
* Configuration options for the calendar
*/
options: CalendarOptionsProps;
/**
* Array of dates that are available for selection in the calendar.
* All other dates not listed here will be disabled (greyed out) and cannot be selected.
*/
availableDates?: Date[];
}
interface SelectFilterConfig extends BaseFilterConfig {
type: 'select';
options: FilterOption[];
allLabel?: string;
classNames?: ClassNamesConfig;
}
interface SearchFilterConfig extends BaseFilterConfig {
type: 'search';
placeholder?: string;
showSubmitButton?: boolean;
}
type FilterConfig = ListFilterConfig | CalendarFilterConfig | SelectFilterConfig | SearchFilterConfig;
/**
* Configuration for the main filters component
*/
type FiltersProps = {
/**
* Array of filter configurations, each defining the settings and options for a specific filter.
*/
filterOptions: FilterConfig[];
/**
* Indicates whether to display a "Clear All" button to reset all filters.
* If true, the button will be shown, allowing users to clear their selections.
*/
allowClearAll?: boolean;
/**
* Indicates whether to display a "Clear All" button for the tab filter
*/
allowClearTabs?: boolean;
/**
* Specifies whether to display currently selected filters.
* If true, the component will show the active filters to users, providing visibility into their selections.
*/
displaySelectedFilters?: boolean;
/**
* Determines where the "Clear All" button should appear.
* - 'filters': inside the main filters container.
* - 'selectedFilters': inside the selected filters (tag list) container.
*/
clearAllPlacement?: 'selectedFilters' | 'filters';
/**
* Determines where the selected filters (tags) should be rendered.
* - 'inside': within the filters container.
* - 'outside': rendered outside the filters container.
*/
selectedFiltersPlacement?: 'inside' | 'outside';
/**
* Determines whether to present filters in an overlay.
* If true, filters will be shown in an overlay.
*/
useOverlay: boolean;
/**
* Optional array of tabs used to render different views or apply different ordering.
* Each tab should define a label for display and a value used for filtering or sorting logic.
*/
tabs?: Tab[];
};
type Tab = {
label: string;
value: string;
};
interface AgendaRef {
favorites: any;
toggleFavorite: () => void;
}
type AgendaProps = {
ref?: Ref<AgendaRef>;
data: DataProps;
searchParams?: Record<string, unknown>;
handleParamsChange?: HandleParamsChange;
helperText: Record<string, unknown>;
filters: FiltersProps;
options: OptionsProps;
components: CustomComponentsProps;
};
type CustomIconsProps = {
prevPage?: React__default.ReactNode;
nextPage?: React__default.ReactNode;
notFound?: React__default.ReactNode;
openFilter?: React__default.ReactNode;
closeFilter?: React__default.ReactNode;
grid?: React__default.ReactNode;
list?: React__default.ReactNode;
favorite?: React__default.ReactNode;
search?: React__default.ReactNode;
calendar?: React__default.ReactNode;
clearButton?: React__default.ReactNode;
};
type CustomComponentsProps = {
/**
* A function that takes a DataItem and returns a ReactNode.
* Use this to override the default Tile component
*
* @param item - The data item to render.
* @returns A ReactNode representing the custom tile.
*/
Tile?: (item: DataItem) => React__default.ReactNode;
/**
* A ReactNode that represents a custom component or message
* to be displayed when no data items are found.
* If not provided, a default "EmptyAgenda" component will be shown.
*/
NotFound?: React__default.ReactNode;
/**
* An object containing icons for custom navigation and other controls.
* Each key represents an icon name, and its value is a ReactNode.
*/
icons?: CustomIconsProps;
/**
* A function that takes an Image object and returns a ReactNode.
* Use this to override the default <img /> tag
*
* @param image - The data item to render.
* @returns A ReactNode.
*/
Image?: (image: any) => React__default.ReactNode;
/**
* Link component to be used instead of a default <a /> tag,
* usually it's next.js Link needed to render page client side
*/
Link?: React__default.ElementType;
/**
* Component to be used instead of the default LoadMore button
*/
LoadMoreButton?: React__default.ReactNode;
InfiniteScrollLoader?: React__default.ReactNode;
select?: React__default.JSX.Element;
list?: React__default.JSX.Element;
calendar?: React__default.JSX.Element;
search?: React__default.JSX.Element;
/**
* Optional wrapper for the calendar input button's inner content
* Receives children to render inside your custom wrapper.
*/
CalendarInputWrapper?: React__default.ComponentType<{
children: React__default.ReactNode;
}>;
/**
* Optional wrapper for the calendar open-trigger button's inner content
* Receives children to render inside your custom wrapper.
*/
CalendarOpenTriggerWrapper?: React__default.ComponentType<{
children: React__default.ReactNode;
}>;
/**
* Component to be used instead of the default MonthSeparator
* works only when `groupEventsByMonth` is true
*/
MonthSeparator?: (month: string) => React__default.ReactNode;
};
interface DateOptions {
formatSingle: string;
formatRange: {
start: string;
end: string;
};
dateRangeDivider: React__default.ReactNode | string;
useMostRecent: boolean;
/**
* Optional time formatting options, used by components that display time values.
*/
time?: {
/**
* Optional mode to control what time is displayed. Overrides `showTime`/`showStartAndEnd` when set.
* - 'none': show no time
* - 'start': show start time only
* - 'range': show start and end time
*/
mode?: 'none' | 'start' | 'range';
/** Custom formatter has highest priority. Return string or ReactNode. */
customFormatter?: (args: {
start?: Date;
end?: Date;
}) => React__default.ReactNode | string;
/**
* Format for single time value. Default 'HH:mm'.
*/
formatSingle?: string;
/**
* Formatting for time ranges. Defaults to start/end 'HH:mm' and divider ' - '.
*/
formatRange?: {
start?: string;
end?: string;
divider?: string | React__default.ReactNode;
};
/** Optional suffix appended to rendered time(s), e.g. ' uur'. */
suffix?: string | React__default.ReactNode;
};
}
type Promo = {
title: string;
subtitle: string;
link: string;
image?: string;
};
/**
* Configuration for automatically scrolling to the first result.
* - `enabled`: Whether auto-scroll should occur.
* - `offset`: Pixels from the top (positive or negative).
* - `duration`: Scroll animation time in milliseconds.
*/
interface AutoScrollOptions {
enabled: boolean;
offset?: number;
duration?: number;
}
type InfinitiveScroll = {
isLoading: boolean;
onLoadMore: () => void;
};
type OptionsProps = {
/**
* Optional locale string to set the language of the calendar and date formatting (e.g., 'en-US').
*/
locale: string;
autoScrollToFirstResult?: AutoScrollOptions;
/**
* Amount of items per page in list component
*/
postsPerPage: number;
/**
* An optional array of promotional components to be rendered within the item list.
* This can include either `Promo` objects (containing title, subtitle, link, and optional image)
* or any valid React nodes, allowing for a flexible mix of standard and custom promotional content.
*/
promoStrips?: (Promo | React__default.ReactNode)[];
/**
* The frequency at which PromoStrips should be displayed within the list
* For example, setting this to 4 will render a PromoStrip after every four items
* If not specified, PromoStrips will not be shown
*/
showViewSwitcher?: boolean;
showTotal?: boolean;
useOverlay?: boolean;
promoFrequency?: number;
date: DateOptions;
/**
* Whether to display horizontal agenda listing with month separators
*/
groupEventsByMonth?: boolean;
/**
* If defined, displays a "Load More" button instead of pagination.
* Ensure that the `data: DataProps` you pass includes `hasNextPage`.
*/
loadMore?: () => void;
/**
* If defined, enables infinite scrolling.
*/
infinitiveScroll?: InfinitiveScroll;
showFavoritesButton?: boolean;
};
/**
* Configuration for an icon component.
*/
interface IconData {
path: string;
viewBox: string;
}
type IconKey = 'ARROW_RIGHT' | 'AGENDA' | 'CLOSE' | 'OPEN_FILTER' | 'CLOSE_FILTER' | 'NORESULTS' | 'GRID' | 'LIST' | 'HEARTH' | 'HEARTH_OUTLINE' | 'SEARCH' | 'SHOPPING_CART' | 'CALENDAR';
type IconsMap = Record<IconKey, IconData>;
declare const _default: React.ForwardRefExoticComponent<Omit<any, "ref"> & React.RefAttributes<AgendaProps>>;
interface TimesProps$1 {
times: TimeItem[];
dateOptions: DateOptions;
locale: Locale;
}
declare const TileDate: ({ times, dateOptions, locale }: TimesProps$1) => react_jsx_runtime.JSX.Element;
type TileImageProps = {
src: string;
alt: string;
renderImage?: (image: any) => React__default.ReactNode;
};
declare const TileImage: ({ src, alt, renderImage, ...props }: TileImageProps) => react_jsx_runtime.JSX.Element;
declare const TileTags: ({ tags }: {
tags: DataItem['tags'];
}) => react_jsx_runtime.JSX.Element;
interface TimesProps {
times: TimeItem[];
}
declare const TileTimes: ({ times }: TimesProps) => react_jsx_runtime.JSX.Element;
interface FiltersRProps extends FiltersProps {
searchParams?: Record<string, unknown>;
total?: number;
handleParamsChange: HandleParamsChange;
helperText: Record<string, unknown>;
components?: CustomComponentsProps;
locale: string;
tabs?: Tab[];
date?: DateOptions;
}
declare const Filters: ({ filterOptions, allowClearAll, allowClearTabs, clearAllPlacement, selectedFiltersPlacement, displaySelectedFilters, searchParams, total, useOverlay, handleParamsChange, helperText, components, locale, tabs, ...props }: FiltersRProps) => react_jsx_runtime.JSX.Element;
interface ExtendedFilterConfig {
handleParamsChange: HandleParamsChange;
name: string;
searchParams?: Record<string | number, unknown>;
strings: Record<string, any>;
locale: string;
components?: CustomComponentsProps;
}
type FilterRendererProps = FilterConfig & ExtendedFilterConfig;
type CalendarProps = FilterRendererProps & CalendarFilterConfig & {
locale: string;
components?: CustomComponentsProps;
date?: DateOptions;
};
declare const Calendar: ({ name, endDateKey, searchParams, options, availableDates, handleParamsChange, locale, components, date, ...props }: CalendarProps) => react_jsx_runtime.JSX.Element;
type SelectProps = ExtendedFilterConfig & SelectFilterConfig;
declare const Select: ({ name, options, label, multiple, handleParamsChange, allLabel, classNames, strings, ...props }: SelectProps) => react_jsx_runtime.JSX.Element;
type ListProps = ExtendedFilterConfig & ListFilterConfig;
declare const List: ({ name, options, multiple, handleParamsChange }: ListProps) => react_jsx_runtime.JSX.Element;
type SearchBoxType = ExtendedFilterConfig & SearchFilterConfig & {
components: CustomComponentsProps;
searchParams: Record<string, unknown>;
};
declare const SearchBox: ({ name, label, placeholder, handleParamsChange, strings, showSubmitButton, components, searchParams }: SearchBoxType) => react_jsx_runtime.JSX.Element;
type TType = {
items: Tab[];
searchParams?: Record<string, unknown>;
handleParamsChange: HandleParamsChange;
};
declare const Tabs: ({ items, searchParams, handleParamsChange }: TType) => react_jsx_runtime.JSX.Element;
interface SelectedFiltersProps {
filters: FilterConfig[];
searchParams?: Record<string, unknown>;
handleParamsChange: HandleParamsChange;
}
declare const SelectedFilters: ({ filters, searchParams, handleParamsChange }: SelectedFiltersProps) => react_jsx_runtime.JSX.Element | null;
interface EventDate {
program_start: string;
program_end?: string;
}
declare function getDateFnsLocale(locale?: string): Locale;
declare function getStartAndEndDates(dates: EventDate[], useMostRecent: boolean): {
start: Date;
end?: Date;
endTime?: Date;
};
declare function formatDate(dates: EventDate[], options: DateOptions, locale: Locale): string | React__default.ReactNode;
export { _default as Agenda, Calendar, Filters, List, SearchBox, Select, SelectedFilters, Tabs, TileDate, TileImage, TileTags, TileTimes, formatDate, getDateFnsLocale, getStartAndEndDates };
export type { AgendaProps, AgendaRef, CalendarButtons, CalendarFilterConfig, CalendarOptionsProps, CustomComponentsProps, CustomIconsProps, DataItem, DataProps, DateOptions, FilterConfig, FilterOption, FiltersProps, HandleParamsChange, HandleParamsChangeArgs, IconData, IconKey, IconsMap, InfinitiveScroll, ListFilterConfig, OptionsProps, Promo, SearchFilterConfig, SelectFilterConfig, Tab, Tags, TimeItem };