Skip to content

Commit

Permalink
Merge pull request #43 from david-abell/package-types
Browse files Browse the repository at this point in the history
Feat: Add typescript declarations and Prettier, resolves #40
  • Loading branch information
markteekman committed Apr 23, 2023
2 parents af7e8d7 + 42fa924 commit 2470f0e
Show file tree
Hide file tree
Showing 16 changed files with 952 additions and 94 deletions.
8 changes: 8 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"tabWidth": 2,
"semi": false,
"singleQuote": true,
"printWidth": 120,
"plugins": ["prettier-plugin-astro"],
"pluginSearchDirs": false
}
34 changes: 20 additions & 14 deletions Accordion.astro
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
---
import type { AccordionItem } from '.'
interface Props {
children: AccordionItem | AccordionItem[]
}
---

<div class="accordion">
<ul class="accordion__wrapper">
<slot />
Expand All @@ -9,12 +17,12 @@
const accordionItems = [...document.querySelectorAll('.accordion__item')]

// functions
const getPanelHeight = accordionItem => {
const getPanelHeight = (accordionItem) => {
const accordionInner = accordionItem.querySelector('.panel__inner')
return accordionInner.getBoundingClientRect().height
}

const openAccordionItem = accordionItem => {
const openAccordionItem = (accordionItem) => {
const accordionItemHeader = accordionItem.querySelector('.accordion__header')
const accordionToggleIndicator = accordionItem.querySelector('.header__toggle-indicator')
const accordionPanel = accordionItem.querySelector('.accordion__panel')
Expand All @@ -25,7 +33,7 @@
accordionToggleIndicator.innerHTML = `<svg class="header__toggle-indicator" aria-hidden="true" data-prefix="fas" data-icon="minus" class="svg-inline--fa fa-minus fa-w-14" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M416 208H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h384c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z"/></svg>`
}

const closeAccordionItem = accordionItem => {
const closeAccordionItem = (accordionItem) => {
const accordionItemHeader = accordionItem.querySelector('.accordion__header')
const accordionToggleIndicator = accordionItem.querySelector('.header__toggle-indicator')
const accordionPanel = accordionItem.querySelector('.accordion__panel')
Expand All @@ -37,23 +45,21 @@
accordionToggleIndicator.innerHTML = `<svg class="header__toggle-indicator" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z"/></svg>`
}

const isAccordionOpen = accordionItem => {
const isAccordionOpen = (accordionItem) => {
return accordionItem.classList.contains('is-active')
}

function toggleAccordionItem () {
function toggleAccordionItem() {
const accordionItem = event.target.closest('.accordion__item')
if (!accordionItem || event.target.closest('.accordion__panel')) return

isAccordionOpen(accordionItem)
? closeAccordionItem(accordionItem)
: openAccordionItem(accordionItem)
isAccordionOpen(accordionItem) ? closeAccordionItem(accordionItem) : openAccordionItem(accordionItem)
}

function recalculateHeight () {
const toggledAccordionItems = accordionItems.filter(element => element.classList.contains('is-active'))
function recalculateHeight() {
const toggledAccordionItems = accordionItems.filter((element) => element.classList.contains('is-active'))

toggledAccordionItems.forEach(toggledAccordionItem => {
toggledAccordionItems.forEach((toggledAccordionItem) => {
const accordionPanel = toggledAccordionItem.querySelector('.accordion__panel')
accordionPanel.style.height = `${getPanelHeight(toggledAccordionItem)}px`
})
Expand All @@ -71,7 +77,7 @@
accordionItemPanel.setAttribute('aria-labelledby', `accordion-item${index + 1}`)
})

document.addEventListener('keydown', event => {
document.addEventListener('keydown', (event) => {
const accordionItem = event.target.closest('.accordion__item')

if (event.key !== 'Escape') return
Expand All @@ -82,13 +88,13 @@
}
})

document.addEventListener('keydown', event => {
document.addEventListener('keydown', (event) => {
if (!event.target.closest('.accordion__header')) return

const accordionWrapper = event.target.closest('.accordion__wrapper')
const accordionItem = event.target.closest('.accordion__item')
const accordionItems = [...accordionWrapper.querySelectorAll('.accordion__item')]
const index = accordionItems.findIndex(element => element === accordionItem)
const index = accordionItems.findIndex((element) => element === accordionItem)

const { key } = event

Expand Down
21 changes: 12 additions & 9 deletions AccordionItem.astro
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
---
const {header} = Astro.props
interface Props {
header: string
children: any
}
const { header } = Astro.props
---

<li class="accordion__item">
Expand All @@ -13,16 +18,14 @@ const {header} = Astro.props
>
{header}
<svg class="header__toggle-indicator" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
<path fill="currentColor" d="M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z"/>
<path
fill="currentColor"
d="M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z"
></path>
</svg>
</button>
</h3>
<div
id="accordion-panel-1"
role="region"
class="accordion__panel"
aria-labelledby="accordion-header-1"
>
<div id="accordion-panel-1" role="region" class="accordion__panel" aria-labelledby="accordion-header-1">
<div class="panel__inner">
<slot />
</div>
Expand Down Expand Up @@ -50,7 +53,7 @@ const {header} = Astro.props
outline-offset: -6px;
box-shadow: inset 0 0 0 2px white;
}

.accordion__item:only-of-type .accordion__header,
.accordion__item:last-of-type .accordion__header {
border: 2px solid #202020;
Expand Down
8 changes: 8 additions & 0 deletions Breadcrumbs.astro
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
---
import type { BreadcrumbsItem } from '.'
interface Props {
children: BreadcrumbsItem | BreadcrumbsItem[]
}
---

<nav class="breadcrumbs" aria-label="Breadcrumbs">
<ol>
<slot />
Expand Down
18 changes: 8 additions & 10 deletions BreadcrumbsItem.astro
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
---
const {
href = '#',
label = 'Breadcrumb',
currentPage = false,
} = Astro.props
interface Props {
href?: string
label: string
currentPage?: boolean
}
const { href = '#', label = 'Breadcrumb', currentPage = false } = Astro.props
---

<li class="breadcrumbs__item">
{
currentPage
? <span>{label}</span>
: <a href={href}>{label}</a>
}
{currentPage ? <span>{label}</span> : <a href={href}>{label}</a>}
</li>

<style is:global>
Expand Down
17 changes: 10 additions & 7 deletions Card.astro
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
---
const {
url = '#',
img = 'https://fakeimg.pl/640x360',
title = 'Default title',
footer = 'Your name'
} = Astro.props
interface Props {
url?: string
img?: string
title?: string
footer: string
children?: HTMLElement | HTMLElement[]
}
const { url = '#', img = 'https://fakeimg.pl/640x360', title = 'Default title', footer = 'Your name' } = Astro.props
---

<div class="card">
<div class="card__image">
<img src={img} alt="">
<img src={img} alt="" />
</div>
<div class="card__content">
<h3>
Expand Down
15 changes: 11 additions & 4 deletions DarkMode.astro
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
---
type Props = Record<string, never>
---
<button class="darkmode-toggle" aria-pressed="false" aria-label="Enable dark mode">
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="M9.353 3C5.849 4.408 3 7.463 3 11.47A9.53 9.53 0 0 0 12.53 21c4.007 0 7.062-2.849 8.47-6.353C8.17 17.065 8.14 8.14 9.353 3z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" width="32" height="32" viewBox="0 0 24 24"
><path
fill="currentColor"
d="M9.353 3C5.849 4.408 3 7.463 3 11.47A9.53 9.53 0 0 0 12.53 21c4.007 0 7.062-2.849 8.47-6.353C8.17 17.065 8.14 8.14 9.353 3z"
></path></svg
>
</button>
<script is:inline>
Expand Down Expand Up @@ -30,8 +39,6 @@
darkModeToggle.addEventListener('click', () => {
darkMode = localStorage.getItem('darkMode')
darkMode !== 'enabled'
? enableDarkMode()
: disableDarkMode()
darkMode !== 'enabled' ? enableDarkMode() : disableDarkMode()
})
</script>
20 changes: 8 additions & 12 deletions Media.astro
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
---
const {
class: classNames,
src = 'https://shorturl.at/tCPS2',
alt = ''
} = Astro.props
interface Props {
class: string
src?: string
alt?: string
}
const { class: classNames, src = 'https://shorturl.at/tCPS2', alt = '' } = Astro.props
---

<img
class={classNames}
src={src}
alt={alt}
loading="lazy"
decoding="async"
>
<img class={classNames} src={src} alt={alt} loading="lazy" decoding="async" />
36 changes: 19 additions & 17 deletions Modal.astro
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
---
const {
triggerId,
title,
closeText = 'Close'
} = Astro.props
interface Props {
triggerId: string
title: string
closeText?: string
children?: HTMLElement | HTMLElement[]
}
const { triggerId, title, closeText = 'Close' } = Astro.props
---

<div class="modal" role="dialog" aria-labelledby={triggerId}>
Expand All @@ -27,21 +30,20 @@ const {
const modalId = modal.getAttribute('aria-labelledby')
const modalCloseButton = modal.querySelector('.modal__close button')
const modalTrigger = document.querySelector(`#${modalId}`)

// functions
const teleportToRoot = element => {
const teleportToRoot = (element) => {
element.remove()
body.appendChild(element)
}

const getKeyboardFocusableElements = element => {
return [...element.querySelectorAll(
'a, button, input, textarea, select, details,[tabindex]:not([tabindex="-1"])'
)]
.filter(el => !el.hasAttribute('disabled'))
const getKeyboardFocusableElements = (element) => {
return [
...element.querySelectorAll('a, button, input, textarea, select, details,[tabindex]:not([tabindex="-1"])'),
].filter((el) => !el.hasAttribute('disabled'))
}

const trapFocus = event => {
const trapFocus = (event) => {
const focusables = getKeyboardFocusableElements(modal)
const firstFocusable = focusables[0]
const lastFocusable = focusables[focusables.length - 1]
Expand All @@ -57,22 +59,22 @@ const {
}
}

const openModal = _ => {
const openModal = (_) => {
const modalTitle = modal.querySelector('h3')

modal.classList.add('show')
body.classList.add('modal-is-active')
modalTitle.focus()
document.addEventListener('keydown', trapFocus)

modal.addEventListener('keydown', event => {
modal.addEventListener('keydown', (event) => {
if (event.key === 'Escape') {
closeModal()
}
})
}

const closeModal = _ => {
const closeModal = (_) => {
modal.classList.remove('show')
body.classList.remove('modal-is-active')
modalTrigger.focus({ preventScroll: true })
Expand All @@ -86,7 +88,7 @@ const {

modalCloseButton.addEventListener('click', closeModal)

modal.addEventListener('click', event => {
modal.addEventListener('click', (event) => {
if (!event.target.closest('.modal__content')) {
closeModal()
}
Expand Down
16 changes: 10 additions & 6 deletions Notification.astro
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
---
const {
type = 'default',
role = 'none',
ariaLive = 'off'
} = Astro.props
interface Props {
// role="region" not supported as element takes no id
type?: 'info' | 'success' | 'warning' | 'error' | 'default'
role?: 'none' | 'alert' | 'log' | 'marquee' | 'status' | 'timer'
ariaLive?: 'off' | 'polite' | 'assertive'
children?: any
}
const { type = 'default', role = 'none', ariaLive = 'off' } = Astro.props
---

<div class={`notification type-${type}`} role={role} aria-live={ariaLive}>
Expand Down Expand Up @@ -52,4 +56,4 @@ const {
flex-shrink: 0;
width: 40px;
}
</style>
</style>
Loading

0 comments on commit 2470f0e

Please sign in to comment.