react-cheminfo 0.54.0 → 0.55.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/README.md +14 -0
- package/lib/chrome/ui/SiteHeader.d.ts +17 -1
- package/lib/chrome/ui/SiteHeader.d.ts.map +1 -1
- package/lib/chrome/ui/SiteHeader.js +9 -2
- package/lib/chrome/ui/SiteHeader.js.map +1 -1
- package/lib/contact/core/contactUrl.d.ts +35 -0
- package/lib/contact/core/contactUrl.d.ts.map +1 -0
- package/lib/contact/core/contactUrl.js +33 -0
- package/lib/contact/core/contactUrl.js.map +1 -0
- package/lib/contact/core/index.d.ts +3 -0
- package/lib/contact/core/index.d.ts.map +1 -0
- package/lib/contact/core/index.js +2 -0
- package/lib/contact/core/index.js.map +1 -0
- package/lib/contact/ui/ContactButton.d.ts +41 -0
- package/lib/contact/ui/ContactButton.d.ts.map +1 -0
- package/lib/contact/ui/ContactButton.js +29 -0
- package/lib/contact/ui/ContactButton.js.map +1 -0
- package/lib/contact/ui/index.d.ts +3 -0
- package/lib/contact/ui/index.d.ts.map +1 -0
- package/lib/contact/ui/index.js +2 -0
- package/lib/contact/ui/index.js.map +1 -0
- 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/deploy/core/reactCopies.d.ts.map +1 -1
- package/lib/deploy/core/reactCopies.js +7 -2
- package/lib/deploy/core/reactCopies.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 +2 -0
- package/lib/locales/en.json +2 -0
- package/lib/locales/es.json +2 -0
- package/lib/locales/fr.json +2 -0
- package/lib/locales/it.json +2 -0
- package/lib/share/ui/ShareConfigOptions.d.ts.map +1 -1
- package/lib/share/ui/ShareConfigOptions.js +2 -1
- package/lib/share/ui/ShareConfigOptions.js.map +1 -1
- package/lib/share/ui/ShareDialogContent.d.ts.map +1 -1
- package/lib/share/ui/ShareDialogContent.js +10 -2
- package/lib/share/ui/ShareDialogContent.js.map +1 -1
- package/lib/share/ui/ShareSealOption.d.ts +19 -0
- package/lib/share/ui/ShareSealOption.d.ts.map +1 -0
- package/lib/share/ui/ShareSealOption.js +16 -0
- package/lib/share/ui/ShareSealOption.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/chrome/ui/SiteHeader.tsx +35 -3
- package/src/contact/core/contactUrl.ts +53 -0
- package/src/contact/core/index.ts +2 -0
- package/src/contact/ui/ContactButton.tsx +74 -0
- package/src/contact/ui/index.ts +2 -0
- package/src/core.ts +1 -0
- package/src/deploy/core/reactCopies.ts +7 -2
- package/src/locales/de.json +2 -0
- package/src/locales/en.json +2 -0
- package/src/locales/es.json +2 -0
- package/src/locales/fr.json +2 -0
- package/src/locales/it.json +2 -0
- package/src/share/ui/ShareConfigOptions.tsx +3 -4
- package/src/share/ui/ShareDialogContent.tsx +33 -2
- package/src/share/ui/ShareSealOption.tsx +37 -0
- package/src/ui.ts +1 -0
- package/styles/chrome.css +21 -0
|
@@ -3,6 +3,7 @@ import { H6 } from '@blueprintjs/core';
|
|
|
3
3
|
import { useChromeT } from "../../i18n/ui/useT.js";
|
|
4
4
|
import { SharePartOptions } from "./SharePartOptions.js";
|
|
5
5
|
import { SharePartRow } from "./SharePartRow.js";
|
|
6
|
+
import { ShareSealOption } from "./ShareSealOption.js";
|
|
6
7
|
const SECTION_STYLE = { marginBottom: 14 };
|
|
7
8
|
/**
|
|
8
9
|
* The switches of the share dialog: the layout — embedded, and sealed where the
|
|
@@ -13,6 +14,6 @@ const SECTION_STYLE = { marginBottom: 14 };
|
|
|
13
14
|
export function ShareConfigOptions(props) {
|
|
14
15
|
const { embed, parts, hidden, descriptions, onEmbedChange, sealed = false, onSealedChange, onPartChange, onPartPointed, } = props;
|
|
15
16
|
const t = useChromeT();
|
|
16
|
-
return (_jsxs(_Fragment, { children: [_jsxs("section", { className: "share-section", style: SECTION_STYLE, children: [_jsx(H6, { children: t('share.layout') }), _jsx(SharePartRow, { label: t('share.embed'), description: t('share.embedHint'), on: embed, descriptions: descriptions, onChange: onEmbedChange }), onSealedChange === undefined ? null : (_jsx(
|
|
17
|
+
return (_jsxs(_Fragment, { children: [_jsxs("section", { className: "share-section", style: SECTION_STYLE, children: [_jsx(H6, { children: t('share.layout') }), _jsx(SharePartRow, { label: t('share.embed'), description: t('share.embedHint'), on: embed, descriptions: descriptions, onChange: onEmbedChange }), onSealedChange === undefined ? null : (_jsx(ShareSealOption, { sealed: sealed, descriptions: descriptions, onChange: onSealedChange }))] }), parts.length > 0 ? (_jsxs("section", { className: "share-section", style: SECTION_STYLE, children: [_jsx(H6, { children: t('share.showOnPage') }), _jsx(SharePartOptions, { parts: parts, hidden: hidden, descriptions: descriptions, onChange: onPartChange, onPointed: onPartPointed })] })) : null] }));
|
|
17
18
|
}
|
|
18
19
|
//# sourceMappingURL=ShareConfigOptions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShareConfigOptions.js","sourceRoot":"","sources":["../../../src/share/ui/ShareConfigOptions.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,mBAAmB,CAAC;AAGvC,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAwB,CAAC;AAE1D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"ShareConfigOptions.js","sourceRoot":"","sources":["../../../src/share/ui/ShareConfigOptions.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,mBAAmB,CAAC;AAGvC,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAwB,CAAC;AAE1D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAuB,CAAC;AAExD,MAAM,aAAa,GAAkB,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC;AA6B1D;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAA8B;IAE9B,MAAM,EACJ,KAAK,EACL,KAAK,EACL,MAAM,EACN,YAAY,EACZ,aAAa,EACb,MAAM,GAAG,KAAK,EACd,cAAc,EACd,YAAY,EACZ,aAAa,GACd,GAAG,KAAK,CAAC;IACV,MAAM,CAAC,GAAG,UAAU,EAAE,CAAC;IAEvB,OAAO,CACL,8BACE,mBAAS,SAAS,EAAC,eAAe,EAAC,KAAK,EAAE,aAAa,aACrD,KAAC,EAAE,cAAE,CAAC,CAAC,cAAc,CAAC,GAAM,EAC5B,KAAC,YAAY,IACX,KAAK,EAAE,CAAC,CAAC,aAAa,CAAC,EACvB,WAAW,EAAE,CAAC,CAAC,iBAAiB,CAAC,EACjC,EAAE,EAAE,KAAK,EACT,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,aAAa,GACvB,EACD,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CACrC,KAAC,eAAe,IACd,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,cAAc,GACxB,CACH,IACO,EAET,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAClB,mBAAS,SAAS,EAAC,eAAe,EAAC,KAAK,EAAE,aAAa,aACrD,KAAC,EAAE,cAAE,CAAC,CAAC,kBAAkB,CAAC,GAAM,EAChC,KAAC,gBAAgB,IACf,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,YAAY,EACtB,SAAS,EAAE,aAAa,GACxB,IACM,CACX,CAAC,CAAC,CAAC,IAAI,IACP,CACJ,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShareDialogContent.d.ts","sourceRoot":"","sources":["../../../src/share/ui/ShareDialogContent.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,YAAY,EAAE,MAAM,OAAO,CAAC;AAIzD,OAAO,KAAK,EAGV,gBAAgB,EAIjB,MAAM,kBAAkB,CAAC;AAc1B,OAAO,KAAK,EAAE,gBAAgB,EAAc,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"ShareDialogContent.d.ts","sourceRoot":"","sources":["../../../src/share/ui/ShareDialogContent.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,YAAY,EAAE,MAAM,OAAO,CAAC;AAIzD,OAAO,KAAK,EAGV,gBAAgB,EAIjB,MAAM,kBAAkB,CAAC;AAc1B,OAAO,KAAK,EAAE,gBAAgB,EAAc,MAAM,mBAAmB,CAAC;AAiBtE,gFAAgF;AAChF,MAAM,MAAM,uBAAuB,CACjC,MAAM,SAAS,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IACrD,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAC,CAAC;AAE3D;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,SAAS,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EACvD,KAAK,EAAE,uBAAuB,CAAC,MAAM,CAAC,GAAG,YAAY,CA0JtD"}
|
|
@@ -8,6 +8,7 @@ import { ShareLinkBar } from "./ShareLinkBar.js";
|
|
|
8
8
|
import { SharePanes } from "./SharePanes.js";
|
|
9
9
|
import { SharePresetTabs } from "./SharePresetTabs.js";
|
|
10
10
|
import { SharePreview } from "./SharePreview.js";
|
|
11
|
+
import { ShareSealOption } from "./ShareSealOption.js";
|
|
11
12
|
import { withPart } from "./draft.js";
|
|
12
13
|
import { useSealedUrl } from "./useSealedUrl.js";
|
|
13
14
|
const NO_PRESETS = [];
|
|
@@ -74,12 +75,19 @@ export function ShareDialogContent(props) {
|
|
|
74
75
|
title: frameTitle ?? title,
|
|
75
76
|
height: frameHeight,
|
|
76
77
|
});
|
|
77
|
-
const
|
|
78
|
+
const onSealedChange = offeredWhenOpened(setSealed);
|
|
79
|
+
const options = (_jsx(ShareConfigOptions, { embed: shown.embed, parts: visibleShareParts(vocabulary.parts, shown.embed), hidden: config.hidden, descriptions: partDescriptions, onEmbedChange: setEmbed, sealed: sealed, onSealedChange: onSealedChange, onPartChange: setPartHidden, onPartPointed: setPointed }));
|
|
78
80
|
const openPreset = findPreset(presets, presetKey);
|
|
79
|
-
const optionsPane = (_jsxs("div", { className: "share-dialog__options", children: [openPreset === undefined ? (options) : (_jsx(
|
|
81
|
+
const optionsPane = (_jsxs("div", { className: "share-dialog__options", children: [openPreset === undefined ? (options) : (_jsx(PresetSummary, { description: openPreset.description, sealed: sealed, descriptions: partDescriptions, onSealedChange: onSealedChange })), children === undefined ? null : (_jsx("section", { className: "share-section", style: SECTION_STYLE, children: typeof children === 'function' ? children(draft) : children }))] }));
|
|
80
82
|
const previewPane = preview ? (_jsx(SharePreview, { url: link, title: frameTitle ?? title, highlight: highlightOf(vocabulary.parts, pointed) })) : null;
|
|
81
83
|
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "share-dialog__body", ref: body, children: [presets.length === 0 ? null : (_jsx("div", { className: "share-dialog__top", children: _jsx(SharePresetTabs, { presets: presets, selected: presetKey, onSelect: selectPreset }) })), _jsx(SharePanes, { options: optionsPane, preview: previewPane, narrow: narrow })] }), _jsx(DialogFooter, { actions: _jsx(ShareLinkBar, { url: link, frame: frame, disabled: !ready, onCopied: onClose }) })] }));
|
|
82
84
|
}
|
|
85
|
+
// A preset says what it hands out; protecting the link is the one switch it
|
|
86
|
+
// leaves to the teacher, so it stays within reach on every tab.
|
|
87
|
+
function PresetSummary(props) {
|
|
88
|
+
const { description, sealed, descriptions, onSealedChange } = props;
|
|
89
|
+
return (_jsxs(_Fragment, { children: [_jsx("p", { className: "share-dialog__preset", children: description }), onSealedChange === undefined ? null : (_jsx(ShareSealOption, { sealed: sealed, descriptions: descriptions, onChange: onSealedChange }))] }));
|
|
90
|
+
}
|
|
83
91
|
// A sealed page is always embedded, whatever a preset said.
|
|
84
92
|
function embeddedWhenSealed(config, sealed) {
|
|
85
93
|
return sealed ? { ...config, embed: true } : config;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShareDialogContent.js","sourceRoot":"","sources":["../../../src/share/ui/ShareDialogContent.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAStE,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,sBAAsB,EACtB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAA0B,CAAC;AAE9D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"ShareDialogContent.js","sourceRoot":"","sources":["../../../src/share/ui/ShareDialogContent.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ReactElement } from 'react';
|
|
2
|
+
import type { SharePartDescriptions } from './SharePartRow.tsx';
|
|
3
|
+
export interface ShareSealOptionProps {
|
|
4
|
+
/** Whether the link is handed out sealed. */
|
|
5
|
+
sealed: boolean;
|
|
6
|
+
/** Where the row says what sealing does. */
|
|
7
|
+
descriptions: SharePartDescriptions;
|
|
8
|
+
/** Called when sealing is switched. */
|
|
9
|
+
onChange: (sealed: boolean) => void;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* The switch that seals a link. It sits with the layout switches, and under a
|
|
13
|
+
* preset's description too, since protecting a link is not part of what any
|
|
14
|
+
* preset chooses.
|
|
15
|
+
* @param props - Whether the link is sealed, and how to change it.
|
|
16
|
+
* @returns The row.
|
|
17
|
+
*/
|
|
18
|
+
export declare function ShareSealOption(props: ShareSealOptionProps): ReactElement;
|
|
19
|
+
//# sourceMappingURL=ShareSealOption.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ShareSealOption.d.ts","sourceRoot":"","sources":["../../../src/share/ui/ShareSealOption.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAI1C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAGhE,MAAM,WAAW,oBAAoB;IACnC,6CAA6C;IAC7C,MAAM,EAAE,OAAO,CAAC;IAChB,4CAA4C;IAC5C,YAAY,EAAE,qBAAqB,CAAC;IACpC,uCAAuC;IACvC,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;CACrC;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,YAAY,CAazE"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useChromeT } from "../../i18n/ui/useT.js";
|
|
3
|
+
import { SharePartRow } from "./SharePartRow.js";
|
|
4
|
+
/**
|
|
5
|
+
* The switch that seals a link. It sits with the layout switches, and under a
|
|
6
|
+
* preset's description too, since protecting a link is not part of what any
|
|
7
|
+
* preset chooses.
|
|
8
|
+
* @param props - Whether the link is sealed, and how to change it.
|
|
9
|
+
* @returns The row.
|
|
10
|
+
*/
|
|
11
|
+
export function ShareSealOption(props) {
|
|
12
|
+
const { sealed, descriptions, onChange } = props;
|
|
13
|
+
const t = useChromeT();
|
|
14
|
+
return (_jsx(SharePartRow, { label: t('share.protect'), description: t('share.protectHint'), on: sealed, descriptions: descriptions, onChange: onChange }));
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=ShareSealOption.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ShareSealOption.js","sourceRoot":"","sources":["../../../src/share/ui/ShareSealOption.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGnD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAoB,CAAC;AAWlD;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,KAA2B;IACzD,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IACjD,MAAM,CAAC,GAAG,UAAU,EAAE,CAAC;IAEvB,OAAO,CACL,KAAC,YAAY,IACX,KAAK,EAAE,CAAC,CAAC,eAAe,CAAC,EACzB,WAAW,EAAE,CAAC,CAAC,mBAAmB,CAAC,EACnC,EAAE,EAAE,MAAM,EACV,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,QAAQ,GAClB,CACH,CAAC;AACJ,CAAC"}
|
package/lib/ui.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export * from './capsule/ui/index.ts';
|
|
|
4
4
|
export * from './chart/ui/index.ts';
|
|
5
5
|
export * from './chrome/ui/index.ts';
|
|
6
6
|
export * from './citation/ui/index.ts';
|
|
7
|
+
export * from './contact/ui/index.ts';
|
|
7
8
|
export * from './clipboard/ui/index.ts';
|
|
8
9
|
export * from './color/ui/index.ts';
|
|
9
10
|
export * from './confirm/ui/index.ts';
|
package/lib/ui.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AAKvC,YAAY,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACnE,YAAY,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EACL,uBAAuB,EACvB,cAAc,EACd,eAAe,GAChB,MAAM,oCAAoC,CAAC"}
|
|
1
|
+
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AAKvC,YAAY,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACnE,YAAY,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EACL,uBAAuB,EACvB,cAAc,EACd,eAAe,GAChB,MAAM,oCAAoC,CAAC"}
|
package/lib/ui.js
CHANGED
|
@@ -4,6 +4,7 @@ export * from "./capsule/ui/index.js";
|
|
|
4
4
|
export * from "./chart/ui/index.js";
|
|
5
5
|
export * from "./chrome/ui/index.js";
|
|
6
6
|
export * from "./citation/ui/index.js";
|
|
7
|
+
export * from "./contact/ui/index.js";
|
|
7
8
|
export * from "./clipboard/ui/index.js";
|
|
8
9
|
export * from "./color/ui/index.js";
|
|
9
10
|
export * from "./confirm/ui/index.js";
|
package/lib/ui.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AAMvC,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAmC,CAAC;AAEnE,OAAO,EACL,uBAAuB,EACvB,cAAc,EACd,eAAe,GAChB,MAAM,oCAAoC,CAAC"}
|
|
1
|
+
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AAMvC,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAmC,CAAC;AAEnE,OAAO,EACL,uBAAuB,EACvB,cAAc,EACd,eAAe,GAChB,MAAM,oCAAoC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-cheminfo",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.55.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "React components, hooks and framework-free helpers shared by the cheminfo sites: site chrome, citations, sharing, routing, pedagogy, charts, and the structure, orbital and 3D molecule viewers",
|
|
6
6
|
"author": "Luc Patiny",
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import type { ReactElement, ReactNode } from 'react';
|
|
2
2
|
import { Fragment } from 'react';
|
|
3
3
|
|
|
4
|
+
import { contactFormUrl } from '../../contact/core/contactUrl.ts';
|
|
5
|
+
import { ContactButton } from '../../contact/ui/ContactButton.tsx';
|
|
4
6
|
import { siteById } from '../../ecosystem/core/lookup.ts';
|
|
5
7
|
import type { SiteId, SiteRecord } from '../../ecosystem/core/sites.ts';
|
|
6
8
|
import { Wordmark } from '../../ecosystem/ui/Wordmark.tsx';
|
|
7
9
|
import { SiteMark } from '../../ecosystem/ui/marks.tsx';
|
|
10
|
+
import { useLanguage } from '../../i18n/ui/useLanguage.ts';
|
|
8
11
|
import { useChromeT } from '../../i18n/ui/useT.ts';
|
|
9
12
|
|
|
10
13
|
import { NavLink } from './NavLink.tsx';
|
|
@@ -39,12 +42,28 @@ export interface SiteHeaderProps {
|
|
|
39
42
|
*/
|
|
40
43
|
activeId?: string;
|
|
41
44
|
/**
|
|
42
|
-
* The utilities pushed to the right edge — Cite, Tools,
|
|
45
|
+
* The utilities pushed to the right edge — About, Cite, Tools, the language,
|
|
46
|
+
* sign in; Share has a prop of its own, so it always comes last. They
|
|
43
47
|
* arrive dressed as bar items, so a plain `nav-link` and a `CiteButton` read
|
|
44
48
|
* alike beside each other.
|
|
45
49
|
* @default undefined
|
|
46
50
|
*/
|
|
47
51
|
actions?: ReactNode;
|
|
52
|
+
/**
|
|
53
|
+
* The Share entry, which closes the utilities on every site, after the
|
|
54
|
+
* Contact entry. A site passes its own when it wraps the shared `ShareButton`
|
|
55
|
+
* in a dialog of its own.
|
|
56
|
+
* @default undefined
|
|
57
|
+
*/
|
|
58
|
+
share?: ReactNode;
|
|
59
|
+
/**
|
|
60
|
+
* The contact form the Contact entry opens, drawn after the site's utilities
|
|
61
|
+
* and just before Share, with
|
|
62
|
+
* `{site}` and `{page}` where the site and the page are written; `false`
|
|
63
|
+
* leaves the entry out. No entry is drawn while there is no form.
|
|
64
|
+
* @default the family's form in the language of the page (`CONTACT_FORM_URLS`)
|
|
65
|
+
*/
|
|
66
|
+
contact?: string | false;
|
|
48
67
|
/**
|
|
49
68
|
* Draws one page the site's own way, for a bar whose entries need a tooltip
|
|
50
69
|
* or a wrapper of their own.
|
|
@@ -113,6 +132,8 @@ export function SiteHeader(props: SiteHeaderProps): ReactElement | null {
|
|
|
113
132
|
nav,
|
|
114
133
|
activeId,
|
|
115
134
|
actions,
|
|
135
|
+
share,
|
|
136
|
+
contact,
|
|
116
137
|
renderNavItem,
|
|
117
138
|
embedded = false,
|
|
118
139
|
homeHref = '/',
|
|
@@ -122,6 +143,7 @@ export function SiteHeader(props: SiteHeaderProps): ReactElement | null {
|
|
|
122
143
|
pagesLabel,
|
|
123
144
|
} = props;
|
|
124
145
|
const t = useChromeT();
|
|
146
|
+
const language = useLanguage();
|
|
125
147
|
|
|
126
148
|
if (embedded) return null;
|
|
127
149
|
|
|
@@ -129,6 +151,8 @@ export function SiteHeader(props: SiteHeaderProps): ReactElement | null {
|
|
|
129
151
|
if (site === undefined) {
|
|
130
152
|
throw new Error('SiteHeader needs one of its `site` and `siteId` props');
|
|
131
153
|
}
|
|
154
|
+
const contactForm =
|
|
155
|
+
contact === false ? '' : (contact ?? contactFormUrl(language));
|
|
132
156
|
|
|
133
157
|
return (
|
|
134
158
|
<header className="app-header no-print">
|
|
@@ -169,8 +193,16 @@ export function SiteHeader(props: SiteHeaderProps): ReactElement | null {
|
|
|
169
193
|
</div>
|
|
170
194
|
) : null}
|
|
171
195
|
<span className="spacer" />
|
|
172
|
-
{actions === undefined
|
|
173
|
-
|
|
196
|
+
{actions === undefined &&
|
|
197
|
+
share === undefined &&
|
|
198
|
+
contactForm === '' ? null : (
|
|
199
|
+
<div className="app-header-actions">
|
|
200
|
+
{actions}
|
|
201
|
+
{contactForm === '' ? null : (
|
|
202
|
+
<ContactButton siteId={site.id} formUrl={contactForm} />
|
|
203
|
+
)}
|
|
204
|
+
{share}
|
|
205
|
+
</div>
|
|
174
206
|
)}
|
|
175
207
|
</div>
|
|
176
208
|
</header>
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { Language } from '../../i18n/core/languages.ts';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Address of the contact form every site of the family opens, one per language the form
|
|
5
|
+
* is written in, with `{site}` and `{page}` where the site and the page are written. A
|
|
6
|
+
* language without a form of its own opens the English one; with no form at all, no
|
|
7
|
+
* Contact entry is drawn.
|
|
8
|
+
*/
|
|
9
|
+
export const CONTACT_FORM_URLS: Readonly<Partial<Record<Language, string>>> = {
|
|
10
|
+
en: 'https://docs.google.com/forms/d/e/1FAIpQLSd_1G3tUOEJh_qapmLn_xrybWa9Nu7B57bpYm76o4nwPKPWsg/viewform?usp=pp_url&entry.569380734={site}&entry.2103045774={page}',
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/** What a contact address is filled with. */
|
|
14
|
+
export interface ContactUrlOptions {
|
|
15
|
+
/** The site the message is about, written as its id. */
|
|
16
|
+
site: string;
|
|
17
|
+
/**
|
|
18
|
+
* The address of the page the reader was on.
|
|
19
|
+
* @default ''
|
|
20
|
+
*/
|
|
21
|
+
page?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The contact form in the language of the page, or the English one when the form is not
|
|
26
|
+
* written in that language.
|
|
27
|
+
* @param language - The language of the page.
|
|
28
|
+
* @param urls - The forms, by language.
|
|
29
|
+
* @returns The address of the form, or an empty string when there is none.
|
|
30
|
+
*/
|
|
31
|
+
export function contactFormUrl(
|
|
32
|
+
language: Language,
|
|
33
|
+
urls: Readonly<Partial<Record<Language, string>>> = CONTACT_FORM_URLS,
|
|
34
|
+
): string {
|
|
35
|
+
return urls[language] ?? urls.en ?? '';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Fill the address of a contact form with the site and the page, both encoded, so the
|
|
40
|
+
* form opens knowing what the message is about.
|
|
41
|
+
* @param template - Address holding `{site}` and `{page}`.
|
|
42
|
+
* @param options - The site and the page.
|
|
43
|
+
* @returns The address to open.
|
|
44
|
+
*/
|
|
45
|
+
export function contactUrl(
|
|
46
|
+
template: string,
|
|
47
|
+
options: ContactUrlOptions,
|
|
48
|
+
): string {
|
|
49
|
+
const { site, page = '' } = options;
|
|
50
|
+
return template
|
|
51
|
+
.replaceAll('{site}', encodeURIComponent(site))
|
|
52
|
+
.replaceAll('{page}', encodeURIComponent(page));
|
|
53
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { ReactElement } from 'react';
|
|
2
|
+
|
|
3
|
+
import { NavLink } from '../../chrome/ui/NavLink.tsx';
|
|
4
|
+
import { useLanguage } from '../../i18n/ui/useLanguage.ts';
|
|
5
|
+
import { useChromeT } from '../../i18n/ui/useT.ts';
|
|
6
|
+
import { contactFormUrl, contactUrl } from '../core/contactUrl.ts';
|
|
7
|
+
|
|
8
|
+
/** What the Contact entry of a header needs. */
|
|
9
|
+
export interface ContactButtonProps {
|
|
10
|
+
/** The site the reader writes about, written into the form. */
|
|
11
|
+
siteId: string;
|
|
12
|
+
/**
|
|
13
|
+
* Address of the form, with `{site}` and `{page}` where they are written.
|
|
14
|
+
* @default the family's form in the language of the page (`CONTACT_FORM_URLS`)
|
|
15
|
+
*/
|
|
16
|
+
formUrl?: string;
|
|
17
|
+
/**
|
|
18
|
+
* The page the reader is on, written into the form.
|
|
19
|
+
* @default the address of the current page
|
|
20
|
+
*/
|
|
21
|
+
page?: string;
|
|
22
|
+
/**
|
|
23
|
+
* What the entry reads. In a compact bar it is not written, but it stays what
|
|
24
|
+
* the pointer and a screen reader are told.
|
|
25
|
+
* @default the chrome's own word for it, in the language of the page
|
|
26
|
+
*/
|
|
27
|
+
label?: string;
|
|
28
|
+
/**
|
|
29
|
+
* What the pointer is told.
|
|
30
|
+
* @default the chrome's own sentence, in the language of the page
|
|
31
|
+
*/
|
|
32
|
+
title?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Class names added after the component's own.
|
|
35
|
+
* @default undefined
|
|
36
|
+
*/
|
|
37
|
+
className?: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* The Contact entry of a site header: it opens the family's contact form in a new tab,
|
|
42
|
+
* with the site and the page already filled in, so the reader only writes the message.
|
|
43
|
+
* The form is opened, never embedded, so nothing is loaded from it before the click.
|
|
44
|
+
* @param props - The site, and the form it opens.
|
|
45
|
+
* @returns The entry, or nothing while no form address is set.
|
|
46
|
+
*/
|
|
47
|
+
export function ContactButton(props: ContactButtonProps): ReactElement | null {
|
|
48
|
+
const {
|
|
49
|
+
siteId,
|
|
50
|
+
page = globalThis.location?.href ?? '',
|
|
51
|
+
label,
|
|
52
|
+
title,
|
|
53
|
+
className,
|
|
54
|
+
} = props;
|
|
55
|
+
const t = useChromeT();
|
|
56
|
+
const language = useLanguage();
|
|
57
|
+
const formUrl = props.formUrl ?? contactFormUrl(language);
|
|
58
|
+
|
|
59
|
+
if (formUrl === '') return null;
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<NavLink
|
|
63
|
+
item={{
|
|
64
|
+
id: 'contact',
|
|
65
|
+
label: label ?? t('chrome.contact'),
|
|
66
|
+
icon: 'chat',
|
|
67
|
+
href: contactUrl(formUrl, { site: siteId, page }),
|
|
68
|
+
external: true,
|
|
69
|
+
title: title ?? t('chrome.contactTitle'),
|
|
70
|
+
}}
|
|
71
|
+
className={className}
|
|
72
|
+
/>
|
|
73
|
+
);
|
|
74
|
+
}
|
package/src/core.ts
CHANGED
|
@@ -5,6 +5,7 @@ export * from './chart/core/index.ts';
|
|
|
5
5
|
export * from './citation/core/index.ts';
|
|
6
6
|
export * from './clipboard/core/index.ts';
|
|
7
7
|
export * from './color/core/index.ts';
|
|
8
|
+
export * from './contact/core/index.ts';
|
|
8
9
|
export * from './credits/core/index.ts';
|
|
9
10
|
export * from './delimited/core/index.ts';
|
|
10
11
|
export * from './download/core/index.ts';
|
|
@@ -108,14 +108,19 @@ export function readReactCopies(
|
|
|
108
108
|
|
|
109
109
|
const stale = stalePeer(entries);
|
|
110
110
|
if (stale !== undefined) {
|
|
111
|
-
|
|
111
|
+
// All four, not the runtime pair: a lock that pins only `react` and
|
|
112
|
+
// `react-dom` keeps a nested `@types/react` of the wrong major, and `tsc`
|
|
113
|
+
// then rejects a component crossing between the two type trees, in a file
|
|
114
|
+
// nobody touched. Twenty-one sites were in that state while this check
|
|
115
|
+
// asked for two.
|
|
116
|
+
for (const name of SINGLE_COPY) {
|
|
112
117
|
if (declared.get(name)?.override !== undefined) continue;
|
|
113
118
|
problems.push({
|
|
114
119
|
file: 'package.json',
|
|
115
120
|
line: lineOf(packageJson, '"dependencies"'),
|
|
116
121
|
kind: 'unpinned-react',
|
|
117
122
|
message: `${stale.name} asks for ${stale.key} ${stale.range}, which excludes React ${REACT_MAJOR}, and nothing pins ${name}`,
|
|
118
|
-
hint: `
|
|
123
|
+
hint: `pin all four in the root "overrides": react, react-dom, @types/react and @types/react-dom, each with the range it is depended on`,
|
|
119
124
|
});
|
|
120
125
|
}
|
|
121
126
|
}
|
package/src/locales/de.json
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
"chrome.pages": "Seiten",
|
|
4
4
|
"chrome.about": "Über",
|
|
5
5
|
"chrome.aboutTitle": "Was diese Seite ist, worauf sie aufbaut und wie man sie zitiert",
|
|
6
|
+
"chrome.contact": "Kontakt",
|
|
7
|
+
"chrome.contactTitle": "Eine Frage, ein Problem, eine Idee? Schreiben Sie uns",
|
|
6
8
|
"account.signIn": "Anmelden",
|
|
7
9
|
"account.signOut": "Abmelden",
|
|
8
10
|
"account.signedInAs": "Angemeldet als {name}",
|
package/src/locales/en.json
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
"chrome.pages": "Pages",
|
|
4
4
|
"chrome.about": "About",
|
|
5
5
|
"chrome.aboutTitle": "What this site is, what it is built on, and how to cite it",
|
|
6
|
+
"chrome.contact": "Contact",
|
|
7
|
+
"chrome.contactTitle": "A question, a problem or an idea? Write to us",
|
|
6
8
|
"account.signIn": "Sign in",
|
|
7
9
|
"account.signOut": "Sign out",
|
|
8
10
|
"account.signedInAs": "Signed in as {name}",
|
package/src/locales/es.json
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
"chrome.pages": "Páginas",
|
|
4
4
|
"chrome.about": "Acerca de",
|
|
5
5
|
"chrome.aboutTitle": "Qué es este sitio, en qué se basa y cómo citarlo",
|
|
6
|
+
"chrome.contact": "Contacto",
|
|
7
|
+
"chrome.contactTitle": "¿Una pregunta, un problema, una idea? Escríbanos",
|
|
6
8
|
"account.signIn": "Iniciar sesión",
|
|
7
9
|
"account.signOut": "Cerrar sesión",
|
|
8
10
|
"account.signedInAs": "Sesión iniciada como {name}",
|
package/src/locales/fr.json
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
"chrome.pages": "Pages",
|
|
4
4
|
"chrome.about": "À propos",
|
|
5
5
|
"chrome.aboutTitle": "Ce qu'est ce site, sur quoi il est bâti et comment le citer",
|
|
6
|
+
"chrome.contact": "Contact",
|
|
7
|
+
"chrome.contactTitle": "Une question, un problème, une idée ? Écrivez-nous",
|
|
6
8
|
"account.signIn": "Se connecter",
|
|
7
9
|
"account.signOut": "Se déconnecter",
|
|
8
10
|
"account.signedInAs": "Connecté comme {name}",
|
package/src/locales/it.json
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
"chrome.pages": "Pagine",
|
|
4
4
|
"chrome.about": "Informazioni",
|
|
5
5
|
"chrome.aboutTitle": "Cosa è questo sito, su cosa si basa e come citarlo",
|
|
6
|
+
"chrome.contact": "Contatto",
|
|
7
|
+
"chrome.contactTitle": "Una domanda, un problema, un'idea? Scriveteci",
|
|
6
8
|
"account.signIn": "Accedi",
|
|
7
9
|
"account.signOut": "Esci",
|
|
8
10
|
"account.signedInAs": "Accesso effettuato come {name}",
|
|
@@ -7,6 +7,7 @@ import type { HideablePart } from '../core/index.ts';
|
|
|
7
7
|
import { SharePartOptions } from './SharePartOptions.tsx';
|
|
8
8
|
import type { SharePartDescriptions } from './SharePartRow.tsx';
|
|
9
9
|
import { SharePartRow } from './SharePartRow.tsx';
|
|
10
|
+
import { ShareSealOption } from './ShareSealOption.tsx';
|
|
10
11
|
|
|
11
12
|
const SECTION_STYLE: CSSProperties = { marginBottom: 14 };
|
|
12
13
|
|
|
@@ -71,10 +72,8 @@ export function ShareConfigOptions(
|
|
|
71
72
|
onChange={onEmbedChange}
|
|
72
73
|
/>
|
|
73
74
|
{onSealedChange === undefined ? null : (
|
|
74
|
-
<
|
|
75
|
-
|
|
76
|
-
description={t('share.protectHint')}
|
|
77
|
-
on={sealed}
|
|
75
|
+
<ShareSealOption
|
|
76
|
+
sealed={sealed}
|
|
78
77
|
descriptions={descriptions}
|
|
79
78
|
onChange={onSealedChange}
|
|
80
79
|
/>
|
|
@@ -27,8 +27,10 @@ import { ShareConfigOptions } from './ShareConfigOptions.tsx';
|
|
|
27
27
|
import type { ShareDialogProps, ShareDraft } from './ShareDialog.tsx';
|
|
28
28
|
import { ShareLinkBar } from './ShareLinkBar.tsx';
|
|
29
29
|
import { SharePanes } from './SharePanes.tsx';
|
|
30
|
+
import type { SharePartDescriptions } from './SharePartRow.tsx';
|
|
30
31
|
import { SharePresetTabs } from './SharePresetTabs.tsx';
|
|
31
32
|
import { SharePreview } from './SharePreview.tsx';
|
|
33
|
+
import { ShareSealOption } from './ShareSealOption.tsx';
|
|
32
34
|
import { withPart } from './draft.ts';
|
|
33
35
|
import { useSealedUrl } from './useSealedUrl.ts';
|
|
34
36
|
|
|
@@ -131,6 +133,7 @@ export function ShareDialogContent<
|
|
|
131
133
|
title: frameTitle ?? title,
|
|
132
134
|
height: frameHeight,
|
|
133
135
|
});
|
|
136
|
+
const onSealedChange = offeredWhenOpened(setSealed);
|
|
134
137
|
const options = (
|
|
135
138
|
<ShareConfigOptions
|
|
136
139
|
embed={shown.embed}
|
|
@@ -139,7 +142,7 @@ export function ShareDialogContent<
|
|
|
139
142
|
descriptions={partDescriptions}
|
|
140
143
|
onEmbedChange={setEmbed}
|
|
141
144
|
sealed={sealed}
|
|
142
|
-
onSealedChange={
|
|
145
|
+
onSealedChange={onSealedChange}
|
|
143
146
|
onPartChange={setPartHidden}
|
|
144
147
|
onPartPointed={setPointed}
|
|
145
148
|
/>
|
|
@@ -151,7 +154,12 @@ export function ShareDialogContent<
|
|
|
151
154
|
{openPreset === undefined ? (
|
|
152
155
|
options
|
|
153
156
|
) : (
|
|
154
|
-
<
|
|
157
|
+
<PresetSummary
|
|
158
|
+
description={openPreset.description}
|
|
159
|
+
sealed={sealed}
|
|
160
|
+
descriptions={partDescriptions}
|
|
161
|
+
onSealedChange={onSealedChange}
|
|
162
|
+
/>
|
|
155
163
|
)}
|
|
156
164
|
|
|
157
165
|
{children === undefined ? null : (
|
|
@@ -203,6 +211,29 @@ export function ShareDialogContent<
|
|
|
203
211
|
);
|
|
204
212
|
}
|
|
205
213
|
|
|
214
|
+
// A preset says what it hands out; protecting the link is the one switch it
|
|
215
|
+
// leaves to the teacher, so it stays within reach on every tab.
|
|
216
|
+
function PresetSummary(props: {
|
|
217
|
+
description: string;
|
|
218
|
+
sealed: boolean;
|
|
219
|
+
descriptions: SharePartDescriptions;
|
|
220
|
+
onSealedChange: ((sealed: boolean) => void) | undefined;
|
|
221
|
+
}): ReactElement {
|
|
222
|
+
const { description, sealed, descriptions, onSealedChange } = props;
|
|
223
|
+
return (
|
|
224
|
+
<>
|
|
225
|
+
<p className="share-dialog__preset">{description}</p>
|
|
226
|
+
{onSealedChange === undefined ? null : (
|
|
227
|
+
<ShareSealOption
|
|
228
|
+
sealed={sealed}
|
|
229
|
+
descriptions={descriptions}
|
|
230
|
+
onChange={onSealedChange}
|
|
231
|
+
/>
|
|
232
|
+
)}
|
|
233
|
+
</>
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
|
|
206
237
|
// A sealed page is always embedded, whatever a preset said.
|
|
207
238
|
function embeddedWhenSealed<Codecs extends ShareParamCodecs>(
|
|
208
239
|
config: ShareConfig<Codecs>,
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { ReactElement } from 'react';
|
|
2
|
+
|
|
3
|
+
import { useChromeT } from '../../i18n/ui/useT.ts';
|
|
4
|
+
|
|
5
|
+
import type { SharePartDescriptions } from './SharePartRow.tsx';
|
|
6
|
+
import { SharePartRow } from './SharePartRow.tsx';
|
|
7
|
+
|
|
8
|
+
export interface ShareSealOptionProps {
|
|
9
|
+
/** Whether the link is handed out sealed. */
|
|
10
|
+
sealed: boolean;
|
|
11
|
+
/** Where the row says what sealing does. */
|
|
12
|
+
descriptions: SharePartDescriptions;
|
|
13
|
+
/** Called when sealing is switched. */
|
|
14
|
+
onChange: (sealed: boolean) => void;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The switch that seals a link. It sits with the layout switches, and under a
|
|
19
|
+
* preset's description too, since protecting a link is not part of what any
|
|
20
|
+
* preset chooses.
|
|
21
|
+
* @param props - Whether the link is sealed, and how to change it.
|
|
22
|
+
* @returns The row.
|
|
23
|
+
*/
|
|
24
|
+
export function ShareSealOption(props: ShareSealOptionProps): ReactElement {
|
|
25
|
+
const { sealed, descriptions, onChange } = props;
|
|
26
|
+
const t = useChromeT();
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<SharePartRow
|
|
30
|
+
label={t('share.protect')}
|
|
31
|
+
description={t('share.protectHint')}
|
|
32
|
+
on={sealed}
|
|
33
|
+
descriptions={descriptions}
|
|
34
|
+
onChange={onChange}
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
37
|
+
}
|
package/src/ui.ts
CHANGED
|
@@ -4,6 +4,7 @@ export * from './capsule/ui/index.ts';
|
|
|
4
4
|
export * from './chart/ui/index.ts';
|
|
5
5
|
export * from './chrome/ui/index.ts';
|
|
6
6
|
export * from './citation/ui/index.ts';
|
|
7
|
+
export * from './contact/ui/index.ts';
|
|
7
8
|
export * from './clipboard/ui/index.ts';
|
|
8
9
|
export * from './color/ui/index.ts';
|
|
9
10
|
export * from './confirm/ui/index.ts';
|