import React, { useMemo, type ReactElement } from "react"; import { Text, View, type StyleProp, type TextStyle, type ViewStyle } from "react-native"; import { StyleSheet } from "react-native-unistyles"; import { formatShortcut, type ShortcutKey } from "@/utils/format-shortcut"; import { getShortcutOs } from "@/utils/shortcut-platform"; function colorWithOpacity(color: string, opacity: number): string { const hex = color.trim(); if (/^#[0-9a-fA-F]{3}$/.test(hex)) { const r = Number.parseInt(hex[1] + hex[1], 16); const g = Number.parseInt(hex[2] + hex[2], 16); const b = Number.parseInt(hex[3] + hex[3], 16); return `rgba(${r}, ${g}, ${b}, ${opacity})`; } if (/^#[0-9a-fA-F]{6}$/.test(hex)) { const r = Number.parseInt(hex.slice(1, 3), 16); const g = Number.parseInt(hex.slice(3, 5), 16); const b = Number.parseInt(hex.slice(5, 7), 16); return `rgba(${r}, ${g}, ${b}, ${opacity})`; } return `rgba(255, 255, 255, ${opacity})`; } export function Shortcut({ keys, chord, style, textStyle, }: { keys?: ShortcutKey[]; chord?: ShortcutKey[][]; style?: StyleProp; textStyle?: StyleProp; }): ReactElement { const displayChord = chord ?? (keys ? [keys] : []); const shortcutOs = getShortcutOs(); const singleCombo = displayChord[0]; const badgeStyle = useMemo(() => [styles.badge, style], [style]); const textCombinedStyle = useMemo(() => [styles.text, textStyle], [textStyle]); const sequenceStyle = useMemo(() => [styles.sequence, style], [style]); if (!singleCombo) { return ; } if (displayChord.length === 1) { return ( {formatShortcut(singleCombo, shortcutOs)} ); } return ( {displayChord.map(function (combo) { return ( {formatShortcut(combo, shortcutOs)} ); })} ); } const styles = StyleSheet.create((theme) => ({ badge: { paddingHorizontal: theme.spacing[1], paddingVertical: 2, borderRadius: theme.borderRadius.md, backgroundColor: colorWithOpacity(theme.colors.foreground, 0.05), borderWidth: 0, }, sequence: { flexDirection: "row", alignItems: "center", flexWrap: "wrap", gap: theme.spacing[1], }, text: { fontSize: theme.fontSize.xs, fontWeight: theme.fontWeight.normal, color: colorWithOpacity(theme.colors.foreground, 0.6), }, }));