@bug-on/m3-expressive 1.2.0 → 1.2.2

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.
Files changed (54) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/buttons.d.mts +26 -5
  3. package/dist/buttons.d.ts +26 -5
  4. package/dist/buttons.js +1074 -765
  5. package/dist/buttons.js.map +1 -1
  6. package/dist/buttons.mjs +1066 -765
  7. package/dist/buttons.mjs.map +1 -1
  8. package/dist/core.js +133 -69
  9. package/dist/core.js.map +1 -1
  10. package/dist/core.mjs +133 -69
  11. package/dist/core.mjs.map +1 -1
  12. package/dist/feedback.js +132 -69
  13. package/dist/feedback.js.map +1 -1
  14. package/dist/feedback.mjs +132 -69
  15. package/dist/feedback.mjs.map +1 -1
  16. package/dist/forms.d.mts +2 -2
  17. package/dist/forms.d.ts +2 -2
  18. package/dist/forms.js +74 -9
  19. package/dist/forms.js.map +1 -1
  20. package/dist/forms.mjs +74 -9
  21. package/dist/forms.mjs.map +1 -1
  22. package/dist/{icon-button-D-gs0gfj.d.mts → icon-button-CSsDmuQC.d.mts} +19 -0
  23. package/dist/{icon-button-D-gs0gfj.d.ts → icon-button-CSsDmuQC.d.ts} +19 -0
  24. package/dist/index.d.mts +4 -4
  25. package/dist/index.d.ts +4 -4
  26. package/dist/index.js +2204 -1464
  27. package/dist/index.js.map +1 -1
  28. package/dist/index.mjs +2056 -1324
  29. package/dist/index.mjs.map +1 -1
  30. package/dist/layout.d.mts +18 -1
  31. package/dist/layout.d.ts +18 -1
  32. package/dist/layout.js +80 -15
  33. package/dist/layout.js.map +1 -1
  34. package/dist/layout.mjs +80 -15
  35. package/dist/layout.mjs.map +1 -1
  36. package/dist/navigation.d.mts +134 -9
  37. package/dist/navigation.d.ts +134 -9
  38. package/dist/navigation.js +461 -101
  39. package/dist/navigation.js.map +1 -1
  40. package/dist/navigation.mjs +455 -102
  41. package/dist/navigation.mjs.map +1 -1
  42. package/dist/overlays.js +261 -197
  43. package/dist/overlays.js.map +1 -1
  44. package/dist/overlays.mjs +223 -159
  45. package/dist/overlays.mjs.map +1 -1
  46. package/dist/pickers.js +392 -301
  47. package/dist/pickers.js.map +1 -1
  48. package/dist/pickers.mjs +361 -270
  49. package/dist/pickers.mjs.map +1 -1
  50. package/dist/{split-button-trailing-uncheckable-BkPbiBo3.d.ts → split-button-trailing-uncheckable-C-qQlyZx.d.ts} +118 -25
  51. package/dist/{split-button-trailing-uncheckable-D_PLPb-u.d.mts → split-button-trailing-uncheckable-DHJqNeq_.d.mts} +118 -25
  52. package/dist/{text-field-eAIpz9z1.d.mts → text-field-T4Rg-9Bw.d.mts} +7 -0
  53. package/dist/{text-field-eAIpz9z1.d.ts → text-field-T4Rg-9Bw.d.ts} +7 -0
  54. package/package.json +3 -3
package/dist/layout.d.mts CHANGED
@@ -30,6 +30,12 @@ interface CardProps extends MotionDivProps, VariantProps<typeof cardVariants> {
30
30
  /** rel for `<a>` element (automatically adds `noreferrer` when `target="_blank"`). */
31
31
  rel?: string;
32
32
  children?: React.ReactNode;
33
+ /**
34
+ * Change the component to the underlying child element and merge props/behavior.
35
+ * Useful when wrapping in Next.js `<Link>` or custom anchor tags.
36
+ * @default false
37
+ */
38
+ asChild?: boolean;
33
39
  }
34
40
  declare const Card: React.NamedExoticComponent<Omit<CardProps, "ref"> & React.RefAttributes<HTMLElement>>;
35
41
 
@@ -373,10 +379,21 @@ declare function shouldTopAlign(height: number): boolean;
373
379
  declare function getExpressiveShape(state: "resting" | "hovered" | "focused" | "pressed" | "selected" | "dragged" | "disabled"): number;
374
380
 
