Skip to content

Commit

Permalink
wip: sidebar
Browse files Browse the repository at this point in the history
  • Loading branch information
ggrossetie committed Feb 4, 2025
1 parent 6a34125 commit e32fc09
Show file tree
Hide file tree
Showing 9 changed files with 229 additions and 72 deletions.
10 changes: 10 additions & 0 deletions front/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion front/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"js-yaml": "^4.1.0",
"lodash.debounce": "^4.0.8",
"lodash.throttle": "^4.1.1",
"lucide-react": "^0.474.0",
"monaco-editor": "^0.52.0",
"object-path-immutable": "^4.1.0",
"pagedjs": "^0.4.0",
Expand Down Expand Up @@ -113,4 +114,4 @@
"node": "18.20.4",
"npm": "10.9.0"
}
}
}
32 changes: 32 additions & 0 deletions front/src/components/Sidebar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import clsx from 'clsx'
import { PanelRightClose, PanelRightOpen } from 'lucide-react'

import styles from './Sidebar.module.scss'

export default function Sidebar({
opened,
setOpened,
labelOpened,
labelClosed,
children,
}) {
const button = opened ? (
<PanelRightClose size={36} />
) : (
<PanelRightOpen size={36} />
)

const label = opened ? labelOpened ?? 'Close' : labelClosed ?? 'Open'

return (
<div
className={clsx(styles.sidebar, opened ? styles.opened : styles.closed)}
>
<div className={styles.action} onClick={() => setOpened(!opened)}>
<div className={styles.icon}>{button}</div>
<div className={styles.label}>{label}</div>
</div>
{opened && <div className={styles.content}>{children}</div>}
</div>
)
}
51 changes: 51 additions & 0 deletions front/src/components/Sidebar.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
.sidebar {
border-left: 1px solid #DCDCDC;
margin-left: 2rem;
max-width: 33vw;
position: relative;
}

.opened {
margin-left: 6rem;
.action {
left: -4.5rem;
}
}

.closed {
margin-left: 6rem;
padding-left: 3rem;

.action {
right: 0.5rem;
}
}

.action {
display: flex;
background-color: #F9F9F9;
border: 1px solid #DCDCDC;
padding: 0.5rem 1rem;
align-items: center;
gap: 0.25rem;
position: absolute;
top: 1rem;
max-width: fit-content;
cursor: pointer;
}

.icon {
display: flex;
align-items: center;
}

.label {
font-weight: 500;
}

.content {
margin-top: 4rem;
padding-top: 1rem;
padding-left: 1rem;
}

118 changes: 48 additions & 70 deletions front/src/components/Write/ArticleEditorMetadata.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useDispatch, useSelector } from 'react-redux'
import PropTypes from 'prop-types'
import { useTranslation } from 'react-i18next'
import YAML from 'js-yaml'
import { Sidebar } from 'react-feather'
import Sidebar from '../Sidebar.jsx'

