diff --git a/apps/web/src/apps/modules/layouts/components/sidebar.tsx b/apps/web/src/apps/modules/layouts/components/sidebar.tsx index e532bbc..8ff44ec 100644 --- a/apps/web/src/apps/modules/layouts/components/sidebar.tsx +++ b/apps/web/src/apps/modules/layouts/components/sidebar.tsx @@ -6,6 +6,7 @@ import { ChevronsLeft, ChevronsRight, PanelTopClose, PanelTopOpen, Search, X } f import type { MenuItemType } from '../types/menu.types'; import type { SidebarVariant } from '@repo/ui/components'; import { useTranslation } from '@repo/core-i18n'; +import { shortcutsData } from '@repo/ui/constants'; // --------------------------------------------------------------------------- // Props @@ -333,13 +334,20 @@ export const SidebarMenu = memo(function SidebarMenu({ } }, [isMini, setSidebarVariant]); - const [isMac, setIsMac] = useState(true); + const [isMac, setIsMac] = useState(false); useEffect(() => { - setIsMac(typeof window !== 'undefined' && navigator.userAgent.includes('Mac')); + setIsMac(typeof window !== 'undefined' && /Mac|iPod|iPhone|iPad/.test(navigator.userAgent)); }, []); - const filterMenuShortcutText = isMac ? '⇧⌘M' : 'Ctrl+Shift+M'; - const toggleShortcutText = isMac ? '⇧⌘B' : 'Ctrl+Shift+B'; + const filterMenuShortcutText = useMemo(() => { + const shortcutData = shortcutsData.find((s) => s.key === 'search_menu'); + return isMac ? shortcutData?.macKeyIcons.join(' ') : shortcutData?.winKeyIcons.join(' '); + }, [isMac]); + + const toggleShortcutText = useMemo(() => { + const shortcutData = shortcutsData.find((s) => s.key === 'collapse_sidebar'); + return isMac ? shortcutData?.macKeyIcons.join(' ') : shortcutData?.winKeyIcons.join(' '); + }, [isMac]); useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { @@ -442,7 +450,7 @@ export const SidebarMenu = memo(function SidebarMenu({ radius="md" size="xs" style={{ flex: 1 }} - rightSectionWidth={searchQuery ? 30 : 48} + rightSectionWidth={searchQuery ? 30 : isMac ? 48 : 68} rightSection={ searchQuery ? ( setSearchQuery('')} size="sm"> diff --git a/apps/web/src/apps/modules/system/information/components/shortcut/index.tsx b/apps/web/src/apps/modules/system/information/components/shortcut/index.tsx index 4382403..671be16 100644 --- a/apps/web/src/apps/modules/system/information/components/shortcut/index.tsx +++ b/apps/web/src/apps/modules/system/information/components/shortcut/index.tsx @@ -1,8 +1,8 @@ import { useTranslation } from '@repo/core-i18n'; import { Group, Kbd, Table, Text, TextInput, Box, Center, ScrollArea } from '@repo/ui/components'; +import { shortcutsData } from '@repo/ui/constants'; import { Search, Keyboard } from 'lucide-react'; -import { useEffect, useState, useMemo } from 'react'; -import { shortcuts } from './data'; +import { useEffect, useState, useMemo, Fragment } from 'react'; export function Shortcut() { const { t } = useTranslation(); @@ -11,15 +11,14 @@ export function Shortcut() { // OS Detection for rendering appropriate keyboard shortcuts useEffect(() => { - setIsMac(typeof window !== 'undefined' && navigator.userAgent.includes('Mac')); + setIsMac(typeof window !== 'undefined' && /Mac|iPod|iPhone|iPad/.test(navigator.userAgent)); }, []); - // Filter logika pencarian berdasarkan label ATAU deskripsi yang sudah diterjemahkan const filteredShortcuts = useMemo(() => { const query = searchQuery.toLowerCase().trim(); - if (!query) return shortcuts; + if (!query) return shortcutsData; - return shortcuts.filter((item) => { + return shortcutsData.filter((item) => { const labelMatch = t(item.label).toLowerCase().includes(query); const descMatch = t(item.desc).toLowerCase().includes(query); return labelMatch || descMatch; @@ -34,23 +33,30 @@ export function Shortcut() { {t(element.label)} - + {t(element.desc)} - + {keys.map((key, i) => ( - - {key} - + + + {key} + + + {i < keys.length - 1 && ( + + + + + )} + ))} ); }); - return ( @@ -76,8 +82,8 @@ export function Shortcut() { > - {t('information:info.table.action')} - {t('information:info.table.shortcut')} + {t('information:info.table.action').toUpperCase()} + {t('information:info.table.shortcut').toUpperCase()} diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json index 697b3f5..ab4ebbc 100644 --- a/apps/web/tsconfig.json +++ b/apps/web/tsconfig.json @@ -1,6 +1,6 @@ { "extends": "@repo/typescript-config/react-app.json", - "include": ["src"], + "include": ["src", "../../packages/ui/src/constant/shortcut.data.ts"], "compilerOptions": { "jsx": "react-jsx" } diff --git a/packages/ui/package.json b/packages/ui/package.json index 67dbe44..44b02dc 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -8,7 +8,8 @@ "./hooks": "./src/hooks/index.ts", "./provider": "./src/provider/index.ts", "./validators": "./src/validators/index.ts", - "./foundations": "./src/foundations/index.ts" + "./foundations": "./src/foundations/index.ts", + "./constants": "./src/constants/index.ts" }, "license": "MIT", "scripts": { diff --git a/packages/ui/src/constants/index.ts b/packages/ui/src/constants/index.ts new file mode 100644 index 0000000..75bf9fa --- /dev/null +++ b/packages/ui/src/constants/index.ts @@ -0,0 +1 @@ +export * from './shortcut.data'; diff --git a/apps/web/src/apps/modules/system/information/components/shortcut/data.ts b/packages/ui/src/constants/shortcut.data.ts similarity index 50% rename from apps/web/src/apps/modules/system/information/components/shortcut/data.ts rename to packages/ui/src/constants/shortcut.data.ts index 4965625..7d11e19 100644 --- a/apps/web/src/apps/modules/system/information/components/shortcut/data.ts +++ b/packages/ui/src/constants/shortcut.data.ts @@ -1,20 +1,29 @@ -export const shortcuts = [ +export const shortcutsData = [ { + key: 'create_data', label: 'information:shortcuts.create.label', desc: 'information:shortcuts.create.desc', - macKeys: ['⌘', '⇧', 'N'], + macKeys: ['Cmd', 'Shift', 'N'], + macKeyIcons: ['⌘', '⇧', 'N'], winKeys: ['Ctrl', 'Shift', 'N'], + winKeyIcons: ['Ctrl', '⇧', 'N'], }, { + key: 'search_menu', label: 'information:shortcuts.searchMenu.label', desc: 'information:shortcuts.searchMenu.desc', - macKeys: ['⌘', '⇧', 'M'], + macKeys: ['Cmd', 'Shift', 'M'], + macKeyIcons: ['⌘', '⇧', 'M'], winKeys: ['Ctrl', 'Shift', 'M'], + winKeyIcons: ['Ctrl', '⇧', 'M'], }, { + key: 'collapse_sidebar', label: 'information:shortcuts.toggleSidebar.label', desc: 'information:shortcuts.toggleSidebar.desc', - macKeys: ['⌘', '⇧', 'B'], + macKeys: ['Cmd', 'Shift', 'B'], + macKeyIcons: ['⌘', '⇧', 'B'], winKeys: ['Ctrl', 'Shift', 'B'], + winKeyIcons: ['Ctrl', '⇧', 'B'], }, ]; diff --git a/packages/ui/src/foundations/enterprise-module/providers/index-page.provider.tsx b/packages/ui/src/foundations/enterprise-module/providers/index-page.provider.tsx index b4ec152..f945c0c 100644 --- a/packages/ui/src/foundations/enterprise-module/providers/index-page.provider.tsx +++ b/packages/ui/src/foundations/enterprise-module/providers/index-page.provider.tsx @@ -10,6 +10,7 @@ import { useEnterpriseModuleNavigationContext, useEnterpriseModuleTranslationContext, } from '../hooks/use-module.context'; +import { shortcutsData } from '../../../constants'; // --------------------------------------------------------------------------- // Helpers @@ -18,9 +19,6 @@ import { /** Detect macOS / iOS for displaying platform-specific shortcut labels. */ const IS_MAC = typeof navigator !== 'undefined' && /Mac|iPod|iPhone|iPad/.test(navigator.userAgent); -/** Platform-aware shortcut label for the Create action. */ -const CREATE_SHORTCUT_LABEL = IS_MAC ? '⇧⌘N' : 'Ctrl+Shift+N'; - // --------------------------------------------------------------------------- // Component // --------------------------------------------------------------------------- @@ -48,6 +46,13 @@ export function EnterpriseIndexPageProvider(p // ------------------------------------------------------------------------- // Global keyboard shortcut: Ctrl+Shift+N / ⌘+Shift+N → Create // ------------------------------------------------------------------------- + + /** Platform-aware shortcut label for the Create action. */ + const CREATE_SHORTCUT_LABEL = useMemo(() => { + const shortcutData = shortcutsData.find((s) => s.key === 'collapse_sidebar'); + return IS_MAC ? shortcutData?.macKeyIcons.join(' ') : shortcutData?.winKeyIcons.join(' '); + }, [IS_MAC]); + useEffect(() => { function onKeyDown(e: KeyboardEvent) { const isShortcut = (e.ctrlKey || e.metaKey) && e.shiftKey && e.key.toLowerCase() === 'n';