react-cheminfo 0.38.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/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 +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/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 +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/styles/chrome.css +414 -14
package/src/chart/ui/Axes.tsx
CHANGED
|
@@ -78,6 +78,25 @@ export interface AxesProps {
|
|
|
78
78
|
* @default 44
|
|
79
79
|
*/
|
|
80
80
|
yTickSpacing?: number;
|
|
81
|
+
/**
|
|
82
|
+
* The values to rule the vertical axis at, instead of the ones the room
|
|
83
|
+
* allows.
|
|
84
|
+
*
|
|
85
|
+
* An axis whose ticks are decided by what is being measured rather than by
|
|
86
|
+
* how much space there is: a concentration read over fifteen decades is ruled
|
|
87
|
+
* at the decades, and a tick at 0.0037 between two of them says nothing. The
|
|
88
|
+
* values outside the window are dropped, so one list serves every zoom.
|
|
89
|
+
* @default the ticks worked out from the window and the room
|
|
90
|
+
*/
|
|
91
|
+
yTickValues?: readonly number[];
|
|
92
|
+
/**
|
|
93
|
+
* How a value up the side is written, instead of as a plain number.
|
|
94
|
+
*
|
|
95
|
+
* What goes with `yTickValues`: an axis ruled at the decades writes `10⁻³`,
|
|
96
|
+
* and the exponent is the only part of it a reader is reading.
|
|
97
|
+
* @default the notation the window's step calls for
|
|
98
|
+
*/
|
|
99
|
+
formatYTick?: (value: number) => string;
|
|
81
100
|
}
|
|
82
101
|
|
|
83
102
|
/**
|
|
@@ -123,6 +142,8 @@ export function Axes(props: AxesProps): ReactElement {
|
|
|
123
142
|
yTitle,
|
|
124
143
|
xTickSpacing = X_TICK_SPACING,
|
|
125
144
|
yTickSpacing = Y_TICK_SPACING,
|
|
145
|
+
yTickValues,
|
|
146
|
+
formatYTick,
|
|
126
147
|
} = props;
|
|
127
148
|
|
|
128
149
|
const xTicks = useMemo(
|
|
@@ -134,7 +155,15 @@ export function Axes(props: AxesProps): ReactElement {
|
|
|
134
155
|
[yDomain, plot.height, yTickSpacing],
|
|
135
156
|
);
|
|
136
157
|
const writeXTick = useMemo(() => axisLabeller(xTicks), [xTicks]);
|
|
137
|
-
const
|
|
158
|
+
const labelYTick = useMemo(() => axisLabeller(yTicks), [yTicks]);
|
|
159
|
+
const writeYTick = formatYTick ?? labelYTick;
|
|
160
|
+
|
|
161
|
+
// Ruled where the quantity asks rather than where there is room; a value the
|
|
162
|
+
// zoom has left behind is dropped rather than drawn onto the margin.
|
|
163
|
+
const yRules = useMemo(
|
|
164
|
+
() => (yTickValues ? insideWindow(yTickValues, yDomain) : yTicks.values),
|
|
165
|
+
[yTickValues, yDomain, yTicks],
|
|
166
|
+
);
|
|
138
167
|
|
|
139
168
|
const middleX = plot.left + plot.width / 2;
|
|
140
169
|
const middleY = plot.top + plot.height / 2;
|
|
@@ -144,8 +173,8 @@ export function Axes(props: AxesProps): ReactElement {
|
|
|
144
173
|
// clear of the narrower — far enough to read as naming the chart rather than
|
|
145
174
|
// the axis.
|
|
146
175
|
const titleColumn = useMemo(
|
|
147
|
-
() => valueTitleColumn(
|
|
148
|
-
[
|
|
176
|
+
() => valueTitleColumn(yRules, writeYTick, absYTicks, plot.left),
|
|
177
|
+
[yRules, writeYTick, absYTicks, plot.left],
|
|
149
178
|
);
|
|
150
179
|
// The rule a mirrored pair is reflected in only exists while both halves are
|
|
151
180
|
// on screen; on an ordinary chart zero is the baseline and already drawn.
|
|
@@ -164,7 +193,7 @@ export function Axes(props: AxesProps): ReactElement {
|
|
|
164
193
|
style={gridStyle}
|
|
165
194
|
/>
|
|
166
195
|
))}
|
|
167
|
-
{
|
|
196
|
+
{yRules.map((tick) => (
|
|
168
197
|
<line
|
|
169
198
|
key={tick}
|
|
170
199
|
x1={plot.left}
|
|
@@ -201,7 +230,7 @@ export function Axes(props: AxesProps): ReactElement {
|
|
|
201
230
|
{writeXTick(tick)}
|
|
202
231
|
</text>
|
|
203
232
|
))}
|
|
204
|
-
{
|
|
233
|
+
{yRules.map((tick) => (
|
|
205
234
|
<text
|
|
206
235
|
key={tick}
|
|
207
236
|
x={plot.left - TICK_LABEL_GAP}
|
|
@@ -238,6 +267,25 @@ export function Axes(props: AxesProps): ReactElement {
|
|
|
238
267
|
);
|
|
239
268
|
}
|
|
240
269
|
|
|
270
|
+
/**
|
|
271
|
+
* The values of a given list that the window still shows.
|
|
272
|
+
* @param values - Every value the axis would be ruled at.
|
|
273
|
+
* @param domain - The window on screen, `[from, to]`.
|
|
274
|
+
* @returns Those inside it, in the order they were given.
|
|
275
|
+
*/
|
|
276
|
+
function insideWindow(
|
|
277
|
+
values: readonly number[],
|
|
278
|
+
domain: readonly [number, number],
|
|
279
|
+
): number[] {
|
|
280
|
+
const low = Math.min(domain[0], domain[1]);
|
|
281
|
+
const high = Math.max(domain[0], domain[1]);
|
|
282
|
+
const inside: number[] = [];
|
|
283
|
+
for (const value of values) {
|
|
284
|
+
if (value >= low && value <= high) inside.push(value);
|
|
285
|
+
}
|
|
286
|
+
return inside;
|
|
287
|
+
}
|
|
288
|
+
|
|
241
289
|
/**
|
|
242
290
|
* The ticks of one axis of a chart a reader has zoomed for themselves.
|
|
243
291
|
*
|
|
@@ -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
|
}}
|
|
@@ -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'}
|