IKHSAN
ENID Baca dalam Bahasa Indonesia

opendesk

Public
Branch
main
Latest commit
08d9f3328 October 2026

CommandPaletteRow.vue

Open raw
<template>
  <div
    class="flex h-9 w-full min-w-0 items-center rounded-4 px-2 text-sm text-ink-gray-8 leading-snug"
    :class="{ 'bg-surface-gray-2': active }"
  >
    <Avatar
      v-if="command.avatar"
      :image="command.avatar.image"
      :label="command.avatar.label"
      size="xs"
      class="me-2.5 shrink-0"
    />
    <!-- Boxed to the icon's 3.5 width, so a dot row's title lands on the same axis. -->
    <span
      v-else-if="command.dotClass"
      class="me-2.5 flex size-3.5 shrink-0 items-center justify-center"
    >
      <span class="size-2 rounded-full bg-current" :class="command.dotClass" />
    </span>
    <component
      :is="command.icon"
      v-else-if="command.icon"
      v-bind="command.iconProps"
      class="me-2.5 size-3.5 shrink-0"
      :class="active ? 'text-ink-gray-7' : 'text-ink-gray-5'"
    />

    <span
      class="min-w-0 flex-1 overflow-hidden text-ellipsis whitespace-nowrap"
    >
      <template v-for="(run, index) in runs" :key="index">
        <span v-if="run.match" class="font-medium text-ink-gray-9">{{
          run.text
        }}</span>
        <template v-else>{{ run.text }}</template>
      </template>
      <span v-if="command.titleSuffix" class="text-ink-gray-5">{{
        " " + command.titleSuffix
      }}</span>
    </span>

    <span v-if="command.subtitle" class="ms-3 shrink-0 text-xs text-ink-gray-4">
      {{ command.subtitle }}
    </span>
    <LucideCheck
      v-if="command.checked"
      class="ms-3 size-3.5 shrink-0 text-ink-gray-7"
    />
    <ShortcutKey
      v-if="command.hint"
      :keys="shortcutKeys"
      class="ms-3 shrink-0"
    />
    <LucideChevronRight
      v-if="command.children"
      class="ms-2 size-3.5 shrink-0 text-ink-gray-4"
    />
  </div>
</template>

<script setup lang="ts">
import ShortcutKey from "@opendesk/shared/ShortcutKey.vue";
import { useDevice } from "@/composables";
import { Avatar } from "frappe-ui";
import { computed } from "vue";
import LucideCheck from "~icons/lucide/check";
import LucideChevronRight from "~icons/lucide/chevron-right";
import { titleRuns, type Command } from "./paletteTypes";

const props = defineProps<{
  command: Command;
  active: boolean;
}>();

const { metaIcon } = useDevice();

/** One unmatched run for every row without server highlighting. */
const runs = computed(() =>
  props.command.marked
    ? titleRuns(props.command.marked)
    : [{ text: props.command.title, match: false }]
);

/** "Mod+Shift+." -> "⌘ Shift ." — ShortcutKey caps each space-separated key. */
const shortcutKeys = computed(() =>
  (props.command.hint ?? "")
    .split("+")
    .map((key) => (key.toLowerCase() === "mod" ? metaIcon : key))
    .join(" ")
);
</script>
bytes
2,722
lines
92
Type
vue
Latest commit
28 October 2026