refactor(vue): use test id helper for dynamic attrs
This commit is contained in:
parent
cb1c52521b
commit
50a4e1bf93
|
|
@ -19,7 +19,7 @@ import {
|
|||
|
||||
import IconChevronRight from '~icons/lucide/chevron-right'
|
||||
|
||||
import { useI18n } from '@open-pencil/vue'
|
||||
import { testId as testIdAttr, useI18n } from '@open-pencil/vue'
|
||||
import { useMenuUI } from '@/components/ui/menu'
|
||||
import { IS_TAURI } from '@/constants'
|
||||
import { useAppMenu } from '@/app/shell/menu/app-menu'
|
||||
|
|
@ -91,7 +91,7 @@ const subMenuCls = useMenuUI({ content: 'min-w-44' })
|
|||
<MenubarRoot class="scrollbar-none flex items-center gap-0.5 overflow-x-auto">
|
||||
<MenubarMenu v-for="menu in topMenus" :key="menu.label">
|
||||
<MenubarTrigger
|
||||
:data-test-id="`menubar-${menu.label.toLowerCase()}`"
|
||||
v-bind="testIdAttr(`menubar-${menu.label.toLowerCase()}`)"
|
||||
class="flex cursor-pointer items-center rounded px-2 py-1 text-xs text-muted transition-colors select-none hover:bg-hover hover:text-surface data-[state=open]:bg-hover data-[state=open]:text-surface"
|
||||
>
|
||||
{{ menu.label }}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,13 @@ import {
|
|||
ContextMenuSubContent,
|
||||
ContextMenuPortal
|
||||
} from 'reka-ui'
|
||||
import { useEditorCommands, useI18n, useMenuModel, useSelectionState } from '@open-pencil/vue'
|
||||
import {
|
||||
testId as testIdAttr,
|
||||
useEditorCommands,
|
||||
useI18n,
|
||||
useMenuModel,
|
||||
useSelectionState
|
||||
} from '@open-pencil/vue'
|
||||
|
||||
import { useEditorStore } from '@/app/editor/active-store'
|
||||
import { createCanvasMenuActions } from '@/app/editor/canvas/menu-actions'
|
||||
|
|
@ -120,7 +126,7 @@ const contextCommandTestIds: Record<string, string> = {
|
|||
</ContextMenuSub>
|
||||
<ContextMenuItem
|
||||
v-else
|
||||
:data-test-id="item.id ? contextCommandTestIds[item.id] : undefined"
|
||||
v-bind="testIdAttr(item.id ? contextCommandTestIds[item.id] : undefined)"
|
||||
:class="canvasMenuItemClass(item.label, cls)"
|
||||
:disabled="item.disabled"
|
||||
@select="item.action?.()"
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
<script setup lang="ts">
|
||||
import { useAttrs } from 'vue'
|
||||
import { ScrubInputRoot, ScrubInputField, ScrubInputDisplay } from '@open-pencil/vue'
|
||||
import { computed, useAttrs } from 'vue'
|
||||
import { ScrubInputRoot, ScrubInputField, ScrubInputDisplay, testId } from '@open-pencil/vue'
|
||||
import { useEditorStore } from '@/app/editor/active-store'
|
||||
|
||||
const attrs = useAttrs()
|
||||
|
||||
const store = useEditorStore()
|
||||
|
||||
const rootTestId = computed(() => (attrs['data-test-id'] as string | undefined) ?? 'scrub-input')
|
||||
|
||||
const { modelValue, min, max, step, icon, label, suffix, sensitivity, placeholder } = defineProps<{
|
||||
modelValue: number | symbol
|
||||
min?: number
|
||||
|
|
@ -47,8 +49,7 @@ defineOptions({ inheritAttrs: false })
|
|||
"
|
||||
>
|
||||
<div
|
||||
v-bind="attrs"
|
||||
:data-test-id="(attrs['data-test-id'] as string | undefined) ?? 'scrub-input'"
|
||||
v-bind="{ ...attrs, ...testId(rootTestId) }"
|
||||
:tabindex="editing ? undefined : 0"
|
||||
:class="[
|
||||
attrs.class,
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import IconChevronDown from '~icons/lucide/chevron-down'
|
|||
|
||||
import { menu } from '@/components/ui/menu'
|
||||
import ToolButton from '@/components/Toolbar/ToolButton.vue'
|
||||
import { ToolbarItem } from '@open-pencil/vue'
|
||||
import { testId as testIdAttr, ToolbarItem } from '@open-pencil/vue'
|
||||
|
||||
import type { Tool } from '@open-pencil/vue'
|
||||
import type { EditorToolDef } from '@open-pencil/core/editor'
|
||||
|
|
@ -69,7 +69,7 @@ function activeKeyForTool() {
|
|||
<DropdownMenuRoot>
|
||||
<DropdownMenuTrigger as-child>
|
||||
<button
|
||||
:data-test-id="`${mobile ? 'mobile-' : ''}toolbar-flyout-${tool.key.toLowerCase()}`"
|
||||
v-bind="testIdAttr(`${mobile ? 'mobile-' : ''}toolbar-flyout-${tool.key.toLowerCase()}`)"
|
||||
class="flex h-8 w-3 cursor-pointer items-center justify-center border-none transition-colors"
|
||||
:class="[
|
||||
mobile ? 'rounded-[6px] select-none' : 'rounded-lg',
|
||||
|
|
@ -93,7 +93,7 @@ function activeKeyForTool() {
|
|||
:tool="sub"
|
||||
>
|
||||
<DropdownMenuItem
|
||||
:data-test-id="`${mobile ? 'mobile-' : ''}toolbar-flyout-item-${sub.toLowerCase()}`"
|
||||
v-bind="testIdAttr(`${mobile ? 'mobile-' : ''}toolbar-flyout-item-${sub.toLowerCase()}`)"
|
||||
:class="menu().item({ class: subActive ? 'bg-accent text-white' : undefined })"
|
||||
@select="actions.select"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { testId as testIdAttr } from '@open-pencil/vue'
|
||||
|
||||
import type { ToolbarActionItem } from '@/components/Toolbar/types'
|
||||
|
||||
const { actions, testPrefix } = defineProps<{
|
||||
|
|
@ -15,7 +17,7 @@ const emit = defineEmits<{
|
|||
<button
|
||||
v-for="item in actions"
|
||||
:key="item.label"
|
||||
:data-test-id="`${testPrefix}-${item.label.toLowerCase()}`"
|
||||
v-bind="testIdAttr(`${testPrefix}-${item.label.toLowerCase()}`)"
|
||||
class="flex size-8 cursor-pointer items-center justify-center rounded-[6px] border-none bg-transparent text-muted transition-colors select-none active:bg-hover active:text-surface"
|
||||
@click="emit('action', item)"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ import {
|
|||
} from 'reka-ui'
|
||||
import { FlexRender } from '@tanstack/vue-table'
|
||||
|
||||
import { useI18n, useVariablesEditor } from '@open-pencil/vue'
|
||||
import { testId as testIdAttr, useI18n, useVariablesEditor } from '@open-pencil/vue'
|
||||
|
||||
import IconHash from '~icons/lucide/hash'
|
||||
import IconPalette from '~icons/lucide/palette'
|
||||
|
|
@ -390,7 +390,7 @@ function modeId(columnId: string): string {
|
|||
v-for="item in variableTypes"
|
||||
:key="item.type"
|
||||
:class="menuCls.item"
|
||||
:data-test-id="`variables-add-${item.type.toLowerCase()}`"
|
||||
v-bind="testIdAttr(`variables-add-${item.type.toLowerCase()}`)"
|
||||
@select="ctx.addVariable(item.type)"
|
||||
>
|
||||
<component :is="variableTypeIcons[item.type]" :class="menuCls.icon" />
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import {
|
|||
AlertDialogTitle
|
||||
} from 'reka-ui'
|
||||
import { computed } from 'vue'
|
||||
import { testId as testIdAttr } from '@open-pencil/vue'
|
||||
|
||||
import {
|
||||
currentPermission,
|
||||
|
|
@ -85,7 +86,7 @@ function handleDismiss() {
|
|||
<AlertDialogAction
|
||||
v-for="opt in allowOptions"
|
||||
:key="opt.optionId"
|
||||
:data-test-id="`acp-permission-option-${opt.kind}`"
|
||||
v-bind="testIdAttr(`acp-permission-option-${opt.kind}`)"
|
||||
class="w-full rounded bg-accent px-3 py-1.5 text-xs font-medium text-white hover:bg-accent/90"
|
||||
@click="respondToPermission(opt.optionId)"
|
||||
>
|
||||
|
|
@ -95,7 +96,7 @@ function handleDismiss() {
|
|||
<AlertDialogCancel
|
||||
v-for="opt in rejectOptions"
|
||||
:key="opt.optionId"
|
||||
:data-test-id="`acp-permission-option-${opt.kind}`"
|
||||
v-bind="testIdAttr(`acp-permission-option-${opt.kind}`)"
|
||||
class="w-full rounded border border-border bg-canvas px-3 py-1.5 text-xs text-muted hover:bg-hover hover:text-surface"
|
||||
@click="respondToPermission(opt.optionId)"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
import { isTextUIPart, isToolUIPart, getToolName } from 'ai'
|
||||
import { CollapsibleContent, CollapsibleRoot, CollapsibleTrigger } from 'reka-ui'
|
||||
import { Markdown } from 'vue-stream-markdown'
|
||||
import { testId as testIdAttr } from '@open-pencil/vue'
|
||||
import 'vue-stream-markdown/index.css'
|
||||
|
||||
import type { UIDataTypes, UIMessage, UIMessagePart, UITools } from 'ai'
|
||||
|
|
@ -40,7 +41,7 @@ function partKey(part: UIMessagePart<UIDataTypes, UITools>, index: number): stri
|
|||
|
||||
<template>
|
||||
<div
|
||||
:data-test-id="`chat-message-${message.role}`"
|
||||
v-bind="testIdAttr(`chat-message-${message.role}`)"
|
||||
:class="message.role === 'user' ? 'flex justify-end' : ''"
|
||||
>
|
||||
<div class="min-w-0 space-y-1.5" :class="message.role === 'user' ? 'max-w-[85%]' : ''">
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import BoundVariableButton from '@/components/properties/BoundVariableButton.vue
|
|||
import VariablePickerPopover from '@/components/properties/VariablePickerPopover.vue'
|
||||
import { useIconButtonUI } from '@/components/ui/icon-button'
|
||||
|
||||
import { useI18n } from '@open-pencil/vue'
|
||||
import { testId as testIdAttr, useI18n } from '@open-pencil/vue'
|
||||
|
||||
import {
|
||||
opacityFromPercent,
|
||||
|
|
@ -99,7 +99,7 @@ const { panels, dialogs } = useI18n()
|
|||
/>
|
||||
|
||||
<button
|
||||
:data-test-id="visibilityTestId"
|
||||
v-bind="testIdAttr(visibilityTestId)"
|
||||
:data-visible="item.visible ? 'true' : 'false'"
|
||||
class="shrink-0 cursor-pointer border-none bg-transparent p-0 text-muted hover:text-surface"
|
||||
@click="emit('toggleVisibility')"
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import ColorInput from '@/components/ColorPicker/ColorInput.vue'
|
|||
import ScrubInput from '@/components/ScrubInput.vue'
|
||||
import { useIconButtonUI } from '@/components/ui/icon-button'
|
||||
import { useSectionUI } from '@/components/ui/section'
|
||||
import { PropertyListRoot, useEffectsControls, useI18n } from '@open-pencil/vue'
|
||||
import { PropertyListRoot, testId as testIdAttr, useEffectsControls, useI18n } from '@open-pencil/vue'
|
||||
|
||||
import { colorToCSS } from '@open-pencil/core/color'
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ const sectionCls = useSectionUI()
|
|||
/>
|
||||
|
||||
<button
|
||||
:data-test-id="`effect-visibility-${i}`"
|
||||
v-bind="testIdAttr(`effect-visibility-${i}`)"
|
||||
:data-visible="effect.visible ? 'true' : 'false'"
|
||||
class="cursor-pointer border-none bg-transparent p-0 text-muted hover:text-surface"
|
||||
@click="actions.toggleVisibility(i)"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import Tip from '@/components/ui/Tip.vue'
|
||||
import { useI18n, useLayoutControlsContext } from '@open-pencil/vue'
|
||||
import { testId as testIdAttr, useI18n, useLayoutControlsContext } from '@open-pencil/vue'
|
||||
|
||||
import type { LayoutMode } from '@open-pencil/core/scene-graph'
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ const layoutModes: { mode: LayoutMode; test: string }[] = [
|
|||
<button
|
||||
v-for="dir in layoutModes"
|
||||
:key="dir.mode"
|
||||
:data-test-id="`layout-direction-${dir.test}`"
|
||||
v-bind="testIdAttr(`layout-direction-${dir.test}`)"
|
||||
class="flex cursor-pointer items-center justify-center rounded border px-2 py-1"
|
||||
:class="
|
||||
(dir.mode === 'GRID' ? ctx.isGrid : ctx.node.layoutMode === dir.mode)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,12 @@ import VariableScrubInput from '@/components/properties/VariableScrubInput.vue'
|
|||
import BoundVariableButton from '@/components/properties/BoundVariableButton.vue'
|
||||
import VariablePickerPopover from '@/components/properties/VariablePickerPopover.vue'
|
||||
import { useSelectUI } from '@/components/ui/select'
|
||||
import { useI18n, useLayoutControlsContext, useNumberVariableBinding } from '@open-pencil/vue'
|
||||
import {
|
||||
testId as testIdAttr,
|
||||
useI18n,
|
||||
useLayoutControlsContext,
|
||||
useNumberVariableBinding
|
||||
} from '@open-pencil/vue'
|
||||
|
||||
import type { LayoutSizing } from '@open-pencil/core/scene-graph'
|
||||
import type { SizeLimitProp, TestId } from '@open-pencil/vue'
|
||||
|
|
@ -341,7 +346,7 @@ function handleSizeSelect(axis: 'width' | 'height', value: SizeSelectValue) {
|
|||
<div :ref="limitFieldRefs.set" class="min-w-0">
|
||||
<VariableScrubInput
|
||||
v-if="ctx.node"
|
||||
:data-test-id="item.testId"
|
||||
v-bind="testIdAttr(item.testId)"
|
||||
:icon="item.icon()"
|
||||
:model-value="Math.round(item.value() ?? 0)"
|
||||
:min="0"
|
||||
|
|
@ -356,7 +361,7 @@ function handleSizeSelect(axis: 'width' | 'height', value: SizeSelectValue) {
|
|||
@update:model-value="(value) => handleLimitSelect(item.prop, value as string)"
|
||||
>
|
||||
<SelectTrigger
|
||||
:data-test-id="`${item.testId}-menu`"
|
||||
v-bind="testIdAttr(`${item.testId}-menu`)"
|
||||
:reference="limitFieldAnchor(index)"
|
||||
class="flex shrink-0 cursor-pointer items-center self-stretch border-none bg-transparent px-1 text-[11px] text-muted outline-none"
|
||||
@pointerdown.stop
|
||||
|
|
@ -385,7 +390,7 @@ function handleSizeSelect(axis: 'width' | 'height', value: SizeSelectValue) {
|
|||
</VariableScrubInput>
|
||||
<ScrubInput
|
||||
v-else
|
||||
:data-test-id="item.testId"
|
||||
v-bind="testIdAttr(item.testId)"
|
||||
:icon="item.icon()"
|
||||
:model-value="Math.round(item.value() ?? 0)"
|
||||
:min="0"
|
||||
|
|
@ -398,7 +403,7 @@ function handleSizeSelect(axis: 'width' | 'height', value: SizeSelectValue) {
|
|||
@update:model-value="(value) => handleLimitSelect(item.prop, value as string)"
|
||||
>
|
||||
<SelectTrigger
|
||||
:data-test-id="`${item.testId}-menu`"
|
||||
v-bind="testIdAttr(`${item.testId}-menu`)"
|
||||
:reference="limitFieldAnchor(index)"
|
||||
class="flex shrink-0 cursor-pointer items-center self-stretch border-none bg-transparent px-1 text-[11px] text-muted outline-none"
|
||||
@pointerdown.stop
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ import {
|
|||
|
||||
import { computed, nextTick, ref, watch } from 'vue'
|
||||
|
||||
import { testId as testIdAttr } from '@open-pencil/vue'
|
||||
|
||||
import type { Variable } from '@open-pencil/core/scene-graph'
|
||||
|
||||
const searchTerm = defineModel<string>('searchTerm', { default: '' })
|
||||
|
|
@ -77,7 +79,7 @@ function submitCreate() {
|
|||
<template>
|
||||
<PopoverRoot v-model:open="open">
|
||||
<PopoverTrigger
|
||||
:data-test-id="triggerTestId"
|
||||
v-bind="testIdAttr(triggerTestId)"
|
||||
:aria-label="triggerLabel"
|
||||
:title="triggerLabel"
|
||||
class="shrink-0 cursor-pointer border-none bg-transparent p-0 text-muted hover:text-surface"
|
||||
|
|
@ -144,7 +146,7 @@ function submitCreate() {
|
|||
class="min-w-0 flex-1 rounded border border-border bg-transparent px-1.5 py-1 text-[11px] text-surface outline-none placeholder:text-muted focus:border-accent"
|
||||
/>
|
||||
<button
|
||||
:data-test-id="createTestId"
|
||||
v-bind="testIdAttr(createTestId)"
|
||||
:disabled="!canCreate"
|
||||
class="rounded border border-border bg-panel px-1.5 py-1 text-[11px] text-surface hover:bg-hover disabled:cursor-not-allowed disabled:opacity-50"
|
||||
type="submit"
|
||||
|
|
@ -154,7 +156,7 @@ function submitCreate() {
|
|||
</form>
|
||||
<button
|
||||
v-else
|
||||
:data-test-id="createTestId"
|
||||
v-bind="testIdAttr(createTestId)"
|
||||
class="flex w-full cursor-pointer items-center gap-1.5 bg-transparent px-2 py-1.5 text-left text-[11px] text-muted hover:bg-hover hover:text-surface"
|
||||
@click="startCreate"
|
||||
>
|
||||
|
|
|
|||
Loading…
Reference in a new issue