@creativecreate/react-footnotes 1.0.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/README.md +426 -0
- package/dist/index.d.mts +155 -0
- package/dist/index.d.ts +155 -0
- package/dist/index.js +285 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +277 -0
- package/dist/index.mjs.map +1 -0
- package/footnotes.css +106 -0
- package/messages.json +11 -0
- package/package.json +38 -0
package/README.md
ADDED
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
# @creativecreate/react-footnotes
|
|
2
|
+
|
|
3
|
+
A React component library for managing footnotes with citation and special symbol support.
|
|
4
|
+
|
|
5
|
+
Maintaining footnotes with proper numbering across different components and pages can be challenging — you need to manually track footnote order, handle duplicates, manage navigation between references and content, and ensure consistency throughout your application. Additionally, maintaining footnote content becomes difficult when footnotes are scattered across multiple files, making it hard to update or manage them centrally. This package tackles these challenges by providing a context-aware, automatic numbering system that handles everything for you. Use footnotes freely across any component without worrying about order or duplicates; the library automatically coordinates numbering, detects duplicates, and provides smart bidirectional navigation. With flexible content management through a centralized messages file, callback functions, or inline children, you can easily maintain and update footnote content regardless of where your components are located.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- 📝 Support for both citation (numbered) and special (symbol) footnotes
|
|
10
|
+
- 🔄 Context-aware coordination and auto numbering: use footnotes freely across different components without manually tracking the order — the library handles everything automatically
|
|
11
|
+
- 🔁 Smart duplicate detection: multiple references to the same footnote automatically share the same number, preventing duplicate entries
|
|
12
|
+
- 🔗 Smart bidirectional navigation: navigate between footnote references and content, with intelligent tracking that traces back to the current reference location even when duplicate references exist
|
|
13
|
+
- 🎯 Flexible content sources: provide footnote content via messages file, callback function (`getContent`), or inline children — choose the approach that fits your needs
|
|
14
|
+
- 🌐 Framework-agnostic: Compatible with Next.js App Router, Remix, Vite, and other React frameworks
|
|
15
|
+
- ♿ Web accessibility compatible: built with ARIA attributes, semantic HTML, keyboard navigation support, and screen reader compatibility following WAI-ARIA best practices
|
|
16
|
+
- 🎨 Fully customizable with custom CSS to match your design style, with built-in responsive design support for all device sizes
|
|
17
|
+
- 📦 TypeScript support
|
|
18
|
+
- 🔄 Route-aware footnote reset for SPA navigation
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install @creativecreate/react-footnotes
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Basic Usage
|
|
27
|
+
|
|
28
|
+
### 1. Create your messages file
|
|
29
|
+
|
|
30
|
+
The package includes a `messages.json` file as a **guideline/template**. You should copy it to your project (e.g., to your `src` directory) and customize it with your own footnote content. You cannot import it directly from the package module.
|
|
31
|
+
|
|
32
|
+
**Step 1:** Copy `messages.json` from the package to your project (e.g., `src/messages.json`)
|
|
33
|
+
|
|
34
|
+
**Step 2:** Customize it with your footnote content:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"footnotes": {
|
|
39
|
+
"citation": {
|
|
40
|
+
"smith-2023-study": "Smith, J., et al. 'Climate Change Impacts on Agriculture.' Nature Climate Change, vol. 13, no. 4, 2023, pp. 245-260.",
|
|
41
|
+
"who-guidelines": "World Health Organization. 'Air Quality Guidelines: Global Update 2021.' WHO Press, 2021.",
|
|
42
|
+
"johnson-research": "Johnson, M. 'Sustainable Energy Solutions.' Renewable Energy Journal, vol. 45, 2023, pp. 112-128."
|
|
43
|
+
},
|
|
44
|
+
"special": {
|
|
45
|
+
"editor-note": "Editor's note: This data was updated on March 15, 2024 to reflect the latest findings.",
|
|
46
|
+
"methodology-note": "Methodology: Survey conducted across 50 countries with a sample size of 10,000 participants."
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Step 3:** Import it from your project:
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
import messagesData from './messages.json'; // Import from your project, not from the package
|
|
56
|
+
|
|
57
|
+
// Extract footnotes from the messages structure
|
|
58
|
+
const messages = messagesData.footnotes;
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### 2. Wrap your app with FootnoteProvider and provide messages
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
import { FootnoteProvider } from '@creativecreate/react-footnotes';
|
|
65
|
+
import messagesData from './messages.json'; // Your custom messages file from your project
|
|
66
|
+
|
|
67
|
+
// Extract footnotes from the messages structure
|
|
68
|
+
const messages = messagesData.footnotes;
|
|
69
|
+
|
|
70
|
+
function App() {
|
|
71
|
+
return (
|
|
72
|
+
<FootnoteProvider
|
|
73
|
+
messages={messages}
|
|
74
|
+
// Alternative: see section - using React router
|
|
75
|
+
pathname={`${window.location.pathname}${window.location.search}`}
|
|
76
|
+
>
|
|
77
|
+
{/* Your app content */}
|
|
78
|
+
</FootnoteProvider>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 3. Add footnote references in your content
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
import { Footnote } from '@creativecreate/react-footnotes';
|
|
87
|
+
|
|
88
|
+
function MyComponent() {
|
|
89
|
+
return (
|
|
90
|
+
<div>
|
|
91
|
+
<p>
|
|
92
|
+
Recent research has shown significant impacts of climate change on agricultural productivity<Footnote id="smith-2023-study" type="citation" />.
|
|
93
|
+
</p>
|
|
94
|
+
<p>
|
|
95
|
+
According to WHO guidelines<Footnote id="who-guidelines" type="citation" />, air quality standards have been updated<Footnote id="editor-note" type="special" />.
|
|
96
|
+
</p>
|
|
97
|
+
</div>
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### 4. Render the footnote list
|
|
103
|
+
|
|
104
|
+
```tsx
|
|
105
|
+
import { FootnoteList } from '@creativecreate/react-footnotes';
|
|
106
|
+
|
|
107
|
+
function Footer() {
|
|
108
|
+
return (
|
|
109
|
+
<footer>
|
|
110
|
+
{/* render footnote list */}
|
|
111
|
+
<FootnoteList />
|
|
112
|
+
</footer>
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Example output:**
|
|
118
|
+
|
|
119
|
+

|
|
120
|
+
|
|
121
|
+
## Advanced Usage
|
|
122
|
+
|
|
123
|
+
### Using getContent prop for dynamic footnotes
|
|
124
|
+
|
|
125
|
+
The `getContent` prop allows you to provide footnote content programmatically, overriding messages from the provider. This is useful for dynamic content or when you want to generate footnotes based on component state or props:
|
|
126
|
+
|
|
127
|
+
```tsx
|
|
128
|
+
import { Footnote } from '@creativecreate/react-footnotes';
|
|
129
|
+
import { useState, useEffect } from 'react';
|
|
130
|
+
|
|
131
|
+
function MyComponent() {
|
|
132
|
+
const [dynamicCitations, setDynamicCitations] = useState<{
|
|
133
|
+
citation?: { [key: string]: string };
|
|
134
|
+
special?: { [key: string]: string };
|
|
135
|
+
}>({});
|
|
136
|
+
|
|
137
|
+
useEffect(() => {
|
|
138
|
+
// Fetch citations asynchronously
|
|
139
|
+
fetchCitations().then(setDynamicCitations);
|
|
140
|
+
}, []);
|
|
141
|
+
|
|
142
|
+
// Custom function to generate footnote content
|
|
143
|
+
const getContent = (id: string, type: 'citation' | 'special') => {
|
|
144
|
+
if (type && id) {
|
|
145
|
+
return dynamicCitations[type]?.[id];
|
|
146
|
+
}
|
|
147
|
+
return null;
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
return (
|
|
151
|
+
<div>
|
|
152
|
+
<p>
|
|
153
|
+
This text has a dynamic footnote
|
|
154
|
+
<Footnote id="dynamic_citation_1" type="citation" getContent={getContent} />.
|
|
155
|
+
</p>
|
|
156
|
+
<p>
|
|
157
|
+
And another one
|
|
158
|
+
<Footnote id="dynamic_special_1" type="special" getContent={getContent} />.
|
|
159
|
+
</p>
|
|
160
|
+
</div>
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**When to use `getContent`:**
|
|
166
|
+
- When footnote content depends on component state or props
|
|
167
|
+
- When you need to fetch content from an API or external source
|
|
168
|
+
- When you want to override provider messages for specific footnotes
|
|
169
|
+
- When content needs to be computed dynamically
|
|
170
|
+
|
|
171
|
+
### Using children prop for inline footnote content
|
|
172
|
+
|
|
173
|
+
The `children` prop provides the highest priority for footnote content and allows you to pass content directly, including formatted text or React components:
|
|
174
|
+
|
|
175
|
+
```tsx
|
|
176
|
+
import { Footnote } from '@creativecreate/react-footnotes';
|
|
177
|
+
import {Link} from '~/components/Link';
|
|
178
|
+
|
|
179
|
+
function MyComponent() {
|
|
180
|
+
return (
|
|
181
|
+
<div>
|
|
182
|
+
<p>
|
|
183
|
+
You can also include formatted content
|
|
184
|
+
<Footnote id="inline-2" type="special">
|
|
185
|
+
<strong>Bold text</strong> and <em>italic text</em> work in children prop.
|
|
186
|
+
</Footnote>.
|
|
187
|
+
</p>
|
|
188
|
+
<p>
|
|
189
|
+
Or even React components
|
|
190
|
+
<Footnote id="inline-3" type="citation">
|
|
191
|
+
Visit <Link href="https://example.com">example.com</Link> for more info.
|
|
192
|
+
</Footnote>.
|
|
193
|
+
</p>
|
|
194
|
+
</div>
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
**When to use `children`:**
|
|
200
|
+
- When you want to provide footnote content directly inline
|
|
201
|
+
- When you need to include formatted text or React components
|
|
202
|
+
- When content is specific to a single footnote instance
|
|
203
|
+
- When you want the highest priority (overrides both `getContent` and messages)
|
|
204
|
+
|
|
205
|
+
**Priority order:**
|
|
206
|
+
1. `children` prop (highest priority)
|
|
207
|
+
2. `getContent` prop
|
|
208
|
+
3. Messages from `FootnoteProvider` (lowest priority)
|
|
209
|
+
|
|
210
|
+
### Customizing FootnoteList styling
|
|
211
|
+
|
|
212
|
+
```tsx
|
|
213
|
+
import { FootnoteList } from '@creativecreate/react-footnotes';
|
|
214
|
+
|
|
215
|
+
function MyPage() {
|
|
216
|
+
return (
|
|
217
|
+
<FootnoteList
|
|
218
|
+
className="my-custom-list-class" // Class for the <ol> wrapper
|
|
219
|
+
itemClassName="my-item-class" // Class for each <li> item
|
|
220
|
+
itemSupClassName="my-sup-class" // Class for the <sup> symbol in items
|
|
221
|
+
itemContentClassName="my-content-class" // Class for the content <span> in items
|
|
222
|
+
itemBackLinkClassName="my-back-link-class" // Class for the back link <button>
|
|
223
|
+
itemBackLinkIconClassName="my-icon-class" // Class for the back link icon <small>
|
|
224
|
+
order="citation-first" // Show citations before special footnotes
|
|
225
|
+
/>
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Customizing Footnote styling
|
|
231
|
+
|
|
232
|
+
```tsx
|
|
233
|
+
import { Footnote } from '@creativecreate/react-footnotes';
|
|
234
|
+
|
|
235
|
+
function MyComponent() {
|
|
236
|
+
return (
|
|
237
|
+
<div>
|
|
238
|
+
<p>
|
|
239
|
+
This text has a customized footnote
|
|
240
|
+
<Footnote
|
|
241
|
+
id="example1"
|
|
242
|
+
type="citation"
|
|
243
|
+
className="my-footnote-ref-class" // Class for the footnote reference <button>
|
|
244
|
+
supClassName="my-footnote-sup-class" // Class for the <sup> element
|
|
245
|
+
/>.
|
|
246
|
+
</p>
|
|
247
|
+
</div>
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Using with React Router
|
|
253
|
+
|
|
254
|
+
When using React Router, pass the `pathname` prop using `useLocation()` to enable automatic footnote reset on route changes:
|
|
255
|
+
|
|
256
|
+
```tsx
|
|
257
|
+
import { BrowserRouter, Routes, Route, useLocation } from 'react-router-dom';
|
|
258
|
+
import { FootnoteProvider } from '@creativecreate/react-footnotes';
|
|
259
|
+
|
|
260
|
+
function AppContent() {
|
|
261
|
+
const location = useLocation();
|
|
262
|
+
|
|
263
|
+
return (
|
|
264
|
+
<FootnoteProvider
|
|
265
|
+
messages={messages}
|
|
266
|
+
pathname={`${location.pathname}${location.search}`}
|
|
267
|
+
>
|
|
268
|
+
{/* Your routes */}
|
|
269
|
+
</FootnoteProvider>
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function App() {
|
|
274
|
+
return (
|
|
275
|
+
<BrowserRouter>
|
|
276
|
+
<AppContent />
|
|
277
|
+
</BrowserRouter>
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
**How it works:**
|
|
283
|
+
- The `pathname` prop tracks the current route
|
|
284
|
+
- When the route changes, footnotes are automatically reset and renumbered
|
|
285
|
+
- This ensures footnote numbering starts fresh on each page (1, 2, 3...)
|
|
286
|
+
- The `location.search` is included to handle query parameters
|
|
287
|
+
|
|
288
|
+
## API Reference
|
|
289
|
+
|
|
290
|
+
### FootnoteProvider
|
|
291
|
+
|
|
292
|
+
The context provider that manages footnote state.
|
|
293
|
+
|
|
294
|
+
**Props:**
|
|
295
|
+
- `children: ReactNode` - Your app content
|
|
296
|
+
- `messages?: FootnoteMessages` - Optional messages object containing footnote content
|
|
297
|
+
```tsx
|
|
298
|
+
{
|
|
299
|
+
citation?: { [id: string]: ReactNode },
|
|
300
|
+
special?: { [id: string]: ReactNode }
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
- `pathname: string` - **Required.** Current pathname string for route-based footnote reset. When the pathname changes, footnotes are automatically reset and renumbered.
|
|
304
|
+
- For React Router: `` `${location.pathname}${location.search}` ``
|
|
305
|
+
- For simple cases: `` `${window.location.pathname}${window.location.search}` ``
|
|
306
|
+
|
|
307
|
+
### Footnote
|
|
308
|
+
|
|
309
|
+
Component for rendering a footnote reference.
|
|
310
|
+
|
|
311
|
+
**Props:**
|
|
312
|
+
- `id: string` - Unique identifier for the footnote (must exist in messages)
|
|
313
|
+
- `type: 'citation' | 'special'` - Type of footnote (required)
|
|
314
|
+
- `getContent?: (id: string, type: 'citation' | 'special') => ReactNode` - Optional function to override messages
|
|
315
|
+
- `children?: ReactNode` - Optional direct content (overrides messages and getContent)
|
|
316
|
+
- `className?: string` - Optional className to override default styles (default: `'footnote-ref'`)
|
|
317
|
+
- `supClassName?: string` - Optional className for the `<sup>` element (default: `'footnote-symbol'`)
|
|
318
|
+
|
|
319
|
+
### FootnoteList
|
|
320
|
+
|
|
321
|
+
Component for rendering all registered footnotes.
|
|
322
|
+
|
|
323
|
+
**Props:**
|
|
324
|
+
- `className?: string` - ClassName for the ordered list (default: `'footnote-list'`)
|
|
325
|
+
- `itemClassName?: string` - Optional className for list items
|
|
326
|
+
- `itemSupClassName?: string` - Optional className for the `<sup>` element in items
|
|
327
|
+
- `itemContentClassName?: string` - Optional className for the content element in items
|
|
328
|
+
- `itemBackLinkClassName?: string` - Optional className for the back link button
|
|
329
|
+
- `itemBackLinkIconClassName?: string` - Optional className for the back link icon
|
|
330
|
+
- `order?: 'special-first' | 'citation-first'` - Order of footnotes (default: `'special-first'`)
|
|
331
|
+
- `'special-first'` - Special footnotes appear first, then citations
|
|
332
|
+
- `'citation-first'` - Citations appear first, then special footnotes
|
|
333
|
+
|
|
334
|
+
### FootnoteListItem
|
|
335
|
+
|
|
336
|
+
Component for rendering an individual footnote list item (used internally by FootnoteList).
|
|
337
|
+
|
|
338
|
+
**Props:**
|
|
339
|
+
- `id: string` - Unique identifier for the footnote
|
|
340
|
+
- `type?: 'citation' | 'special'` - Type of footnote
|
|
341
|
+
- `symbol: string` - The symbol or number to display
|
|
342
|
+
- `children?: ReactNode` - The footnote content
|
|
343
|
+
- `className?: string` - Optional className for the list item (default: `'footnote-list-item'`)
|
|
344
|
+
- `supClassName?: string` - Optional className for the `<sup>` element (default: `'footnote-list-item__symbol'`)
|
|
345
|
+
- `contentClassName?: string` - Optional className for the content (default: `'footnote-list-item__content'`)
|
|
346
|
+
- `backLinkClassName?: string` - Optional className for the back link button (default: `'footnote-list-item__back-link'`)
|
|
347
|
+
- `backLinkIconClassName?: string` - Optional className for the back link icon (default: `'footnote-list-item__back-link-icon'`)
|
|
348
|
+
|
|
349
|
+
### useFootnotes
|
|
350
|
+
|
|
351
|
+
Hook to access footnote context.
|
|
352
|
+
|
|
353
|
+
**Returns:**
|
|
354
|
+
- `registerFootnote: (footnote: FootnoteProps) => void` - Register a footnote
|
|
355
|
+
- `citationList: FootnoteProps[]` - List of citation footnotes
|
|
356
|
+
- `specialList: FootnoteProps[]` - List of special footnotes
|
|
357
|
+
- `clickHandler: (e: React.MouseEvent<HTMLButtonElement>) => void` - Click handler for navigation
|
|
358
|
+
- `getContent: (id: string, type: FootnotesCategory) => ReactNode | null` - Function to get content from messages
|
|
359
|
+
|
|
360
|
+
## Styling
|
|
361
|
+
|
|
362
|
+
The components use generic CSS class names that you can style with any CSS framework or custom CSS. The package doesn't require Tailwind CSS or any other specific styling library.
|
|
363
|
+
|
|
364
|
+
### Default Styles
|
|
365
|
+
|
|
366
|
+
Import the default stylesheet (optional):
|
|
367
|
+
|
|
368
|
+
```tsx
|
|
369
|
+
import '@creativecreate/react-footnotes/footnotes.css';
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
Or copy the styles from `footnotes.css` to your own CSS file.
|
|
373
|
+
|
|
374
|
+
### CSS Class Names
|
|
375
|
+
|
|
376
|
+
The package uses the following BEM-style class names that you can override:
|
|
377
|
+
|
|
378
|
+
- `.footnote-ref` - The footnote reference button (clickable superscript)
|
|
379
|
+
- `.footnote-symbol` - The symbol/number inside the reference button
|
|
380
|
+
- `.footnote-list` - The footnote list ordered list element
|
|
381
|
+
- `.footnote-list-item` - Individual footnote list item
|
|
382
|
+
- `.footnote-list-item__symbol` - The symbol in the list item
|
|
383
|
+
- `.footnote-list-item__content` - The footnote content
|
|
384
|
+
- `.footnote-list-item__back-link` - The "back to reference" button
|
|
385
|
+
- `.footnote-list-item__back-link-icon` - The back link icon
|
|
386
|
+
|
|
387
|
+
### Customizing Styles
|
|
388
|
+
|
|
389
|
+
You can customize styles in several ways:
|
|
390
|
+
|
|
391
|
+
1. **Override with your own CSS:**
|
|
392
|
+
```css
|
|
393
|
+
.footnote-ref {
|
|
394
|
+
color: #your-color;
|
|
395
|
+
margin-left: 0.5rem;
|
|
396
|
+
}
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
2. **Use className props:**
|
|
400
|
+
```tsx
|
|
401
|
+
<Footnote
|
|
402
|
+
id="smith-2023-study"
|
|
403
|
+
type="citation"
|
|
404
|
+
className="my-custom-class"
|
|
405
|
+
supClassName="my-sup-class"
|
|
406
|
+
/>
|
|
407
|
+
<FootnoteList
|
|
408
|
+
className="my-list-class"
|
|
409
|
+
itemClassName="my-item-class"
|
|
410
|
+
order="citation-first"
|
|
411
|
+
/>
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
3. **Use CSS modules or styled-components:**
|
|
415
|
+
```tsx
|
|
416
|
+
import styles from './footnotes.module.css';
|
|
417
|
+
<Footnote id="smith-2023-study" type="citation" className={styles.footnote} />
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
## TypeScript
|
|
421
|
+
|
|
422
|
+
The package is written in TypeScript and includes type definitions. All types are exported from the main entry point.
|
|
423
|
+
|
|
424
|
+
## License
|
|
425
|
+
|
|
426
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
type FootnotesCategory = 'citation' | 'special';
|
|
5
|
+
type FootnoteKeys = string;
|
|
6
|
+
type FootnoteProps = {
|
|
7
|
+
id: FootnoteKeys;
|
|
8
|
+
type?: FootnotesCategory;
|
|
9
|
+
children?: ReactNode;
|
|
10
|
+
};
|
|
11
|
+
type FootnoteMessages = {
|
|
12
|
+
citation?: Record<string, ReactNode>;
|
|
13
|
+
special?: Record<string, ReactNode>;
|
|
14
|
+
};
|
|
15
|
+
type FootnoteContextType = {
|
|
16
|
+
registerFootnote: (footnote: FootnoteProps) => void;
|
|
17
|
+
citationList: FootnoteProps[];
|
|
18
|
+
specialList: FootnoteProps[];
|
|
19
|
+
clickHandler: (e: React.MouseEvent<HTMLButtonElement>) => void;
|
|
20
|
+
getContent: (id: string, type: FootnotesCategory) => ReactNode | null;
|
|
21
|
+
};
|
|
22
|
+
declare const splitFootnotes: (footnotes: FootnoteProps[]) => {
|
|
23
|
+
specialList: FootnoteProps[];
|
|
24
|
+
citationList: FootnoteProps[];
|
|
25
|
+
};
|
|
26
|
+
declare const getSpecialChar: (footnoteList: FootnoteProps[], id: FootnoteKeys) => string;
|
|
27
|
+
|
|
28
|
+
type FootnoteProviderProps = {
|
|
29
|
+
children: ReactNode;
|
|
30
|
+
/**
|
|
31
|
+
* Messages object containing footnote content.
|
|
32
|
+
* Structure: { citation: { id: content }, special: { id: content } }
|
|
33
|
+
*/
|
|
34
|
+
messages?: FootnoteMessages;
|
|
35
|
+
/**
|
|
36
|
+
* Current pathname string for route-based footnote reset.
|
|
37
|
+
* For React Router: `\`${location.pathname}${location.search}\``
|
|
38
|
+
* For simple cases: `\`${window.location.pathname}${window.location.search}\``
|
|
39
|
+
*/
|
|
40
|
+
pathname: string;
|
|
41
|
+
};
|
|
42
|
+
declare const FootnoteProvider: ({ children, messages, pathname, }: FootnoteProviderProps) => react_jsx_runtime.JSX.Element;
|
|
43
|
+
declare const useFootnotes: () => FootnoteContextType;
|
|
44
|
+
|
|
45
|
+
type FootnoteListProps = {
|
|
46
|
+
className?: string;
|
|
47
|
+
/**
|
|
48
|
+
* Optional className for the list item
|
|
49
|
+
*/
|
|
50
|
+
itemClassName?: string;
|
|
51
|
+
/**
|
|
52
|
+
* Optional className for the <sup> element
|
|
53
|
+
*/
|
|
54
|
+
itemSupClassName?: string;
|
|
55
|
+
/**
|
|
56
|
+
* Optional className for the content element
|
|
57
|
+
*/
|
|
58
|
+
itemContentClassName?: string;
|
|
59
|
+
/**
|
|
60
|
+
* Optional className for the back link button
|
|
61
|
+
*/
|
|
62
|
+
itemBackLinkClassName?: string;
|
|
63
|
+
/**
|
|
64
|
+
* Optional className for the back link icon
|
|
65
|
+
*/
|
|
66
|
+
itemBackLinkIconClassName?: string;
|
|
67
|
+
/**
|
|
68
|
+
* Order of footnotes in the list
|
|
69
|
+
* @default 'special-first' - Special footnotes appear first, then citations
|
|
70
|
+
* 'citation-first' - Citations appear first, then special footnotes
|
|
71
|
+
*/
|
|
72
|
+
order?: 'special-first' | 'citation-first';
|
|
73
|
+
};
|
|
74
|
+
declare const FootnoteList: ({ className, itemClassName, itemSupClassName, itemContentClassName, itemBackLinkClassName, itemBackLinkIconClassName, order, }: FootnoteListProps) => react_jsx_runtime.JSX.Element | null;
|
|
75
|
+
|
|
76
|
+
interface FootnoteListItemProps {
|
|
77
|
+
id: FootnoteKeys;
|
|
78
|
+
type?: 'citation' | 'special';
|
|
79
|
+
symbol: string;
|
|
80
|
+
children?: React.ReactNode;
|
|
81
|
+
/**
|
|
82
|
+
* Optional className to override default styles
|
|
83
|
+
*/
|
|
84
|
+
className?: string;
|
|
85
|
+
/**
|
|
86
|
+
* Optional className for the <sup> element
|
|
87
|
+
*/
|
|
88
|
+
supClassName?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Optional className for the content element
|
|
91
|
+
*/
|
|
92
|
+
contentClassName?: string;
|
|
93
|
+
/**
|
|
94
|
+
* Optional className for the back link button
|
|
95
|
+
*/
|
|
96
|
+
backLinkClassName?: string;
|
|
97
|
+
/**
|
|
98
|
+
* Optional className for the back link icon
|
|
99
|
+
*/
|
|
100
|
+
backLinkIconClassName?: string;
|
|
101
|
+
}
|
|
102
|
+
declare const FootnoteListItem: ({ id, children, symbol, className, supClassName, contentClassName, backLinkClassName, backLinkIconClassName, }: FootnoteListItemProps) => react_jsx_runtime.JSX.Element;
|
|
103
|
+
|
|
104
|
+
type FootnoteComponentProps = {
|
|
105
|
+
id: FootnoteKeys;
|
|
106
|
+
/**
|
|
107
|
+
* Type of footnote: 'citation' or 'special'
|
|
108
|
+
* Required when using messages from FootnoteProvider
|
|
109
|
+
*/
|
|
110
|
+
type: FootnotesCategory;
|
|
111
|
+
/**
|
|
112
|
+
* Optional function to get footnote content.
|
|
113
|
+
* If provided, will override messages from FootnoteProvider.
|
|
114
|
+
* Should return the content for the footnote with the given id and type.
|
|
115
|
+
*/
|
|
116
|
+
getContent?: (id: string, type: FootnotesCategory) => React.ReactNode;
|
|
117
|
+
/**
|
|
118
|
+
* Optional children to use as footnote content.
|
|
119
|
+
* If provided, will be used instead of getContent or messages.
|
|
120
|
+
*/
|
|
121
|
+
children?: React.ReactNode;
|
|
122
|
+
/**
|
|
123
|
+
* Optional className to override default styles
|
|
124
|
+
*/
|
|
125
|
+
className?: string;
|
|
126
|
+
/**
|
|
127
|
+
* Optional className for the <sup> element
|
|
128
|
+
*/
|
|
129
|
+
supClassName?: string;
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Footnote component - renders an inline footnote reference.
|
|
134
|
+
*
|
|
135
|
+
* Priority for content:
|
|
136
|
+
* 1. If `children` is provided, it will be used for the footnote content (highest priority).
|
|
137
|
+
* 2. If `getContent` prop is passed, it is called with `id` and `type` and its result is used.
|
|
138
|
+
* 3. Otherwise, content is fetched from messages via FootnoteProvider context (`getContentFromContext`).
|
|
139
|
+
*
|
|
140
|
+
* Registers itself in the footnote context via `registerFootnote` when content exists.
|
|
141
|
+
*
|
|
142
|
+
* Displays a symbol (number for 'citation', special character for 'special').
|
|
143
|
+
* Clicking the reference will navigate to its corresponding item in the FootnoteList.
|
|
144
|
+
*
|
|
145
|
+
* Props:
|
|
146
|
+
* - id: Unique id for the footnote
|
|
147
|
+
* - type: "citation" | "special"
|
|
148
|
+
* - getContent?: (id, type) => content (overrides messages)
|
|
149
|
+
* - children?: ReactNode (overrides everything, highest priority)
|
|
150
|
+
* - className?: class for the button/footnote ref
|
|
151
|
+
* - supClassName?: class for the <sup> element
|
|
152
|
+
*/
|
|
153
|
+
declare const Footnote: ({ id, type, getContent, children, className, supClassName, }: FootnoteComponentProps) => react_jsx_runtime.JSX.Element | null;
|
|
154
|
+
|
|
155
|
+
export { Footnote, type FootnoteKeys, FootnoteList, FootnoteListItem, type FootnoteMessages, type FootnoteProps, FootnoteProvider, type FootnotesCategory, getSpecialChar, splitFootnotes, useFootnotes };
|