@tinybigui/react 0.21.0 → 0.21.1

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.
package/README.md CHANGED
@@ -12,7 +12,7 @@ A modern, accessible React component library implementing Google's Material Desi
12
12
 
13
13
  ## ✅ Status
14
14
 
15
- > **Latest Release: v0.21.0** (2026-06-10)
15
+ > **Latest Release: v0.21.1** (2026-06-10)
16
16
  >
17
17
  > **29 MD3 components** published to npm with full TypeScript support and WCAG 2.1 AA accessibility.
18
18
  >
@@ -166,7 +166,7 @@ See [THEMING.md](./THEMING.md) for the full customization guide.
166
166
  | `Menu` | ✅ | Dropdown, context menu, submenus |
167
167
  | `Progress` | ✅ | MD3 expressive slot CVA, colorful tokens, wavy shape, thick track (v0.16.0) |
168
168
  | `BottomSheet` | ✅ | MD3 expressive handle, variants-vs-states architecture (v0.11.0) |
169
- | `Tooltip` | ✅ | Plain and rich tooltip with positioning |
169
+ | `Tooltip` | ✅ | Slot-based MD3 styling, reduced-motion guard, rich tooltip token fixes (v0.21.1) |
170
170
 
171
171
  ### Phase 4: Data Display ✅
172
172
 
