@@ -874,7 +874,7 @@ function ActionRow({
874874 value = { action . id }
875875 keywords = { action . keywords }
876876 onSelect = { ( ) => onSelect ( action ) }
877- className = "flex min-h-[3.1rem] cursor-pointer items-center justify-between gap-3 rounded-md px-3 py-2 text-left outline-none transition-colors data-[selected=true]:bg-[#DDEFF4] dark:data-[selected=true]:bg-white/[0.09]"
877+ className = "ec-command-row flex min-h-[3.1rem] cursor-pointer items-center justify-between gap-3 rounded-md px-3 py-2 text-left outline-none transition-colors data-[selected=true]:bg-[#DDEFF4] dark:data-[selected=true]:bg-white/[0.09]"
878878 >
879879 < span className = "min-w-0 flex-1" >
880880 < span className = "block truncate text-sm font-semibold text-black dark:text-[#F3F7FA]" >
@@ -901,7 +901,7 @@ function UnavailableCourseRow({
901901 resource : CommandResourceIntent ;
902902} ) {
903903 return (
904- < div className = "mx-1 mb-1 rounded-md border border-black/10 bg-black/[0.03] px-3 py-2.5 dark:border-white/10 dark:bg-white/[0.045]" >
904+ < div className = "ec-command-row mx-1 mb-1 rounded-md border border-black/10 bg-black/[0.03] px-3 py-2.5 dark:border-white/10 dark:bg-white/[0.045]" >
905905 < div className = "text-sm font-semibold text-black dark:text-[#F3F7FA]" >
906906 No { getResourceLabel ( resource ) } for { course . title }
907907 </ div >
@@ -940,7 +940,7 @@ function PaperRow({
940940 String ( paper . year ?? "" ) ,
941941 ] }
942942 onSelect = { ( ) => onSelect ( paper . href ) }
943- className = "flex min-h-[3.1rem] cursor-pointer items-center justify-between gap-3 rounded-md px-3 py-2 text-left outline-none transition-colors data-[selected=true]:bg-[#DDEFF4] dark:data-[selected=true]:bg-white/[0.09]"
943+ className = "ec-command-row flex min-h-[3.1rem] cursor-pointer items-center justify-between gap-3 rounded-md px-3 py-2 text-left outline-none transition-colors data-[selected=true]:bg-[#DDEFF4] dark:data-[selected=true]:bg-white/[0.09]"
944944 >
945945 < span className = "min-w-0 flex-1" >
946946 < span className = "block truncate text-sm font-semibold text-black dark:text-[#F3F7FA]" >
@@ -957,6 +957,29 @@ function PaperRow({
957957 ) ;
958958}
959959
960+ function RecentSkeletonRow ( { widthHint } : { widthHint : "lg" | "md" | "sm" } ) {
961+ const titleWidth =
962+ widthHint === "lg" ? "w-7/12" : widthHint === "md" ? "w-6/12" : "w-5/12" ;
963+ const metaWidth =
964+ widthHint === "lg" ? "w-4/12" : widthHint === "md" ? "w-3/12" : "w-3/12" ;
965+ return (
966+ < div
967+ aria-hidden = "true"
968+ className = "ec-command-skeleton-row flex min-h-[3.1rem] items-center justify-between gap-3 rounded-md px-3 py-2"
969+ >
970+ < span className = "min-w-0 flex-1" >
971+ < span
972+ className = { `block h-2.5 ${ titleWidth } rounded-full bg-black/[0.10] dark:bg-white/[0.12]` }
973+ />
974+ < span
975+ className = { `mt-2 block h-2 ${ metaWidth } rounded-full bg-black/[0.07] dark:bg-white/[0.08]` }
976+ />
977+ </ span >
978+ < span className = "h-4 w-12 shrink-0 rounded border border-black/10 bg-black/[0.05] dark:border-white/10 dark:bg-white/[0.06]" />
979+ </ div >
980+ ) ;
981+ }
982+
960983function CommandSuspenseFallback ( {
961984 label,
962985} : {
@@ -1015,8 +1038,9 @@ export default function CommandPalette({ open, onOpenChange }: CommandPalettePro
10151038 } , [ isSupportedViewport ] ) ;
10161039
10171040 useEffect ( ( ) => {
1041+ if ( ! isSupportedViewport ) return ;
1042+
10181043 const handleKeyDown = ( event : KeyboardEvent ) => {
1019- if ( ! isSupportedViewport ) return ;
10201044 if ( event . key . toLowerCase ( ) !== "k" || ( ! event . metaKey && ! event . ctrlKey ) ) {
10211045 return ;
10221046 }
@@ -1026,7 +1050,7 @@ export default function CommandPalette({ open, onOpenChange }: CommandPalettePro
10261050
10271051 document . addEventListener ( "keydown" , handleKeyDown ) ;
10281052 return ( ) => document . removeEventListener ( "keydown" , handleKeyDown ) ;
1029- } , [ ] ) ;
1053+ } , [ isSupportedViewport ] ) ;
10301054
10311055 if ( ! isSupportedViewport ) {
10321056 return null ;
@@ -1379,6 +1403,10 @@ function CommandPaletteSession({
13791403 ! hasVisibleResults &&
13801404 ! shouldShowResolvingFallback &&
13811405 ( courseStatus === "ready" || courseStatus === "error" ) ;
1406+ const showRecentSkeletons =
1407+ ! hasSearch &&
1408+ recentCourseActions . length === 0 &&
1409+ ( courseStatus === "idle" || courseStatus === "loading" ) ;
13821410
13831411 const rememberCoursePreference = ( action : CommandAction ) => {
13841412 if ( ! action . courseCode || ! action . courseTitle ) return ;
@@ -1486,11 +1514,11 @@ function CommandPaletteSession({
14861514 < Dialog . Portal forceMount >
14871515 < Dialog . Overlay
14881516 forceMount
1489- className = "fixed inset-0 z-[95] bg-[#19323A]/28 backdrop-blur-sm data-[state=closed]:hidden dark:bg-black/42"
1517+ className = "ec-command-dialog-overlay fixed inset-0 z-[95] bg-[#19323A]/28 backdrop-blur-sm dark:bg-black/42"
14901518 />
14911519 < Dialog . Content
14921520 forceMount
1493- className = "ec-command-dialog-panel fixed left-1/2 top-1/2 z-[96] h-[min(20rem,calc(100dvh-2rem))] w-[calc(100vw-2rem)] max-w-[34rem] overflow-hidden rounded-lg border border-[#BED0D7] bg-[#FBFDFE]/98 shadow-[0_24px_70px_rgba(20,54,66,0.24)] outline-none backdrop-blur-xl data-[state=closed]:hidden dark:border-white/14 dark:bg-[#11151D]/98 dark:shadow-[0_24px_90px_rgba(0,0,0,0.62)]"
1521+ className = "ec-command-dialog-panel fixed left-1/2 top-1/2 z-[96] h-[min(20rem,calc(100dvh-2rem))] w-[calc(100vw-2rem)] max-w-[34rem] overflow-hidden rounded-lg border border-[#BED0D7] bg-[#FBFDFE]/98 shadow-[0_24px_70px_rgba(20,54,66,0.24)] outline-none backdrop-blur-xl dark:border-white/14 dark:bg-[#11151D]/98 dark:shadow-[0_24px_90px_rgba(0,0,0,0.62)]"
14941522 >
14951523 < Dialog . Title className = "sr-only" > ExamCooker command menu</ Dialog . Title >
14961524 < Dialog . Description className = "sr-only" >
@@ -1522,6 +1550,14 @@ function CommandPaletteSession({
15221550 </ div >
15231551
15241552 < Command . List className = "min-h-0 flex-1 overflow-y-auto overscroll-contain px-2 py-2" >
1553+ { showRecentSkeletons ? (
1554+ < >
1555+ < RecentSkeletonRow widthHint = "lg" />
1556+ < RecentSkeletonRow widthHint = "md" />
1557+ < RecentSkeletonRow widthHint = "sm" />
1558+ </ >
1559+ ) : null }
1560+
15251561 { requestedResource
15261562 ? unavailableCourses . map ( ( course ) => (
15271563 < UnavailableCourseRow
0 commit comments