@curvenote/theme-ui 1.0.1
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/dist/components/index.d.ts +4 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +3 -0
- package/dist/components/layout/app-layout.d.ts +8 -0
- package/dist/components/layout/app-layout.d.ts.map +1 -0
- package/dist/components/layout/app-layout.js +24 -0
- package/dist/components/layout/app-sidebar.d.ts +2 -0
- package/dist/components/layout/app-sidebar.d.ts.map +1 -0
- package/dist/components/layout/app-sidebar.js +125 -0
- package/dist/components/layout/article-layout.d.ts +8 -0
- package/dist/components/layout/article-layout.d.ts.map +1 -0
- package/dist/components/layout/article-layout.js +20 -0
- package/dist/components/layout/grid.d.ts +2 -0
- package/dist/components/layout/grid.d.ts.map +1 -0
- package/dist/components/layout/grid.js +4 -0
- package/dist/components/layout/header.d.ts +5 -0
- package/dist/components/layout/header.d.ts.map +1 -0
- package/dist/components/layout/header.js +5 -0
- package/dist/components/layout/index.d.ts +7 -0
- package/dist/components/layout/index.d.ts.map +1 -0
- package/dist/components/layout/index.js +7 -0
- package/dist/components/layout/loading-bar.d.ts +12 -0
- package/dist/components/layout/loading-bar.d.ts.map +1 -0
- package/dist/components/layout/loading-bar.js +53 -0
- package/dist/components/layout/site-header.d.ts +8 -0
- package/dist/components/layout/site-header.d.ts.map +1 -0
- package/dist/components/layout/site-header.js +55 -0
- package/dist/components/layout/types.d.ts +6 -0
- package/dist/components/layout/types.d.ts.map +1 -0
- package/dist/components/layout/types.js +1 -0
- package/dist/components/providers/compute.d.ts +5 -0
- package/dist/components/providers/compute.d.ts.map +1 -0
- package/dist/components/providers/compute.js +6 -0
- package/dist/components/providers/connect.d.ts +24 -0
- package/dist/components/providers/connect.d.ts.map +1 -0
- package/dist/components/providers/connect.js +208 -0
- package/dist/components/providers/curvenote-providers.d.ts +52 -0
- package/dist/components/providers/curvenote-providers.d.ts.map +1 -0
- package/dist/components/providers/curvenote-providers.js +199 -0
- package/dist/components/providers/design.d.ts +39 -0
- package/dist/components/providers/design.d.ts.map +1 -0
- package/dist/components/providers/design.js +50 -0
- package/dist/components/providers/index.d.ts +10 -0
- package/dist/components/providers/index.d.ts.map +1 -0
- package/dist/components/providers/index.js +12 -0
- package/dist/components/providers/lightbox-provider.d.ts +31 -0
- package/dist/components/providers/lightbox-provider.d.ts.map +1 -0
- package/dist/components/providers/lightbox-provider.js +109 -0
- package/dist/components/providers/myst-providers.d.ts +6 -0
- package/dist/components/providers/myst-providers.d.ts.map +1 -0
- package/dist/components/providers/myst-providers.js +29 -0
- package/dist/components/providers/page-providers.d.ts +15 -0
- package/dist/components/providers/page-providers.d.ts.map +1 -0
- package/dist/components/providers/page-providers.js +28 -0
- package/dist/components/providers/ping-boundary.d.ts +40 -0
- package/dist/components/providers/ping-boundary.d.ts.map +1 -0
- package/dist/components/providers/ping-boundary.js +115 -0
- package/dist/components/providers/platform-providers.d.ts +18 -0
- package/dist/components/providers/platform-providers.d.ts.map +1 -0
- package/dist/components/providers/platform-providers.js +29 -0
- package/dist/components/providers/types.d.ts +30 -0
- package/dist/components/providers/types.d.ts.map +1 -0
- package/dist/components/providers/types.js +1 -0
- package/dist/components/ui/Callout.d.ts +10 -0
- package/dist/components/ui/Callout.d.ts.map +1 -0
- package/dist/components/ui/Callout.js +7 -0
- package/dist/components/ui/PageCards.d.ts +2 -0
- package/dist/components/ui/PageCards.d.ts.map +1 -0
- package/dist/components/ui/PageCards.js +11 -0
- package/dist/components/ui/abbreviations.d.ts +5 -0
- package/dist/components/ui/abbreviations.d.ts.map +1 -0
- package/dist/components/ui/abbreviations.js +31 -0
- package/dist/components/ui/abstract.d.ts +8 -0
- package/dist/components/ui/abstract.d.ts.map +1 -0
- package/dist/components/ui/abstract.js +9 -0
- package/dist/components/ui/accessibility-skip-to.d.ts +15 -0
- package/dist/components/ui/accessibility-skip-to.d.ts.map +1 -0
- package/dist/components/ui/accessibility-skip-to.js +31 -0
- package/dist/components/ui/acknowledgements.d.ts +4 -0
- package/dist/components/ui/acknowledgements.d.ts.map +1 -0
- package/dist/components/ui/acknowledgements.js +20 -0
- package/dist/components/ui/article-actions-downloads.d.ts +26 -0
- package/dist/components/ui/article-actions-downloads.d.ts.map +1 -0
- package/dist/components/ui/article-actions-downloads.js +143 -0
- package/dist/components/ui/article-actions-dropdown.d.ts +5 -0
- package/dist/components/ui/article-actions-dropdown.d.ts.map +1 -0
- package/dist/components/ui/article-actions-dropdown.js +68 -0
- package/dist/components/ui/article-actions-share.d.ts +5 -0
- package/dist/components/ui/article-actions-share.d.ts.map +1 -0
- package/dist/components/ui/article-actions-share.js +52 -0
- package/dist/components/ui/article-actions.d.ts +2 -0
- package/dist/components/ui/article-actions.d.ts.map +1 -0
- package/dist/components/ui/article-actions.js +20 -0
- package/dist/components/ui/article-bar.d.ts +8 -0
- package/dist/components/ui/article-bar.d.ts.map +1 -0
- package/dist/components/ui/article-bar.js +32 -0
- package/dist/components/ui/article-card.d.ts +12 -0
- package/dist/components/ui/article-card.d.ts.map +1 -0
- package/dist/components/ui/article-card.js +22 -0
- package/dist/components/ui/article-footer.d.ts +2 -0
- package/dist/components/ui/article-footer.d.ts.map +1 -0
- package/dist/components/ui/article-footer.js +7 -0
- package/dist/components/ui/author-popover.d.ts +7 -0
- package/dist/components/ui/author-popover.d.ts.map +1 -0
- package/dist/components/ui/author-popover.js +36 -0
- package/dist/components/ui/backmatter.d.ts +9 -0
- package/dist/components/ui/backmatter.d.ts.map +1 -0
- package/dist/components/ui/backmatter.js +49 -0
- package/dist/components/ui/badge.d.ts +10 -0
- package/dist/components/ui/badge.d.ts.map +1 -0
- package/dist/components/ui/badge.js +23 -0
- package/dist/components/ui/banner.d.ts +7 -0
- package/dist/components/ui/banner.d.ts.map +1 -0
- package/dist/components/ui/banner.js +44 -0
- package/dist/components/ui/bibliography.d.ts +6 -0
- package/dist/components/ui/bibliography.d.ts.map +1 -0
- package/dist/components/ui/bibliography.js +20 -0
- package/dist/components/ui/breadcrumb.d.ts +12 -0
- package/dist/components/ui/breadcrumb.d.ts.map +1 -0
- package/dist/components/ui/breadcrumb.js +28 -0
- package/dist/components/ui/button.d.ts +11 -0
- package/dist/components/ui/button.d.ts.map +1 -0
- package/dist/components/ui/button.js +33 -0
- package/dist/components/ui/citation.d.ts +7 -0
- package/dist/components/ui/citation.d.ts.map +1 -0
- package/dist/components/ui/citation.js +99 -0
- package/dist/components/ui/collapsible.d.ts +6 -0
- package/dist/components/ui/collapsible.d.ts.map +1 -0
- package/dist/components/ui/collapsible.js +12 -0
- package/dist/components/ui/cookie-banner.d.ts +8 -0
- package/dist/components/ui/cookie-banner.d.ts.map +1 -0
- package/dist/components/ui/cookie-banner.js +31 -0
- package/dist/components/ui/data-availability.d.ts +4 -0
- package/dist/components/ui/data-availability.d.ts.map +1 -0
- package/dist/components/ui/data-availability.js +20 -0
- package/dist/components/ui/dialog.d.ts +16 -0
- package/dist/components/ui/dialog.d.ts.map +1 -0
- package/dist/components/ui/dialog.js +36 -0
- package/dist/components/ui/document-outline.d.ts +8 -0
- package/dist/components/ui/document-outline.d.ts.map +1 -0
- package/dist/components/ui/document-outline.js +168 -0
- package/dist/components/ui/dropdown-menu.d.ts +26 -0
- package/dist/components/ui/dropdown-menu.d.ts.map +1 -0
- package/dist/components/ui/dropdown-menu.js +51 -0
- package/dist/components/ui/error-page.d.ts +9 -0
- package/dist/components/ui/error-page.d.ts.map +1 -0
- package/dist/components/ui/error-page.js +21 -0
- package/dist/components/ui/footer-links.d.ts +14 -0
- package/dist/components/ui/footer-links.d.ts.map +1 -0
- package/dist/components/ui/footer-links.js +18 -0
- package/dist/components/ui/footnotes.d.ts +4 -0
- package/dist/components/ui/footnotes.d.ts.map +1 -0
- package/dist/components/ui/footnotes.js +30 -0
- package/dist/components/ui/frontmatter-badges.d.ts +27 -0
- package/dist/components/ui/frontmatter-badges.d.ts.map +1 -0
- package/dist/components/ui/frontmatter-badges.js +60 -0
- package/dist/components/ui/frontmatter.d.ts +7 -0
- package/dist/components/ui/frontmatter.d.ts.map +1 -0
- package/dist/components/ui/frontmatter.js +6 -0
- package/dist/components/ui/image.d.ts +34 -0
- package/dist/components/ui/image.d.ts.map +1 -0
- package/dist/components/ui/image.js +83 -0
- package/dist/components/ui/index.d.ts +50 -0
- package/dist/components/ui/index.d.ts.map +1 -0
- package/dist/components/ui/index.js +56 -0
- package/dist/components/ui/input.d.ts +4 -0
- package/dist/components/ui/input.d.ts.map +1 -0
- package/dist/components/ui/input.js +7 -0
- package/dist/components/ui/license-description.d.ts +4 -0
- package/dist/components/ui/license-description.d.ts.map +1 -0
- package/dist/components/ui/license-description.js +63 -0
- package/dist/components/ui/license-frontmatter.d.ts +22 -0
- package/dist/components/ui/license-frontmatter.d.ts.map +1 -0
- package/dist/components/ui/license-frontmatter.js +37 -0
- package/dist/components/ui/lightbox-container.d.ts +11 -0
- package/dist/components/ui/lightbox-container.d.ts.map +1 -0
- package/dist/components/ui/lightbox-container.js +13 -0
- package/dist/components/ui/lightbox.d.ts +17 -0
- package/dist/components/ui/lightbox.d.ts.map +1 -0
- package/dist/components/ui/lightbox.js +129 -0
- package/dist/components/ui/link-card.d.ts +15 -0
- package/dist/components/ui/link-card.d.ts.map +1 -0
- package/dist/components/ui/link-card.js +28 -0
- package/dist/components/ui/popover.d.ts +8 -0
- package/dist/components/ui/popover.d.ts.map +1 -0
- package/dist/components/ui/popover.js +17 -0
- package/dist/components/ui/search.d.ts +9 -0
- package/dist/components/ui/search.d.ts.map +1 -0
- package/dist/components/ui/search.js +290 -0
- package/dist/components/ui/separator.d.ts +5 -0
- package/dist/components/ui/separator.d.ts.map +1 -0
- package/dist/components/ui/separator.js +8 -0
- package/dist/components/ui/sheet.d.ts +14 -0
- package/dist/components/ui/sheet.d.ts.map +1 -0
- package/dist/components/ui/sheet.js +40 -0
- package/dist/components/ui/sidebar.d.ts +67 -0
- package/dist/components/ui/sidebar.d.ts.map +1 -0
- package/dist/components/ui/sidebar.js +202 -0
- package/dist/components/ui/skeleton.d.ts +3 -0
- package/dist/components/ui/skeleton.d.ts.map +1 -0
- package/dist/components/ui/skeleton.js +6 -0
- package/dist/components/ui/sonner.d.ts +5 -0
- package/dist/components/ui/sonner.d.ts.map +1 -0
- package/dist/components/ui/sonner.js +13 -0
- package/dist/components/ui/theme-button.d.ts +2 -0
- package/dist/components/ui/theme-button.d.ts.map +1 -0
- package/dist/components/ui/theme-button.js +9 -0
- package/dist/components/ui/tooltip.d.ts +13 -0
- package/dist/components/ui/tooltip.d.ts.map +1 -0
- package/dist/components/ui/tooltip.js +20 -0
- package/dist/components/ui/types.d.ts +11 -0
- package/dist/components/ui/types.d.ts.map +1 -0
- package/dist/components/ui/types.js +10 -0
- package/dist/hooks/index.d.ts +5 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +4 -0
- package/dist/hooks/use-hydrated.d.ts +2 -0
- package/dist/hooks/use-hydrated.d.ts.map +1 -0
- package/dist/hooks/use-hydrated.js +6 -0
- package/dist/hooks/use-image-load.d.ts +14 -0
- package/dist/hooks/use-image-load.d.ts.map +1 -0
- package/dist/hooks/use-image-load.js +41 -0
- package/dist/hooks/use-mobile.d.ts +2 -0
- package/dist/hooks/use-mobile.d.ts.map +1 -0
- package/dist/hooks/use-mobile.js +15 -0
- package/dist/hooks/use-theme.d.ts +6 -0
- package/dist/hooks/use-theme.d.ts.map +1 -0
- package/dist/hooks/use-theme.js +23 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/lib/checkMecaExport.d.ts +5 -0
- package/dist/lib/checkMecaExport.d.ts.map +1 -0
- package/dist/lib/checkMecaExport.js +4 -0
- package/dist/lib/index.d.ts +6 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +6 -0
- package/dist/lib/knownParts.d.ts +12 -0
- package/dist/lib/knownParts.d.ts.map +1 -0
- package/dist/lib/knownParts.js +14 -0
- package/dist/lib/links.d.ts +3 -0
- package/dist/lib/links.d.ts.map +1 -0
- package/dist/lib/links.js +7 -0
- package/dist/lib/parse-date.d.ts +2 -0
- package/dist/lib/parse-date.d.ts.map +1 -0
- package/dist/lib/parse-date.js +7 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +5 -0
- package/package.json +67 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useFrontmatter, useReferences } from '@myst-theme/providers';
|
|
3
|
+
import { copyNode } from 'myst-common';
|
|
4
|
+
import { MyST, HashLink } from 'myst-to-react';
|
|
5
|
+
import { cn } from '../../lib/utils';
|
|
6
|
+
import { extractKnownParts } from '../../lib/knownParts';
|
|
7
|
+
import { PART_IDS } from './types';
|
|
8
|
+
function useAcknowledgements() {
|
|
9
|
+
const frontmatter = useFrontmatter();
|
|
10
|
+
const references = useReferences();
|
|
11
|
+
const tree = copyNode(references?.article ?? { type: 'root', children: [] });
|
|
12
|
+
const knownParts = extractKnownParts(tree, frontmatter?.parts);
|
|
13
|
+
return knownParts.acknowledgments;
|
|
14
|
+
}
|
|
15
|
+
export function Acknowledgements({ className }) {
|
|
16
|
+
const acknowledgements = useAcknowledgements();
|
|
17
|
+
if (!acknowledgements)
|
|
18
|
+
return null;
|
|
19
|
+
return (_jsxs("section", { id: PART_IDS.acknowledgements, className: cn('min-w-full prose dark:prose-invert prose-sm', className), children: [_jsxs("header", { className: "text-lg font-semibold text-stone-900 dark:text-white group", children: ["Acknowledgements", _jsx(HashLink, { id: PART_IDS.acknowledgements, title: "Link to Acknowledgements", hover: true, className: "ml-2" })] }), _jsx("div", { className: cn('pl-3 mb-8 text-sm text-stone-500 dark:text-stone-300'), children: _jsx(MyST, { ast: acknowledgements }) })] }));
|
|
20
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { SiteAction, SiteExport } from 'myst-config';
|
|
2
|
+
/**
|
|
3
|
+
* triggerDirectDownload - aims to trigger a direct download for the
|
|
4
|
+
*
|
|
5
|
+
* @param url - url or resource to download
|
|
6
|
+
* @param filename - default filename and extension for dialog / system
|
|
7
|
+
* @returns - true or throws
|
|
8
|
+
*/
|
|
9
|
+
export declare function triggerDirectDownload(url: string, filename?: string): Promise<any>;
|
|
10
|
+
/**
|
|
11
|
+
* triggerBlobDownload - aims to trigger a direct download for the
|
|
12
|
+
*
|
|
13
|
+
* @param blob - blob to download
|
|
14
|
+
* @param filename - default filename and extension for dialog / system
|
|
15
|
+
* @returns - true or throws
|
|
16
|
+
*/
|
|
17
|
+
export declare function triggerBlobDownload(blob: Blob, filename?: string): Promise<any>;
|
|
18
|
+
export declare function useDownloads(): {
|
|
19
|
+
projectExports: SiteExport[];
|
|
20
|
+
projectDownloads: SiteAction[];
|
|
21
|
+
articleExports: SiteExport[];
|
|
22
|
+
articleDownloads: SiteAction[];
|
|
23
|
+
};
|
|
24
|
+
export declare function ArticleDownloadItems(): import("react/jsx-runtime").JSX.Element | null;
|
|
25
|
+
export declare function ArticleExportItems(): import("react/jsx-runtime").JSX.Element | null;
|
|
26
|
+
//# sourceMappingURL=article-actions-downloads.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"article-actions-downloads.d.ts","sourceRoot":"","sources":["../../../src/components/ui/article-actions-downloads.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAI1D;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,gBAKzE;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,EAAE,MAAM,gBA0BtE;AAoCD,wBAAgB,YAAY;;;;;EAa3B;AAkDD,wBAAgB,oBAAoB,mDAwBnC;AAED,wBAAgB,kBAAkB,mDA0BjC"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { DropdownMenuItem, DropdownMenuSeparator, DropdownMenuLabel } from '.';
|
|
3
|
+
import { useFrontmatter, useProjectManifest, useSiteManifest } from '@myst-theme/providers';
|
|
4
|
+
import { toast } from 'sonner';
|
|
5
|
+
import { File, FileText, FileCode, FileArchive, ScrollText } from 'lucide-react';
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import { BibTeXCitationMenuItem, useShowCitation } from './citation';
|
|
8
|
+
/**
|
|
9
|
+
* triggerDirectDownload - aims to trigger a direct download for the
|
|
10
|
+
*
|
|
11
|
+
* @param url - url or resource to download
|
|
12
|
+
* @param filename - default filename and extension for dialog / system
|
|
13
|
+
* @returns - true or throws
|
|
14
|
+
*/
|
|
15
|
+
export async function triggerDirectDownload(url, filename) {
|
|
16
|
+
const resp = await fetch(url);
|
|
17
|
+
const blob = await resp.blob();
|
|
18
|
+
return triggerBlobDownload(blob, filename);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* triggerBlobDownload - aims to trigger a direct download for the
|
|
22
|
+
*
|
|
23
|
+
* @param blob - blob to download
|
|
24
|
+
* @param filename - default filename and extension for dialog / system
|
|
25
|
+
* @returns - true or throws
|
|
26
|
+
*/
|
|
27
|
+
export async function triggerBlobDownload(blob, filename) {
|
|
28
|
+
if (window.navigator && window.navigator.msSaveOrOpenBlob)
|
|
29
|
+
return window.navigator.msSaveOrOpenBlob(blob);
|
|
30
|
+
const objectUrl = URL.createObjectURL(blob);
|
|
31
|
+
const a = document.createElement('a');
|
|
32
|
+
a.href = objectUrl;
|
|
33
|
+
if (filename)
|
|
34
|
+
a.download = filename;
|
|
35
|
+
a.style.display = 'none';
|
|
36
|
+
a.dispatchEvent(new MouseEvent('click', {
|
|
37
|
+
bubbles: true,
|
|
38
|
+
cancelable: true,
|
|
39
|
+
view: window,
|
|
40
|
+
}));
|
|
41
|
+
setTimeout(() => {
|
|
42
|
+
// For Firefox it is necessary to delay revoking the ObjectURL
|
|
43
|
+
URL.revokeObjectURL(objectUrl);
|
|
44
|
+
a.remove();
|
|
45
|
+
}, 100);
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Get a nice display name for the format
|
|
50
|
+
*/
|
|
51
|
+
function getFormatDisplayName(format) {
|
|
52
|
+
switch (format.toLowerCase()) {
|
|
53
|
+
case 'md':
|
|
54
|
+
return 'Markdown';
|
|
55
|
+
case 'pdf':
|
|
56
|
+
return 'PDF';
|
|
57
|
+
case 'docx':
|
|
58
|
+
return 'Microsoft Word';
|
|
59
|
+
case 'xml':
|
|
60
|
+
case 'jats':
|
|
61
|
+
case 'jats xml':
|
|
62
|
+
return 'JATS XML';
|
|
63
|
+
case 'meca':
|
|
64
|
+
return 'MECA';
|
|
65
|
+
case 'bibtex':
|
|
66
|
+
return 'BibTeX';
|
|
67
|
+
case 'ipynb':
|
|
68
|
+
return 'Jupyter Notebook';
|
|
69
|
+
case 'tex':
|
|
70
|
+
return 'LaTeX';
|
|
71
|
+
case 'html':
|
|
72
|
+
return 'HTML';
|
|
73
|
+
default:
|
|
74
|
+
// Capitalize the first letter of each word
|
|
75
|
+
return format
|
|
76
|
+
.split(' ')
|
|
77
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
78
|
+
.join(' ');
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
export function useDownloads() {
|
|
82
|
+
const project = useProjectManifest();
|
|
83
|
+
const site = useSiteManifest();
|
|
84
|
+
const article = useFrontmatter();
|
|
85
|
+
const legacyActions = site?.actions?.filter((a) => a.title === 'pdf' || a.title === 'paper' || a.title === 'omex') ??
|
|
86
|
+
[];
|
|
87
|
+
return {
|
|
88
|
+
projectExports: project?.exports ?? [],
|
|
89
|
+
projectDownloads: [...(project?.downloads ?? []), ...(legacyActions ?? [])],
|
|
90
|
+
articleExports: article?.exports ?? [],
|
|
91
|
+
articleDownloads: article?.downloads ?? [],
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
async function handleDownload(download) {
|
|
95
|
+
toast.success(_jsxs(_Fragment, { children: ["Download starting... ", _jsx("br", {}), _jsx("code", { children: download.filename })] }));
|
|
96
|
+
await triggerDirectDownload(download.url, download.filename).catch((error) => {
|
|
97
|
+
console.error('Download failed:', error);
|
|
98
|
+
toast.error('Download failed. Please try again.');
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
const formatIconMap = {
|
|
102
|
+
pdf: FileText,
|
|
103
|
+
xml: FileCode,
|
|
104
|
+
jats: FileCode,
|
|
105
|
+
meca: FileArchive,
|
|
106
|
+
omex: FileArchive,
|
|
107
|
+
tex: ScrollText,
|
|
108
|
+
typst: ScrollText,
|
|
109
|
+
};
|
|
110
|
+
function getIconForFormat(format) {
|
|
111
|
+
const lowerFormat = format.toLowerCase();
|
|
112
|
+
for (const [key, icon] of Object.entries(formatIconMap)) {
|
|
113
|
+
if (lowerFormat.includes(key)) {
|
|
114
|
+
return icon;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return File;
|
|
118
|
+
}
|
|
119
|
+
function renderDownloadItems(downloads) {
|
|
120
|
+
return downloads.map((download, index) => {
|
|
121
|
+
const format = download.format || 'unknown';
|
|
122
|
+
const downloadName = download.title || getFormatDisplayName(format);
|
|
123
|
+
const icon = getIconForFormat(format);
|
|
124
|
+
return (_jsxs(DropdownMenuItem, { onClick: () => handleDownload(download), children: [React.createElement(icon, { className: 'mr-2 h-4 w-4' }), downloadName] }, index));
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
export function ArticleDownloadItems() {
|
|
128
|
+
const { projectDownloads, articleDownloads } = useDownloads();
|
|
129
|
+
const hasProjectDownloads = projectDownloads.length > 0;
|
|
130
|
+
const hasArticleDownloads = articleDownloads.length > 0;
|
|
131
|
+
if (!hasProjectDownloads && !hasArticleDownloads)
|
|
132
|
+
return null;
|
|
133
|
+
return (_jsxs(_Fragment, { children: [hasProjectDownloads && (_jsxs(_Fragment, { children: [renderDownloadItems(projectDownloads), hasArticleDownloads && _jsx(DropdownMenuSeparator, {})] })), hasArticleDownloads && (_jsxs(_Fragment, { children: [_jsx(DropdownMenuLabel, { children: "Page Downloads" }), renderDownloadItems(articleDownloads)] }))] }));
|
|
134
|
+
}
|
|
135
|
+
export function ArticleExportItems() {
|
|
136
|
+
const { projectExports, articleExports } = useDownloads();
|
|
137
|
+
const showCitation = useShowCitation();
|
|
138
|
+
const hasProjectExports = projectExports.length > 0;
|
|
139
|
+
const hasArticleExports = articleExports.length > 0;
|
|
140
|
+
if (!hasProjectExports && !hasArticleExports)
|
|
141
|
+
return null;
|
|
142
|
+
return (_jsxs(_Fragment, { children: [(hasProjectExports || showCitation) && (_jsxs(_Fragment, { children: [renderDownloadItems(projectExports), showCitation && _jsx(BibTeXCitationMenuItem, {}), hasArticleExports && _jsx(DropdownMenuSeparator, {})] })), hasArticleExports && (_jsxs(_Fragment, { children: [_jsx(DropdownMenuLabel, { children: "Page Exports" }), renderDownloadItems(articleExports)] }))] }));
|
|
143
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"article-actions-dropdown.d.ts","sourceRoot":"","sources":["../../../src/components/ui/article-actions-dropdown.tsx"],"names":[],"mappings":"AAqCA,OAAO,KAAK,MAAM,OAAO,CAAC;AAiD1B,wBAAgB,sBAAsB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,2CAmLjF"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, Badge, } from '.';
|
|
3
|
+
import { Citation } from './citation';
|
|
4
|
+
import { useFrontmatter, useProjectManifest } from '@myst-theme/providers';
|
|
5
|
+
import { toast } from 'sonner';
|
|
6
|
+
import { doi } from 'doi-utils';
|
|
7
|
+
import { Download, Quote, Copy, Rocket, Pencil, Clock, BlocksIcon, Share, Sun, Moon, Monitor, FolderCode, FileText, } from 'lucide-react';
|
|
8
|
+
import { ArticleDownloadItems, ArticleExportItems, useDownloads, triggerDirectDownload, } from './article-actions-downloads';
|
|
9
|
+
import React from 'react';
|
|
10
|
+
import { ArticleActionsShare } from './article-actions-share';
|
|
11
|
+
import { useTheme } from 'next-themes';
|
|
12
|
+
const mockVersions = [
|
|
13
|
+
{
|
|
14
|
+
number: 2,
|
|
15
|
+
date: '2025-03-17',
|
|
16
|
+
description: 'Fixed a bug in the notebook that was causing the notebook to not run correctly.',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
number: 1,
|
|
20
|
+
date: '2025-03-10',
|
|
21
|
+
description: '',
|
|
22
|
+
},
|
|
23
|
+
];
|
|
24
|
+
function formatDate(dateStr) {
|
|
25
|
+
return new Date(dateStr).toLocaleDateString('en-US', {
|
|
26
|
+
month: 'short',
|
|
27
|
+
day: 'numeric',
|
|
28
|
+
year: 'numeric',
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function ArticleVersionList({ versions }) {
|
|
32
|
+
return (_jsx(_Fragment, { children: versions.map((v) => (_jsx(DropdownMenuItem, { children: _jsxs("div", { className: "flex flex-col", children: [_jsxs("div", { className: "flex items-center", children: [_jsxs("span", { className: "mr-4 font-mono text-muted-foreground", children: ["v", v.number] }), _jsx("span", { children: formatDate(v.date) }), _jsx("span", { className: "flex-1" }), v.number === 2 && _jsx(Badge, { variant: "outline", children: "Current" })] }), v.description && (_jsx("div", { className: "mt-1 max-w-xs text-xs leading-snug text-muted-foreground", children: v.description }))] }) }, v.number))) }));
|
|
33
|
+
}
|
|
34
|
+
export function ArticleActionsDropdown({ children }) {
|
|
35
|
+
const project = useProjectManifest();
|
|
36
|
+
const article = useFrontmatter();
|
|
37
|
+
const { projectDownloads, articleDownloads, projectExports, articleExports } = useDownloads();
|
|
38
|
+
const { theme, setTheme } = useTheme();
|
|
39
|
+
const allDownloads = [...projectDownloads, ...articleDownloads];
|
|
40
|
+
const hasDownloads = allDownloads.length > 0;
|
|
41
|
+
const hasExports = projectExports.length > 0 || articleExports.length > 0;
|
|
42
|
+
// Check if there's only one download and it's a PDF
|
|
43
|
+
const hasSinglePdfDownload = allDownloads.length === 1 &&
|
|
44
|
+
(allDownloads[0]?.format?.toLowerCase() === 'pdf' ||
|
|
45
|
+
allDownloads[0]?.url?.toLowerCase().endsWith('.pdf'));
|
|
46
|
+
const singlePdfDownload = hasSinglePdfDownload ? allDownloads[0] : null;
|
|
47
|
+
const handleSinglePdfDownload = async () => {
|
|
48
|
+
if (!singlePdfDownload)
|
|
49
|
+
return;
|
|
50
|
+
toast.success(_jsxs(_Fragment, { children: ["Download starting... ", _jsx("br", {}), _jsx("code", { children: singlePdfDownload.filename })] }));
|
|
51
|
+
await triggerDirectDownload(singlePdfDownload.url, singlePdfDownload.filename).catch((error) => {
|
|
52
|
+
console.error('Download failed:', error);
|
|
53
|
+
toast.error('Download failed. Please try again.');
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
const doiString = doi.buildUrl(project?.doi);
|
|
57
|
+
const handleCopyDOI = () => {
|
|
58
|
+
if (doiString) {
|
|
59
|
+
navigator.clipboard.writeText(doiString);
|
|
60
|
+
toast.success(_jsxs("div", { children: ["DOI copied to clipboard: ", _jsx("br", {}), _jsx("a", { href: doiString, children: doiString })] }));
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
return (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: children }), _jsxs(DropdownMenuContent, { className: "w-56", align: "end", children: [_jsx(DropdownMenuLabel, { children: "Article Actions" }), _jsx(DropdownMenuSeparator, {}), hasSinglePdfDownload && singlePdfDownload ? (_jsxs(DropdownMenuItem, { onClick: handleSinglePdfDownload, children: [_jsx(FileText, { className: "mr-2 w-4 h-4" }), "Download PDF"] })) : (hasDownloads && (_jsxs(DropdownMenuSub, { children: [_jsxs(DropdownMenuSubTrigger, { children: [_jsx(Download, { className: "mr-4 w-4 h-4" }), "Download"] }), _jsx(DropdownMenuSubContent, { children: _jsx(ArticleDownloadItems, {}) })] }))), hasExports && (_jsxs(DropdownMenuSub, { children: [_jsxs(DropdownMenuSubTrigger, { children: [_jsx(FolderCode, { className: "mr-4 w-4 h-4" }), "Exports"] }), _jsx(DropdownMenuSubContent, { children: _jsx(ArticleExportItems, {}) })] })), _jsx(Citation, { children: _jsxs(DropdownMenuItem, { onSelect: (e) => e.preventDefault(), children: [_jsx(Quote, { className: "mr-2 w-4 h-4" }), "Cite Article"] }) }), _jsxs(DropdownMenuSub, { children: [_jsxs(DropdownMenuSubTrigger, { children: [_jsx(Share, { className: "mr-4 w-4 h-4" }), "Share"] }), _jsx(DropdownMenuSubContent, { children: _jsx(ArticleActionsShare, { title: article?.title || '' }) })] }), project?.github && (_jsx(DropdownMenuItem, { asChild: true, children: _jsxs("a", { href: project.github, target: "_blank", rel: "noopener noreferrer", children: [_jsx(BlocksIcon, { className: "mr-2 w-4 h-4" }), "GitHub Repository"] }) })), doiString && (_jsxs(DropdownMenuItem, { onClick: handleCopyDOI, children: [_jsx(Copy, { className: "mr-2 w-4 h-4" }), "Copy DOI"] })), _jsx(DropdownMenuSeparator, {}), article?.edit_url && (_jsx(DropdownMenuItem, { asChild: true, children: _jsxs("a", { href: article?.edit_url, target: "_blank", rel: "noopener noreferrer", children: [_jsx(Pencil, { className: "mr-2 w-4 h-4" }), article?.edit_url?.includes('github.com')
|
|
64
|
+
? 'Edit in GitHub'
|
|
65
|
+
: article?.edit_url?.includes('gitlab')
|
|
66
|
+
? 'Edit in GitLab'
|
|
67
|
+
: 'Edit source'] }) })), _jsxs(DropdownMenuSub, { children: [_jsxs(DropdownMenuSubTrigger, { children: [theme === 'dark' ? (_jsx(Sun, { className: "mr-2 w-4 h-4" })) : (_jsx(Moon, { className: "mr-2 w-4 h-4" })), "Theme"] }), _jsxs(DropdownMenuSubContent, { children: [_jsxs(DropdownMenuItem, { onClick: () => setTheme('light'), children: [_jsx(Sun, { className: "mr-2 w-4 h-4" }), "Light"] }), _jsxs(DropdownMenuItem, { onClick: () => setTheme('dark'), children: [_jsx(Moon, { className: "mr-2 w-4 h-4" }), "Dark"] }), _jsxs(DropdownMenuItem, { onClick: () => setTheme('system'), children: [_jsx(Monitor, { className: "mr-2 w-4 h-4" }), "System"] })] })] })] })] }));
|
|
68
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"article-actions-share.d.ts","sourceRoot":"","sources":["../../../src/components/ui/article-actions-share.tsx"],"names":[],"mappings":"AAwDA,wBAAgB,mBAAmB,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,2CAyBlF"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import React, { useEffect, useState } from 'react';
|
|
3
|
+
import { DropdownMenuItem } from '.';
|
|
4
|
+
import { BlueskyIcon,
|
|
5
|
+
// RedditIcon,
|
|
6
|
+
// FacebookIcon,
|
|
7
|
+
LinkedinIcon, XIcon, EmailIcon, } from '@scienceicons/react/24/solid';
|
|
8
|
+
const SHARE_OPTIONS = [
|
|
9
|
+
{
|
|
10
|
+
name: 'Bluesky',
|
|
11
|
+
Icon: BlueskyIcon,
|
|
12
|
+
getUrl: (url, title) => `https://bsky.app/intent/compose?text=${encodeURIComponent(title + ' ' + url)}`,
|
|
13
|
+
},
|
|
14
|
+
// {
|
|
15
|
+
// name: 'Reddit',
|
|
16
|
+
// Icon: RedditIcon,
|
|
17
|
+
// getUrl: (url: string, title: string) =>
|
|
18
|
+
// `https://www.reddit.com/submit?url=${encodeURIComponent(url)}&title=${encodeURIComponent(
|
|
19
|
+
// title,
|
|
20
|
+
// )}`,
|
|
21
|
+
// },
|
|
22
|
+
// {
|
|
23
|
+
// name: 'Facebook',
|
|
24
|
+
// Icon: FacebookIcon,
|
|
25
|
+
// getUrl: (url: string) =>
|
|
26
|
+
// `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(url)}`,
|
|
27
|
+
// },
|
|
28
|
+
{
|
|
29
|
+
name: 'Linkedin',
|
|
30
|
+
Icon: LinkedinIcon,
|
|
31
|
+
getUrl: (url, title) => `https://www.linkedin.com/shareArticle?url=${encodeURIComponent(url)}&title=${encodeURIComponent(title)}`,
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: '𝕏',
|
|
35
|
+
Icon: XIcon,
|
|
36
|
+
getUrl: (url, title) => `https://twitter.com/intent/tweet?text=${encodeURIComponent(title)}&url=${encodeURIComponent(url)}`,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: 'Email',
|
|
40
|
+
Icon: EmailIcon,
|
|
41
|
+
getUrl: (url, title) => `mailto:?subject=${encodeURIComponent(title)}&body=${encodeURIComponent(url)}`,
|
|
42
|
+
},
|
|
43
|
+
];
|
|
44
|
+
export function ArticleActionsShare({ url, title }) {
|
|
45
|
+
const [shareUrl, setShareUrl] = useState(url || '');
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
if (!url) {
|
|
48
|
+
setShareUrl(window.location.href);
|
|
49
|
+
}
|
|
50
|
+
}, [url]);
|
|
51
|
+
return (_jsx(_Fragment, { children: SHARE_OPTIONS.map(({ name, Icon, getUrl }) => (_jsx(DropdownMenuItem, { asChild: true, children: _jsxs("a", { href: getUrl(shareUrl, title), target: "_blank", rel: "noopener noreferrer", "aria-label": `Share on ${name}`, children: [_jsx(Icon, { className: "mr-2 h-4 w-4" }), name] }) }, name))) }));
|
|
52
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"article-actions.d.ts","sourceRoot":"","sources":["../../../src/components/ui/article-actions.tsx"],"names":[],"mappings":"AASA,wBAAgB,cAAc,4CAqE7B"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button, SimpleTooltip } from '.';
|
|
3
|
+
import { QuoteIcon, EllipsisVerticalIcon, SearchIcon, FileDown } from 'lucide-react';
|
|
4
|
+
import { Citation } from './citation';
|
|
5
|
+
import { ArticleActionsDropdown } from './article-actions-dropdown';
|
|
6
|
+
import { useDownloads } from './article-actions-downloads';
|
|
7
|
+
import { SearchDialog } from './search';
|
|
8
|
+
import { useDesign } from '../providers';
|
|
9
|
+
import { useBaseurl, withBaseurl } from '@myst-theme/providers';
|
|
10
|
+
export function ArticleActions() {
|
|
11
|
+
const { projectDownloads, articleDownloads } = useDownloads();
|
|
12
|
+
const design = useDesign();
|
|
13
|
+
const baseurl = useBaseurl();
|
|
14
|
+
// Combine all downloads for PDF search
|
|
15
|
+
const allDownloads = [...projectDownloads, ...articleDownloads];
|
|
16
|
+
// Find PDF download
|
|
17
|
+
const pdfDownload = allDownloads.find((download) => download.format?.toLowerCase() === 'pdf' || download.url?.toLowerCase().endsWith('.pdf'));
|
|
18
|
+
const pdfDownloadUrl = baseurl ? withBaseurl('.pdf', baseurl) : pdfDownload?.url;
|
|
19
|
+
return (_jsxs("div", { className: "flex gap-2 items-center", children: [!design.hide_search && (_jsx(SearchDialog, { children: _jsx(SimpleTooltip, { title: "Search", children: _jsx(Button, { variant: "outline", size: "icon", "aria-label": "Search", asChild: true, children: _jsx("div", { children: _jsx(SearchIcon, {}) }) }) }) })), pdfDownload && (_jsx(SimpleTooltip, { title: "Download PDF", children: _jsx(Button, { variant: "outline", className: "cursor-pointer", size: "icon", "aria-label": "Download PDF", asChild: true, children: _jsx("a", { href: pdfDownloadUrl, target: "_blank", rel: "noopener noreferrer", children: _jsx(FileDown, {}) }) }) })), _jsx(Citation, { children: _jsx(SimpleTooltip, { title: "Cite this article", children: _jsx(Button, { variant: "outline", className: "cursor-pointer", size: "icon", "aria-label": "Cite this article", children: _jsx(QuoteIcon, {}) }) }) }), _jsx(ArticleActionsDropdown, { children: _jsx(Button, { variant: "ghost", size: "icon", className: "cursor-pointer", children: _jsx(EllipsisVerticalIcon, {}) }) })] }));
|
|
20
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function AuthorsList({ source }: {
|
|
2
|
+
source?: 'project' | 'article';
|
|
3
|
+
}): import("react/jsx-runtime").JSX.Element | null;
|
|
4
|
+
export declare function ArticleBar({ source, sticky, }: {
|
|
5
|
+
source?: 'project' | 'article';
|
|
6
|
+
sticky?: 'top' | 'bottom';
|
|
7
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
//# sourceMappingURL=article-bar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"article-bar.d.ts","sourceRoot":"","sources":["../../../src/components/ui/article-bar.tsx"],"names":[],"mappings":"AA6BA,wBAAgB,WAAW,CAAC,EAAE,MAAkB,EAAE,EAAE;IAAE,MAAM,CAAC,EAAE,SAAS,GAAG,SAAS,CAAA;CAAE,kDAcrF;AAED,wBAAgB,UAAU,CAAC,EACzB,MAAkB,EAClB,MAAM,GACP,EAAE;IACD,MAAM,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;IAC/B,MAAM,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;CAC3B,2CAmCA"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { AuthorPopover } from './author-popover';
|
|
3
|
+
import { DateString, DoiLink, EmailLink, OpenAccessBadge, OrcidBadge } from './frontmatter-badges';
|
|
4
|
+
import { LicenseBadges } from './license-frontmatter';
|
|
5
|
+
import { ArticleActions } from './article-actions';
|
|
6
|
+
import { useFrontmatter, useProjectManifest } from '@myst-theme/providers';
|
|
7
|
+
import { cn } from '@curvenote/react-utils';
|
|
8
|
+
function AuthorsPopoverList({ authors = [], affiliations = [], }) {
|
|
9
|
+
return (_jsx("div", { className: "flex flex-row flex-wrap gap-x-2", children: authors.map((author, idx) => (_jsxs("div", { className: "flex items-center", children: [_jsx(AuthorPopover, { author: author, affiliations: affiliations }), author.corresponding && _jsx(EmailLink, { email: author.email }), author.orcid && _jsx(OrcidBadge, { orcid: author.orcid, className: "ml-1" }), idx < authors.length - 1 && _jsx("span", { className: "text-muted-foreground", children: "," })] }, author.orcid || author.email || idx))) }));
|
|
10
|
+
}
|
|
11
|
+
export function AuthorsList({ source = 'article' }) {
|
|
12
|
+
const project = useProjectManifest();
|
|
13
|
+
const page = useFrontmatter();
|
|
14
|
+
const frontmatter = source === 'project' ? project : page;
|
|
15
|
+
if (!frontmatter?.authors ||
|
|
16
|
+
!Array.isArray(frontmatter?.authors) ||
|
|
17
|
+
frontmatter?.authors.length == 0) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
return (_jsx(AuthorsPopoverList, { authors: frontmatter.authors, affiliations: frontmatter.affiliations }));
|
|
21
|
+
}
|
|
22
|
+
export function ArticleBar({ source = 'article', sticky, }) {
|
|
23
|
+
const project = useProjectManifest();
|
|
24
|
+
const page = useFrontmatter();
|
|
25
|
+
const frontmatter = source === 'project' ? project : page;
|
|
26
|
+
return (_jsx("div", { className: cn('my-4 pointer-events-none', {
|
|
27
|
+
'sticky top-0 pb-4': sticky === 'top',
|
|
28
|
+
'sticky bottom-0 pt-4': sticky === 'bottom',
|
|
29
|
+
// Add a full-width gradient fade-in pseudo element when sticky bottom
|
|
30
|
+
'before:absolute before:top-0 before:left-0 before:w-full before:h-4 before:pointer-events-none before:z-[-1] before:content-[""] before:bg-gradient-to-t before:from-background before:to-transparent': sticky === 'bottom',
|
|
31
|
+
}), children: _jsxs("div", { className: cn('bg-background flex flex-col items-center py-3 sm:flex-row border-y border-border', 'pointer-events-auto'), children: [_jsx("div", { className: "flex flex-col flex-1 gap-1", children: _jsxs("div", { className: "flex gap-1 items-center mb-2 font-sans text-sm text-muted-foreground", children: [frontmatter?.date && (_jsx(DateString, { date: frontmatter?.date, spacer: !!frontmatter?.doi })), frontmatter?.doi && _jsx(DoiLink, { doi: frontmatter?.doi }), _jsx(LicenseBadges, { license: frontmatter?.license }), _jsx(OpenAccessBadge, { open_access: frontmatter?.open_access })] }) }), _jsx(ArticleActions, {})] }) }));
|
|
32
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { WorkVersionDTO } from '@curvenote/common';
|
|
2
|
+
interface ArticleCardProps {
|
|
3
|
+
to: string;
|
|
4
|
+
article: Partial<Pick<WorkVersionDTO, 'id' | 'title' | 'description' | 'authors' | 'date' | 'collection' | 'doi' | 'links'>>;
|
|
5
|
+
showThumbnails: boolean;
|
|
6
|
+
showAuthors?: boolean;
|
|
7
|
+
showDoi?: boolean;
|
|
8
|
+
showDate?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function ArticleCard({ to, article, showThumbnails, showAuthors, showDoi, showDate, }: ArticleCardProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=article-card.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"article-card.d.ts","sourceRoot":"","sources":["../../../src/components/ui/article-card.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGxD,UAAU,gBAAgB;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,OAAO,CACd,IAAI,CACF,cAAc,EACd,IAAI,GAAG,OAAO,GAAG,aAAa,GAAG,SAAS,GAAG,MAAM,GAAG,YAAY,GAAG,KAAK,GAAG,OAAO,CACrF,CACF,CAAC;IACF,cAAc,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,WAAW,CAAC,EAC1B,EAAE,EACF,OAAO,EACP,cAAc,EACd,WAAW,EACX,OAAe,EACf,QAAgB,GACjB,EAAE,gBAAgB,2CAmGlB"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Link } from 'react-router';
|
|
3
|
+
import { buildUrl } from 'doi-utils';
|
|
4
|
+
import { CurvenoteIcon } from '@scienceicons/react/24/solid';
|
|
5
|
+
import { useImageLoad } from '../../hooks';
|
|
6
|
+
export function ArticleCard({ to, article, showThumbnails, showAuthors, showDoi = false, showDate = false, }) {
|
|
7
|
+
const { imageLoaded, showPlaceholder, imgRef, handleImageLoad } = useImageLoad({
|
|
8
|
+
src: article.links?.thumbnail || '',
|
|
9
|
+
minDelay: 300,
|
|
10
|
+
});
|
|
11
|
+
return (_jsx(Link, { to: to, className: "block no-underline group hover:no-underline", prefetch: "intent", children: _jsx("article", { className: "overflow-hidden font-sans rounded-sm border transition-shadow border-gray-200/50 hover:shadow-md not-prose", children: _jsxs("div", { className: "flex", children: [showThumbnails && article.links?.thumbnail && (_jsxs("div", { className: "hidden relative flex-shrink-0 w-40 sm:block lg:w-50 xl:w-60", children: [_jsx("div", { className: "absolute inset-0 bg-center bg-no-repeat bg-cover transition-opacity duration-750", style: {
|
|
12
|
+
backgroundImage: imageLoaded ? `url(${article.links.thumbnail})` : 'none',
|
|
13
|
+
opacity: imageLoaded ? 1 : 0,
|
|
14
|
+
} }), showPlaceholder && (_jsx("div", { className: "flex relative justify-center items-center h-full bg-gray-100 dark:bg-gray-800", children: _jsx(CurvenoteIcon, { className: "fill-gray-200 dark:fill-gray-900", height: 60, width: 60 }) })), _jsx("img", { ref: imgRef, src: article.links.thumbnail, className: "hidden", onLoad: handleImageLoad })] })), _jsxs("div", { className: "flex-1 p-6 min-w-0", children: [_jsx("div", { className: "mb-2 text-lg text-foreground", children: _jsx("span", { className: "transition-colors group-hover:text-blue-800 dark:group-hover:text-blue-500", children: article.title }) }), article.description && (_jsx("p", { className: "mb-3 text-sm font-light text-muted-foreground line-clamp-2", children: article.description })), _jsxs("div", { className: "flex flex-wrap gap-4 items-center text-xs font-light text-muted-foreground", children: [showAuthors && article.authors && article.authors.length > 0 && (_jsx("div", { className: "flex items-center", children: _jsx("span", { children: article.authors.length <= 3 ? (article.authors.map((author, index) => (_jsxs("span", { children: [author.name, index < (article.authors?.length ?? 0) - 1
|
|
15
|
+
? index === (article.authors?.length ?? 0) - 2
|
|
16
|
+
? `${(article.authors?.length ?? 0) > 2 ? ',' : ''} and `
|
|
17
|
+
: ', '
|
|
18
|
+
: ''] }, index)))) : (_jsxs(_Fragment, { children: [article.authors
|
|
19
|
+
.slice(0, 3)
|
|
20
|
+
.map((a) => a.name)
|
|
21
|
+
.join(', '), ' et al.'] })) }) })), showDate && article.date && (_jsx("div", { className: "flex items-center", children: _jsx("span", { children: new Date(article.date).toLocaleDateString() }) })), showDoi && article.doi && (_jsx("div", { className: "flex items-center", children: _jsx("span", { children: buildUrl(article.doi) }) }))] })] })] }) }) }));
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"article-footer.d.ts","sourceRoot":"","sources":["../../../src/components/ui/article-footer.tsx"],"names":[],"mappings":"AAGA,wBAAgB,aAAa,4CAc5B"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { JournalFooter } from '@curvenote/footers';
|
|
3
|
+
import { Backmatter, useBackmatter } from './backmatter';
|
|
4
|
+
export function ArticleFooter() {
|
|
5
|
+
const backmatter = useBackmatter();
|
|
6
|
+
return (_jsxs("footer", { className: "mt-10", children: [backmatter && (_jsx("div", { className: "py-10 w-full border-t bg-stone-50/10", children: _jsx("section", { className: "px-2 max-w-full lg:max-w-screen-lg lg:mx-auto md:px-4", children: _jsx(Backmatter, {}) }) })), _jsx(JournalFooter, { className: "mt-0 bg-stone-800", brandFooter: null })] }));
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { PageFrontmatter } from 'myst-frontmatter';
|
|
2
|
+
export declare function AuthorPopover({ author, affiliations, className, }: {
|
|
3
|
+
author: Required<PageFrontmatter>['authors'][0];
|
|
4
|
+
affiliations: PageFrontmatter['affiliations'];
|
|
5
|
+
className?: string;
|
|
6
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=author-popover.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"author-popover.d.ts","sourceRoot":"","sources":["../../../src/components/ui/author-popover.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAsBxD,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,YAAY,EACZ,SAAS,GACV,EAAE;IACD,MAAM,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,YAAY,EAAE,eAAe,CAAC,cAAc,CAAC,CAAC;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,2CAkGA"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button, Popover, PopoverContent, PopoverTrigger, SimpleTooltip } from '.';
|
|
3
|
+
import { cn } from '../../lib/utils';
|
|
4
|
+
import { PopoverArrow } from '@radix-ui/react-popover';
|
|
5
|
+
import { Copy } from 'lucide-react';
|
|
6
|
+
import { toast } from 'sonner';
|
|
7
|
+
function Affiliation({ affiliations, affiliationId, }) {
|
|
8
|
+
const affiliation = affiliations?.find((a) => a.id === affiliationId);
|
|
9
|
+
if (!affiliation) {
|
|
10
|
+
// Fallback to showing the ID (for some earlier data)
|
|
11
|
+
return _jsx("div", { className: "text-xs text-muted-foreground", children: affiliationId });
|
|
12
|
+
}
|
|
13
|
+
return _jsx("div", { className: "text-xs text-muted-foreground", children: affiliation.name });
|
|
14
|
+
}
|
|
15
|
+
export function AuthorPopover({ author, affiliations, className, }) {
|
|
16
|
+
const handleCopyEmail = () => {
|
|
17
|
+
if (author.email) {
|
|
18
|
+
navigator.clipboard.writeText(author.email);
|
|
19
|
+
toast.success('Email copied to clipboard');
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
const handleCopyOrcid = () => {
|
|
23
|
+
if (author.orcid) {
|
|
24
|
+
navigator.clipboard.writeText(author.orcid);
|
|
25
|
+
toast.success('ORCID copied to clipboard');
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx("button", { className: cn('cursor-pointer hover:underline text-[15px]', className), type: "button", children: author.nameParsed
|
|
29
|
+
? `${author.nameParsed?.given} ${author.nameParsed?.family}`
|
|
30
|
+
: author.name }) }), _jsxs(PopoverContent, { className: "p-4 w-80", onOpenAutoFocus: (event) => {
|
|
31
|
+
// This stops the popover from automatically focusing on the first input, the tooltip, when it opens
|
|
32
|
+
event.preventDefault();
|
|
33
|
+
}, children: [_jsx("div", { className: "mb-1 text-base font-semibold", children: author.nameParsed
|
|
34
|
+
? `${author.nameParsed?.given} ${author.nameParsed?.family}`
|
|
35
|
+
: author.name }), author.email && (_jsxs("div", { className: "flex gap-1 items-center mb-1 text-xs text-muted-foreground", children: [_jsx("span", { className: "font-medium", children: "Email:" }), ' ', _jsx("a", { href: `mailto:${author.email}`, target: "_blank", rel: "noopener noreferrer", className: "underline", children: author.email }), _jsx(SimpleTooltip, { title: "Copy email address", children: _jsx(Button, { onClick: handleCopyEmail, variant: "ghost", size: "xs", children: _jsx(Copy, {}) }) })] })), author.orcid && (_jsxs("div", { className: "flex gap-1 items-center mb-1 text-xs text-muted-foreground", children: [_jsx("span", { className: "font-medium", children: "ORCID:" }), ' ', _jsx("a", { href: `https://orcid.org/${author.orcid}`, target: "_blank", rel: "noopener noreferrer", className: "underline", children: author.orcid }), _jsx(SimpleTooltip, { title: "Copy ORCID", children: _jsx(Button, { onClick: handleCopyOrcid, variant: "ghost", size: "xs", children: _jsx(Copy, {}) }) })] })), author.affiliations && author.affiliations.length > 0 && (_jsxs("div", { className: "mb-1", children: [_jsx("span", { className: "text-xs font-medium", children: "Affiliations:" }), _jsx("div", { className: "ml-2 flex flex-col gap-0.5", children: author.affiliations.map((affiliationId) => (_jsx(Affiliation, { affiliations: affiliations, affiliationId: affiliationId }, affiliationId))) })] })), author.roles && author.roles.length > 0 && (_jsxs("div", { className: "mt-2 text-xs", children: [_jsx("span", { className: "font-medium", children: "Roles:" }), " ", author.roles.join(', ')] })), _jsx(PopoverArrow, { className: "fill-gray-200" })] })] }));
|
|
36
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { GenericParent } from 'myst-common';
|
|
2
|
+
import type { PageFrontmatterWithDownloads } from '@myst-theme/common';
|
|
3
|
+
export declare function useBackmatter({ mdast, frontmatter, }?: {
|
|
4
|
+
mdast?: GenericParent;
|
|
5
|
+
frontmatter?: PageFrontmatterWithDownloads;
|
|
6
|
+
}): boolean;
|
|
7
|
+
export declare function Backmatter(): import("react/jsx-runtime").JSX.Element | null;
|
|
8
|
+
export default Backmatter;
|
|
9
|
+
//# sourceMappingURL=backmatter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backmatter.d.ts","sourceRoot":"","sources":["../../../src/components/ui/backmatter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,aAAa,EAAE,MAAM,aAAa,CAAC;AAQ5D,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAC;AAkCvE,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,WAAW,GACZ,GAAE;IACD,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,WAAW,CAAC,EAAE,4BAA4B,CAAC;CACvC,GAAG,OAAO,CAiBf;AAED,wBAAgB,UAAU,mDAczB;AAED,eAAe,UAAU,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useFrontmatter, useReferences } from '@myst-theme/providers';
|
|
3
|
+
import { Abbreviations } from './abbreviations';
|
|
4
|
+
import { Bibliography } from './bibliography';
|
|
5
|
+
import { Footnotes } from './footnotes';
|
|
6
|
+
import { Acknowledgements } from './acknowledgements';
|
|
7
|
+
import { DataAvailability } from './data-availability';
|
|
8
|
+
import { selectAll } from 'unist-util-select';
|
|
9
|
+
import { extractKnownParts } from '../../lib/knownParts';
|
|
10
|
+
import { copyNode } from 'myst-common';
|
|
11
|
+
import { LicenseDescription } from './license-description';
|
|
12
|
+
import { PART_IDS } from './types';
|
|
13
|
+
function getTrees(mdast, parts) {
|
|
14
|
+
return [mdast, ...Object.values(parts ?? {}).map((part) => part.mdast)].filter(Boolean);
|
|
15
|
+
}
|
|
16
|
+
function hasFootnotes(trees) {
|
|
17
|
+
return trees.some((part) => selectAll('footnoteReference', part).length > 0);
|
|
18
|
+
}
|
|
19
|
+
function hasAbbreviations(frontmatter, trees) {
|
|
20
|
+
return ((Object.keys(frontmatter?.abbreviations ?? {}).length > 0 ||
|
|
21
|
+
trees?.some((part) => selectAll('abbreviation', part).length > 0)) ??
|
|
22
|
+
false);
|
|
23
|
+
}
|
|
24
|
+
function hasBibliography(cite) {
|
|
25
|
+
return Object.keys(cite?.data ?? 0).length > 0;
|
|
26
|
+
}
|
|
27
|
+
export function useBackmatter({ mdast, frontmatter, } = {}) {
|
|
28
|
+
const references = useReferences();
|
|
29
|
+
const pageFrontmatter = useFrontmatter();
|
|
30
|
+
const page = mdast ?? references?.article;
|
|
31
|
+
const parts = (frontmatter ?? pageFrontmatter)?.parts;
|
|
32
|
+
const trees = getTrees(page, parts);
|
|
33
|
+
const footnotes = hasFootnotes(trees);
|
|
34
|
+
const abbreviations = hasAbbreviations(frontmatter, trees);
|
|
35
|
+
const bibliography = hasBibliography(references?.cite);
|
|
36
|
+
// Check for acknowledgements and data availability
|
|
37
|
+
const tree = copyNode(page || { type: 'root', children: [] });
|
|
38
|
+
const knownParts = page ? extractKnownParts(tree, parts) : null;
|
|
39
|
+
const acknowledgements = !!knownParts?.acknowledgments;
|
|
40
|
+
const dataAvailability = !!knownParts?.data_availability;
|
|
41
|
+
return footnotes || abbreviations || bibliography || acknowledgements || dataAvailability;
|
|
42
|
+
}
|
|
43
|
+
export function Backmatter() {
|
|
44
|
+
const hasBackmatter = useBackmatter();
|
|
45
|
+
if (!hasBackmatter)
|
|
46
|
+
return null;
|
|
47
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { id: PART_IDS.skip_to_backmatter }), _jsx(Acknowledgements, {}), _jsx(DataAvailability, {}), _jsx(LicenseDescription, {}), _jsx(Footnotes, {}), _jsx(Abbreviations, {}), _jsx(Bibliography, {})] }));
|
|
48
|
+
}
|
|
49
|
+
export default Backmatter;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type VariantProps } from 'class-variance-authority';
|
|
3
|
+
declare const badgeVariants: (props?: ({
|
|
4
|
+
variant?: "default" | "destructive" | "outline" | "secondary" | null | undefined;
|
|
5
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
6
|
+
declare function Badge({ className, variant, asChild, ...props }: React.ComponentProps<'span'> & VariantProps<typeof badgeVariants> & {
|
|
7
|
+
asChild?: boolean;
|
|
8
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export { Badge, badgeVariants };
|
|
10
|
+
//# sourceMappingURL=badge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"badge.d.ts","sourceRoot":"","sources":["../../../src/components/ui/badge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAIlE,QAAA,MAAM,aAAa;;8EAiBlB,CAAC;AAEF,iBAAS,KAAK,CAAC,EACb,SAAS,EACT,OAAO,EACP,OAAe,EACf,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,YAAY,CAAC,OAAO,aAAa,CAAC,GAAG;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,2CAM3F;AAED,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC"}
|