@bug-on/m3-expressive 1.3.5 → 1.3.6

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 (43) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/forms.d.mts +2 -2
  3. package/dist/forms.d.ts +2 -2
  4. package/dist/forms.js +16 -6
  5. package/dist/forms.js.map +1 -1
  6. package/dist/forms.mjs +16 -6
  7. package/dist/forms.mjs.map +1 -1
  8. package/dist/index.d.mts +4 -4
  9. package/dist/index.d.ts +4 -4
  10. package/dist/index.js +722 -187
  11. package/dist/index.js.map +1 -1
  12. package/dist/index.mjs +718 -188
  13. package/dist/index.mjs.map +1 -1
  14. package/dist/{md3-expressive-shapes-CPcfl_Hf.d.mts → md3-expressive-shapes-wk_98LJh.d.mts} +20 -1
  15. package/dist/{md3-expressive-shapes-CPcfl_Hf.d.ts → md3-expressive-shapes-wk_98LJh.d.ts} +20 -1
  16. package/dist/navigation.d.mts +1 -1
  17. package/dist/navigation.d.ts +1 -1
  18. package/dist/navigation.js +73 -20
  19. package/dist/navigation.js.map +1 -1
  20. package/dist/navigation.mjs +73 -20
  21. package/dist/navigation.mjs.map +1 -1
  22. package/dist/overlays.d.mts +4 -2
  23. package/dist/overlays.d.ts +4 -2
  24. package/dist/overlays.js +84 -43
  25. package/dist/overlays.js.map +1 -1
  26. package/dist/overlays.mjs +84 -43
  27. package/dist/overlays.mjs.map +1 -1
  28. package/dist/pickers.js +88 -55
  29. package/dist/pickers.js.map +1 -1
  30. package/dist/pickers.mjs +88 -55
  31. package/dist/pickers.mjs.map +1 -1
  32. package/dist/shapes.d.mts +141 -15
  33. package/dist/shapes.d.ts +141 -15
  34. package/dist/shapes.js +618 -126
  35. package/dist/shapes.js.map +1 -1
  36. package/dist/shapes.mjs +614 -127
  37. package/dist/shapes.mjs.map +1 -1
  38. package/dist/{side-sheet-modal-64FGhDxL.d.mts → side-sheet-modal-BycxrabB.d.mts} +70 -0
  39. package/dist/{side-sheet-modal-Bd5Qqvp9.d.ts → side-sheet-modal-Cw4vemKx.d.ts} +70 -0
  40. package/dist/{text-field-4OlT9o8s.d.mts → text-field-B1fLh5Sh.d.mts} +22 -3
  41. package/dist/{text-field-DARNdj14.d.ts → text-field-C0VQLp8Y.d.ts} +22 -3
  42. package/llms-full.txt +7 -0
  43. package/package.json +1 -1
@@ -109,6 +109,11 @@ declare function directionVector(dx: number, dy: number): [number, number];
109
109
  * @returns true if convex
110
110
  */
111
111
  declare function convex(prevX: number, prevY: number, currX: number, currY: number, nextX: number, nextY: number): boolean;
112
+ /**
113
+ * Formats a coordinate to at most 4 decimal places with maximum performance.
114
+ * Avoids string parsing and intermediate allocations.
115
+ */
116
+ declare function formatCoordinate(v: number): string;
112
117
  /**
113
118
  * Type for a function that transforms a point (x, y) → (x', y').
114
119
  */
@@ -447,6 +452,20 @@ declare class RoundedPolygon {
447
452
  * @returns [minX, minY, maxX, maxY] of the max-bounds square
448
453
  */
449
454
  calculateMaxBounds(): [number, number, number, number];
455
+ /**
456
+ * Calculates the approximate signed area of the polygon using anchor points.
457
+ * Returns > 0 for Clockwise (in screen coords, y down), < 0 for Counter-Clockwise.
458
+ */
459
+ calculateSignedArea(): number;
460
+ /**
461
+ * Returns true if the polygon outline runs in Clockwise order (screen coords).
462
+ */
463
+ isClockwise(): boolean;
464
+ /**
465
+ * Returns a reversed copy of the polygon with reversed traversal order.
466
+ * Flips the winding direction (CW ↔ CCW).
467
+ */
468
+ reversed(): RoundedPolygon;
450
469
  }
