Skip to content
Open
95 changes: 95 additions & 0 deletions src/widgets/modals.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import {
ModalWidgetStyleOptions,
modalStyles,
getModalStyle,
getModalContentStyle,
getModalCloseStyle
} from './modalsStyle'
import { getClasses } from '../jss'

Comment thread
SharonStrats marked this conversation as resolved.
export type ListItem = {
label: string,
link: string
}

// Two functions that need to be implemented to use the modal
// When the user clicks the button, open the modal
Comment thread
SharonStrats marked this conversation as resolved.
Outdated
/* Click handler on the button to display it.
btn.onclick = function() {
modal.style.display = "block";
}

// When the user clicks anywhere outside of the modal, close it
Comment thread
SharonStrats marked this conversation as resolved.
Outdated
Window click handler so that the modal will close
even if the user doesn't click close
Comment thread
SharonStrats marked this conversation as resolved.
Outdated
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
} */
const closeClickHandler = () => {
const modal: HTMLDivElement | null = document.querySelector('.modal')
if (modal) {
modal.style.display = 'none'
}
}
Comment thread
SharonStrats marked this conversation as resolved.
Outdated

const createModal = (dom: HTMLDocument, options: ModalWidgetStyleOptions) => {
const modal = dom.createElement('div')
const style = getModalStyle(options)
const { classes } = getClasses(dom.head, {
modal: style
})
modal.classList.add(classes.modal)
return modal
}

const createModalContent = (dom: HTMLDocument) => {
const modalContent: HTMLDivElement = dom.createElement('div')
const style = getModalContentStyle()
const { classes } = getClasses(dom.head, {
modalContent: style
})
modalContent.classList.add(classes.modalContent)
return modalContent
}

const createCloseButton = (dom: HTMLDocument) => {
const closeButton: HTMLSpanElement = dom.createElement('span')
closeButton.addEventListener('click', closeClickHandler)
const style = getModalCloseStyle()
const { classes } = getClasses(dom.head, {
close: style
})
closeButton.classList.add(classes.close)
return closeButton
Comment thread
SharonStrats marked this conversation as resolved.
Outdated
Comment thread
SharonStrats marked this conversation as resolved.
Outdated
}

const createListItems = (dom: HTMLDocument, list: ListItem) => {
const li:HTMLLIElement = dom.createElement('li')
li.setAttribute('style', modalStyles.listItemStyle)
const link: HTMLAnchorElement = dom.createElement('a')
link.setAttribute('style', modalStyles.anchorStyle)
link.href = list.link
link.innerHTML = list.label
Comment thread
SharonStrats marked this conversation as resolved.
Outdated
li.appendChild(link)
return li
}

const createUnOrderedList = (dom: HTMLDocument, listOfLinks: ListItem[]) => {
const ul: HTMLUListElement = dom.createElement('ul')
ul.setAttribute('style', modalStyles.unorderedListStyle)
listOfLinks.forEach(list => {
const li = createListItems(dom, list)
ul.appendChild(li)
})
return ul
Comment thread
SharonStrats marked this conversation as resolved.
Outdated
}
export const createWindow = (dom: HTMLDocument, listOfLinks: ListItem[], options: ModalWidgetStyleOptions) => {
const modal = createModal(dom, options)
Comment thread
SharonStrats marked this conversation as resolved.
Outdated
const modalContent = createModalContent(dom)
const closeButton = createCloseButton(dom)
const ul = createUnOrderedList(dom, listOfLinks)
modalContent.appendChild(closeButton)
modalContent.appendChild(ul)
modal.appendChild(modalContent)
}
Comment thread
SharonStrats marked this conversation as resolved.
Outdated
72 changes: 72 additions & 0 deletions src/widgets/modalsStyle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
* Get the button style, based on options.
* See https://design.inrupt.com/atomic-core/?cat=Atoms#Buttons
Comment thread
SharonStrats marked this conversation as resolved.
Outdated
*/
export type ModalWidgetStyleOptions = {
topPosition?: string,
leftPosition?: string,
withGreyedBackground?: boolean
}

export const modalStyles = {
unorderedListStyle: 'padding: 0 .2em;',
listItemStyle: 'list-style: none; box-shadow: 1px 1px 1px 1px #888888; padding: .5em',
anchorStyle: 'text-decoration: none'
}

export const getModalStyle = (options: ModalWidgetStyleOptions = {}) => {
const topPosition = (options.topPosition) ? options.topPosition : '50px'
const leftPosition = (options.leftPosition) ? options.leftPosition : '50px'

if (options.withGreyedBackground) {
return {
display: 'none',
position: 'fixed',
'z-index': '1',
overflow: 'auto', /* Enable scroll if needed */
'background-color': 'rgba(0,0,0,0.4)', /* Black w/ opacity */
'padding-top': '100px',
left: '0',
top: '0',
width: '100%',
height: '100%'
}
}

return {
display: 'none',
position: 'fixed',
'z-index': '1',
top: `${topPosition}`,
left: `${leftPosition}`,
overflow: 'auto', /* Enable scroll if needed */
'background-color': 'rgba(0,0,0,0.4)' /* Black w/ opacity */
}
}

export const getModalContentStyle = () => {
return {
display: 'flex',
'flex-direction': 'column',
'background-color': '#fefefe'
}
}

export const getModalCloseStyle = () => {
return {
color: '#aaaaaa',
'align-self': 'flex-end',
'font-size': '20px',
'font-weight': 'bold',
'margin-right': '.2em',
'margin-top': '.2em',
'&:hover': {
'text-decoration': 'none',
cursor: 'pointer'
},
'&:focus': {
'text-decoration': 'none',
cursor: 'pointer'
}
}
}