Controls
Circular, absolutely positioned overlay buttons for previous/next navigation over carousels and media.
Controls is an object grouping three client components — Control, ControlLeft, and ControlRight — that render a white circular motion.div positioned absolutely at the vertical centre of the nearest positioned ancestor. Use them for previous/next navigation over carousels and media.
Import#
import { Controls } from "@reactberry/system/blocks";
Usage#
"use client";
import { useState } from "react";
import { Controls } from "@reactberry/system/blocks";
import { Box, Text } from "@reactberry/system/elements";
const slides = ["One", "Two", "Three"];
export default function SlideViewer() {
const [index, setIndex] = useState(0);
const prev = () => setIndex((i) => (i - 1 + slides.length) % slides.length);
const next = () => setIndex((i) => (i + 1) % slides.length);
return (
<Box position="relative" height="12rem" skin="surface" shape="rounded" p="l">
<Text>{slides[index]}</Text>
<Controls.ControlLeft onClick={prev} title="Previous slide" />
<Controls.ControlRight onClick={next} title="Next slide" left="auto" right="0" />
</Box>
);
}
Examples#
Custom content#
Controls.Control renders any children, for example a dismiss button in the corner of a card.
Invite your team and edit projects together.
Bottom placement#
Every position default can be overridden. Here both arrows sit in the bottom-right corner and fade at the ends.
API#
Control#
| Prop | Type | Default | Description |
|---|---|---|---|
children* | ReactNode | — | Content of the control, typically an icon. |
as | any | — | Element to render instead of the default |
href | string | — | Passed through to the element, e.g. with |
target | string | — | Passed through to the element, e.g. with |
title | string | — | Native |
rel | string | — | Passed through to the element, e.g. with |
onClick | (() => void) | — | Click handler. |
children (React.ReactNode, required) is the content of the control, typically an icon.
Control extends BoxProps and accepts any additional prop. All props are spread onto the Box after its defaults, so every default can be overridden. Defaults: position="absolute", top="calc(50% - 1.25rem)", left="0", bg="white", color="black", $shadow="small", size="2.5rem", p="xsmall", shape="circle", cursor="pointer", zIndex of 99, and centred flex content.
ControlLeft#
Control with a left arrow icon (IconArrowLeft, 1.125rem). Accepts any props and spreads them onto Control; children is replaced by the icon.
ControlRight#
Control with a right arrow icon (IconArrowRight, 1.125rem). Accepts any props and spreads them onto Control; children is replaced by the icon.
Control, ControlLeft, and ControlRight are also named exports of the Controls module source, but @reactberry/system/blocks exports only the Controls object.
Accessibility#
- The default element is a
div, not abutton. It is not keyboard-focusable and has no role or accessible name. - For accessible controls, pass
as="button"(orroleandtabIndex) plus anaria-label.titleonly adds a hover tooltip. - The arrow icons have no text alternative.
Notes#
- The parent must establish a positioning context (for example
position="relative"), otherwise the controls are positioned against a higher ancestor. ControlRightalso defaults toleft="0"; passleft="auto"andright="0"to place it on the right edge.- The
motionprops (variants,initial,animate,whileHover) are always set. Withasset to a plain element such as"button"or"a", they are forwarded to the DOM element. - The hover variants (
initialandactive) are empty objects, sowhileHoverproduces no visual change.