451
470
 
452
471
  /**
@@ -495,4 +514,4 @@ declare const MD3Shapes: {
495
514
  };
496
515
  type MD3ShapeName = keyof typeof MD3Shapes;
497
516
 
498
- export { ANGLE_EPSILON as A, scalePoint as B, type CornerFeature as C, DISTANCE_EPSILON as D, type EdgeFeature as E, FLOAT_PI as F, square as G, subtractPoints as H, transformFeature as I, transformPoint as J, type MD3ShapeName as M, type Point as P, RoundedPolygon as R, UNROUNDED as U, type CornerRounding as a, Cubic as b, type Feature as c, MD3Shapes as d, MutableCubic as e, type PointTransformer as f, addPoints as g, clockwise as h, convex as i, cornerFeature as j, cornerRounding as k, directionVector as l, distance as m, distanceSquared as n, dividePoint as o, dotProduct as p, edgeFeature as q, getDirection as r, getDistance as s, getDistanceSquared as t, interpolate as u, lerpPoint as v, point as w, positiveModulo as x, radialToCartesian as y, rotate90 as z };
517
+ export { ANGLE_EPSILON as A, rotate90 as B, type CornerFeature as C, DISTANCE_EPSILON as D, type EdgeFeature as E, FLOAT_PI as F, scalePoint as G, square as H, subtractPoints as I, transformFeature as J, transformPoint as K, type MD3ShapeName as M, type Point as P, RoundedPolygon as R, UNROUNDED as U, type CornerRounding as a, Cubic as b, type Feature as c, MD3Shapes as d, MutableCubic as e, type PointTransformer as f, addPoints as g, clockwise as h, convex as i, cornerFeature as j, cornerRounding as k, directionVector as l, distance as m, distanceSquared as n, dividePoint as o, dotProduct as p, edgeFeature as q, formatCoordinate as r, getDirection as s, getDistance as t, getDistanceSquared as u, interpolate as v, lerpPoint as w, point as x, positiveModulo as y, radialToCartesian as z };
@@ -109,6 +109,11 @@ declare function directionVector(dx: number, dy: number): [number, number];
109
109
  * @returns true if convex
110
110
  */
111
111
  declare function convex(prevX: number, prevY: number, currX: number, currY: number, nextX: number, nextY: number): boolean;
112
+ /**
113
+ * Formats a coordinate to at most 4 decimal places with maximum performance.
114
+ * Avoids string parsing and intermediate allocations.
115
+ */
116
+ declare function formatCoordinate(v: number): string;
112
117
  /**
113
118
  * Type for a function that transforms a point (x, y) → (x', y').
114
119
  */
@@ -447,6 +452,20 @@ declare class RoundedPolygon {
447
452
  * @returns [minX, minY, maxX, maxY] of the max-bounds square
448
453
  */
449
454
  calculateMaxBounds(): [number, number, number, number];
455
+ /**
456
+ * Calculates the approximate signed area of the polygon using anchor points.
457
+ * Returns > 0 for Clockwise (in screen coords, y down), < 0 for Counter-Clockwise.
458
+ */
459
+ calculateSignedArea(): number;
460
+ /**
461
+ * Returns true if the polygon outline runs in Clockwise order (screen coords).
462
+ */
463
+ isClockwise(): boolean;
464
+ /**
465
+ * Returns a reversed copy of the polygon with reversed traversal order.
466
+ * Flips the winding direction (CW ↔ CCW).
467
+ */
468
+ reversed(): RoundedPolygon;
450
469
  }
451
470
 
