mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-09-26 15:55:35 +00:00
fix: restore shared UI behavior and keyboard accessibility
This commit is contained in:
@@ -275,7 +275,11 @@ export function AnnouncementDialog({ audience }: { audience: AnnouncementAudienc
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className={usesCoverMedia ? "" : undefined}
|
||||
className={
|
||||
usesCoverMedia
|
||||
? "text-white hover:text-white hover:bg-white/15"
|
||||
: undefined
|
||||
}
|
||||
onClick={() =>
|
||||
setCurrentIndex(
|
||||
(index) =>
|
||||
@@ -297,7 +301,8 @@ export function AnnouncementDialog({ audience }: { audience: AnnouncementAudienc
|
||||
<Button
|
||||
type="button"
|
||||
key={announcement.id}
|
||||
className={`h-1.5 ${
|
||||
variant="ghost"
|
||||
className={`h-1.5 min-w-0 p-0 rounded-full ${
|
||||
index === currentIndex
|
||||
? `w-6 ${usesCoverMedia ? "bg-white" : "bg-primary"}`
|
||||
: `w-1.5 ${usesCoverMedia ? "bg-white/40" : "bg-foreground/25"}`
|
||||
@@ -313,7 +318,11 @@ export function AnnouncementDialog({ audience }: { audience: AnnouncementAudienc
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className={usesCoverMedia ? "" : undefined}
|
||||
className={
|
||||
usesCoverMedia
|
||||
? "text-white hover:text-white hover:bg-white/15"
|
||||
: undefined
|
||||
}
|
||||
onClick={() =>
|
||||
setCurrentIndex(
|
||||
(index) => (index + 1) % announcements.length,
|
||||
@@ -332,7 +341,11 @@ export function AnnouncementDialog({ audience }: { audience: AnnouncementAudienc
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
className={usesCoverMedia ? "" : undefined}
|
||||
className={
|
||||
usesCoverMedia
|
||||
? "text-white hover:text-white hover:bg-white/15"
|
||||
: undefined
|
||||
}
|
||||
onClick={dismissCurrent}
|
||||
>
|
||||
{t("announcements.dismiss", "Dismiss")}
|
||||
|
||||
@@ -118,7 +118,7 @@ export function EditorAnnouncementBanner() {
|
||||
variant="link"
|
||||
size="sm"
|
||||
onClick={() => void openAction()}
|
||||
className="h-auto shrink-0 gap-1 px-1 py-0 text-xs underline decoration-white/50 underline-offset-2 dark:decoration-black/50"
|
||||
className="text-current h-auto shrink-0 gap-1 px-1 py-0 text-xs underline decoration-white/50 underline-offset-2 dark:decoration-black/50"
|
||||
>
|
||||
{current.action?.label}
|
||||
{current.action?.url ? (
|
||||
@@ -133,7 +133,7 @@ export function EditorAnnouncementBanner() {
|
||||
variant="ghost"
|
||||
type="button"
|
||||
onClick={dismissCurrent}
|
||||
className="absolute right-4 inline-flex h-6 w-6 items-center justify-center"
|
||||
className="text-current absolute right-4 inline-flex h-6 w-6 items-center justify-center"
|
||||
aria-label={t("announcements.dismiss", "Dismiss")}
|
||||
>
|
||||
<X className="h-3.5 w-3.5" />
|
||||
|
||||
@@ -372,7 +372,7 @@ function LaunchWindowContent() {
|
||||
onOpenProject={openProjectFromLibrary}
|
||||
trigger={
|
||||
<Button
|
||||
aria-label={t("recording.openProject")}
|
||||
aria-hidden="true"
|
||||
tabIndex={-1}
|
||||
variant="ghost"
|
||||
className="absolute size-px min-w-0 p-0 pointer-events-none opacity-0"
|
||||
|
||||
@@ -62,6 +62,7 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button
|
||||
"[&_svg]:size-5": iconSize === "lg",
|
||||
"[&_svg]:size-6": iconSize === "xl",
|
||||
},
|
||||
variant === "link" && "h-auto p-0 underline underline-offset-4",
|
||||
className,
|
||||
),
|
||||
};
|
||||
|
||||
@@ -20,7 +20,7 @@ export function ChoiceGroup({
|
||||
}) {
|
||||
return (
|
||||
<TagGroup
|
||||
size="md"
|
||||
size={props.size ?? "md"}
|
||||
aria-label={props["aria-label"]}
|
||||
selectionMode="single"
|
||||
disallowEmptySelection
|
||||
|
||||
@@ -31,10 +31,13 @@ export function DropdownMenuContent({
|
||||
}
|
||||
export function DropdownMenuItem({
|
||||
onSelect,
|
||||
onClick,
|
||||
onAction,
|
||||
disabled,
|
||||
children,
|
||||
...props
|
||||
}: Omit<ComponentProps<typeof Dropdown.Item>, "onSelect"> & {
|
||||
}: Omit<ComponentProps<typeof Dropdown.Item>, "onSelect" | "onClick"> & {
|
||||
onClick?: () => void;
|
||||
onSelect?: (event: Event) => void;
|
||||
disabled?: boolean;
|
||||
}) {
|
||||
@@ -46,7 +49,11 @@ export function DropdownMenuItem({
|
||||
props.textValue ??
|
||||
(typeof children === "string" ? children : String(props.id ?? "Action"))
|
||||
}
|
||||
onAction={() => onSelect?.(new Event("select"))}
|
||||
onAction={() => {
|
||||
onSelect?.(new Event("select"));
|
||||
onClick?.();
|
||||
onAction?.();
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</Dropdown.Item>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ToggleButton } from "@heroui/react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ComponentProps } from "react";
|
||||
type Props = Omit<ComponentProps<typeof ToggleButton>, "size" | "variant"> & {
|
||||
pressed?: boolean;
|
||||
@@ -15,7 +16,15 @@ export function Toggle({ pressed, onPressedChange, disabled, size, variant, ...p
|
||||
onChange={onPressedChange}
|
||||
isDisabled={disabled}
|
||||
size={size === "default" ? "md" : size}
|
||||
variant={variant === "outline" ? "default" : "ghost"}
|
||||
variant="ghost"
|
||||
className={(state) =>
|
||||
cn(
|
||||
variant === "outline" && "border border-border bg-transparent",
|
||||
typeof props.className === "function"
|
||||
? props.className(state)
|
||||
: props.className,
|
||||
)
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -115,7 +115,9 @@ export function EditorHeader(props: Props) {
|
||||
onClick={props.onToggleVideos}
|
||||
>
|
||||
<FilmStrip className="h-4 w-4" />
|
||||
<span className="text-sm font-semibold tracking-tight">Videos</span>
|
||||
<span className="text-sm font-semibold tracking-tight">
|
||||
{t("editor.library.videos", "Videos")}
|
||||
</span>
|
||||
</Button>
|
||||
<Button
|
||||
ref={projectBrowserTriggerRef}
|
||||
|
||||
@@ -106,6 +106,7 @@ const modes = [
|
||||
"presets-empty",
|
||||
"presets-saved",
|
||||
"announcement-popup",
|
||||
"announcement-cover",
|
||||
"announcement-banner",
|
||||
"announcement-notification",
|
||||
];
|
||||
|
||||
@@ -111,8 +111,8 @@ function TimelineSample({
|
||||
videoPath={media}
|
||||
videoSourcePath={media}
|
||||
disableSuggestedZooms
|
||||
clipRegions={clips}
|
||||
zoomRegions={zooms}
|
||||
clipRegions={selection === "empty" ? [] : clips}
|
||||
zoomRegions={selection === "empty" ? [] : zooms}
|
||||
onZoomAdded={noop}
|
||||
onZoomSpanChange={noop}
|
||||
onZoomDelete={noop}
|
||||
@@ -123,40 +123,62 @@ function TimelineSample({
|
||||
onClipDelete={noop}
|
||||
selectedClipId={selection === "clip" ? "clip-a" : null}
|
||||
onSelectClip={noop}
|
||||
annotationRegions={[
|
||||
annotation,
|
||||
{
|
||||
...annotation,
|
||||
id: "annotation-b",
|
||||
startMs: 3500,
|
||||
endMs: 5100,
|
||||
content: "A second callout",
|
||||
trackIndex: 1,
|
||||
},
|
||||
]}
|
||||
annotationRegions={
|
||||
selection === "empty"
|
||||
? []
|
||||
: [
|
||||
annotation,
|
||||
{
|
||||
...annotation,
|
||||
id: "annotation-b",
|
||||
startMs: 3500,
|
||||
endMs: 5100,
|
||||
content: "A second callout",
|
||||
trackIndex: 1,
|
||||
},
|
||||
]
|
||||
}
|
||||
onAnnotationAdded={noop}
|
||||
onAnnotationSpanChange={noop}
|
||||
onAnnotationDelete={noop}
|
||||
onSelectAnnotation={noop}
|
||||
selectedAnnotationId={selection === "annotation" ? "annotation-a" : null}
|
||||
audioRegions={[
|
||||
{
|
||||
id: "audio-a",
|
||||
startMs: 0,
|
||||
endMs: 6000,
|
||||
audioPath: `${location.origin}/tests/ui/fixtures/preview.mp4`,
|
||||
volume: 0.8,
|
||||
},
|
||||
]}
|
||||
audioRegions={
|
||||
selection === "empty"
|
||||
? []
|
||||
: [
|
||||
{
|
||||
id: "audio-a",
|
||||
startMs: 0,
|
||||
endMs: 6000,
|
||||
audioPath: `${location.origin}/tests/ui/fixtures/preview.mp4`,
|
||||
volume: 0.8,
|
||||
},
|
||||
]
|
||||
}
|
||||
onAudioAdded={noop}
|
||||
onAudioSpanChange={noop}
|
||||
onAudioDelete={noop}
|
||||
onSelectAudio={noop}
|
||||
selectedAudioId={selection === "audio" ? "audio-a" : null}
|
||||
captionRegions={[
|
||||
{ id: "caption-a", startMs: 100, endMs: 2000, text: "Welcome to Recordly" },
|
||||
{ id: "caption-b", startMs: 2900, endMs: 5200, text: "Create something clear." },
|
||||
]}
|
||||
captionRegions={
|
||||
selection === "empty"
|
||||
? []
|
||||
: [
|
||||
{
|
||||
id: "caption-a",
|
||||
startMs: 100,
|
||||
endMs: 2000,
|
||||
text: "Welcome to Recordly",
|
||||
},
|
||||
{
|
||||
id: "caption-b",
|
||||
startMs: 2900,
|
||||
endMs: 5200,
|
||||
text: "Create something clear.",
|
||||
},
|
||||
]
|
||||
}
|
||||
captionsEnabled
|
||||
captionQuickAddEnabled
|
||||
onCaptionAdded={noop}
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
{
|
||||
"library": {
|
||||
"videos": "Videos"
|
||||
},
|
||||
"playback": {
|
||||
"play": "Wiedergabe",
|
||||
"pause": "Pause",
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
{
|
||||
"library": {
|
||||
"videos": "Videos"
|
||||
},
|
||||
"playback": {
|
||||
"play": "Play",
|
||||
"pause": "Pause",
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
{
|
||||
"library": {
|
||||
"videos": "Vídeos"
|
||||
},
|
||||
"playback": {
|
||||
"play": "Reproducir",
|
||||
"pause": "Pausar",
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
{
|
||||
"library": {
|
||||
"videos": "Vidéos"
|
||||
},
|
||||
"playback": {
|
||||
"play": "Lecture",
|
||||
"pause": "Pause",
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
{
|
||||
"library": {
|
||||
"videos": "Video"
|
||||
},
|
||||
"playback": {
|
||||
"play": "Riproduci",
|
||||
"pause": "Pausa",
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
{
|
||||
"library": {
|
||||
"videos": "동영상"
|
||||
},
|
||||
"playback": {
|
||||
"play": "재생",
|
||||
"pause": "일시 정지",
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
{
|
||||
"library": {
|
||||
"videos": "Video’s"
|
||||
},
|
||||
"playback": {
|
||||
"play": "Afspelen",
|
||||
"pause": "Pauzeren",
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
{
|
||||
"library": {
|
||||
"videos": "Vídeos"
|
||||
},
|
||||
"playback": {
|
||||
"play": "Reproduzir",
|
||||
"pause": "Pausar",
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
{
|
||||
"library": {
|
||||
"videos": "Видео"
|
||||
},
|
||||
"playback": {
|
||||
"play": "Воспроизвести",
|
||||
"pause": "Пауза",
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
{
|
||||
"library": {
|
||||
"videos": "视频"
|
||||
},
|
||||
"playback": {
|
||||
"play": "播放",
|
||||
"pause": "暂停",
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
{
|
||||
"library": {
|
||||
"videos": "影片"
|
||||
},
|
||||
"playback": {
|
||||
"play": "播放",
|
||||
"pause": "暫停",
|
||||
|
||||
+6
-4
@@ -127,13 +127,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* highlight rings look ugly — keep them transparent; keyboard focus gets an inset underline. */
|
||||
/* Visible keyboard focus for HeroUI controls and native focusable elements. */
|
||||
:root,
|
||||
.dark {
|
||||
--focus: transparent;
|
||||
--focus: var(--foreground);
|
||||
}
|
||||
[data-focus-visible="true"] {
|
||||
box-shadow: inset 0 -2px 0 color-mix(in oklab, var(--foreground) 45%, transparent);
|
||||
[data-focus-visible="true"],
|
||||
:focus-visible {
|
||||
outline: 2px solid var(--focus);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
@container (max-width: 110px) {
|
||||
|
||||
Reference in New Issue
Block a user