Repository: GraphiteEditor/Graphite
File: frontend/src/components/widgets/options/ToolOptions.vue (Vue)

Code before:
<template>
	<div class="tool-options">
		<template v-for="(option, index) in toolOptions[activeTool] || []" :key="index">
			<!-- TODO: Use `<component :is="" v-bind="attributesObject"></component>` to avoid all the separate components with `v-if` -->
			<IconButton v-if="option.kind === 'IconButton'" :action="() => handleIconButtonAction(option)" :title="option.tooltip" v-bind="option.props" />
			<PopoverButton v-if="option.kind === 'PopoverButton'" :title="option.tooltip" :action="option.callback" v-bind="option.props">
				<h3>{{ option.popover.title }}</h3>
				<p>{{ option.popover.text }}</p>
			</PopoverButton>
			<NumberInput
				v-if="option.kind === 'NumberInput'"
				@update:value="(value) => updateToolOptions(option.path, value)"
				:title="option.tooltip"
				v-bind="{ ...option.props, value: getToolOption(option.path) }"
			/>
			<Separator v-if="option.kind === 'Separator'" v-bind="option.props" />
		</template>
	</div>
</template>

<style lang="scss">
.tool-options {
	height: 100%;
	flex: 0 0 auto;
	display: flex;
	align-items: center;
}
</style>

<script lang="ts">
import { defineComponent } from "vue";

import { comingSoon } from "@/utilities/errors";
import { WidgetRow, SeparatorType, IconButtonWidget } from "@/components/widgets/widgets";

import Separator from "@/components/widgets/separators/Separator.vue";
import IconButton from "@/components/widgets/buttons/IconButton.vue";
import PopoverButton from "@/components/widgets/buttons/PopoverButton.vue";
import NumberInput from "@/components/widgets/inputs/NumberInput.vue";

Review comment (suggestion):
Since you changed the `NumberInputWidget` definition to `props: Omit<NumberInputProps, "value">;`, doesn't that mean we'll never receive an `option.props` containing a `value` property? If you agree with that logic, I think it would be clearer to separate this into two attributes: `:value="getToolOption(option.path)"` and `v-bind="option.props"`.

Code after:
<template>
	<div class="tool-options">
		<template v-for="(option, index) in toolOptionsWidgets[activeTool] || []" :key="index">
			<!-- TODO: Use `<component :is="" v-bind="attributesObject"></component>` to avoid all the separate components with `v-if` -->
			<IconButton v-if="option.kind === 'IconButton'" :action="() => handleIconButtonAction(option)" :title="option.tooltip" v-bind="option.props" />
			<PopoverButton v-if="option.kind === 'PopoverButton'" :title="option.tooltip" :action="option.callback" v-bind="option.props">
				<h3>{{ option.popover.title }}</h3>
				<p>{{ option.popover.text }}</p>
			</PopoverButton>
			<NumberInput
				v-if="option.kind === 'NumberInput'"
				@update:value="(value) => updateToolOptions(option.optionPath, value)"
				:title="option.tooltip"
				:value="getToolOption(option.optionPath)"
				v-bind="option.props"
			/>
			<Separator v-if="option.kind === 'Separator'" v-bind="option.props" />
		</template>
	</div>
</template>

<style lang="scss">
.tool-options {
	height: 100%;
	flex: 0 0 auto;
	display: flex;
	align-items: center;
}
</style>

<script lang="ts">
import { defineComponent, PropType } from "vue";

import { comingSoon } from "@/utilities/errors";
import { WidgetRow, SeparatorType, IconButtonWidget } from "@/components/widgets/widgets";

import Separator from "@/components/widgets/separators/Separator.vue";
import IconButton from "@/components/widgets/buttons/IconButton.vue";
import PopoverButton from "@/components/widgets/buttons/PopoverButton.vue";