From 3fa7ccf0c1b2f9d4826ac7a6b38c47e0930b84f3 Mon Sep 17 00:00:00 2001 From: thepaperpilot <thepaperpilot@gmail.com> Date: Sun, 27 Mar 2022 13:47:36 -0500 Subject: [PATCH] Added collapsibles --- src/components/layout/Collapsible.vue | 51 +++++++++++++++++++++++++++ src/util/vue.tsx | 18 +++++++++- 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 src/components/layout/Collapsible.vue diff --git a/src/components/layout/Collapsible.vue b/src/components/layout/Collapsible.vue new file mode 100644 index 0000000..a9554cc --- /dev/null +++ b/src/components/layout/Collapsible.vue @@ -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> diff --git a/src/util/vue.tsx b/src/util/vue.tsx index f11e63f..7606e55 100644 --- a/src/util/vue.tsx +++ b/src/util/vue.tsx @@ -5,7 +5,8 @@ import { Component as ComponentKey, GatherProps, GenericComponent, - JSXFunction + JSXFunction, + Visibility } from "features/feature"; import { Component, @@ -121,6 +122,21 @@ export function setupHoldToClick( 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( component: Ref<ProcessedComputable<CoercableComponent>>, defaultWrapper = "div"