eidotter 0.20.1 → 0.21.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.
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import type { TimelineEntryData, ZoomLevel } from './types';
2
+ import type { TimelineEntryData, TimelineRenderEntry, ZoomLevel } from './types';
3
3
  import './TimelineContainer.css';
4
4
  import './views/views.css';
5
5
  export interface TimelineContainerProps extends React.HTMLAttributes<HTMLDivElement> {
@@ -8,10 +8,13 @@ export interface TimelineContainerProps extends React.HTMLAttributes<HTMLDivElem
8
8
  /**
9
9
  * Display mode
10
10
  * - "interactive" (default): zoom controls, selection, keyboard shortcuts
11
- * - "static": read-only vertical feed of expandable entries (replaces TimelineList)
11
+ * - "static": read-only vertical feed of always-expanded entries (replaces TimelineList)
12
+ * - "feed": paginated vertical list with collapsed-by-default entries that
13
+ * expand on selection. Renders a DOS-style "LOAD MORE..." button while
14
+ * more entries are available. No zoom controls.
12
15
  * @default 'interactive'
13
16
  */
14
- mode?: 'interactive' | 'static';
17
+ mode?: 'interactive' | 'static' | 'feed';
15
18
  /**
16
19
  * Controlled zoom level — overrides internal state when provided.
17
20
  * Use with `onZoomChange` for full control. Disables drill-down navigation.
@@ -51,6 +54,27 @@ export interface TimelineContainerProps extends React.HTMLAttributes<HTMLDivElem
51
54
  * @default true
52
55
  */
53
56
  keyboardShortcuts?: boolean;
57
+ /**
58
+ * Pluggable entry renderer. When provided, this is called for every entry
59
+ * in every zoom-level view (and in static / feed modes) instead of rendering
60
+ * the built-in `TimelineEntryCard`. Return `context.defaultRender()` to keep
61
+ * the default card for some entries while customising others.
62
+ *
63
+ * Use this to render different card UIs per entry type — blog posts,
64
+ * photos, financial records, etc.
65
+ */
66
+ renderEntry?: TimelineRenderEntry;
67
+ /**
68
+ * Number of entries to show per page in feed mode. Ignored for other modes.
69
+ * @default 10
70
+ */
71
+ pageSize?: number;
72
+ /**
73
+ * Fired in feed mode after the user clicks "LOAD MORE…", with the new total
74
+ * number of visible entries. Use this to fetch the next batch from a backend
75
+ * and append to `entries`, or for analytics.
76
+ */
77
+ onLoadMore?: (visibleCount: number) => void;
54
78
  }
55
79
  /**
56
80
  * TimelineContainer - Interactive multi-level zoom timeline
@@ -1,11 +1,12 @@
1
1
  import React from 'react';
2
- import type { ZoomLevel, DateBucket } from './types';
2
+ import type { ZoomLevel, DateBucket, TimelineRenderEntry } from './types';
3
3
  export interface TimelineContentProps {
4
4
  zoomLevel: ZoomLevel;
5
5
  buckets: readonly DateBucket[];
6
6
  selectedEntryId: string | null;
7
7
  onEntrySelect?: (entryId: string) => void;
8
8
  onBucketClick?: (bucket: DateBucket) => void;
9
+ renderEntry?: TimelineRenderEntry;
9
10
  }
10
11
  /**
11
12
  * View switcher that renders the appropriate zoom level view.
@@ -1,5 +1,5 @@
1
1
  export { TimelineContainer } from './TimelineContainer';
2
2
  export type { TimelineContainerProps } from './TimelineContainer';
3
3
  export { ZOOM_LEVELS } from './types';
4
- export type { TimelineEntry, TimelineEntryData, DateBucket, ZoomLevel } from './types';
4
+ export type { TimelineEntry, TimelineEntryData, TimelineEntryRenderContext, TimelineRenderEntry, DateBucket, ZoomLevel, } from './types';
5
5
  export type { DrillDownEntry, UseDrillDownReturn } from './useDrillDown';
@@ -27,6 +27,24 @@ export interface TimelineEntryData {
27
27
  * @deprecated Use TimelineEntryData instead.
28
28
  */
29
29
  export type TimelineEntry = TimelineEntryData;
30
+ /**
31
+ * Context passed to a `renderEntry` function so consumers can decide how
32
+ * to render their custom entry, while still being able to fall back to
33
+ * the built-in `TimelineEntryCard` rendering when needed.
34
+ */
35
+ export interface TimelineEntryRenderContext {
36
+ /** True when this entry is currently expanded (its content is visible). */
37
+ isExpanded: boolean;
38
+ /** True when this entry is the currently selected entry. */
39
+ isSelected: boolean;
40
+ /** Render the built-in `TimelineEntryCard` for this entry. */
41
+ defaultRender: () => ReactNode;
42
+ }
43
+ /**
44
+ * Pluggable entry renderer. Return `defaultRender()` to delegate back to the
45
+ * built-in card, or any custom ReactNode to take over the entry slot.
46
+ */
47
+ export type TimelineRenderEntry = (entry: TimelineEntryData, context: TimelineEntryRenderContext) => ReactNode;
30
48
  export interface DateBucket {
31
49
  /** Human-readable label, e.g. "2024", "March 2024", "Mar 15" */
32
50
  label: string;
@@ -45,4 +63,6 @@ export interface TimelineViewProps {
45
63
  selectedEntryId?: string | null;
46
64
  /** Callback when a bucket header is clicked (for drill-down) */
47
65
  onBucketClick?: (bucket: DateBucket) => void;
66
+ /** Optional pluggable entry renderer */
67
+ renderEntry?: TimelineRenderEntry;
48
68
  }
@@ -1,3 +1,3 @@
1
1
  export { TimelineContainer } from './components';
2
- export type { TimelineContainerProps, TimelineEntry, TimelineEntryData, DateBucket, ZoomLevel } from './components';
2
+ export type { TimelineContainerProps, TimelineEntry, TimelineEntryData, TimelineEntryRenderContext, TimelineRenderEntry, DateBucket, ZoomLevel, } from './components';
3
3
  export { ZOOM_LEVELS } from './components';