package/dist/index.cjs CHANGED
@@ -8213,7 +8213,8 @@ function TooltipOverlayHeadless({
8213
8213
  }
8214
8214
  var TooltipAnimationContext = React.createContext({
8215
8215
  isExiting: false,
8216
- onAnimationEnd: () => void 0
8216
+ onAnimationEnd: () => void 0,
8217
+ reducedMotion: false
8217
8218
  });
8218
8219
  function useTooltipAnimation() {
8219
8220
  return React.useContext(TooltipAnimationContext);
@@ -8223,46 +8224,60 @@ function TooltipTrigger({
8223
8224
  delay = 300,
8224
8225
  isDisabled
8225
8226
  }) {
8227
+ const reducedMotion = useReducedMotion();
8226
8228
  const [isMounted, setIsMounted] = React.useState(false);
8227
8229
  const [isExiting, setIsExiting] = React.useState(false);
8228
8230
  const isExitingRef = React.useRef(false);
8229
8231
  const isPointerOverTooltipRef = React.useRef(false);
8230
8232
  const pendingCloseRef = React.useRef(false);
8231
- const handleOpenChange = React.useCallback((open) => {
8232
- if (open) {
8233
- pendingCloseRef.current = false;
8234
- isExitingRef.current = false;
8235
- setIsMounted(true);
8236
- setIsExiting(false);
8237
- } else if (isPointerOverTooltipRef.current) {
8238
- pendingCloseRef.current = true;
8239
- } else if (!isExitingRef.current) {
8240
- isExitingRef.current = true;
8241
- setIsExiting(true);
8242
- }
8243
- }, []);
8244
- const handleAnimationEnd = React.useCallback(() => {
8245
- if (!isExitingRef.current) return;
8233
+ const unmountImmediately = React.useCallback(() => {
8246
8234
  isExitingRef.current = false;
8247
8235
  pendingCloseRef.current = false;
8248
8236
  setIsMounted(false);
8249
8237
  setIsExiting(false);
8250
8238
  }, []);
8239
+ const handleOpenChange = React.useCallback(
8240
+ (open) => {
8241
+ if (open) {
8242
+ pendingCloseRef.current = false;
8243
+ isExitingRef.current = false;
8244
+ setIsMounted(true);
8245
+ setIsExiting(false);
8246
+ } else if (isPointerOverTooltipRef.current) {
8247
+ pendingCloseRef.current = true;
8248
+ } else if (reducedMotion) {
8249
+ unmountImmediately();
8250
+ } else if (!isExitingRef.current) {
8251
+ isExitingRef.current = true;
8252
+ setIsExiting(true);
8253
+ }
8254
+ },
8255
+ [reducedMotion, unmountImmediately]
8256
+ );
8257
+ const handleAnimationEnd = React.useCallback(() => {
8258
+ if (!isExitingRef.current) return;
8259
+ unmountImmediately();
8260
+ }, [unmountImmediately]);
8251
8261
  const handleOverlayPointerEnter = React.useCallback(() => {
8252
8262
  isPointerOverTooltipRef.current = true;
8253
8263
  pendingCloseRef.current = false;
8254
8264
  }, []);
8255
8265
  const handleOverlayPointerLeave = React.useCallback(() => {
8256
8266
  isPointerOverTooltipRef.current = false;
8257
- if (pendingCloseRef.current && !isExitingRef.current) {
8267
+ if (pendingCloseRef.current) {
8258
8268
  pendingCloseRef.current = false;
8259
- isExitingRef.current = true;
8260
- setIsExiting(true);
8269
+ if (reducedMotion) {
8270
+ unmountImmediately();
8271
+ } else if (!isExitingRef.current) {
8272
+ isExitingRef.current = true;
8273
+ setIsExiting(true);
8274
+ }
8261
8275
  }
8262
- }, []);
8276
+ }, [reducedMotion, unmountImmediately]);
8263
8277
  const contextValue = {
8264
8278
  isExiting,
8265
- onAnimationEnd: handleAnimationEnd
8279
+ onAnimationEnd: handleAnimationEnd,
8280
+ reducedMotion
8266
8281
  };
8267
8282
  const [triggerChild, tooltipChild] = children;
8268
8283
  const placement = React.isValidElement(tooltipChild) ? tooltipChild.props.placement ?? "top" : "top";
@@ -8291,51 +8306,69 @@ function TooltipTrigger({
8291
8306
  ) });
8292
8307
  }
8293
8308
  var tooltipVariants = classVarianceAuthority.cva(
8294
- "z-50 w-fit min-h-6 rounded-xs px-2 py-1 text-body-small bg-inverse-surface text-inverse-on-surface max-w-50",
8309
+ [
8310
+ "z-50 inline-flex items-center w-fit",
8311
+ "min-h-6 rounded-xs px-2 py-1",
8312
+ "text-body-small bg-inverse-surface text-inverse-on-surface",
8313
+ "max-w-50"
8314
+ ],
8295
8315
  {
8296
8316
  variants: {
8297
8317
  /**
8298
- * Drives the MD3 enter/exit animation class.
8318
+ * Controls the enter/exit animation class.
8299
8319
  * Managed by `TooltipTrigger`'s animation state machine.
8300
- * @default true
8320
+ * Set to `"none"` when `prefers-reduced-motion: reduce` is active.
8321
+ * @default "enter"
8301
8322
  */
8302
- isVisible: {
8303
- true: "animate-md-scale-in",
8304
- false: "animate-md-scale-out"
8323
+ animation: {
8324
+ enter: "animate-md-scale-in",
8325
+ exit: "animate-md-scale-out",
8326
+ none: ""
8305
8327
  }
8306
8328
  },
8307
8329
  defaultVariants: {
8308
- isVisible: true
8330
+ animation: "enter"
8309
8331
  }
8310
8332
  }
8311
8333
  );
8312
8334
  var richTooltipVariants = classVarianceAuthority.cva(
8313
- "z-50 w-fit min-h-6 rounded-md px-4 py-3 bg-surface-container text-on-surface shadow-elevation-2 max-w-80",
8335
+ [
8336
+ "z-50 flex flex-col w-fit",
8337
+ "min-h-6 rounded-md px-4 py-3",
8338
+ "bg-surface-container text-on-surface shadow-elevation-2",
8339
+ "max-w-80"
8340
+ ],
8314
8341
  {
8315
8342
  variants: {
8316
8343
  /**
8317
- * Drives the MD3 enter/exit animation class.
8344
+ * Controls the enter/exit animation class.
8318
8345
  * Managed by `TooltipTrigger`'s animation state machine.
8319
- * @default true
8346
+ * Set to `"none"` when `prefers-reduced-motion: reduce` is active.
8347
+ * @default "enter"
8320
8348
  */
8321
- isVisible: {
8322
- true: "animate-md-scale-in",
8323
- false: "animate-md-scale-out"
8349
+ animation: {
8350
+ enter: "animate-md-scale-in",
8351
+ exit: "animate-md-scale-out",
8352
+ none: ""
8324
8353
  }
8325
8354
  },
8326
8355
  defaultVariants: {
8327
- isVisible: true
8356
+ animation: "enter"
8328
8357
  }
8329
8358
  }
8330
8359
  );
8360
+ var richTooltipTitleVariants = classVarianceAuthority.cva(["text-title-small text-on-surface-variant mb-1"]);
8361
+ var richTooltipSupportingTextVariants = classVarianceAuthority.cva(["text-body-medium text-on-surface-variant"]);
8362
+ var richTooltipActionsVariants = classVarianceAuthority.cva(["flex items-center justify-start mt-3 -ml-2"]);
8331
8363
  var Tooltip = React.forwardRef(
8332
8364
  ({ children, className, placement: _placement }, ref) => {
8333
- const { isExiting, onAnimationEnd } = useTooltipAnimation();
8365
+ const { isExiting, onAnimationEnd, reducedMotion } = useTooltipAnimation();
8366
+ const animation = reducedMotion ? "none" : isExiting ? "exit" : "enter";
8334
8367
  return /* @__PURE__ */ jsxRuntime.jsx(
8335
8368
  "div",
8336
8369
  {
8337
8370
  ref,
8338
- className: cn(tooltipVariants({ isVisible: !isExiting }), className),
8371
+ className: cn(tooltipVariants({ animation }), className),
8339
8372
  onAnimationEnd,
8340
8373
  children
8341
8374
  }
@@ -8345,17 +8378,18 @@ var Tooltip = React.forwardRef(
8345
8378
  Tooltip.displayName = "Tooltip";
8346
8379
  var RichTooltip = React.forwardRef(
8347
8380
  ({ title, children, action, className, placement: _placement }, ref) => {
8348
- const { isExiting, onAnimationEnd } = useTooltipAnimation();
8381
+ const { isExiting, onAnimationEnd, reducedMotion } = useTooltipAnimation();
8382
+ const animation = reducedMotion ? "none" : isExiting ? "exit" : "enter";
8349
8383
  return /* @__PURE__ */ jsxRuntime.jsxs(
8350
8384
  "div",
8351
8385
  {
8352
8386
  ref,
8353
- className: cn(richTooltipVariants({ isVisible: !isExiting }), className),
8387
+ className: cn(richTooltipVariants({ animation }), className),
8354
8388
  onAnimationEnd,
8355
8389
  children: [
8356
- title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-on-surface text-title-small mb-1", children: title }),
8357
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-on-surface-variant text-body-medium", children }),
8358
- action
8390
+ title && /* @__PURE__ */ jsxRuntime.jsx("p", { className: richTooltipTitleVariants(), children: title }),
8391
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: richTooltipSupportingTextVariants(), children }),
8392
+ action && /* @__PURE__ */ jsxRuntime.jsx("div", { className: richTooltipActionsVariants(), children: action })
8359
8393
  ]
8360
8394
  }
8361
8395
  );