-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* MentionTextArea Tiptap lib * DiscussionBoard folder DiscussionModalWrapper Sidepanel
- Loading branch information
Showing
17 changed files
with
1,321 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
/* MentionList renders the TipTap suggestion dropdown in addition to defining | ||
defining keyboard events */ | ||
|
||
import React, { | ||
forwardRef, | ||
useEffect, | ||
useImperativeHandle, | ||
useState | ||
} from 'react'; | ||
import { useTranslation } from 'react-i18next'; | ||
|
||
import Spinner from 'components/Spinner'; | ||
|
||
import './index.scss'; | ||
|
||
export const SuggestionLoading = () => { | ||
return ( | ||
<div className="items width-full padding-1"> | ||
<Spinner size="small" /> | ||
</div> | ||
); | ||
}; | ||
|
||
// Handler dropdown scroll event on keypress | ||
const scrollIntoView = () => { | ||
const selectedElm = document.querySelector('.is-selected'); | ||
selectedElm?.scrollIntoView({ block: 'nearest' }); | ||
}; | ||
|
||
const MentionList = forwardRef((props: any, ref) => { | ||
const { t } = useTranslation('discussionsMisc'); | ||
|
||
const [selectedIndex, setSelectedIndex] = useState(0); | ||
|
||
// Sets the selected mention within the editor props | ||
const selectItem = (index: any) => { | ||
const item = props.items[index]; | ||
|
||
if (item) { | ||
props.command({ | ||
id: item.username, | ||
label: item.displayName, | ||
'tag-type': item.tagType | ||
}); | ||
} | ||
}; | ||
|
||
const upHandler = () => { | ||
setSelectedIndex( | ||
(selectedIndex + props.items?.length - 1) % props.items?.length | ||
); | ||
scrollIntoView(); | ||
}; | ||
|
||
const downHandler = () => { | ||
setSelectedIndex((selectedIndex + 1) % props.items?.length); | ||
scrollIntoView(); | ||
}; | ||
|
||
const enterHandler = () => { | ||
selectItem(selectedIndex); | ||
}; | ||
|
||
useEffect(() => setSelectedIndex(0), [props.items]); | ||
|
||
useImperativeHandle(ref, () => ({ | ||
onKeyDown: ({ event }: { event: any }) => { | ||
if (event.key === 'ArrowUp' || (event.shiftKey && event.key === 'Tab')) { | ||
upHandler(); | ||
return true; | ||
} | ||
|
||
if ( | ||
event.key === 'ArrowDown' || | ||
(!event.shiftKey && event.key === 'Tab') | ||
) { | ||
downHandler(); | ||
return true; | ||
} | ||
|
||
if (event.key === 'Enter') { | ||
enterHandler(); | ||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
})); | ||
|
||
return ( | ||
<div className="items"> | ||
{props.items?.length ? ( | ||
props.items?.map((item: any, index: any) => ( | ||
<button | ||
className={`item ${index === selectedIndex ? 'is-selected' : ''}`} | ||
key={item.username} | ||
id={item.username} | ||
type="button" | ||
onClick={() => selectItem(index)} | ||
> | ||
{item.displayName} | ||
</button> | ||
)) | ||
) : ( | ||
<div className="item">{t('noResults')}</div> | ||
)} | ||
</div> | ||
); | ||
}); | ||
|
||
export default MentionList; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
@use 'uswds-core' as *; | ||
|
||
/* Basic editor styles */ | ||
.tiptap { | ||
border: 1px solid black; | ||
padding: .5rem; | ||
|
||
p { | ||
margin: 0px; | ||
} | ||
|
||
&__readonly { | ||
margin-bottom: 1rem; | ||
|
||
.ProseMirror { | ||
outline: none; | ||
border: none; | ||
padding: 0; | ||
} | ||
|
||
&.notification__content { | ||
p { | ||
quotes: "“" "”"; | ||
|
||
&:first-child::before { | ||
content: open-quote; | ||
} | ||
|
||
&:last-child::after { | ||
content: close-quote; | ||
} | ||
|
||
span.react-renderer.node-mention { | ||
& ~ .ProseMirror-trailingBreak { | ||
display: none; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
&__editable { | ||
.ProseMirror { | ||
min-height: 155px; | ||
font-size: 16px; | ||
line-height: 22px; | ||
} | ||
} | ||
} | ||
|
||
[data-tippy-root] { | ||
width: 99.7%; | ||
margin-left: .1rem !important; | ||
} | ||
|
||
.tippy-box { | ||
max-width: none !important; | ||
} | ||
|
||
.mention { | ||
color: #005EA2; | ||
border: none; | ||
background-color: transparent; | ||
padding: 0; | ||
} | ||
|
||
.text-base-darker { | ||
.mention { | ||
color: color($theme-color-base-darker); | ||
} | ||
} | ||
|
||
.text-base-darkest { | ||
.mention { | ||
color: color($theme-color-base-darkest); | ||
} | ||
} | ||
|
||
.items { | ||
position: relative; | ||
background: #FFF; | ||
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05), 0px 10px 20px rgba(0, 0, 0, 0.1); | ||
border: 1px solid color($theme-color-base-lighter); | ||
padding: 0; | ||
max-height: 300px; | ||
overflow: auto; | ||
} | ||
|
||
.item { | ||
display: block; | ||
border: none; | ||
margin: 0; | ||
width: 100%; | ||
text-align: left; | ||
background: transparent; | ||
padding-top: 0.65rem; | ||
padding-bottom: 0.65rem; | ||
border-bottom: 1px solid color($theme-color-base-lighter); | ||
min-width: 475px; | ||
|
||
&.is-selected { | ||
background-color: #d9e8f6; | ||
} | ||
} |
Oops, something went wrong.