react-cheminfo 0.37.0 → 0.39.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 +77 -1
- package/bin/check-seo.mjs +43 -1
- package/lib/chart/ui/Axes.d.ts +19 -0
- package/lib/chart/ui/Axes.d.ts.map +1 -1
- package/lib/chart/ui/Axes.js +25 -5
- package/lib/chart/ui/Axes.js.map +1 -1
- package/lib/chrome/ui/NavMenuButton.d.ts.map +1 -1
- package/lib/chrome/ui/NavMenuButton.js +41 -11
- package/lib/chrome/ui/NavMenuButton.js.map +1 -1
- package/lib/chrome/ui/SiteHeader.js +24 -1
- package/lib/chrome/ui/SiteHeader.js.map +1 -1
- package/lib/chrome/ui/navItem.d.ts +7 -0
- package/lib/chrome/ui/navItem.d.ts.map +1 -1
- package/lib/chrome/ui/navItem.js.map +1 -1
- package/lib/citation/ui/entries.d.ts.map +1 -1
- package/lib/citation/ui/entries.js +6 -1
- package/lib/citation/ui/entries.js.map +1 -1
- package/lib/clipboard/ui/ClickToCopy.d.ts +11 -0
- package/lib/clipboard/ui/ClickToCopy.d.ts.map +1 -1
- package/lib/clipboard/ui/ClickToCopy.js +28 -10
- package/lib/clipboard/ui/ClickToCopy.js.map +1 -1
- package/lib/clipboard/ui/CopyButton.d.ts +2 -1
- package/lib/clipboard/ui/CopyButton.d.ts.map +1 -1
- package/lib/clipboard/ui/CopyButton.js +2 -1
- package/lib/clipboard/ui/CopyButton.js.map +1 -1
- package/lib/clipboard/ui/CopyableValue.d.ts +24 -4
- package/lib/clipboard/ui/CopyableValue.d.ts.map +1 -1
- package/lib/clipboard/ui/CopyableValue.js +35 -3
- package/lib/clipboard/ui/CopyableValue.js.map +1 -1
- package/lib/clipboard/ui/index.d.ts +1 -1
- package/lib/clipboard/ui/index.d.ts.map +1 -1
- package/lib/clipboard/ui/index.js.map +1 -1
- package/lib/confirm/ui/ConfirmButton.d.ts.map +1 -1
- package/lib/confirm/ui/ConfirmButton.js +2 -1
- 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/delimited/ui/TableDataButton.d.ts.map +1 -1
- package/lib/delimited/ui/TableDataButton.js +2 -1
- package/lib/delimited/ui/TableDataButton.js.map +1 -1
- package/lib/download/core/figureSvg.d.ts.map +1 -1
- package/lib/download/core/figureSvg.js +37 -12
- package/lib/download/core/figureSvg.js.map +1 -1
- package/lib/help/ui/HelpToolbarButton.d.ts.map +1 -1
- package/lib/help/ui/HelpToolbarButton.js +2 -1
- package/lib/help/ui/HelpToolbarButton.js.map +1 -1
- package/lib/i18n/core/chromeCatalog.d.ts +1 -1
- package/lib/i18n/core/chromeCatalog.d.ts.map +1 -1
- package/lib/locales/de.json +48 -5
- package/lib/locales/en.json +48 -5
- package/lib/locales/es.json +48 -5
- package/lib/locales/fr.json +48 -5
- package/lib/locales/it.json +48 -5
- package/lib/number/core/index.d.ts +1 -1
- package/lib/number/core/index.d.ts.map +1 -1
- package/lib/number/core/index.js +1 -1
- package/lib/number/core/index.js.map +1 -1
- package/lib/number/core/numberText.d.ts +13 -0
- package/lib/number/core/numberText.d.ts.map +1 -1
- package/lib/number/core/numberText.js +20 -0
- package/lib/number/core/numberText.js.map +1 -1
- package/lib/number/ui/NumberInput.js +1 -1
- package/lib/number/ui/NumberInput.js.map +1 -1
- package/lib/overlay/ui/OverlayIconButton.d.ts.map +1 -1
- package/lib/overlay/ui/OverlayIconButton.js +1 -1
- package/lib/overlay/ui/OverlayIconButton.js.map +1 -1
- package/lib/panel/ui/ClearButton.d.ts.map +1 -1
- package/lib/panel/ui/ClearButton.js +1 -1
- package/lib/panel/ui/ClearButton.js.map +1 -1
- package/lib/pedagogy/core/inlineMarks.d.ts +9 -5
- package/lib/pedagogy/core/inlineMarks.d.ts.map +1 -1
- package/lib/pedagogy/core/inlineMarks.js +14 -6
- package/lib/pedagogy/core/inlineMarks.js.map +1 -1
- package/lib/pedagogy/ui/GlossaryDefinition.d.ts +4 -10
- package/lib/pedagogy/ui/GlossaryDefinition.d.ts.map +1 -1
- package/lib/pedagogy/ui/GlossaryDefinition.js +7 -7
- package/lib/pedagogy/ui/GlossaryDefinition.js.map +1 -1
- package/lib/pedagogy/ui/GlossaryIndex.d.ts.map +1 -1
- package/lib/pedagogy/ui/GlossaryIndex.js +1 -1
- package/lib/pedagogy/ui/GlossaryIndex.js.map +1 -1
- package/lib/pedagogy/ui/GlossaryProvider.d.ts +7 -0
- package/lib/pedagogy/ui/GlossaryProvider.d.ts.map +1 -1
- package/lib/pedagogy/ui/GlossaryProvider.js +3 -2
- package/lib/pedagogy/ui/GlossaryProvider.js.map +1 -1
- package/lib/pedagogy/ui/GlossaryText.d.ts +7 -2
- package/lib/pedagogy/ui/GlossaryText.d.ts.map +1 -1
- package/lib/pedagogy/ui/GlossaryText.js +3 -2
- package/lib/pedagogy/ui/GlossaryText.js.map +1 -1
- package/lib/pedagogy/ui/InlineText.d.ts +8 -2
- package/lib/pedagogy/ui/InlineText.d.ts.map +1 -1
- package/lib/pedagogy/ui/InlineText.js +7 -2
- package/lib/pedagogy/ui/InlineText.js.map +1 -1
- package/lib/pedagogy/ui/ReferenceSectionBlock.d.ts +4 -1
- package/lib/pedagogy/ui/ReferenceSectionBlock.d.ts.map +1 -1
- package/lib/pedagogy/ui/ReferenceSectionBlock.js +2 -1
- package/lib/pedagogy/ui/ReferenceSectionBlock.js.map +1 -1
- package/lib/pedagogy/ui/SyntaxTooltip.d.ts.map +1 -1
- package/lib/pedagogy/ui/SyntaxTooltip.js +11 -10
- 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 +18 -4
- package/lib/pedagogy/ui/TutorialStepStrip.js.map +1 -1
- package/lib/pedagogy/ui/glossaryContext.d.ts +7 -0
- package/lib/pedagogy/ui/glossaryContext.d.ts.map +1 -1
- package/lib/pedagogy/ui/glossaryContext.js.map +1 -1
- package/lib/pedagogy/ui/index.d.ts +1 -1
- package/lib/pedagogy/ui/index.d.ts.map +1 -1
- package/lib/pedagogy/ui/inlineSegments.d.ts +5 -0
- package/lib/pedagogy/ui/inlineSegments.d.ts.map +1 -1
- package/lib/pedagogy/ui/inlineSegments.js +2 -0
- package/lib/pedagogy/ui/inlineSegments.js.map +1 -1
- package/lib/pedagogy/ui/pedagogyStyle.d.ts +8 -9
- package/lib/pedagogy/ui/pedagogyStyle.d.ts.map +1 -1
- package/lib/pedagogy/ui/pedagogyStyle.js +10 -18
- package/lib/pedagogy/ui/pedagogyStyle.js.map +1 -1
- package/lib/range/core/index.d.ts +4 -0
- package/lib/range/core/index.d.ts.map +1 -0
- package/lib/range/core/index.js +3 -0
- package/lib/range/core/index.js.map +1 -0
- package/lib/range/core/rangeBounds.d.ts +79 -0
- package/lib/range/core/rangeBounds.d.ts.map +1 -0
- package/lib/range/core/rangeBounds.js +110 -0
- package/lib/range/core/rangeBounds.js.map +1 -0
- package/lib/range/core/rangeHistogram.d.ts +13 -0
- package/lib/range/core/rangeHistogram.d.ts.map +1 -0
- package/lib/range/core/rangeHistogram.js +39 -0
- package/lib/range/core/rangeHistogram.js.map +1 -0
- package/lib/range/ui/RangeHistogram.d.ts +20 -0
- package/lib/range/ui/RangeHistogram.d.ts.map +1 -0
- package/lib/range/ui/RangeHistogram.js +18 -0
- package/lib/range/ui/RangeHistogram.js.map +1 -0
- package/lib/range/ui/RangeSlider.d.ts +77 -0
- package/lib/range/ui/RangeSlider.d.ts.map +1 -0
- package/lib/range/ui/RangeSlider.js +60 -0
- package/lib/range/ui/RangeSlider.js.map +1 -0
- package/lib/range/ui/RangeValue.d.ts +41 -0
- package/lib/range/ui/RangeValue.d.ts.map +1 -0
- package/lib/range/ui/RangeValue.js +73 -0
- package/lib/range/ui/RangeValue.js.map +1 -0
- package/lib/range/ui/index.d.ts +3 -0
- package/lib/range/ui/index.d.ts.map +1 -0
- package/lib/range/ui/index.js +2 -0
- package/lib/range/ui/index.js.map +1 -0
- package/lib/seo/core/documentMeta.d.ts +16 -0
- package/lib/seo/core/documentMeta.d.ts.map +1 -1
- package/lib/seo/core/documentMeta.js +18 -0
- package/lib/seo/core/documentMeta.js.map +1 -1
- package/lib/seo/core/index.d.ts +3 -1
- package/lib/seo/core/index.d.ts.map +1 -1
- package/lib/seo/core/index.js +2 -1
- package/lib/seo/core/index.js.map +1 -1
- package/lib/seo/core/noscript.d.ts +8 -0
- package/lib/seo/core/noscript.d.ts.map +1 -1
- package/lib/seo/core/noscript.js +10 -3
- package/lib/seo/core/noscript.js.map +1 -1
- package/lib/seo/core/pageMeta.d.ts +10 -2
- package/lib/seo/core/pageMeta.d.ts.map +1 -1
- package/lib/seo/core/pageMeta.js +12 -3
- package/lib/seo/core/pageMeta.js.map +1 -1
- package/lib/seo/core/plainDescription.d.ts +2 -2
- package/lib/seo/core/plainDescription.js +5 -2
- package/lib/seo/core/plainDescription.js.map +1 -1
- package/lib/seo/core/siteFiles.d.ts +32 -3
- package/lib/seo/core/siteFiles.d.ts.map +1 -1
- package/lib/seo/core/siteFiles.js +13 -4
- package/lib/seo/core/siteFiles.js.map +1 -1
- package/lib/seo/core/startDocumentMeta.js +8 -7
- package/lib/seo/core/startDocumentMeta.js.map +1 -1
- package/lib/seo/vite/prerender.d.ts +26 -4
- package/lib/seo/vite/prerender.d.ts.map +1 -1
- package/lib/seo/vite/prerender.js +100 -30
- package/lib/seo/vite/prerender.js.map +1 -1
- package/lib/share/core/devices.d.ts +41 -0
- package/lib/share/core/devices.d.ts.map +1 -0
- package/lib/share/core/devices.js +58 -0
- package/lib/share/core/devices.js.map +1 -0
- package/lib/share/core/index.d.ts +4 -0
- package/lib/share/core/index.d.ts.map +1 -1
- package/lib/share/core/index.js +2 -0
- package/lib/share/core/index.js.map +1 -1
- package/lib/share/core/regions.d.ts +43 -0
- package/lib/share/core/regions.d.ts.map +1 -0
- package/lib/share/core/regions.js +71 -0
- package/lib/share/core/regions.js.map +1 -0
- package/lib/share/ui/HiddenPartsProvider.d.ts.map +1 -1
- package/lib/share/ui/HiddenPartsProvider.js +4 -1
- package/lib/share/ui/HiddenPartsProvider.js.map +1 -1
- package/lib/share/ui/PagePart.d.ts.map +1 -1
- package/lib/share/ui/PagePart.js +10 -1
- package/lib/share/ui/PagePart.js.map +1 -1
- package/lib/share/ui/ShareButton.d.ts.map +1 -1
- package/lib/share/ui/ShareButton.js +3 -4
- package/lib/share/ui/ShareButton.js.map +1 -1
- package/lib/share/ui/ShareConfigOptions.d.ts +6 -1
- package/lib/share/ui/ShareConfigOptions.d.ts.map +1 -1
- package/lib/share/ui/ShareConfigOptions.js +6 -13
- package/lib/share/ui/ShareConfigOptions.js.map +1 -1
- package/lib/share/ui/ShareDialog.d.ts +14 -0
- package/lib/share/ui/ShareDialog.d.ts.map +1 -1
- package/lib/share/ui/ShareDialog.js +3 -3
- package/lib/share/ui/ShareDialog.js.map +1 -1
- package/lib/share/ui/ShareDialogContent.d.ts +2 -2
- package/lib/share/ui/ShareDialogContent.d.ts.map +1 -1
- package/lib/share/ui/ShareDialogContent.js +36 -30
- package/lib/share/ui/ShareDialogContent.js.map +1 -1
- package/lib/share/ui/ShareLinkBar.d.ts +21 -0
- package/lib/share/ui/ShareLinkBar.d.ts.map +1 -0
- package/lib/share/ui/ShareLinkBar.js +32 -0
- package/lib/share/ui/ShareLinkBar.js.map +1 -0
- package/lib/share/ui/SharePanes.d.ts +17 -0
- package/lib/share/ui/SharePanes.d.ts.map +1 -0
- package/lib/share/ui/SharePanes.js +27 -0
- package/lib/share/ui/SharePanes.js.map +1 -0
- package/lib/share/ui/SharePartOptions.d.ts +9 -3
- package/lib/share/ui/SharePartOptions.d.ts.map +1 -1
- package/lib/share/ui/SharePartOptions.js +12 -16
- package/lib/share/ui/SharePartOptions.js.map +1 -1
- package/lib/share/ui/SharePartRow.d.ts +37 -0
- package/lib/share/ui/SharePartRow.d.ts.map +1 -0
- package/lib/share/ui/SharePartRow.js +25 -0
- package/lib/share/ui/SharePartRow.js.map +1 -0
- package/lib/share/ui/SharePresetTabs.d.ts +10 -7
- package/lib/share/ui/SharePresetTabs.d.ts.map +1 -1
- package/lib/share/ui/SharePresetTabs.js +17 -17
- package/lib/share/ui/SharePresetTabs.js.map +1 -1
- package/lib/share/ui/SharePreview.d.ts +32 -0
- package/lib/share/ui/SharePreview.d.ts.map +1 -0
- package/lib/share/ui/SharePreview.js +104 -0
- package/lib/share/ui/SharePreview.js.map +1 -0
- package/lib/share/ui/SharePreviewDevices.d.ts +20 -0
- package/lib/share/ui/SharePreviewDevices.d.ts.map +1 -0
- package/lib/share/ui/SharePreviewDevices.js +40 -0
- package/lib/share/ui/SharePreviewDevices.js.map +1 -0
- package/lib/share/ui/index.d.ts +1 -0
- package/lib/share/ui/index.d.ts.map +1 -1
- package/lib/share/ui/index.js.map +1 -1
- package/lib/share/ui/shareMarking.d.ts +14 -0
- package/lib/share/ui/shareMarking.d.ts.map +1 -0
- package/lib/share/ui/shareMarking.js +17 -0
- package/lib/share/ui/shareMarking.js.map +1 -0
- package/lib/share/ui/useShareRegionReports.d.ts +12 -0
- package/lib/share/ui/useShareRegionReports.d.ts.map +1 -0
- package/lib/share/ui/useShareRegionReports.js +73 -0
- package/lib/share/ui/useShareRegionReports.js.map +1 -0
- package/lib/shared/ui/ActionTooltip.d.ts +42 -0
- package/lib/shared/ui/ActionTooltip.d.ts.map +1 -0
- package/lib/shared/ui/ActionTooltip.js +21 -0
- package/lib/shared/ui/ActionTooltip.js.map +1 -0
- package/lib/shared/ui/index.d.ts +4 -0
- package/lib/shared/ui/index.d.ts.map +1 -1
- package/lib/shared/ui/index.js +2 -0
- package/lib/shared/ui/index.js.map +1 -1
- package/lib/shared/ui/useActionTooltip.d.ts +48 -0
- package/lib/shared/ui/useActionTooltip.d.ts.map +1 -0
- package/lib/shared/ui/useActionTooltip.js +78 -0
- package/lib/shared/ui/useActionTooltip.js.map +1 -0
- package/lib/structure/core/index.d.ts +2 -0
- package/lib/structure/core/index.d.ts.map +1 -1
- package/lib/structure/core/index.js +1 -0
- package/lib/structure/core/index.js.map +1 -1
- package/lib/structure/core/sourceMolecule.d.ts +18 -0
- package/lib/structure/core/sourceMolecule.d.ts.map +1 -0
- package/lib/structure/core/sourceMolecule.js +26 -0
- package/lib/structure/core/sourceMolecule.js.map +1 -0
- package/lib/structure/core/structureNotations.d.ts +57 -0
- package/lib/structure/core/structureNotations.d.ts.map +1 -0
- package/lib/structure/core/structureNotations.js +74 -0
- package/lib/structure/core/structureNotations.js.map +1 -0
- package/lib/structure/core/structurePicture.d.ts +49 -0
- package/lib/structure/core/structurePicture.d.ts.map +1 -0
- package/lib/structure/core/structurePicture.js +83 -0
- package/lib/structure/core/structurePicture.js.map +1 -0
- package/lib/structure/ui/EditorExportButton.d.ts +23 -0
- package/lib/structure/ui/EditorExportButton.d.ts.map +1 -0
- package/lib/structure/ui/EditorExportButton.js +23 -0
- package/lib/structure/ui/EditorExportButton.js.map +1 -0
- package/lib/structure/ui/EditorHelpButton.d.ts +5 -2
- package/lib/structure/ui/EditorHelpButton.d.ts.map +1 -1
- package/lib/structure/ui/EditorHelpButton.js +8 -9
- package/lib/structure/ui/EditorHelpButton.js.map +1 -1
- package/lib/structure/ui/StructureEditor.d.ts +8 -0
- package/lib/structure/ui/StructureEditor.d.ts.map +1 -1
- package/lib/structure/ui/StructureEditor.js +26 -3
- package/lib/structure/ui/StructureEditor.js.map +1 -1
- package/lib/structure/ui/StructureExportDialog.d.ts +34 -0
- package/lib/structure/ui/StructureExportDialog.d.ts.map +1 -0
- package/lib/structure/ui/StructureExportDialog.js +43 -0
- package/lib/structure/ui/StructureExportDialog.js.map +1 -0
- package/lib/structure/ui/StructureExportPanel.d.ts +37 -0
- package/lib/structure/ui/StructureExportPanel.d.ts.map +1 -0
- package/lib/structure/ui/StructureExportPanel.js +75 -0
- package/lib/structure/ui/StructureExportPanel.js.map +1 -0
- package/lib/structure/ui/StructureNotationRow.d.ts +22 -0
- package/lib/structure/ui/StructureNotationRow.d.ts.map +1 -0
- package/lib/structure/ui/StructureNotationRow.js +34 -0
- package/lib/structure/ui/StructureNotationRow.js.map +1 -0
- package/lib/structure/ui/StructurePicturePane.d.ts +23 -0
- package/lib/structure/ui/StructurePicturePane.d.ts.map +1 -0
- package/lib/structure/ui/StructurePicturePane.js +113 -0
- package/lib/structure/ui/StructurePicturePane.js.map +1 -0
- package/lib/structure/ui/StructureSvg.d.ts.map +1 -1
- package/lib/structure/ui/StructureSvg.js +2 -18
- package/lib/structure/ui/StructureSvg.js.map +1 -1
- package/lib/structure/ui/ToolbarTooltip.d.ts.map +1 -1
- package/lib/structure/ui/ToolbarTooltip.js +1 -2
- package/lib/structure/ui/ToolbarTooltip.js.map +1 -1
- package/lib/structure/ui/index.d.ts +7 -3
- package/lib/structure/ui/index.d.ts.map +1 -1
- package/lib/structure/ui/index.js +5 -3
- package/lib/structure/ui/index.js.map +1 -1
- package/lib/structure/ui/structureNotationText.d.ts +23 -0
- package/lib/structure/ui/structureNotationText.d.ts.map +1 -0
- package/lib/structure/ui/structureNotationText.js +42 -0
- package/lib/structure/ui/structureNotationText.js.map +1 -0
- package/lib/structure/ui/useEditorStructure.d.ts +37 -0
- package/lib/structure/ui/useEditorStructure.d.ts.map +1 -0
- package/lib/structure/ui/useEditorStructure.js +70 -0
- package/lib/structure/ui/useEditorStructure.js.map +1 -0
- 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 +1 -1
- package/src/chart/ui/Axes.tsx +53 -5
- package/src/chrome/ui/NavMenuButton.tsx +61 -18
- package/src/chrome/ui/SiteHeader.tsx +37 -1
- package/src/chrome/ui/navItem.ts +7 -0
- package/src/citation/ui/entries.tsx +10 -2
- package/src/clipboard/ui/ClickToCopy.tsx +47 -13
- package/src/clipboard/ui/CopyButton.tsx +4 -2
- package/src/clipboard/ui/CopyableValue.tsx +88 -13
- package/src/clipboard/ui/index.ts +5 -1
- package/src/confirm/ui/ConfirmButton.tsx +2 -0
- package/src/core.ts +1 -0
- package/src/delimited/ui/TableDataButton.tsx +2 -1
- package/src/download/core/figureSvg.ts +42 -10
- package/src/help/ui/HelpToolbarButton.tsx +2 -1
- package/src/locales/de.json +48 -5
- package/src/locales/en.json +48 -5
- package/src/locales/es.json +48 -5
- package/src/locales/fr.json +48 -5
- package/src/locales/it.json +48 -5
- package/src/number/core/index.ts +1 -0
- package/src/number/core/numberText.ts +20 -0
- package/src/number/ui/NumberInput.tsx +1 -1
- package/src/overlay/ui/OverlayIconButton.tsx +1 -0
- package/src/panel/ui/ClearButton.tsx +1 -0
- package/src/pedagogy/core/inlineMarks.ts +15 -7
- package/src/pedagogy/ui/GlossaryDefinition.tsx +8 -18
- package/src/pedagogy/ui/GlossaryIndex.tsx +0 -1
- package/src/pedagogy/ui/GlossaryProvider.tsx +10 -2
- package/src/pedagogy/ui/GlossaryText.tsx +10 -2
- package/src/pedagogy/ui/InlineText.tsx +21 -4
- package/src/pedagogy/ui/ReferenceSectionBlock.tsx +8 -2
- package/src/pedagogy/ui/SyntaxTooltip.tsx +11 -9
- package/src/pedagogy/ui/TutorialStepStrip.tsx +50 -18
- package/src/pedagogy/ui/glossaryContext.ts +7 -0
- package/src/pedagogy/ui/index.ts +1 -1
- package/src/pedagogy/ui/inlineSegments.tsx +7 -0
- package/src/pedagogy/ui/pedagogyStyle.ts +12 -24
- package/src/range/core/index.ts +11 -0
- package/src/range/core/rangeBounds.ts +143 -0
- package/src/range/core/rangeHistogram.ts +38 -0
- package/src/range/ui/RangeHistogram.tsx +49 -0
- package/src/range/ui/RangeSlider.tsx +209 -0
- package/src/range/ui/RangeValue.tsx +166 -0
- package/src/range/ui/index.ts +2 -0
- package/src/seo/core/documentMeta.ts +22 -0
- package/src/seo/core/index.ts +8 -1
- package/src/seo/core/noscript.ts +20 -2
- package/src/seo/core/pageMeta.ts +29 -5
- package/src/seo/core/plainDescription.ts +4 -2
- package/src/seo/core/siteFiles.ts +45 -10
- package/src/seo/core/startDocumentMeta.ts +9 -9
- package/src/seo/vite/prerender.ts +160 -36
- package/src/share/core/devices.ts +80 -0
- package/src/share/core/index.ts +14 -0
- package/src/share/core/regions.ts +87 -0
- package/src/share/ui/HiddenPartsProvider.tsx +6 -1
- package/src/share/ui/PagePart.tsx +12 -1
- package/src/share/ui/ShareButton.tsx +3 -6
- package/src/share/ui/ShareConfigOptions.tsx +25 -16
- package/src/share/ui/ShareDialog.tsx +17 -3
- package/src/share/ui/ShareDialogContent.tsx +80 -77
- package/src/share/ui/ShareLinkBar.tsx +70 -0
- package/src/share/ui/SharePanes.tsx +62 -0
- package/src/share/ui/SharePartOptions.tsx +25 -26
- package/src/share/ui/SharePartRow.tsx +78 -0
- package/src/share/ui/SharePresetTabs.tsx +36 -43
- package/src/share/ui/SharePreview.tsx +204 -0
- package/src/share/ui/SharePreviewDevices.tsx +70 -0
- package/src/share/ui/index.ts +1 -0
- package/src/share/ui/shareMarking.ts +18 -0
- package/src/share/ui/useShareRegionReports.ts +84 -0
- package/src/shared/ui/ActionTooltip.tsx +70 -0
- package/src/shared/ui/index.ts +7 -0
- package/src/shared/ui/useActionTooltip.ts +103 -0
- package/src/structure/core/index.ts +5 -0
- package/src/structure/core/sourceMolecule.ts +26 -0
- package/src/structure/core/structureNotations.ts +125 -0
- package/src/structure/core/structurePicture.ts +119 -0
- package/src/structure/ui/EditorExportButton.tsx +62 -0
- package/src/structure/ui/EditorHelpButton.tsx +26 -30
- package/src/structure/ui/StructureEditor.tsx +51 -5
- package/src/structure/ui/StructureExportDialog.tsx +90 -0
- package/src/structure/ui/StructureExportPanel.tsx +156 -0
- package/src/structure/ui/StructureNotationRow.tsx +74 -0
- package/src/structure/ui/StructurePicturePane.tsx +208 -0
- package/src/structure/ui/StructureSvg.tsx +3 -12
- package/src/structure/ui/ToolbarTooltip.tsx +1 -1
- package/src/structure/ui/index.ts +7 -3
- package/src/structure/ui/structureNotationText.ts +56 -0
- package/src/structure/ui/useEditorStructure.ts +119 -0
- package/src/ui.ts +1 -0
- package/styles/chrome.css +546 -11
|
@@ -58,7 +58,7 @@ export function NavMenuButton(props: NavMenuButtonProps): ReactElement {
|
|
|
58
58
|
children,
|
|
59
59
|
} = props;
|
|
60
60
|
|
|
61
|
-
const holdsActive = items
|
|
61
|
+
const holdsActive = holdsId(items, activeId);
|
|
62
62
|
const classes = [
|
|
63
63
|
'nav-link',
|
|
64
64
|
icon === undefined ? null : 'nav-link--icon',
|
|
@@ -73,23 +73,7 @@ export function NavMenuButton(props: NavMenuButtonProps): ReactElement {
|
|
|
73
73
|
content={
|
|
74
74
|
<Menu className="nav-menu">
|
|
75
75
|
{items.map((item) => (
|
|
76
|
-
<
|
|
77
|
-
key={item.id}
|
|
78
|
-
icon={item.icon}
|
|
79
|
-
text={item.label}
|
|
80
|
-
// A real address, so a crawler reaching the menu can follow it
|
|
81
|
-
// and a middle click opens a tab of its own.
|
|
82
|
-
href={item.href}
|
|
83
|
-
target={item.external ? '_blank' : undefined}
|
|
84
|
-
active={item.id === activeId}
|
|
85
|
-
onClick={(event) => {
|
|
86
|
-
if (item.onSelect === undefined || isModifiedClick(event)) {
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
event.preventDefault();
|
|
90
|
-
item.onSelect();
|
|
91
|
-
}}
|
|
92
|
-
/>
|
|
76
|
+
<NavMenuEntry key={item.id} item={item} activeId={activeId} />
|
|
93
77
|
))}
|
|
94
78
|
{children}
|
|
95
79
|
</Menu>
|
|
@@ -114,3 +98,62 @@ export function NavMenuButton(props: NavMenuButtonProps): ReactElement {
|
|
|
114
98
|
</PopoverNext>
|
|
115
99
|
);
|
|
116
100
|
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* One line of a header menu, holding a submenu of its own when the entry folds
|
|
104
|
+
* pages — which is how a bar entry that is already a menu reads once the whole
|
|
105
|
+
* bar has folded into one.
|
|
106
|
+
* @param props - The entry and the page on show.
|
|
107
|
+
* @param props.item - The entry.
|
|
108
|
+
* @param props.activeId - The page on show.
|
|
109
|
+
* @returns The line.
|
|
110
|
+
*/
|
|
111
|
+
function NavMenuEntry(props: {
|
|
112
|
+
item: NavItem;
|
|
113
|
+
activeId: string | undefined;
|
|
114
|
+
}): ReactElement {
|
|
115
|
+
const { item, activeId } = props;
|
|
116
|
+
|
|
117
|
+
return (
|
|
118
|
+
<MenuItem
|
|
119
|
+
icon={item.icon}
|
|
120
|
+
text={item.label}
|
|
121
|
+
// A real address, so a crawler reaching the menu can follow it and a
|
|
122
|
+
// middle click opens a tab of its own.
|
|
123
|
+
href={item.href}
|
|
124
|
+
target={item.external ? '_blank' : undefined}
|
|
125
|
+
active={
|
|
126
|
+
item.items === undefined
|
|
127
|
+
? item.id === activeId
|
|
128
|
+
: holdsId(item.items, activeId)
|
|
129
|
+
}
|
|
130
|
+
onClick={(event) => {
|
|
131
|
+
if (item.onSelect === undefined || isModifiedClick(event)) return;
|
|
132
|
+
event.preventDefault();
|
|
133
|
+
item.onSelect();
|
|
134
|
+
}}
|
|
135
|
+
>
|
|
136
|
+
{item.items?.map((child) => (
|
|
137
|
+
<NavMenuEntry key={child.id} item={child} activeId={activeId} />
|
|
138
|
+
))}
|
|
139
|
+
</MenuItem>
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Whether a run of entries holds the page on show, looking through the ones
|
|
145
|
+
* that are menus of their own.
|
|
146
|
+
* @param items - The entries.
|
|
147
|
+
* @param activeId - The page on show.
|
|
148
|
+
* @returns Whether one of them is it.
|
|
149
|
+
*/
|
|
150
|
+
function holdsId(
|
|
151
|
+
items: readonly NavItem[],
|
|
152
|
+
activeId: string | undefined,
|
|
153
|
+
): boolean {
|
|
154
|
+
for (const item of items) {
|
|
155
|
+
if (item.id === activeId) return true;
|
|
156
|
+
if (item.items !== undefined && holdsId(item.items, activeId)) return true;
|
|
157
|
+
}
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
@@ -150,7 +150,7 @@ export function SiteHeader(props: SiteHeaderProps): ReactElement | null {
|
|
|
150
150
|
{nav.map((item) => (
|
|
151
151
|
<Fragment key={item.id}>
|
|
152
152
|
{renderNavItem === undefined ? (
|
|
153
|
-
<
|
|
153
|
+
<NavEntry item={item} activeId={activeId} />
|
|
154
154
|
) : (
|
|
155
155
|
renderNavItem(item, item.id === activeId)
|
|
156
156
|
)}
|
|
@@ -177,6 +177,42 @@ export function SiteHeader(props: SiteHeaderProps): ReactElement | null {
|
|
|
177
177
|
);
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
+
/**
|
|
181
|
+
* One page of the bar: a link, or the menu it opens when the entry folds pages
|
|
182
|
+
* of its own. A menu stands where its pages would, among them and not among the
|
|
183
|
+
* utilities, because picking one of them changes what the page shows.
|
|
184
|
+
* @param props - The entry and the page on show.
|
|
185
|
+
* @param props.item - The entry.
|
|
186
|
+
* @param props.activeId - The page on show.
|
|
187
|
+
* @returns The entry.
|
|
188
|
+
*/
|
|
189
|
+
function NavEntry(props: {
|
|
190
|
+
item: NavItem;
|
|
191
|
+
activeId: string | undefined;
|
|
192
|
+
}): ReactElement {
|
|
193
|
+
const { item, activeId } = props;
|
|
194
|
+
if (item.items === undefined) {
|
|
195
|
+
return <NavLink item={item} active={item.id === activeId} />;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return (
|
|
199
|
+
<NavMenuButton
|
|
200
|
+
label={menuLabel(item)}
|
|
201
|
+
icon={typeof item.icon === 'string' ? item.icon : undefined}
|
|
202
|
+
items={item.items}
|
|
203
|
+
activeId={activeId}
|
|
204
|
+
placement="bottom-start"
|
|
205
|
+
/>
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// The trigger names itself to a screen reader, so an entry drawn as a glyph
|
|
210
|
+
// alone says what it opens through its title rather than through its id.
|
|
211
|
+
function menuLabel(item: NavItem): string {
|
|
212
|
+
if (typeof item.label === 'string') return item.label;
|
|
213
|
+
return item.title ?? item.id;
|
|
214
|
+
}
|
|
215
|
+
|
|
180
216
|
/** The two widths the bar's contents run at, as the classes that set them. */
|
|
181
217
|
const INNER_CLASS = {
|
|
182
218
|
page: 'app-header__inner',
|
package/src/chrome/ui/navItem.ts
CHANGED
|
@@ -49,6 +49,13 @@ export interface NavItem {
|
|
|
49
49
|
* @default undefined
|
|
50
50
|
*/
|
|
51
51
|
after?: ReactNode;
|
|
52
|
+
/**
|
|
53
|
+
* The pages this entry folds, which make it a menu rather than a link: the
|
|
54
|
+
* run of pages that do not each need a place of their own in the bar. The
|
|
55
|
+
* entry takes the brand tint while one of them is the page on show.
|
|
56
|
+
* @default undefined
|
|
57
|
+
*/
|
|
58
|
+
items?: readonly NavItem[];
|
|
52
59
|
/**
|
|
53
60
|
* Whether the page cannot be opened yet — a view that needs data the site
|
|
54
61
|
* has not been given.
|
|
@@ -3,6 +3,7 @@ import { MenuItem, Tooltip } from '@blueprintjs/core';
|
|
|
3
3
|
import type { CSSProperties, ReactElement } from 'react';
|
|
4
4
|
|
|
5
5
|
import { useChromeT } from '../../i18n/ui/useT.ts';
|
|
6
|
+
import { useActionTooltip } from '../../shared/ui/useActionTooltip.ts';
|
|
6
7
|
import { downloadCitations } from '../core/download.ts';
|
|
7
8
|
import type { CitationDownload, CitationFormat } from '../core/formats.ts';
|
|
8
9
|
import type { Reference } from '../core/reference.ts';
|
|
@@ -131,11 +132,16 @@ function PreviewTooltip(props: {
|
|
|
131
132
|
children: (targetProps: Record<string, unknown>) => ReactElement;
|
|
132
133
|
}): ReactElement {
|
|
133
134
|
const { references, format, style, children } = props;
|
|
135
|
+
// Held rather than left to Blueprint: pressing an entry downloads or copies
|
|
136
|
+
// and closes the menu, and a preview opened by the hover that led to the
|
|
137
|
+
// press would outlive both — see `useActionTooltip`.
|
|
138
|
+
const { isOpen, target } = useActionTooltip(false, PREVIEW_OPEN_DELAY);
|
|
139
|
+
|
|
134
140
|
return (
|
|
135
141
|
<Tooltip
|
|
136
142
|
placement="left"
|
|
137
143
|
popoverClassName="citation-tooltip"
|
|
138
|
-
|
|
144
|
+
isOpen={isOpen}
|
|
139
145
|
content={
|
|
140
146
|
<CitationPreview
|
|
141
147
|
reference={references}
|
|
@@ -143,7 +149,9 @@ function PreviewTooltip(props: {
|
|
|
143
149
|
style={style?.id}
|
|
144
150
|
/>
|
|
145
151
|
}
|
|
146
|
-
renderTarget={({ isOpen, ...targetProps }) =>
|
|
152
|
+
renderTarget={({ isOpen: drawn, ...targetProps }) =>
|
|
153
|
+
children({ ...targetProps, ...target })
|
|
154
|
+
}
|
|
147
155
|
/>
|
|
148
156
|
);
|
|
149
157
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { IconName } from '@blueprintjs/core';
|
|
1
2
|
import { Icon } from '@blueprintjs/core';
|
|
2
3
|
import type {
|
|
3
4
|
CSSProperties,
|
|
@@ -20,6 +21,9 @@ import { useCopyToClipboard } from './useCopyToClipboard.ts';
|
|
|
20
21
|
/** The elements a {@link ClickToCopy} can be, so a table cell is its own target. */
|
|
21
22
|
export type ClickToCopyElement = 'span' | 'code' | 'div' | 'td' | 'th';
|
|
22
23
|
|
|
24
|
+
/** Where the glyph sits: past the value, or inside its right edge. */
|
|
25
|
+
export type ClickToCopyLayout = 'inline' | 'block';
|
|
26
|
+
|
|
23
27
|
/** What {@link ClickToCopy} copies, and how it reads. */
|
|
24
28
|
export interface ClickToCopyProps {
|
|
25
29
|
/**
|
|
@@ -48,6 +52,15 @@ export interface ClickToCopyProps {
|
|
|
48
52
|
* @default 'span'
|
|
49
53
|
*/
|
|
50
54
|
as?: ClickToCopyElement;
|
|
55
|
+
/**
|
|
56
|
+
* Where the glyph goes. A value in a line of text shows it just past itself,
|
|
57
|
+
* so the line keeps its spacing; one laid out as a block keeps room for it
|
|
58
|
+
* inside its right edge, because a glyph past the edge of a full-width block
|
|
59
|
+
* is a glyph past the edge of whatever holds it — which scrolls the page
|
|
60
|
+
* sideways by the width of the glyph.
|
|
61
|
+
* @default read from `as`: a `span` or a `code` is inline, the rest a block
|
|
62
|
+
*/
|
|
63
|
+
layout?: ClickToCopyLayout;
|
|
51
64
|
/**
|
|
52
65
|
* Whether the value is a tab stop and a button of its own, with the glyph a
|
|
53
66
|
* keyboard is shown instead of the cursor. Off when a copy button beside it
|
|
@@ -108,6 +121,7 @@ export function ClickToCopy(props: ClickToCopyProps): ReactElement {
|
|
|
108
121
|
label,
|
|
109
122
|
title,
|
|
110
123
|
as: Element = 'span',
|
|
124
|
+
layout,
|
|
111
125
|
focusable = true,
|
|
112
126
|
disabled = false,
|
|
113
127
|
className,
|
|
@@ -116,6 +130,7 @@ export function ClickToCopy(props: ClickToCopyProps): ReactElement {
|
|
|
116
130
|
} = props;
|
|
117
131
|
const t = useChromeT();
|
|
118
132
|
const { copied, failed, copy } = useCopyToClipboard();
|
|
133
|
+
const placing = layout ?? (INLINE.has(Element) ? 'inline' : 'block');
|
|
119
134
|
|
|
120
135
|
if (disabled) {
|
|
121
136
|
return (
|
|
@@ -141,7 +156,7 @@ export function ClickToCopy(props: ClickToCopyProps): ReactElement {
|
|
|
141
156
|
<Element
|
|
142
157
|
className={joinClassNames(
|
|
143
158
|
'click-to-copy',
|
|
144
|
-
|
|
159
|
+
`click-to-copy--${placing}`,
|
|
145
160
|
className,
|
|
146
161
|
)}
|
|
147
162
|
style={style}
|
|
@@ -157,27 +172,46 @@ export function ClickToCopy(props: ClickToCopyProps): ReactElement {
|
|
|
157
172
|
{focusable ? (
|
|
158
173
|
<Icon
|
|
159
174
|
className="click-to-copy__icon"
|
|
160
|
-
icon={
|
|
161
|
-
outcome === 'copied'
|
|
162
|
-
? 'tick'
|
|
163
|
-
: outcome === 'failed'
|
|
164
|
-
? 'cross'
|
|
165
|
-
: 'clipboard'
|
|
166
|
-
}
|
|
175
|
+
icon={outcomeIcon(outcome)}
|
|
167
176
|
size={16}
|
|
168
177
|
/>
|
|
169
178
|
) : null}
|
|
170
179
|
<span className="click-to-copy__status" role="status">
|
|
171
|
-
{outcome
|
|
172
|
-
? t('clipboard.copied')
|
|
173
|
-
: outcome === 'failed'
|
|
174
|
-
? t('clipboard.failed')
|
|
175
|
-
: null}
|
|
180
|
+
{outcomeStatus(outcome, t)}
|
|
176
181
|
</span>
|
|
177
182
|
</Element>
|
|
178
183
|
);
|
|
179
184
|
}
|
|
180
185
|
|
|
186
|
+
/** How the last copy went, while it is still being confirmed. */
|
|
187
|
+
type CopyOutcome = 'copied' | 'failed' | undefined;
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* The glyph the value carries: the clipboard at rest, then the answer.
|
|
191
|
+
* @param outcome - How the last copy went.
|
|
192
|
+
* @returns The icon.
|
|
193
|
+
*/
|
|
194
|
+
function outcomeIcon(outcome: CopyOutcome): IconName {
|
|
195
|
+
if (outcome === 'copied') return 'tick';
|
|
196
|
+
if (outcome === 'failed') return 'cross';
|
|
197
|
+
return 'clipboard';
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* What a screen reader is told once a copy has been attempted.
|
|
202
|
+
* @param outcome - How it went.
|
|
203
|
+
* @param t - The chrome's formatter.
|
|
204
|
+
* @returns The line, or nothing before anything was copied.
|
|
205
|
+
*/
|
|
206
|
+
function outcomeStatus(
|
|
207
|
+
outcome: CopyOutcome,
|
|
208
|
+
t: Translate<ChromeKey>,
|
|
209
|
+
): string | null {
|
|
210
|
+
if (outcome === 'copied') return t('clipboard.copied');
|
|
211
|
+
if (outcome === 'failed') return t('clipboard.failed');
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
|
|
181
215
|
function isOnNestedControl(
|
|
182
216
|
event: MouseEvent<HTMLElement> | KeyboardEvent<HTMLElement>,
|
|
183
217
|
): boolean {
|
|
@@ -3,6 +3,7 @@ import { Button } from '@blueprintjs/core';
|
|
|
3
3
|
import type { ReactElement } from 'react';
|
|
4
4
|
|
|
5
5
|
import { useChromeT } from '../../i18n/ui/useT.ts';
|
|
6
|
+
import { joinClassNames } from '../../shared/ui/joinClassNames.ts';
|
|
6
7
|
|
|
7
8
|
import {
|
|
8
9
|
DEFAULT_COPY_RESET_AFTER,
|
|
@@ -60,7 +61,8 @@ export interface CopyButtonProps {
|
|
|
60
61
|
*/
|
|
61
62
|
resetAfter?: number;
|
|
62
63
|
/**
|
|
63
|
-
* What the pointer and a screen reader are told.
|
|
64
|
+
* What the pointer and a screen reader are told. An empty string drops the
|
|
65
|
+
* hover title, for a button that already sits in a tooltip of its own.
|
|
64
66
|
* @default the chrome's own line, in the language of the page
|
|
65
67
|
*/
|
|
66
68
|
title?: string;
|
|
@@ -105,7 +107,7 @@ export function CopyButton(props: CopyButtonProps): ReactElement {
|
|
|
105
107
|
|
|
106
108
|
return (
|
|
107
109
|
<Button
|
|
108
|
-
className={className}
|
|
110
|
+
className={joinClassNames('no-print', className)}
|
|
109
111
|
variant={minimal ? 'minimal' : 'solid'}
|
|
110
112
|
size={small ? 'small' : 'medium'}
|
|
111
113
|
icon={look.icon}
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import type { CSSProperties, ReactElement, ReactNode } from 'react';
|
|
2
2
|
|
|
3
3
|
import { MISSING_VALUE } from '../../format/core/missing.ts';
|
|
4
|
+
import type { HelpText } from '../../help/ui/HelpBody.tsx';
|
|
5
|
+
import { HelpTooltip } from '../../help/ui/HelpTooltip.tsx';
|
|
6
|
+
import { OVERLAY_HELP_NAME_STYLE } from '../../overlay/ui/overlayRowStyles.ts';
|
|
4
7
|
import { TOKEN } from '../../tokens/core/familyTokens.ts';
|
|
5
8
|
|
|
6
9
|
import { ClickToCopy } from './ClickToCopy.tsx';
|
|
7
10
|
|
|
8
11
|
const DEFAULT_BLOCK_HEIGHT = 160;
|
|
9
12
|
|
|
13
|
+
/** What says there is more of the value than is on screen. */
|
|
14
|
+
const FADE = 'linear-gradient(to bottom, #000 72%, transparent 100%)';
|
|
15
|
+
|
|
10
16
|
/** What {@link CopyableValue} names, shows and copies. */
|
|
11
17
|
export interface CopyableValueProps {
|
|
12
18
|
/** What the value is, written above it, e.g. `InChIKey`. */
|
|
@@ -14,10 +20,13 @@ export interface CopyableValueProps {
|
|
|
14
20
|
/** The value itself, which is what a click on it copies. */
|
|
15
21
|
value: string;
|
|
16
22
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
23
|
+
* What the value is, read by hovering the label — which is underlined with
|
|
24
|
+
* dots to say so. It opens as the family's help card rather than as the
|
|
25
|
+
* browser's own tooltip, which takes a second to appear and is drawn by the
|
|
26
|
+
* operating system rather than by us.
|
|
27
|
+
* @default undefined — the label explains nothing beyond itself
|
|
19
28
|
*/
|
|
20
|
-
hint?:
|
|
29
|
+
hint?: HelpText;
|
|
21
30
|
/**
|
|
22
31
|
* Whether the value keeps its line breaks and scrolls past `maxHeight`, for
|
|
23
32
|
* a molfile or any other multi-line notation.
|
|
@@ -25,16 +34,32 @@ export interface CopyableValueProps {
|
|
|
25
34
|
*/
|
|
26
35
|
block?: boolean;
|
|
27
36
|
/**
|
|
28
|
-
* Height past which a block value scrolls on its own
|
|
37
|
+
* Height past which a block value scrolls on its own, or is cut off when it
|
|
38
|
+
* is clipped.
|
|
29
39
|
* @default 160
|
|
30
40
|
*/
|
|
31
41
|
maxHeight?: number | string;
|
|
42
|
+
/**
|
|
43
|
+
* Whether a block value is cut off at `maxHeight` and faded, rather than
|
|
44
|
+
* given scrollbars. A notation is copied rather than read, and a molfile is
|
|
45
|
+
* both long and wide, so a scrollbar on each axis of each of two of them is
|
|
46
|
+
* four bars of chrome buying nothing.
|
|
47
|
+
* @default false
|
|
48
|
+
*/
|
|
49
|
+
clip?: boolean;
|
|
32
50
|
/**
|
|
33
51
|
* What the pointer and a screen reader are told, replacing the title built
|
|
34
52
|
* from the label and the value.
|
|
35
53
|
* @default undefined — `Copy the ${label} (${value})`
|
|
36
54
|
*/
|
|
37
55
|
copyTitle?: string;
|
|
56
|
+
/**
|
|
57
|
+
* A control on the label's own line, pushed to the right — a save button for
|
|
58
|
+
* a notation that is also a file, a menu of the forms it comes in. It sits
|
|
59
|
+
* outside the value, so pressing it never copies.
|
|
60
|
+
* @default undefined
|
|
61
|
+
*/
|
|
62
|
+
action?: ReactNode;
|
|
38
63
|
/**
|
|
39
64
|
* What goes under the value: the links an identifier leads to, a note on it.
|
|
40
65
|
* @default undefined
|
|
@@ -66,12 +91,31 @@ export function CopyableValue(props: CopyableValueProps): ReactElement {
|
|
|
66
91
|
hint,
|
|
67
92
|
block = false,
|
|
68
93
|
maxHeight = DEFAULT_BLOCK_HEIGHT,
|
|
94
|
+
clip = false,
|
|
69
95
|
copyTitle,
|
|
96
|
+
action,
|
|
70
97
|
children,
|
|
71
98
|
className,
|
|
72
99
|
} = props;
|
|
73
100
|
const isEmpty = value === '';
|
|
74
101
|
|
|
102
|
+
const written = (
|
|
103
|
+
<span
|
|
104
|
+
className="copyable-value__label"
|
|
105
|
+
style={hint === undefined ? LABEL_STYLE : HINTED_LABEL_STYLE}
|
|
106
|
+
>
|
|
107
|
+
{label}
|
|
108
|
+
</span>
|
|
109
|
+
);
|
|
110
|
+
const name =
|
|
111
|
+
hint === undefined ? (
|
|
112
|
+
written
|
|
113
|
+
) : (
|
|
114
|
+
<HelpTooltip content={{ body: hint }} placement="top-start">
|
|
115
|
+
{written}
|
|
116
|
+
</HelpTooltip>
|
|
117
|
+
);
|
|
118
|
+
|
|
75
119
|
return (
|
|
76
120
|
<div
|
|
77
121
|
className={
|
|
@@ -80,21 +124,29 @@ export function CopyableValue(props: CopyableValueProps): ReactElement {
|
|
|
80
124
|
: `copyable-value ${className}`
|
|
81
125
|
}
|
|
82
126
|
>
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
127
|
+
{action === undefined ? (
|
|
128
|
+
name
|
|
129
|
+
) : (
|
|
130
|
+
<span className="copyable-value__header" style={HEADER_STYLE}>
|
|
131
|
+
{name}
|
|
132
|
+
{action}
|
|
133
|
+
</span>
|
|
134
|
+
)}
|
|
90
135
|
<ClickToCopy
|
|
91
136
|
as="code"
|
|
137
|
+
// The value fills the row, so the glyph goes inside its right edge: a
|
|
138
|
+
// `code` is an inline element but this one is laid out as a block.
|
|
139
|
+
layout="block"
|
|
92
140
|
value={value}
|
|
93
141
|
label={label}
|
|
94
142
|
title={copyTitle}
|
|
95
143
|
disabled={isEmpty}
|
|
96
144
|
className="copyable-value__value"
|
|
97
|
-
style={
|
|
145
|
+
style={
|
|
146
|
+
block
|
|
147
|
+
? { ...(clip ? CLIPPED_VALUE_STYLE : BLOCK_VALUE_STYLE), maxHeight }
|
|
148
|
+
: VALUE_STYLE
|
|
149
|
+
}
|
|
98
150
|
>
|
|
99
151
|
{isEmpty ? MISSING_VALUE : value}
|
|
100
152
|
</ClickToCopy>
|
|
@@ -110,9 +162,24 @@ const LABEL_STYLE = {
|
|
|
110
162
|
fontWeight: 600,
|
|
111
163
|
} as const satisfies CSSProperties;
|
|
112
164
|
|
|
165
|
+
/**
|
|
166
|
+
* A label that explains itself is underlined with dots, which is the one
|
|
167
|
+
* convention that lets a `?` glyph leave the row — see `OverlayRow`, where the
|
|
168
|
+
* rest of the package already reads this way.
|
|
169
|
+
*/
|
|
113
170
|
const HINTED_LABEL_STYLE = {
|
|
114
171
|
...LABEL_STYLE,
|
|
115
|
-
|
|
172
|
+
...OVERLAY_HELP_NAME_STYLE,
|
|
173
|
+
display: 'inline',
|
|
174
|
+
} as const satisfies CSSProperties;
|
|
175
|
+
|
|
176
|
+
/** The label and its control, on one line with the control at the right. */
|
|
177
|
+
const HEADER_STYLE = {
|
|
178
|
+
display: 'flex',
|
|
179
|
+
minHeight: 20,
|
|
180
|
+
alignItems: 'center',
|
|
181
|
+
justifyContent: 'space-between',
|
|
182
|
+
gap: 8,
|
|
116
183
|
} as const satisfies CSSProperties;
|
|
117
184
|
|
|
118
185
|
const VALUE_STYLE = {
|
|
@@ -128,3 +195,11 @@ const BLOCK_VALUE_STYLE = {
|
|
|
128
195
|
overflowWrap: 'normal',
|
|
129
196
|
overflow: 'auto',
|
|
130
197
|
} as const satisfies CSSProperties;
|
|
198
|
+
|
|
199
|
+
/** The same block, cut off at its height and faded out rather than scrolled. */
|
|
200
|
+
const CLIPPED_VALUE_STYLE = {
|
|
201
|
+
...BLOCK_VALUE_STYLE,
|
|
202
|
+
overflow: 'hidden',
|
|
203
|
+
maskImage: FADE,
|
|
204
|
+
WebkitMaskImage: FADE,
|
|
205
|
+
} as const satisfies CSSProperties;
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
export type {
|
|
1
|
+
export type {
|
|
2
|
+
ClickToCopyElement,
|
|
3
|
+
ClickToCopyLayout,
|
|
4
|
+
ClickToCopyProps,
|
|
5
|
+
} from './ClickToCopy.tsx';
|
|
2
6
|
export { ClickToCopy } from './ClickToCopy.tsx';
|
|
3
7
|
export type { CodeBlockProps, CodeBlockTone } from './CodeBlock.tsx';
|
|
4
8
|
export { CodeBlock } from './CodeBlock.tsx';
|
|
@@ -4,6 +4,7 @@ import type { ReactElement, ReactNode } from 'react';
|
|
|
4
4
|
import { useState } from 'react';
|
|
5
5
|
|
|
6
6
|
import { useChromeT } from '../../i18n/ui/useT.ts';
|
|
7
|
+
import { joinClassNames } from '../../shared/ui/joinClassNames.ts';
|
|
7
8
|
|
|
8
9
|
/** Props of {@link ConfirmButton}: a Blueprint button, and what it asks. */
|
|
9
10
|
export interface ConfirmButtonProps extends Omit<ButtonProps, 'onClick'> {
|
|
@@ -46,6 +47,7 @@ export function ConfirmButton(props: ConfirmButtonProps): ReactElement {
|
|
|
46
47
|
<>
|
|
47
48
|
<Button
|
|
48
49
|
{...buttonProps}
|
|
50
|
+
className={joinClassNames('no-print', buttonProps.className)}
|
|
49
51
|
onClick={() => {
|
|
50
52
|
setAsking(true);
|
|
51
53
|
}}
|
package/src/core.ts
CHANGED
|
@@ -21,6 +21,7 @@ export * from './parallel/core/index.ts';
|
|
|
21
21
|
export * from './pedagogy/core/index.ts';
|
|
22
22
|
export * from './periodic/core/index.ts';
|
|
23
23
|
export * from './projection/core/index.ts';
|
|
24
|
+
export * from './range/core/index.ts';
|
|
24
25
|
export * from './router/core/index.ts';
|
|
25
26
|
export * from './scatter/core/index.ts';
|
|
26
27
|
export * from './scatter3d/core/index.ts';
|
|
@@ -4,6 +4,7 @@ import type { ReactElement, ReactNode } from 'react';
|
|
|
4
4
|
import { useState } from 'react';
|
|
5
5
|
|
|
6
6
|
import { useChromeT } from '../../i18n/ui/useT.ts';
|
|
7
|
+
import { joinClassNames } from '../../shared/ui/joinClassNames.ts';
|
|
7
8
|
|
|
8
9
|
import type { DelimitedTextDialogProps } from './DelimitedTextDialog.tsx';
|
|
9
10
|
import { DelimitedTextDialog } from './DelimitedTextDialog.tsx';
|
|
@@ -139,7 +140,7 @@ export function TableDataButton(props: TableDataButtonProps): ReactElement {
|
|
|
139
140
|
trigger(show)
|
|
140
141
|
) : (
|
|
141
142
|
<Button
|
|
142
|
-
className={buttonClassName}
|
|
143
|
+
className={joinClassNames('no-print', buttonClassName)}
|
|
143
144
|
icon={icon}
|
|
144
145
|
text={text}
|
|
145
146
|
variant={minimal ? 'minimal' : 'solid'}
|
|
@@ -48,6 +48,13 @@ export interface FigureSvg {
|
|
|
48
48
|
/** What a saved SVG figure is, for the file and for the renderer reading it. */
|
|
49
49
|
export const FIGURE_SVG_TYPE = 'image/svg+xml;charset=utf-8';
|
|
50
50
|
|
|
51
|
+
/** A run of words inside a card, with where it sits and how it is set. */
|
|
52
|
+
interface TextRun {
|
|
53
|
+
text: string;
|
|
54
|
+
box: DOMRect;
|
|
55
|
+
type: CSSStyleDeclaration;
|
|
56
|
+
}
|
|
57
|
+
|
|
51
58
|
/** The token a figure's own ground is named by. */
|
|
52
59
|
const SURFACE_TOKEN = '--surface';
|
|
53
60
|
|
|
@@ -138,19 +145,15 @@ function legendMarkup(legend: Element, box: DOMRect): string {
|
|
|
138
145
|
}
|
|
139
146
|
|
|
140
147
|
const texts: FigureLegendText[] = [];
|
|
141
|
-
for (const run of legend
|
|
142
|
-
|
|
143
|
-
const words = run.textContent?.trim() ?? '';
|
|
144
|
-
if (words === '') continue;
|
|
145
|
-
const at = run.getBoundingClientRect();
|
|
146
|
-
const type = window.getComputedStyle(run);
|
|
148
|
+
for (const run of textRuns(legend)) {
|
|
149
|
+
const at = run.box;
|
|
147
150
|
texts.push({
|
|
148
|
-
text:
|
|
151
|
+
text: run.text,
|
|
149
152
|
x: at.left - box.left,
|
|
150
153
|
y: at.top - box.top + at.height / 2,
|
|
151
|
-
color: type.color,
|
|
152
|
-
fontSize: Number.parseFloat(type.fontSize),
|
|
153
|
-
fontWeight: type.fontWeight,
|
|
154
|
+
color: run.type.color,
|
|
155
|
+
fontSize: Number.parseFloat(run.type.fontSize),
|
|
156
|
+
fontWeight: run.type.fontWeight,
|
|
154
157
|
});
|
|
155
158
|
}
|
|
156
159
|
|
|
@@ -172,6 +175,35 @@ function legendMarkup(legend: Element, box: DOMRect): string {
|
|
|
172
175
|
});
|
|
173
176
|
}
|
|
174
177
|
|
|
178
|
+
/**
|
|
179
|
+
* Every run of words inside a card, with the box the browser gave it.
|
|
180
|
+
*
|
|
181
|
+
* Collected as text nodes rather than as elements, because an element is only
|
|
182
|
+
* the smallest box around a run when it holds nothing else: a formula drawn as
|
|
183
|
+
* `HCO<sub>3</sub><sup>-</sup>` keeps `HCO` on the element itself, and a card
|
|
184
|
+
* read element by element loses exactly the letters that name the species. The
|
|
185
|
+
* box is measured over the characters with a `Range`, which is also tighter
|
|
186
|
+
* than the element's own box wherever that element is padded.
|
|
187
|
+
* @param legend - The card, as it sits on the page.
|
|
188
|
+
* @returns The runs, in the order they are written.
|
|
189
|
+
*/
|
|
190
|
+
function textRuns(legend: Element): TextRun[] {
|
|
191
|
+
const runs: TextRun[] = [];
|
|
192
|
+
const walker = document.createTreeWalker(legend, NodeFilter.SHOW_TEXT);
|
|
193
|
+
const range = document.createRange();
|
|
194
|
+
for (let node = walker.nextNode(); node !== null; node = walker.nextNode()) {
|
|
195
|
+
const words = node.textContent?.trim() ?? '';
|
|
196
|
+
if (words === '') continue;
|
|
197
|
+
const parent = node.parentElement;
|
|
198
|
+
if (parent === null) continue;
|
|
199
|
+
range.selectNodeContents(node);
|
|
200
|
+
const box = range.getBoundingClientRect();
|
|
201
|
+
if (box.width <= 0 || box.height <= 0) continue;
|
|
202
|
+
runs.push({ text: words, box, type: window.getComputedStyle(parent) });
|
|
203
|
+
}
|
|
204
|
+
return runs;
|
|
205
|
+
}
|
|
206
|
+
|
|
175
207
|
/**
|
|
176
208
|
* One drawing, serialized with every token it names written out.
|
|
177
209
|
*
|
|
@@ -3,6 +3,7 @@ import { Button } from '@blueprintjs/core';
|
|
|
3
3
|
import type { ReactElement } from 'react';
|
|
4
4
|
|
|
5
5
|
import { useChromeT } from '../../i18n/ui/useT.ts';
|
|
6
|
+
import { joinClassNames } from '../../shared/ui/joinClassNames.ts';
|
|
6
7
|
|
|
7
8
|
import type { HelpContent } from './HelpBody.tsx';
|
|
8
9
|
import { HelpTooltip } from './HelpTooltip.tsx';
|
|
@@ -68,7 +69,7 @@ export function HelpToolbarButton(props: HelpToolbarButtonProps): ReactElement {
|
|
|
68
69
|
icon={icon}
|
|
69
70
|
text={label}
|
|
70
71
|
aria-label={label ?? helpName(content, t)}
|
|
71
|
-
className={className}
|
|
72
|
+
className={joinClassNames('no-print', className)}
|
|
72
73
|
onClick={onClick}
|
|
73
74
|
/>
|
|
74
75
|
</HelpTooltip>
|