Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/sondh0127/vue-epg-planby
https://github.com/sondh0127/vue-epg-planby
Last synced: 1 day ago
JSON representation
- Host: GitHub
- URL: https://github.com/sondh0127/vue-epg-planby
- Owner: sondh0127
- License: mit
- Created: 2022-07-02T14:00:13.000Z (over 2 years ago)
- Default Branch: master
- Last Pushed: 2022-09-09T03:14:54.000Z (over 2 years ago)
- Last Synced: 2025-01-03T07:05:47.069Z (19 days ago)
- Language: TypeScript
- Homepage: https://stackblitz.com/edit/vue-epg-planby-demo?file=src%2FApp.vue
- Size: 439 KB
- Stars: 9
- Watchers: 1
- Forks: 3
- Open Issues: 1
-
Metadata Files:
- Readme: readme.md
- Funding: .github/FUNDING.yml
- License: license.md
Awesome Lists containing this project
README
## Vue EPG Planby
[![License](https://img.shields.io/github/license/logustra/vue-epg-planby)](https://github.com/sondh0127/vue-epg-planby/blob/master/license.md)
[![Code Style](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
[![Commitizen](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli)> Electronic Program Guide (EPG) is a digital TV program that is used to display information about a channel's programs.
> Vue EPG Planby is a Vue components for EPG based Timeline, (ported from [planby](https://github.com/karolkozer/planby) - React based)
## Features
- Reactivity props
- Customizable template## Installation
```sh
# install packages
$ pnpm install @sondh0127/vue-epg-planby
```## Usage
Vue 3 (Vue 2.7)
### Basic Usage
```ts
import { addDays, addHours, endOfDay, format, startOfDay, subDays } from 'date-fns'
import type { Channel, Program, Theme } from '@sondh0127/vue-epg-planby'
import { Epg, Layout, TIME_FORMAT, formatTime, useEpg } from '@sondh0127/vue-epg-planby'
import '@sondh0127/vue-epg-planby/style.css'import { fetchChannels, fetchEpg } from './helpers'
const darkTheme: Theme = {
primary: {
600: '#1a202c',
900: '#171923',
},
grey: { 300: '#d1d1d1' },
white: '#fff',
green: {
300: '#2C7A7B',
},
loader: {
bg: '#171923db',
},
scrollbar: {
border: '#ffffff',
thumb: {
bg: '#e1e1e1',
},
},gradient: {
blue: {
300: '#002eb3',
600: '#002360',
900: '#051937',
},
},text: {
grey: {
300: '#a0aec0',
500: '#718096',
},
},timeline: {
divider: {
bg: '#718096',
},
},
}const themeLight: Theme = {
primary: {
600: '#f7fafc',
900: '#cbd5e0',
},
grey: { 300: '#2d3748' },
white: '#1a202c',
green: {
300: '#2C7A7B',
},
loader: {
bg: '#cbd5e0db',
},
scrollbar: {
border: '#ffffff',
thumb: {
bg: '#718096',
},
},gradient: {
blue: {
300: '#a0aec0',
600: '#e2e8f0',
900: '#a0aec0',
},
},text: {
grey: {
300: '#2d3748',
500: '#1a202c',
},
},timeline: {
divider: {
bg: '#1a202c',
},
},
}const themeValue = useStorage('__VUE_EPG_THEME__', 'light')
const options = [
{
label: 'Dark theme',
value: 'dark',
},
{
label: 'Light theme',
value: 'light',
},
]const theme = computed(() => {
return themeValue.value === 'dark' ? darkTheme : themeLight
})const channels = ref([])
const epg = ref([])
const isLoading = ref(false)const date = ref(new Date())
const timeRange = ref([addHours(startOfDay(new Date()), 0), endOfDay(new Date())])const startDate = computed(() => {
const day = date.value
const startTime = timeRange.value[0]
day.setHours(startTime.getHours())
day.setMinutes(startTime.getMinutes())
day.setSeconds(startTime.getSeconds())
return formatTime(day)
})const endDate = computed(() => {
const day = date.value
const endTime = timeRange.value[1]
day.setHours(endTime.getHours())
day.setMinutes(endTime.getMinutes())
day.setSeconds(endTime.getSeconds())
return formatTime(day)
})const itemHeight = ref(80)
const dayWidth = ref(7200)
const sidebarWidth = ref(100)
const isSidebar = ref(true)
const isTimeline = ref(true)
const isBaseTimeFormat = ref(false)const _24hFormat = computed({
get() {
return !isBaseTimeFormat.value
},
set(value) {
isBaseTimeFormat.value = !value
},
})const { getEpgProps, getLayoutProps, onScrollToNow } = useEpg({
channels,
epg,
dayWidth,
sidebarWidth,
itemHeight,
isSidebar,
isTimeline,
isLine: true,
startDate,
endDate,
isBaseTimeFormat,
theme,
})async function fetchDate() {
isLoading.value = true
epg.value = await fetchEpg(
format(subDays(date.value, 1), TIME_FORMAT.DATE),
format(addDays(date.value, 0), TIME_FORMAT.DATE),
)channels.value = await fetchChannels()
isLoading.value = false
}onMounted(async () => {
await fetchDate()
})watch(date, async () => {
await fetchDate()
})function disabledSeconds() {
return Array.from({ length: 60 }, (_, i) => i)
}function onProgramClick(p: Program) {
console.log('onProgramClick', p)
}function onChannelClick(c: Channel) {
console.log('onChannelClick', c)
}```
```html
Reload
Now
{{ data.title }}
{{ format12HoursTime(data.since) }} -{{ " " }}
{{ format12HoursTime(data.till) }}
{{ formatTimelineTime(index + offsetStartHoursRange) }}
```
[Demo →](https://stackblitz.com/edit/vue-epg-planby-demo?file=src%2FApp.vue)
## Checklist
When you use this template, try follow the checklist to update your info properly- [x] full Interactive Demo
- [x] Light | Dark Theme
- [ ] Zooming use dayWidth
- [x] stackblitz demo
- [ ] Testing
- [ ] Loader
- [x] renderProps => scoped slot
- [ ] Vue 2.7 Test
- [x] Ref => MaybeRef => new convention of passing reactive getters as arguments. [https://github.com/vueuse/vueuse/releases/tag/v9.0.0-beta.0](https://github.com/vueuse/vueuse/releases/tag/v9.0.0-beta.0)
- [ ] Tanstack/Virtual## Cheer me on
If you like my works, you can cheer me on here 😆## License
MIT License © 2022 Son Hong Do## Credits
Karol Kozer - [@kozerkarol_twitter](https://twitter.com/kozerkarol)
Planby: React based [https://github.com/karolkozer/planby](https://github.com/karolkozer/planby)