@candor-ui/react 2.4.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,7 +5,10 @@ import { cn } from "../lib/utils.js";
5
5
  import { useCopy } from "../lib/use-copy.js";
6
6
  import { useStrings } from "./locale.js";
7
7
  import { motion } from "../lib/motion.js";
8
- /** The tick or cross after the clipboard write settles. */
8
+ /**
9
+ * @motion pop:tick After the person copies, a tick (or a cross, if the browser refused the clipboard) pops in on the
10
+ * button once the browser has answered. Nothing shows before the answer, and under reduced motion it fades in.
11
+ */
9
12
  const tickMotion = motion("copy-field", "tick", "pop");
10
13
  /** CopyField's fixed words; override them under `copyField` in LocaleProvider's `strings`. */
11
14
  export const copyFieldStrings = {
@@ -5,6 +5,10 @@ import { cn } from "../lib/utils.js";
5
5
  import { Button } from "../ui/button.js";
6
6
  import { useStrings } from "./locale.js";
7
7
  import { motion } from "../lib/motion.js";
8
+ /**
9
+ * @motion live:busy While a retry is under way, the retry icon turns in place and the button says it is retrying. It
10
+ * stops when the app ends the retry, and under reduced motion the icon is still.
11
+ */
8
12
  const spinMotion = motion("degraded-panel", "busy", "live", { dur: 1000 });
9
13
  /** DegradedPanel's fixed words; override them under `degradedPanel` in LocaleProvider's `strings`. */
10
14
  export const degradedPanelStrings = {
@@ -15,8 +15,17 @@ function animationMs(el) {
15
15
  .filter((n) => Number.isFinite(n));
16
16
  return times.length ? Math.max(...times) : undefined;
17
17
  }
18
- /** A press on the locked control: the reason is emphasised, and under expressive the control shakes. */
18
+ /**
19
+ * @motion refuse:refuse A press on a locked control shows the reason it is locked; under the expressive setting the
20
+ * control also shakes once. The control stays locked and does nothing it would have done unlocked. Nothing plays
21
+ * until the person presses it.
22
+ */
19
23
  const refuseMotion = motion("locked", "refuse", "refuse");
24
+ /**
25
+ * @motion tint:reason When the person presses a locked control, its reason changes from muted to full-strength text
26
+ * so it can be read, and goes back to muted for a moment after the press. Screen readers always have the reason,
27
+ * whether or not it is shown.
28
+ */
20
29
  const reasonMotion = motion("locked", "reason", "tint", { dur: 200 });
21
30
  /**
22
31
  * The honest-state rule: a control that cannot be used says why.
@@ -4,9 +4,16 @@ import { cn } from "../lib/utils.js";
4
4
  import { useNow } from "./relative-time.js";
5
5
  import { motion, useSettled } from "../lib/motion.js";
6
6
  import { runLiveness, STALE_AFTER, useStatusLabel } from "../lib/status.js";
7
- /** The pulse while a run is heard from. */
7
+ /**
8
+ * @motion live:live A running or waiting dot pulses only while the run has been heard from within the allowed
9
+ * silence. Past it, or when the time can't be read, the dot is still rather than claiming the run is alive, and under
10
+ * reduced motion it is still.
11
+ */
8
12
  const liveMotion = motion("status-dot", "live", "live");
9
- /** The dot popping into its final colour when the run settles on screen. */
13
+ /**
14
+ * @motion pop:settle The dot pops into its final colour when a run it was showing as unfinished settles while it is
15
+ * on screen. A dot that is already settled when it appears is drawn in its colour at once.
16
+ */
10
17
  const settleMotion = motion("status-dot", "settle", "pop");
11
18
  const dotColor = {
12
19
  idle: "bg-faint-foreground/60",
@@ -5,12 +5,25 @@ import { CircleSlash, Hand, LoaderCircle } from "lucide-react";
5
5
  import { cn } from "../lib/utils.js";
6
6
  import { motion, useArrived, useSettled } from "../lib/motion.js";
7
7
  import { useStatusLabel } from "../lib/status.js";
8
- /** A step's tick or cross, drawn when its status settles on screen. */
8
+ /**
9
+ * @motion mark:mark A step's tick or cross is drawn along its path when the step settles while the list is on screen.
10
+ * Steps that were already settled when the list appeared show their mark at once.
11
+ */
9
12
  const markMotion = motion("step-list", "mark", "mark");
10
- /** The rail growing to a step that finished on screen. */
13
+ /**
14
+ * @motion fill:rail The line leading to a step fills in when that step finishes while the list is on screen, never
15
+ * ahead of it. Lines for steps that were already finished when the list appeared are full at once.
16
+ */
11
17
  const railMotion = motion("step-list", "rail", "fill");
12
- /** A step added after the list first drew. */
18
+ /**
19
+ * @motion arrive:arrive A step rises in when the app adds it after the list first drew. The steps the list was drawn
20
+ * with appear still.
21
+ */
13
22
  const arriveMotion = motion("step-list", "arrive", "arrive");
23
+ /**
24
+ * @motion live:working A step that is running shows a spinner that turns until the app reports it finished or failed.
25
+ * Under reduced motion the spinner is still, and the step's status is still written in words.
26
+ */
14
27
  const workingMotion = motion("step-list", "working", "live", { dur: 1000 });
15
28
  /** A tick, drawn along its path when `draw` is above zero (and again each time it changes). */
16
29
  function Tick({ draw }) {
@@ -1,6 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { cn } from "../lib/utils.js";
3
3
  import { motion } from "../lib/motion.js";
4
+ /**
5
+ * @motion live:caret While the text is still streaming in, a caret blinks at its end. It goes when streaming stops,
6
+ * and under reduced motion it is a still bar.
7
+ */
4
8
  const caretMotion = motion("streaming-text", "caret", "live", { dur: 1000 });
5
9
  /**
6
10
  * Text that is still arriving. Shows a caret while `streaming`, and announces
@@ -6,6 +6,10 @@ import { DegradedPanel } from "../blocks/degraded-panel.js";
6
6
  import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../ui/collapsible.js";
7
7
  import { useStrings } from "../blocks/locale.js";
8
8
  import { motion } from "../lib/motion.js";
9
+ /**
10
+ * @motion reveal:open The text view opens to its full height when the person asks to see the card as text, and the
11
+ * chevron turns with it; closing reverses both. Under reduced motion it snaps open or shut.
12
+ */
9
13
  const turnMotion = motion("card-registry", "open", "reveal");
10
14
  /** CardRegistry's fixed words; override them under `cardRegistry` in LocaleProvider's `strings`. */
11
15
  export const cardRegistryStrings = {
@@ -28,6 +28,9 @@ declare function SourceDetail({ source, }: {
28
28
  * An inline [n]. Opens the source in a popover on click or Enter, so evidence is
29
29
  * one step away without leaving the thread. A source the message doesn't list
30
30
  * renders as a plain bracket rather than a guess.
31
+ *
32
+ * @motion tint:tint A source chip's border and text colour change when the pointer is over it, and a ring fades in
33
+ * when a citation number or chip takes keyboard focus.
31
34
  */
32
35
  declare function Citation({ source, marker, }: {
33
36
  /** The source this marker points to; without it the marker says it's unknown. */
@@ -48,6 +48,9 @@ function SourceDetail({ source, }) {
48
48
  * An inline [n]. Opens the source in a popover on click or Enter, so evidence is
49
49
  * one step away without leaving the thread. A source the message doesn't list
50
50
  * renders as a plain bracket rather than a guess.
51
+ *
52
+ * @motion tint:tint A source chip's border and text colour change when the pointer is over it, and a ring fades in
53
+ * when a citation number or chip takes keyboard focus.
51
54
  */
52
55
  function Citation({ source, marker, }) {
53
56
  const t = useStrings("citation", citationStrings);
@@ -8,12 +8,25 @@ import { EntityChip, useEntityKinds } from "./entity-chip.js";
8
8
  import { AttachmentChip } from "./attachment-preview.js";
9
9
  import { useStrings } from "../blocks/locale.js";
10
10
  import { motion, useArrived, useLeaving } from "../lib/motion.js";
11
- /** A chip added after the first draw pops in; a removed one pops out as a ghost. */
11
+ /**
12
+ * @motion pop:chip A mention or attachment chip pops in when the person adds one while writing, and a chip they
13
+ * remove pops out. Chips that were there when the composer first drew, such as a restored draft, appear still.
14
+ */
12
15
  const chipMotion = motion("composer", "chip", "pop");
13
- /** The mention and command menu: 2.2's fade and 4 px rise. */
16
+ /**
17
+ * @motion overlay:menu The mention and command menu rises a little and fades in above the field when the person types
18
+ * the character that opens it, and goes at once when it closes. Under reduced motion it is a short fade.
19
+ */
14
20
  const menuMotion = motion("composer", "menu", "overlay", { variant: "slide" });
15
- /** Send and Stop acknowledge the press: 2.2's scale of 0.95. */
21
+ /**
22
+ * @motion press:send Send and Stop shrink a little while they are held down and return when let go. A Send that is
23
+ * disabled never moves, and under reduced motion neither changes size.
24
+ */
16
25
  const sendMotion = motion("composer", "send", "press", { amp: "0.9" });
26
+ /**
27
+ * @motion live:sending While the app reports that the message is being sent, a spinner turns in place of Send's
28
+ * arrow. It stops when the app says sending is over, and under reduced motion the spinner is still.
29
+ */
17
30
  const sendingMotion = motion("composer", "sending", "live", { dur: 1000 });
18
31
  /** Composer's fixed words; override them under `composer` in LocaleProvider's `strings`. */
19
32
  export const composerStrings = {
@@ -43,6 +43,9 @@ declare function useEntityKinds(): (kind: string) => EntityKindInfo;
43
43
  * so "Account" the table and "Account" the report never read alike. The
44
44
  * identifier is the label unless a friendlier one is given; then the
45
45
  * identifier is on hover and for screen readers.
46
+ *
47
+ * @motion tint:tint A chip that can be pressed changes its border and background when the pointer is over it, and a
48
+ * ring fades in on keyboard focus. A chip that can't be pressed does not change.
46
49
  */
47
50
  declare function EntityChip({ entity, onOpen, onRemove, className, style, }: {
48
51
  /** The thing to show: its kind, identifier and optional label. */
@@ -71,6 +71,9 @@ function useEntityKinds() {
71
71
  * so "Account" the table and "Account" the report never read alike. The
72
72
  * identifier is the label unless a friendlier one is given; then the
73
73
  * identifier is on hover and for screen readers.
74
+ *
75
+ * @motion tint:tint A chip that can be pressed changes its border and background when the pointer is over it, and a
76
+ * ring fades in on keyboard focus. A chip that can't be pressed does not change.
74
77
  */
75
78
  function EntityChip({ entity, onOpen, onRemove, className, style, }) {
76
79
  const { Icon, noun } = useEntityKinds()(entity.kind);
@@ -6,6 +6,10 @@ import { cn } from "../lib/utils.js";
6
6
  import { useStrings } from "../blocks/locale.js";
7
7
  import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../ui/collapsible.js";
8
8
  import { motion } from "../lib/motion.js";
9
+ /**
10
+ * @motion reveal:open The folded turns open to their full height when the person presses the summary, with its
11
+ * chevron turning, and close the same way. Under reduced motion they snap open or shut.
12
+ */
9
13
  const turnMotion = motion("folded-turns", "open", "reveal");
10
14
  /** FoldedTurns' fixed words; override them under `foldedTurns` in LocaleProvider's `strings`. */
11
15
  export const foldedTurnsStrings = {
@@ -7,7 +7,10 @@ import { useCopy } from "../lib/use-copy.js";
7
7
  import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip.js";
8
8
  import { useStrings } from "../blocks/locale.js";
9
9
  import { motion } from "../lib/motion.js";
10
- /** The tick or cross after the clipboard write settles. */
10
+ /**
11
+ * @motion pop:tick After the person copies, a tick (or a cross, if the browser refused the clipboard) pops in on the
12
+ * button once the browser has answered. Nothing shows before the answer, and under reduced motion it fades in.
13
+ */
11
14
  const tickMotion = motion("message-actions", "tick", "pop");
12
15
  /** MessageActions' fixed words; override them under `messageActions` in LocaleProvider's `strings`. */
13
16
  export const messageActionsStrings = {
@@ -12,8 +12,15 @@ import { Reasoning } from "./reasoning.js";
12
12
  import { ThreadEvent } from "./thread-event.js";
13
13
  import { useStrings } from "../blocks/locale.js";
14
14
  import { motion } from "../lib/motion.js";
15
- /** A message that arrived after the thread first drew rises in (Thread marks it `data-arrived`); loaded history is still. */
15
+ /**
16
+ * @motion arrive:arrive A message rises in when it is added to a Thread after the thread first drew, whether it is
17
+ * the person's or the agent's. Messages loaded with the thread, and a Message outside a Thread, are drawn still.
18
+ */
16
19
  const arriveMotion = motion("message", "arrive", "arrive");
20
+ /**
21
+ * @motion live:caret While a reply is still streaming, a caret blinks at the end of its text. It goes when the reply
22
+ * finishes or is interrupted, and under reduced motion it is a still bar.
23
+ */
17
24
  const caretMotion = motion("message", "caret", "live", { dur: 1000 });
18
25
  /** Message's fixed words; override them under `message` in LocaleProvider's `strings`. */
19
26
  export const messageStrings = {
@@ -16,6 +16,9 @@ export declare const payloadStrings: {
16
16
  *
17
17
  * Code is split into tokens (keywords, strings, comments…) rendered as spans of text, never as HTML. They're coloured
18
18
  * when `highlight` is set, or anywhere under `data-syntax="highlight"` (set it on `<html>` for the whole app).
19
+ *
20
+ * @motion tint:tint The copy button's background and text colour change when the pointer is over it, and a ring fades
21
+ * in when it takes keyboard focus.
19
22
  */
20
23
  declare function Payload({ language, text, title, bare, highlight, className, }: {
21
24
  /** Shown as the label, e.g. json, sql, python. Never executed or highlighted as HTML. */
@@ -32,6 +32,9 @@ const languageLabel = (lang, t) => {
32
32
  *
33
33
  * Code is split into tokens (keywords, strings, comments…) rendered as spans of text, never as HTML. They're coloured
34
34
  * when `highlight` is set, or anywhere under `data-syntax="highlight"` (set it on `<html>` for the whole app).
35
+ *
36
+ * @motion tint:tint The copy button's background and text colour change when the pointer is over it, and a ring fades
37
+ * in when it takes keyboard focus.
35
38
  */
36
39
  function Payload({ language, text, title, bare = false, highlight, className, }) {
37
40
  const { state, copy } = useCopy();
@@ -5,7 +5,10 @@ import { cn } from "../lib/utils.js";
5
5
  import { Skeleton } from "../ui/skeleton.js";
6
6
  import { useStrings } from "../blocks/locale.js";
7
7
  import { motion } from "../lib/motion.js";
8
- /** A suggestion pressed: 2.2's slight scale of 0.99. */
8
+ /**
9
+ * @motion press:press A suggestion shrinks slightly while it is held down and returns when it is let go. Under
10
+ * reduced motion no suggestion changes size.
11
+ */
9
12
  const pressMotion = motion("prompt-suggestions", "press", "press", { amp: "0.98" });
10
13
  /** PromptSuggestions' fixed words; override them under `promptSuggestions` in LocaleProvider's `strings`. */
11
14
  export const promptSuggestionsStrings = {
@@ -7,7 +7,15 @@ import { ShimmerLabel } from "../blocks/streaming-text.js";
7
7
  import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../ui/collapsible.js";
8
8
  import { useStrings } from "../blocks/locale.js";
9
9
  import { motion, useArrived } from "../lib/motion.js";
10
+ /**
11
+ * @motion arrive:arrive A step of reasoning rises in when the agent adds it while the reasoning is on screen. A step
12
+ * added while it is folded rises in when it is opened. The steps it was drawn with are still.
13
+ */
10
14
  const arriveMotion = motion("reasoning", "arrive", "arrive");
15
+ /**
16
+ * @motion reveal:open The steps open to their full height when the person opens the summary, or when the agent starts
17
+ * thinking, and the chevron turns with it; closing reverses both. Under reduced motion they snap open or shut.
18
+ */
11
19
  const turnMotion = motion("reasoning", "open", "reveal");
12
20
  /** Reasoning's fixed words; override them under `reasoning` in LocaleProvider's `strings`. */
13
21
  export const reasoningStrings = {
@@ -6,9 +6,12 @@ import { cn } from "../lib/utils.js";
6
6
  import { useStrings } from "../blocks/locale.js";
7
7
  import { useVirtualList } from "../lib/use-virtual-list.js";
8
8
  import { motion, useMotionAllowed } from "../lib/motion.js";
9
- /** The smooth scroll to the latest message. */
9
+ /**
10
+ * @motion move:scroll When the person presses Jump to latest, the thread glides down to the newest message. Under
11
+ * reduced motion it jumps. Opening the thread and following new messages while the person is at the bottom are never
12
+ * smooth scrolls.
13
+ */
10
14
  const scrollMotion = motion("thread", "scroll", "move");
11
- /** Jump to latest appearing while the reader is scrolled up: 2.2's 150 ms and 4 px rise. */
12
15
  /** How long the animations running on `el` take in all, in milliseconds (the longest of duration × iteration count, capped at 6 s); undefined when it can't be read. */
13
16
  function animationMs(el) {
14
17
  if (!el || typeof getComputedStyle === "undefined")
@@ -19,8 +22,15 @@ function animationMs(el) {
19
22
  const totals = durations.map((d, i) => d * (counts[i % counts.length] || 1)).filter((n) => Number.isFinite(n) || n === Number.POSITIVE_INFINITY);
20
23
  return totals.length ? Math.min(6000, Math.max(...totals)) : undefined;
21
24
  }
25
+ /**
26
+ * @motion arrive:jump The Jump to latest control fades in when the person scrolls up from the bottom and goes when
27
+ * they return. It is not shown for a thread that has no messages.
28
+ */
22
29
  const jumpMotion = motion("thread", "jump", "arrive", { dur: 150 });
23
- /** Its ring when a message arrives while the reader is scrolled up. */
30
+ /**
31
+ * @motion attention:arrival While the person is scrolled up, Jump to latest pulses once each time a new message
32
+ * arrives, then is still. Nothing pulses at the bottom, where the new message is already in view.
33
+ */
24
34
  const arrivalMotion = motion("thread", "arrival", "attention");
25
35
  /** Thread's fixed words; override them under `thread` in LocaleProvider's `strings`. */
26
36
  export const threadStrings = {
@@ -10,8 +10,15 @@ import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../ui/colla
10
10
  import { Payload } from "./payload.js";
11
11
  import { useStrings } from "../blocks/locale.js";
12
12
  import { motion } from "../lib/motion.js";
13
- /** A call's detail opening, and a group of calls. */
13
+ /**
14
+ * @motion reveal:open A call's detail opens to its full height when the person opens it, and the chevron turns with
15
+ * it; closing reverses both. Under reduced motion it snaps open or shut.
16
+ */
14
17
  const openMotion = motion("tool-call", "open", "reveal");
18
+ /**
19
+ * @motion reveal:group-open A group of calls opens to its full height when the person opens it, and its chevron turns
20
+ * with it; closing reverses both. Under reduced motion it snaps open or shut.
21
+ */
15
22
  const groupMotion = motion("tool-call", "group-open", "reveal");
16
23
  /** ToolCall's fixed words; override them under `toolCall` in LocaleProvider's `strings`. */
17
24
  export const toolCallStrings = {
@@ -16,8 +16,8 @@ declare function AccordionTrigger(allProps: React.ComponentProps<typeof Accordio
16
16
  * The panel. It opens and closes to the height Radix measured, so a change is seen settling rather than snapping;
17
17
  * data-motion="none" and the OS's reduced-motion setting make it snap.
18
18
  *
19
- * @motion reveal:open The panel grows to its measured height when opened and shrinks back when closed, in the base
20
- * duration. Content the app puts in it is not animated.
19
+ * @motion reveal:open The panel grows to its full height when the person opens it and shrinks back when they close it.
20
+ * What the app puts inside it doesn't move. Under reduced motion the panel snaps open or shut.
21
21
  */
22
22
  declare function AccordionContent(allProps: React.ComponentProps<typeof AccordionPrimitive.Content> & RenderProp): React.JSX.Element;
23
23
  export { Accordion, AccordionItem, AccordionTrigger, AccordionContent };
@@ -32,8 +32,8 @@ function AccordionTrigger(allProps) {
32
32
  * The panel. It opens and closes to the height Radix measured, so a change is seen settling rather than snapping;
33
33
  * data-motion="none" and the OS's reduced-motion setting make it snap.
34
34
  *
35
- * @motion reveal:open The panel grows to its measured height when opened and shrinks back when closed, in the base
36
- * duration. Content the app puts in it is not animated.
35
+ * @motion reveal:open The panel grows to its full height when the person opens it and shrinks back when they close it.
36
+ * What the app puts inside it doesn't move. Under reduced motion the panel snaps open or shut.
37
37
  */
38
38
  function AccordionContent(allProps) {
39
39
  const { className, children, render, nativeButton: _nativeButton, style, ...props } = allProps;
@@ -7,9 +7,8 @@ import * as React from "react";
7
7
  * For a short notice that goes away by itself use a toast; an Alert doesn't dismiss itself.
8
8
  *
9
9
  * @motion arrive:enter An Alert that appears after the page has drawn rises in over a quarter of a second. One that is
10
- * there when the page first draws, or when it is rendered on the server, is simply there. "After the page has drawn" is
11
- * counted from when the page loaded, not from the route: after a client-side navigation, an Alert on the new route
12
- * rises in.
10
+ * there when the page first draws, or that the server rendered, is simply there; after a client-side navigation, an
11
+ * Alert on the new route rises in.
13
12
  */
14
13
  declare function Alert({ className, variant, role, style, ...props }: React.ComponentProps<"div"> & {
15
14
  /** The kind of message. `destructive` is for a failure or something that can't be undone; `warning` for care before acting; `attention` for something waiting on the person; `success` for a confirmed result. Defaults to a plain card. */
package/dist/ui/alert.js CHANGED
@@ -36,9 +36,8 @@ const alertVariants = cva("relative grid w-full grid-cols-[0_1fr] items-start ga
36
36
  * For a short notice that goes away by itself use a toast; an Alert doesn't dismiss itself.
37
37
  *
38
38
  * @motion arrive:enter An Alert that appears after the page has drawn rises in over a quarter of a second. One that is
39
- * there when the page first draws, or when it is rendered on the server, is simply there. "After the page has drawn" is
40
- * counted from when the page loaded, not from the route: after a client-side navigation, an Alert on the new route
41
- * rises in.
39
+ * there when the page first draws, or that the server rendered, is simply there; after a client-side navigation, an
40
+ * Alert on the new route rises in.
42
41
  */
43
42
  function Alert({ className, variant, role, style, ...props }) {
44
43
  // Whether this Alert mounted after the page's first draw. The server and the hydrating render answer no, so what
package/dist/ui/button.js CHANGED
@@ -6,6 +6,10 @@ import { Slot } from "radix-ui";
6
6
  import { withRender } from "../lib/render-prop.js";
7
7
  import { cn } from "../lib/utils.js";
8
8
  import { motion } from "../lib/motion.js";
9
+ /**
10
+ * @motion press:press The button shrinks a little while it is held down and returns when it is let go. A button that
11
+ * is locked or disabled never moves, and under reduced motion no button changes size.
12
+ */
9
13
  const pressMotion = motion("button", "press", "press");
10
14
  // The accent fills the one primary act, the radius is the theme's
11
15
  // --cd-radius-button, and buttons press down slightly on :active.
@@ -4,6 +4,11 @@ import { Collapsible as CollapsiblePrimitive } from "radix-ui";
4
4
  import { cn } from "../lib/utils.js";
5
5
  import { withRender } from "../lib/render-prop.js";
6
6
  import { motion } from "../lib/motion.js";
7
+ /**
8
+ * @motion reveal:open The content grows to its full height when the person opens it and shrinks when they close it. A
9
+ * collapsible that is already open when it first appears is shown open at once, and under reduced motion it snaps
10
+ * open or shut.
11
+ */
7
12
  const openMotion = motion("collapsible", "open", "reveal");
8
13
  function Collapsible({ ...props }) {
9
14
  return _jsx(CollapsiblePrimitive.Root, { "data-slot": "collapsible", ...props });
@@ -5,6 +5,10 @@ import { cn } from "../lib/utils.js";
5
5
  import { Popover as PopoverPrimitive } from "radix-ui";
6
6
  import { withRender } from "../lib/render-prop.js";
7
7
  import { motion } from "../lib/motion.js";
8
+ /**
9
+ * @motion overlay:open The popover fades in and scales up a little from its trigger when the person opens it, and
10
+ * fades out when it closes. Under reduced motion it is a short fade.
11
+ */
8
12
  const openMotion = motion("popover", "open", "overlay");
9
13
  function Popover({ ...props }) {
10
14
  return _jsx(PopoverPrimitive.Root, { "data-slot": "popover", ...props });
@@ -1,7 +1,10 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { cn } from "../lib/utils.js";
3
3
  import { motion } from "../lib/motion.js";
4
- /** Pulses while the content it stands in for is being fetched; still at level 0 and under calm. */
4
+ /**
5
+ * @motion live:loading The placeholder pulses softly for as long as it is on screen, which should be only while the
6
+ * content it stands in for is being fetched. Under reduced motion it is still.
7
+ */
5
8
  const loadingMotion = motion("skeleton", "loading", "live", { dur: 2000 });
6
9
  function Skeleton({ className, style, ...props }) {
7
10
  return (_jsx("div", { "data-slot": "skeleton", style: { ...loadingMotion, ...style }, className: cn("cd-live-pulse rounded-md bg-accent", className), ...props }));
@@ -9,7 +9,7 @@ import { type RenderProp } from "../lib/render-prop.js";
9
9
  *
10
10
  * @motion clock:drag The thumb and the filled range follow the pointer exactly, with no easing: what moves is the
11
11
  * person's hand, not an animation.
12
- * @motion tint:focus The thumb's ring grows in on hover and keyboard focus.
12
+ * @motion tint:tint The thumb's ring fades in when the pointer is over it and when it takes keyboard focus.
13
13
  */
14
14
  declare function Slider(allProps: SliderProps): React.JSX.Element;
15
15
  type SliderProps = React.ComponentProps<typeof SliderPrimitive.Root> & RenderProp & {
package/dist/ui/slider.js CHANGED
@@ -14,7 +14,7 @@ const lockedKeys = new Set(["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", "
14
14
  *
15
15
  * @motion clock:drag The thumb and the filled range follow the pointer exactly, with no easing: what moves is the
16
16
  * person's hand, not an animation.
17
- * @motion tint:focus The thumb's ring grows in on hover and keyboard focus.
17
+ * @motion tint:tint The thumb's ring fades in when the pointer is over it and when it takes keyboard focus.
18
18
  */
19
19
  function Slider(allProps) {
20
20
  const { className, locked, thumbLabels, value, defaultValue, min = 0, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, onPointerDownCapture, onKeyDownCapture, render, nativeButton: _nativeButton, children, ...props } = allProps;
@@ -5,6 +5,10 @@ import { cn } from "../lib/utils.js";
5
5
  import { Tooltip as TooltipPrimitive } from "radix-ui";
6
6
  import { withRender } from "../lib/render-prop.js";
7
7
  import { motion } from "../lib/motion.js";
8
+ /**
9
+ * @motion overlay:open The tooltip fades in and scales up a little from the control it describes once the delay has
10
+ * passed, and fades out when the pointer or focus leaves. Under reduced motion it is a short fade.
11
+ */
8
12
  const openMotion = motion("tooltip", "open", "overlay");
9
13
  // Whether a TooltipProvider is above, so a lone Tooltip can supply its own.
10
14
  const HasProvider = React.createContext(false);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@candor-ui/react",
3
- "version": "2.4.0",
3
+ "version": "2.5.0",
4
4
  "description": "Candor UI's free tier as an npm package: React components for agents that do real work, on shadcn/ui and Tailwind 4.",
5
5
  "license": "MIT",
6
6
  "author": "Methodic LLC",