452
471
  /**
@@ -495,4 +514,4 @@ declare const MD3Shapes: {
495
514
  };
496
515
  type MD3ShapeName = keyof typeof MD3Shapes;
497
516
 
498
- export { ANGLE_EPSILON as A, scalePoint as B, type CornerFeature as C, DISTANCE_EPSILON as D, type EdgeFeature as E, FLOAT_PI as F, square as G, subtractPoints as H, transformFeature as I, transformPoint as J, type MD3ShapeName as M, type Point as P, RoundedPolygon as R, UNROUNDED as U, type CornerRounding as a, Cubic as b, type Feature as c, MD3Shapes as d, MutableCubic as e, type PointTransformer as f, addPoints as g, clockwise as h, convex as i, cornerFeature as j, cornerRounding as k, directionVector as l, distance as m, distanceSquared as n, dividePoint as o, dotProduct as p, edgeFeature as q, getDirection as r, getDistance as s, getDistanceSquared as t, interpolate as u, lerpPoint as v, point as w, positiveModulo as x, radialToCartesian as y, rotate90 as z };
517
+ export { ANGLE_EPSILON as A, rotate90 as B, type CornerFeature as C, DISTANCE_EPSILON as D, type EdgeFeature as E, FLOAT_PI as F, scalePoint as G, square as H, subtractPoints as I, transformFeature as J, transformPoint as K, type MD3ShapeName as M, type Point as P, RoundedPolygon as R, UNROUNDED as U, type CornerRounding as a, Cubic as b, type Feature as c, MD3Shapes as d, MutableCubic as e, type PointTransformer as f, addPoints as g, clockwise as h, convex as i, cornerFeature as j, cornerRounding as k, directionVector as l, distance as m, distanceSquared as n, dividePoint as o, dotProduct as p, edgeFeature as q, formatCoordinate as r, getDirection as s, getDistance as t, getDistanceSquared as u, interpolate as v, lerpPoint as w, point as x, positiveModulo as y, radialToCartesian as z };
@@ -9,7 +9,7 @@ import { a as ContextMenuProps, C as ContextMenuContentProps, b as ContextMenuTr
9
9
  export { e as MenuGroupPosition, g as MenuItemPosition, n as VerticalMenuGroupProps, p as VerticalMenuSeparatorStyle } from './menu-types-rZNQFO7Y.mjs';
10
10
  import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
11
11
  import { Transition, Variants, HTMLMotionProps } from 'motion/react';
12
- import { M as MD3ShapeName } from './md3-expressive-shapes-CPcfl_Hf.mjs';
12
+ import { M as MD3ShapeName } from './md3-expressive-shapes-wk_98LJh.mjs';
13
13
  import { d as MD3SlotWidth } from './md3-BQhRygSi.mjs';
14
14
  import { B as BaseIconButtonProps } from './icon-button-CxyJv7UV.mjs';
15
15
 
@@ -9,7 +9,7 @@ import { a as ContextMenuProps, C as ContextMenuContentProps, b as ContextMenuTr
9
9
  export { e as MenuGroupPosition, g as MenuItemPosition, n as VerticalMenuGroupProps, p as VerticalMenuSeparatorStyle } from './menu-types-rZNQFO7Y.js';
10
10
  import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
11
11
  import { Transition, Variants, HTMLMotionProps } from 'motion/react';
12
- import { M as MD3ShapeName } from './md3-expressive-shapes-CPcfl_Hf.js';
12
+ import { M as MD3ShapeName } from './md3-expressive-shapes-wk_98LJh.js';
13
13
  import { d as MD3SlotWidth } from './md3-BQhRygSi.js';
14
14
  import { B as BaseIconButtonProps } from './icon-button-Di8VX6ou.js';
15
15
 
@@ -2971,6 +2971,13 @@ function transformFeature(feature, fn) {
2971
2971
  }
2972
2972
  return edgeFeature(cubics);
2973
2973
  }
2974
+ function reverseFeature(feature) {
2975
+ const cubics = feature.cubics.slice().reverse().map((c) => c.reverse());
2976
+ if (feature.type === "corner") {
2977
+ return cornerFeature(cubics, feature.convex);
2978
+ }
2979
+ return edgeFeature(cubics);
2980
+ }
2974
2981
 
2975
2982
  // src/shapes/math/corner-rounding.ts
2976
2983
  var UNROUNDED = Object.freeze({
@@ -3003,6 +3010,10 @@ function convex(prevX, prevY, currX, currY, nextX, nextY) {
3003
3010
  const v2y = nextY - currY;
3004
3011
  return v1x * v2y - v1y * v2x > 0;
3005
3012
  }
3013
+ function formatCoordinate(v) {
3014
+ const rounded = Math.round(v * 1e4) / 1e4;
3015
+ return (rounded === 0 ? 0 : rounded).toString();
3016
+ }
3006
3017
 
3007
3018
  // src/shapes/math/point.ts
3008
3019
  function point(x, y) {
@@ -3055,9 +3066,16 @@ var Cubic = class _Cubic {
3055
3066
  */
