generated from it-at-m/oss-repository-en-template
-
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.
✨ 41 sparkles adding business hours component (#93)
- Loading branch information
Showing
3 changed files
with
302 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/** | ||
* Shorthand notation of all seven days in german. | ||
* | ||
* @typedef {"Mo" | "Di" | "Mi" | "Do" | "Fr" | "Sa" | "So"} WeekDays | ||
*/ | ||
type WeekDays = "Mo" | "Di" | "Mi" | "Do" | "Fr" | "Sa" | "So"; | ||
|
||
/** | ||
* @typedef {Object} OpeningHour | ||
* @property {string} from - The start time of the opening period (in 'HH:mm' format). | ||
* @property {string} to - The end time of the opening period (in 'HH:mm' format). | ||
*/ | ||
type OpeningHour = { | ||
from: string; | ||
to: string; | ||
}; | ||
|
||
/** | ||
* @typedef {Object} BusinessHourType | ||
* @property {WeekDays} weekDay - The day of the week for which the opening hours apply. | ||
* @property {OpeningHour[]} openingHours - A list of opening hours for the specified day of the week. | ||
*/ | ||
type BusinessHourType = { | ||
weekDay: WeekDays; | ||
openingHours: OpeningHour[]; | ||
}; | ||
|
||
export type { BusinessHourType, OpeningHour, WeekDays }; |
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,108 @@ | ||
import MucBusinessHours from "./MucBusinessHours.vue"; | ||
|
||
export default { | ||
component: MucBusinessHours, | ||
title: "MucBusinessHours", | ||
tags: ["autodocs"], | ||
// 👇 Use `fn` to spy on the onClick arg, which will appear in the actions panel once invoked | ||
parameters: { | ||
docs: { | ||
description: { | ||
component: ` | ||
The businessHours component is used to display the business hours for each day of the week. | ||
The current day is highlighted as well as the days that are closed. | ||
In the toggleable variant, the current day and the opening hours are also displayed on the toggle button. | ||
[🔗 Patternlab-Docs](https://patternlab.muenchen.space/?p=viewall-components-business-hours) | ||
`, | ||
}, | ||
}, | ||
}, | ||
}; | ||
|
||
const businessHours = [ | ||
{ | ||
weekDay: "Mo", | ||
openingHours: [ | ||
{ | ||
from: "08:00", | ||
to: "12:00", | ||
}, | ||
{ | ||
from: "14:00", | ||
to: "18:00", | ||
}, | ||
], | ||
}, | ||
{ | ||
weekDay: "Di", | ||
openingHours: [ | ||
{ | ||
from: "09:00", | ||
to: "13:00", | ||
}, | ||
], | ||
}, | ||
{ | ||
weekDay: "Mi", | ||
openingHours: [ | ||
{ | ||
from: "10:00", | ||
to: "14:00", | ||
}, | ||
], | ||
}, | ||
{ | ||
weekDay: "Do", | ||
openingHours: [ | ||
{ | ||
from: "08:00", | ||
to: "12:00", | ||
}, | ||
{ | ||
from: "15:00", | ||
to: "19:00", | ||
}, | ||
], | ||
}, | ||
{ | ||
weekDay: "Fr", | ||
openingHours: [ | ||
{ | ||
from: "08:00", | ||
to: "12:00", | ||
}, | ||
{ | ||
from: "13:00", | ||
to: "17:00", | ||
}, | ||
], | ||
}, | ||
{ | ||
weekDay: "Sa", | ||
openingHours: [ | ||
{ | ||
from: "10:00", | ||
to: "13:00", | ||
}, | ||
], | ||
}, | ||
{ | ||
weekDay: "So", | ||
openingHours: [], | ||
}, | ||
]; | ||
|
||
export const Default = { | ||
args: { | ||
businessHours: businessHours, | ||
toggleable: true, | ||
}, | ||
}; | ||
|
||
export const Fixed = { | ||
args: { | ||
...Default.args, | ||
toggleable: false, | ||
}, | ||
}; |
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,166 @@ | ||
<template> | ||
<div class="m-business-hours-toggle"> | ||
<h3 class="m-business-hours-toggle__title visually-hidden"> | ||
Öffnungszeiten | ||
</h3> | ||
<button | ||
v-if="toggleable" | ||
@click="toggleCollapsable" | ||
class="m-business-hours-toggle__trigger is-open" | ||
:class="collapsedClass" | ||
type="button" | ||
data-bs-toggle="collapse" | ||
:aria-expanded="!collapsed" | ||
> | ||
<svg | ||
aria-hidden="true" | ||
class="icon icon--before" | ||
> | ||
<use :xlink:href="'#icon-' + icon"></use> | ||
</svg> | ||
<div v-if="todaysBusinessHours"> | ||
<span> {{ todaysBusinessHours.weekDay }} geöffnet </span> | ||
<span | ||
v-for="(time, index) in todaysBusinessHours.openingHours" | ||
:key="index" | ||
> | ||
{{ time.from }} bis {{ time.to }} | ||
<span v-if="index < todaysBusinessHours.openingHours.length - 1"> | ||
und | ||
</span> | ||
</span> | ||
</div> | ||
|
||
<svg | ||
aria-hidden="true" | ||
class="icon icon--after" | ||
> | ||
<use xlink:href="#icon-chevron-down"></use> | ||
</svg> | ||
</button> | ||
<div | ||
class="m-business-hours-toggle__content" | ||
:class="collapseClass" | ||
> | ||
<ul class="ml-0"> | ||
<li | ||
v-for="day in businessHours" | ||
:key="day.weekDay" | ||
:class="highlightBusinessDay(day)" | ||
> | ||
<span class="weekday">{{ day.weekDay }}</span> | ||
<span class="hours"> | ||
<div v-if="day.openingHours.length === 0">geschlossen</div> | ||
<div | ||
v-else | ||
v-for="time in day.openingHours" | ||
:key="time.from" | ||
> | ||
{{ time.from }} - {{ time.to }} | ||
</div> | ||
</span> | ||
</li> | ||
</ul> | ||
<div | ||
v-if="slots['hint']" | ||
class="hint" | ||
> | ||
<slot name="hint" /> | ||
</div> | ||
</div> | ||
</div> | ||
</template> | ||
|
||
<script setup lang="ts"> | ||
import { computed, ref } from "vue"; | ||
import { BusinessHourType } from "./BusinessHourType"; | ||
const LOCALES = "de-DE"; | ||
const props = withDefaults( | ||
defineProps<{ | ||
/** | ||
* This array includes all the opening hours for all days of the week. | ||
*/ | ||
businessHours: BusinessHourType[]; | ||
/** | ||
* Lets you choose between the toggleable and fixed state of the component. | ||
* In the fixed state, no toggle button will be shown. | ||
*/ | ||
toggleable?: boolean; | ||
/** | ||
* Choose an icon for the toggle button. The default if none is given is the time icon. | ||
*/ | ||
icon?: string; | ||
}>(), | ||
{ | ||
icon: "time", | ||
toggleable: false, | ||
} | ||
); | ||
let collapsed = ref(props.toggleable); | ||
const slots = defineSlots<{ | ||
/** | ||
* Display a hint beneath all the opening hours. | ||
*/ | ||
hint(): any; | ||
}>(); | ||
/** | ||
* Toggles the collapsed state of the business hours section. | ||
*/ | ||
const toggleCollapsable = () => { | ||
collapsed.value = !collapsed.value; | ||
}; | ||
/** | ||
* Computes the CSS class for the collapse state. | ||
* | ||
* @returns {string} The CSS class for the collapse state. | ||
*/ | ||
const collapseClass = computed(() => (collapsed.value ? "collapse" : "")); | ||
/** | ||
* Computes the CSS class for the collapsed state. | ||
* | ||
* @returns {string} The CSS class for the collapsed state. | ||
*/ | ||
const collapsedClass = computed(() => (collapsed.value ? "collapsed" : "")); | ||
/** | ||
* Computes the short name of today's day. | ||
* | ||
* @returns {string} The short name of today's day (e.g., "Mo", "Di"). | ||
*/ | ||
const todaysDayShortName = computed(() => { | ||
const today = new Date(); | ||
return today.toLocaleDateString(LOCALES, { weekday: "short" }); | ||
}); | ||
/** | ||
* Highlights the business day based on whether it has opening hours and if it is today's day. | ||
* | ||
* @param {BusinessHourType} businessHour - The business hour object to check. | ||
* @returns {string} The CSS class indicating if the business is open or closed. | ||
*/ | ||
const highlightBusinessDay = (businessHour: BusinessHourType) => { | ||
if (businessHour.openingHours.length === 0) return "is-closed"; | ||
if (businessHour.weekDay === todaysDayShortName.value) return "is-open"; | ||
}; | ||
/** | ||
* Computes today's business hours from the provided business hours. | ||
* | ||
* @returns {BusinessHourType | undefined} The business hours for today, if available. | ||
*/ | ||
const todaysBusinessHours = computed(() => | ||
props.businessHours.find((curr) => curr.weekDay === todaysDayShortName.value) | ||
); | ||
</script> | ||
|
||
<style scoped></style> |