Mixins / foldkit-mixins-ui

MarqueeSlots

const · packages/mixins-ui/src/marquee.ts:36

const MarqueeSlots: Slots.Contract<{
  readonly root: Slot.UnnamedSlot<
    Capability.Capability<
      'Container',
      readonly [
        Capability.Capability<
          'Interactive',
          readonly [Capability.Capability<'Base', readonly []>]
        >,
      ]
    >,
    readonly Slot.EventName[],
    readonly [Attr.AttrToken<'role'>, Attr.AttrToken<'aria-label'>],
    readonly Slot.RequirementName[],
    boolean
  >
  readonly viewport: Slot.UnnamedSlot<
    Capability.Capability<
      'Container',
      readonly [
        Capability.Capability<
          'Interactive',
          readonly [Capability.Capability<'Base', readonly []>]
        >,
      ]
    >,
    readonly Slot.EventName[],
    readonly Slot.AttributeName[],
    readonly Slot.RequirementName[],
    boolean
  >
  readonly content: Slot.UnnamedSlot<
    Capability.Capability<
      'Container',
      readonly [
        Capability.Capability<
          'Interactive',
          readonly [Capability.Capability<'Base', readonly []>]
        >,
      ]
    >,
    readonly Slot.EventName[],
    readonly Slot.AttributeName[],
    readonly Slot.RequirementName[],
    boolean
  >
  readonly item: Slot.UnnamedSlot<
    Capability.Capability<
      'Container',
      readonly [
        Capability.Capability<
          'Interactive',
          readonly [Capability.Capability<'Base', readonly []>]
        >,
      ]
    >,
    readonly Slot.EventName[],
    readonly Slot.AttributeName[],
    readonly Slot.RequirementName[],
    boolean
  >
  readonly pause: Slot.UnnamedSlot<
    Capability.Capability<
      'Interactive',
      readonly [Capability.Capability<'Base', readonly []>]
    >,
    readonly [Event.EventToken<'click'>],
    readonly [Attr.AttrToken<'aria-label'>],
    readonly Slot.RequirementName[],
    boolean
  >
}>

Content that scrolls on and on, after Zag's marquee: a region with aria-roledescription="marquee" named by its label, whose content is drawn as many times as it takes to fill the viewport and one more, each copy sliding by its own length and starting again, so the seam never shows. The copies after the first are inert: assistive technology reads the content once, and the keys reach each link in it once.

Resize (content, viewport) -> Measured -> copies, duration = length / speed

The sizes measured and whether it is paused are this Model, which the application keeps and folds with update. The movement itself is CSS: a pointer over it or focus inside it pauses it (pauseOnInteraction), and the pause press, drawn by default as WCAG 2.2.2 asks of anything that moves for more than five seconds, holds it until pressed again. Until the content is measured it moves at the recipe's --fk-marquee-duration.

Its distance travels, so reduced motion stills it; the recipe then lets the viewport scroll and draws one copy. The root carries data-side, data-orientation, data-paused and data-pause-on-interaction, and the timing as --fk-marquee-duration (seconds), --fk-marquee-delay and --fk-marquee-loop-count.