[merge] merge dev2
This commit is contained in:
commit
91ab4bae73
@ -3,7 +3,7 @@
|
|||||||
// varible declare
|
// varible declare
|
||||||
$fontColor: white;
|
$fontColor: white;
|
||||||
$backgroundColor: #1f4163;
|
$backgroundColor: #1f4163;
|
||||||
$fontFamily: 'Noto Sans CJK TC', monospace;
|
$fontFamily: 'Noto Sans TC', monospace;
|
||||||
|
|
||||||
@mixin fontSize() {
|
@mixin fontSize() {
|
||||||
font-size: 14pt;
|
font-size: 14pt;
|
||||||
|
@ -32,7 +32,7 @@ body {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
font-size: 13pt;
|
font-size: 13pt;
|
||||||
font-family: 'Noto Sans CJK TC', sans-serif;
|
font-family: 'Noto Sans TC', sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
#app {
|
#app {
|
||||||
|
@ -22,12 +22,29 @@ $max-width-small-3: 360px;
|
|||||||
// .info-container
|
// .info-container
|
||||||
@mixin infoContainer() {
|
@mixin infoContainer() {
|
||||||
max-width: 80%;
|
max-width: 80%;
|
||||||
|
<<<<<<< HEAD
|
||||||
// padding-left: 7%;
|
// padding-left: 7%;
|
||||||
@media only screen and (max-width: 1030px){
|
@media only screen and (max-width: 1030px){
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
padding-left: 40px;
|
padding-left: 40px;
|
||||||
padding-right: 40px;
|
padding-right: 40px;
|
||||||
}
|
}
|
||||||
|
=======
|
||||||
|
@media screen and (max-width: 1365px) {
|
||||||
|
margin: 0 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 1023px) {
|
||||||
|
margin: 0 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $max-width-small-0) {
|
||||||
|
margin: 0;
|
||||||
|
max-width: 100%;
|
||||||
|
padding-left: 40px;
|
||||||
|
padding-right: 40px;
|
||||||
|
}
|
||||||
|
>>>>>>> dev2
|
||||||
}
|
}
|
||||||
|
|
||||||
// .info-section
|
// .info-section
|
||||||
@ -215,10 +232,10 @@ $max-width-small-3: 360px;
|
|||||||
@mixin qaTitleFontsize() {
|
@mixin qaTitleFontsize() {
|
||||||
font-size: 18pt;
|
font-size: 18pt;
|
||||||
@media only screen and (max-width: $max-width-medium-0) {
|
@media only screen and (max-width: $max-width-medium-0) {
|
||||||
font-size: 17pt;
|
font-size: 16pt;
|
||||||
}
|
}
|
||||||
@media only screen and (max-width: $max-width-medium-1) {
|
@media only screen and (max-width: $max-width-medium-1) {
|
||||||
font-size: 15pt;
|
font-size: 14pt;
|
||||||
}
|
}
|
||||||
@media only screen and (max-width: $max-width-small-0) {
|
@media only screen and (max-width: $max-width-small-0) {
|
||||||
font-size: 11pt;
|
font-size: 11pt;
|
||||||
@ -360,7 +377,7 @@ $max-width-small-3: 360px;
|
|||||||
|
|
||||||
&-container {
|
&-container {
|
||||||
@include infoContainer();
|
@include infoContainer();
|
||||||
margin: 0 auto;
|
margin: 0 280px;
|
||||||
// float: left;
|
// float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,82 +346,3 @@ $fontFamily: Noto Sans TC, monospace;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.news-nav {
|
|
||||||
position: fixed;
|
|
||||||
text-align: end;
|
|
||||||
top: 25px;
|
|
||||||
right: 50px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
border-radius: 15px;
|
|
||||||
padding: 10px;
|
|
||||||
box-shadow: 3px 3px 15px $mid-blue;
|
|
||||||
background: white;
|
|
||||||
z-index: 5;
|
|
||||||
&-item {
|
|
||||||
margin: 0 8px;
|
|
||||||
padding: 5px 1em;
|
|
||||||
color: $mid-blue;
|
|
||||||
font-family: $fontFamily;
|
|
||||||
cursor: point;
|
|
||||||
border-right: 3px solid $sky-blue;
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
font-weight: 900;
|
|
||||||
border-right: 3px solid $mid-blue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&-button {
|
|
||||||
color: $mid-blue;
|
|
||||||
border: none;
|
|
||||||
background: transparent;
|
|
||||||
font-size: 20px;
|
|
||||||
cursor: point;
|
|
||||||
&:focus {
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&-contribute-button {
|
|
||||||
display: inline-block;
|
|
||||||
border-radius: 6px;
|
|
||||||
background: $mid-blue;
|
|
||||||
color: $white;
|
|
||||||
font-weight: 900;
|
|
||||||
padding: 0.5em 1em;
|
|
||||||
font-size: 1.2em;
|
|
||||||
margin: 1em auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-control-button {
|
|
||||||
color: $mid-blue;
|
|
||||||
position: fixed;
|
|
||||||
z-index: 5;
|
|
||||||
top: 25px;
|
|
||||||
right: 50px;
|
|
||||||
border-radius: 5px;
|
|
||||||
border: none;
|
|
||||||
font-size: 24px;
|
|
||||||
position: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
width: 55px;
|
|
||||||
background-color: white;
|
|
||||||
box-shadow: -2px 0 15px $mid-blue;
|
|
||||||
padding: 0 15px;
|
|
||||||
cursor: pointer;
|
|
||||||
p {
|
|
||||||
text-align: end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 1024px) {
|
|
||||||
.nav-control-button {
|
|
||||||
top: 250px;
|
|
||||||
right: 0;
|
|
||||||
width: 35px;
|
|
||||||
font-size: 16px;
|
|
||||||
text-align: left;
|
|
||||||
padding: 0 10px;
|
|
||||||
}
|
|
||||||
}
|
|
114
src/assets/scss/news/navbar.scss
Normal file
114
src/assets/scss/news/navbar.scss
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
@import '../color';
|
||||||
|
@import '../font';
|
||||||
|
|
||||||
|
$mobileView: 1024px;
|
||||||
|
|
||||||
|
#news-nav {
|
||||||
|
font-size: 13pt;
|
||||||
|
line-height: 1em;
|
||||||
|
z-index: 2;
|
||||||
|
|
||||||
|
position: sticky;
|
||||||
|
top: 25px;
|
||||||
|
|
||||||
|
&.fixed {
|
||||||
|
position: fixed;
|
||||||
|
top: 25px;
|
||||||
|
right: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news-nav {
|
||||||
|
float: right;
|
||||||
|
text-align: end;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
border-radius: 15px;
|
||||||
|
padding: 10px;
|
||||||
|
box-shadow: 3px 3px 15px $mid-blue;
|
||||||
|
background: white;
|
||||||
|
z-index: 5;
|
||||||
|
|
||||||
|
transform: translateX(0);
|
||||||
|
transition: transform 0.5s ease-in-out;
|
||||||
|
|
||||||
|
&-item {
|
||||||
|
margin: 0 8px;
|
||||||
|
padding: 5px 1em;
|
||||||
|
color: $mid-blue;
|
||||||
|
font-family: $fontFamily;
|
||||||
|
cursor: point;
|
||||||
|
border-right: 3px solid $sky-blue;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
font-weight: 900;
|
||||||
|
border-right: 3px solid $mid-blue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&-button {
|
||||||
|
color: $mid-blue;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
padding: 0.5em 0;
|
||||||
|
font-size: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&-contribute-button {
|
||||||
|
display: inline-block;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: $mid-blue;
|
||||||
|
color: $white;
|
||||||
|
font-weight: 900;
|
||||||
|
padding: 0.5em 1em;
|
||||||
|
font-size: 1.2em;
|
||||||
|
margin: 1em auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-control-button {
|
||||||
|
color: $mid-blue;
|
||||||
|
position: fixed;
|
||||||
|
z-index: 5;
|
||||||
|
top: 25px;
|
||||||
|
right: 50px;
|
||||||
|
border-radius: 5px;
|
||||||
|
border: none;
|
||||||
|
font-size: 24px;
|
||||||
|
position: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 55px;
|
||||||
|
background-color: white;
|
||||||
|
box-shadow: -2px 0 15px $mid-blue;
|
||||||
|
padding: 0 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
p {
|
||||||
|
text-align: end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $mobileView) {
|
||||||
|
.nav-control-button {
|
||||||
|
top: 250px;
|
||||||
|
right: 0;
|
||||||
|
width: 35px;
|
||||||
|
font-size: 16px;
|
||||||
|
text-align: left;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: $mobileView) {
|
||||||
|
#news-nav,
|
||||||
|
#news-nav.fixed {
|
||||||
|
position: fixed;
|
||||||
|
top: 25px;
|
||||||
|
right: 20px;
|
||||||
|
}
|
||||||
|
}
|
@ -1,15 +1,13 @@
|
|||||||
@import "../breakpoint";
|
@import "../breakpoint";
|
||||||
@import "../color";
|
@import "../color";
|
||||||
@import "../font.scss";
|
@import "../font";
|
||||||
// No need to import font; the fonts have been imported in App.vue
|
// No need to import font; the fonts have been imported in App.vue
|
||||||
// @import '@/assets/scss/font';
|
// @import '@/assets/scss/font';
|
||||||
|
|
||||||
$fontFamily: 'Noto Sans CJK TC', monospace;
|
|
||||||
|
|
||||||
#news-schedule {
|
#news-schedule {
|
||||||
position: relative;
|
position: relative;
|
||||||
max-width: 80vw;
|
max-width: 80vw;
|
||||||
margin: 0 auto;
|
margin: 0 280px;
|
||||||
|
|
||||||
font-family: $fontFamily;
|
font-family: $fontFamily;
|
||||||
font-size: 15pt;
|
font-size: 15pt;
|
||||||
@ -96,8 +94,16 @@ $fontFamily: 'Noto Sans CJK TC', monospace;
|
|||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include md {
|
@media screen and (max-width: 1365px) {
|
||||||
#news-schedule {
|
#news-schedule {
|
||||||
|
margin: 0 120px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 1023px) {
|
||||||
|
#news-schedule {
|
||||||
|
margin: 0 100px;
|
||||||
|
|
||||||
#presentation-example,
|
#presentation-example,
|
||||||
#espresso-example {
|
#espresso-example {
|
||||||
margin-bottom: unset;
|
margin-bottom: unset;
|
||||||
@ -112,6 +118,7 @@ $fontFamily: 'Noto Sans CJK TC', monospace;
|
|||||||
|
|
||||||
@media screen and (max-width: $max-width-small-0) {
|
@media screen and (max-width: $max-width-small-0) {
|
||||||
#news-schedule {
|
#news-schedule {
|
||||||
|
margin: 0;
|
||||||
max-width: 100vw;
|
max-width: 100vw;
|
||||||
padding: 0 40px;
|
padding: 0 40px;
|
||||||
font-size: 11pt;
|
font-size: 11pt;
|
||||||
|
@ -46,30 +46,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<nav v-if="navVisible">
|
|
||||||
<div class="news-nav" v-scrollspy="{ selectors: navbarItems }">
|
|
||||||
<a class="news-nav-item" href="#schedule">重要時程</a>
|
|
||||||
<a class="news-nav-item" href="#example">投稿主題範例</a>
|
|
||||||
<a class="news-nav-item" href="#code-of-conduct">Code of Conduct</a>
|
|
||||||
<a class="news-nav-item" href="#info-section">議程種類</a>
|
|
||||||
<a class="news-nav-item" href="#process">流程</a>
|
|
||||||
<a class="news-nav-item" href="#methods">投稿方式</a>
|
|
||||||
<a class="news-nav-item" href="#review">審稿方式</a>
|
|
||||||
<a class="news-nav-item" href="#precautions">投稿注意事項</a>
|
|
||||||
<a class="news-nav-contribute-button" target="_blank" rel="noopener" href="https://forms.gle/XoXJSD2P8dL8X8s2A">我要投稿</a>
|
|
||||||
<button class="news-nav-button" @click="(e)=>navVisible=!navVisible">▲</button>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
<button v-if="!navVisible" class="nav-control-button" @click="(e)=>navVisible=!navVisible">
|
|
||||||
<p>▲</p>
|
|
||||||
<p>▼</p>
|
|
||||||
</button>
|
|
||||||
</header>
|
</header>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Component, Prop, Vue } from 'vue-property-decorator';
|
import { Component, Prop, Vue } from 'vue-property-decorator';
|
||||||
import ScrollSpyDirective from './ScrollSpyDirective';
|
|
||||||
|
|
||||||
const DEAD_LINE = Math.floor(
|
const DEAD_LINE = Math.floor(
|
||||||
new Date('22 Feb 2021 06:24:00 GMT+8').getTime() / 1000
|
new Date('22 Feb 2021 06:24:00 GMT+8').getTime() / 1000
|
||||||
@ -82,24 +63,9 @@ interface Countdown {
|
|||||||
d: number;
|
d: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({})
|
||||||
directives: {
|
|
||||||
scrollspy: ScrollSpyDirective
|
|
||||||
}
|
|
||||||
})
|
|
||||||
export default class CfpHeader extends Vue {
|
export default class CfpHeader extends Vue {
|
||||||
private timerId!: number;
|
private timerId!: number;
|
||||||
private navbarItems = [
|
|
||||||
'#schedule',
|
|
||||||
'#example',
|
|
||||||
'#code-of-conduct',
|
|
||||||
'#info-section',
|
|
||||||
'#process',
|
|
||||||
'#methods',
|
|
||||||
'#review',
|
|
||||||
'#precautions'
|
|
||||||
];
|
|
||||||
private navVisible = false;
|
|
||||||
private countdown: Countdown = {
|
private countdown: Countdown = {
|
||||||
s: 0,
|
s: 0,
|
||||||
m: 0,
|
m: 0,
|
||||||
|
82
src/components/news/Navbar.vue
Normal file
82
src/components/news/Navbar.vue
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<template>
|
||||||
|
<nav id="news-nav" :class="{ fixed: isNavbarFixed }">
|
||||||
|
<div v-show="!isMobileView || navVisible" class="news-nav" v-scrollspy="{ selectors: navbarItems }">
|
||||||
|
<a class="news-nav-item" href="#schedule">重要時程</a>
|
||||||
|
<a class="news-nav-item" href="#example">投稿主題範例</a>
|
||||||
|
<a class="news-nav-item" href="#code-of-conduct">Code of Conduct</a>
|
||||||
|
<a class="news-nav-item" href="#info-section">議程種類</a>
|
||||||
|
<a class="news-nav-item" href="#process">流程</a>
|
||||||
|
<a class="news-nav-item" href="#methods">投稿方式</a>
|
||||||
|
<a class="news-nav-item" href="#review">審稿方式</a>
|
||||||
|
<a class="news-nav-item" href="#precautions">投稿注意事項</a>
|
||||||
|
<a class="news-nav-contribute-button" target="_blank" rel="noopener" href="https://forms.gle/XoXJSD2P8dL8X8s2A" v-show="!isMobileView">我要投稿</a>
|
||||||
|
<button class="news-nav-button" @click="(e)=>navVisible=!navVisible" v-show="isMobileView">▲</button>
|
||||||
|
</div>
|
||||||
|
<button v-show="!navVisible && isMobileView" class="nav-control-button" @click="(e)=>navVisible=!navVisible">
|
||||||
|
<p>▲</p>
|
||||||
|
<p>▼</p>
|
||||||
|
</button>
|
||||||
|
</nav>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { Component, Prop, Vue } from 'vue-property-decorator';
|
||||||
|
import ScrollSpyDirective from './ScrollSpyDirective';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
directives: {
|
||||||
|
scrollspy: ScrollSpyDirective
|
||||||
|
}
|
||||||
|
})
|
||||||
|
export default class Navbar extends Vue {
|
||||||
|
private isMobileView: boolean = false;
|
||||||
|
private isNavbarFixed = false;
|
||||||
|
private navVisible: boolean = false;
|
||||||
|
private navbarItems: string[] = [
|
||||||
|
'#schedule',
|
||||||
|
'#example',
|
||||||
|
'#code-of-conduct',
|
||||||
|
'#info-section',
|
||||||
|
'#process',
|
||||||
|
'#methods',
|
||||||
|
'#review',
|
||||||
|
'#precautions'
|
||||||
|
];
|
||||||
|
|
||||||
|
public mounted () {
|
||||||
|
this.$nextTick().then(() => {
|
||||||
|
const query: string = '(max-width: 1024px)';
|
||||||
|
const mq: MediaQueryList = window.matchMedia(query);
|
||||||
|
if (mq.addEventListener) {
|
||||||
|
mq.addEventListener('change', this.matchMediaCallback);
|
||||||
|
} else {
|
||||||
|
mq.addListener(this.matchMediaCallback);
|
||||||
|
}
|
||||||
|
// check first
|
||||||
|
this.matchMediaCallback(mq);
|
||||||
|
|
||||||
|
// observe header: header appears => no fix; header disappears => fix.
|
||||||
|
const fixObserver: IntersectionObserver = new IntersectionObserver((entries, observer) => {
|
||||||
|
entries.forEach((entry) => {
|
||||||
|
if (!entry.isIntersecting) {
|
||||||
|
this.isNavbarFixed = true;
|
||||||
|
} else {
|
||||||
|
this.isNavbarFixed = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, { rootMargin: '25px 0px 0px 0px', threshold: 0 });
|
||||||
|
fixObserver.observe(document.querySelector('#news-header') as Element);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private matchMediaCallback (ev: (MediaQueryList | MediaQueryListEvent)) {
|
||||||
|
this.isMobileView = ev.matches;
|
||||||
|
// alaways disable navbar while view changing
|
||||||
|
this.navVisible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/assets/scss/news/navbar';
|
||||||
|
</style>
|
@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
|
<Navbar />
|
||||||
<!-- 重要時程 -->
|
<!-- 重要時程 -->
|
||||||
<section id="schedule">
|
<section id="schedule">
|
||||||
<h1>重要時程</h1>
|
<h1>重要時程</h1>
|
||||||
@ -57,6 +58,7 @@
|
|||||||
import { Component, Prop, Vue } from 'vue-property-decorator';
|
import { Component, Prop, Vue } from 'vue-property-decorator';
|
||||||
import AgendaCard from './AgendaCard.vue';
|
import AgendaCard from './AgendaCard.vue';
|
||||||
import Topic from './Topic.vue';
|
import Topic from './Topic.vue';
|
||||||
|
import Navbar from './Navbar.vue';
|
||||||
|
|
||||||
// import data
|
// import data
|
||||||
import themeExample from '../../../template/themeExample.cfp';
|
import themeExample from '../../../template/themeExample.cfp';
|
||||||
@ -66,7 +68,8 @@ import presentation from '../../../template/presentation.cfp';
|
|||||||
@Component({
|
@Component({
|
||||||
components: {
|
components: {
|
||||||
AgendaCard,
|
AgendaCard,
|
||||||
Topic
|
Topic,
|
||||||
|
Navbar
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
export default class Schedule extends Vue {
|
export default class Schedule extends Vue {
|
||||||
|
@ -4,7 +4,7 @@ let selectors!: string[];
|
|||||||
let observer!: IntersectionObserver;
|
let observer!: IntersectionObserver;
|
||||||
|
|
||||||
const ScrollSpyDirective: DirectiveOptions = {
|
const ScrollSpyDirective: DirectiveOptions = {
|
||||||
bind (el: Element, binding: VNodeDirective , vnode: VNode) {
|
inserted (el: Element, binding: VNodeDirective, vnode: VNode) {
|
||||||
selectors = binding.value.selectors;
|
selectors = binding.value.selectors;
|
||||||
|
|
||||||
// highlight first element
|
// highlight first element
|
||||||
|
Loading…
x
Reference in New Issue
Block a user