Sakuga Back to Sakuga
Theme
Sound
Jump to a component

AniCanonKit · Productions

TrimFrames

TrimFrames shows a cut’s in and out frames with their timecodes and a frame-at-a-time nudge under each. active (in or out) rings the frame being trimmed. Each frame takes image, imageStyle, timecode and an optional href. Frame size with frameWidth and frameHeight (60 × 107 for 9:16). Frames narrower than their rows (a 9:16 cut at 60 × 107) centre the picture, with its name, timecode and nudges centred under it.

@anicanon/sakuga/anicanonkitv1.0Used onWebFrom AniCanon™

Live, from @anicanon/sakuga 2.0.0

Sakuga for iOS and Android is coming

iOS

Web only

TrimFrames is made for the web, and isn’t part of Sakuga for iOS yet.

Android

Web only

TrimFrames is made for the web, and isn’t part of Sakuga for Android yet.

Use it for
The selected cut's in and out frames with their timecodes and a frame-at-a-time nudge under each, ringing the one being trimmed.
Not for
  • Trimming an item on the tracks by its endsTimeline
  • A picture in a frameThumb
  • A number stepped a unit at a timeNumberField
  • The frame grid of what gets generated for a cutTimesheet

Guidelines

  • onNudge(which, frames) runs a nudge on a frame with no href (which is in or out, frames −1 or 1).
TrimFramesExample.jsxReact
import { TrimFrames } from '@anicanon/sakuga/anicanonkit';

export default function TrimFramesExample() {
  return (
    <>
      <TrimFrames
        in={{ image: '/art/eba-cinema.webp', timecode: '0+00' }}
        out={{
          image: '/art/eba-cinema.webp',
          imageStyle: 'object-position:62% 34%',
          timecode: '6+12',
        }}
        active="out"
      />
      <TrimFrames
        frameWidth={60}
        frameHeight={107}
        in={{
          image: '/art/eba-cinema.webp',
          imageStyle: 'object-position:30% 40%',
          timecode: '0+00',
        }}
        out={{
          image: '/art/eba-cinema.webp',
          imageStyle: 'object-position:62% 34%',
          timecode: '6+12',
        }}
        active="out"
        label="Trim, 9:16"
      />
    </>
  );
}

PropsTrimFramesProps

inrequired
TrimFrame
outrequired
TrimFrame
active
'in' | 'out'
frameWidth
number
frameHeight
number
label
string
onNudge
(which: 'in' | 'out', frames: -1 | 1) => void
A nudge pressed on a frame with no href.

Types

interface TrimFrame {
    image: string;
    imageStyle?: string;
    timecode: string;
    href?: string;
}
TrimFramesExample.swiftiOS · coming soon
TrimFramesExample.ktAndroid · coming soon

Each token reads a role, and the role lands on a value in each theme. Change the role and every component that reads it follows.

Space and shape

trim-gap
gap-md
8px
trim-f-gap
gap-xs
4px
trim-nudge-gap
gap-2xs
2px
trim-nudge-margin-left
its own value
calc(-1 * 6px)
trim-lab-narrow-gap
gap-sm
6px

Type

trim-lab-font
text-small-strong
600 12px/16px "Funnel Sans", system-ui, -apple-system, "Segoe UI", sans-serif
trim-lab-span-font-weight
weight-medium
500

Checked automatically with axe-core 4.11.4 against WCAG 2.2 A and AA, on the live preview above, in light and dark, on 26 October 2026.

Result
No issues found, in light or in dark.
By design
A group named by label (default "Trim"): each frame reads "In" or "Out" and its timecode, a frame with href is a link named like "In frame, 0:12" (with "selected" on the active one), and Tab reaches its nudge buttons ("In a frame earlier", "In a frame later", and the same for Out). Without href the nudges run onNudge.
Not tested
The automated check doesn't test keyboard use, focus order or what a screen reader says. The lines above are the design system's own account of them.