import { toYaml } from './metadata/yaml.js'
import ArticleEditorMetadataForm from './yamleditor/ArticleEditorMetadataForm.jsx'
Expand Down Expand Up @@ -74,77 +74,55 @@ export default function ArticleEditorMetadata({
)

return (
<nav className={`${expanded ? styles.expandRight : styles.retractRight}`}>
<button
onClick={toggleExpand}
className={expanded ? styles.close : styles.open}
>
<Sidebar />{' '}
{expanded
? t('write.sidebar.closeButton')
: t('write.sidebar.metadataButton')}
</button>
{expanded && (
<div className={styles.yamlEditor}>
<header className={styles.header}>
<h2>Metadonnées</h2>
<div
className={styles.toggle}
onClick={() => setSelector(selector === 'raw' ? 'basic' : 'raw')}
>
<Toggle
id="raw-mode"
checked={selector === 'raw'}
title={'Activer le mode YAML'}
onChange={(e) => {
console.log(e)
setSelector(e.target.checked ? 'raw' : 'basic')
}}
/>
<label htmlFor="raw-mode">YAML</label>
</div>
</header>

{/*<NavTag*/}
{/* defaultValue={selector}*/}
{/* onChange={setSelector}*/}
{/* items={[*/}
{/* {*/}
{/* value: 'basic',*/}
{/* name: t('write.basicMode.metadataButton'),*/}
{/* },*/}
{/* {*/}
{/* value: 'raw',*/}
{/* name: t('write.rawMode.metadataButton'),*/}
{/* },*/}
{/* ]}*/}
{/*/>*/}
{selector === 'raw' && (
<>
{error !== '' && <p className={styles.error}>{error}</p>}
<MonacoYamlEditor
height="calc(100vh - 280px)"
fontSize="14"
text={rawYaml}
onTextUpdate={handleRawYamlChange}
/>
</>
)}
{selector !== 'raw' && (
<ArticleEditorMetadataForm
metadata={metadata}
error={(reason) => {
setError(reason)
if (reason !== '') {
setSelector('raw')
}
<Sidebar
labelClosed={'Métadonnées'}
opened={expanded}
setOpened={toggleExpand}
>
<div className={styles.metadata}>
<header className={styles.header}>
<h2>Metadonnées</h2>
<div
className={styles.toggle}
onClick={() => setSelector(selector === 'raw' ? 'basic' : 'raw')}
>
<Toggle
id="raw-mode"
checked={selector === 'raw'}
title={'Activer le mode YAML'}
onChange={(e) => {
console.log(e)
setSelector(e.target.checked ? 'raw' : 'basic')
}}
onChange={handleFormUpdate}
/>
)}
</div>
)}
</nav>
<label htmlFor="raw-mode">YAML</label>
</div>
</header>
{selector === 'raw' && (
<>
{error !== '' && <p className={styles.error}>{error}</p>}
<MonacoYamlEditor
height="calc(100vh - 280px)"
fontSize="14"
text={rawYaml}
onTextUpdate={handleRawYamlChange}
/>
</>
)}
{selector !== 'raw' && (
<ArticleEditorMetadataForm
metadata={metadata}
error={(reason) => {
setError(reason)
if (reason !== '') {
setSelector('raw')
}
}}
onChange={handleFormUpdate}
/>
)}
</div>
</Sidebar>
)
}

Expand Down
7 changes: 6 additions & 1 deletion front/src/components/Write/articleEditorMetadata.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,14 @@
margin-bottom: 1.25rem;
}

.yamlEditor {
.metadata {
display: flex;
flex-direction: column;
min-width: 375px;
max-width: 375px;
max-height: calc(100vh - 180px);
overflow-y: scroll;
padding-right: 0.5rem;

> section {
:global {
Expand Down
71 changes: 71 additions & 0 deletions front/src/stories/Sidebar.story.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import React, { useState } from 'react'
import Sidebar from '../components/Sidebar.jsx'

import styles from './Sidebar.story.module.scss'

export default function SidebarStory() {
const [opened, setOpened] = useState(false)
return (
<div className={styles.container}>
<section>
<p>
Proin pulvinar felis vitae commodo volutpat. Ut ut purus felis. Donec
blandit faucibus odio, a pulvinar turpis pharetra quis. Aenean
ultricies venenatis arcu, nec malesuada libero ornare nec. Sed
faucibus quam eget placerat accumsan. Aenean ut elementum arcu. Nulla
tortor dolor, scelerisque at porta placerat, tincidunt nec enim.
Phasellus dictum lacinia vestibulum. Aenean vestibulum arcu a ex
molestie, sit amet mattis magna ultrices. Nulla quam nibh, cursus ut
neque eget, imperdiet mattis ipsum.
</p>

<p>
Curabitur viverra, lorem hendrerit fringilla ornare, ex libero
tincidunt sapien, in malesuada eros eros sit amet urna. Sed porta eu
quam sit amet rhoncus. Sed imperdiet, nulla eu venenatis congue, orci
mi fermentum magna, in cursus eros lectus quis ex. Nullam interdum
bibendum congue. Donec sit amet mattis libero. Vivamus suscipit risus
at diam hendrerit pulvinar. Curabitur tristique arcu vel tincidunt
rutrum. Integer placerat, metus vitae vestibulum eleifend, felis mi
fringilla tellus, a efficitur erat risus vitae augue. Nunc tincidunt,
lectus eu volutpat suscipit, augue est vestibulum tortor, sed sodales
quam elit at enim. Integer ut felis id justo pretium condimentum.
Phasellus lobortis vel ipsum sit amet pulvinar. Donec vehicula
molestie lorem sed lobortis. Proin suscipit pharetra arcu, varius
scelerisque enim porta pellentesque.
</p>
</section>
<Sidebar opened={opened} setOpened={setOpened}>
<div>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce
rutrum velit nisl, sit amet iaculis tortor scelerisque in. Nam sed
tellus tincidunt, efficitur nunc quis, consequat metus. Maecenas
vestibulum mauris ut tristique aliquam. Quisque at sodales nisi, eu
molestie arcu. Vivamus lobortis, risus eu ultrices viverra, libero
ligula fringilla elit, ac pellentesque augue neque in nibh. Sed
lacinia pharetra ipsum eget iaculis. Aenean a pulvinar tortor. Sed
ut porttitor libero. Sed vitae dui non libero venenatis vulputate id
eget erat. Vivamus lorem ex, fringilla quis efficitur et, venenatis
tristique nunc. Ut blandit tempor turpis, nec dignissim sem
pellentesque vitae. Aliquam malesuada, orci ac semper cursus, turpis
dolor imperdiet tortor, id interdum velit nibh sit amet diam.
Interdum et malesuada fames ac ante ipsum primis in faucibus.
</p>

<p>
Duis sodales massa a iaculis vehicula. Aenean porttitor, eros vel
auctor semper, nunc augue feugiat lectus, sit amet sagittis orci
turpis sed leo. Duis vestibulum pulvinar quam, nec fermentum nisi
interdum eget. Nam nec augue nec odio tempor rhoncus sit amet ut
magna. Suspendisse potenti. Sed ut urna ac nulla commodo volutpat.
Nulla efficitur mollis venenatis. Vestibulum vehicula nulla sed
vulputate sagittis. Suspendisse potenti. Pellentesque arcu massa,
cursus et maximus nec, auctor vel sapien. Nulla facilisi. Ut ac
laoreet ex.
</p>
</div>
</Sidebar>
</div>
)
}
4 changes: 4 additions & 0 deletions front/src/stories/Sidebar.story.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.container {
display: flex;
gap: 1rem;
}
5 changes: 5 additions & 0 deletions front/src/stories/Story.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import { Search } from 'react-feather'
import buttonStyles from '../components/button.module.scss'
import Field from '../components/Field.jsx'
import Select from '../components/Select.jsx'
import Sidebar from '../components/Sidebar.jsx'
import ButtonStory from './Button.story.jsx'
import FormStory from './Form.story.jsx'
import SidebarStory from './Sidebar.story.jsx'

import styles from './story.module.scss'

Expand Down Expand Up @@ -36,6 +38,9 @@ export default function Story() {
<option>St Marcellin</option>
</Select>
</Tabs.Item>
<Tabs.Item label="sidebar" value="4">
<SidebarStory />
</Tabs.Item>
</Tabs>
</div>
)
Expand Down

0 comments on commit e32fc09

Please sign in to comment.