react-cheminfo 0.25.0 → 0.26.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 +73 -2
- package/bin/check-messages.mjs +229 -0
- package/lib/about/ui/AboutBuild.d.ts.map +1 -1
- package/lib/about/ui/AboutBuild.js +15 -4
- package/lib/about/ui/AboutBuild.js.map +1 -1
- package/lib/about/ui/AboutCitations.d.ts.map +1 -1
- package/lib/about/ui/AboutCitations.js +3 -1
- package/lib/about/ui/AboutCitations.js.map +1 -1
- package/lib/about/ui/AboutPage.d.ts.map +1 -1
- package/lib/about/ui/AboutPage.js +9 -1
- package/lib/about/ui/AboutPage.js.map +1 -1
- package/lib/about/ui/AboutProvidedBy.d.ts.map +1 -1
- package/lib/about/ui/AboutProvidedBy.js +8 -3
- package/lib/about/ui/AboutProvidedBy.js.map +1 -1
- package/lib/capsule/ui/Capsule.d.ts +30 -0
- package/lib/capsule/ui/Capsule.d.ts.map +1 -0
- package/lib/capsule/ui/Capsule.js +12 -0
- package/lib/capsule/ui/Capsule.js.map +1 -0
- package/lib/capsule/ui/CapsuleFilter.d.ts +19 -3
- package/lib/capsule/ui/CapsuleFilter.d.ts.map +1 -1
- package/lib/capsule/ui/CapsuleFilter.js +14 -44
- package/lib/capsule/ui/CapsuleFilter.js.map +1 -1
- package/lib/capsule/ui/capsuleFilterCapsules.d.ts +15 -0
- package/lib/capsule/ui/capsuleFilterCapsules.d.ts.map +1 -0
- package/lib/capsule/ui/capsuleFilterCapsules.js +47 -0
- package/lib/capsule/ui/capsuleFilterCapsules.js.map +1 -0
- package/lib/chart/ui/ChartTrackingLayer.d.ts.map +1 -1
- package/lib/chart/ui/ChartTrackingLayer.js +4 -2
- package/lib/chart/ui/ChartTrackingLayer.js.map +1 -1
- package/lib/chrome/ui/SiteHeader.d.ts +1 -1
- package/lib/chrome/ui/SiteHeader.d.ts.map +1 -1
- package/lib/chrome/ui/SiteHeader.js +4 -2
- package/lib/chrome/ui/SiteHeader.js.map +1 -1
- package/lib/citation/ui/CitationMenu.d.ts +1 -1
- package/lib/citation/ui/CitationMenu.d.ts.map +1 -1
- package/lib/citation/ui/CitationMenu.js +7 -3
- package/lib/citation/ui/CitationMenu.js.map +1 -1
- package/lib/citation/ui/CiteButton.d.ts +1 -1
- package/lib/citation/ui/CiteButton.d.ts.map +1 -1
- package/lib/citation/ui/CiteButton.js +3 -1
- package/lib/citation/ui/CiteButton.js.map +1 -1
- package/lib/citation/ui/CopyFormatEntries.d.ts.map +1 -1
- package/lib/citation/ui/CopyFormatEntries.js +3 -1
- package/lib/citation/ui/CopyFormatEntries.js.map +1 -1
- package/lib/citation/ui/WorkEntry.d.ts.map +1 -1
- package/lib/citation/ui/WorkEntry.js +3 -1
- package/lib/citation/ui/WorkEntry.js.map +1 -1
- package/lib/citation/ui/entries.d.ts.map +1 -1
- package/lib/citation/ui/entries.js +8 -2
- package/lib/citation/ui/entries.js.map +1 -1
- package/lib/citation/ui/useCopyFeedback.d.ts.map +1 -1
- package/lib/citation/ui/useCopyFeedback.js +9 -4
- package/lib/citation/ui/useCopyFeedback.js.map +1 -1
- package/lib/clipboard/ui/ClickToCopy.d.ts.map +1 -1
- package/lib/clipboard/ui/ClickToCopy.js +12 -6
- package/lib/clipboard/ui/ClickToCopy.js.map +1 -1
- package/lib/clipboard/ui/CopyButton.d.ts +3 -3
- package/lib/clipboard/ui/CopyButton.d.ts.map +1 -1
- package/lib/clipboard/ui/CopyButton.js +7 -4
- package/lib/clipboard/ui/CopyButton.js.map +1 -1
- package/lib/color/ui/ColorScaleEditor.d.ts.map +1 -1
- package/lib/color/ui/ColorScaleEditor.js +15 -10
- package/lib/color/ui/ColorScaleEditor.js.map +1 -1
- package/lib/color/ui/ColorScaleEntry.d.ts.map +1 -1
- package/lib/color/ui/ColorScaleEntry.js +4 -2
- package/lib/color/ui/ColorScaleEntry.js.map +1 -1
- package/lib/color/ui/ColorScaleLegend.d.ts.map +1 -1
- package/lib/color/ui/ColorScaleLegend.js +7 -1
- package/lib/color/ui/ColorScaleLegend.js.map +1 -1
- package/lib/color/ui/ColorScaleSelect.d.ts.map +1 -1
- package/lib/color/ui/ColorScaleSelect.js +8 -4
- package/lib/color/ui/ColorScaleSelect.js.map +1 -1
- package/lib/confirm/ui/ConfirmButton.d.ts +2 -2
- package/lib/confirm/ui/ConfirmButton.d.ts.map +1 -1
- package/lib/confirm/ui/ConfirmButton.js +4 -2
- package/lib/confirm/ui/ConfirmButton.js.map +1 -1
- package/lib/core.d.ts +1 -0
- package/lib/core.d.ts.map +1 -1
- package/lib/core.js +1 -0
- package/lib/core.js.map +1 -1
- package/lib/credits/ui/CreditsList.d.ts.map +1 -1
- package/lib/credits/ui/CreditsList.js +3 -1
- package/lib/credits/ui/CreditsList.js.map +1 -1
- package/lib/delimited/ui/DelimitedTextDialog.d.ts.map +1 -1
- package/lib/delimited/ui/DelimitedTextDialog.js +5 -2
- package/lib/delimited/ui/DelimitedTextDialog.js.map +1 -1
- package/lib/delimited/ui/DelimitedTextPanel.d.ts.map +1 -1
- package/lib/delimited/ui/DelimitedTextPanel.js +8 -8
- package/lib/delimited/ui/DelimitedTextPanel.js.map +1 -1
- package/lib/download/ui/FigureDownload.d.ts +2 -2
- package/lib/download/ui/FigureDownload.d.ts.map +1 -1
- package/lib/download/ui/FigureDownload.js +4 -2
- package/lib/download/ui/FigureDownload.js.map +1 -1
- package/lib/download/ui/FigureDownloadPanel.d.ts.map +1 -1
- package/lib/download/ui/FigureDownloadPanel.js +24 -18
- package/lib/download/ui/FigureDownloadPanel.js.map +1 -1
- package/lib/ecosystem/ui/EcosystemButton.d.ts +1 -1
- package/lib/ecosystem/ui/EcosystemButton.d.ts.map +1 -1
- package/lib/ecosystem/ui/EcosystemButton.js +4 -2
- package/lib/ecosystem/ui/EcosystemButton.js.map +1 -1
- package/lib/ecosystem/ui/EcosystemLinks.d.ts +1 -1
- package/lib/ecosystem/ui/EcosystemLinks.d.ts.map +1 -1
- package/lib/ecosystem/ui/EcosystemLinks.js +5 -2
- package/lib/ecosystem/ui/EcosystemLinks.js.map +1 -1
- package/lib/ecosystem/ui/EcosystemMenu.d.ts.map +1 -1
- package/lib/ecosystem/ui/EcosystemMenu.js +3 -1
- package/lib/ecosystem/ui/EcosystemMenu.js.map +1 -1
- package/lib/ecosystem/ui/SiteGroupSection.d.ts.map +1 -1
- package/lib/ecosystem/ui/SiteGroupSection.js +3 -1
- package/lib/ecosystem/ui/SiteGroupSection.js.map +1 -1
- package/lib/ecosystem/ui/SiteTile.d.ts.map +1 -1
- package/lib/ecosystem/ui/SiteTile.js +3 -1
- package/lib/ecosystem/ui/SiteTile.js.map +1 -1
- package/lib/error/ui/ErrorFallback.d.ts +2 -2
- package/lib/error/ui/ErrorFallback.d.ts.map +1 -1
- package/lib/error/ui/ErrorFallback.js +4 -2
- package/lib/error/ui/ErrorFallback.js.map +1 -1
- package/lib/help/ui/HelpBody.d.ts.map +1 -1
- package/lib/help/ui/HelpBody.js +3 -1
- package/lib/help/ui/HelpBody.js.map +1 -1
- package/lib/help/ui/HelpIcon.d.ts +2 -1
- package/lib/help/ui/HelpIcon.d.ts.map +1 -1
- package/lib/help/ui/HelpIcon.js +4 -2
- package/lib/help/ui/HelpIcon.js.map +1 -1
- package/lib/help/ui/HelpToolbarButton.d.ts.map +1 -1
- package/lib/help/ui/HelpToolbarButton.js +3 -1
- package/lib/help/ui/HelpToolbarButton.js.map +1 -1
- package/lib/help/ui/helpName.d.ts +5 -1
- package/lib/help/ui/helpName.d.ts.map +1 -1
- package/lib/help/ui/helpName.js +4 -2
- package/lib/help/ui/helpName.js.map +1 -1
- package/lib/i18n/core/chromeCatalog.d.ts +21 -0
- package/lib/i18n/core/chromeCatalog.d.ts.map +1 -0
- package/lib/i18n/core/chromeCatalog.js +29 -0
- package/lib/i18n/core/chromeCatalog.js.map +1 -0
- package/lib/i18n/core/index.d.ts +12 -0
- package/lib/i18n/core/index.d.ts.map +1 -0
- package/lib/i18n/core/index.js +6 -0
- package/lib/i18n/core/index.js.map +1 -0
- package/lib/i18n/core/languages.d.ts +32 -0
- package/lib/i18n/core/languages.d.ts.map +1 -0
- package/lib/i18n/core/languages.js +41 -0
- package/lib/i18n/core/languages.js.map +1 -0
- package/lib/i18n/core/messageCatalog.d.ts +113 -0
- package/lib/i18n/core/messageCatalog.d.ts.map +1 -0
- package/lib/i18n/core/messageCatalog.js +135 -0
- package/lib/i18n/core/messageCatalog.js.map +1 -0
- package/lib/i18n/core/messageValues.d.ts +3 -0
- package/lib/i18n/core/messageValues.d.ts.map +1 -0
- package/lib/i18n/core/messageValues.js +2 -0
- package/lib/i18n/core/messageValues.js.map +1 -0
- package/lib/i18n/core/session.d.ts +51 -0
- package/lib/i18n/core/session.d.ts.map +1 -0
- package/lib/i18n/core/session.js +64 -0
- package/lib/i18n/core/session.js.map +1 -0
- package/lib/i18n/core/translateSetup.d.ts +28 -0
- package/lib/i18n/core/translateSetup.d.ts.map +1 -0
- package/lib/i18n/core/translateSetup.js +30 -0
- package/lib/i18n/core/translateSetup.js.map +1 -0
- package/lib/i18n/ui/LanguageSelect.d.ts +37 -0
- package/lib/i18n/ui/LanguageSelect.d.ts.map +1 -0
- package/lib/i18n/ui/LanguageSelect.js +27 -0
- package/lib/i18n/ui/LanguageSelect.js.map +1 -0
- package/lib/i18n/ui/index.d.ts +6 -0
- package/lib/i18n/ui/index.d.ts.map +1 -0
- package/lib/i18n/ui/index.js +4 -0
- package/lib/i18n/ui/index.js.map +1 -0
- package/lib/i18n/ui/useLanguage.d.ts +23 -0
- package/lib/i18n/ui/useLanguage.d.ts.map +1 -0
- package/lib/i18n/ui/useLanguage.js +36 -0
- package/lib/i18n/ui/useLanguage.js.map +1 -0
- package/lib/i18n/ui/useT.d.ts +47 -0
- package/lib/i18n/ui/useT.d.ts.map +1 -0
- package/lib/i18n/ui/useT.js +51 -0
- package/lib/i18n/ui/useT.js.map +1 -0
- package/lib/locales/de.json +442 -0
- package/lib/locales/en.json +442 -0
- package/lib/locales/es.json +442 -0
- package/lib/locales/fr.json +442 -0
- package/lib/molecule3d/core/gestures.d.ts +10 -0
- package/lib/molecule3d/core/gestures.d.ts.map +1 -1
- package/lib/molecule3d/core/gestures.js +39 -7
- package/lib/molecule3d/core/gestures.js.map +1 -1
- package/lib/molecule3d/ui/Molecule3DExport.d.ts.map +1 -1
- package/lib/molecule3d/ui/Molecule3DExport.js +3 -1
- package/lib/molecule3d/ui/Molecule3DExport.js.map +1 -1
- package/lib/molecule3d/ui/Molecule3DHelp.d.ts.map +1 -1
- package/lib/molecule3d/ui/Molecule3DHelp.js +7 -2
- package/lib/molecule3d/ui/Molecule3DHelp.js.map +1 -1
- package/lib/molecule3d/ui/Molecule3DOptions.d.ts.map +1 -1
- package/lib/molecule3d/ui/Molecule3DOptions.js +9 -9
- package/lib/molecule3d/ui/Molecule3DOptions.js.map +1 -1
- package/lib/molecule3d/ui/Molecule3DSurfaceColors.d.ts.map +1 -1
- package/lib/molecule3d/ui/Molecule3DSurfaceColors.js +8 -8
- package/lib/molecule3d/ui/Molecule3DSurfaceColors.js.map +1 -1
- package/lib/molecule3d/ui/Molecule3DToolbar.d.ts.map +1 -1
- package/lib/molecule3d/ui/Molecule3DToolbar.js +15 -10
- package/lib/molecule3d/ui/Molecule3DToolbar.js.map +1 -1
- package/lib/molecule3d/ui/MoleculeViewer3D.d.ts.map +1 -1
- package/lib/molecule3d/ui/MoleculeViewer3D.js +6 -3
- package/lib/molecule3d/ui/MoleculeViewer3D.js.map +1 -1
- package/lib/orbital/ui/AtomicOrbitalCanvas.d.ts.map +1 -1
- package/lib/orbital/ui/AtomicOrbitalCanvas.js +3 -1
- package/lib/orbital/ui/AtomicOrbitalCanvas.js.map +1 -1
- package/lib/orbital/ui/AtomicOrbitalControls.d.ts.map +1 -1
- package/lib/orbital/ui/AtomicOrbitalControls.js +12 -15
- package/lib/orbital/ui/AtomicOrbitalControls.js.map +1 -1
- package/lib/orbital/ui/AtomicOrbitalViewer.d.ts.map +1 -1
- package/lib/orbital/ui/AtomicOrbitalViewer.js +6 -3
- package/lib/orbital/ui/AtomicOrbitalViewer.js.map +1 -1
- package/lib/orbital/ui/capability.d.ts +4 -0
- package/lib/orbital/ui/capability.d.ts.map +1 -1
- package/lib/orbital/ui/capability.js +4 -0
- package/lib/orbital/ui/capability.js.map +1 -1
- package/lib/overlay/ui/OverlayBar.d.ts +1 -1
- package/lib/overlay/ui/OverlayBar.d.ts.map +1 -1
- package/lib/overlay/ui/OverlayBar.js +6 -3
- package/lib/overlay/ui/OverlayBar.js.map +1 -1
- package/lib/overlay/ui/OverlayInfo.d.ts +1 -1
- package/lib/overlay/ui/OverlayInfo.d.ts.map +1 -1
- package/lib/overlay/ui/OverlayInfo.js +5 -2
- package/lib/overlay/ui/OverlayInfo.js.map +1 -1
- package/lib/overlay/ui/OverlayPanel.d.ts +9 -2
- package/lib/overlay/ui/OverlayPanel.d.ts.map +1 -1
- package/lib/overlay/ui/OverlayPanel.js +5 -11
- package/lib/overlay/ui/OverlayPanel.js.map +1 -1
- package/lib/overlay/ui/OverlayReadout.d.ts.map +1 -1
- package/lib/overlay/ui/OverlayReadout.js +3 -1
- package/lib/overlay/ui/OverlayReadout.js.map +1 -1
- package/lib/pedagogy/ui/ExerciseActions.d.ts +1 -1
- package/lib/pedagogy/ui/ExerciseActions.d.ts.map +1 -1
- package/lib/pedagogy/ui/ExerciseActions.js +9 -2
- package/lib/pedagogy/ui/ExerciseActions.js.map +1 -1
- package/lib/pedagogy/ui/ExerciseProgressHeader.d.ts +1 -1
- package/lib/pedagogy/ui/ExerciseProgressHeader.d.ts.map +1 -1
- package/lib/pedagogy/ui/ExerciseProgressHeader.js +9 -5
- package/lib/pedagogy/ui/ExerciseProgressHeader.js.map +1 -1
- package/lib/pedagogy/ui/GlossaryIndex.d.ts +1 -1
- package/lib/pedagogy/ui/GlossaryIndex.d.ts.map +1 -1
- package/lib/pedagogy/ui/GlossaryIndex.js +6 -8
- package/lib/pedagogy/ui/GlossaryIndex.js.map +1 -1
- package/lib/pedagogy/ui/HintLadder.d.ts +2 -2
- package/lib/pedagogy/ui/HintLadder.d.ts.map +1 -1
- package/lib/pedagogy/ui/HintLadder.js +8 -2
- package/lib/pedagogy/ui/HintLadder.js.map +1 -1
- package/lib/pedagogy/ui/SyntaxTooltip.d.ts +4 -4
- package/lib/pedagogy/ui/SyntaxTooltip.d.ts.map +1 -1
- package/lib/pedagogy/ui/SyntaxTooltip.js +4 -2
- package/lib/pedagogy/ui/SyntaxTooltip.js.map +1 -1
- package/lib/pedagogy/ui/TutorialStepStrip.d.ts.map +1 -1
- package/lib/pedagogy/ui/TutorialStepStrip.js +7 -2
- package/lib/pedagogy/ui/TutorialStepStrip.js.map +1 -1
- package/lib/periodic/ui/CategoryLegend.d.ts.map +1 -1
- package/lib/periodic/ui/CategoryLegend.js +3 -1
- package/lib/periodic/ui/CategoryLegend.js.map +1 -1
- package/lib/periodic/ui/ElementCell.d.ts.map +1 -1
- package/lib/periodic/ui/ElementCell.js +7 -1
- package/lib/periodic/ui/ElementCell.js.map +1 -1
- package/lib/periodic/ui/PeriodicTable.d.ts.map +1 -1
- package/lib/periodic/ui/PeriodicTable.js +3 -1
- package/lib/periodic/ui/PeriodicTable.js.map +1 -1
- package/lib/periodic/ui/PeriodicTableChrome.d.ts.map +1 -1
- package/lib/periodic/ui/PeriodicTableChrome.js +4 -2
- package/lib/periodic/ui/PeriodicTableChrome.js.map +1 -1
- package/lib/share/ui/ShareButton.d.ts +2 -2
- package/lib/share/ui/ShareButton.d.ts.map +1 -1
- package/lib/share/ui/ShareButton.js +5 -2
- package/lib/share/ui/ShareButton.js.map +1 -1
- package/lib/share/ui/ShareConfigOptions.d.ts.map +1 -1
- package/lib/share/ui/ShareConfigOptions.js +4 -2
- package/lib/share/ui/ShareConfigOptions.js.map +1 -1
- package/lib/share/ui/ShareDialog.d.ts.map +1 -1
- package/lib/share/ui/ShareDialog.js +3 -1
- package/lib/share/ui/ShareDialog.js.map +1 -1
- package/lib/share/ui/ShareDialogContent.d.ts.map +1 -1
- package/lib/share/ui/ShareDialogContent.js +10 -1
- package/lib/share/ui/ShareDialogContent.js.map +1 -1
- package/lib/share/ui/SharePresetTabs.d.ts.map +1 -1
- package/lib/share/ui/SharePresetTabs.js +3 -1
- package/lib/share/ui/SharePresetTabs.js.map +1 -1
- package/lib/slides/ui/BackToSlides.d.ts.map +1 -1
- package/lib/slides/ui/BackToSlides.js +4 -2
- package/lib/slides/ui/BackToSlides.js.map +1 -1
- package/lib/slides/ui/EmbedSlide.d.ts.map +1 -1
- package/lib/slides/ui/EmbedSlide.js +3 -1
- package/lib/slides/ui/EmbedSlide.js.map +1 -1
- package/lib/slides/ui/Slide.d.ts.map +1 -1
- package/lib/slides/ui/Slide.js +3 -1
- package/lib/slides/ui/Slide.js.map +1 -1
- package/lib/slides/ui/SlideshowBar.d.ts.map +1 -1
- package/lib/slides/ui/SlideshowBar.js +5 -3
- package/lib/slides/ui/SlideshowBar.js.map +1 -1
- package/lib/slides/ui/TalkList.d.ts +1 -1
- package/lib/slides/ui/TalkList.d.ts.map +1 -1
- package/lib/slides/ui/TalkList.js +4 -2
- package/lib/slides/ui/TalkList.js.map +1 -1
- package/lib/structure/core/editorGuide.d.ts +14 -0
- package/lib/structure/core/editorGuide.d.ts.map +1 -1
- package/lib/structure/core/editorGuide.js +117 -19
- package/lib/structure/core/editorGuide.js.map +1 -1
- package/lib/structure/core/editorToolbar.d.ts +3 -1
- package/lib/structure/core/editorToolbar.d.ts.map +1 -1
- package/lib/structure/core/editorToolbar.js +44 -23
- package/lib/structure/core/editorToolbar.js.map +1 -1
- package/lib/structure/ui/EditorHelpButton.d.ts.map +1 -1
- package/lib/structure/ui/EditorHelpButton.js +3 -2
- package/lib/structure/ui/EditorHelpButton.js.map +1 -1
- package/lib/structure/ui/StructureEditor.d.ts.map +1 -1
- package/lib/structure/ui/StructureEditor.js +3 -1
- package/lib/structure/ui/StructureEditor.js.map +1 -1
- package/lib/structure/ui/StructureEditorHelp.d.ts.map +1 -1
- package/lib/structure/ui/StructureEditorHelp.js +12 -3
- package/lib/structure/ui/StructureEditorHelp.js.map +1 -1
- package/lib/structure/ui/ToolbarTooltip.d.ts.map +1 -1
- package/lib/structure/ui/ToolbarTooltip.js +5 -3
- package/lib/structure/ui/ToolbarTooltip.js.map +1 -1
- package/lib/ui.d.ts +1 -0
- package/lib/ui.d.ts.map +1 -1
- package/lib/ui.js +1 -0
- package/lib/ui.js.map +1 -1
- package/package.json +4 -2
- package/src/about/ui/AboutBuild.tsx +23 -16
- package/src/about/ui/AboutCitations.tsx +3 -1
- package/src/about/ui/AboutPage.tsx +38 -12
- package/src/about/ui/AboutProvidedBy.tsx +13 -3
- package/src/capsule/ui/Capsule.tsx +48 -0
- package/src/capsule/ui/CapsuleFilter.tsx +38 -114
- package/src/capsule/ui/capsuleFilterCapsules.tsx +110 -0
- package/src/chart/ui/ChartTrackingLayer.tsx +4 -2
- package/src/chrome/ui/SiteHeader.tsx +5 -3
- package/src/citation/ui/CitationMenu.tsx +9 -5
- package/src/citation/ui/CiteButton.tsx +4 -2
- package/src/citation/ui/CopyFormatEntries.tsx +3 -1
- package/src/citation/ui/WorkEntry.tsx +5 -3
- package/src/citation/ui/entries.tsx +9 -2
- package/src/citation/ui/useCopyFeedback.ts +11 -4
- package/src/clipboard/ui/ClickToCopy.tsx +15 -5
- package/src/clipboard/ui/CopyButton.tsx +14 -10
- package/src/color/ui/ColorScaleEditor.tsx +17 -15
- package/src/color/ui/ColorScaleEntry.tsx +7 -3
- package/src/color/ui/ColorScaleLegend.tsx +7 -1
- package/src/color/ui/ColorScaleSelect.tsx +12 -6
- package/src/confirm/ui/ConfirmButton.tsx +9 -11
- package/src/core.ts +1 -0
- package/src/credits/ui/CreditsList.tsx +5 -1
- package/src/delimited/ui/DelimitedTextDialog.tsx +10 -10
- package/src/delimited/ui/DelimitedTextPanel.tsx +19 -12
- package/src/download/ui/FigureDownload.tsx +7 -5
- package/src/download/ui/FigureDownloadPanel.tsx +31 -25
- package/src/ecosystem/ui/EcosystemButton.tsx +5 -3
- package/src/ecosystem/ui/EcosystemLinks.tsx +10 -10
- package/src/ecosystem/ui/EcosystemMenu.tsx +3 -1
- package/src/ecosystem/ui/SiteGroupSection.tsx +6 -2
- package/src/ecosystem/ui/SiteTile.tsx +6 -2
- package/src/error/ui/ErrorFallback.tsx +13 -12
- package/src/help/ui/HelpBody.tsx +4 -2
- package/src/help/ui/HelpIcon.tsx +6 -3
- package/src/help/ui/HelpToolbarButton.tsx +4 -1
- package/src/help/ui/helpName.ts +10 -2
- package/src/i18n/core/chromeCatalog.ts +35 -0
- package/src/i18n/core/index.ts +26 -0
- package/src/i18n/core/languages.ts +46 -0
- package/src/i18n/core/messageCatalog.ts +202 -0
- package/src/i18n/core/messageValues.ts +2 -0
- package/src/i18n/core/session.ts +82 -0
- package/src/i18n/core/translateSetup.ts +47 -0
- package/src/i18n/ui/LanguageSelect.tsx +72 -0
- package/src/i18n/ui/index.ts +9 -0
- package/src/i18n/ui/useLanguage.ts +48 -0
- package/src/i18n/ui/useT.ts +90 -0
- package/src/locales/de.json +442 -0
- package/src/locales/en.json +442 -0
- package/src/locales/es.json +442 -0
- package/src/locales/fr.json +442 -0
- package/src/molecule3d/core/gestures.ts +44 -7
- package/src/molecule3d/ui/Molecule3DExport.tsx +3 -1
- package/src/molecule3d/ui/Molecule3DHelp.tsx +17 -6
- package/src/molecule3d/ui/Molecule3DOptions.tsx +13 -13
- package/src/molecule3d/ui/Molecule3DSurfaceColors.tsx +16 -13
- package/src/molecule3d/ui/Molecule3DToolbar.tsx +29 -18
- package/src/molecule3d/ui/MoleculeViewer3D.tsx +13 -8
- package/src/orbital/ui/AtomicOrbitalCanvas.tsx +3 -1
- package/src/orbital/ui/AtomicOrbitalControls.tsx +15 -20
- package/src/orbital/ui/AtomicOrbitalViewer.tsx +13 -13
- package/src/orbital/ui/capability.ts +10 -0
- package/src/overlay/ui/OverlayBar.tsx +7 -4
- package/src/overlay/ui/OverlayInfo.tsx +6 -3
- package/src/overlay/ui/OverlayPanel.tsx +10 -7
- package/src/overlay/ui/OverlayReadout.tsx +3 -1
- package/src/pedagogy/ui/ExerciseActions.tsx +16 -6
- package/src/pedagogy/ui/ExerciseProgressHeader.tsx +13 -11
- package/src/pedagogy/ui/GlossaryIndex.tsx +11 -12
- package/src/pedagogy/ui/HintLadder.tsx +15 -12
- package/src/pedagogy/ui/SyntaxTooltip.tsx +9 -7
- package/src/pedagogy/ui/TutorialStepStrip.tsx +8 -3
- package/src/periodic/ui/CategoryLegend.tsx +6 -1
- package/src/periodic/ui/ElementCell.tsx +7 -1
- package/src/periodic/ui/PeriodicTable.tsx +3 -1
- package/src/periodic/ui/PeriodicTableChrome.tsx +4 -2
- package/src/share/ui/ShareButton.tsx +8 -5
- package/src/share/ui/ShareConfigOptions.tsx +6 -7
- package/src/share/ui/ShareDialog.tsx +3 -1
- package/src/share/ui/ShareDialogContent.tsx +20 -10
- package/src/share/ui/SharePresetTabs.tsx +3 -1
- package/src/slides/ui/BackToSlides.tsx +4 -2
- package/src/slides/ui/EmbedSlide.tsx +3 -3
- package/src/slides/ui/Slide.tsx +3 -1
- package/src/slides/ui/SlideshowBar.tsx +12 -4
- package/src/slides/ui/TalkList.tsx +8 -10
- package/src/structure/core/editorGuide.ts +126 -19
- package/src/structure/core/editorToolbar.ts +52 -24
- package/src/structure/ui/EditorHelpButton.tsx +9 -4
- package/src/structure/ui/StructureEditor.tsx +7 -1
- package/src/structure/ui/StructureEditorHelp.tsx +34 -11
- package/src/structure/ui/ToolbarTooltip.tsx +8 -4
- package/src/ui.ts +1 -0
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { Intent } from '@blueprintjs/core';
|
|
2
|
-
import {
|
|
3
|
-
import type { CSSProperties, ReactElement } from 'react';
|
|
2
|
+
import type { CSSProperties, ReactElement, ReactNode } from 'react';
|
|
4
3
|
|
|
5
|
-
import {
|
|
4
|
+
import { useChromeT } from '../../i18n/ui/useT.ts';
|
|
6
5
|
import { joinClassNames } from '../../shared/ui/joinClassNames.ts';
|
|
6
|
+
import { TOKEN } from '../../tokens/core/familyTokens.ts';
|
|
7
|
+
|
|
8
|
+
import { capsuleFilterCapsules } from './capsuleFilterCapsules.tsx';
|
|
7
9
|
|
|
8
10
|
/** One capsule of a {@link CapsuleFilter} row. */
|
|
9
11
|
export interface CapsuleOption<TValue extends string = string> {
|
|
@@ -43,6 +45,13 @@ export interface CapsuleAllOption {
|
|
|
43
45
|
* @default undefined
|
|
44
46
|
*/
|
|
45
47
|
title?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Whether the capsule is filled, for a row that reads its selection back
|
|
50
|
+
* from a richer state: a pick no capsule can spell leaves `values` empty
|
|
51
|
+
* without meaning every row is kept.
|
|
52
|
+
* @default undefined — filled while no capsule is selected
|
|
53
|
+
*/
|
|
54
|
+
selected?: boolean;
|
|
46
55
|
}
|
|
47
56
|
|
|
48
57
|
/** What every row of filter capsules needs, whatever it selects. */
|
|
@@ -51,7 +60,7 @@ export interface CapsuleFilterBaseProps<TValue extends string = string> {
|
|
|
51
60
|
options: ReadonlyArray<CapsuleOption<TValue>>;
|
|
52
61
|
/**
|
|
53
62
|
* What the group is called, for a screen reader reaching the row.
|
|
54
|
-
* @default '
|
|
63
|
+
* @default the chrome's own word for it, in the language of the page
|
|
55
64
|
*/
|
|
56
65
|
label?: string;
|
|
57
66
|
/**
|
|
@@ -64,6 +73,14 @@ export interface CapsuleFilterBaseProps<TValue extends string = string> {
|
|
|
64
73
|
* @default undefined
|
|
65
74
|
*/
|
|
66
75
|
className?: string;
|
|
76
|
+
/**
|
|
77
|
+
* What the row reads back, drawn muted after the last capsule: the selection
|
|
78
|
+
* the capsules cannot spell on their own, or how else it is made. It wraps
|
|
79
|
+
* with them rather than sitting on a line of its own, so the one place a
|
|
80
|
+
* selection is made is the one place it is read.
|
|
81
|
+
* @default undefined — the row is capsules alone
|
|
82
|
+
*/
|
|
83
|
+
note?: ReactNode;
|
|
67
84
|
}
|
|
68
85
|
|
|
69
86
|
/** A row where exactly one capsule is selected. */
|
|
@@ -109,136 +126,43 @@ export type CapsuleFilterProps<TValue extends string = string> =
|
|
|
109
126
|
* Every capsule keeps its semantic colour whether or not it is selected, so
|
|
110
127
|
* what a status means stays learnable — the filled shape is what encodes the
|
|
111
128
|
* selection. Each is a real interactive tag, so the row is reachable by tab and
|
|
112
|
-
* a capsule answers to Enter and Space.
|
|
129
|
+
* a capsule answers to Enter and Space. A `note` rides at the end of the row,
|
|
130
|
+
* which is where a selection finer than the capsules can spell is read back.
|
|
113
131
|
* @param props - See {@link CapsuleFilterProps}.
|
|
114
132
|
* @returns The capsule row.
|
|
115
133
|
*/
|
|
116
134
|
export function CapsuleFilter<TValue extends string = string>(
|
|
117
135
|
props: CapsuleFilterProps<TValue>,
|
|
118
136
|
): ReactElement {
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
const { label = 'Filter', className } = props;
|
|
137
|
+
const { label, className, note } = props;
|
|
138
|
+
const t = useChromeT();
|
|
122
139
|
|
|
123
140
|
return (
|
|
124
141
|
<div
|
|
125
142
|
role="group"
|
|
126
|
-
aria-label={label}
|
|
143
|
+
aria-label={label ?? t('capsule.filter')}
|
|
127
144
|
className={joinClassNames('capsule-filter', className)}
|
|
128
145
|
style={ROW_STYLE}
|
|
129
146
|
>
|
|
130
|
-
{
|
|
147
|
+
{capsuleFilterCapsules(props)}
|
|
148
|
+
{note === undefined ? null : (
|
|
149
|
+
<span className="capsule-filter__note" style={NOTE_STYLE}>
|
|
150
|
+
{note}
|
|
151
|
+
</span>
|
|
152
|
+
)}
|
|
131
153
|
</div>
|
|
132
154
|
);
|
|
133
155
|
}
|
|
134
156
|
|
|
135
|
-
function singleCapsules<TValue extends string>(
|
|
136
|
-
props: SingleCapsuleFilterProps<TValue>,
|
|
137
|
-
): ReactElement[] {
|
|
138
|
-
const { options, value, onChange, formatCount = formatInteger } = props;
|
|
139
|
-
const capsules: ReactElement[] = [];
|
|
140
|
-
for (const option of options) {
|
|
141
|
-
capsules.push(
|
|
142
|
-
<Capsule
|
|
143
|
-
key={`option:${option.value}`}
|
|
144
|
-
text={capsuleText(option, formatCount)}
|
|
145
|
-
selected={option.value === value}
|
|
146
|
-
intent={option.intent}
|
|
147
|
-
title={option.title}
|
|
148
|
-
onClick={() => onChange(option.value)}
|
|
149
|
-
/>,
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
return capsules;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
function multipleCapsules<TValue extends string>(
|
|
156
|
-
props: MultipleCapsuleFilterProps<TValue>,
|
|
157
|
-
): ReactElement[] {
|
|
158
|
-
const {
|
|
159
|
-
options,
|
|
160
|
-
values,
|
|
161
|
-
onChange,
|
|
162
|
-
allOption,
|
|
163
|
-
formatCount = formatInteger,
|
|
164
|
-
} = props;
|
|
165
|
-
const capsules: ReactElement[] = [];
|
|
166
|
-
if (allOption !== undefined) {
|
|
167
|
-
capsules.push(
|
|
168
|
-
<Capsule
|
|
169
|
-
key="all"
|
|
170
|
-
text={capsuleText(allOption, formatCount)}
|
|
171
|
-
selected={values.length === 0}
|
|
172
|
-
title={allOption.title}
|
|
173
|
-
onClick={() => onChange([])}
|
|
174
|
-
/>,
|
|
175
|
-
);
|
|
176
|
-
}
|
|
177
|
-
for (const option of options) {
|
|
178
|
-
capsules.push(
|
|
179
|
-
<Capsule
|
|
180
|
-
key={`option:${option.value}`}
|
|
181
|
-
text={capsuleText(option, formatCount)}
|
|
182
|
-
selected={values.includes(option.value)}
|
|
183
|
-
intent={option.intent}
|
|
184
|
-
title={option.title}
|
|
185
|
-
onClick={() => onChange(toggled(options, values, option.value))}
|
|
186
|
-
/>,
|
|
187
|
-
);
|
|
188
|
-
}
|
|
189
|
-
return capsules;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
interface CapsuleProps {
|
|
193
|
-
text: string;
|
|
194
|
-
selected: boolean;
|
|
195
|
-
intent?: Intent;
|
|
196
|
-
title: string | undefined;
|
|
197
|
-
onClick: () => void;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
function Capsule(props: CapsuleProps): ReactElement {
|
|
201
|
-
const { text, selected, intent, title, onClick } = props;
|
|
202
|
-
return (
|
|
203
|
-
<Tag
|
|
204
|
-
interactive
|
|
205
|
-
round
|
|
206
|
-
minimal={!selected}
|
|
207
|
-
intent={intent}
|
|
208
|
-
aria-pressed={selected}
|
|
209
|
-
htmlTitle={title}
|
|
210
|
-
onClick={onClick}
|
|
211
|
-
>
|
|
212
|
-
{text}
|
|
213
|
-
</Tag>
|
|
214
|
-
);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
function capsuleText(
|
|
218
|
-
capsule: { label: string; count?: number },
|
|
219
|
-
formatCount: (count: number) => string,
|
|
220
|
-
): string {
|
|
221
|
-
return capsule.count === undefined
|
|
222
|
-
? capsule.label
|
|
223
|
-
: `${capsule.label} (${formatCount(capsule.count)})`;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
function toggled<TValue extends string>(
|
|
227
|
-
options: ReadonlyArray<CapsuleOption<TValue>>,
|
|
228
|
-
values: readonly TValue[],
|
|
229
|
-
flipped: TValue,
|
|
230
|
-
): TValue[] {
|
|
231
|
-
const next: TValue[] = [];
|
|
232
|
-
for (const option of options) {
|
|
233
|
-
const kept = values.includes(option.value);
|
|
234
|
-
if (option.value === flipped ? !kept : kept) next.push(option.value);
|
|
235
|
-
}
|
|
236
|
-
return next;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
157
|
const ROW_STYLE = {
|
|
240
158
|
display: 'flex',
|
|
241
159
|
flexWrap: 'wrap',
|
|
242
160
|
alignItems: 'center',
|
|
243
161
|
gap: 6,
|
|
244
162
|
} as const satisfies CSSProperties;
|
|
163
|
+
|
|
164
|
+
const NOTE_STYLE = {
|
|
165
|
+
marginLeft: 2,
|
|
166
|
+
color: TOKEN.textMuted,
|
|
167
|
+
fontSize: '0.75rem',
|
|
168
|
+
} as const satisfies CSSProperties;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The capsules of a filter row, and nothing around them.
|
|
3
|
+
*
|
|
4
|
+
* They are a plain function of the row's props; the row itself reads the
|
|
5
|
+
* language of the page, which only a render can do, so the two are separate.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { ReactElement } from 'react';
|
|
9
|
+
|
|
10
|
+
import { formatInteger } from '../../format/core/numbers.ts';
|
|
11
|
+
|
|
12
|
+
import { Capsule } from './Capsule.tsx';
|
|
13
|
+
import type {
|
|
14
|
+
CapsuleFilterProps,
|
|
15
|
+
CapsuleOption,
|
|
16
|
+
MultipleCapsuleFilterProps,
|
|
17
|
+
SingleCapsuleFilterProps,
|
|
18
|
+
} from './CapsuleFilter.tsx';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The capsules a row draws, in order.
|
|
22
|
+
* @param props - See `CapsuleFilterProps`.
|
|
23
|
+
* @returns The capsules.
|
|
24
|
+
*/
|
|
25
|
+
export function capsuleFilterCapsules<TValue extends string = string>(
|
|
26
|
+
props: CapsuleFilterProps<TValue>,
|
|
27
|
+
): ReactElement[] {
|
|
28
|
+
return props.multiple === true
|
|
29
|
+
? multipleCapsules(props)
|
|
30
|
+
: singleCapsules(props);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function singleCapsules<TValue extends string>(
|
|
34
|
+
props: SingleCapsuleFilterProps<TValue>,
|
|
35
|
+
): ReactElement[] {
|
|
36
|
+
const { options, value, onChange, formatCount = formatInteger } = props;
|
|
37
|
+
const capsules: ReactElement[] = [];
|
|
38
|
+
for (const option of options) {
|
|
39
|
+
capsules.push(
|
|
40
|
+
<Capsule
|
|
41
|
+
key={`option:${option.value}`}
|
|
42
|
+
text={capsuleText(option, formatCount)}
|
|
43
|
+
selected={option.value === value}
|
|
44
|
+
intent={option.intent}
|
|
45
|
+
title={option.title}
|
|
46
|
+
onClick={() => onChange(option.value)}
|
|
47
|
+
/>,
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
return capsules;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function multipleCapsules<TValue extends string>(
|
|
54
|
+
props: MultipleCapsuleFilterProps<TValue>,
|
|
55
|
+
): ReactElement[] {
|
|
56
|
+
const {
|
|
57
|
+
options,
|
|
58
|
+
values,
|
|
59
|
+
onChange,
|
|
60
|
+
allOption,
|
|
61
|
+
formatCount = formatInteger,
|
|
62
|
+
} = props;
|
|
63
|
+
const capsules: ReactElement[] = [];
|
|
64
|
+
if (allOption !== undefined) {
|
|
65
|
+
capsules.push(
|
|
66
|
+
<Capsule
|
|
67
|
+
key="all"
|
|
68
|
+
text={capsuleText(allOption, formatCount)}
|
|
69
|
+
selected={allOption.selected ?? values.length === 0}
|
|
70
|
+
title={allOption.title}
|
|
71
|
+
onClick={() => onChange([])}
|
|
72
|
+
/>,
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
for (const option of options) {
|
|
76
|
+
capsules.push(
|
|
77
|
+
<Capsule
|
|
78
|
+
key={`option:${option.value}`}
|
|
79
|
+
text={capsuleText(option, formatCount)}
|
|
80
|
+
selected={values.includes(option.value)}
|
|
81
|
+
intent={option.intent}
|
|
82
|
+
title={option.title}
|
|
83
|
+
onClick={() => onChange(toggled(options, values, option.value))}
|
|
84
|
+
/>,
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
return capsules;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function capsuleText(
|
|
91
|
+
capsule: { label: string; count?: number },
|
|
92
|
+
formatCount: (count: number) => string,
|
|
93
|
+
): string {
|
|
94
|
+
return capsule.count === undefined
|
|
95
|
+
? capsule.label
|
|
96
|
+
: `${capsule.label} (${formatCount(capsule.count)})`;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function toggled<TValue extends string>(
|
|
100
|
+
options: ReadonlyArray<CapsuleOption<TValue>>,
|
|
101
|
+
values: readonly TValue[],
|
|
102
|
+
flipped: TValue,
|
|
103
|
+
): TValue[] {
|
|
104
|
+
const next: TValue[] = [];
|
|
105
|
+
for (const option of options) {
|
|
106
|
+
const kept = values.includes(option.value);
|
|
107
|
+
if (option.value === flipped ? !kept : kept) next.push(option.value);
|
|
108
|
+
}
|
|
109
|
+
return next;
|
|
110
|
+
}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import type { CSSProperties, MouseEvent, ReactElement } from 'react';
|
|
9
9
|
import { useRef } from 'react';
|
|
10
10
|
|
|
11
|
+
import { useChromeT } from '../../i18n/ui/useT.ts';
|
|
11
12
|
import type { ChartAxisScale } from '../core/chartAxisScale.ts';
|
|
12
13
|
import type { ChartBand } from '../core/chartBand.ts';
|
|
13
14
|
import { chartBandCenter, chartBandIndexAt } from '../core/chartBand.ts';
|
|
@@ -64,6 +65,7 @@ export function ChartTrackingLayer(
|
|
|
64
65
|
): ReactElement {
|
|
65
66
|
const { plot, band, y, categories, series, index, onTrack, onSelect } = props;
|
|
66
67
|
const { slotAxis, title } = props;
|
|
68
|
+
const t = useChromeT();
|
|
67
69
|
const entered = useRef<number | null>(null);
|
|
68
70
|
const slot = index ?? -1;
|
|
69
71
|
const tracked = slot >= 0 && slot < band.count;
|
|
@@ -137,8 +139,8 @@ export function ChartTrackingLayer(
|
|
|
137
139
|
role="button"
|
|
138
140
|
aria-label={
|
|
139
141
|
tracked
|
|
140
|
-
?
|
|
141
|
-
: (title ?? '
|
|
142
|
+
? t('chart.measurement', { name: categories[slot] ?? '' })
|
|
143
|
+
: (title ?? t('chart.measurements'))
|
|
142
144
|
}
|
|
143
145
|
onPointerDown={move}
|
|
144
146
|
onPointerMove={move}
|
|
@@ -5,6 +5,7 @@ import { siteById } from '../../ecosystem/core/lookup.ts';
|
|
|
5
5
|
import type { SiteId, SiteRecord } from '../../ecosystem/core/sites.ts';
|
|
6
6
|
import { Wordmark } from '../../ecosystem/ui/Wordmark.tsx';
|
|
7
7
|
import { SiteMark } from '../../ecosystem/ui/marks.tsx';
|
|
8
|
+
import { useChromeT } from '../../i18n/ui/useT.ts';
|
|
8
9
|
|
|
9
10
|
import { NavLink } from './NavLink.tsx';
|
|
10
11
|
import { NavMenuButton } from './NavMenuButton.tsx';
|
|
@@ -86,7 +87,7 @@ export interface SiteHeaderProps {
|
|
|
86
87
|
/**
|
|
87
88
|
* What the menu the pages fold into on a phone is called, for the pointer
|
|
88
89
|
* and a screen reader.
|
|
89
|
-
* @default '
|
|
90
|
+
* @default the chrome's own word for it, in the language of the page
|
|
90
91
|
*/
|
|
91
92
|
pagesLabel?: string;
|
|
92
93
|
}
|
|
@@ -118,8 +119,9 @@ export function SiteHeader(props: SiteHeaderProps): ReactElement | null {
|
|
|
118
119
|
onHome,
|
|
119
120
|
markSize = 28,
|
|
120
121
|
width = 'page',
|
|
121
|
-
pagesLabel
|
|
122
|
+
pagesLabel,
|
|
122
123
|
} = props;
|
|
124
|
+
const t = useChromeT();
|
|
123
125
|
|
|
124
126
|
if (embedded) return null;
|
|
125
127
|
|
|
@@ -158,7 +160,7 @@ export function SiteHeader(props: SiteHeaderProps): ReactElement | null {
|
|
|
158
160
|
{nav.length > 1 ? (
|
|
159
161
|
<div className="app-header-nav-menu">
|
|
160
162
|
<NavMenuButton
|
|
161
|
-
label={pagesLabel}
|
|
163
|
+
label={pagesLabel ?? t('chrome.pages')}
|
|
162
164
|
icon="menu"
|
|
163
165
|
compact
|
|
164
166
|
items={nav}
|
|
@@ -2,6 +2,7 @@ import { Menu, MenuDivider, MenuItem } from '@blueprintjs/core';
|
|
|
2
2
|
import { SvgLogoDoi } from 'cheminfo-font';
|
|
3
3
|
import type { CSSProperties, ReactElement } from 'react';
|
|
4
4
|
|
|
5
|
+
import { useChromeT } from '../../i18n/ui/useT.ts';
|
|
5
6
|
import { CITATION_DOWNLOADS } from '../core/formats.ts';
|
|
6
7
|
import type { Reference } from '../core/reference.ts';
|
|
7
8
|
import { doiUrl } from '../core/reference.ts';
|
|
@@ -31,7 +32,7 @@ export interface CitedWorksProps {
|
|
|
31
32
|
/**
|
|
32
33
|
* The line heading the menu, saying which of the works a reader is expected
|
|
33
34
|
* to cite.
|
|
34
|
-
* @default '
|
|
35
|
+
* @default the chrome's own line, in the language of the page
|
|
35
36
|
*/
|
|
36
37
|
guidance?: string;
|
|
37
38
|
}
|
|
@@ -69,6 +70,7 @@ export function CitationMenu(props: CitationMenuProps): ReactElement {
|
|
|
69
70
|
*/
|
|
70
71
|
function OneWorkMenu(props: CitedReferenceProps): ReactElement {
|
|
71
72
|
const { reference } = props;
|
|
73
|
+
const t = useChromeT();
|
|
72
74
|
const feedback = useCopyFeedback();
|
|
73
75
|
const references = [reference];
|
|
74
76
|
|
|
@@ -82,7 +84,7 @@ function OneWorkMenu(props: CitedReferenceProps): ReactElement {
|
|
|
82
84
|
target="_blank"
|
|
83
85
|
rel="noreferrer"
|
|
84
86
|
/>
|
|
85
|
-
<MenuDivider title=
|
|
87
|
+
<MenuDivider title={t('cite.copyReferenceAs')} />
|
|
86
88
|
<CopyFormatEntries references={references} feedback={feedback} />
|
|
87
89
|
<ImportSection references={references} />
|
|
88
90
|
</Menu>
|
|
@@ -97,6 +99,7 @@ function OneWorkMenu(props: CitedReferenceProps): ReactElement {
|
|
|
97
99
|
*/
|
|
98
100
|
function WorkSetMenu(props: CitedWorksProps): ReactElement {
|
|
99
101
|
const { works, guidance } = props;
|
|
102
|
+
const t = useChromeT();
|
|
100
103
|
const feedback = useCopyFeedback();
|
|
101
104
|
const references = citedReferences(works);
|
|
102
105
|
const both = works.length === 2;
|
|
@@ -106,14 +109,14 @@ function WorkSetMenu(props: CitedWorksProps): ReactElement {
|
|
|
106
109
|
<MenuDivider
|
|
107
110
|
title={
|
|
108
111
|
guidance ??
|
|
109
|
-
(both ? '
|
|
112
|
+
(both ? t('cite.pleaseCiteBoth') : t('cite.pleaseCiteEvery'))
|
|
110
113
|
}
|
|
111
114
|
/>
|
|
112
115
|
{works.map((work) => (
|
|
113
116
|
<WorkEntry key={work.reference.doi} work={work} feedback={feedback} />
|
|
114
117
|
))}
|
|
115
118
|
<MenuDivider
|
|
116
|
-
title={both ? '
|
|
119
|
+
title={both ? t('cite.copyBothAs') : t('cite.copyEveryAs')}
|
|
117
120
|
/>
|
|
118
121
|
<CopyFormatEntries references={references} feedback={feedback} />
|
|
119
122
|
<ImportSection references={references} />
|
|
@@ -132,9 +135,10 @@ function ImportSection(props: {
|
|
|
132
135
|
references: readonly Reference[];
|
|
133
136
|
}): ReactElement {
|
|
134
137
|
const { references } = props;
|
|
138
|
+
const t = useChromeT();
|
|
135
139
|
return (
|
|
136
140
|
<>
|
|
137
|
-
<MenuDivider title=
|
|
141
|
+
<MenuDivider title={t('cite.importIntoManager')} />
|
|
138
142
|
{CITATION_DOWNLOADS.map((download) => (
|
|
139
143
|
<DownloadEntry
|
|
140
144
|
key={download.format}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ReactElement } from 'react';
|
|
2
2
|
|
|
3
|
+
import { useChromeT } from '../../i18n/ui/useT.ts';
|
|
3
4
|
import type { HeaderButtonProps } from '../../shared/ui/MenuButton.tsx';
|
|
4
5
|
import { MenuButton } from '../../shared/ui/MenuButton.tsx';
|
|
5
6
|
|
|
@@ -10,7 +11,7 @@ interface CiteButtonBaseProps extends HeaderButtonProps {
|
|
|
10
11
|
/**
|
|
11
12
|
* Text of the button. In a compact bar it is not written, but it stays what
|
|
12
13
|
* the pointer and a screen reader are told.
|
|
13
|
-
* @default '
|
|
14
|
+
* @default the chrome's own word for it, in the language of the page
|
|
14
15
|
*/
|
|
15
16
|
label?: string;
|
|
16
17
|
}
|
|
@@ -33,7 +34,8 @@ export type CiteButtonProps = CiteOneWorkProps | CiteWorksProps;
|
|
|
33
34
|
* @returns The button and its menu.
|
|
34
35
|
*/
|
|
35
36
|
export function CiteButton(props: CiteButtonProps): ReactElement {
|
|
36
|
-
const
|
|
37
|
+
const t = useChromeT();
|
|
38
|
+
const label = props.label ?? t('cite.button');
|
|
37
39
|
|
|
38
40
|
return (
|
|
39
41
|
<MenuButton
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { MenuItem } from '@blueprintjs/core';
|
|
2
2
|
import type { ReactElement } from 'react';
|
|
3
3
|
|
|
4
|
+
import { useChromeT } from '../../i18n/ui/useT.ts';
|
|
4
5
|
import { CITATION_FORMATS } from '../core/formats.ts';
|
|
5
6
|
import type { Reference } from '../core/reference.ts';
|
|
6
7
|
import { CITATION_STYLES } from '../core/segments.ts';
|
|
@@ -39,6 +40,7 @@ export function CopyFormatEntries(
|
|
|
39
40
|
props: CopyFormatEntriesProps,
|
|
40
41
|
): ReactElement[] {
|
|
41
42
|
const { references, feedback, keyPrefix = '', styled = true } = props;
|
|
43
|
+
const t = useChromeT();
|
|
42
44
|
|
|
43
45
|
return CITATION_FORMATS.map((format) => {
|
|
44
46
|
if (!styled || !format.styled) {
|
|
@@ -60,7 +62,7 @@ export function CopyFormatEntries(
|
|
|
60
62
|
<MenuItem
|
|
61
63
|
key={format.id}
|
|
62
64
|
icon="clipboard"
|
|
63
|
-
text={format.label}
|
|
65
|
+
text={t.or(`cite.format.${format.id}`, format.label)}
|
|
64
66
|
label={format.hint}
|
|
65
67
|
>
|
|
66
68
|
{CITATION_STYLES.map((style) => {
|
|
@@ -2,6 +2,7 @@ import { MenuDivider, MenuItem } from '@blueprintjs/core';
|
|
|
2
2
|
import { SvgLogoDoi } from 'cheminfo-font';
|
|
3
3
|
import type { CSSProperties, ReactElement } from 'react';
|
|
4
4
|
|
|
5
|
+
import { useChromeT } from '../../i18n/ui/useT.ts';
|
|
5
6
|
import { CITATION_DOWNLOADS } from '../core/formats.ts';
|
|
6
7
|
import { doiUrl } from '../core/reference.ts';
|
|
7
8
|
import type { CitedWork } from '../core/works.ts';
|
|
@@ -38,6 +39,7 @@ export interface WorkEntryProps {
|
|
|
38
39
|
*/
|
|
39
40
|
export function WorkEntry(props: WorkEntryProps): ReactElement {
|
|
40
41
|
const { work, feedback } = props;
|
|
42
|
+
const t = useChromeT();
|
|
41
43
|
const { reference, what, note } = work;
|
|
42
44
|
const references = [reference];
|
|
43
45
|
|
|
@@ -54,20 +56,20 @@ export function WorkEntry(props: WorkEntryProps): ReactElement {
|
|
|
54
56
|
>
|
|
55
57
|
<MenuItem
|
|
56
58
|
icon={<SvgLogoDoi style={DOI_ICON_STYLE} />}
|
|
57
|
-
text=
|
|
59
|
+
text={t('cite.openArticle')}
|
|
58
60
|
label={reference.doi}
|
|
59
61
|
href={doiUrl(reference)}
|
|
60
62
|
target="_blank"
|
|
61
63
|
rel="noreferrer"
|
|
62
64
|
/>
|
|
63
|
-
<MenuDivider title=
|
|
65
|
+
<MenuDivider title={t('cite.copyThisAs')} />
|
|
64
66
|
<CopyFormatEntries
|
|
65
67
|
references={references}
|
|
66
68
|
feedback={feedback}
|
|
67
69
|
keyPrefix={`${reference.doi}:`}
|
|
68
70
|
styled={false}
|
|
69
71
|
/>
|
|
70
|
-
<MenuDivider title=
|
|
72
|
+
<MenuDivider title={t('cite.importThis')} />
|
|
71
73
|
{CITATION_DOWNLOADS.map((download) => (
|
|
72
74
|
<DownloadEntry
|
|
73
75
|
key={download.format}
|
|
@@ -2,6 +2,7 @@ import type { IconName, Intent } from '@blueprintjs/core';
|
|
|
2
2
|
import { MenuItem, Tooltip } from '@blueprintjs/core';
|
|
3
3
|
import type { CSSProperties, ReactElement } from 'react';
|
|
4
4
|
|
|
5
|
+
import { useChromeT } from '../../i18n/ui/useT.ts';
|
|
5
6
|
import { downloadCitations } from '../core/download.ts';
|
|
6
7
|
import type { CitationDownload, CitationFormat } from '../core/formats.ts';
|
|
7
8
|
import type { Reference } from '../core/reference.ts';
|
|
@@ -49,7 +50,12 @@ export interface CopyEntryProps {
|
|
|
49
50
|
*/
|
|
50
51
|
export function CopyEntry(props: CopyEntryProps): ReactElement {
|
|
51
52
|
const { references, format, style, state, onCopy } = props;
|
|
53
|
+
const t = useChromeT();
|
|
52
54
|
const entry = style ?? format;
|
|
55
|
+
const label =
|
|
56
|
+
style === undefined
|
|
57
|
+
? t.or(`cite.format.${format.id}`, format.label)
|
|
58
|
+
: style.label;
|
|
53
59
|
|
|
54
60
|
return (
|
|
55
61
|
<PreviewTooltip references={references} format={format.id} style={style}>
|
|
@@ -59,7 +65,7 @@ export function CopyEntry(props: CopyEntryProps): ReactElement {
|
|
|
59
65
|
style={ENTRY_STYLE}
|
|
60
66
|
icon={state?.icon ?? 'clipboard'}
|
|
61
67
|
intent={state?.intent}
|
|
62
|
-
text={
|
|
68
|
+
text={label}
|
|
63
69
|
labelElement={
|
|
64
70
|
// The hint of a style entry is a list of journals, in italic.
|
|
65
71
|
style !== undefined && state === null ? (
|
|
@@ -90,6 +96,7 @@ export interface DownloadEntryProps {
|
|
|
90
96
|
*/
|
|
91
97
|
export function DownloadEntry(props: DownloadEntryProps): ReactElement {
|
|
92
98
|
const { references, download } = props;
|
|
99
|
+
const t = useChromeT();
|
|
93
100
|
return (
|
|
94
101
|
<PreviewTooltip references={references} format={download.format}>
|
|
95
102
|
{(targetProps) => (
|
|
@@ -97,7 +104,7 @@ export function DownloadEntry(props: DownloadEntryProps): ReactElement {
|
|
|
97
104
|
{...targetProps}
|
|
98
105
|
style={ENTRY_STYLE}
|
|
99
106
|
icon="download"
|
|
100
|
-
text={download.label}
|
|
107
|
+
text={t.or(`cite.download.${download.format}`, download.label)}
|
|
101
108
|
labelElement={download.hint}
|
|
102
109
|
onClick={() => {
|
|
103
110
|
downloadCitations(references, download);
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { useEffect, useRef, useState } from 'react';
|
|
2
2
|
|
|
3
|
+
import type { ChromeKey } from '../../i18n/core/chromeCatalog.ts';
|
|
4
|
+
import type { Translate } from '../../i18n/ui/useT.ts';
|
|
5
|
+
import { useChromeT } from '../../i18n/ui/useT.ts';
|
|
3
6
|
import { copyCitations } from '../core/clipboard.ts';
|
|
4
7
|
import type { CitationFormatId } from '../core/formats.ts';
|
|
5
8
|
import type { Reference } from '../core/reference.ts';
|
|
@@ -31,6 +34,7 @@ export interface CopyFeedback {
|
|
|
31
34
|
* @returns The copy action, and the feedback of the entry that used it.
|
|
32
35
|
*/
|
|
33
36
|
export function useCopyFeedback(): CopyFeedback {
|
|
37
|
+
const t = useChromeT();
|
|
34
38
|
const [copied, setCopied] = useState<string | null>(null);
|
|
35
39
|
const [hasFailed, setHasFailed] = useState(false);
|
|
36
40
|
const timeout = useRef<number | null>(null);
|
|
@@ -52,7 +56,7 @@ export function useCopyFeedback(): CopyFeedback {
|
|
|
52
56
|
}
|
|
53
57
|
|
|
54
58
|
return {
|
|
55
|
-
stateOf: (key) => (copied === key ? feedback(hasFailed) : null),
|
|
59
|
+
stateOf: (key) => (copied === key ? feedback(hasFailed, t) : null),
|
|
56
60
|
copy: (key, references, format, style) => {
|
|
57
61
|
copyCitations(references, format, style).then(
|
|
58
62
|
() => {
|
|
@@ -68,9 +72,12 @@ export function useCopyFeedback(): CopyFeedback {
|
|
|
68
72
|
};
|
|
69
73
|
}
|
|
70
74
|
|
|
71
|
-
|
|
75
|
+
// The label rides at the right of a menu row, where the format's own hint
|
|
76
|
+
// otherwise sits — `LaTeX`, `Word, Docs, email` — so it is written in that
|
|
77
|
+
// register rather than as the word a copy button shows on its own.
|
|
78
|
+
function feedback(failed: boolean, t: Translate<ChromeKey>): CopyState {
|
|
72
79
|
if (failed) {
|
|
73
|
-
return { icon: 'cross', intent: 'danger', label: '
|
|
80
|
+
return { icon: 'cross', intent: 'danger', label: t('cite.copyFailed') };
|
|
74
81
|
}
|
|
75
|
-
return { icon: 'tick', intent: 'success', label: 'copied' };
|
|
82
|
+
return { icon: 'tick', intent: 'success', label: t('cite.copied') };
|
|
76
83
|
}
|
|
@@ -8,6 +8,9 @@ import type {
|
|
|
8
8
|
} from 'react';
|
|
9
9
|
|
|
10
10
|
import { onActivateKey } from '../../hooks/ui/activationKey.ts';
|
|
11
|
+
import type { ChromeKey } from '../../i18n/core/chromeCatalog.ts';
|
|
12
|
+
import type { Translate } from '../../i18n/ui/useT.ts';
|
|
13
|
+
import { useChromeT } from '../../i18n/ui/useT.ts';
|
|
11
14
|
import { joinClassNames } from '../../shared/ui/joinClassNames.ts';
|
|
12
15
|
import type { ClipboardContent } from '../core/writeToClipboard.ts';
|
|
13
16
|
import { writeToClipboard } from '../core/writeToClipboard.ts';
|
|
@@ -104,6 +107,7 @@ export function ClickToCopy(props: ClickToCopyProps): ReactElement {
|
|
|
104
107
|
className,
|
|
105
108
|
style,
|
|
106
109
|
} = props;
|
|
110
|
+
const t = useChromeT();
|
|
107
111
|
const { copied, failed, copy } = useCopyToClipboard();
|
|
108
112
|
|
|
109
113
|
if (disabled) {
|
|
@@ -136,7 +140,7 @@ export function ClickToCopy(props: ClickToCopyProps): ReactElement {
|
|
|
136
140
|
style={style}
|
|
137
141
|
role={focusable && !CELLS.has(Element) ? 'button' : undefined}
|
|
138
142
|
tabIndex={focusable ? 0 : undefined}
|
|
139
|
-
title={title ?? copyTitle(value, label)}
|
|
143
|
+
title={title ?? copyTitle(value, label, t)}
|
|
140
144
|
data-copy={outcome}
|
|
141
145
|
onClick={activate}
|
|
142
146
|
onKeyDown={onActivateKey<KeyboardEvent<HTMLElement>>(activate)}
|
|
@@ -157,9 +161,9 @@ export function ClickToCopy(props: ClickToCopyProps): ReactElement {
|
|
|
157
161
|
) : null}
|
|
158
162
|
<span className="click-to-copy__status" role="status">
|
|
159
163
|
{outcome === 'copied'
|
|
160
|
-
? '
|
|
164
|
+
? t('clipboard.copied')
|
|
161
165
|
: outcome === 'failed'
|
|
162
|
-
? '
|
|
166
|
+
? t('clipboard.failed')
|
|
163
167
|
: null}
|
|
164
168
|
</span>
|
|
165
169
|
</Element>
|
|
@@ -182,10 +186,16 @@ function isOnNestedControl(
|
|
|
182
186
|
function copyTitle(
|
|
183
187
|
value: ClickToCopyProps['value'],
|
|
184
188
|
label: string | undefined,
|
|
189
|
+
t: Translate<ChromeKey>,
|
|
185
190
|
): string {
|
|
186
|
-
const what =
|
|
191
|
+
const what =
|
|
192
|
+
label === undefined
|
|
193
|
+
? t('clipboard.copy')
|
|
194
|
+
: t('clipboard.copyThe', { what: label });
|
|
187
195
|
if (typeof value === 'function') return what;
|
|
188
196
|
const text = typeof value === 'string' ? value : value.text;
|
|
189
197
|
if (text === '' || text.length > TITLE_VALUE_MAX) return what;
|
|
190
|
-
return label === undefined
|
|
198
|
+
return label === undefined
|
|
199
|
+
? t('clipboard.copyValue', { value: text })
|
|
200
|
+
: `${what} (${text})`;
|
|
191
201
|
}
|