Skip to content

Commit

Permalink
feat(ui): introduce collapsible section - WF-47
Browse files Browse the repository at this point in the history
closes #506
  • Loading branch information
madeindjs committed Oct 20, 2024
1 parent d82f245 commit cc146fe
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 64 deletions.
32 changes: 12 additions & 20 deletions src/ui/src/components/core/layout/CoreColumn.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,17 @@
<div v-if="!isCollapsed" class="titleContainer">
<h3 v-if="fields.title.value">{{ fields.title.value }}</h3>
</div>
<div
<button
v-if="isCollapsible"
role="button"
class="collapser"
@click="toggleCollapsed"
>
<IconGen
class="collapserArrow"
icon-key="collapseArrow"
></IconGen>
</div>
</button>
</div>
<div v-if="isCollapsed && fields.title.value" class="collapsedTitle">
<div class="transformed">
Expand All @@ -31,6 +32,7 @@
</div>
<BaseContainer
class="container"
:aria-expanded="isCollapsible ? 'true' : null"
:content-h-align="fields.contentHAlign.value"
:content-v-align="fields.contentVAlign.value"
:content-padding="fields.contentPadding.value"
Expand All @@ -48,6 +50,8 @@ import {
contentVAlign,
cssClasses,
separatorColor,
startCollapsed,
isCollapsible as isCollapsibleField,
} from "@/renderer/sharedStyleFields";
const description =
Expand Down Expand Up @@ -83,25 +87,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 Down Expand Up @@ -230,6 +218,7 @@ watch(
}
.CoreColumn > .header > .collapser {
border: none;
order: 2;
flex: 0 0 32px;
border-radius: 16px;
Expand All @@ -239,6 +228,9 @@ watch(
align-items: center;
justify-content: center;
stroke: var(--primaryTextColor);
height: 32px;
width: 32px;
cursor: pointer;
}
.CoreColumn > .header > .collapser > .collapserArrow {
Expand Down
66 changes: 62 additions & 4 deletions src/ui/src/components/core/layout/CoreSection.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,30 @@
<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>
<button
v-if="isCollapsible"
role="button"
class="CoreSection__title__collapser"
@click="isCollapsed = !isCollapsed"
>
<i class="material-symbols-outlined">keyboard_arrow_up</i>
</button>
</div>
<BaseContainer
v-if="!isCollapsed"
:content-h-align="fields.contentHAlign.value"
:content-padding="fields.contentPadding.value"
:aria-expanded="isCollapsible ? 'true' : null"
>
<slot></slot>
</BaseContainer>
Expand All @@ -25,6 +46,8 @@ import {
cssClasses,
contentHAlign,
contentPadding,
isCollapsible as isCollapsibleField,
startCollapsed,
} from "@/renderer/sharedStyleFields";
const description =
Expand All @@ -43,6 +66,8 @@ export default {
desc: "Leave blank to hide.",
type: FieldType.Text,
},
isCollapsible: isCollapsibleField,
startCollapsed,
accentColor,
primaryTextColor,
secondaryTextColor,
Expand All @@ -64,11 +89,16 @@ 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";
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 +110,35 @@ 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;
}
.CoreSection__title--collapsed .CoreSection__title__collapser {
transform: rotate(180deg);
}
.CoreSection__title__collapser {
border: none;
border-radius: 16px;
padding: 4px;
background: var(--separatorColor);
display: flex;
align-items: center;
justify-content: center;
height: 24px;
width: 24px;
cursor: pointer;
}
.CoreSection__title__collapser {
transition: all 0.3s ease-in-out;
transform: rotate(0deg);
}
</style>
11 changes: 3 additions & 8 deletions src/ui/src/components/core/layout/CoreSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
buttonTextColor,
buttonShadow,
cssClasses,
startCollapsed,
} from "@/renderer/sharedStyleFields";
const description =
Expand All @@ -49,14 +50,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 Down
55 changes: 39 additions & 16 deletions src/ui/src/renderer/sharedStyleFields.ts
Original file line number Diff line number Diff line change
@@ -1,108 +1,131 @@
import { FieldCategory, FieldType } from "@/writerTypes";
import {
FieldCategory,
FieldType,
WriterComponentDefinitionField,
} from "@/writerTypes";

