@bearmenu/ui 0.8.47 → 0.8.48

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.
@@ -4,7 +4,7 @@ import * as React from 'react';
4
4
  import { VariantProps } from 'class-variance-authority';
5
5
 
6
6
  declare const badgeVariants: (props?: ({
7
- variant?: "secondary" | "default" | "success" | "warning" | "destructive" | "outline" | "glass" | "overlay" | "brown" | "code" | "onPrimary" | "confirmed" | "pending" | "completed" | "assignee" | "softSuccess" | "softWarning" | "softDestructive" | "softNeutral" | null | undefined;
7
+ variant?: "default" | "secondary" | "success" | "warning" | "destructive" | "outline" | "glass" | "overlay" | "brown" | "code" | "onPrimary" | "confirmed" | "pending" | "completed" | "assignee" | "softSuccess" | "softWarning" | "softDestructive" | "softNeutral" | null | undefined;
8
8
  size?: "status" | "chip" | null | undefined;
9
9
  live?: boolean | null | undefined;
10
10
  } & class_variance_authority_types.ClassProp) | undefined) => string;
@@ -3,8 +3,8 @@ import * as React from 'react';
3
3
  import { VariantProps } from 'class-variance-authority';
4
4
 
5
5
  declare const buttonVariants: (props?: ({
6
- variant?: "secondary" | "default" | "link" | "warning" | "destructive" | "outline" | "ghost" | "glass" | "overlay" | "ink" | "brown" | "cta" | null | undefined;
7
- size?: "default" | "icon" | "cta" | "xs" | "sm" | "lg" | "pill" | "cta-sm" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
6
+ variant?: "default" | "link" | "secondary" | "warning" | "destructive" | "outline" | "ghost" | "glass" | "overlay" | "ink" | "brown" | "cta" | null | undefined;
7
+ size?: "icon" | "default" | "cta" | "xs" | "sm" | "lg" | "pill" | "cta-sm" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
8
8
  fullWidth?: boolean | null | undefined;
9
9
  } & class_variance_authority_types.ClassProp) | undefined) => string;
10
10
  interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
@@ -77,6 +77,7 @@ type CoachMarksLabels = {
77
77
  next: string;
78
78
  /** The last stop's forward action, e.g. "Done". */
79
79
  done: string;
80
+ /** The corner X's accessible name, e.g. "Skip tour"; not drawn as text. */
80
81
  skip: string;
81
82
  };
82
83
  type CoachMarksProps = {
@@ -5,7 +5,7 @@ import { cn } from '../chunk-FEK5XGZW.js';
5
5
  import '../chunk-MMUBH76A.js';
6
6
  import { useState, useLayoutEffect, useCallback, useRef, useEffect } from 'react';
7
7
  import { createPortal } from 'react-dom';
8
- import { Lightbulb, ArrowRight } from 'lucide-react';
8
+ import { Lightbulb, X, ArrowRight } from 'lucide-react';
9
9
  import { jsxs, jsx } from 'react/jsx-runtime';
10
10
 
11
11
  var PAD = 8;
@@ -203,14 +203,38 @@ function CoachMarks({
203
203
  style: { left: caretLeft }
204
204
  }
205
205
  ),
206
- /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5 rounded-full bg-[oklch(0.82_0.15_85)] px-2.5 py-1 text-xs font-extrabold uppercase tracking-[0.08em] text-[oklch(0.26_0.03_60)]", children: [
207
- /* @__PURE__ */ jsx(Lightbulb, { className: "h-3 w-3", "aria-hidden": true }),
208
- labels.progress(index + 1, available.length)
206
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
207
+ /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5 rounded-full bg-[oklch(0.82_0.15_85)] px-2.5 py-1 text-xs font-extrabold uppercase tracking-[0.08em] text-[oklch(0.26_0.03_60)]", children: [
208
+ /* @__PURE__ */ jsx(Lightbulb, { className: "h-3 w-3", "aria-hidden": true }),
209
+ labels.progress(index + 1, available.length)
210
+ ] }),
211
+ /* @__PURE__ */ jsx(
212
+ Button,
213
+ {
214
+ type: "button",
215
+ variant: "ghost",
216
+ size: "icon",
217
+ className: "-my-2.5 -mr-2.5 shrink-0 text-muted-foreground hover:text-foreground",
218
+ "aria-label": labels.skip,
219
+ onClick: onClose,
220
+ children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4", "aria-hidden": true })
221
+ }
222
+ )
209
223
  ] }),