3056
3067
  pointOnCurve(t) {
3057
3068
  const u = 1 - t;
3069
+ const uu = u * u;
3070
+ const tt = t * t;
3071
+ const uuu = uu * u;
3072
+ const ttt = tt * t;
3073
+ const c0 = 3 * t * uu;
3074
+ const c1 = 3 * tt * u;
3075
+ const p = this.points;
3058
3076
  return point(
3059
- this.anchor0X * (u * u * u) + this.control0X * (3 * t * u * u) + this.control1X * (3 * t * t * u) + this.anchor1X * (t * t * t),
3060
- this.anchor0Y * (u * u * u) + this.control0Y * (3 * t * u * u) + this.control1Y * (3 * t * t * u) + this.anchor1Y * (t * t * t)
3077
+ p[0] * uuu + p[2] * c0 + p[4] * c1 + p[6] * ttt,
3078
+ p[1] * uuu + p[3] * c0 + p[5] * c1 + p[7] * ttt
3061
3079
  );
3062
3080
  }
3063
3081
  /**
@@ -3666,6 +3684,36 @@ var RoundedPolygon = class _RoundedPolygon {
3666
3684
  this.centerY + d
3667
3685
  ];
3668
3686
  }
3687
+ /**
3688
+ * Calculates the approximate signed area of the polygon using anchor points.
3689
+ * Returns > 0 for Clockwise (in screen coords, y down), < 0 for Counter-Clockwise.
3690
+ */
3691
+ calculateSignedArea() {
3692
+ let area = 0;
3693
+ const n = this.cubics.length;
3694
+ for (let i = 0; i < n; i++) {
3695
+ const c = this.cubics[i];
3696
+ area += c.anchor0X * c.anchor1Y - c.anchor1X * c.anchor0Y;
3697
+ }
3698
+ return area / 2;
3699
+ }
3700
+ /**
3701
+ * Returns true if the polygon outline runs in Clockwise order (screen coords).
3702
+ */
3703
+ isClockwise() {
3704
+ return this.calculateSignedArea() > 0;
3705
+ }
3706
+ /**
3707
+ * Returns a reversed copy of the polygon with reversed traversal order.
3708
+ * Flips the winding direction (CW ↔ CCW).
3709
+ */
3710
+ reversed() {
3711
+ const reversedFeatures = this.features.slice().reverse().map((f) => reverseFeature(f));
3712
+ return new _RoundedPolygon(
3713
+ reversedFeatures,
3714
+ point(this.centerX, this.centerY)
3715
+ );
3716
+ }
3669
3717
  };