375
381
  declare const typographyVariants: (props?: ({
376
- variant?: "display-lg" | "display-md" | "display-sm" | "headline-lg" | "headline-md" | "headline-sm" | "title-lg" | "title-md" | "title-sm" | "label-lg" | "label-md" | "label-sm" | "body-lg" | "body-md" | "body-sm" | null | undefined;
382
+ variant?: "display-lg" | "display-md" | "display-sm" | "headline-lg" | "headline-md" | "headline-sm" | "title-lg" | "title-md" | "title-sm" | "label-lg" | "label-md" | "label-sm" | "body-lg" | "body-md" | "body-sm" | "display-large" | "display-medium" | "display-small" | "headline-large" | "headline-medium" | "headline-small" | "title-large" | "title-medium" | "title-small" | "label-large" | "label-medium" | "label-small" | "body-large" | "body-medium" | "body-small" | "displayLarge" | "displayMedium" | "displaySmall" | "headlineLarge" | "headlineMedium" | "headlineSmall" | "titleLarge" | "titleMedium" | "titleSmall" | "labelLarge" | "labelMedium" | "labelSmall" | "bodyLarge" | "bodyMedium" | "bodySmall" | null | undefined;
377
383
  } & class_variance_authority_types.ClassProp) | undefined) => string;
378
384
  interface TextProps extends React.HTMLAttributes<HTMLElement>, VariantProps<typeof typographyVariants> {
385
+ /**
386
+ * Custom HTML element tag override.
387
+ */
379
388
  as?: React.ElementType;
389
+ /**
390
+ * Text color override (CSS color value or Tailwind color class).
391
+ */
392
+ color?: string;
393
+ /**
394
+ * Font weight override.
395
+ */
396
+ weight?: string | number;
380
397
  }
381
398
  declare const Text: React.ForwardRefExoticComponent<TextProps & React.RefAttributes<HTMLElement>>;
382
399
 
package/dist/layout.d.ts CHANGED
@@ -30,6 +30,12 @@ interface CardProps extends MotionDivProps, VariantProps<typeof cardVariants> {
30
30
  /** rel for `<a>` element (automatically adds `noreferrer` when `target="_blank"`). */
31
31
  rel?: string;
32
32
  children?: React.ReactNode;
33
+ /**
34
+ * Change the component to the underlying child element and merge props/behavior.
35
+ * Useful when wrapping in Next.js `<Link>` or custom anchor tags.
36
+ * @default false
37
+ */
38
+ asChild?: boolean;
33
39
  }
34
40
  declare const Card: React.NamedExoticComponent<Omit<CardProps, "ref"> & React.RefAttributes<HTMLElement>>;
35
41
 
@@ -373,10 +379,21 @@ declare function shouldTopAlign(height: number): boolean;
373
379
  declare function getExpressiveShape(state: "resting" | "hovered" | "focused" | "pressed" | "selected" | "dragged" | "disabled"): number;
374
380
 
375
381
  declare const typographyVariants: (props?: ({
376
- variant?: "display-lg" | "display-md" | "display-sm" | "headline-lg" | "headline-md" | "headline-sm" | "title-lg" | "title-md" | "title-sm" | "label-lg" | "label-md" | "label-sm" | "body-lg" | "body-md" | "body-sm" | null | undefined;
382
+ variant?: "display-lg" | "display-md" | "display-sm" | "headline-lg" | "headline-md" | "headline-sm" | "title-lg" | "title-md" | "title-sm" | "label-lg" | "label-md" | "label-sm" | "body-lg" | "body-md" | "body-sm" | "display-large" | "display-medium" | "display-small" | "headline-large" | "headline-medium" | "headline-small" | "title-large" | "title-medium" | "title-small" | "label-large" | "label-medium" | "label-small" | "body-large" | "body-medium" | "body-small" | "displayLarge" | "displayMedium" | "displaySmall" | "headlineLarge" | "headlineMedium" | "headlineSmall" | "titleLarge" | "titleMedium" | "titleSmall" | "labelLarge" | "labelMedium" | "labelSmall" | "bodyLarge" | "bodyMedium" | "bodySmall" | null | undefined;
377
383
  } & class_variance_authority_types.ClassProp) | undefined) => string;
378
384
  interface TextProps extends React.HTMLAttributes<HTMLElement>, VariantProps<typeof typographyVariants> {
385
+ /**
386
+ * Custom HTML element tag override.
387
+ */
379
388
  as?: React.ElementType;
389
+ /**
390
+ * Text color override (CSS color value or Tailwind color class).
391
+ */
392
+ color?: string;
393
+ /**
394
+ * Font weight override.
395
+ */
396
+ weight?: string | number;
380
397
  }
