-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat #128: first step towards responsive layout #132
Changes from all commits
9e93c81
2ce20de
73439d6
727072b
2bf64ff
432a027
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@getodk/web-forms": patch | ||
--- | ||
|
||
Responsive layout: Adjust Form header based on screen size (#128) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -88,3 +88,6 @@ | |
.icon-repeat:before { | ||
content: '\e914'; | ||
} | ||
.icon-menu:before { | ||
content: '\e916'; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
body { | ||
background: var(--gray-200); | ||
margin: 0; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,115 @@ | ||
<script setup lang="ts"> | ||
import Card from 'primevue/card'; | ||
defineProps<{title: string}>(); | ||
import { type FormLanguage, type RootNode, type SyntheticDefaultLanguage } from '@getodk/xforms-engine'; | ||
import PrimeButton from 'primevue/button'; | ||
import PrimeCard from 'primevue/card'; | ||
import PrimeMenu from 'primevue/menu'; | ||
import { ref } from 'vue'; | ||
import FormLanguageDialog from './FormLanguageDialog.vue'; | ||
import FormLanguageMenu from './FormLanguageMenu.vue'; | ||
|
||
const props = defineProps<{form: RootNode}>(); | ||
const languageDialogState = ref(false); | ||
const menu = ref<PrimeMenu>(); | ||
|
||
const isFormLanguage = (lang: FormLanguage | SyntheticDefaultLanguage) : lang is FormLanguage => { | ||
return !lang.isSyntheticDefault; | ||
} | ||
|
||
const languages = props.form.languages.filter(isFormLanguage); | ||
|
||
const print = () => window.print(); | ||
|
||
const items = ref([ | ||
{ | ||
label: 'Print', | ||
icon: 'icon-local_printshop', | ||
command: print | ||
} | ||
]); | ||
|
||
if(languages.length > 0){ | ||
items.value.unshift({ | ||
label: 'Change language', | ||
icon: 'icon-language', | ||
command: () => languageDialogState.value = true | ||
}) | ||
} | ||
|
||
const handleLanguageChange = (event: FormLanguage) => { | ||
props.form.setLanguage(event); | ||
}; | ||
</script> | ||
|
||
<template> | ||
<Card class="form-title"> | ||
<!-- for desktop --> | ||
<div class="hidden lg:flex justify-content-end flex-wrap gap-3 larger-screens"> | ||
<PrimeButton class="print-button" severity="secondary" rounded icon="icon-local_printshop" @click="print" /> | ||
<FormLanguageMenu | ||
:active-language="form.currentState.activeLanguage" | ||
:languages="languages" | ||
@update:active-language="handleLanguageChange" | ||
/> | ||
</div> | ||
<PrimeCard class="form-title hidden lg:block"> | ||
<template #content> | ||
<h1>{{ title }}</h1> | ||
<!-- TODO/q: should the title be on the definition or definition.form be accessible instead of definition.bind.form --> | ||
<h1>{{ form.definition.bind.form.title }}</h1> | ||
<!-- last saved timestamp --> | ||
</template> | ||
</Card> | ||
</PrimeCard> | ||
|
||
<!-- for mobile and tablet --> | ||
<div class="flex lg:hidden align-items-center smaller-screens"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was curious to see how wrapping looks for forms with long titles. Pretty good! I think we may want to iterate later on...
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good points, I am quoting these in #139 |
||
<h1 class="flex-grow-1"> | ||
{{ form.definition.bind.form.title }} | ||
</h1> | ||
|
||
<!-- for tablet --> | ||
<div class="form-options hidden md:flex justify-content-end gap-3"> | ||
<PrimeButton class="print-button" severity="secondary" rounded icon="icon-local_printshop" @click="print" /> | ||
<FormLanguageMenu | ||
:active-language="form.currentState.activeLanguage" | ||
:languages="languages" | ||
@update:active-language="handleLanguageChange" | ||
/> | ||
</div> | ||
|
||
<!-- for mobile --> | ||
<div class="form-options flex md:hidden"> | ||
<PrimeButton v-if="languages.length > 0" icon="icon-menu" class="btn-menu" text rounded aria-label="Menu" @click="menu?.toggle" /> | ||
<PrimeButton v-else class="print-button" severity="secondary" rounded icon="icon-local_printshop" @click="print" /> | ||
<PrimeMenu id="overlay_menu" ref="menu" :model="items" :popup="true" /> | ||
<FormLanguageDialog | ||
v-model:state="languageDialogState" | ||
:active-language="form.currentState.activeLanguage" | ||
:languages="languages" | ||
@update:active-language="handleLanguageChange" | ||
/> | ||
</div> | ||
</div> | ||
</template> | ||
|
||
<style scoped lang="scss"> | ||
.p-button.p-button-icon-only.p-button-rounded { | ||
height: 2.5rem; | ||
width: 2.5rem; | ||
min-width: 2.5rem; | ||
font-size: 1.5rem; | ||
|
||
&:hover{ | ||
background: var(--primary-100); | ||
} | ||
&:active, &:focus { | ||
background: var(--primary-50); | ||
} | ||
Comment on lines
+99
to
+104
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unclear where to put this comment, but this is where it's most visible: the hamburger menu looks great in its default state, but when these background colors are applied it shows the background all the way to the right edge of the viewport. This is a minor nitpick, but it feels a little unpolished and maybe worth a little finesse. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I had a discussion with Aly and she suggested to add equal spacing on the right side as there is on the left side, which is 10px. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now that you mention this, it caught my eye that quite a lot of measurements in the styles are in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's talk about this in Slack There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We talked about using |
||
} | ||
|
||
|
||
.form-title { | ||
// var(--light-elevation-1); | ||
|
||
border-radius: 10px; | ||
box-shadow: 0px 1px 3px 1px #00000026; | ||
box-shadow: var(--light-elevation-1); | ||
border-top: none; | ||
margin-top: 20px; | ||
|
||
|
@@ -28,4 +123,23 @@ defineProps<{title: string}>(); | |
} | ||
} | ||
} | ||
|
||
.smaller-screens { | ||
background-color: var(--surface-0); | ||
filter: drop-shadow(0px 2px 6px rgba(0, 0, 0, 0.15)) drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.30)) ; | ||
|
||
h1 { | ||
padding-left: 10px; | ||
font-size: 1.5rem; | ||
} | ||
|
||
.form-options{ | ||
padding-right: 10px; | ||
} | ||
|
||
.btn-menu{ | ||
color: var(--surface-900); | ||
} | ||
} | ||
|
||
</style> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also not something we need to act on right now (unless you want to explore it!): if we are sure we want to preserve the single-row presentation and condense horizontal space, this feels like a potentially excellent use case for container queries. Using it well for this might have other design implications (i.e. we'd need to know how much space is needed upfront before we can query it).
The nice thing about container queries here would be the possibility of triggering space-saving as needed, which might allow more functionality to stay visible for e.g. forms with shorter titles.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good suggestion. For now I have run with the existing media query, I will try to use it next time we have any changes in the UI of the Form header.