export const accentColor = {
export const accentColor: WriterComponentDefinitionField = {
name: "Accent",
type: FieldType.Color,
category: FieldCategory.Style,
applyStyleVariable: true,
};

export const primaryTextColor = {
export const primaryTextColor: WriterComponentDefinitionField = {
name: "Primary text",
type: FieldType.Color,
category: FieldCategory.Style,
applyStyleVariable: true,
};

export const secondaryTextColor = {
export const secondaryTextColor: WriterComponentDefinitionField = {
name: "Secondary text",
type: FieldType.Color,
category: FieldCategory.Style,
applyStyleVariable: true,
};

export const emptinessColor = {
export const emptinessColor: WriterComponentDefinitionField = {
name: "Emptiness",
desc: "Page background color",
type: FieldType.Color,
category: FieldCategory.Style,
applyStyleVariable: true,
};

export const containerBackgroundColor = {
export const containerBackgroundColor: WriterComponentDefinitionField = {
name: "Container background",
type: FieldType.Color,
category: FieldCategory.Style,
applyStyleVariable: true,
};

export const containerShadow = {
export const containerShadow: WriterComponentDefinitionField = {
name: "Container shadow",
type: FieldType.Shadow,
category: FieldCategory.Style,
applyStyleVariable: true,
};

export const separatorColor = {
export const separatorColor: WriterComponentDefinitionField = {
name: "Separator",
type: FieldType.Color,
category: FieldCategory.Style,
applyStyleVariable: true,
};

export const buttonColor = {
export const buttonColor: WriterComponentDefinitionField = {
name: "Button",
type: FieldType.Color,
category: FieldCategory.Style,
applyStyleVariable: true,
};

export const buttonTextColor = {
export const buttonTextColor: WriterComponentDefinitionField = {
name: "Button text",
type: FieldType.Color,
category: FieldCategory.Style,
applyStyleVariable: true,
};

export const buttonShadow = {
export const buttonShadow: WriterComponentDefinitionField = {
name: "Button shadow",
type: FieldType.Shadow,
category: FieldCategory.Style,
applyStyleVariable: true,
};

export const cssClasses = {
export const cssClasses: WriterComponentDefinitionField = {
name: "Custom CSS classes",
type: FieldType.Text,
category: FieldCategory.Style,
desc: "CSS classes, separated by spaces. You can define classes in custom stylesheets.",
};

export const contentWidth = {
export const contentWidth: WriterComponentDefinitionField = {
name: "Content width",
type: FieldType.Width,
default: "100%",
category: FieldCategory.Style,
desc: "Configure content width using CSS units, e.g. 100px, 50%, 10vw, etc.",
};

export const contentHAlign = {
export const contentHAlign: WriterComponentDefinitionField = {
name: "Content alignment (H)",
type: FieldType.HAlign,
default: "unset",
category: FieldCategory.Style,
};

export const contentVAlign = {
export const contentVAlign: WriterComponentDefinitionField = {
name: "Content alignment (V)",
type: FieldType.VAlign,
default: "unset",
category: FieldCategory.Style,
};

export const contentPadding = {
export const contentPadding: WriterComponentDefinitionField = {
name: "Padding",
type: FieldType.Padding,
default: "0",
category: FieldCategory.Style,
};

const yesNoOptions = { yes: "Yes", no: "No" };

export const isCollapsible: WriterComponentDefinitionField = {
name: "Collapsible",
default: "no",
type: FieldType.Text,
options: yesNoOptions,
category: FieldCategory.Style,
};

export const startCollapsed: WriterComponentDefinitionField = {
name: "Start collapsed",
type: FieldType.Text,
category: FieldCategory.Style,
default: "no",
options: yesNoOptions,
desc: "Only applied when the component is collapsible.",
};
Loading

0 comments on commit cc146fe

Please sign in to comment.