react-cheminfo 0.38.0 → 0.39.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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/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 +39 -4
- package/lib/locales/en.json +39 -4
- package/lib/locales/es.json +39 -4
- package/lib/locales/fr.json +39 -4
- package/lib/locales/it.json +39 -4
- 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/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/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 +129 -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 +102 -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/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/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 +39 -4
- package/src/locales/en.json +39 -4
- package/src/locales/es.json +39 -4
- package/src/locales/fr.json +39 -4
- package/src/locales/it.json +39 -4
- 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/seo/core/plainDescription.ts +4 -2
- 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 +235 -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 +108 -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/styles/chrome.css +414 -14
|
@@ -2,6 +2,7 @@ import { Button, Icon } from '@blueprintjs/core';
|
|
|
2
2
|
import type { ReactElement } from 'react';
|
|
3
3
|
|
|
4
4
|
import { useChromeT } from '../../i18n/ui/useT.ts';
|
|
5
|
+
import { joinClassNames } from '../../shared/ui/joinClassNames.ts';
|
|
5
6
|
|
|
6
7
|
/** How the button is dressed for the bar it sits in. */
|
|
7
8
|
export type ShareButtonVariant = 'nav-link' | 'blueprint';
|
|
@@ -61,7 +62,7 @@ export function ShareButton(props: ShareButtonProps): ReactElement {
|
|
|
61
62
|
if (variant === 'blueprint') {
|
|
62
63
|
return (
|
|
63
64
|
<Button
|
|
64
|
-
className={className}
|
|
65
|
+
className={joinClassNames('no-print', className)}
|
|
65
66
|
variant="minimal"
|
|
66
67
|
icon="share"
|
|
67
68
|
text={text}
|
|
@@ -75,11 +76,7 @@ export function ShareButton(props: ShareButtonProps): ReactElement {
|
|
|
75
76
|
return (
|
|
76
77
|
<button
|
|
77
78
|
type="button"
|
|
78
|
-
className={
|
|
79
|
-
className === undefined
|
|
80
|
-
? 'nav-link nav-link--icon'
|
|
81
|
-
: `nav-link nav-link--icon ${className}`
|
|
82
|
-
}
|
|
79
|
+
className={joinClassNames('nav-link nav-link--icon no-print', className)}
|
|
83
80
|
title={title}
|
|
84
81
|
aria-label={label}
|
|
85
82
|
onClick={onClick}
|
|
@@ -1,18 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { H6 } from '@blueprintjs/core';
|
|
2
2
|
import type { CSSProperties, ReactElement } from 'react';
|
|
3
3
|
|
|
4
4
|
import { useChromeT } from '../../i18n/ui/useT.ts';
|
|
5
5
|
import type { HideablePart } from '../core/index.ts';
|
|
6
6
|
|
|
7
7
|
import { SharePartOptions } from './SharePartOptions.tsx';
|
|
8
|
+
import type { SharePartDescriptions } from './SharePartRow.tsx';
|
|
9
|
+
import { SharePartRow } from './SharePartRow.tsx';
|
|
8
10
|
|
|
9
|
-
const SECTION_STYLE: CSSProperties = { marginBottom:
|
|
10
|
-
const HINT_STYLE: CSSProperties = {
|
|
11
|
-
display: 'block',
|
|
12
|
-
marginLeft: 26,
|
|
13
|
-
color: 'var(--text-muted, #5b6875)',
|
|
14
|
-
fontSize: 12,
|
|
15
|
-
};
|
|
11
|
+
const SECTION_STYLE: CSSProperties = { marginBottom: 14 };
|
|
16
12
|
|
|
17
13
|
export interface ShareConfigOptionsProps {
|
|
18
14
|
/** Whether the draft drops the site chrome. */
|
|
@@ -21,35 +17,46 @@ export interface ShareConfigOptionsProps {
|
|
|
21
17
|
parts: readonly HideablePart[];
|
|
22
18
|
/** The parts the draft switches off. */
|
|
23
19
|
hidden: readonly string[];
|
|
20
|
+
/** Where each row says what switching it off does. */
|
|
21
|
+
descriptions: SharePartDescriptions;
|
|
24
22
|
/** Called when the layout is switched. */
|
|
25
23
|
onEmbedChange: (embed: boolean) => void;
|
|
26
24
|
/** Called with the part and whether the link should switch it off. */
|
|
27
25
|
onPartChange: (part: string, hidden: boolean) => void;
|
|
26
|
+
/** Called with the part the pointer is on, or `null` when it leaves. */
|
|
27
|
+
onPartPointed: (part: string | null) => void;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
|
-
* The
|
|
31
|
+
* The switches of the share dialog: the layout, then one per part of the page.
|
|
32
32
|
* @param props - The draft's layout and parts, and how to change them.
|
|
33
33
|
* @returns The two sections.
|
|
34
34
|
*/
|
|
35
35
|
export function ShareConfigOptions(
|
|
36
36
|
props: ShareConfigOptionsProps,
|
|
37
37
|
): ReactElement {
|
|
38
|
-
const {
|
|
38
|
+
const {
|
|
39
|
+
embed,
|
|
40
|
+
parts,
|
|
41
|
+
hidden,
|
|
42
|
+
descriptions,
|
|
43
|
+
onEmbedChange,
|
|
44
|
+
onPartChange,
|
|
45
|
+
onPartPointed,
|
|
46
|
+
} = props;
|
|
39
47
|
const t = useChromeT();
|
|
40
48
|
|
|
41
49
|
return (
|
|
42
50
|
<>
|
|
43
51
|
<section className="share-section" style={SECTION_STYLE}>
|
|
44
52
|
<H6>{t('share.layout')}</H6>
|
|
45
|
-
<
|
|
46
|
-
checked={embed}
|
|
53
|
+
<SharePartRow
|
|
47
54
|
label={t('share.embed')}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
55
|
+
description={t('share.embedHint')}
|
|
56
|
+
on={embed}
|
|
57
|
+
descriptions={descriptions}
|
|
58
|
+
onChange={onEmbedChange}
|
|
51
59
|
/>
|
|
52
|
-
<span style={HINT_STYLE}>{t('share.embedHint')}</span>
|
|
53
60
|
</section>
|
|
54
61
|
|
|
55
62
|
{parts.length > 0 ? (
|
|
@@ -58,7 +65,9 @@ export function ShareConfigOptions(
|
|
|
58
65
|
<SharePartOptions
|
|
59
66
|
parts={parts}
|
|
60
67
|
hidden={hidden}
|
|
68
|
+
descriptions={descriptions}
|
|
61
69
|
onChange={onPartChange}
|
|
70
|
+
onPointed={onPartPointed}
|
|
62
71
|
/>
|
|
63
72
|
</section>
|
|
64
73
|
) : null}
|
|
@@ -11,10 +11,11 @@ import type {
|
|
|
11
11
|
} from '../core/index.ts';
|
|
12
12
|
|
|
13
13
|
import { ShareDialogContent } from './ShareDialogContent.tsx';
|
|
14
|
+
import type { SharePartDescriptions } from './SharePartRow.tsx';
|
|
14
15
|
|
|
15
16
|
const DIALOG_STYLE: CSSProperties = {
|
|
16
|
-
width: 'min(
|
|
17
|
-
height: 'min(
|
|
17
|
+
width: 'min(1180px, 96vw)',
|
|
18
|
+
height: 'min(820px, 92dvh)',
|
|
18
19
|
};
|
|
19
20
|
|
|
20
21
|
/**
|
|
@@ -85,6 +86,19 @@ export interface ShareDialogProps<
|
|
|
85
86
|
* @default 700
|
|
86
87
|
*/
|
|
87
88
|
frameHeight?: number;
|
|
89
|
+
/**
|
|
90
|
+
* Whether the page the link hands out is shown live beside the options.
|
|
91
|
+
* A tool whose page is too heavy to load a second time switches it off.
|
|
92
|
+
* @default true
|
|
93
|
+
*/
|
|
94
|
+
preview?: boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Where each row says what switching it off does: `inline` writes it under
|
|
97
|
+
* the label, which is where it is read; `help` puts it behind a glyph beside
|
|
98
|
+
* the label, for a dialog short on room.
|
|
99
|
+
* @default 'inline'
|
|
100
|
+
*/
|
|
101
|
+
partDescriptions?: SharePartDescriptions;
|
|
88
102
|
/**
|
|
89
103
|
* Whether the dialog is rendered through a portal on `document.body`.
|
|
90
104
|
* @default true
|
|
@@ -120,7 +134,7 @@ export function ShareDialog<
|
|
|
120
134
|
isOpen={isOpen}
|
|
121
135
|
onClose={onClose}
|
|
122
136
|
usePortal={usePortal}
|
|
123
|
-
title={t('share.
|
|
137
|
+
title={t('share.dialogTitleFor', { title: rest.title })}
|
|
124
138
|
icon="share"
|
|
125
139
|
className="share-dialog"
|
|
126
140
|
style={DIALOG_STYLE}
|
|
@@ -1,16 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
H6,
|
|
7
|
-
} from '@blueprintjs/core';
|
|
8
|
-
import type { CSSProperties, ReactElement, ReactNode } from 'react';
|
|
9
|
-
import { useState } from 'react';
|
|
10
|
-
|
|
11
|
-
import { CodeBlock, CopyButton } from '../../clipboard/ui/index.ts';
|
|
1
|
+
import { Button, DialogFooter } from '@blueprintjs/core';
|
|
2
|
+
import type { CSSProperties, ReactElement } from 'react';
|
|
3
|
+
import { useRef, useState } from 'react';
|
|
4
|
+
|
|
5
|
+
import { useContainerSize } from '../../hooks/ui/useContainerSize.ts';
|
|
12
6
|
import { useChromeT } from '../../i18n/ui/useT.ts';
|
|
13
7
|
import type {
|
|
8
|
+
HideablePart,
|
|
14
9
|
ShareConfig,
|
|
15
10
|
ShareParamCodecs,
|
|
16
11
|
ShareParamValues,
|
|
@@ -30,27 +25,18 @@ import {
|
|
|
30
25
|
|
|
31
26
|
import { ShareConfigOptions } from './ShareConfigOptions.tsx';
|
|
32
27
|
import type { ShareDialogProps, ShareDraft } from './ShareDialog.tsx';
|
|
28
|
+
import { ShareLinkBar } from './ShareLinkBar.tsx';
|
|
29
|
+
import { SharePanes } from './SharePanes.tsx';
|
|
33
30
|
import { SharePresetTabs } from './SharePresetTabs.tsx';
|
|
31
|
+
import { SharePreview } from './SharePreview.tsx';
|
|
34
32
|
import { withPart } from './draft.ts';
|
|
35
33
|
|
|
36
|
-
const LEAD_STYLE: CSSProperties = {
|
|
37
|
-
marginTop: 0,
|
|
38
|
-
color: 'var(--text-muted, #5b6875)',
|
|
39
|
-
};
|
|
40
|
-
const SECTION_STYLE: CSSProperties = { marginBottom: 18 };
|
|
41
|
-
const ACTIONS_STYLE: CSSProperties = {
|
|
42
|
-
display: 'flex',
|
|
43
|
-
flexWrap: 'wrap',
|
|
44
|
-
gap: 8,
|
|
45
|
-
marginTop: 8,
|
|
46
|
-
};
|
|
47
|
-
|
|
48
34
|
const NO_PRESETS: readonly never[] = [];
|
|
49
35
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const
|
|
36
|
+
/** Width below which the two panes stop fitting side by side and become tabs. */
|
|
37
|
+
const TWO_PANE_WIDTH = 720;
|
|
38
|
+
|
|
39
|
+
const SECTION_STYLE: CSSProperties = { marginBottom: 14 };
|
|
54
40
|
|
|
55
41
|
/** Everything the dialog holds, minus what only its shell is concerned with. */
|
|
56
42
|
export type ShareDialogContentProps<
|
|
@@ -58,8 +44,8 @@ export type ShareDialogContentProps<
|
|
|
58
44
|
> = Omit<ShareDialogProps<Codecs>, 'isOpen' | 'usePortal'>;
|
|
59
45
|
|
|
60
46
|
/**
|
|
61
|
-
* The
|
|
62
|
-
* the
|
|
47
|
+
* The share dialog's body: what one does with the link above, never scrolled
|
|
48
|
+
* away, then the options on the left and the page they write on the right.
|
|
63
49
|
* @param props - What the site's links can say, how the page is named, and the extra section.
|
|
64
50
|
* @returns The body and the footer of the dialog.
|
|
65
51
|
*/
|
|
@@ -76,6 +62,8 @@ export function ShareDialogContent<
|
|
|
76
62
|
search,
|
|
77
63
|
frameTitle,
|
|
78
64
|
frameHeight,
|
|
65
|
+
preview = true,
|
|
66
|
+
partDescriptions = 'inline',
|
|
79
67
|
children,
|
|
80
68
|
} = props;
|
|
81
69
|
const t = useChromeT();
|
|
@@ -86,9 +74,16 @@ export function ShareDialogContent<
|
|
|
86
74
|
const [config, setConfig] = useState<ShareConfig<Codecs>>(() =>
|
|
87
75
|
initialDraft(query, vocabulary, findPreset(presets, defaultPreset ?? null)),
|
|
88
76
|
);
|
|
77
|
+
const [pointed, setPointed] = useState<string | null>(null);
|
|
89
78
|
const [presetKey, setPresetKey] = useState<string | null>(
|
|
90
79
|
() => findSharePreset(config, presets, vocabulary)?.key ?? null,
|
|
91
80
|
);
|
|
81
|
+
const body = useRef<HTMLDivElement>(null);
|
|
82
|
+
const { width } = useContainerSize(body);
|
|
83
|
+
// Zero until the body is first measured, and the wide layout is the one that
|
|
84
|
+
// renders both panes, so nothing is missing from a first paint or a render
|
|
85
|
+
// with no layout at all.
|
|
86
|
+
const narrow = width > 0 && width < TWO_PANE_WIDTH;
|
|
92
87
|
|
|
93
88
|
function setEmbed(embed: boolean): void {
|
|
94
89
|
setConfig((previous) => ({ ...previous, embed }));
|
|
@@ -135,55 +130,57 @@ export function ShareDialogContent<
|
|
|
135
130
|
embed={config.embed}
|
|
136
131
|
parts={visibleShareParts(vocabulary.parts, config.embed)}
|
|
137
132
|
hidden={config.hidden}
|
|
133
|
+
descriptions={partDescriptions}
|
|
138
134
|
onEmbedChange={setEmbed}
|
|
139
135
|
onPartChange={setPartHidden}
|
|
136
|
+
onPartPointed={setPointed}
|
|
140
137
|
/>
|
|
141
138
|
);
|
|
142
139
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
<SharePresetTabs
|
|
152
|
-
presets={presets}
|
|
153
|
-
selected={presetKey}
|
|
154
|
-
onSelect={selectPreset}
|
|
155
|
-
custom={options}
|
|
156
|
-
/>
|
|
157
|
-
)}
|
|
158
|
-
|
|
159
|
-
{children === undefined ? null : (
|
|
160
|
-
<section className="share-section" style={SECTION_STYLE}>
|
|
161
|
-
{typeof children === 'function' ? children(draft) : children}
|
|
162
|
-
</section>
|
|
163
|
-
)}
|
|
140
|
+
const openPreset = findPreset(presets, presetKey);
|
|
141
|
+
const optionsPane = (
|
|
142
|
+
<div className="share-dialog__options">
|
|
143
|
+
{openPreset === undefined ? (
|
|
144
|
+
options
|
|
145
|
+
) : (
|
|
146
|
+
<p className="share-dialog__preset">{openPreset.description}</p>
|
|
147
|
+
)}
|
|
164
148
|
|
|
149
|
+
{children === undefined ? null : (
|
|
165
150
|
<section className="share-section" style={SECTION_STYLE}>
|
|
166
|
-
|
|
167
|
-
<CodeBlock code={url} tone="muted" />
|
|
168
|
-
<div style={ACTIONS_STYLE}>
|
|
169
|
-
<CopyButton content={url} label={t('share.copyLink')} />
|
|
170
|
-
<AnchorButton
|
|
171
|
-
icon="share"
|
|
172
|
-
text={t('share.openInNewTab')}
|
|
173
|
-
href={url}
|
|
174
|
-
target="_blank"
|
|
175
|
-
rel="noopener noreferrer"
|
|
176
|
-
/>
|
|
177
|
-
</div>
|
|
151
|
+
{typeof children === 'function' ? children(draft) : children}
|
|
178
152
|
</section>
|
|
153
|
+
)}
|
|
154
|
+
</div>
|
|
155
|
+
);
|
|
179
156
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
157
|
+
const previewPane = preview ? (
|
|
158
|
+
<SharePreview
|
|
159
|
+
url={url}
|
|
160
|
+
title={frameTitle ?? title}
|
|
161
|
+
highlight={highlightOf(vocabulary.parts, pointed)}
|
|
162
|
+
/>
|
|
163
|
+
) : null;
|
|
164
|
+
|
|
165
|
+
return (
|
|
166
|
+
<>
|
|
167
|
+
<div className="share-dialog__body" ref={body}>
|
|
168
|
+
<div className="share-dialog__top">
|
|
169
|
+
{presets.length === 0 ? null : (
|
|
170
|
+
<SharePresetTabs
|
|
171
|
+
presets={presets}
|
|
172
|
+
selected={presetKey}
|
|
173
|
+
onSelect={selectPreset}
|
|
174
|
+
/>
|
|
175
|
+
)}
|
|
176
|
+
<ShareLinkBar url={url} frame={frame} />
|
|
177
|
+
</div>
|
|
178
|
+
|
|
179
|
+
<SharePanes
|
|
180
|
+
options={optionsPane}
|
|
181
|
+
preview={previewPane}
|
|
182
|
+
narrow={narrow}
|
|
183
|
+
/>
|
|
187
184
|
</div>
|
|
188
185
|
<DialogFooter
|
|
189
186
|
actions={
|
|
@@ -194,14 +191,6 @@ export function ShareDialogContent<
|
|
|
194
191
|
);
|
|
195
192
|
}
|
|
196
193
|
|
|
197
|
-
// The name of the page is set in bold inside a sentence whose word order is
|
|
198
|
-
// the translator's, so the message is split at its placeholder rather than
|
|
199
|
-
// written as a prefix and a suffix.
|
|
200
|
-
function lead(message: string, title: string): ReactNode[] {
|
|
201
|
-
const [before = '', after = ''] = message.split('{title}');
|
|
202
|
-
return [before, <b key="title">{title}</b>, after];
|
|
203
|
-
}
|
|
204
|
-
|
|
205
194
|
function initialDraft<Codecs extends ShareParamCodecs>(
|
|
206
195
|
search: string,
|
|
207
196
|
vocabulary: ShareVocabulary<Codecs>,
|
|
@@ -215,6 +204,20 @@ function initialDraft<Codecs extends ShareParamCodecs>(
|
|
|
215
204
|
: applySharePreset(suggested, preset, vocabulary);
|
|
216
205
|
}
|
|
217
206
|
|
|
207
|
+
// The name in the list and the box on the page are the same thing, so the
|
|
208
|
+
// preview is told what the reader is pointing at rather than a key it would
|
|
209
|
+
// have to look a name up for.
|
|
210
|
+
function highlightOf(
|
|
211
|
+
parts: readonly HideablePart[],
|
|
212
|
+
pointed: string | null,
|
|
213
|
+
): { part: string; label: string } | null {
|
|
214
|
+
if (pointed === null) return null;
|
|
215
|
+
for (const part of parts) {
|
|
216
|
+
if (part.key === pointed) return { part: part.key, label: part.label };
|
|
217
|
+
}
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
|
|
218
221
|
function findPreset<Codecs extends ShareParamCodecs>(
|
|
219
222
|
presets: ReadonlyArray<SharePreset<Codecs>>,
|
|
220
223
|
key: string | null,
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { AnchorButton } from '@blueprintjs/core';
|
|
2
|
+
import type { ReactElement } from 'react';
|
|
3
|
+
|
|
4
|
+
import { CopyButton } from '../../clipboard/ui/index.ts';
|
|
5
|
+
import { HelpTooltip } from '../../help/ui/index.ts';
|
|
6
|
+
import { useChromeT } from '../../i18n/ui/useT.ts';
|
|
7
|
+
|
|
8
|
+
export interface ShareLinkBarProps {
|
|
9
|
+
/** The address the link hands out. */
|
|
10
|
+
url: string;
|
|
11
|
+
/** The markup that frames the page in someone else's site. */
|
|
12
|
+
frame: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The three things one does with a share link, kept above the options and
|
|
17
|
+
* never scrolled away: a dialog whose Copy button is below the fold is a dialog
|
|
18
|
+
* one scrolls through every single time.
|
|
19
|
+
*
|
|
20
|
+
* Neither the address nor the frame markup is printed. A teacher reads neither
|
|
21
|
+
* before pasting it, and a hundred characters of query string set in monospace
|
|
22
|
+
* is the widest thing in the dialog; what tells them which button to press is
|
|
23
|
+
* the help on it.
|
|
24
|
+
* @param props - The address, and the frame markup the third button copies.
|
|
25
|
+
* @returns The bar.
|
|
26
|
+
*/
|
|
27
|
+
export function ShareLinkBar(props: ShareLinkBarProps): ReactElement {
|
|
28
|
+
const { url, frame } = props;
|
|
29
|
+
const t = useChromeT();
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<div className="share-linkbar">
|
|
33
|
+
<HelpTooltip
|
|
34
|
+
content={{
|
|
35
|
+
title: t('share.copyLinkHelpTitle'),
|
|
36
|
+
body: t('share.copyLinkHelp'),
|
|
37
|
+
}}
|
|
38
|
+
>
|
|
39
|
+
<CopyButton content={url} label={t('share.copyLink')} title="" />
|
|
40
|
+
</HelpTooltip>
|
|
41
|
+
<HelpTooltip
|
|
42
|
+
content={{
|
|
43
|
+
title: t('share.openInNewTabHelpTitle'),
|
|
44
|
+
body: t('share.openInNewTabHelp'),
|
|
45
|
+
}}
|
|
46
|
+
>
|
|
47
|
+
<AnchorButton
|
|
48
|
+
icon="share"
|
|
49
|
+
text={t('share.openInNewTab')}
|
|
50
|
+
href={url}
|
|
51
|
+
target="_blank"
|
|
52
|
+
rel="noopener noreferrer"
|
|
53
|
+
/>
|
|
54
|
+
</HelpTooltip>
|
|
55
|
+
<HelpTooltip
|
|
56
|
+
content={{
|
|
57
|
+
title: t('share.copyIframeHelpTitle'),
|
|
58
|
+
body: t('share.copyIframeHelp'),
|
|
59
|
+
}}
|
|
60
|
+
>
|
|
61
|
+
<CopyButton
|
|
62
|
+
content={frame}
|
|
63
|
+
icon="code"
|
|
64
|
+
label={t('share.copyIframe')}
|
|
65
|
+
title=""
|
|
66
|
+
/>
|
|
67
|
+
</HelpTooltip>
|
|
68
|
+
</div>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Tab, Tabs } from '@blueprintjs/core';
|
|
2
|
+
import type { ReactElement } from 'react';
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
|
|
5
|
+
import { useChromeT } from '../../i18n/ui/useT.ts';
|
|
6
|
+
|
|
7
|
+
const OPTIONS_TAB = 'options';
|
|
8
|
+
const PREVIEW_TAB = 'preview';
|
|
9
|
+
|
|
10
|
+
export interface SharePanesProps {
|
|
11
|
+
/** What the link says: the presets, the boxes, and the tool's own section. */
|
|
12
|
+
options: ReactElement;
|
|
13
|
+
/** The live page, or nothing when the dialog shows no preview. */
|
|
14
|
+
preview: ReactElement | null;
|
|
15
|
+
/** Whether the dialog is too narrow to hold the two panes side by side. */
|
|
16
|
+
narrow: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The options and the page they write: side by side where there is room, and
|
|
21
|
+
* two tabs where there is not.
|
|
22
|
+
* @param props - The two panes, and whether they still fit together.
|
|
23
|
+
* @returns The panes, or the tabs holding them.
|
|
24
|
+
*/
|
|
25
|
+
export function SharePanes(props: SharePanesProps): ReactElement {
|
|
26
|
+
const { options, preview, narrow } = props;
|
|
27
|
+
const t = useChromeT();
|
|
28
|
+
const [tab, setTab] = useState<string>(OPTIONS_TAB);
|
|
29
|
+
|
|
30
|
+
if (preview === null) {
|
|
31
|
+
return (
|
|
32
|
+
<div className="share-dialog__panes share-dialog__panes--single">
|
|
33
|
+
{options}
|
|
34
|
+
</div>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (narrow) {
|
|
39
|
+
return (
|
|
40
|
+
<Tabs
|
|
41
|
+
id="share-panes"
|
|
42
|
+
className="share-dialog__tabs"
|
|
43
|
+
animate={false}
|
|
44
|
+
renderActiveTabPanelOnly
|
|
45
|
+
selectedTabId={tab}
|
|
46
|
+
onChange={(tabId) => {
|
|
47
|
+
setTab(String(tabId));
|
|
48
|
+
}}
|
|
49
|
+
>
|
|
50
|
+
<Tab id={OPTIONS_TAB} title={t('share.options')} panel={options} />
|
|
51
|
+
<Tab id={PREVIEW_TAB} title={t('share.preview')} panel={preview} />
|
|
52
|
+
</Tabs>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<div className="share-dialog__panes">
|
|
58
|
+
{options}
|
|
59
|
+
{preview}
|
|
60
|
+
</div>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
@@ -1,50 +1,49 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { CSSProperties, ReactElement } from 'react';
|
|
1
|
+
import type { ReactElement } from 'react';
|
|
3
2
|
|
|
4
3
|
import type { HideablePart } from '../core/index.ts';
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const DESCRIPTION_STYLE: CSSProperties = {
|
|
9
|
-
display: 'block',
|
|
10
|
-
marginLeft: 26,
|
|
11
|
-
color: 'var(--text-muted, #5b6875)',
|
|
12
|
-
fontSize: 12,
|
|
13
|
-
};
|
|
5
|
+
import type { SharePartDescriptions } from './SharePartRow.tsx';
|
|
6
|
+
import { SharePartRow } from './SharePartRow.tsx';
|
|
14
7
|
|
|
15
8
|
export interface SharePartOptionsProps {
|
|
16
9
|
/** The parts this page can switch off, in the order the vocabulary lists them. */
|
|
17
10
|
parts: readonly HideablePart[];
|
|
18
11
|
/** The parts the draft currently switches off. */
|
|
19
12
|
hidden: readonly string[];
|
|
13
|
+
/** Where each row says what switching it off does. */
|
|
14
|
+
descriptions: SharePartDescriptions;
|
|
20
15
|
/** Called with the part and whether the link should switch it off. */
|
|
21
16
|
onChange: (part: string, hidden: boolean) => void;
|
|
17
|
+
/** Called with the part the pointer is on, or `null` when it leaves. */
|
|
18
|
+
onPointed: (part: string | null) => void;
|
|
22
19
|
}
|
|
23
20
|
|
|
24
21
|
/**
|
|
25
|
-
* One
|
|
26
|
-
* link keeps, which is how somebody building a course tile thinks
|
|
22
|
+
* One switch per part of the page, worded positively: a part that is `On` is a
|
|
23
|
+
* part the link keeps, which is how somebody building a course tile thinks
|
|
24
|
+
* about it.
|
|
27
25
|
* @param props - The parts, what is switched off, and how to change it.
|
|
28
|
-
* @returns The
|
|
26
|
+
* @returns The rows.
|
|
29
27
|
*/
|
|
30
28
|
export function SharePartOptions(props: SharePartOptionsProps): ReactElement {
|
|
31
|
-
const { parts, hidden, onChange } = props;
|
|
29
|
+
const { parts, hidden, descriptions, onChange, onPointed } = props;
|
|
32
30
|
|
|
33
31
|
return (
|
|
34
32
|
<>
|
|
35
33
|
{parts.map((part) => (
|
|
36
|
-
<
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
34
|
+
<SharePartRow
|
|
35
|
+
key={part.key}
|
|
36
|
+
label={part.label}
|
|
37
|
+
description={part.description}
|
|
38
|
+
on={!hidden.includes(part.key)}
|
|
39
|
+
descriptions={descriptions}
|
|
40
|
+
onChange={(on) => {
|
|
41
|
+
onChange(part.key, !on);
|
|
42
|
+
}}
|
|
43
|
+
onPointed={(pointed) => {
|
|
44
|
+
onPointed(pointed ? part.key : null);
|
|
45
|
+
}}
|
|
46
|
+
/>
|
|
48
47
|
))}
|
|
49
48
|
</>
|
|
50
49
|
);
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { Switch } from '@blueprintjs/core';
|
|
2
|
+
import type { ReactElement } from 'react';
|
|
3
|
+
import { useId } from 'react';
|
|
4
|
+
|
|
5
|
+
import { HelpIcon } from '../../help/ui/index.ts';
|
|
6
|
+
import { useChromeT } from '../../i18n/ui/useT.ts';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Where a row says what switching it off does: behind a help glyph beside the
|
|
10
|
+
* label, or on a line of its own under it.
|
|
11
|
+
*/
|
|
12
|
+
export type SharePartDescriptions = 'help' | 'inline';
|
|
13
|
+
|
|
14
|
+
export interface SharePartRowProps {
|
|
15
|
+
/** What the row switches, named as the reader sees it on the page. */
|
|
16
|
+
label: string;
|
|
17
|
+
/** What switching it off does, in one sentence. */
|
|
18
|
+
description: string;
|
|
19
|
+
/** Whether the link keeps it. */
|
|
20
|
+
on: boolean;
|
|
21
|
+
/** Where the description is shown. */
|
|
22
|
+
descriptions: SharePartDescriptions;
|
|
23
|
+
/** Called with the state the reader asked for. */
|
|
24
|
+
onChange: (on: boolean) => void;
|
|
25
|
+
/**
|
|
26
|
+
* Called when the pointer enters or leaves the row, so the preview can draw
|
|
27
|
+
* the region it names.
|
|
28
|
+
* @default undefined — the row is not pointed out anywhere
|
|
29
|
+
*/
|
|
30
|
+
onPointed?: (pointed: boolean) => void;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* One row of the share dialog: what it is on the left, whether the link keeps
|
|
35
|
+
* it on the right.
|
|
36
|
+
*
|
|
37
|
+
* The state is written inside the switch rather than left to a tick, because a
|
|
38
|
+
* tick means nothing without the heading above the column — and the heading is
|
|
39
|
+
* the first thing a reader scrolls past. A row that says `On` reads correctly
|
|
40
|
+
* on its own, in every language.
|
|
41
|
+
* @param props - See {@link SharePartRowProps}.
|
|
42
|
+
* @returns The row.
|
|
43
|
+
*/
|
|
44
|
+
export function SharePartRow(props: SharePartRowProps): ReactElement {
|
|
45
|
+
const { label, description, on, descriptions, onChange, onPointed } = props;
|
|
46
|
+
const t = useChromeT();
|
|
47
|
+
const id = useId();
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<div
|
|
51
|
+
className="share-part"
|
|
52
|
+
onMouseEnter={() => onPointed?.(true)}
|
|
53
|
+
onMouseLeave={() => onPointed?.(false)}
|
|
54
|
+
onFocus={() => onPointed?.(true)}
|
|
55
|
+
onBlur={() => onPointed?.(false)}
|
|
56
|
+
>
|
|
57
|
+
<label className="share-part__label" htmlFor={id}>
|
|
58
|
+
{label}
|
|
59
|
+
</label>
|
|
60
|
+
{descriptions === 'help' ? (
|
|
61
|
+
<HelpIcon content={{ title: label, body: description }} label={label} />
|
|
62
|
+
) : null}
|
|
63
|
+
<Switch
|
|
64
|
+
id={id}
|
|
65
|
+
className="share-part__switch"
|
|
66
|
+
checked={on}
|
|
67
|
+
innerLabel={t('share.off')}
|
|
68
|
+
innerLabelChecked={t('share.on')}
|
|
69
|
+
onChange={(event) => {
|
|
70
|
+
onChange(event.currentTarget.checked);
|
|
71
|
+
}}
|
|
72
|
+
/>
|
|
73
|
+
{descriptions === 'inline' ? (
|
|
74
|
+
<p className="share-part__description">{description}</p>
|
|
75
|
+
) : null}
|
|
76
|
+
</div>
|
|
77
|
+
);
|
|
78
|
+
}
|