210
224
  /* @__PURE__ */ jsx("p", { className: "mt-3 text-base font-semibold leading-snug", children: current.title }),
211
225
  /* @__PURE__ */ jsx("p", { className: "mt-1.5 text-sm leading-relaxed text-muted-foreground", children: current.body }),
212
- /* @__PURE__ */ jsxs("div", { className: "mt-4 flex items-center gap-2", children: [
213
- index > 0 && /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "pill", onClick: () => setIndex(index - 1), children: labels.back }),
226
+ /* @__PURE__ */ jsxs("div", { className: "mt-4 flex flex-wrap items-center justify-end gap-2", children: [
227
+ index > 0 && /* @__PURE__ */ jsx(
228
+ Button,
229
+ {
230
+ type: "button",
231
+ variant: "ghost",
232
+ size: "pill",
233
+ className: "mr-auto",
234
+ onClick: () => setIndex(index - 1),
235
+ children: labels.back
236
+ }
237
+ ),
214
238
  /* @__PURE__ */ jsxs(
215
239
  Button,
216
240
  {
@@ -222,17 +246,6 @@ function CoachMarks({
222
246
  !last && /* @__PURE__ */ jsx(ArrowRight, { "aria-hidden": true })
223
247
  ]
224
248
  }
225
- ),
226
- /* @__PURE__ */ jsx(
227
- Button,
228
- {
229
- type: "button",
230
- variant: "link",
231
- size: "sm",
232
- className: "ml-auto min-h-11",
233
- onClick: onClose,
234
- children: labels.skip
235
- }
236
249
  )
237
250
  ] })
238
251
  ]
@@ -28,7 +28,7 @@ declare const CommandInput: React.ForwardRefExoticComponent<Omit<Omit<Pick<Pick<
28
28
  ref?: React.Ref<HTMLInputElement>;
29
29
  } & {
30
30
  asChild?: boolean;
31
- }, "asChild" | "key" | keyof React.InputHTMLAttributes<HTMLInputElement>>, "onChange" | "value" | "type"> & {
31
+ }, "asChild" | "key" | keyof React.InputHTMLAttributes<HTMLInputElement>>, "value" | "onChange" | "type"> & {
32
32
  value?: string;
33
33
  onValueChange?: (search: string) => void;
34
34
  } & React.RefAttributes<HTMLInputElement>, "ref"> & React.RefAttributes<HTMLInputElement>>;
