mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-08-04 13:30:48 +00:00
CSS editor layout fixes and scrolling
Major CSS improvements to layout at small screen sizes. By adding min-width: 0 and min-height: 0 on the nested display: flex structure, widgets no longer coerce the whole layout into large-scale resizing. Scrollbars are now used to allow correct overflowing of the tab bar (fixes #177), Document Panel options bar, and tool shelf. Improvements to responsive resizing are also included for viewing the UI correctly on mobile now. Additional small fixes to styling of widget colors and corner roundness. The ruler has been darkened one shade to improve text contrast and aesthetics.
This commit is contained in:
parent
9904021744
commit
54590d594a
16 changed files with 105 additions and 20 deletions
|
@ -70,6 +70,7 @@ body,
|
|||
height: 100%;
|
||||
background: var(--color-2-mildblack);
|
||||
user-select: none;
|
||||
overscroll-behavior: none;
|
||||
}
|
||||
|
||||
html,
|
||||
|
@ -78,6 +79,7 @@ input,
|
|||
textarea,
|
||||
button {
|
||||
font-family: "Source Sans Pro", Arial, sans-serif;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
line-height: 1;
|
||||
color: var(--color-e-nearwhite);
|
||||
|
@ -104,10 +106,12 @@ img {
|
|||
// WebKit
|
||||
&::-webkit-scrollbar {
|
||||
width: calc(2px + 6px + 2px);
|
||||
height: calc(2px + 6px + 2px);
|
||||
}
|
||||
|
||||
&:not(:hover)::-webkit-scrollbar {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
|
||||
.spacer {
|
||||
flex: 1 1 100%;
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-grow: 1;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
|
||||
.spacer {
|
||||
flex: 1 1 100%;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<LayoutCol :class="'document'">
|
||||
<LayoutRow :class="'options-bar'">
|
||||
<LayoutRow :class="'options-bar scrollable-x'">
|
||||
<div class="left side">
|
||||
<DropdownInput :menuEntries="documentModeEntries" v-model:selectedIndex="documentModeSelectionIndex" :drawIcon="true" />
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
|||
|
||||
<Separator :type="SeparatorType.Unrelated" />
|
||||
|
||||
<RadioInput :entries="viewModeEntries" v-model:selectedIndex="viewModeIndex" />
|
||||
<RadioInput :entries="viewModeEntries" v-model:selectedIndex="viewModeIndex" class="combined-after" />
|
||||
<PopoverButton>
|
||||
<h3>View Mode</h3>
|
||||
<p>The contents of this popover menu are coming soon</p>
|
||||
|
@ -42,7 +42,7 @@
|
|||
|
||||
<Separator :type="SeparatorType.Section" />
|
||||
|
||||
<NumberInput @update:value="setRotation" v-model:value="documentRotation" :incrementFactor="15" :unit="`°`" ref="rotation" />
|
||||
<NumberInput @update:value="setRotation" v-model:value="documentRotation" :incrementFactor="15" :unit="`°`" />
|
||||
|
||||
<Separator :type="SeparatorType.Section" />
|
||||
|
||||
|
@ -68,7 +68,7 @@
|
|||
</LayoutRow>
|
||||
<LayoutRow :class="'shelf-and-viewport'">
|
||||
<LayoutCol :class="'shelf'">
|
||||
<div class="tools">
|
||||
<div class="tools scrollable-y">
|
||||
<ShelfItemInput icon="LayoutSelectTool" title="Select Tool (V)" :active="activeTool === 'Select'" :action="() => selectTool('Select')" />
|
||||
<ShelfItemInput icon="LayoutCropTool" title="Crop Tool" :active="activeTool === 'Crop'" :action="() => comingSoon(289) && selectTool('Crop')" />
|
||||
<ShelfItemInput icon="LayoutNavigateTool" title="Navigate Tool (Z)" :active="activeTool === 'Navigate'" :action="() => comingSoon(155) && selectTool('Navigate')" />
|
||||
|
@ -163,6 +163,10 @@
|
|||
align-items: center;
|
||||
margin: 0 4px;
|
||||
}
|
||||
|
||||
.spacer {
|
||||
min-width: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.shelf-and-viewport {
|
||||
|
@ -171,7 +175,17 @@
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.tools {
|
||||
flex: 0 1 auto;
|
||||
}
|
||||
|
||||
.spacer {
|
||||
flex: 1 0 auto;
|
||||
min-height: 8px;
|
||||
}
|
||||
|
||||
.working-colors .swap-and-reset {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -132,6 +132,7 @@
|
|||
|
||||
.layer {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
align-items: center;
|
||||
border-radius: 2px;
|
||||
background: var(--color-5-dullgray);
|
||||
|
@ -150,6 +151,7 @@
|
|||
height: 100%;
|
||||
background: white;
|
||||
border-radius: 2px;
|
||||
flex: 0 0 auto;
|
||||
|
||||
svg {
|
||||
width: calc(100% - 4px);
|
||||
|
@ -161,6 +163,20 @@
|
|||
.layer-type-icon {
|
||||
margin-left: 8px;
|
||||
margin-right: 4px;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.layer-name {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
flex: 1 1 100%;
|
||||
margin-right: 8px;
|
||||
|
||||
span {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,10 @@
|
|||
border: none;
|
||||
border-radius: 2px;
|
||||
background: none;
|
||||
fill: var(--color-e-nearwhite);
|
||||
|
||||
svg {
|
||||
fill: var(--color-e-nearwhite);
|
||||
}
|
||||
|
||||
// The `where` pseudo-class does not contribtue to specificity
|
||||
& + :where(.icon-button) {
|
||||
|
@ -25,7 +28,10 @@
|
|||
&:hover {
|
||||
background: var(--color-6-lowergray);
|
||||
color: var(--color-f-white);
|
||||
fill: var(--color-f-white);
|
||||
|
||||
svg {
|
||||
fill: var(--color-f-white);
|
||||
}
|
||||
}
|
||||
|
||||
&.size-12 {
|
||||
|
|
|
@ -29,11 +29,16 @@
|
|||
flex-direction: row-reverse;
|
||||
|
||||
label {
|
||||
flex: 0 0 auto;
|
||||
cursor: text;
|
||||
flex: 1 1 100%;
|
||||
line-height: 18px;
|
||||
margin-left: 8px;
|
||||
padding: 3px 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
&:not(.disabled) label {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
input {
|
||||
|
@ -54,7 +59,6 @@
|
|||
|
||||
&:not(:focus).has-label {
|
||||
text-align: right;
|
||||
padding-left: 4px;
|
||||
margin-left: 0;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
|
|
@ -58,6 +58,11 @@
|
|||
.text-label {
|
||||
margin: 0 4px;
|
||||
}
|
||||
|
||||
&.combined-before button:first-of-type,
|
||||
&.combined-after button:last-of-type {
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
line-height: 18px;
|
||||
|
||||
&.bold {
|
||||
font-weight: bold;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
&.italic {
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
.input-key {
|
||||
font-family: "Inconsolata", monospace;
|
||||
font-weight: 400;
|
||||
text-align: center;
|
||||
color: var(--color-e-nearwhite);
|
||||
border: 1px;
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<style lang="scss">
|
||||
.canvas-ruler {
|
||||
flex: 1 1 100%;
|
||||
background: var(--color-5-dullgray);
|
||||
background: var(--color-4-dimgray);
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
.plus {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-weight: bold;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.user-input-label + .user-input-label {
|
||||
|
|
|
@ -10,7 +10,10 @@
|
|||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 8px;
|
||||
fill: var(--color-e-nearwhite);
|
||||
|
||||
svg {
|
||||
fill: var(--color-e-nearwhite);
|
||||
}
|
||||
|
||||
.text-label {
|
||||
margin-right: 8px;
|
||||
|
@ -19,7 +22,10 @@
|
|||
&:hover {
|
||||
background: var(--color-6-lowergray);
|
||||
color: var(--color-f-white);
|
||||
fill: var(--color-f-white);
|
||||
|
||||
svg {
|
||||
fill: var(--color-f-white);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<template>
|
||||
<div class="panel">
|
||||
<div class="tab-bar" :class="{ 'min-widths': tabMinWidths }">
|
||||
<div class="tab-group">
|
||||
<div class="tab-group scrollable-x">
|
||||
<div
|
||||
class="tab"
|
||||
:class="{ active: tabIndex === tabActiveIndex }"
|
||||
v-for="(tabLabel, tabIndex) in tabLabels"
|
||||
:key="tabIndex"
|
||||
@click.middle="
|
||||
(e) => {
|
||||
(e) => {
|
||||
e.stopPropagation();
|
||||
closeDocumentWithConfirmation(tabIndex);
|
||||
}
|
||||
|
@ -63,7 +63,17 @@
|
|||
flex: 1 1 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
// This always hangs out at the end of the last tab, providing 16px (15px plus the 1px reserved for the separator line) to the right of the tabs.
|
||||
// When the last tab is selected, its bottom rounded fillet adds 16px to the width, which stretches the scrollbar width allocation in only that situation.
|
||||
// This pseudo-element ensures we always reserve that space to prevent the scrollbar from jumping when the last tab is selected.
|
||||
// There is unfortunately no apparent way to remove that 16px gap from the end of the scroll container, since negative margin does not reduce the scrollbar allocation.
|
||||
&::after {
|
||||
content: "";
|
||||
width: 15px;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.tab {
|
||||
height: 100%;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
:tabMinWidths="true"
|
||||
:tabLabels="documents.documents.map((doc) => doc.displayName)"
|
||||
:tabActiveIndex="documents.activeDocumentIndex"
|
||||
ref="documentsPanel"
|
||||
/>
|
||||
</LayoutCol>
|
||||
<LayoutCol class="workspace-grid-resize-gutter"></LayoutCol>
|
||||
|
@ -70,5 +71,20 @@ export default defineComponent({
|
|||
data() {
|
||||
return {};
|
||||
},
|
||||
computed: {
|
||||
activeDocumentIndex() {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
return (this as any).documents.activeDocumentIndex;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
activeDocumentIndex(newIndex: number) {
|
||||
this.$nextTick(() => {
|
||||
const documentsPanel = this.$refs.documentsPanel as typeof Panel;
|
||||
const newActiveTab = documentsPanel.$el.querySelectorAll(".tab-bar .tab-group .tab")[newIndex];
|
||||
newActiveTab.scrollIntoView();
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue