Reorganize Vue components and add documentation explaining each folder

This commit is contained in:
Keavon Chambers 2022-05-23 19:03:34 -07:00
parent 5650a87465
commit e4e37cca7b
23 changed files with 46 additions and 28 deletions

View file

@ -1,11 +1,25 @@
# Vue components
# Overview of `/frontend/src/components/`
Each component represents a (usually reusable) part of the Graphite Editor GUI. These all get mounted within the Vue entry point, `App.vue`, in the `/src` directory above this one.
Each component is a layout or widget in the GUI.
## Floating Menus: `floating-menus/`
The temporary UI areas with dark backgrounds which hover over the top of the editor window content. Examples include popovers, dropdown menu selectors, and dialog modals.
This document is a growing list of quick reference information for helpful Vue solutions and best practices. Feel free to add to this to help contributors learn things, or yourself remember tricks you'll likely forget in a few months.
## Layout: `layout/`
Useful containers that control the flow of content held within.
## Panels: `panels/`
The dockable tabbed regions like the Document, Properties, Layer Tree, and Node Graph panels.
## Widgets: `widgets/`
The interactive input items used to display information and provide user control.
## Window: `window/`
The building blocks for the Title Bar, Workspace, and Status Bar within an editor application window.
# Vue tips and tricks
This section contains a growing list of quick reference information for helpful Vue solutions and best practices. Feel free to add to this to help contributors learn things, or yourself remember tricks you'll likely forget in a few months.
## Bi-directional props
The component declares this:
```ts
export default defineComponent({

View file

@ -68,10 +68,10 @@
<script lang="ts">
import { defineComponent } from "vue";
import FloatingMenu from "@/components/floating-menus/FloatingMenu.vue";
import LayoutCol from "@/components/layout/LayoutCol.vue";
import LayoutRow from "@/components/layout/LayoutRow.vue";
import TextButton from "@/components/widgets/buttons/TextButton.vue";
import FloatingMenu from "@/components/widgets/floating-menus/FloatingMenu.vue";
import IconLabel from "@/components/widgets/labels/IconLabel.vue";
import WidgetLayout from "@/components/widgets/WidgetLayout.vue";

View file

@ -143,12 +143,12 @@ import { defineComponent, PropType } from "vue";
import { IconName } from "@/utility-functions/icons";
import FloatingMenu, { MenuDirection } from "@/components/floating-menus/FloatingMenu.vue";
import LayoutRow from "@/components/layout/LayoutRow.vue";
import FloatingMenu, { MenuDirection } from "@/components/widgets/floating-menus/FloatingMenu.vue";
import CheckboxInput from "@/components/widgets/inputs/CheckboxInput.vue";
import IconLabel from "@/components/widgets/labels/IconLabel.vue";
import Separator from "@/components/widgets/labels/Separator.vue";
import UserInputLabel from "@/components/widgets/labels/UserInputLabel.vue";
import Separator from "@/components/widgets/separators/Separator.vue";
export type MenuListEntries<Value = string> = MenuListEntry<Value>[];
export type SectionsOfMenuListEntries<Value = string> = MenuListEntries<Value>[];

View file

@ -244,8 +244,8 @@ import LayoutCol from "@/components/layout/LayoutCol.vue";
import LayoutRow from "@/components/layout/LayoutRow.vue";
import IconButton from "@/components/widgets/buttons/IconButton.vue";
import SwatchPairInput from "@/components/widgets/inputs/SwatchPairInput.vue";
import CanvasRuler from "@/components/widgets/rulers/CanvasRuler.vue";
import PersistentScrollbar from "@/components/widgets/scrollbars/PersistentScrollbar.vue";
import CanvasRuler from "@/components/widgets/metrics/CanvasRuler.vue";
import PersistentScrollbar from "@/components/widgets/metrics/PersistentScrollbar.vue";
import WidgetLayout from "@/components/widgets/WidgetLayout.vue";
export default defineComponent({

View file

@ -1,3 +1,5 @@
<!-- TODO: Refactor this component (together with `WidgetRow.vue`) to be more logically consistent with our layout definition goals, in terms of naming and capabilities -->
<template>
<div class="widget-layout">
<component :is="layoutRowType(layoutRow)" :widgetData="layoutRow" :layoutTarget="layout.layout_target" v-for="(layoutRow, index) in layout.layout" :key="index" />
@ -18,8 +20,8 @@ import { defineComponent, PropType } from "vue";
import { isWidgetColumn, isWidgetRow, isWidgetSection, LayoutRow, WidgetLayout } from "@/wasm-communication/messages";
import WidgetSection from "@/components/widgets/groups/WidgetSection.vue";
import WidgetRow from "@/components/widgets/WidgetRow.vue";
import WidgetSection from "@/components/widgets/WidgetSection.vue";
export default defineComponent({
props: {

View file

@ -1,7 +1,9 @@
<!-- TODO: Refactor this component to use `<component :is="" v-bind="attributesObject"></component>` to avoid all the separate components with `v-if` -->
<!-- TODO: Also rename this component, and probably move the `widget-${direction}` wrapper to be part of `WidgetLayout.vue` as part of its refactor -->
<template>
<div :class="`widget-${direction}`">
<template v-for="(component, index) in widgets" :key="index">
<!-- TODO: Use `<component :is="" v-bind="attributesObject"></component>` to avoid all the separate components with `v-if` -->
<CheckboxInput v-if="component.kind === 'CheckboxInput'" v-bind="component.props" @update:checked="(value: boolean) => updateLayout(component.widget_id, value)" />
<ColorInput v-if="component.kind === 'ColorInput'" v-bind="component.props" v-model:open="open" @update:value="(value: string) => updateLayout(component.widget_id, value)" />
<DropdownInput v-if="component.kind === 'DropdownInput'" v-bind="component.props" v-model:open="open" @update:selectedIndex="(value: number) => updateLayout(component.widget_id, value)" />
@ -85,8 +87,8 @@ import RadioInput from "@/components/widgets/inputs/RadioInput.vue";
import TextAreaInput from "@/components/widgets/inputs/TextAreaInput.vue";
import TextInput from "@/components/widgets/inputs/TextInput.vue";
import IconLabel from "@/components/widgets/labels/IconLabel.vue";
import Separator from "@/components/widgets/labels/Separator.vue";
import TextLabel from "@/components/widgets/labels/TextLabel.vue";
import Separator from "@/components/widgets/separators/Separator.vue";
export default defineComponent({
inject: ["editor"],

View file

@ -51,9 +51,9 @@ import { defineComponent, PropType } from "vue";
import { IconName } from "@/utility-functions/icons";
import FloatingMenu from "@/components/floating-menus/FloatingMenu.vue";
import LayoutRow from "@/components/layout/LayoutRow.vue";
import IconButton from "@/components/widgets/buttons/IconButton.vue";
import FloatingMenu from "@/components/widgets/floating-menus/FloatingMenu.vue";
export default defineComponent({
components: {

View file

@ -73,8 +73,8 @@ import { isWidgetRow, isWidgetSection, LayoutRow as LayoutSystemRow, WidgetSecti
import LayoutCol from "@/components/layout/LayoutCol.vue";
import LayoutRow from "@/components/layout/LayoutRow.vue";
import Separator from "@/components/widgets/labels/Separator.vue";
import TextLabel from "@/components/widgets/labels/TextLabel.vue";
import Separator from "@/components/widgets/separators/Separator.vue";
import WidgetRow from "@/components/widgets/WidgetRow.vue";
const WidgetSection = defineComponent({

View file

@ -72,12 +72,12 @@ import { defineComponent, PropType } from "vue";
import { RGBA } from "@/wasm-communication/messages";
import ColorPicker from "@/components/floating-menus/ColorPicker.vue";
import FloatingMenu from "@/components/floating-menus/FloatingMenu.vue";
import LayoutRow from "@/components/layout/LayoutRow.vue";
import ColorPicker from "@/components/widgets/floating-menus/ColorPicker.vue";
import FloatingMenu from "@/components/widgets/floating-menus/FloatingMenu.vue";
import OptionalInput from "@/components/widgets/inputs/OptionalInput.vue";
import TextInput from "@/components/widgets/inputs/TextInput.vue";
import Separator from "@/components/widgets/separators/Separator.vue";
import Separator from "@/components/widgets/labels/Separator.vue";
export default defineComponent({
emits: ["update:value", "update:open"],

View file

@ -87,8 +87,8 @@
<script lang="ts">
import { defineComponent, PropType, toRaw } from "vue";
import MenuList, { MenuListEntry, SectionsOfMenuListEntries } from "@/components/floating-menus/MenuList.vue";
import LayoutRow from "@/components/layout/LayoutRow.vue";
import MenuList, { MenuListEntry, SectionsOfMenuListEntries } from "@/components/widgets/floating-menus/MenuList.vue";
import IconLabel from "@/components/widgets/labels/IconLabel.vue";
const DASH_ENTRY = { label: "-" };

View file

@ -85,8 +85,8 @@
<script lang="ts">
import { defineComponent, PropType } from "vue";
import MenuList, { MenuListEntry, SectionsOfMenuListEntries } from "@/components/floating-menus/MenuList.vue";
import LayoutRow from "@/components/layout/LayoutRow.vue";
import MenuList, { MenuListEntry, SectionsOfMenuListEntries } from "@/components/widgets/floating-menus/MenuList.vue";
import IconLabel from "@/components/widgets/labels/IconLabel.vue";
export default defineComponent({

View file

@ -63,7 +63,7 @@ import { defineComponent } from "vue";
import { Editor } from "@/wasm-communication/editor";
import MenuList, { MenuListEntry, MenuListEntries } from "@/components/widgets/floating-menus/MenuList.vue";
import MenuList, { MenuListEntry, MenuListEntries } from "@/components/floating-menus/MenuList.vue";
import IconLabel from "@/components/widgets/labels/IconLabel.vue";
function makeEntries(editor: Editor): MenuListEntries {

View file

@ -71,10 +71,10 @@ import { defineComponent } from "vue";
import { rgbaToDecimalRgba } from "@/utility-functions/color";
import { type RGBA, UpdateWorkingColors } from "@/wasm-communication/messages";
import ColorPicker from "@/components/floating-menus/ColorPicker.vue";
import FloatingMenu from "@/components/floating-menus/FloatingMenu.vue";
import LayoutCol from "@/components/layout/LayoutCol.vue";
import LayoutRow from "@/components/layout/LayoutRow.vue";
import ColorPicker from "@/components/widgets/floating-menus/ColorPicker.vue";
import FloatingMenu from "@/components/widgets/floating-menus/FloatingMenu.vue";
export default defineComponent({
inject: ["editor"],

View file

@ -22,7 +22,7 @@ import { defineComponent } from "vue";
import LayoutCol from "@/components/layout/LayoutCol.vue";
import StatusBar from "@/components/window/status-bar/StatusBar.vue";
import TitleBar from "@/components/window/title-bar/TitleBar.vue";
import Workspace from "@/components/workspace/Workspace.vue";
import Workspace from "@/components/window/workspace/Workspace.vue";
export type ApplicationPlatform = "Windows" | "Mac" | "Linux" | "Web";

View file

@ -47,8 +47,8 @@ import { defineComponent } from "vue";
import { HintData, UpdateInputHints } from "@/wasm-communication/messages";
import LayoutRow from "@/components/layout/LayoutRow.vue";
import Separator from "@/components/widgets/labels/Separator.vue";
import UserInputLabel from "@/components/widgets/labels/UserInputLabel.vue";
import Separator from "@/components/widgets/separators/Separator.vue";
export default defineComponent({
inject: ["editor"],

View file

@ -66,10 +66,10 @@
<script lang="ts">
import { defineComponent } from "vue";
import DialogModal from "@/components/floating-menus/DialogModal.vue";
import LayoutCol from "@/components/layout/LayoutCol.vue";
import LayoutRow from "@/components/layout/LayoutRow.vue";
import DialogModal from "@/components/widgets/floating-menus/DialogModal.vue";
import Panel from "@/components/workspace/Panel.vue";
import Panel from "@/components/window/workspace/Panel.vue";
const MIN_PANEL_SIZE = 100;

View file

@ -1,7 +1,7 @@
import { type RGBA as RGBA_ } from "@/wasm-communication/messages";
import FloatingMenu from "@/components/widgets/floating-menus/FloatingMenu.vue";
import MenuList from "@/components/widgets/floating-menus/MenuList.vue";
import FloatingMenu from "@/components/floating-menus/FloatingMenu.vue";
import MenuList from "@/components/floating-menus/MenuList.vue";
// TODO: When a Volar bug is fixed (likely in v0.34.16):
// TODO: - Uncomment this block