Rename and organize widget components to conform to design terminology (#132)

This commit is contained in:
Keavon Chambers
2021-05-21 13:10:32 -07:00
parent b9248b828c
commit 3b0762ef18
17 changed files with 251 additions and 220 deletions
@@ -0,0 +1,54 @@
<template>
<div class="menu-bar-input">
<div class="entry"><GraphiteLogo width="16" height="16" /></div>
<div class="entry"><span>File</span></div>
<div class="entry"><span>Edit</span></div>
<div class="entry"><span>Document</span></div>
<div class="entry"><span>View</span></div>
<div class="entry"><span>Help</span></div>
</div>
</template>
<style lang="scss">
.menu-bar-input {
display: flex;
.entry {
display: flex;
align-items: center;
white-space: nowrap;
padding: 0 8px;
svg {
fill: #ddd;
}
&:hover {
background: #666;
svg {
fill: #fff;
}
span {
color: #fff;
}
}
}
}
</style>
<script lang="ts">
import { defineComponent } from "vue";
import { ApplicationPlatform } from "../../window/MainWindow.vue";
import GraphiteLogo from "../../../../assets/svg/16x16-bounds-16x16-icon/graphite-logo.svg";
export default defineComponent({
components: { GraphiteLogo },
data() {
return {
ApplicationPlatform,
};
},
});
</script>
@@ -0,0 +1,102 @@
<template>
<div class="number-input">
<button class="arrow left"></button>
<button class="arrow right"></button>
<input type="text" spellcheck="false" value="25%" />
</div>
</template>
<style lang="scss">
.number-input {
width: 64px;
height: 24px;
position: relative;
border-radius: 2px;
background: #111;
overflow: hidden;
input {
width: calc(100% - 8px);
margin: 0 4px;
outline: none;
border: none;
background: none;
padding: 0;
line-height: 24px;
color: #ddd;
font-size: inherit;
text-align: center;
font-family: inherit;
&::selection {
background: #3194d6;
}
}
&:not(:hover) .arrow {
display: none;
}
.arrow {
position: absolute;
top: 0;
outline: none;
border: none;
background: none;
padding: 9px 0;
&:hover {
background: #666;
&.right::before {
border-color: transparent transparent transparent #fff;
}
&.left::after {
border-color: transparent #fff transparent transparent;
}
}
&.right {
right: 0;
padding-left: 7px;
padding-right: 6px;
&::before {
content: "";
width: 0;
height: 0;
border-style: solid;
border-width: 3px 0 3px 3px;
border-color: transparent transparent transparent #ddd;
display: block;
}
}
&.left {
left: 0;
padding-left: 6px;
padding-right: 7px;
&::after {
content: "";
width: 0;
height: 0;
border-style: solid;
border-width: 3px 3px 3px 0;
border-color: transparent #ddd transparent transparent;
display: block;
}
}
}
}
</style>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
components: {},
props: {},
});
</script>
@@ -0,0 +1,89 @@
<template>
<div class="radio-input" ref="radioInput">
<slot></slot>
</div>
</template>
<style lang="scss">
.radio-input {
.popover-button button {
border-radius: 0;
}
& > * {
border-radius: 0;
margin: 0;
&:first-child,
&:first-child button {
border-radius: 2px 0 0 2px;
}
&:last-child,
&:last-child button {
border-radius: 0 2px 2px 0;
}
& + * {
margin-left: 1px;
}
}
button {
background: #555;
fill: #ddd;
&:hover {
background: #666;
}
&.active {
background: #3194d6;
fill: #fff;
}
}
}
</style>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
components: {},
props: {
initialIndex: { type: Number, required: true },
setIndex: { type: Function, required: false },
},
data() {
return {
activeIndex: this.initialIndex,
};
},
mounted() {
this.updateActiveIconButton();
(this.$refs.radioInput as Element).querySelectorAll(".icon-button").forEach((iconButton, index) => {
iconButton.addEventListener("click", () => {
this.activeIndex = index;
this.$emit("changed", index);
});
});
},
watch: {
activeIndex() {
this.updateActiveIconButton();
},
},
methods: {
// This method may be called by the user of this component by setting a `ref="radioInput"` attribute and calling `(this.$refs.viewModePicker as typeof RadioInput).setActive(...)`
setActive(index: number) {
this.activeIndex = index;
},
updateActiveIconButton() {
const iconButtons = (this.$refs.radioInput as Element).querySelectorAll(".icon-button");
iconButtons.forEach((iconButton) => iconButton.classList.remove("active"));
iconButtons[this.activeIndex].classList.add("active");
},
},
});
</script>
@@ -0,0 +1,81 @@
<template>
<div class="swatch-pair">
<div class="secondary swatch">
<button @click="clickSecondarySwatch" style="background: white"></button>
<Popover :direction="PopoverDirection.Right" horizontal ref="secondarySwatchPopover">
<ColorPicker />
</Popover>
</div>
<div class="primary swatch">
<button @click="clickPrimarySwatch" style="background: black"></button>
<Popover :direction="PopoverDirection.Right" horizontal ref="primarySwatchPopover">
<ColorPicker />
</Popover>
</div>
</div>
</template>
<style lang="scss">
.swatch-pair {
display: flex;
// Reversed order of elements paired with `column-reverse` allows primary to overlap secondary without relying on `z-index`
flex-direction: column-reverse;
.swatch {
width: 28px;
height: 28px;
margin: 2px;
position: relative;
button {
width: 100%;
height: 100%;
border-radius: 50%;
border: 2px #888 solid;
box-shadow: 0 0 0 2px #333;
margin: 0;
padding: 0;
box-sizing: border-box;
outline: none;
}
.popover {
top: 50%;
right: -2px;
}
&.primary {
margin-bottom: -8px;
}
}
}
</style>
<script lang="ts">
import { defineComponent } from "vue";
import ColorPicker from "../../popovers/ColorPicker.vue";
import Popover, { PopoverDirection } from "../overlays/Popover.vue";
export default defineComponent({
components: {
Popover,
ColorPicker,
},
props: {},
methods: {
clickPrimarySwatch() {
(this.$refs.primarySwatchPopover as typeof Popover).setOpen();
(this.$refs.secondarySwatchPopover as typeof Popover).setClosed();
},
clickSecondarySwatch() {
(this.$refs.secondarySwatchPopover as typeof Popover).setOpen();
(this.$refs.primarySwatchPopover as typeof Popover).setClosed();
},
},
data() {
return {
PopoverDirection,
};
},
});
</script>