3670
3718
  function buildCubicsList(features) {
3671
3719
  const result = [];
@@ -3734,10 +3782,21 @@ function validateContiguity(cubics) {
3734
3782
 
3735
3783
  // src/shapes/catalog/md3-expressive-shapes.ts
3736
3784
  function createShape(pts) {
3737
- const cubics = pts.map((p) => new Cubic(p));
3738
- return RoundedPolygon.fromFeatures(
3739
- cubics.map((c) => cornerFeature([c], false))
3740
- );
3785
+ let rawArea = 0;
3786
+ for (const p of pts) {
3787
+ rawArea += p[0] * p[7] - p[6] * p[1];
3788
+ }
3789
+ const normalizedPts = rawArea < 0 ? pts.slice().reverse().map((p) => [p[6], p[7], p[4], p[5], p[2], p[3], p[0], p[1]]) : pts;
3790
+ const cubics = normalizedPts.map((p) => new Cubic(p));
3791
+ const n = cubics.length;
3792
+ const features = cubics.map((c, i) => {
3793
+ const prev = cubics[(i - 1 + n) % n].pointOnCurve(0.5);
3794
+ const curr = c.pointOnCurve(0.5);
3795
+ const next = cubics[(i + 1) % n].pointOnCurve(0.5);
3796
+ const isConvex = convex(prev.x, prev.y, curr.x, curr.y, next.x, next.y);
3797
+ return cornerFeature([c], isConvex);
3798
+ });
3799
+ return RoundedPolygon.fromFeatures(features);
3741
3800
  }
3742
3801
  var archShape = createShape([
3743
3802
  [1, 0.83461, 1, 0.8547, 1, 0.86477, 0.99898, 0.87322],
@@ -4831,30 +4890,24 @@ var MD3Shapes = {
4831
4890
 
4832
4891
  // src/shapes/render/shape-rendering.ts
4833
4892
  function toSvgPath(cubics, width = 1, height = 1) {
4834
- if (cubics.length === 0) return "";
4893
+ const len = cubics.length;
4894
+ if (len === 0) return "";
4835
4895
  const paddingX = width * 0.015;
4836
4896
  const paddingY = height * 0.015;
4837
4897
  const sx = width - 2 * paddingX;
4838
4898
  const sy = height - 2 * paddingY;
4839
- const flipY = (y) => paddingY + sy * (1 - y);
4840
- const parts = [
4841
- `M ${fmt(paddingX + cubics[0].anchor0X * sx)} ${fmt(flipY(cubics[0].anchor0Y))}`
4842
- ];
4843
- for (const c of cubics) {
4844
- parts.push(
4845
- `C ${fmt(paddingX + c.control0X * sx)} ${fmt(flipY(c.control0Y))},${fmt(paddingX + c.control1X * sx)} ${fmt(flipY(c.control1Y))},${fmt(paddingX + c.anchor1X * sx)} ${fmt(flipY(c.anchor1Y))}`
4846
- );
4899
+ const c0 = cubics[0];
4900
+ let d = `M ${formatCoordinate(paddingX + c0.anchor0X * sx)} ${formatCoordinate(paddingY + sy * (1 - c0.anchor0Y))}`;
4901
+ for (let i = 0; i < len; i++) {
4902
+ const c = cubics[i];
4903
+ d += ` C ${formatCoordinate(paddingX + c.control0X * sx)} ${formatCoordinate(paddingY + sy * (1 - c.control0Y))},${formatCoordinate(paddingX + c.control1X * sx)} ${formatCoordinate(paddingY + sy * (1 - c.control1Y))},${formatCoordinate(paddingX + c.anchor1X * sx)} ${formatCoordinate(paddingY + sy * (1 - c.anchor1Y))}`;
4847
4904
  }
4848
- parts.push("Z");
4849
- return parts.join(" ");
4905
+ return `${d} Z`;
4850
4906
  }
4851
4907
  function toClipPath(polygon, width, height) {
4852
4908
  const pathData = toSvgPath(polygon.cubics, width, height);
4853
4909
  return `path('${pathData}')`;
4854
4910
  }
4855
- function fmt(v) {
4856
- return Number(v.toFixed(4)).toString();
4857
- }
4858
4911
 
4859
4912
  // src/ui/navigation/navigation-shape-utils.ts
4860
4913
  function getNavigationShapeStyle(shape, width = 56, height = 56) {