@@ -64,7 +64,7 @@ declare const CommandGroup: React.ForwardRefExoticComponent<Omit<{
64
64
  ref?: React.Ref<HTMLDivElement>;
65
65
  } & {
66
66
  asChild?: boolean;
67
- }, keyof React.HTMLAttributes<HTMLDivElement> | "asChild" | "key">, "heading" | "value"> & {
67
+ }, keyof React.HTMLAttributes<HTMLDivElement> | "asChild" | "key">, "value" | "heading"> & {
68
68
  heading?: React.ReactNode;
69
69
  value?: string;
70
70
  forceMount?: boolean;
@@ -82,7 +82,7 @@ declare const CommandItem: React.ForwardRefExoticComponent<Omit<{
82
82
  ref?: React.Ref<HTMLDivElement>;
83
83
  } & {
84
84
  asChild?: boolean;
85
- }, keyof React.HTMLAttributes<HTMLDivElement> | "asChild" | "key">, "onSelect" | "value" | "disabled"> & {
85
+ }, keyof React.HTMLAttributes<HTMLDivElement> | "asChild" | "key">, "value" | "onSelect" | "disabled"> & {
86
86
  disabled?: boolean;
87
87
  onSelect?: (value: string) => void;
88
88
  value?: string;
@@ -4,11 +4,11 @@ import { VariantProps } from 'class-variance-authority';
4
4
 
5
5
  declare const spinnerVariants: (props?: ({
6
6
  size?: "default" | "xs" | "sm" | "lg" | "xl" | null | undefined;
7
- tone?: "primary" | "default" | "inherit" | "destructive" | null | undefined;
7
+ tone?: "default" | "inherit" | "primary" | "destructive" | null | undefined;
8
8
  } & class_variance_authority_types.ClassProp) | undefined) => string;
9
9
  declare const Spinner: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLSpanElement> & VariantProps<(props?: ({
10
10
  size?: "default" | "xs" | "sm" | "lg" | "xl" | null | undefined;
11
- tone?: "primary" | "default" | "inherit" | "destructive" | null | undefined;
11
+ tone?: "default" | "inherit" | "primary" | "destructive" | null | undefined;
12
12
  } & class_variance_authority_types.ClassProp) | undefined) => string> & {
13
13
  /** Visually-hidden label for screen readers. Defaults to "Loading". */
14
14
  label?: string;
@@ -3,11 +3,11 @@ import * as React from 'react';
3
3
  import { VariantProps } from 'class-variance-authority';
4
4
 
5
5
  declare const tagVariants: (props?: ({
6
- variant?: "primary" | "default" | "success" | "warning" | "destructive" | "outline" | "quiet" | null | undefined;
6
+ variant?: "default" | "primary" | "success" | "warning" | "destructive" | "outline" | "quiet" | null | undefined;
7
7
  size?: "default" | "sm" | "lg" | null | undefined;
8
8
  } & class_variance_authority_types.ClassProp) | undefined) => string;
9
9
  declare const Tag: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLSpanElement> & VariantProps<(props?: ({
10
- variant?: "primary" | "default" | "success" | "warning" | "destructive" | "outline" | "quiet" | null | undefined;
10
+ variant?: "default" | "primary" | "success" | "warning" | "destructive" | "outline" | "quiet" | null | undefined;
11
11
  size?: "default" | "sm" | "lg" | null | undefined;
12
12
  } & class_variance_authority_types.ClassProp) | undefined) => string> & {
13
13
  onRemove?: () => void;
@@ -22,8 +22,8 @@ import { VariantProps } from 'class-variance-authority';
22
22
  * Weights are 400 / 600 / 700. 500 is not in the system.
23
23
  */
24
24
  declare const textVariants: (props?: ({
25
- variant?: "small" | "body" | "display" | "h2" | "h3" | "label" | "caption" | "h1" | "h4" | "body-lg" | "body-sm" | "overline" | null | undefined;
26
- color?: "primary" | "default" | "inherit" | "destructive" | "muted" | "primary-foreground" | null | undefined;
25
+ variant?: "body" | "small" | "display" | "h2" | "h3" | "label" | "caption" | "h1" | "h4" | "body-lg" | "body-sm" | "overline" | null | undefined;
26
+ color?: "default" | "inherit" | "primary" | "destructive" | "muted" | "primary-foreground" | null | undefined;
27
27
  weight?: "bold" | "medium" | "normal" | "semibold" | null | undefined;
28
28
  leading?: "none" | "normal" | "tight" | "snug" | "relaxed" | "loose" | null | undefined;
29
29
  tracking?: "normal" | "tight" | "wide" | "wider" | null | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bearmenu/ui",
3
- "version": "0.8.47",
3
+ "version": "0.8.48",
4
4
  "description": "BearMenu design system — shared UI tokens, primitives, and components",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
@@ -127,7 +127,7 @@ describe("CoachMarks", () => {
127
127
  it("Skip and Escape close; the dimmed page does not", () => {
128
128
  const onClose = vi.fn();
129
129
  render(<Page onClose={onClose} />);
130
- fireEvent.click(screen.getByText("Skip"));
130
+ fireEvent.click(screen.getByRole("button", { name: "Skip" }));
131
131
  fireEvent.keyDown(window, { key: "Escape" });
132
132
  expect(onClose).toHaveBeenCalledTimes(2);
133
133
  expect(screen.getAllByRole("button", { name: "Skip" })).toHaveLength(1);
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
4
4
  import { createPortal } from "react-dom";
5
- import { ArrowRight, Lightbulb } from "lucide-react";
5
+ import { ArrowRight, Lightbulb, X } from "lucide-react";
6
6
  import { cn } from "../lib/utils";
7
7
  import { Button } from "./button";
8
8
 
@@ -86,6 +86,7 @@ export type CoachMarksLabels = {
86
86
  next: string;
87
87
  /** The last stop's forward action, e.g. "Done". */
88
88
  done: string;
89
+ /** The corner X's accessible name, e.g. "Skip tour"; not drawn as text. */
89
90
  skip: string;
90
91
  };
91
92
 
@@ -374,15 +375,35 @@ export function CoachMarks({
374
375
  style={{ left: caretLeft }}
375
376
  />
376
377
  )}
377
- <span className="inline-flex items-center gap-1.5 rounded-full bg-[oklch(0.82_0.15_85)] px-2.5 py-1 text-xs font-extrabold uppercase tracking-[0.08em] text-[oklch(0.26_0.03_60)]">
378
- <Lightbulb className="h-3 w-3" aria-hidden />
379
- {labels.progress(index + 1, available.length)}
380
- </span>
378
+ {/* Skip is chrome, not a step action: the corner X keeps the footer
379
+ to Back and Next, which fit the callout in any locale. */}
380
+ <div className="flex items-center justify-between gap-2">
381
+ <span className="inline-flex items-center gap-1.5 rounded-full bg-[oklch(0.82_0.15_85)] px-2.5 py-1 text-xs font-extrabold uppercase tracking-[0.08em] text-[oklch(0.26_0.03_60)]">
382
+ <Lightbulb className="h-3 w-3" aria-hidden />
383
+ {labels.progress(index + 1, available.length)}
384
+ </span>
385
+ <Button
386
+ type="button"
387
+ variant="ghost"
388
+ size="icon"
389
+ className="-my-2.5 -mr-2.5 shrink-0 text-muted-foreground hover:text-foreground"
390
+ aria-label={labels.skip}
391
+ onClick={onClose}
392
+ >
393
+ <X className="h-4 w-4" aria-hidden />
394
+ </Button>
395
+ </div>
381
396
  <p className="mt-3 text-base font-semibold leading-snug">{current.title}</p>
382
397
  <p className="mt-1.5 text-sm leading-relaxed text-muted-foreground">{current.body}</p>
383
- <div className="mt-4 flex items-center gap-2">
398
+ <div className="mt-4 flex flex-wrap items-center justify-end gap-2">
384
399
  {index > 0 && (
385
- <Button type="button" variant="ghost" size="pill" onClick={() => setIndex(index - 1)}>
400
+ <Button
401
+ type="button"
402
+ variant="ghost"
403
+ size="pill"
404
+ className="mr-auto"
405
+ onClick={() => setIndex(index - 1)}
406
+ >
386
407
  {labels.back}
387
408
  </Button>
388
409
  )}
@@ -394,15 +415,6 @@ export function CoachMarks({
394
415
  {last ? labels.done : labels.next}
395
416
  {!last && <ArrowRight aria-hidden />}
396
417
  </Button>
397
- <Button
398
- type="button"
399
- variant="link"
400
- size="sm"
401
- className="ml-auto min-h-11"
402
- onClick={onClose}
403
- >
404
- {labels.skip}
405
- </Button>
406
418
  </div>
407
419
  </div>
408
420
  </div>,