@tribepad/themis 1.6.12 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/elements/Timeline/Timeline.d.ts +35 -0
- package/dist/elements/Timeline/Timeline.d.ts.map +1 -0
- package/dist/elements/Timeline/Timeline.styles.d.ts +41 -0
- package/dist/elements/Timeline/Timeline.styles.d.ts.map +1 -0
- package/dist/elements/Timeline/Timeline.types.d.ts +177 -0
- package/dist/elements/Timeline/Timeline.types.d.ts.map +1 -0
- package/dist/elements/Timeline/TimelineContext.d.ts +25 -0
- package/dist/elements/Timeline/TimelineContext.d.ts.map +1 -0
- package/dist/elements/Timeline/TimelineItem.d.ts +22 -0
- package/dist/elements/Timeline/TimelineItem.d.ts.map +1 -0
- package/dist/elements/Timeline/index.d.ts +14 -0
- package/dist/elements/Timeline/index.d.ts.map +1 -0
- package/dist/elements/Timeline/index.js +3 -0
- package/dist/elements/Timeline/index.js.map +1 -0
- package/dist/elements/Timeline/index.mjs +3 -0
- package/dist/elements/Timeline/index.mjs.map +1 -0
- package/dist/elements/index.d.ts +2 -0
- package/dist/elements/index.d.ts.map +1 -1
- package/dist/elements/index.js +1 -1
- package/dist/elements/index.js.map +1 -1
- package/dist/elements/index.mjs +1 -1
- package/dist/elements/index.mjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/elements/Timeline/Timeline.stories.tsx +244 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.7.0] - 2026-06-22
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **New `Timeline` component** — an accessible, chronological feed of events built on the compound pattern (`<Timeline>` + `<Timeline.Item>`) and rendered as a semantic `<ol>`/`<li>` (WCAG 2.2 AAA). Two axes of variation: `orientation` (`vertical` (default) | `horizontal`) × `marker` (`dot` | `basic` | `icon`). The `basic` style draws a continuous primary rail the full length of the timeline with a short primary stub branching into each item; `dot`/`icon` place a marker per event with a muted connector. Connector lines and markers are decorative (`aria-hidden`); meaning comes from the text.
|
|
12
|
+
- **Data & dates.** Events enter as `<Timeline.Item>` children. Each item takes `date` (`Date | string | number`), rendered inside `<time dateTime>`. Date granularity (hour/day/month/year) is controlled with `dateFormatOptions` (`Intl.DateTimeFormatOptions`, default `{ year: 'numeric', month: 'long' }` → "April 2025"), with `locale`, a per-item `dateFormatOptions` override, and a `formatDate` render override; a non-date `label` is supported as a fallback. A single `Intl.DateTimeFormat` instance is memoised at the root and shared by all items.
|
|
13
|
+
- **Body precedence.** `title`/`description` cover the common case; passing `children` supersedes them (dev-only warning if both are given) so richer item content — e.g. an activity-log row with an avatar and message bubble — can be composed via the `icon` slot + `children` body without a dedicated variant.
|
|
14
|
+
- **Responsive.** Horizontal timelines auto-collapse to vertical below `collapseBelow` (default `640`px, container-query based; pass `false` to disable). Wide horizontal timelines stay keyboard-scrollable.
|
|
15
|
+
- **Pagination.** Server/consumer-fed via `onLoadMore` / `hasMore` / `isLoadingMore` and a built-in "Show more" button (`loadMoreLabel`); the component renders every item it is given (no client-side windowing, which would hide content from find-in-page and screen readers) and uses `content-visibility: auto` per item for large-list performance. Focus stays on the button across loads and moves to the first new item when the final load removes it; a `role="status"` live region announces on user-initiated load only.
|
|
16
|
+
- **Navigation.** Imperative `ref` handle exposes `scrollToItem(id)` and `focusItem(id)` (smooth scrolling honours `prefers-reduced-motion`).
|
|
17
|
+
- **Interactive items.** `href` or `onPress` makes an item actionable (real `<a>`/`<button>`, 44px target, visible focus ring); hovering/focusing highlights the marker and shows a roomy background that doesn't shift the text. An optional `emptyState` slot renders when there are no items, and `titleHeadingLevel` (`'p'` default, or `h2`–`h6`) controls title semantics. There is **no** "active"/selected-item concept.
|
|
18
|
+
- New exports: `Timeline`, `TimelineItem`, `useTimelineContext`, the `timeline*Variants` CVA functions, `Timeline*Schema` schemas, and the `TimelineProps` / `TimelineItemProps` / `TimelineHandle` / orientation & marker types.
|
|
19
|
+
|
|
8
20
|
## [1.6.12] - 2026-06-22
|
|
9
21
|
|
|
10
22
|
### Fixed
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Timeline — compound root.
|
|
3
|
+
*
|
|
4
|
+
* An accessible, chronological feed of events rendered as a semantic `<ol>`. WCAG 2.2 AAA.
|
|
5
|
+
*
|
|
6
|
+
* Design notes:
|
|
7
|
+
* - Renders EVERY child it is given — it never caps/slices present data (hidden content
|
|
8
|
+
* would be invisible to find-in-page and screen readers). Large/server-fed data uses
|
|
9
|
+
* `onLoadMore`/`hasMore` to append more `<Timeline.Item>` children; performance for
|
|
10
|
+
* long, fully-rendered lists comes from `content-visibility: auto` on each item.
|
|
11
|
+
* - Config (orientation, marker, formatter, …) lives in a memoised context.
|
|
12
|
+
* - Horizontal timelines auto-collapse to vertical on narrow containers via
|
|
13
|
+
* `useContainerNarrow`. There is no "active"/selected item concept; programmatic
|
|
14
|
+
* navigation is via the imperative handle (`scrollToItem`/`focusItem`).
|
|
15
|
+
*
|
|
16
|
+
* @see Wizard (role="status" live region, configurable heading level)
|
|
17
|
+
* @see Tabs (compound children + context)
|
|
18
|
+
*/
|
|
19
|
+
import { type ReactElement } from 'react';
|
|
20
|
+
import type { TimelineHandle, TimelineProps } from './Timeline.types';
|
|
21
|
+
/**
|
|
22
|
+
* Timeline compound component.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```tsx
|
|
26
|
+
* <Timeline aria-label="Application history" marker="dot">
|
|
27
|
+
* <Timeline.Item date="2025-04-02" title="Applied" description="Application received." />
|
|
28
|
+
* <Timeline.Item date="2025-04-10" title="Interview" status="active" />
|
|
29
|
+
* </Timeline>
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export declare const Timeline: import("react").ForwardRefExoticComponent<TimelineProps & import("react").RefAttributes<TimelineHandle>> & {
|
|
33
|
+
Item: import("react").MemoExoticComponent<({ id, date, label, dateFormatOptions, title, description, children, icon, href, target, rel, onPress, className, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, "data-testid": testId, }: import("./Timeline.types").TimelineItemProps) => ReactElement>;
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=Timeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Timeline.d.ts","sourceRoot":"","sources":["../../../src/elements/Timeline/Timeline.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAUL,KAAK,YAAY,EAClB,MAAM,OAAO,CAAC;AAWf,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AA+KtE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,QAAQ;;CAEnB,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ordered list. Vertical stacks top-to-bottom; horizontal flows left-to-right
|
|
3
|
+
* and is keyboard-scrollable when it overflows (the component adds `tabIndex`).
|
|
4
|
+
*/
|
|
5
|
+
export declare const timelineVariants: (props?: ({
|
|
6
|
+
orientation?: "horizontal" | "vertical" | null | undefined;
|
|
7
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
8
|
+
/**
|
|
9
|
+
* A single event (`<li>`). Marker rail + content.
|
|
10
|
+
*
|
|
11
|
+
* `content-visibility: auto` keeps every node in the DOM and the a11y tree (Ctrl+F and
|
|
12
|
+
* screen-reader traversal still work — AAA-safe) while skipping layout/paint for
|
|
13
|
+
* off-screen items. `contain-intrinsic-size` is orientation-aware (height placeholder
|
|
14
|
+
* when vertical, width placeholder when horizontal).
|
|
15
|
+
*/
|
|
16
|
+
export declare const timelineItemVariants: (props?: ({
|
|
17
|
+
orientation?: "horizontal" | "vertical" | null | undefined;
|
|
18
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
19
|
+
/**
|
|
20
|
+
* The marker node for the `'dot'` and `'icon'` styles (the `'basic'` line style has no
|
|
21
|
+
* marker). Dots are a muted node on the rail; the icon badge is primary-filled.
|
|
22
|
+
*/
|
|
23
|
+
export declare const timelineMarkerVariants: (props?: ({
|
|
24
|
+
marker?: "icon" | "dot" | null | undefined;
|
|
25
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
26
|
+
/**
|
|
27
|
+
* The connector between dot/icon markers — a muted line that `flex-1` fills down to
|
|
28
|
+
* (vertical) or across to (horizontal) the next marker. (The `'basic'` style draws its
|
|
29
|
+
* own full-length primary rail instead; see TimelineItem.)
|
|
30
|
+
*/
|
|
31
|
+
export declare const timelineConnectorVariants: (props?: ({
|
|
32
|
+
orientation?: "horizontal" | "vertical" | null | undefined;
|
|
33
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
34
|
+
/**
|
|
35
|
+
* The content column (meta / title / description / custom body). When the item is
|
|
36
|
+
* interactive the inner Link/Button reuses these paddings.
|
|
37
|
+
*/
|
|
38
|
+
export declare const timelineContentVariants: (props?: ({
|
|
39
|
+
orientation?: "horizontal" | "vertical" | null | undefined;
|
|
40
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
41
|
+
//# sourceMappingURL=Timeline.styles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Timeline.styles.d.ts","sourceRoot":"","sources":["../../../src/elements/Timeline/Timeline.styles.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,eAAO,MAAM,gBAAgB;;8EAU3B,CAAC;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB;;8EAW/B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,sBAAsB;;8EAalC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,yBAAyB;;8EAarC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,uBAAuB;;8EAWlC,CAAC"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* Timeline orientation.
|
|
5
|
+
*
|
|
6
|
+
* - 'vertical': events stack top-to-bottom with a vertical connector rail (default).
|
|
7
|
+
* - 'horizontal': events flow left-to-right with a horizontal connector. Auto-collapses
|
|
8
|
+
* to vertical on narrow containers (see `collapseBelow`).
|
|
9
|
+
*/
|
|
10
|
+
export declare const TimelineOrientationSchema: z.ZodEnum<{
|
|
11
|
+
horizontal: "horizontal";
|
|
12
|
+
vertical: "vertical";
|
|
13
|
+
}>;
|
|
14
|
+
export type TimelineOrientation = z.infer<typeof TimelineOrientationSchema>;
|
|
15
|
+
/**
|
|
16
|
+
* Marker style for each event.
|
|
17
|
+
*
|
|
18
|
+
* - 'dot': small circular node on the connector (default).
|
|
19
|
+
* - 'basic': no node — just the connector line; active items colour the line segment.
|
|
20
|
+
* - 'icon': circular badge holding an icon or avatar.
|
|
21
|
+
*/
|
|
22
|
+
export declare const TimelineMarkerSchema: z.ZodEnum<{
|
|
23
|
+
icon: "icon";
|
|
24
|
+
dot: "dot";
|
|
25
|
+
basic: "basic";
|
|
26
|
+
}>;
|
|
27
|
+
export type TimelineMarker = z.infer<typeof TimelineMarkerSchema>;
|
|
28
|
+
/**
|
|
29
|
+
* Heading level for item titles. Mirrors Wizard's `stepHeadingLevel`. Defaults to
|
|
30
|
+
* `'p'` (rendered as a styled `<strong>`-like paragraph) to avoid breaking the host
|
|
31
|
+
* page's heading hierarchy; opt into real headings (`h2`–`h6`) when appropriate.
|
|
32
|
+
*/
|
|
33
|
+
export declare const TimelineHeadingLevelSchema: z.ZodEnum<{
|
|
34
|
+
h2: "h2";
|
|
35
|
+
h3: "h3";
|
|
36
|
+
h4: "h4";
|
|
37
|
+
h5: "h5";
|
|
38
|
+
h6: "h6";
|
|
39
|
+
p: "p";
|
|
40
|
+
}>;
|
|
41
|
+
export type TimelineHeadingLevel = z.infer<typeof TimelineHeadingLevelSchema>;
|
|
42
|
+
/** A value accepted by `new Date(...)`. */
|
|
43
|
+
export type TimelineDateInput = Date | string | number;
|
|
44
|
+
/**
|
|
45
|
+
* Imperative handle exposed via `ref` for in-timeline navigation.
|
|
46
|
+
*/
|
|
47
|
+
export interface TimelineHandle {
|
|
48
|
+
/** Scroll the item with this `id` into view (respects `prefers-reduced-motion`). */
|
|
49
|
+
scrollToItem: (id: string) => void;
|
|
50
|
+
/** Move focus to the item with this `id`. */
|
|
51
|
+
focusItem: (id: string) => void;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Timeline root props.
|
|
55
|
+
*
|
|
56
|
+
* Data enters via `<Timeline.Item>` children (compound pattern). Timeline renders
|
|
57
|
+
* every child it is given — it never caps/slices present data (that would hide
|
|
58
|
+
* content from find-in-page and screen readers). For large or server-fed data use
|
|
59
|
+
* `onLoadMore`/`hasMore` to append more items.
|
|
60
|
+
*/
|
|
61
|
+
export declare const TimelinePropsSchema: z.ZodObject<{
|
|
62
|
+
className: z.ZodOptional<z.ZodString>;
|
|
63
|
+
id: z.ZodOptional<z.ZodString>;
|
|
64
|
+
'aria-label': z.ZodOptional<z.ZodString>;
|
|
65
|
+
'aria-labelledby': z.ZodOptional<z.ZodString>;
|
|
66
|
+
'aria-describedby': z.ZodOptional<z.ZodString>;
|
|
67
|
+
'aria-live': z.ZodOptional<z.ZodEnum<{
|
|
68
|
+
off: "off";
|
|
69
|
+
polite: "polite";
|
|
70
|
+
assertive: "assertive";
|
|
71
|
+
}>>;
|
|
72
|
+
'aria-hidden': z.ZodOptional<z.ZodBoolean>;
|
|
73
|
+
'data-testid': z.ZodOptional<z.ZodString>;
|
|
74
|
+
children: z.ZodOptional<z.ZodCustom<ReactNode, ReactNode>>;
|
|
75
|
+
orientation: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
76
|
+
horizontal: "horizontal";
|
|
77
|
+
vertical: "vertical";
|
|
78
|
+
}>>>;
|
|
79
|
+
marker: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
80
|
+
icon: "icon";
|
|
81
|
+
dot: "dot";
|
|
82
|
+
basic: "basic";
|
|
83
|
+
}>>>;
|
|
84
|
+
locale: z.ZodOptional<z.ZodString>;
|
|
85
|
+
dateFormatOptions: z.ZodOptional<z.ZodCustom<Intl.DateTimeFormatOptions, Intl.DateTimeFormatOptions>>;
|
|
86
|
+
formatDate: z.ZodOptional<z.ZodCustom<(date: Date) => ReactNode, (date: Date) => ReactNode>>;
|
|
87
|
+
titleHeadingLevel: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
88
|
+
h2: "h2";
|
|
89
|
+
h3: "h3";
|
|
90
|
+
h4: "h4";
|
|
91
|
+
h5: "h5";
|
|
92
|
+
h6: "h6";
|
|
93
|
+
p: "p";
|
|
94
|
+
}>>>;
|
|
95
|
+
collapseBelow: z.ZodDefault<z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodLiteral<false>]>>>;
|
|
96
|
+
onLoadMore: z.ZodOptional<z.ZodCustom<() => void | Promise<void>, () => void | Promise<void>>>;
|
|
97
|
+
hasMore: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
98
|
+
isLoadingMore: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
99
|
+
loadMoreLabel: z.ZodOptional<z.ZodString>;
|
|
100
|
+
emptyState: z.ZodOptional<z.ZodCustom<ReactNode, ReactNode>>;
|
|
101
|
+
landmarkLabel: z.ZodOptional<z.ZodString>;
|
|
102
|
+
}, z.core.$strip>;
|
|
103
|
+
export interface TimelineProps {
|
|
104
|
+
className?: string;
|
|
105
|
+
children?: ReactNode;
|
|
106
|
+
id?: string;
|
|
107
|
+
'aria-label'?: string;
|
|
108
|
+
'aria-labelledby'?: string;
|
|
109
|
+
'aria-describedby'?: string;
|
|
110
|
+
'data-testid'?: string;
|
|
111
|
+
orientation?: TimelineOrientation;
|
|
112
|
+
marker?: TimelineMarker;
|
|
113
|
+
locale?: string;
|
|
114
|
+
dateFormatOptions?: Intl.DateTimeFormatOptions;
|
|
115
|
+
formatDate?: (date: Date) => ReactNode;
|
|
116
|
+
titleHeadingLevel?: TimelineHeadingLevel;
|
|
117
|
+
collapseBelow?: number | false;
|
|
118
|
+
onLoadMore?: () => void | Promise<void>;
|
|
119
|
+
hasMore?: boolean;
|
|
120
|
+
isLoadingMore?: boolean;
|
|
121
|
+
loadMoreLabel?: string;
|
|
122
|
+
emptyState?: ReactNode;
|
|
123
|
+
landmarkLabel?: string;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Timeline.Item props.
|
|
127
|
+
*
|
|
128
|
+
* Body precedence: if `children` is provided it is the body and supersedes
|
|
129
|
+
* `title`/`description` (a dev-only warning fires if both are passed). The meta
|
|
130
|
+
* region (`date`/`label`) and the marker are always owned by Timeline.Item. There is
|
|
131
|
+
* no "active"/selected concept — every item is presented identically per the variant.
|
|
132
|
+
*/
|
|
133
|
+
export declare const TimelineItemPropsSchema: z.ZodObject<{
|
|
134
|
+
className: z.ZodOptional<z.ZodString>;
|
|
135
|
+
'aria-label': z.ZodOptional<z.ZodString>;
|
|
136
|
+
'aria-labelledby': z.ZodOptional<z.ZodString>;
|
|
137
|
+
'aria-describedby': z.ZodOptional<z.ZodString>;
|
|
138
|
+
'aria-live': z.ZodOptional<z.ZodEnum<{
|
|
139
|
+
off: "off";
|
|
140
|
+
polite: "polite";
|
|
141
|
+
assertive: "assertive";
|
|
142
|
+
}>>;
|
|
143
|
+
'aria-hidden': z.ZodOptional<z.ZodBoolean>;
|
|
144
|
+
'data-testid': z.ZodOptional<z.ZodString>;
|
|
145
|
+
id: z.ZodOptional<z.ZodString>;
|
|
146
|
+
date: z.ZodOptional<z.ZodCustom<string | number | Date, string | number | Date>>;
|
|
147
|
+
label: z.ZodOptional<z.ZodCustom<ReactNode, ReactNode>>;
|
|
148
|
+
dateFormatOptions: z.ZodOptional<z.ZodCustom<Intl.DateTimeFormatOptions, Intl.DateTimeFormatOptions>>;
|
|
149
|
+
title: z.ZodOptional<z.ZodCustom<ReactNode, ReactNode>>;
|
|
150
|
+
description: z.ZodOptional<z.ZodCustom<ReactNode, ReactNode>>;
|
|
151
|
+
children: z.ZodOptional<z.ZodCustom<ReactNode, ReactNode>>;
|
|
152
|
+
icon: z.ZodOptional<z.ZodCustom<ReactNode, ReactNode>>;
|
|
153
|
+
href: z.ZodOptional<z.ZodString>;
|
|
154
|
+
target: z.ZodOptional<z.ZodString>;
|
|
155
|
+
rel: z.ZodOptional<z.ZodString>;
|
|
156
|
+
onPress: z.ZodOptional<z.ZodCustom<() => void, () => void>>;
|
|
157
|
+
}, z.core.$strip>;
|
|
158
|
+
export interface TimelineItemProps {
|
|
159
|
+
className?: string;
|
|
160
|
+
children?: ReactNode;
|
|
161
|
+
id?: string;
|
|
162
|
+
'aria-label'?: string;
|
|
163
|
+
'aria-labelledby'?: string;
|
|
164
|
+
'aria-describedby'?: string;
|
|
165
|
+
'data-testid'?: string;
|
|
166
|
+
date?: TimelineDateInput;
|
|
167
|
+
label?: ReactNode;
|
|
168
|
+
dateFormatOptions?: Intl.DateTimeFormatOptions;
|
|
169
|
+
title?: ReactNode;
|
|
170
|
+
description?: ReactNode;
|
|
171
|
+
icon?: ReactNode;
|
|
172
|
+
href?: string;
|
|
173
|
+
target?: string;
|
|
174
|
+
rel?: string;
|
|
175
|
+
onPress?: () => void;
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=Timeline.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Timeline.types.d.ts","sourceRoot":"","sources":["../../../src/elements/Timeline/Timeline.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { TimelineHeadingLevel, TimelineMarker, TimelineOrientation } from './Timeline.types';
|
|
3
|
+
/**
|
|
4
|
+
* Stable configuration shared with every `Timeline.Item`. Memoised at the root and
|
|
5
|
+
* changes ~never, so item content (notably date formatting) is not recomputed on
|
|
6
|
+
* unrelated root re-renders.
|
|
7
|
+
*/
|
|
8
|
+
export interface TimelineConfigContextValue {
|
|
9
|
+
/** Effective orientation (already resolved for the mobile collapse). */
|
|
10
|
+
orientation: TimelineOrientation;
|
|
11
|
+
marker: TimelineMarker;
|
|
12
|
+
locale: string | undefined;
|
|
13
|
+
/** Shared `Intl.DateTimeFormat` instance — built once, reused by all items. */
|
|
14
|
+
dateFormatter: Intl.DateTimeFormat;
|
|
15
|
+
formatDate: ((date: Date) => ReactNode) | undefined;
|
|
16
|
+
dateFormatOptions: Intl.DateTimeFormatOptions | undefined;
|
|
17
|
+
titleHeadingLevel: TimelineHeadingLevel;
|
|
18
|
+
/** Whether the user prefers reduced motion (gates smooth scrolling). */
|
|
19
|
+
reducedMotion: boolean;
|
|
20
|
+
/** Items register their focus target node here for `scrollToItem`/`focusItem`. */
|
|
21
|
+
registerItem: (id: string, node: HTMLElement | null) => void;
|
|
22
|
+
}
|
|
23
|
+
export declare const TimelineConfigContext: import("react").Context<TimelineConfigContextValue | null>;
|
|
24
|
+
export declare function useTimelineContext(): TimelineConfigContextValue;
|
|
25
|
+
//# sourceMappingURL=TimelineContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TimelineContext.d.ts","sourceRoot":"","sources":["../../../src/elements/Timeline/TimelineContext.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EACV,oBAAoB,EACpB,cAAc,EACd,mBAAmB,EACpB,MAAM,kBAAkB,CAAC;AAE1B;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IACzC,wEAAwE;IACxE,WAAW,EAAE,mBAAmB,CAAC;IACjC,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,+EAA+E;IAC/E,aAAa,EAAE,IAAI,CAAC,cAAc,CAAC;IACnC,UAAU,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC,GAAG,SAAS,CAAC;IACpD,iBAAiB,EAAE,IAAI,CAAC,qBAAqB,GAAG,SAAS,CAAC;IAC1D,iBAAiB,EAAE,oBAAoB,CAAC;IACxC,wEAAwE;IACxE,aAAa,EAAE,OAAO,CAAC;IACvB,kFAAkF;IAClF,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAC;CAC9D;AAED,eAAO,MAAM,qBAAqB,4DAAyD,CAAC;AAE5F,wBAAgB,kBAAkB,IAAI,0BAA0B,CAM/D"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Timeline.Item — a single event (`<li>`): marker rail + content.
|
|
3
|
+
*
|
|
4
|
+
* Body precedence: `children` is the body and supersedes `title`/`description`
|
|
5
|
+
* (dev-only warning if both are passed). The meta region (`date`/`label`) and the
|
|
6
|
+
* marker are always owned here so date/marker presentation stays consistent even for
|
|
7
|
+
* fully-custom bodies (e.g. an activity-log item composed via `icon` + `children`).
|
|
8
|
+
*
|
|
9
|
+
* Accessibility:
|
|
10
|
+
* - The marker rail (decorative dot/icon + connector) is `aria-hidden`; meaning comes
|
|
11
|
+
* from the text. Interactive items wrap the content in a real `<a>`/`<button>` with a
|
|
12
|
+
* visible focus ring; static items are focusable only programmatically (`tabIndex=-1`)
|
|
13
|
+
* so `focusItem`/`scrollToItem` can target them.
|
|
14
|
+
* - The whole-card link/button must not contain nested interactive children — if an
|
|
15
|
+
* item needs secondary actions, make only the title a link instead.
|
|
16
|
+
*/
|
|
17
|
+
import { type ReactElement } from 'react';
|
|
18
|
+
import type { TimelineItemProps } from './Timeline.types';
|
|
19
|
+
declare function TimelineItemImpl({ id, date, label, dateFormatOptions, title, description, children, icon, href, target, rel, onPress, className, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, 'aria-describedby': ariaDescribedBy, 'data-testid': testId, }: TimelineItemProps): ReactElement;
|
|
20
|
+
export declare const TimelineItem: import("react").MemoExoticComponent<typeof TimelineItemImpl>;
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=TimelineItem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TimelineItem.d.ts","sourceRoot":"","sources":["../../../src/elements/Timeline/TimelineItem.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAA8B,KAAK,YAAY,EAAkB,MAAM,OAAO,CAAC;AAUtF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AA8B1D,iBAAS,gBAAgB,CAAC,EACxB,EAAE,EACF,IAAI,EACJ,KAAK,EACL,iBAAiB,EACjB,KAAK,EACL,WAAW,EACX,QAAQ,EACR,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,GAAG,EACH,OAAO,EACP,SAAS,EACT,YAAY,EAAE,SAAS,EACvB,iBAAiB,EAAE,cAAc,EACjC,kBAAkB,EAAE,eAAe,EACnC,aAAa,EAAE,MAAM,GACtB,EAAE,iBAAiB,GAAG,YAAY,CAkNlC;AAED,eAAO,MAAM,YAAY,8DAAyB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Timeline Component Barrel Exports
|
|
3
|
+
*
|
|
4
|
+
* @see Timeline.tsx (root + compound)
|
|
5
|
+
* @see TimelineItem.tsx (event item)
|
|
6
|
+
* @see Timeline.types.ts (types + schemas)
|
|
7
|
+
*/
|
|
8
|
+
export { Timeline } from './Timeline';
|
|
9
|
+
export { TimelineItem } from './TimelineItem';
|
|
10
|
+
export { useTimelineContext } from './TimelineContext';
|
|
11
|
+
export { timelineVariants, timelineItemVariants, timelineMarkerVariants, timelineConnectorVariants, timelineContentVariants, } from './Timeline.styles';
|
|
12
|
+
export type { TimelineProps, TimelineItemProps, TimelineOrientation, TimelineMarker, TimelineHeadingLevel, TimelineDateInput, TimelineHandle, } from './Timeline.types';
|
|
13
|
+
export { TimelinePropsSchema, TimelineItemPropsSchema, TimelineOrientationSchema, TimelineMarkerSchema, TimelineHeadingLevelSchema, } from './Timeline.types';
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/elements/Timeline/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAGvD,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,sBAAsB,EACtB,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAG3B,YAAY,EACV,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EACd,oBAAoB,EACpB,iBAAiB,EACjB,cAAc,GACf,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,yBAAyB,EACzB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';var react=require('react'),reactAriaComponents=require('react-aria-components'),lucideReact=require('lucide-react'),clsx=require('clsx'),tailwindMerge=require('tailwind-merge'),classVarianceAuthority=require('class-variance-authority'),jsxRuntime=require('react/jsx-runtime'),zod=require('zod');function l(...n){return tailwindMerge.twMerge(clsx.clsx(n))}var te=classVarianceAuthority.cva("inline-flex justify-center min-h-[44px] min-w-[44px] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50",{variants:{fullWidth:{true:"w-full",false:""},inVerticalGroup:{true:"items-stretch",false:"items-center"}},defaultVariants:{fullWidth:false,inVerticalGroup:false}}),oe=classVarianceAuthority.cva("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-normal ring-offset-background motion-safe:transition-transform motion-safe:duration-200 motion-safe:[transition-timing-function:cubic-bezier(0.34,1.56,0.64,1)] motion-reduce:transition-none [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 relative cursor-pointer",{variants:{variant:{default:"bg-[var(--primary-action)] text-[var(--primary-action-foreground)] shadow-md hover:bg-[var(--primary-action-hover)] hover:-translate-y-1",destructive:"bg-[var(--destructive-background)] text-[var(--destructive-foreground)] hover:bg-[var(--destructive-background-hover,var(--destructive-background))] motion-safe:hover:btn-warn-shake",outline:"border border-[var(--input-border)] bg-[var(--page-background)] hover:bg-[var(--input-border)]",secondary:"bg-[var(--secondary)] text-[var(--secondary-foreground)] hover:bg-[var(--secondary-hover,var(--secondary))]",ghost:"hover:bg-[var(--accent)] hover:text-[var(--accent-foreground)]",link:"text-[var(--text-link)] underline underline-offset-4 hover:bg-[var(--accent)] hover:text-[var(--text-link-hover)]"},fullWidth:{true:"w-full",false:""},visualSize:{default:"h-10 px-4 py-2",sm:"h-9 rounded-md px-3 text-xs",lg:"h-11 rounded-md px-6 text-base",icon:"h-10 w-10",dot:"h-5 w-5 rounded-full p-0 min-h-0 min-w-0"},paywall:{true:"!bg-[var(--paywall)] !text-[var(--paywall-foreground)] hover:!bg-[var(--paywall)]/90 !cursor-not-allowed !border-transparent",false:""}},defaultVariants:{variant:"default",visualSize:"default",paywall:false}});var ne="data-[pressed]:scale-[0.97]";var j="hc:data-[hovered]:outline hc:data-[hovered]:outline-2 hc:data-[hovered]:outline-foreground",q="hc:data-[pressed]:outline hc:data-[pressed]:outline-2 hc:data-[pressed]:outline-offset-1 hc:data-[pressed]:outline-foreground";var Ie=react.createContext(null);Ie.displayName="ButtonGroupContext";function Ce(){return react.useContext(Ie)}var Ee=react.createContext(null);Ee.displayName="ButtonGroupItemContext";function Ve(){return react.useContext(Ee)}classVarianceAuthority.cva("inline-flex items-center gap-0",{variants:{orientation:{horizontal:"flex-row",vertical:"flex-col w-full"}},defaultVariants:{orientation:"horizontal"}});var Re=classVarianceAuthority.cva("",{variants:{orientation:{horizontal:"min-w-[44px]",vertical:"flex min-h-[44px]"},position:{first:"",middle:"",last:"",only:""}},compoundVariants:[{orientation:"horizontal",position:"first",className:"rounded-r-none border-r-0"},{orientation:"horizontal",position:"middle",className:"rounded-none border-r-0"},{orientation:"horizontal",position:"last",className:"rounded-l-none"},{orientation:"vertical",position:"first",className:"rounded-b-none border-b-0"},{orientation:"vertical",position:"middle",className:"rounded-none border-b-0"},{orientation:"vertical",position:"last",className:"rounded-t-none"}],defaultVariants:{orientation:"horizontal",position:"only"}});classVarianceAuthority.cva("bg-[var(--border)]",{variants:{orientation:{horizontal:"w-px h-6 mx-1",vertical:"h-px w-full my-1"}},defaultVariants:{orientation:"horizontal"}});var Q=react.memo(react.forwardRef(({className:n,buttonVisualClassName:a,variant:d,size:u,visualSize:o,fullWidth:i,loading:c=false,loadingText:M="Loading...",shortcut:g,children:E,isDisabled:V,paywall:p=false,paywallRedirect:B,paywallDescription:k,onPress:R,...T},P)=>{let f=react.useId(),s=Ce(),w=Ve(),N=d??s?.variant??"default",z=u??s?.size,y=V??s?.isDisabled??false,S=s?.orientation==="vertical",h=i||S,v=w?Re({orientation:s?.orientation??"horizontal",position:w.position}):"",L=o??z??"default";return process.env.NODE_ENV!=="production"&&(L==="dot"||L==="icon")&&!T["aria-label"]&&!E&&console.warn('[Button] visualSize="dot" or "icon" requires aria-label when no visible text is provided (WCAG 1.1.1)'),jsxRuntime.jsx(reactAriaComponents.Button,{ref:P,isDisabled:y||c||void 0,"aria-disabled":p?true:void 0,"aria-describedby":p?f:void 0,onPress:m=>{if(p){B&&window.open(B,"_blank","noopener,noreferrer");return}R?.(m);},className:l(te({fullWidth:h,inVerticalGroup:S}),n),...T,children:m=>jsxRuntime.jsxs("span",{className:l(oe({variant:N,visualSize:L,paywall:p,fullWidth:h}),v,a,ne,"",j,q),"data-pressed":m.isPressed||void 0,children:[c&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(lucideReact.Loader2,{className:"motion-safe:animate-spin","aria-hidden":"true"}),jsxRuntime.jsx("span",{className:"sr-only","aria-live":"polite",children:M})]}),!c&&E,p&&jsxRuntime.jsx(lucideReact.Zap,{"data-testid":"zap-icon","aria-hidden":"true",className:"ml-1"}),p&&jsxRuntime.jsxs("span",{id:f,className:"sr-only",children:["Premium feature: ",k||"Upgrade required to access this feature"]}),m.isFocusVisible&&g&&jsxRuntime.jsx("kbd",{className:"ml-auto hidden text-xs opacity-60 lg:inline",children:g})]})})}));Q.displayName="Button";function we(n,a){let[d,u]=react.useState(false);return react.useEffect(()=>{let o=n.current;if(!o)return;let i=()=>u(o.offsetWidth<a);i();let c;return typeof ResizeObserver<"u"&&(c=new ResizeObserver(i),c.observe(o)),window.addEventListener("resize",i),()=>{window.removeEventListener("resize",i),c?.disconnect();}},[n,a]),d}var Le="(prefers-reduced-motion: reduce)";function ot(){return typeof window>"u"?false:window.matchMedia(Le).matches}function He(){let[n,a]=react.useState(ot);return react.useEffect(()=>{let d=window.matchMedia(Le);a(d.matches);let u=o=>{a(o.matches);};return d.addEventListener("change",u),()=>d.removeEventListener("change",u)},[]),n}var se=react.createContext(null);function le(){let n=react.useContext(se);if(!n)throw new Error("Timeline.Item must be used within <Timeline>");return n}var ce=classVarianceAuthority.cva("m-0 flex list-none p-0",{variants:{orientation:{vertical:"flex-col",horizontal:"flex-row items-stretch overflow-x-auto"}},defaultVariants:{orientation:"vertical"}}),me=classVarianceAuthority.cva("relative [content-visibility:auto]",{variants:{orientation:{vertical:"grid grid-cols-[auto_minmax(0,1fr)] gap-x-4 [contain-intrinsic-size:auto_88px]",horizontal:"flex min-w-[12rem] flex-1 flex-col [contain-intrinsic-size:14rem_auto]"}},defaultVariants:{orientation:"vertical"}}),de=classVarianceAuthority.cva("relative z-10 flex shrink-0 items-center justify-center",{variants:{marker:{dot:"h-3 w-3 rounded-full bg-[var(--input-border)]",icon:"h-8 w-8 rounded-full bg-[var(--primary-action)] text-[var(--primary-action-foreground)] [&_svg]:h-4 [&_svg]:w-4"}},defaultVariants:{marker:"dot"}}),ue=classVarianceAuthority.cva("shrink-0 flex-1 rounded-full bg-[var(--border)]",{variants:{orientation:{vertical:"mt-1 w-0.5",horizontal:"ml-2 h-0.5"}},defaultVariants:{orientation:"vertical"}}),pe=classVarianceAuthority.cva("min-w-0",{variants:{orientation:{vertical:"pb-6",horizontal:"pt-3 pr-6"}},defaultVariants:{orientation:"vertical"}});var K="bg-[var(--primary-action)]",_e="block text-xs text-[var(--muted-foreground)]",Me="mt-0.5 text-base font-bold text-[var(--content-foreground)]",Be="mt-1 text-sm text-[var(--muted-foreground)]",ke="relative isolate block rounded-md text-[var(--content-foreground)] no-underline cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2 [scroll-margin:1rem]",ct="pointer-events-none absolute -inset-2 -z-10 rounded-md transition-colors group-hover/tl-item:bg-[var(--muted)] group-focus-within/tl-item:bg-[var(--muted)]",mt="transition-colors group-hover/tl-item:bg-[var(--primary-action)] group-focus-within/tl-item:bg-[var(--primary-action)]",dt="transition-transform group-hover/tl-item:scale-110 group-focus-within/tl-item:scale-110";function ut({id:n,date:a,label:d,dateFormatOptions:u,title:o,description:i,children:c,icon:M,href:g,target:E,rel:V,onPress:p,className:B,"aria-label":k,"aria-labelledby":R,"aria-describedby":T,"data-testid":P}){let{orientation:f,marker:s,locale:w,dateFormatter:N,formatDate:z,titleHeadingLevel:y,registerItem:S}=le();process.env.NODE_ENV!=="production"&&c!=null&&(o!=null||i!=null)&&console.warn("Timeline.Item: `children` supersedes `title`/`description` \u2014 pass one or the other.");let h=react.useMemo(()=>u?new Intl.DateTimeFormat(w,u):N,[u,w,N]),v=react.useMemo(()=>a!=null?new Date(a):null,[a]),L=v!=null&&!Number.isNaN(v.getTime()),x=react.useCallback(r=>{n!==void 0&&S(n,r);},[n,S]),A=L?jsxRuntime.jsx("time",{dateTime:v.toISOString(),className:_e,children:z?z(v):h.format(v)}):d!=null?jsxRuntime.jsx("span",{className:_e,children:d}):null,m=g!=null||p!=null,W=y==="p"?"p":y,X=o==null?null:m?jsxRuntime.jsx("span",{className:l("block",Me),children:o}):jsxRuntime.jsx(W,{className:Me,children:o}),I=i==null?null:m?jsxRuntime.jsx("span",{className:l("block",Be),children:i}):jsxRuntime.jsx("p",{className:Be,children:i}),D=jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[A,c??jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[X,I]})]}),G;if(s==="basic")G=f==="vertical"?jsxRuntime.jsxs("div",{className:"relative w-2 self-stretch","aria-hidden":"true",children:[jsxRuntime.jsx("span",{"data-timeline-connector":true,className:l("absolute inset-y-0 left-0 w-0.5",K)}),jsxRuntime.jsx("span",{className:l("absolute left-0 top-2 h-0.5 w-3",K)})]}):jsxRuntime.jsxs("div",{className:"relative h-2 w-full","aria-hidden":"true",children:[jsxRuntime.jsx("span",{"data-timeline-connector":true,className:l("absolute inset-x-0 top-0 h-0.5",K)}),jsxRuntime.jsx("span",{className:l("absolute left-0 top-0 h-3 w-0.5",K)})]});else {let r=s==="dot"&&f==="vertical"?"mt-0.5":"",O=m?s==="dot"?mt:dt:"",ee=jsxRuntime.jsx("span",{className:l(de({marker:s}),r,O),children:s==="icon"?M:null}),xe=jsxRuntime.jsx("span",{"data-timeline-connector":true,className:ue({orientation:f})});G=f==="vertical"?jsxRuntime.jsxs("div",{className:"flex flex-col items-center self-stretch","aria-hidden":"true",children:[ee,xe]}):jsxRuntime.jsxs("div",{className:"flex w-full items-center","aria-hidden":"true",children:[ee,xe]});}let F=pe({orientation:f}),U=jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("span",{"aria-hidden":"true",className:ct}),D]}),H;return g!=null?H=jsxRuntime.jsx("div",{className:F,children:jsxRuntime.jsx(reactAriaComponents.Link,{ref:x,href:g,target:E,rel:V,className:ke,"aria-label":k,"aria-labelledby":R,"aria-describedby":T,children:U})}):p!=null?H=jsxRuntime.jsx("div",{className:F,children:jsxRuntime.jsx(reactAriaComponents.Button,{ref:x,onPress:p,className:l(ke,"w-full text-left"),"aria-label":k,"aria-labelledby":R,"aria-describedby":T,children:U})}):H=jsxRuntime.jsx("div",{className:F,children:D}),jsxRuntime.jsxs("li",{ref:m?void 0:x,tabIndex:m?void 0:-1,className:l(me({orientation:f}),s!=="basic"&&"[&:last-child_[data-timeline-connector]]:hidden",s==="basic"&&f==="vertical"&&"[&:first-child_[data-timeline-connector]]:top-2",m&&"group/tl-item rounded-md outline-none",B),"data-testid":P,children:[G,H]})}var Z=react.memo(ut);Z.displayName="Timeline.Item";var xt={year:"numeric",month:"long"},Pe=react.forwardRef(function({children:a,orientation:d="vertical",marker:u="dot",locale:o,dateFormatOptions:i,formatDate:c,titleHeadingLevel:M="p",collapseBelow:g=640,onLoadMore:E,hasMore:V=false,isLoadingMore:p=false,loadMoreLabel:B="Show more",emptyState:k,landmarkLabel:R,className:T,id:P,"aria-label":f,"aria-labelledby":s,"aria-describedby":w,"data-testid":N="timeline"},z){let y=react.useRef(null),S=react.useRef(null),h=react.useRef(new Map),v=He(),L=we(y,g===false?0:g),x=d==="horizontal"&&L?"vertical":d,A=react.useCallback(r=>{r?.scrollIntoView({behavior:v?"auto":"smooth",block:"nearest",inline:"nearest"});},[v]),m=react.useCallback((r,O)=>{O?h.current.set(r,O):h.current.delete(r);},[]);react.useImperativeHandle(z,()=>({scrollToItem:r=>A(h.current.get(r)),focusItem:r=>h.current.get(r)?.focus()}),[A]);let W=react.useMemo(()=>new Intl.DateTimeFormat(o,i??xt),[o,i]),X=react.useMemo(()=>({orientation:x,marker:u,locale:o,dateFormatter:W,formatDate:c,dateFormatOptions:i,titleHeadingLevel:M,reducedMotion:v,registerItem:m}),[x,u,o,W,c,i,M,v,m]),I=react.useMemo(()=>react.Children.toArray(a).filter(react.isValidElement).length,[a]),he=I===0,D=react.useRef(null),[G,F]=react.useState(""),U=react.useCallback(()=>{D.current=I,E?.();},[I,E]);if(react.useEffect(()=>{let r=D.current;if(!(r==null||I<=r)){if(!V){let O=S.current?.children[r];(O?.querySelector("a, button")??O)?.focus();}F(`Showing ${I} items`),D.current=null;}},[I,V]),he)return jsxRuntime.jsx("div",{ref:y,id:P,className:T,"data-testid":N,children:k??null});let H=jsxRuntime.jsx("ol",{ref:S,className:ce({orientation:x}),"aria-label":f,"aria-labelledby":s,"aria-describedby":w,tabIndex:x==="horizontal"?0:void 0,children:a});return jsxRuntime.jsx(se.Provider,{value:X,children:jsxRuntime.jsxs("div",{ref:y,id:P,className:l("w-full",T),"data-testid":N,children:[R!=null?jsxRuntime.jsx("nav",{"aria-label":R,children:H}):H,V&&jsxRuntime.jsx("div",{className:"mt-2 flex justify-center",children:jsxRuntime.jsx(Q,{variant:"outline",onPress:U,loading:p,loadingText:"Loading\u2026","data-testid":`${N}-load-more`,children:B})}),jsxRuntime.jsx("div",{role:"status","aria-live":"polite","aria-atomic":"true",className:"sr-only",children:G})]})})});Pe.displayName="Timeline";var Tt=Object.assign(Pe,{Item:Z});var ge=zod.z.object({className:zod.z.string().optional(),children:zod.z.any().optional(),id:zod.z.string().optional(),"aria-label":zod.z.string().optional(),"aria-labelledby":zod.z.string().optional(),"aria-describedby":zod.z.string().optional(),"aria-live":zod.z.enum(["off","polite","assertive"]).optional(),"aria-hidden":zod.z.boolean().optional(),"data-testid":zod.z.string().optional()});var ze=zod.z.enum(["vertical","horizontal"]),De=zod.z.enum(["dot","basic","icon"]),Ae=zod.z.enum(["h2","h3","h4","h5","h6","p"]),yt=ge.extend({children:zod.z.custom().optional(),orientation:ze.optional().default("vertical"),marker:De.optional().default("dot"),locale:zod.z.string().optional(),dateFormatOptions:zod.z.custom().optional(),formatDate:zod.z.custom().optional(),titleHeadingLevel:Ae.optional().default("p"),collapseBelow:zod.z.union([zod.z.number(),zod.z.literal(false)]).optional().default(640),onLoadMore:zod.z.custom().optional(),hasMore:zod.z.boolean().optional().default(false),isLoadingMore:zod.z.boolean().optional().default(false),loadMoreLabel:zod.z.string().optional(),emptyState:zod.z.custom().optional(),landmarkLabel:zod.z.string().optional()}),St=ge.extend({id:zod.z.string().optional(),date:zod.z.custom().optional(),label:zod.z.custom().optional(),dateFormatOptions:zod.z.custom().optional(),title:zod.z.custom().optional(),description:zod.z.custom().optional(),children:zod.z.custom().optional(),icon:zod.z.custom().optional(),href:zod.z.string().optional(),target:zod.z.string().optional(),rel:zod.z.string().optional(),onPress:zod.z.custom().optional()});exports.Timeline=Tt;exports.TimelineHeadingLevelSchema=Ae;exports.TimelineItem=Z;exports.TimelineItemPropsSchema=St;exports.TimelineMarkerSchema=De;exports.TimelineOrientationSchema=ze;exports.TimelinePropsSchema=yt;exports.timelineConnectorVariants=ue;exports.timelineContentVariants=pe;exports.timelineItemVariants=me;exports.timelineMarkerVariants=de;exports.timelineVariants=ce;exports.useTimelineContext=le;//# sourceMappingURL=index.js.map
|
|
3
|
+
//# sourceMappingURL=index.js.map
|