381
398
  declare const Text: React.ForwardRefExoticComponent<TextProps & React.RefAttributes<HTMLElement>>;
382
399
 
package/dist/layout.js CHANGED
@@ -1,13 +1,13 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
+ var reactSlot = require('@radix-ui/react-slot');
4
5
  var classVarianceAuthority = require('class-variance-authority');
5
6
  var react = require('motion/react');
6
7
  var React18 = require('react');
7
8
  var clsx = require('clsx');
8
9
  var tailwindMerge = require('tailwind-merge');
9
10
  var jsxRuntime = require('react/jsx-runtime');
10
- var reactSlot = require('@radix-ui/react-slot');
11
11
  var m3Tokens = require('@bug-on/m3-tokens');
12
12
  var RadixScrollArea = require('@radix-ui/react-scroll-area');
13
13
  var core = require('@dnd-kit/core');
@@ -128,7 +128,10 @@ function useRippleState(options = {}) {
128
128
  const rect = e.currentTarget.getBoundingClientRect();
129
129
  const x = e.clientX - rect.left;
130
130
  const y = e.clientY - rect.top;
131
- const rippleSize = Math.hypot(rect.width, rect.height) * 2;
131
+ const rippleSize = Math.max(
132
+ Math.hypot(rect.width, rect.height) * 2.5,
133
+ 320
134
+ );
132
135
  setRipples((prev) => [
133
136
  ...prev,
134
137
  { id: Date.now(), x, y, size: rippleSize }
@@ -210,6 +213,7 @@ var CardImpl = React18__namespace.forwardRef(
210
213
  target,
211
214
  rel: relProp,
212
215
  onClick,
216
+ asChild = false,
213
217
  children
214
218
  } = _b, props = __objRest(_b, [
215
219
  "className",
@@ -220,10 +224,11 @@ var CardImpl = React18__namespace.forwardRef(
220
224
  "target",
221
225
  "rel",
222
226
  "onClick",
227
+ "asChild",
223
228
  "children"
224
229
  ]);
225
230
  const safeVariant = variant;
226
- const isInteractive = !!onClick || !!href || interactive;
231
+ const isInteractive = !!onClick || !!href || interactive || asChild;
227
232
  const elevationProps = useCardElevation(safeVariant, disabled);
228
233
  const { ripples, onPointerDown, removeRipple } = useRippleState();
229
234
  const baseClass = cn(
@@ -244,6 +249,26 @@ var CardImpl = React18__namespace.forwardRef(
244
249
  // Outlined interactive card: change border color to m3-outline on focus/press/hover
245
250
  variant === "outlined" && "hover:border-m3-outline focus-visible:border-m3-outline active:border-m3-outline"
246
251
  );
252
+ if (asChild) {
253
+ const child = React18__namespace.Children.only(children);
254
+ const innerContent = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
255
+ /* @__PURE__ */ jsxRuntime.jsx(Ripple, { ripples, onRippleDone: removeRipple }),
256
+ child.props.children
257
+ ] });
258
+ return /* @__PURE__ */ jsxRuntime.jsx(react.LazyMotion, { features: react.domMax, strict: true, children: /* @__PURE__ */ jsxRuntime.jsx(
259
+ reactSlot.Slot,
260
+ __spreadProps(__spreadValues({
261
+ ref,
262
+ className: cn(baseClass, interactiveClass),
263
+ "aria-disabled": disabled ? true : void 0,
264
+ tabIndex: disabled ? -1 : 0,
265
+ onPointerDown,
266
+ onClick
267
+ }, props), {
268
+ children: React18__namespace.cloneElement(child, { children: innerContent })
269
+ })
270
+ ) });
271
+ }
247
272
  if (!isInteractive) {
248
273
  return /* @__PURE__ */ jsxRuntime.jsx(
249
274
  "div",
@@ -1488,6 +1513,7 @@ var ButtonComponent = React18__namespace.forwardRef(
1488
1513
  shape = "round",
1489
1514
  selected,
1490
1515
  icon,
1516
+ selectedIcon,
1491
1517
  iconPosition = "leading",
1492
1518
  loading = false,
1493
1519
  loadingVariant = "loading-indicator",
@@ -1509,6 +1535,7 @@ var ButtonComponent = React18__namespace.forwardRef(
1509
1535
  "shape",
1510
1536
  "selected",
1511
1537
  "icon",
1538
+ "selectedIcon",
1512
1539
  "iconPosition",
1513
1540
  "loading",
1514
1541
  "loadingVariant",
@@ -1608,10 +1635,11 @@ var ButtonComponent = React18__namespace.forwardRef(
1608
1635
  layout: BUTTON_SHAPE_MORPH_SPRING,
1609
1636
  default: SPRING_TRANSITION
1610
1637
  };
1638
+ const activeIcon = isSelected && selectedIcon ? selectedIcon : icon;
1611
1639
  const innerContent = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1612
1640
  needsTouchTarget && /* @__PURE__ */ jsxRuntime.jsx(TouchTarget, {}),
1613
1641
  /* @__PURE__ */ jsxRuntime.jsx(Ripple, { ripples, onRippleDone: removeRipple }),
1614
- /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { initial: false, mode: "popLayout", children: (loading || icon && iconPosition === "leading") && /* @__PURE__ */ jsxRuntime.jsx(
1642
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { initial: false, mode: "wait", children: (loading || activeIcon && iconPosition === "leading") && /* @__PURE__ */ jsxRuntime.jsx(
1615
1643
  AnimatedIconSlot,
1616
1644
  {
1617
1645
  iconSize: sizeTokens.iconSize,
@@ -1633,8 +1661,9 @@ var ButtonComponent = React18__namespace.forwardRef(
1633
1661
  trackColor: "transparent",
1634
1662
  "aria-label": "Loading"
1635
1663
  }
1636
- ) : icon
1637
- }
1664
+ ) : activeIcon
1665
+ },
1666
+ isSelected && selectedIcon ? "selected-icon" : "icon"
1638
1667
  ) }),
1639
1668
  labelText && /* @__PURE__ */ jsxRuntime.jsx(
1640
1669
  react.m.span,
@@ -1645,14 +1674,15 @@ var ButtonComponent = React18__namespace.forwardRef(
1645
1674
  children: labelText
1646
1675
  }
1647
1676
  ),
1648
- /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { initial: false, mode: "popLayout", children: icon && iconPosition === "trailing" && /* @__PURE__ */ jsxRuntime.jsx(
1677
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { initial: false, mode: "wait", children: !loading && activeIcon && iconPosition === "trailing" && /* @__PURE__ */ jsxRuntime.jsx(
1649
1678
  AnimatedIconSlot,
1650
1679
  {
1651
1680
  iconSize: sizeTokens.iconSize,
1652
1681
  ariaHidden: true,
1653
1682
  transition: sharedTransition,
1654
- children: icon
1655
- }
1683
+ children: activeIcon
1684
+ },
1685
+ isSelected && selectedIcon ? "selected-icon" : "icon"
1656
1686
  ) })
1657
1687
  ] });
1658
1688
  const handleAsChildPointerDown = React18__namespace.useCallback(
@@ -4247,6 +4277,7 @@ var ListItem = React18__namespace.memo(ListItemImpl);
4247
4277
  var typographyVariants = classVarianceAuthority.cva("m-0 p-0 text-m3-on-surface", {
4248
4278
  variants: {
4249
4279
  variant: {
4280
+ // Short hyphenated
4250
4281
  "display-lg": "text-[57px] leading-[64px] font-normal tracking-[-0.25px]",
4251
4282
  "display-md": "text-[45px] leading-[52px] font-normal tracking-[0px]",
4252
4283
  "display-sm": "text-[36px] leading-[44px] font-normal tracking-[0px]",
@@ -4261,7 +4292,39 @@ var typographyVariants = classVarianceAuthority.cva("m-0 p-0 text-m3-on-surface"
4261
4292
  "label-sm": "text-[11px] leading-[16px] font-medium tracking-[0.5px]",
4262
4293
  "body-lg": "text-[16px] leading-[24px] font-normal tracking-[0.5px]",
4263
4294
  "body-md": "text-[14px] leading-[20px] font-normal tracking-[0.25px]",
4264
- "body-sm": "text-[12px] leading-[16px] font-normal tracking-[0.4px]"
4295
+ "body-sm": "text-[12px] leading-[16px] font-normal tracking-[0.4px]",
4296
+ // Full hyphenated aliases
4297
+ "display-large": "text-[57px] leading-[64px] font-normal tracking-[-0.25px]",
4298
+ "display-medium": "text-[45px] leading-[52px] font-normal tracking-[0px]",
4299
+ "display-small": "text-[36px] leading-[44px] font-normal tracking-[0px]",
4300
+ "headline-large": "text-[32px] leading-[40px] font-normal tracking-[0px]",
4301
+ "headline-medium": "text-[28px] leading-[36px] font-normal tracking-[0px]",
4302
+ "headline-small": "text-[24px] leading-[32px] font-normal tracking-[0px]",
4303
+ "title-large": "text-[22px] leading-[28px] font-normal tracking-[0px]",
4304
+ "title-medium": "text-[16px] leading-[24px] font-medium tracking-[0.15px]",
4305
+ "title-small": "text-[14px] leading-[20px] font-medium tracking-[0.1px]",
4306
+ "label-large": "text-[14px] leading-[20px] font-medium tracking-[0.1px]",
4307
+ "label-medium": "text-[12px] leading-[16px] font-medium tracking-[0.5px]",
4308
+ "label-small": "text-[11px] leading-[16px] font-medium tracking-[0.5px]",
4309
+ "body-large": "text-[16px] leading-[24px] font-normal tracking-[0.5px]",
4310
+ "body-medium": "text-[14px] leading-[20px] font-normal tracking-[0.25px]",
4311
+ "body-small": "text-[12px] leading-[16px] font-normal tracking-[0.4px]",
4312
+ // CamelCase aliases
4313
+ displayLarge: "text-[57px] leading-[64px] font-normal tracking-[-0.25px]",
4314
+ displayMedium: "text-[45px] leading-[52px] font-normal tracking-[0px]",
4315
+ displaySmall: "text-[36px] leading-[44px] font-normal tracking-[0px]",
4316
+ headlineLarge: "text-[32px] leading-[40px] font-normal tracking-[0px]",
4317
+ headlineMedium: "text-[28px] leading-[36px] font-normal tracking-[0px]",
4318
+ headlineSmall: "text-[24px] leading-[32px] font-normal tracking-[0px]",
4319
+ titleLarge: "text-[22px] leading-[28px] font-normal tracking-[0px]",
4320
+ titleMedium: "text-[16px] leading-[24px] font-medium tracking-[0.15px]",
4321
+ titleSmall: "text-[14px] leading-[20px] font-medium tracking-[0.1px]",
4322
+ labelLarge: "text-[14px] leading-[20px] font-medium tracking-[0.1px]",
4323
+ labelMedium: "text-[12px] leading-[16px] font-medium tracking-[0.5px]",
4324
+ labelSmall: "text-[11px] leading-[16px] font-medium tracking-[0.5px]",
4325
+ bodyLarge: "text-[16px] leading-[24px] font-normal tracking-[0.5px]",
4326
+ bodyMedium: "text-[14px] leading-[20px] font-normal tracking-[0.25px]",
4327
+ bodySmall: "text-[12px] leading-[16px] font-normal tracking-[0.4px]"
4265
4328
  }
4266
4329
  },
4267
4330
  defaultVariants: {
@@ -4270,19 +4333,21 @@ var typographyVariants = classVarianceAuthority.cva("m-0 p-0 text-m3-on-surface"
4270
4333
  });
4271
4334
  var Text = React18__namespace.forwardRef(
4272
4335
  (_a, ref) => {
4273
- var _b = _a, { className, variant, as: Component } = _b, props = __objRest(_b, ["className", "variant", "as"]);
4336
+ var _b = _a, { className, variant, as: Component, color, weight, style } = _b, props = __objRest(_b, ["className", "variant", "as", "color", "weight", "style"]);
4274
4337
  const defaultComponent = React18__namespace.useMemo(() => {
4275
- if ((variant == null ? void 0 : variant.startsWith("display")) || (variant == null ? void 0 : variant.startsWith("headline")))
4276
- return "h1";
4277
- if (variant == null ? void 0 : variant.startsWith("title")) return "h2";
4338
+ const v = variant ? String(variant).toLowerCase() : "";
4339
+ if (v.startsWith("display") || v.startsWith("headline")) return "h1";
4340
+ if (v.startsWith("title")) return "h2";
4278
4341
  return "p";
4279
4342
  }, [variant]);
4280
4343
  const Tag = Component || defaultComponent;
4344
+ const customStyle = __spreadValues(__spreadValues(__spreadValues({}, style), color ? { color } : {}), weight ? { fontWeight: weight } : {});
4281
4345
  return /* @__PURE__ */ jsxRuntime.jsx(
4282
4346
  Tag,
4283
4347
  __spreadValues({
4284
4348
  ref,
4285
- className: cn(typographyVariants({ variant, className }))
4349
+ className: cn(typographyVariants({ variant, className })),
4350
+ style: customStyle
4286
4351
  }, props)
4287
4352
  );
4288
4353
  }