Skip to content
Snippets Groups Projects
Commit e1439b11 authored by Remi Lazarini's avatar Remi Lazarini
Browse files

[Ivette] help : move scroll function from help to markdown

parent 512229ec
No related branches found
No related tags found
No related merge requests found
react@^18 react-dom@^18 source-map-support lodash@^4 react-virtualized@9.22.5 react-draggable react-fast-compare diff@^5 codemirror@5.65.2 @codemirror/language@6.10.0 @codemirror/search@6.5.5 @codemirror/state@6.4.0 @codemirror/view@6.23.1 @lezer/cpp@^1 react-virtualized-auto-sizer@^1.0.22 react-force-graph-2d@^1.25.4 react-force-graph-3d@^1.24.2 d3-selection@^3 d3-graphviz@^5 react@^18 react-dom@^18 source-map-support lodash@^4 react-virtualized@9.22.5 react-draggable react-fast-compare diff@^5 codemirror@5.65.2 @codemirror/language@6.10.0 @codemirror/search@6.5.5 @codemirror/state@6.4.0 @codemirror/view@6.23.1 @lezer/cpp@^1 react-virtualized-auto-sizer@^1.0.22 react-force-graph-2d@^1.25.4 react-force-graph-3d@^1.24.2 d3-selection@^3 d3-graphviz@^5 react-markdown@9.0.1
...@@ -57,6 +57,7 @@ ...@@ -57,6 +57,7 @@
"react-pivottable": "^0.11.0", "react-pivottable": "^0.11.0",
"react-virtualized": "9.22.5", "react-virtualized": "9.22.5",
"react-virtualized-auto-sizer": "^1.0.22", "react-virtualized-auto-sizer": "^1.0.22",
"remark-custom-header-id": "^1.0.0",
"source-map-support": "^0.5.21", "source-map-support": "^0.5.21",
"tippy.js": "6.3.7", "tippy.js": "6.3.7",
"typedoc": "^0.26.6" "typedoc": "^0.26.6"
......
...@@ -26,95 +26,44 @@ ...@@ -26,95 +26,44 @@
*/ */
import React from 'react'; import React from 'react';
import { classes } from 'dome/misc/utils'; import { IconButton } from './controls/buttons';
import { IconButton, IconButtonKind } from './controls/buttons'; import { Modal, showModal } from './dialogs';
import { Modal, showModal, ModalProps } from './dialogs';
import { iconTag, Markdown, Pattern } from './text/markdown'; import { iconTag, Markdown, Pattern } from './text/markdown';
/* --------------------------------------------------------------------------*/ /* --------------------------------------------------------------------------*/
/* --- Panel List */ /* --- Help */
/* --------------------------------------------------------------------------*/ /* --------------------------------------------------------------------------*/
interface HelpMarkdownProps {
/** classes for Doc component */
className?: string;
/** Tab of patterns */
patterns?: Pattern[];
/**
* scroll to title h1 or h2 when component is render.
* The value must be the id of the balise html.
* Id is calculate by title.toLowerCase().replaceAll(' ','-')
* where title is the content of h1 or h2 if it is a string
*/
initialScrollTo?: string;
/** Markdown content. */
children?: string;
}
export function HelpMarkdown(props: HelpMarkdownProps): JSX.Element {
const { patterns = [iconTag], className, initialScrollTo, children } = props;
const classNames = classes('dome-xHelp', className);
const scrollableDivRef = React.useRef<HTMLDivElement>(null);
const anchorsRef = React.useRef<{
[key: string] : HTMLHeadingElement | null
}>({});
const scrollToAnchor = (id: string): void => {
const scrollableDiv = scrollableDivRef.current;
const anchor = anchorsRef.current[id];
const top = scrollableDiv?.offsetTop || 0;
if (scrollableDiv && anchor) {
const anchorPosition = anchor.offsetTop - top;
scrollableDiv.scrollTo({
top: anchorPosition,
behavior: 'smooth',
});
}
};
React.useEffect(() => {
if(initialScrollTo) scrollToAnchor(initialScrollTo);
}, [initialScrollTo]);
return ( interface HelpIconProps {
<div ref={scrollableDivRef} className={classNames}> /** icon size */
<Markdown
patterns={patterns || [iconTag]}
anchorsRef={anchorsRef}
>{ children }</Markdown>
</div>
);
}
interface IconModalMdProps extends HelpMarkdownProps {
/** Icon props */
kind?: IconButtonKind;
title?: string;
size?: number; size?: number;
/** Properties of Modal component */ /** Tab of patterns */
modal: Omit<ModalProps, 'children'>; patterns?: Pattern[];
/** Initial scroll to the chosen id */
scrollTo?: string;
/** Text of the label. Prepend to other children elements. */
label: string;
/** Function onClose */
onClose?: () => void
/** children */
children: string;
} }
export function IconHelpModalMd(props: IconModalMdProps): JSX.Element { export function HelpIcon(props: HelpIconProps): JSX.Element {
const { title, kind, size, const { size, patterns, scrollTo, label, onClose, children } = props;
patterns, initialScrollTo,
modal, children
} = props;
return ( return (
<IconButton <IconButton
icon='HELP' icon='HELP'
className='dome-xDoc-icon'
title={title}
kind={kind}
size={size} size={size}
className='dome-xDoc-icon'
title={'Help'}
onClick={() => showModal( onClick={() => showModal(
<Modal {...modal} > <Modal label= {label} onClose={onClose} >
<HelpMarkdown <Markdown
patterns={patterns} patterns={patterns || [iconTag]}
initialScrollTo={initialScrollTo} scrollTo={scrollTo}
>{ children }</HelpMarkdown> >{ children }</Markdown>
</Modal>) </Modal>)
} }
/> />
......
...@@ -288,13 +288,3 @@ input[type="checkbox"]:checked { ...@@ -288,13 +288,3 @@ input[type="checkbox"]:checked {
} }
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
/* --- Doc --- */
/* -------------------------------------------------------------------------- */
.dome-xHelp {
max-height: 100%;
overflow-y: auto;
padding: 10px;
}
/* -------------------------------------------------------------------------- */
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
import React from 'react'; import React from 'react';
import ReactMarkdown, { Options } from 'react-markdown'; import ReactMarkdown, { Options } from 'react-markdown';
import remarkCustomHeaderId from 'remark-custom-header-id';
import * as Themes from 'dome/themes'; import * as Themes from 'dome/themes';
import { classes } from 'dome/misc/utils'; import { classes } from 'dome/misc/utils';
...@@ -54,9 +55,9 @@ export const iconTag: Pattern = { ...@@ -54,9 +55,9 @@ export const iconTag: Pattern = {
*/ */
function replaceTags( function replaceTags(
children: React.ReactNode, children: React.ReactNode,
patterns: Pattern[], patterns?: Pattern[],
): React.ReactNode { ): React.ReactNode {
if(patterns.length < 1) return children; if(!patterns || patterns.length < 1) return children;
const buffer: React.ReactNode[] = []; const buffer: React.ReactNode[] = [];
let counter = 0; let counter = 0;
...@@ -100,14 +101,13 @@ function replaceTags( ...@@ -100,14 +101,13 @@ function replaceTags(
// --- Markdown component // --- Markdown component
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
interface MarkdownProps { export interface MarkdownProps {
/** classes for Markdown component */ /** classes for Markdown component */
className?: string; className?: string;
/** Tab of patterns */ /** Tab of patterns */
patterns?: Pattern[]; patterns?: Pattern[];
/** Anchors ref */ /** scroll to the chosen id */
anchorsRef: React.MutableRefObject< scrollTo?: string;
{[key: string] : HTMLHeadingElement | null}>;
/** Children */ /** Children */
children?: string | null; children?: string | null;
} }
...@@ -115,36 +115,27 @@ interface MarkdownProps { ...@@ -115,36 +115,27 @@ interface MarkdownProps {
export function Markdown( export function Markdown(
props: MarkdownProps props: MarkdownProps
): JSX.Element { ): JSX.Element {
const { className, patterns, anchorsRef, children } = props; const { className, scrollTo, patterns, children } = props;
const theme = Themes.useColorTheme()[0]; const theme = Themes.useColorTheme()[0];
const markdownClasses = classes( const markdownClasses = classes(
"dome-xMarkdown", "dome-pages", className "dome-xMarkdown", "dome-pages", className
); );
/** const scroll = (id: string): void => {
* If children is a string this function return the const elt = document.getElementById(id);
* heading element with an id and save ref in anchorsRef if(elt) elt.scrollIntoView({ behavior: "smooth" });
*/
const getHtmlTitle = (
children: React.ReactNode,
tag: "h1" | "h2" = 'h1'
): JSX.Element => {
const Tag = tag;
const id = typeof children === "string" ?
children.toLowerCase().replaceAll(' ', '-') : undefined;
return id ?
<Tag id={id} ref={(el) => anchorsRef.current[id] = el}>{children}</Tag>:
<Tag>{children}</Tag>;
}; };
const options: Options = { className: markdownClasses }; React.useEffect(() => { if(scrollTo) scroll(scrollTo); }, [scrollTo]);
if(patterns && patterns.length > 0) options.components = {
const options: Options = {
className: markdownClasses,
remarkPlugins: [remarkCustomHeaderId],
};
options.components = {
p: ({ children }) => <div>{replaceTags(children, patterns)}</div>, p: ({ children }) => <div>{replaceTags(children, patterns)}</div>,
li: ({ children }) => <li>{replaceTags(children, patterns)}</li>, li: ({ children }) => <li>{replaceTags(children, patterns)}</li>,
h1: ({ children }) => getHtmlTitle(children), /** Uses codeBlock if ``` is used in markdown with a language,
h2: ({ children }) => getHtmlTitle(children, 'h2'),
/** Uses codeBlock if ```` is used in markdown with a language,
* otherwise the code-inline class is added */ * otherwise the code-inline class is added */
code: ({ className, children }) => { code: ({ className, children }) => {
if (className && className.includes("language-") if (className && className.includes("language-")
...@@ -160,6 +151,19 @@ export function Markdown( ...@@ -160,6 +151,19 @@ export function Markdown(
} }
return <code className='code-inline'>{children}</code>; return <code className='code-inline'>{children}</code>;
}, },
/** Change the behavior of links on anchors */
a: ({ href, children }) => {
if (href && href.startsWith("#")) {
const id = href.slice(1);
return ( <a href={href}
onClick={(e) => {
e.preventDefault();
scroll(id);
}}>{children}</a>
);
}
return <a href={href}>{children}</a>;
},
}; };
return <ReactMarkdown {...options}>{ children }</ReactMarkdown>; return <ReactMarkdown {...options}>{ children }</ReactMarkdown>;
......
...@@ -232,6 +232,10 @@ ...@@ -232,6 +232,10 @@
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
.dome-xMarkdown { .dome-xMarkdown {
max-height: 100%;
overflow-y: auto;
padding: 10px;
&>* { padding: 1px; } &>* { padding: 1px; }
} }
......
...@@ -26,23 +26,42 @@ ...@@ -26,23 +26,42 @@
import React from 'react'; import React from 'react';
import { registerSandbox, TitleBar } from 'ivette'; import { registerSandbox, TitleBar } from 'ivette';
import { HelpMarkdown, IconHelpModalMd } from 'dome/help'; import { HelpIcon } from 'dome/help';
import docSandbox from './sandbox.md?raw'; import helpSandbox from './sandbox.md?raw';
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// --- Main force graph component // --- Main force graph component
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
function SandboxHelp(): JSX.Element { function SandboxHelp(): JSX.Element {
const style = {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
width: '100%',
height: '100%',
fontSize: '1.5em'
};
return ( return (
<> <>
<TitleBar> <TitleBar>
<IconHelpModalMd <HelpIcon
modal={{ label: 'docsandbox - Help' }} label='Sandbox - Help'
initialScrollTo={'help'} scrollTo={'sandbox-help'}
>{ docSandbox }</IconHelpModalMd> >{ helpSandbox }</HelpIcon>
</TitleBar> </TitleBar>
<HelpMarkdown initialScrollTo={'help'}>{ docSandbox }</HelpMarkdown> <div style={style}>
<>
Click the help button to display help : here
<HelpIcon
label='Sandbox - Help'
size={18}
scrollTo={'sandbox-help'}
>{ helpSandbox }</HelpIcon>
or on the toolbar
</>
</div>
</> </>
); );
} }
......
...@@ -37,7 +37,7 @@ import { Icon } from 'dome/controls/icons'; ...@@ -37,7 +37,7 @@ import { Icon } from 'dome/controls/icons';
import './style.css'; import './style.css';
import { Label } from 'dome/controls/labels'; import { Label } from 'dome/controls/labels';
import { Modal, showModal } from 'dome/dialogs'; import { Modal, showModal } from 'dome/dialogs';
import { IconHelpModalMd } from 'dome/help'; import { HelpIcon } from 'dome/help';
import docSandbox from './sandbox.md?raw'; import docSandbox from './sandbox.md?raw';
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
...@@ -82,14 +82,12 @@ function UsePanel(): JSX.Element { ...@@ -82,14 +82,12 @@ function UsePanel(): JSX.Element {
title={"show or hide the panel"} title={"show or hide the panel"}
onClick={flipVisible} onClick={flipVisible}
/> />
<IconHelpModalMd <HelpIcon
modal={{ label='Sandbox - Panel'
label: 'docsandbox - Panel' scrollTo={'sandbox-panel'}
}}
initialScrollTo={'panel'}
> >
{ docSandbox } { docSandbox }
</IconHelpModalMd> </HelpIcon>
</TitleBar> </TitleBar>
<div style={{ position: 'relative', height: '100%' }}> <div style={{ position: 'relative', height: '100%' }}>
<Panel visible={visible} position={position}> <Panel visible={visible} position={position}>
......
# Sandbox # Sandbox {#help-sandbox}
The sandbox part of Ivette is only available in development mode. The sandbox part of Ivette is only available in development mode.
It allows you to test new modules and discover a simplified form of the basic modules before using them. It allows you to test new modules and discover a simplified form of the basic modules before using them.
## Dot Diagram ## Dot Diagram {#sandbox-dot-diagram}
Documentation is not yet available for this module. Documentation is not yet available for this module.
## ForceGraph ## ForceGraph {#sandbox-forcegraph}
Documentation is not yet available for this module. Documentation is not yet available for this module.
## Icons ## Icons {#sandbox-icons}
Documentation is not yet available for this module. Documentation is not yet available for this module.
## Panel ## Panel {#sandbox-panel}
The Panel component allows the addition of a retractable panel to a positioned block. The Panel component allows the addition of a retractable panel to a positioned block.
...@@ -40,21 +40,20 @@ The panel can be displayed on any side of the block using the position prop, whi ...@@ -40,21 +40,20 @@ The panel can be displayed on any side of the block using the position prop, whi
``` ```
## Qsplit ## Qsplit {#sandbox-qsplit}
Documentation is not yet available for this module. Documentation is not yet available for this module.
## Text ## Text {#sandbox-text}
Documentation is not yet available for this module. Documentation is not yet available for this module.
## UseDnd ## UseDnd {#sandbox-usednd}
Documentation is not yet available for this module. Documentation is not yet available for this module.
## Help ## Help {#sandbox-help}
the documentation is written in [Markdown](#sandbox-markdown). It must be in a `*.md` file, the raw content of which will be retrieved via an import.
the documentation is written in [Markdown](#markdown). It must be in a `*.md` file, the raw content of which will be retrieved via an import.
For example, for the documentation of a sandbox module For example, for the documentation of a sandbox module
``` javascript ``` javascript
...@@ -68,45 +67,29 @@ Typically, the documentation will be displayed in the application's modal. ...@@ -68,45 +67,29 @@ Typically, the documentation will be displayed in the application's modal.
This file contains components that make it easier to display documentation in your components. This file contains components that make it easier to display documentation in your components.
#### HelpMarkdown #### HelpIcon
This component is used to display the markdown help, it is used by `IconodalMd` and you can see an example of it out of modal in the `help` sandbox.
It takes the following props:
``` javascript
interface DocMarkdownProps {
/** classes for Doc component */
className?: string;
/** Tab of patterns */
patterns?: Pattern[];
/**
* scroll to title h1 or h2 when component is render.
* The value must be the id of the balise html.
* Id is calculate by title.toLowerCase().replaceAll(' ','-')
* where title is the content of h1 or h2 if it is a string
*/
initialScrollTo?: string;
/** Markdown content. */
children?: string;
}
```
#### IconModalMd
Allows you to add a `HELP` icon ([icon-HELP]) which will open a modal window with the chosen document when clicked. Allows you to add a `HELP` icon ([icon-HELP]) which will open a modal window with the chosen document when clicked.
``` javascript ``` javascript
interface IconModalMdProps extends DocMarkdownProps { interface HelpIconProps {
/** Icon props */ /** icon size */
kind?: IconButtonKind;
title?: string;
size?: number; size?: number;
/** Properties of Modal component */ /** Tab of patterns */
modal: Omit<ModalProps, 'children'>; patterns?: Pattern[];
/** Initial scroll to the chosen id */
scrollTo?: string;
/** Text of the label. Prepend to other children elements. */
label: string;
/** Function onClose */
onClose?: () => void
/** children */
children: string;
} }
``` ```
## Markdown ## Markdown {#sandbox-markdown}
TO BE COMPLETED TO BE COMPLETED
......
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment