-
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.
- fix #1283 use min width for the Help link in the header - add Ellipse collapsible panel to FaqPage - fix #1277 jump to the right place, added custom margin top of 100 - fix #1282 (entries cut off)
- Loading branch information
1 parent
21b6f51
commit 50ef1f2
Showing
13 changed files
with
614 additions
and
218 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,124 @@ | ||
<template> | ||
<div ref="rootRef" class="CollapsiblePanel" :class="className" :style="rootStyles"> | ||
<div | ||
ref="headerRef" | ||
class="CollapsiblePanel__header d-flex justify-content-between align-items-center" | ||
@click="togglePanelState" | ||
> | ||
<slot name="header"> | ||
<div class="p-3"> | ||
<h4 class="m-0">{{ title }}</h4> | ||
<p v-if="subtitle.length" class="mb-0">subtitle</p> | ||
</div> | ||
</slot> | ||
<button | ||
class="btn btn-sm btn-icon mx-2" | ||
:class="{ | ||
active: modelValue | ||
}" | ||
> | ||
<Icon name="chevron" /> | ||
</button> | ||
</div> | ||
<div class="CollapsiblePanel__body position-absolute"> | ||
<slot></slot> | ||
</div> | ||
</div> | ||
</template> | ||
<script setup lang="ts"> | ||
/** | ||
* Model value is used to control the visibility of the panel. | ||
*/ | ||
import { ref, computed, watch } from 'vue' | ||
import Icon from './base/Icon.vue' | ||
const emit = defineEmits(['update:modelValue', 'heightChanged']) | ||
const props = defineProps({ | ||
modelValue: { | ||
type: Boolean, | ||
default: false, | ||
required: true | ||
}, | ||
title: { | ||
type: String, | ||
required: true | ||
}, | ||
subtitle: { | ||
type: String, | ||
default: '' | ||
}, | ||
className: { | ||
type: String, | ||
default: '' | ||
} | ||
}) | ||
const rootRef = ref<HTMLElement | null>(null) | ||
const headerRef = ref<HTMLElement | null>(null) | ||
const togglePanelState = () => { | ||
emit('update:modelValue', !props.modelValue) | ||
} | ||
const collapsedHeight = computed(() => { | ||
const header = headerRef.value | ||
return header ? `${header.offsetHeight}px` : 'auto' | ||
}) | ||
const expandedHeight = computed(() => { | ||
const root = rootRef.value | ||
const parsedOffset = parseInt(collapsedHeight.value) | ||
const offset = isNaN(parsedOffset) ? 0 : parsedOffset | ||
return root ? `${root.scrollHeight + offset}px` : 'auto' | ||
}) | ||
const rootStyles = computed(() => { | ||
return { | ||
height: props.modelValue ? expandedHeight.value : collapsedHeight.value | ||
} | ||
}) | ||
watch( | ||
() => rootStyles.value.height, | ||
height => { | ||
emit('heightChanged', height) | ||
}, | ||
{ immediate: true } | ||
) | ||
</script> | ||
|
||
<style> | ||
.CollapsiblePanel { | ||
position: relative; | ||
overflow: hidden; | ||
will-change: height; | ||
transition: height 0.6s; | ||
transition-timing-function: var(--impresso-transition-ease); | ||
} | ||
.CollapsiblePanel__header { | ||
cursor: pointer; | ||
user-select: none; | ||
box-sizing: border-box; | ||
} | ||
.CollapsiblePanel h3 { | ||
font-family: var(--bs-font-sans-serif); | ||
} | ||
.CollapsiblePanel__body { | ||
min-height: 50px; | ||
width: 100%; | ||
} | ||
.CollapsiblePanel button { | ||
transition: transform 0.3s; | ||
transition-timing-function: var(--impresso-transition-ease); | ||
} | ||
.CollapsiblePanel button.active { | ||
transform: rotate(180deg); | ||
} | ||
</style> |
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,79 @@ | ||
<template> | ||
<CollapsiblePanel | ||
class="CollapsibleParagraph" | ||
v-model="state" | ||
:title="paragraph.title" | ||
@heightChanged="e => emit('heightChanged', e)" | ||
> | ||
<template v-slot:header> | ||
<div class="d-flex align-items-center"> | ||
<h4 class="mb-0">{{ paragraph.title }}</h4> | ||
</div> | ||
</template> | ||
<div v-html="paragraph.description"></div> | ||
<ol v-if="paragraph.paragraphs.length"> | ||
<li | ||
v-for="(subtask, idx) in paragraph.paragraphs" | ||
:key="subtask.id" | ||
class="pt-2 mb-2 mx-2 d-flex align-items-center" | ||
> | ||
<div class="p-1 flex-grow-1"> | ||
{{ subtask.title }} | ||
</div> | ||
</li> | ||
</ol> | ||
</CollapsiblePanel> | ||
</template> | ||
|
||
<script setup lang="ts"> | ||
import { computed, PropType } from 'vue' | ||
import CollapsiblePanel from './CollapsiblePanel.vue' | ||
import type { ICollapsibleParagraph } from '@/models/CollapsibleParagraph' | ||
const emit = defineEmits(['update:modelValue', 'heightChanged']) | ||
const props = defineProps({ | ||
modelValue: { | ||
type: Boolean, | ||
default: false, | ||
required: true | ||
}, | ||
paragraph: { | ||
type: Object as PropType<ICollapsibleParagraph>, | ||
required: true | ||
}, | ||
taskNum: { | ||
type: Number, | ||
required: true | ||
} | ||
}) | ||
const state = computed({ | ||
set(value: boolean) { | ||
emit('update:modelValue', value) | ||
}, | ||
get() { | ||
return props.modelValue | ||
} | ||
}) | ||
</script> | ||
<style> | ||
.CollapsibleParagraph h4 { | ||
font-family: var(--bs-font-sans-serif); | ||
font-size: inherit; | ||
} | ||
.CollapsibleParagraph__num { | ||
font-size: var(--impresso-font-size-smallcaps); | ||
font-family: var(--bs-font-sans-serif); | ||
text-transform: uppercase; | ||
letter-spacing: var(--impresso-letter-spacing-smallcaps); | ||
font-weight: var(--impresso-wght-smallcaps); | ||
font-variation-settings: 'wght' var(--impresso-wght-smallcaps); | ||
} | ||
.CollapsibleParagraph.CollapsiblePanel { | ||
box-shadow: none; | ||
border-radius: 0; | ||
} | ||
</style> |
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,119 @@ | ||
<template> | ||
<CollapsiblePanel | ||
class="CollapsibleSection border border-dark" | ||
v-model="isOpen" | ||
:subtitle="subtitle" | ||
:title="title" | ||
:style="{ height: isOpen ? `${offsetHeight}px` : `${headerHeight}px` }" | ||
> | ||
<template v-slot:header> | ||
<div class="p-3"> | ||
<h3 class="mb-0">{{ title }}</h3> | ||
<span class="text-muted">{{ subtitle }}</span> | ||
</div> | ||
</template> | ||
<ol> | ||
<li v-for="(paragraph, idx) in paragraphs" :key="paragraph.id"> | ||
<CollapsibleParagraph | ||
:modelValue="currentOpenTaskId === paragraph.id" | ||
:paragraph="paragraph" | ||
:taskNum="idx + 1" | ||
@update:modelValue="(value: boolean) => (currentOpenTaskId = value ? task.id : null)" | ||
@heightChanged="(e: string) => updateHeight(paragraph.id, e)" | ||
> | ||
</CollapsibleParagraph> | ||
</li> | ||
</ol> | ||
</CollapsiblePanel> | ||
</template> | ||
<script setup lang="ts"> | ||
import { computed, PropType, ref, watch } from 'vue' | ||
import CollapsiblePanel from './CollapsiblePanel.vue' | ||
import CollapsibleParagraph from './CollapsibleParagraph.vue' | ||
import type { ICollapsibleParagraph } from '../models/CollapsibleParagraph' | ||
// TODO: Get from the element? | ||
const headerHeight = 50 | ||
const offsetHeights = ref<Record<string, number>>({}) | ||
const offsetHeight = computed( | ||
() => headerHeight + Object.values(offsetHeights.value).reduce((a, b) => a + b, 0) | ||
) | ||
const props = defineProps({ | ||
title: { | ||
type: String, | ||
required: true | ||
}, | ||
isCollapsed: { | ||
type: Boolean, | ||
default: true | ||
}, | ||
subtitle: { | ||
type: String, | ||
default: '' | ||
}, | ||
paragraphs: { | ||
type: Array as PropType<ICollapsibleParagraph[]>, | ||
required: true | ||
}, | ||
initialOpenedParagraphId: { | ||
type: String, | ||
default: null | ||
} | ||
}) | ||
const isOpen = ref(!props.isCollapsed) | ||
const currentOpenTaskId = ref<string | null>(props.initialOpenedParagraphId) | ||
watch( | ||
() => props.isCollapsed, | ||
isCollapsed => { | ||
isOpen.value = !isCollapsed | ||
} | ||
) | ||
const updateHeight = (id: string, height: string) => { | ||
const heightAsNumber = parseInt(height.replace('px', '')) | ||
offsetHeights.value[id] = isNaN(heightAsNumber) ? 0 : heightAsNumber | ||
} | ||
// const onTutorialTaskToggled = (idx: number, payload: CollapsiblePanelData) => { | ||
// console.debug('[CollapsibleSection] idx', idx, '@onTutorialTaskToggled', payload) | ||
// offsetHeights[idx] = payload.value ? 50 : payload.expandedHeight | ||
// } | ||
</script> | ||
|
||
<style> | ||
.CollapsibleSection.CollapsiblePanel { | ||
box-shadow: var(--bs-box-shadow-sm); | ||
border-radius: var(--border-radius-lg); | ||
} | ||
.CollapsibleSection ol { | ||
list-style-type: none; | ||
padding-inline-start: 0; | ||
padding-inline-end: 0; | ||
margin-inline-start: var(--spacing-2); | ||
margin-inline-end: var(--spacing-2); | ||
margin-bottom: var(--spacing-1); | ||
} | ||
.CollapsibleSection li { | ||
border-top: 1px solid var(--clr-grey-200); | ||
} | ||
.CollapsibleSection li:first-of-type { | ||
border-top-width: 0px; | ||
} | ||
.CollapsibleSection h3 { | ||
font-size: var(--impresso-font-size-smallcaps); | ||
font-family: var(--bs-font-sans-serif); | ||
text-transform: uppercase; | ||
letter-spacing: var(--impresso-letter-spacing-smallcaps); | ||
font-weight: var(--impresso-wght-smallcaps); | ||
font-variation-settings: 'wght' var(--impresso-wght-smallcaps); | ||
} | ||
</style> |
Oops, something went wrong.