forked from profectus/Profectus
Added collapsibles
This commit is contained in:
parent
270894f59d
commit
3fa7ccf0c1
2 changed files with 68 additions and 1 deletions
51
src/components/layout/Collapsible.vue
Normal file
51
src/components/layout/Collapsible.vue
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
<template>
|
||||||
|
<Col style="width: 100%">
|
||||||
|
<button @click="collapsed.value = !collapsed.value" class="feature collapsible-toggle">
|
||||||
|
<component :is="displayComponent" />
|
||||||
|
</button>
|
||||||
|
<component v-if="!collapsed.value" :is="contentComponent" />
|
||||||
|
</Col>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { CoercableComponent } from "features/feature";
|
||||||
|
import { coerceComponent } from "util/vue";
|
||||||
|
import { computed, Ref } from "vue";
|
||||||
|
import Col from "./Column.vue";
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
collapsed: Ref<boolean>;
|
||||||
|
display: CoercableComponent;
|
||||||
|
content: CoercableComponent;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const displayComponent = computed(() => coerceComponent(props.display));
|
||||||
|
const contentComponent = computed(() => coerceComponent(props.content));
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.collapsible-toggle {
|
||||||
|
width: calc(100% - 10px);
|
||||||
|
background: var(--raised-background);
|
||||||
|
padding: var(--feature-margin);
|
||||||
|
color: var(--foreground);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.col) {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mergeAdjacent .collapsible-toggle {
|
||||||
|
border: 0;
|
||||||
|
border-top-left-radius: 0 !important;
|
||||||
|
border-top-right-radius: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.mergeAdjacent .feature:not(.dontMerge):first-child) {
|
||||||
|
border-top-left-radius: 0 !important;
|
||||||
|
border-top-right-radius: 0 !important;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -5,7 +5,8 @@ import {
|
||||||
Component as ComponentKey,
|
Component as ComponentKey,
|
||||||
GatherProps,
|
GatherProps,
|
||||||
GenericComponent,
|
GenericComponent,
|
||||||
JSXFunction
|
JSXFunction,
|
||||||
|
Visibility
|
||||||
} from "features/feature";
|
} from "features/feature";
|
||||||
import {
|
import {
|
||||||
Component,
|
Component,
|
||||||
|
@ -121,6 +122,21 @@ export function setupHoldToClick(
|
||||||
return { start, stop, handleHolding };
|
return { start, stop, handleHolding };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getFirstFeature<T extends { visibility: ProcessedComputable<Visibility> }>(
|
||||||
|
features: T[],
|
||||||
|
filter: (feature: T) => boolean
|
||||||
|
): { firstFeature: Ref<T | undefined>; hiddenFeatures: Ref<T[]> } {
|
||||||
|
const filteredFeatures = computed(() =>
|
||||||
|
features.filter(
|
||||||
|
feature => unref(feature.visibility) === Visibility.Visible && filter(feature)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
firstFeature: computed(() => filteredFeatures.value[0]),
|
||||||
|
hiddenFeatures: computed(() => filteredFeatures.value.slice(1))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function computeComponent(
|
export function computeComponent(
|
||||||
component: Ref<ProcessedComputable<CoercableComponent>>,
|
component: Ref<ProcessedComputable<CoercableComponent>>,
|
||||||
defaultWrapper = "div"
|
defaultWrapper = "div"
|
||||||
|
|
Loading…
Reference in a new issue