Skip to content

Commit

Permalink
Merge pull request #599 from madeindjs/WF-47
Browse files Browse the repository at this point in the history
feat(ui): introduce collapsible section + harmonize collapser - WF-47
  • Loading branch information
ramedina86 authored Oct 26, 2024
2 parents 4399c8d + 74d2a99 commit 330f317
Show file tree
Hide file tree
Showing 7 changed files with 169 additions and 132 deletions.
55 changes: 55 additions & 0 deletions src/ui/src/components/core/base/BaseCollapseButton.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<template>
<button
role="button"
class="BaseCollapseIcon"
:class="{ 'BaseCollapseIcon--collapsed': isCollapsed }"
@click="isCollapsed = !isCollapsed"
>
<i class="material-symbols-outlined">{{ icon }}</i>
</button>
</template>

<script setup lang="ts">
import { computed, PropType } from "vue";
const props = defineProps({
direction: {
type: String as PropType<"left-right" | "top-bottom">,
required: true,
},
});
const isCollapsed = defineModel({ type: Boolean, required: true });
const icon = computed(() =>
props.direction === "left-right" ? "chevron_left" : "keyboard_arrow_up",
);
</script>

<style scoped>
.BaseCollapseIcon {
border: none;
border-radius: 50%;
padding: 4px;
display: flex;
align-items: center;
justify-content: center;
background-color: transparent;
height: 32px;
width: 32px;
cursor: pointer;
transition: all 0.3s ease-in-out;
transform: rotate(0deg);
border: 1px solid var(--separatorColor);
}
.BaseCollapseIcon:hover {
background: var(--separatorColor);
}
.BaseCollapseIcon--collapsed {
transform: rotate(180deg);
}
</style>
49 changes: 10 additions & 39 deletions src/ui/src/components/core/layout/CoreColumn.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,12 @@
<div v-if="!isCollapsed" class="titleContainer">
<h3 v-if="fields.title.value">{{ fields.title.value }}</h3>
</div>
<div
<BaseCollapseButton
v-if="isCollapsible"
v-model="isCollapsed"
class="collapser"
@click="toggleCollapsed"
>
<IconGen
class="collapserArrow"
icon-key="collapseArrow"
></IconGen>
</div>
direction="left-right"
/>
</div>
<div v-if="isCollapsed && fields.title.value" class="collapsedTitle">
<div class="transformed">
Expand All @@ -31,6 +27,7 @@
</div>
<BaseContainer
class="container"
:aria-expanded="isCollapsible ? isCollapsed : null"
:content-h-align="fields.contentHAlign.value"
:content-v-align="fields.contentVAlign.value"
:content-padding="fields.contentPadding.value"
Expand All @@ -48,7 +45,10 @@ import {
contentVAlign,
cssClasses,
separatorColor,
startCollapsed,
isCollapsible as isCollapsibleField,
} from "@/renderer/sharedStyleFields";
import BaseCollapseButton from "../base/BaseCollapseButton.vue";
const description =
"A layout component that organises its child components in columns. Must be inside a Column Container component.";
Expand Down Expand Up @@ -83,25 +83,9 @@ export default {
},
category: FieldCategory.Style,
},
isCollapsible: {
name: "Collapsible",
default: "no",
type: FieldType.Text,
options: {
yes: "Yes",
no: "No",
},
category: FieldCategory.Style,
},
isCollapsible: isCollapsibleField,
startCollapsed: {
name: "Start collapsed",
type: FieldType.Text,
category: FieldCategory.Style,
default: "no",
options: {
yes: "Yes",
no: "No",
},
...startCollapsed,
desc: "Only applied when the column is collapsible.",
},
separatorColor,
Expand All @@ -111,13 +95,11 @@ export default {
cssClasses,
},
},
components: { IconGen },
};
</script>
<script setup lang="ts">
import { computed, ComputedRef, inject, Ref, ref, watch } from "vue";
import injectionKeys from "@/injectionKeys";
import IconGen from "@/renderer/IconGen.vue";
import BaseContainer from "../base/BaseContainer.vue";
const instancePath = inject(injectionKeys.instancePath);
const instanceData = inject(injectionKeys.instanceData);
Expand All @@ -144,10 +126,6 @@ const rootStyle = computed(() => {
return style;
});
const toggleCollapsed = () => {
isCollapsed.value = !isCollapsed.value;
};
/* Collapsing direction
The minimum non-collapsible column position (mnccp) determines how other columns collapse.
Those with a position lower than mnccp collapse to the left.
Expand Down Expand Up @@ -232,13 +210,6 @@ watch(
.CoreColumn > .header > .collapser {
order: 2;
flex: 0 0 32px;
border-radius: 16px;
padding: 4px;
background: var(--separatorColor);
display: flex;
align-items: center;
justify-content: center;
stroke: var(--primaryTextColor);
}
.CoreColumn > .header > .collapser > .collapserArrow {
Expand Down
41 changes: 37 additions & 4 deletions src/ui/src/components/core/layout/CoreSection.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,27 @@
<template>
<section class="CoreSection">
<h3 v-if="fields.title.value">{{ fields.title.value }}</h3>
<section
class="CoreSection"
:class="{ 'CoreSection--collapsible': isCollapsible }"
>
<div
v-if="fields.title.value || isCollapsible"
class="CoreSection__title"
:class="{
'CoreSection__title--collapsed': isCollapsible && isCollapsed,
}"
>
<h3>{{ fields.title.value }}</h3>
<BaseCollapseButton
v-if="isCollapsible"
v-model="isCollapsed"
direction="top-bottom"
/>
</div>
<BaseContainer
v-if="!isCollapsed"
:content-h-align="fields.contentHAlign.value"
:content-padding="fields.contentPadding.value"
:aria-expanded="isCollapsible ? isCollapsed : null"
>
<slot></slot>
</BaseContainer>
Expand All @@ -25,6 +43,8 @@ import {
cssClasses,
contentHAlign,
contentPadding,
isCollapsible as isCollapsibleField,
startCollapsed,
} from "@/renderer/sharedStyleFields";
const description =
Expand All @@ -43,6 +63,8 @@ export default {
desc: "Leave blank to hide.",
type: FieldType.Text,
},
isCollapsible: isCollapsibleField,
startCollapsed,
accentColor,
primaryTextColor,
secondaryTextColor,
Expand All @@ -64,11 +86,17 @@ export default {
};
</script>
<script setup lang="ts">
import { inject } from "vue";
import { computed, inject, ref } from "vue";
import injectionKeys from "@/injectionKeys";
import BaseContainer from "../base/BaseContainer.vue";
import BaseCollapseButton from "../base/BaseCollapseButton.vue";
const fields = inject(injectionKeys.evaluatedFields);
const isCollapsible = computed(() => fields.isCollapsible.value === "yes");
const isCollapsed = ref<boolean>(
isCollapsible.value && fields.startCollapsed.value === "yes",
);
</script>

<style scoped>
Expand All @@ -80,7 +108,12 @@ const fields = inject(injectionKeys.evaluatedFields);
background-color: var(--containerBackgroundColor);
}
h3 {
.CoreSection__title {
margin: 16px 16px 0 16px;
display: grid;
grid-template-columns: 1fr auto;
}
.CoreSection__title--collapsed {
margin: 16px;
}
</style>
33 changes: 5 additions & 28 deletions src/ui/src/components/core/layout/CoreSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,7 @@
}"
>
<div class="collapserContainer">
<div class="collapser" @click="toggleCollapsed">
<IconGen
class="collapserArrow"
icon-key="collapseArrow"
></IconGen>
</div>
<BaseCollapseButton v-model="isCollapsed" direction="left-right" />
</div>
<div class="container" data-writer-container>
<slot></slot>
Expand All @@ -33,7 +28,9 @@ import {
buttonTextColor,
buttonShadow,
cssClasses,
startCollapsed,
} from "@/renderer/sharedStyleFields";
import BaseCollapseButton from "../base/BaseCollapseButton.vue";
const description =
"A container component that organises its children in a sidebar. Its parent must be a Page component.";
Expand All @@ -49,14 +46,8 @@ export default {
category: "Layout",
fields: {
startCollapsed: {
name: "Start collapsed",
type: FieldType.Text,
category: FieldCategory.Style,
default: "no",
options: {
yes: "Yes",
no: "No",
},
...startCollapsed,
desc: undefined,
},
sidebarBackgroundColor: {
name: "Background",
Expand All @@ -82,7 +73,6 @@ export default {
<script setup lang="ts">
import { computed, inject, onMounted, Ref, ref, watch } from "vue";
import injectionKeys from "@/injectionKeys";
import IconGen from "@/renderer/IconGen.vue";
const fields = inject(injectionKeys.evaluatedFields);
const isCollapsed: Ref<boolean> = ref(fields.startCollapsed.value == "yes");
Expand All @@ -91,10 +81,6 @@ const ssbm = inject(injectionKeys.builderManager);
const componentId = inject(injectionKeys.componentId);
const selectedId = computed(() => ssbm?.getSelectedId());
const toggleCollapsed = () => {
isCollapsed.value = !isCollapsed.value;
};
const rendererTop = ref(0);
const rootStyle = computed(() => {
Expand Down Expand Up @@ -153,15 +139,6 @@ onMounted(() => {
.collapserContainer > .collapser {
flex: 0 0 32px;
min-width: 32px;
border-radius: 16px;
padding: 4px;
display: flex;
align-items: center;
justify-content: center;
stroke: var(--primaryTextColor);
border: 1px solid var(--separatorColor);
pointer: cursor;
}
.collapserContainer .collapserArrow {
Expand Down
29 changes: 0 additions & 29 deletions src/ui/src/renderer/IconGen.vue

This file was deleted.

Loading

0 comments on commit 330f317

Please sign in to comment.