@bug-on/md3-tokens 3.0.0 → 3.0.3

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/motion.ts"],"sourcesContent":["/**\n * MD3 Expressive Motion Tokens\n * Framework-agnostic JS objects.\n */\n\nexport const duration = {\n\tshort1: 50,\n\tshort2: 100,\n\tshort3: 150,\n\tshort4: 200,\n\tmedium1: 250,\n\tmedium2: 300,\n\tmedium3: 350,\n\tmedium4: 400,\n\tlong1: 450,\n\tlong2: 500,\n\tlong3: 550,\n\tlong4: 600,\n\textraLong1: 700,\n\textraLong2: 800,\n\textraLong3: 900,\n\textraLong4: 1000,\n} as const;\n\nexport const easing = {\n\tstandard: [0.2, 0, 0, 1] as [number, number, number, number],\n\tstandardAccelerate: [0.3, 0, 1, 1] as [number, number, number, number],\n\tstandardDecelerate: [0, 0, 0, 1] as [number, number, number, number],\n\temphasized: [0.2, 0, 0, 1] as [number, number, number, number],\n\temphasizedAccelerate: [0.3, 0, 0.8, 0.15] as [number, number, number, number],\n\temphasizedDecelerate: [0.05, 0.7, 0.1, 1.0] as [\n\t\tnumber,\n\t\tnumber,\n\t\tnumber,\n\t\tnumber,\n\t],\n} as const;\n\nexport const spring = {\n\tdefault: { type: \"spring\" as const, stiffness: 500, damping: 30, mass: 0.8 },\n\tsnappy: { type: \"spring\" as const, stiffness: 600, damping: 25 },\n\tgentle: { type: \"spring\" as const, stiffness: 300, damping: 20 },\n\tbouncy: { type: \"spring\" as const, stiffness: 400, damping: 15 },\n} as const;\n\nexport const motionTokens = { duration, easing, spring };\n"],"mappings":";AAKO,IAAM,WAAW;AAAA,EACvB,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,YAAY;AACb;AAEO,IAAM,SAAS;AAAA,EACrB,UAAU,CAAC,KAAK,GAAG,GAAG,CAAC;AAAA,EACvB,oBAAoB,CAAC,KAAK,GAAG,GAAG,CAAC;AAAA,EACjC,oBAAoB,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,EAC/B,YAAY,CAAC,KAAK,GAAG,GAAG,CAAC;AAAA,EACzB,sBAAsB,CAAC,KAAK,GAAG,KAAK,IAAI;AAAA,EACxC,sBAAsB,CAAC,MAAM,KAAK,KAAK,CAAG;AAM3C;AAEO,IAAM,SAAS;AAAA,EACrB,SAAS,EAAE,MAAM,UAAmB,WAAW,KAAK,SAAS,IAAI,MAAM,IAAI;AAAA,EAC3E,QAAQ,EAAE,MAAM,UAAmB,WAAW,KAAK,SAAS,GAAG;AAAA,EAC/D,QAAQ,EAAE,MAAM,UAAmB,WAAW,KAAK,SAAS,GAAG;AAAA,EAC/D,QAAQ,EAAE,MAAM,UAAmB,WAAW,KAAK,SAAS,GAAG;AAChE;AAEO,IAAM,eAAe,EAAE,UAAU,QAAQ,OAAO;","names":[]}
1
+ {"version":3,"sources":["../src/motion.ts","../src/shape.ts"],"sourcesContent":["/**\n * MD3 Expressive Motion Tokens\n *\n * Source of truth for all motion in the design system. Two layers:\n *\n * 1. **Physics-based system** (May 2025, primary) — Spring tokens per the MD3\n * motion physics system. Use these for Framer Motion / JS animations.\n * 2. **Legacy easing + duration** (still valid for CSS transitions) — Original\n * MD3 cubic-bezier tokens kept as a fallback.\n *\n * @see https://m3.material.io/styles/motion/overview/how-it-works\n * @see https://m3.material.io/styles/motion/overview/specs\n */\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Types\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Motion scheme — controls whether springs bounce (expressive) or not (standard). */\nexport type MotionScheme = \"expressive\" | \"standard\";\n\n/** Spring speed tier. */\nexport type SpringSpeed = \"fast\" | \"default\" | \"slow\";\n\n/** Spring type — spatial (position/size/shape) or effects (color/opacity). */\nexport type SpringType = \"spatial\" | \"effects\";\n\n/** Raw MD3 spring token — damping ratio + stiffness as specified in the design token. */\nexport interface MD3SpringToken {\n\t/** Damping ratio: 0 = no damping, 1 = critically damped (no bounce). */\n\tdampingRatio: number;\n\t/** Spring stiffness. Higher = faster animation. */\n\tstiffness: number;\n}\n\n/** A pre-converted spring ready for Framer Motion `Transition`. */\nexport interface FramerSpring {\n\ttype: \"spring\";\n\t/** Absolute damping coefficient (converted from dampingRatio). */\n\tdamping: number;\n\tstiffness: number;\n}\n\n/** Web CSS curve equivalent for a spring token (for CSS transitions). */\nexport interface WebCurveToken {\n\t/** CSS cubic-bezier(...) string. */\n\tcurve: string;\n\t/** Duration in milliseconds. */\n\tdurationMs: number;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// MD3 Expressive Spring Tokens (raw: dampingRatio + stiffness)\n// Source: md.sys.motion.spring.{speed}.{type}\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Raw MD3 spring tokens per the official specification.\n * Values are identical for both \"expressive\" and \"standard\" schemes —\n * the scheme is applied at the product level, not the token level.\n *\n * @see https://m3.material.io/styles/motion/easing-and-duration/tokens-specs\n */\nexport const md3SpringTokens = {\n\tfast: {\n\t\tspatial: { dampingRatio: 0.6, stiffness: 800 } satisfies MD3SpringToken,\n\t\teffects: { dampingRatio: 1.0, stiffness: 3800 } satisfies MD3SpringToken,\n\t},\n\tdefault: {\n\t\tspatial: { dampingRatio: 0.8, stiffness: 380 } satisfies MD3SpringToken,\n\t\teffects: { dampingRatio: 1.0, stiffness: 1600 } satisfies MD3SpringToken,\n\t},\n\tslow: {\n\t\tspatial: { dampingRatio: 0.8, stiffness: 200 } satisfies MD3SpringToken,\n\t\teffects: { dampingRatio: 1.0, stiffness: 800 } satisfies MD3SpringToken,\n\t},\n} as const;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Framer Motion Spring Presets\n// damping = 2 * dampingRatio * sqrt(stiffness * mass), mass = 1 (default)\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction toFramerSpring(token: MD3SpringToken): FramerSpring {\n\tconst damping = 2 * token.dampingRatio * Math.sqrt(token.stiffness);\n\treturn { type: \"spring\", stiffness: token.stiffness, damping };\n}\n\n/**\n * Ready-to-use Framer Motion spring configs, derived from MD3 spring tokens.\n *\n * Use **spatial** springs for: position, size, border-radius, rotation, scale.\n * Use **effects** springs for: color, opacity (no overshoot).\n *\n * @example\n * ```tsx\n * import { framerSprings } from \"@md3-expressive/tokens\";\n * <m.div transition={framerSprings.fast.spatial} />\n * ```\n */\nexport const framerSprings = {\n\tfast: {\n\t\tspatial: toFramerSpring(md3SpringTokens.fast.spatial),\n\t\teffects: toFramerSpring(md3SpringTokens.fast.effects),\n\t},\n\tdefault: {\n\t\tspatial: toFramerSpring(md3SpringTokens.default.spatial),\n\t\teffects: toFramerSpring(md3SpringTokens.default.effects),\n\t},\n\tslow: {\n\t\tspatial: toFramerSpring(md3SpringTokens.slow.spatial),\n\t\teffects: toFramerSpring(md3SpringTokens.slow.effects),\n\t},\n} as const;\n\n// Convenient named aliases (mirror menu-animations.ts naming convention)\nexport const FAST_SPATIAL_SPRING = framerSprings.fast.spatial;\nexport const FAST_EFFECTS_SPRING = framerSprings.fast.effects;\nexport const DEFAULT_SPATIAL_SPRING = framerSprings.default.spatial;\nexport const DEFAULT_EFFECTS_SPRING = framerSprings.default.effects;\nexport const SLOW_SPATIAL_SPRING = framerSprings.slow.spatial;\nexport const SLOW_EFFECTS_SPRING = framerSprings.slow.effects;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Web CSS Curve Conversions\n// Use these when Framer Motion is not available (pure CSS transitions).\n// Source: https://m3.material.io/styles/motion/overview/specs#web-convert\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * CSS cubic-bezier + duration equivalents of MD3 spring tokens.\n * For non-interruptible CSS transitions when JS springs are unavailable.\n *\n * @see https://m3.material.io/styles/motion/overview/specs\n */\nexport const webCurves = {\n\texpressive: {\n\t\tfast: {\n\t\t\tspatial: {\n\t\t\t\tcurve: \"cubic-bezier(0.42, 1.67, 0.21, 0.90)\",\n\t\t\t\tdurationMs: 350,\n\t\t\t} satisfies WebCurveToken,\n\t\t\teffects: {\n\t\t\t\tcurve: \"cubic-bezier(0.31, 0.94, 0.34, 1.00)\",\n\t\t\t\tdurationMs: 150,\n\t\t\t} satisfies WebCurveToken,\n\t\t},\n\t\tdefault: {\n\t\t\tspatial: {\n\t\t\t\tcurve: \"cubic-bezier(0.38, 1.21, 0.22, 1.00)\",\n\t\t\t\tdurationMs: 500,\n\t\t\t} satisfies WebCurveToken,\n\t\t\teffects: {\n\t\t\t\tcurve: \"cubic-bezier(0.34, 0.80, 0.34, 1.00)\",\n\t\t\t\tdurationMs: 200,\n\t\t\t} satisfies WebCurveToken,\n\t\t},\n\t\tslow: {\n\t\t\tspatial: {\n\t\t\t\tcurve: \"cubic-bezier(0.39, 1.29, 0.35, 0.98)\",\n\t\t\t\tdurationMs: 650,\n\t\t\t} satisfies WebCurveToken,\n\t\t\teffects: {\n\t\t\t\tcurve: \"cubic-bezier(0.34, 0.88, 0.34, 1.00)\",\n\t\t\t\tdurationMs: 300,\n\t\t\t} satisfies WebCurveToken,\n\t\t},\n\t},\n\tstandard: {\n\t\tfast: {\n\t\t\tspatial: {\n\t\t\t\tcurve: \"cubic-bezier(0.27, 1.06, 0.18, 1.00)\",\n\t\t\t\tdurationMs: 350,\n\t\t\t} satisfies WebCurveToken,\n\t\t\teffects: {\n\t\t\t\tcurve: \"cubic-bezier(0.31, 0.94, 0.34, 1.00)\",\n\t\t\t\tdurationMs: 150,\n\t\t\t} satisfies WebCurveToken,\n\t\t},\n\t\tdefault: {\n\t\t\tspatial: {\n\t\t\t\tcurve: \"cubic-bezier(0.27, 1.06, 0.18, 1.00)\",\n\t\t\t\tdurationMs: 500,\n\t\t\t} satisfies WebCurveToken,\n\t\t\teffects: {\n\t\t\t\tcurve: \"cubic-bezier(0.34, 0.80, 0.34, 1.00)\",\n\t\t\t\tdurationMs: 200,\n\t\t\t} satisfies WebCurveToken,\n\t\t},\n\t\tslow: {\n\t\t\tspatial: {\n\t\t\t\tcurve: \"cubic-bezier(0.27, 1.06, 0.18, 1.00)\",\n\t\t\t\tdurationMs: 750,\n\t\t\t} satisfies WebCurveToken,\n\t\t\teffects: {\n\t\t\t\tcurve: \"cubic-bezier(0.34, 0.88, 0.34, 1.00)\",\n\t\t\t\tdurationMs: 300,\n\t\t\t} satisfies WebCurveToken,\n\t\t},\n\t},\n} as const;\n\n/**\n * Get a Framer Motion spring config for the given scheme, speed, and type.\n *\n * @example\n * ```tsx\n * transition={getSpring(\"expressive\", \"fast\", \"spatial\")}\n * ```\n */\nexport function getSpring(\n\t_scheme: MotionScheme,\n\tspeed: SpringSpeed,\n\ttype: SpringType,\n): FramerSpring {\n\t// Spring token values are scheme-agnostic; scheme is applied at product level.\n\treturn framerSprings[speed][type];\n}\n\n/**\n * Get a CSS transition string for the given scheme, speed, and type.\n *\n * @example\n * ```ts\n * element.style.transition = `transform ${getCSSTransition(\"expressive\", \"fast\", \"spatial\")}`;\n * ```\n */\nexport function getCSSTransition(\n\tscheme: MotionScheme,\n\tspeed: SpringSpeed,\n\ttype: SpringType,\n): string {\n\tconst { curve, durationMs } = webCurves[scheme][speed][type];\n\treturn `${durationMs}ms ${curve}`;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Legacy: Duration tokens (ms) — md.sys.motion.duration.*\n// Still valid; used as CSS fallback and for easing-based animations.\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const duration = {\n\tshort1: 50,\n\tshort2: 100,\n\tshort3: 150,\n\tshort4: 200,\n\tmedium1: 250,\n\tmedium2: 300,\n\tmedium3: 350,\n\tmedium4: 400,\n\tlong1: 450,\n\tlong2: 500,\n\tlong3: 550,\n\tlong4: 600,\n\textraLong1: 700,\n\textraLong2: 800,\n\textraLong3: 900,\n\textraLong4: 1000,\n} as const;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Legacy: Easing tokens — md.sys.motion.easing.*\n// Cubic-bezier control points [x1, y1, x2, y2].\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const easing = {\n\t// Emphasized set — most common for M3 Expressive transitions\n\temphasized: [0.2, 0, 0, 1] as [number, number, number, number],\n\temphasizedAccelerate: [0.3, 0, 0.8, 0.15] as [number, number, number, number],\n\temphasizedDecelerate: [0.05, 0.7, 0.1, 1.0] as [\n\t\tnumber,\n\t\tnumber,\n\t\tnumber,\n\t\tnumber,\n\t],\n\n\t// Standard set — for simple/utility transitions and CSS fallback\n\tstandard: [0.2, 0, 0, 1] as [number, number, number, number],\n\tstandardAccelerate: [0.3, 0, 1, 1] as [number, number, number, number],\n\tstandardDecelerate: [0, 0, 0, 1] as [number, number, number, number],\n\n\t// Legacy set (M2 compat)\n\tlegacy: [0.4, 0, 0.2, 1] as [number, number, number, number],\n\tlegacyAccelerate: [0.4, 0, 1, 1] as [number, number, number, number],\n\tlegacyDecelerate: [0, 0, 0.2, 1] as [number, number, number, number],\n\n\t// Linear\n\tlinear: [0, 0, 1, 1] as [number, number, number, number],\n} as const;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// @deprecated Legacy spring presets — kept for backward compat only.\n// Migrate to framerSprings.* or the named FAST_SPATIAL_SPRING etc. exports.\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** @deprecated Use `framerSprings.default.spatial` or `DEFAULT_SPATIAL_SPRING` instead. */\nexport const spring = {\n\tdefault: framerSprings.default.spatial,\n\tsnappy: framerSprings.fast.spatial,\n\tgentle: framerSprings.slow.spatial,\n\tbouncy: {\n\t\t...framerSprings.fast.spatial,\n\t\tdamping: framerSprings.fast.spatial.damping * 0.5,\n\t},\n} as const;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Aggregate export\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const motionTokens = {\n\tduration,\n\teasing,\n\tspring: md3SpringTokens,\n\tframerSprings,\n\twebCurves,\n} as const;\n","/**\n * MD3 Expressive Shape Tokens\n *\n * TypeScript counterpart to `shape.css`. Provides numeric corner radius values,\n * CSS custom property names, and asymmetric corner helpers.\n *\n * Updated for M3 Expressive (May 2025): 10-level corner radius scale.\n *\n * @see https://m3.material.io/styles/shape/corner-radius-scale\n */\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Corner radius scale — numeric values in pixels\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Numeric corner radius values (px) for all 10 shape scale levels.\n * Map directly to `--md-sys-shape-corner-*` CSS custom properties.\n *\n * @example\n * ```ts\n * element.style.borderRadius = `${cornerRadius.medium}px`; // 12px\n * ```\n */\nexport const cornerRadius = {\n\tnone: 0,\n\textraSmall: 4,\n\tsmall: 8,\n\tmedium: 12,\n\tlarge: 16,\n\t/** New in M3 Expressive (May 2025) */\n\tlargeIncreased: 20,\n\textraLarge: 28,\n\t/** New in M3 Expressive (May 2025) */\n\textraLargeIncreased: 32,\n\t/** New in M3 Expressive (May 2025) */\n\textraExtraLarge: 48,\n\tfull: 9999,\n} as const;\n\nexport type CornerRadiusKey = keyof typeof cornerRadius;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// CSS custom property names\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Maps each corner radius key to its CSS custom property name.\n *\n * @example\n * ```ts\n * const cssVar = cornerCssVar.medium; // \"--md-sys-shape-corner-medium\"\n * element.style.borderRadius = `var(${cssVar})`;\n * ```\n */\nexport const cornerCssVar: Record<CornerRadiusKey, string> = {\n\tnone: \"--md-sys-shape-corner-none\",\n\textraSmall: \"--md-sys-shape-corner-extra-small\",\n\tsmall: \"--md-sys-shape-corner-small\",\n\tmedium: \"--md-sys-shape-corner-medium\",\n\tlarge: \"--md-sys-shape-corner-large\",\n\tlargeIncreased: \"--md-sys-shape-corner-large-increased\",\n\textraLarge: \"--md-sys-shape-corner-extra-large\",\n\textraLargeIncreased: \"--md-sys-shape-corner-extra-large-increased\",\n\textraExtraLarge: \"--md-sys-shape-corner-extra-extra-large\",\n\tfull: \"--md-sys-shape-corner-full\",\n};\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Asymmetric corner helpers\n// Used for inner-corner components (menus, split buttons, grouped items).\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Describes per-corner rounding for asymmetric shapes.\n * Follows CSS `border-radius` shorthand order:\n * top-left, top-right, bottom-right, bottom-left.\n */\nexport interface AsymmetricCorners {\n\ttopLeft: number;\n\ttopRight: number;\n\tbottomRight: number;\n\tbottomLeft: number;\n}\n\n/** Shorthand presets for common asymmetric corner patterns. */\nexport const asymmetricCorners = {\n\t/** Fully rounded top, square bottom — e.g. menu at top of screen. */\n\ttopFull: (r = cornerRadius.extraLarge): AsymmetricCorners => ({\n\t\ttopLeft: r,\n\t\ttopRight: r,\n\t\tbottomRight: 0,\n\t\tbottomLeft: 0,\n\t}),\n\t/** Square top, fully rounded bottom — e.g. menu at bottom of screen. */\n\tbottomFull: (r = cornerRadius.extraLarge): AsymmetricCorners => ({\n\t\ttopLeft: 0,\n\t\ttopRight: 0,\n\t\tbottomRight: r,\n\t\tbottomLeft: r,\n\t}),\n\t/** Rounded start edge only — e.g. left item in a grouped set. */\n\tstartFull: (r = cornerRadius.full): AsymmetricCorners => ({\n\t\ttopLeft: r,\n\t\ttopRight: 0,\n\t\tbottomRight: 0,\n\t\tbottomLeft: r,\n\t}),\n\t/** Rounded end edge only — e.g. right item in a grouped set. */\n\tendFull: (r = cornerRadius.full): AsymmetricCorners => ({\n\t\ttopLeft: 0,\n\t\ttopRight: r,\n\t\tbottomRight: r,\n\t\tbottomLeft: 0,\n\t}),\n} as const;\n\n/**\n * Converts an `AsymmetricCorners` object to a CSS `border-radius` string.\n *\n * @example\n * ```ts\n * element.style.borderRadius = toCSS(asymmetricCorners.topFull());\n * // \"28px 28px 0px 0px\"\n * ```\n */\nexport function asymmetricCornersToCSS(corners: AsymmetricCorners): string {\n\treturn `${corners.topLeft}px ${corners.topRight}px ${corners.bottomRight}px ${corners.bottomLeft}px`;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Optical roundness helper\n// When nesting rounded objects: inner radius = outer radius - padding\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Calculates the inner border-radius that maintains optical roundness\n * when nesting one rounded container inside another.\n *\n * Formula: `inner = outer - padding`\n *\n * @see https://m3.material.io/styles/shape/corner-radius-scale#adjust-for-optical-roundness\n *\n * @example\n * ```ts\n * // Container has extraExtraLarge (48px), padding is 14px\n * const inner = opticalRadius(cornerRadius.extraExtraLarge, 14); // 34\n * ```\n */\nexport function opticalRadius(outerRadius: number, padding: number): number {\n\treturn Math.max(0, outerRadius - padding);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Aggregate export\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const shapeTokens = {\n\tcornerRadius,\n\tcornerCssVar,\n\tasymmetricCorners,\n} as const;\n"],"mappings":"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","names":[]}
package/dist/shape.css CHANGED
@@ -1,9 +1,18 @@
1
1
  :root {
2
+ /* ── MD3 Expressive Corner Radius Scale (10 levels) ─────────────────────── */
3
+ /* Source: https://m3.material.io/styles/shape/corner-radius-scale */
4
+
2
5
  --md-sys-shape-corner-none: 0px;
3
6
  --md-sys-shape-corner-extra-small: 4px;
4
7
  --md-sys-shape-corner-small: 8px;
5
8
  --md-sys-shape-corner-medium: 12px;
6
9
  --md-sys-shape-corner-large: 16px;
10
+ /* New in M3 Expressive (May 2025) */
11
+ --md-sys-shape-corner-large-increased: 20px;
7
12
  --md-sys-shape-corner-extra-large: 28px;
13
+ /* New in M3 Expressive (May 2025) */
14
+ --md-sys-shape-corner-extra-large-increased: 32px;
15
+ /* New in M3 Expressive (May 2025) */
16
+ --md-sys-shape-corner-extra-extra-large: 48px;
8
17
  --md-sys-shape-corner-full: 9999px;
9
18
  }
@@ -0,0 +1,2 @@
1
+ // CSS module — no runtime types
2
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bug-on/md3-tokens",
3
- "version": "3.0.0",
3
+ "version": "3.0.3",
4
4
  "description": "Material Design 3 Expressive design tokens",
5
5
  "author": "Bug Ổn",
6
6
  "license": "MIT",
@@ -23,9 +23,14 @@
23
23
  "types": "./dist/index.d.ts",
24
24
  "exports": {
25
25
  ".": {
26
- "types": "./dist/index.d.ts",
27
- "import": "./dist/index.mjs",
28
- "require": "./dist/index.js"
26
+ "import": {
27
+ "types": "./dist/index.d.mts",
28
+ "default": "./dist/index.mjs"
29
+ },
30
+ "require": {
31
+ "types": "./dist/index.d.ts",
32
+ "default": "./dist/index.js"
33
+ }
29
34
  },
30
35
  "./colors.css": {
31
36
  "types": "./dist/colors.css.d.ts",
@@ -36,20 +41,19 @@
36
41
  "default": "./dist/shape.css"
37
42
  }
38
43
  },
39
- "peerDependencies": {
40
- "react": "^19.0.0",
41
- "react-dom": "^19.0.0"
42
- },
44
+ "peerDependencies": {},
43
45
  "publishConfig": {
44
46
  "access": "public"
45
47
  },
46
48
  "devDependencies": {
49
+ "react": "^19.0.0",
50
+ "react-dom": "^19.0.0",
47
51
  "tsup": "^8.4.0",
48
52
  "typescript": "5.8.3"
49
53
  },
50
54
  "scripts": {
51
- "build": "tsup",
52
- "dev": "tsup --watch",
55
+ "build": "tsup && node scripts/copy-css.js",
56
+ "dev": "tsup --watch --onSuccess \"node scripts/copy-css.js\"",
53
57
  "clean": "rm -rf dist"
54
58
  }
55
59
  }
@@ -12,7 +12,7 @@ if (!fs.existsSync(distDir)) {
12
12
  console.log("Copying CSS assets to dist...");
13
13
 
14
14
  // CSS files to copy from src/ to dist/ (only files that exist in src/)
15
- const cssFiles = ["colors.css", "shape.css", "index.css"];
15
+ const cssFiles = ["colors.css", "shape.css"];
16
16
 
17
17
  for (const file of cssFiles) {
18
18
  const srcPath = path.join(srcDir, file);
package/src/index.ts CHANGED
@@ -1 +1,47 @@
1
- export { duration, easing, motionTokens, spring } from "./motion";
1
+ // Motion tokens MD3 Expressive physics-based system + legacy easing/duration
2
+ export {
3
+ DEFAULT_EFFECTS_SPRING,
4
+ DEFAULT_SPATIAL_SPRING,
5
+ // Legacy duration + easing (still valid, kept as fallback)
6
+ duration,
7
+ easing,
8
+ FAST_EFFECTS_SPRING,
9
+ FAST_SPATIAL_SPRING,
10
+ type FramerSpring,
11
+ // Framer Motion ready presets
12
+ framerSprings,
13
+ getCSSTransition,
14
+ // Helpers
15
+ getSpring,
16
+ type MD3SpringToken,
17
+ // Types
18
+ type MotionScheme,
19
+ // Raw MD3 spring tokens (dampingRatio + stiffness)
20
+ md3SpringTokens,
21
+ // Aggregate
22
+ motionTokens,
23
+ SLOW_EFFECTS_SPRING,
24
+ SLOW_SPATIAL_SPRING,
25
+ type SpringSpeed,
26
+ type SpringType,
27
+ // @deprecated legacy spring presets
28
+ spring,
29
+ type WebCurveToken,
30
+ // Web CSS curve equivalents
31
+ webCurves,
32
+ } from "./motion";
33
+
34
+ // Shape tokens — MD3 Expressive 10-level corner radius scale + helpers
35
+ export {
36
+ type AsymmetricCorners,
37
+ asymmetricCorners,
38
+ asymmetricCornersToCSS,
39
+ // Types
40
+ type CornerRadiusKey,
41
+ cornerCssVar,
42
+ // Corner radius values
43
+ cornerRadius,
44
+ opticalRadius,
45
+ // Aggregate
46
+ shapeTokens,
47
+ } from "./shape";
package/src/motion.ts CHANGED
@@ -1,8 +1,244 @@
1
1
  /**
2
2
  * MD3 Expressive Motion Tokens
3
- * Framework-agnostic JS objects.
3
+ *
4
+ * Source of truth for all motion in the design system. Two layers:
5
+ *
6
+ * 1. **Physics-based system** (May 2025, primary) — Spring tokens per the MD3
7
+ * motion physics system. Use these for Framer Motion / JS animations.
8
+ * 2. **Legacy easing + duration** (still valid for CSS transitions) — Original
9
+ * MD3 cubic-bezier tokens kept as a fallback.
10
+ *
11
+ * @see https://m3.material.io/styles/motion/overview/how-it-works
12
+ * @see https://m3.material.io/styles/motion/overview/specs
4
13
  */
5
14
 
15
+ // ─────────────────────────────────────────────────────────────────────────────
16
+ // Types
17
+ // ─────────────────────────────────────────────────────────────────────────────
18
+
19
+ /** Motion scheme — controls whether springs bounce (expressive) or not (standard). */
20
+ export type MotionScheme = "expressive" | "standard";
21
+
22
+ /** Spring speed tier. */
23
+ export type SpringSpeed = "fast" | "default" | "slow";
24
+
25
+ /** Spring type — spatial (position/size/shape) or effects (color/opacity). */
26
+ export type SpringType = "spatial" | "effects";
27
+
28
+ /** Raw MD3 spring token — damping ratio + stiffness as specified in the design token. */
29
+ export interface MD3SpringToken {
30
+ /** Damping ratio: 0 = no damping, 1 = critically damped (no bounce). */
31
+ dampingRatio: number;
32
+ /** Spring stiffness. Higher = faster animation. */
33
+ stiffness: number;
34
+ }
35
+
36
+ /** A pre-converted spring ready for Framer Motion `Transition`. */
37
+ export interface FramerSpring {
38
+ type: "spring";
39
+ /** Absolute damping coefficient (converted from dampingRatio). */
40
+ damping: number;
41
+ stiffness: number;
42
+ }
43
+
44
+ /** Web CSS curve equivalent for a spring token (for CSS transitions). */
45
+ export interface WebCurveToken {
46
+ /** CSS cubic-bezier(...) string. */
47
+ curve: string;
48
+ /** Duration in milliseconds. */
49
+ durationMs: number;
50
+ }
51
+
52
+ // ─────────────────────────────────────────────────────────────────────────────
53
+ // MD3 Expressive Spring Tokens (raw: dampingRatio + stiffness)
54
+ // Source: md.sys.motion.spring.{speed}.{type}
55
+ // ─────────────────────────────────────────────────────────────────────────────
56
+
57
+ /**
58
+ * Raw MD3 spring tokens per the official specification.
59
+ * Values are identical for both "expressive" and "standard" schemes —
60
+ * the scheme is applied at the product level, not the token level.
61
+ *
62
+ * @see https://m3.material.io/styles/motion/easing-and-duration/tokens-specs
63
+ */
64
+ export const md3SpringTokens = {
65
+ fast: {
66
+ spatial: { dampingRatio: 0.6, stiffness: 800 } satisfies MD3SpringToken,
67
+ effects: { dampingRatio: 1.0, stiffness: 3800 } satisfies MD3SpringToken,
68
+ },
69
+ default: {
70
+ spatial: { dampingRatio: 0.8, stiffness: 380 } satisfies MD3SpringToken,
71
+ effects: { dampingRatio: 1.0, stiffness: 1600 } satisfies MD3SpringToken,
72
+ },
73
+ slow: {
74
+ spatial: { dampingRatio: 0.8, stiffness: 200 } satisfies MD3SpringToken,
75
+ effects: { dampingRatio: 1.0, stiffness: 800 } satisfies MD3SpringToken,
76
+ },
77
+ } as const;
78
+
79
+ // ─────────────────────────────────────────────────────────────────────────────
80
+ // Framer Motion Spring Presets
81
+ // damping = 2 * dampingRatio * sqrt(stiffness * mass), mass = 1 (default)
82
+ // ─────────────────────────────────────────────────────────────────────────────
83
+
84
+ function toFramerSpring(token: MD3SpringToken): FramerSpring {
85
+ const damping = 2 * token.dampingRatio * Math.sqrt(token.stiffness);
86
+ return { type: "spring", stiffness: token.stiffness, damping };
87
+ }
88
+
89
+ /**
90
+ * Ready-to-use Framer Motion spring configs, derived from MD3 spring tokens.
91
+ *
92
+ * Use **spatial** springs for: position, size, border-radius, rotation, scale.
93
+ * Use **effects** springs for: color, opacity (no overshoot).
94
+ *
95
+ * @example
96
+ * ```tsx
97
+ * import { framerSprings } from "@md3-expressive/tokens";
98
+ * <m.div transition={framerSprings.fast.spatial} />
99
+ * ```
100
+ */
101
+ export const framerSprings = {
102
+ fast: {
103
+ spatial: toFramerSpring(md3SpringTokens.fast.spatial),
104
+ effects: toFramerSpring(md3SpringTokens.fast.effects),
105
+ },
106
+ default: {
107
+ spatial: toFramerSpring(md3SpringTokens.default.spatial),
108
+ effects: toFramerSpring(md3SpringTokens.default.effects),
109
+ },
110
+ slow: {
111
+ spatial: toFramerSpring(md3SpringTokens.slow.spatial),
112
+ effects: toFramerSpring(md3SpringTokens.slow.effects),
113
+ },
114
+ } as const;
115
+
116
+ // Convenient named aliases (mirror menu-animations.ts naming convention)
117
+ export const FAST_SPATIAL_SPRING = framerSprings.fast.spatial;
118
+ export const FAST_EFFECTS_SPRING = framerSprings.fast.effects;
119
+ export const DEFAULT_SPATIAL_SPRING = framerSprings.default.spatial;
120
+ export const DEFAULT_EFFECTS_SPRING = framerSprings.default.effects;
121
+ export const SLOW_SPATIAL_SPRING = framerSprings.slow.spatial;
122
+ export const SLOW_EFFECTS_SPRING = framerSprings.slow.effects;
123
+
124
+ // ─────────────────────────────────────────────────────────────────────────────
125
+ // Web CSS Curve Conversions
126
+ // Use these when Framer Motion is not available (pure CSS transitions).
127
+ // Source: https://m3.material.io/styles/motion/overview/specs#web-convert
128
+ // ─────────────────────────────────────────────────────────────────────────────
129
+
130
+ /**
131
+ * CSS cubic-bezier + duration equivalents of MD3 spring tokens.
132
+ * For non-interruptible CSS transitions when JS springs are unavailable.
133
+ *
134
+ * @see https://m3.material.io/styles/motion/overview/specs
135
+ */
136
+ export const webCurves = {
137
+ expressive: {
138
+ fast: {
139
+ spatial: {
140
+ curve: "cubic-bezier(0.42, 1.67, 0.21, 0.90)",
141
+ durationMs: 350,
142
+ } satisfies WebCurveToken,
143
+ effects: {
144
+ curve: "cubic-bezier(0.31, 0.94, 0.34, 1.00)",
145
+ durationMs: 150,
146
+ } satisfies WebCurveToken,
147
+ },
148
+ default: {
149
+ spatial: {
150
+ curve: "cubic-bezier(0.38, 1.21, 0.22, 1.00)",
151
+ durationMs: 500,
152
+ } satisfies WebCurveToken,
153
+ effects: {
154
+ curve: "cubic-bezier(0.34, 0.80, 0.34, 1.00)",
155
+ durationMs: 200,
156
+ } satisfies WebCurveToken,
157
+ },
158
+ slow: {
159
+ spatial: {
160
+ curve: "cubic-bezier(0.39, 1.29, 0.35, 0.98)",
161
+ durationMs: 650,
162
+ } satisfies WebCurveToken,
163
+ effects: {
164
+ curve: "cubic-bezier(0.34, 0.88, 0.34, 1.00)",
165
+ durationMs: 300,
166
+ } satisfies WebCurveToken,
167
+ },
168
+ },
169
+ standard: {
170
+ fast: {
171
+ spatial: {
172
+ curve: "cubic-bezier(0.27, 1.06, 0.18, 1.00)",
173
+ durationMs: 350,
174
+ } satisfies WebCurveToken,
175
+ effects: {
176
+ curve: "cubic-bezier(0.31, 0.94, 0.34, 1.00)",
177
+ durationMs: 150,
178
+ } satisfies WebCurveToken,
179
+ },
180
+ default: {
181
+ spatial: {
182
+ curve: "cubic-bezier(0.27, 1.06, 0.18, 1.00)",
183
+ durationMs: 500,
184
+ } satisfies WebCurveToken,
185
+ effects: {
186
+ curve: "cubic-bezier(0.34, 0.80, 0.34, 1.00)",
187
+ durationMs: 200,
188
+ } satisfies WebCurveToken,
189
+ },
190
+ slow: {
191
+ spatial: {
192
+ curve: "cubic-bezier(0.27, 1.06, 0.18, 1.00)",
193
+ durationMs: 750,
194
+ } satisfies WebCurveToken,
195
+ effects: {
196
+ curve: "cubic-bezier(0.34, 0.88, 0.34, 1.00)",
197
+ durationMs: 300,
198
+ } satisfies WebCurveToken,
199
+ },
200
+ },
201
+ } as const;
202
+
203
+ /**
204
+ * Get a Framer Motion spring config for the given scheme, speed, and type.
205
+ *
206
+ * @example
207
+ * ```tsx
208
+ * transition={getSpring("expressive", "fast", "spatial")}
209
+ * ```
210
+ */
211
+ export function getSpring(
212
+ _scheme: MotionScheme,
213
+ speed: SpringSpeed,
214
+ type: SpringType,
215
+ ): FramerSpring {
216
+ // Spring token values are scheme-agnostic; scheme is applied at product level.
217
+ return framerSprings[speed][type];
218
+ }
219
+
220
+ /**
221
+ * Get a CSS transition string for the given scheme, speed, and type.
222
+ *
223
+ * @example
224
+ * ```ts
225
+ * element.style.transition = `transform ${getCSSTransition("expressive", "fast", "spatial")}`;
226
+ * ```
227
+ */
228
+ export function getCSSTransition(
229
+ scheme: MotionScheme,
230
+ speed: SpringSpeed,
231
+ type: SpringType,
232
+ ): string {
233
+ const { curve, durationMs } = webCurves[scheme][speed][type];
234
+ return `${durationMs}ms ${curve}`;
235
+ }
236
+
237
+ // ─────────────────────────────────────────────────────────────────────────────
238
+ // Legacy: Duration tokens (ms) — md.sys.motion.duration.*
239
+ // Still valid; used as CSS fallback and for easing-based animations.
240
+ // ─────────────────────────────────────────────────────────────────────────────
241
+
6
242
  export const duration = {
7
243
  short1: 50,
8
244
  short2: 100,
@@ -22,10 +258,13 @@ export const duration = {
22
258
  extraLong4: 1000,
23
259
  } as const;
24
260
 
261
+ // ─────────────────────────────────────────────────────────────────────────────
262
+ // Legacy: Easing tokens — md.sys.motion.easing.*
263
+ // Cubic-bezier control points [x1, y1, x2, y2].
264
+ // ─────────────────────────────────────────────────────────────────────────────
265
+
25
266
  export const easing = {
26
- standard: [0.2, 0, 0, 1] as [number, number, number, number],
27
- standardAccelerate: [0.3, 0, 1, 1] as [number, number, number, number],
28
- standardDecelerate: [0, 0, 0, 1] as [number, number, number, number],
267
+ // Emphasized set most common for M3 Expressive transitions
29
268
  emphasized: [0.2, 0, 0, 1] as [number, number, number, number],
30
269
  emphasizedAccelerate: [0.3, 0, 0.8, 0.15] as [number, number, number, number],
31
270
  emphasizedDecelerate: [0.05, 0.7, 0.1, 1.0] as [
@@ -34,13 +273,45 @@ export const easing = {
34
273
  number,
35
274
  number,
36
275
  ],
276
+
277
+ // Standard set — for simple/utility transitions and CSS fallback
278
+ standard: [0.2, 0, 0, 1] as [number, number, number, number],
279
+ standardAccelerate: [0.3, 0, 1, 1] as [number, number, number, number],
280
+ standardDecelerate: [0, 0, 0, 1] as [number, number, number, number],
281
+
282
+ // Legacy set (M2 compat)
283
+ legacy: [0.4, 0, 0.2, 1] as [number, number, number, number],
284
+ legacyAccelerate: [0.4, 0, 1, 1] as [number, number, number, number],
285
+ legacyDecelerate: [0, 0, 0.2, 1] as [number, number, number, number],
286
+
287
+ // Linear
288
+ linear: [0, 0, 1, 1] as [number, number, number, number],
37
289
  } as const;
38
290
 
291
+ // ─────────────────────────────────────────────────────────────────────────────
292
+ // @deprecated Legacy spring presets — kept for backward compat only.
293
+ // Migrate to framerSprings.* or the named FAST_SPATIAL_SPRING etc. exports.
294
+ // ─────────────────────────────────────────────────────────────────────────────
295
+
296
+ /** @deprecated Use `framerSprings.default.spatial` or `DEFAULT_SPATIAL_SPRING` instead. */
39
297
  export const spring = {
40
- default: { type: "spring" as const, stiffness: 500, damping: 30, mass: 0.8 },
41
- snappy: { type: "spring" as const, stiffness: 600, damping: 25 },
42
- gentle: { type: "spring" as const, stiffness: 300, damping: 20 },
43
- bouncy: { type: "spring" as const, stiffness: 400, damping: 15 },
298
+ default: framerSprings.default.spatial,
299
+ snappy: framerSprings.fast.spatial,
300
+ gentle: framerSprings.slow.spatial,
301
+ bouncy: {
302
+ ...framerSprings.fast.spatial,
303
+ damping: framerSprings.fast.spatial.damping * 0.5,
304
+ },
44
305
  } as const;
45
306
 
46
- export const motionTokens = { duration, easing, spring };
307
+ // ─────────────────────────────────────────────────────────────────────────────
308
+ // Aggregate export
309
+ // ─────────────────────────────────────────────────────────────────────────────
310
+
311
+ export const motionTokens = {
312
+ duration,
313
+ easing,
314
+ spring: md3SpringTokens,
315
+ framerSprings,
316
+ webCurves,
317
+ } as const;
package/src/shape.css CHANGED
@@ -1,9 +1,18 @@
1
1
  :root {
2
+ /* ── MD3 Expressive Corner Radius Scale (10 levels) ─────────────────────── */
3
+ /* Source: https://m3.material.io/styles/shape/corner-radius-scale */
4
+
2
5
  --md-sys-shape-corner-none: 0px;
3
6
  --md-sys-shape-corner-extra-small: 4px;
4
7
  --md-sys-shape-corner-small: 8px;
5
8
  --md-sys-shape-corner-medium: 12px;
6
9
  --md-sys-shape-corner-large: 16px;
10
+ /* New in M3 Expressive (May 2025) */
11
+ --md-sys-shape-corner-large-increased: 20px;
7
12
  --md-sys-shape-corner-extra-large: 28px;
13
+ /* New in M3 Expressive (May 2025) */
14
+ --md-sys-shape-corner-extra-large-increased: 32px;
15
+ /* New in M3 Expressive (May 2025) */
16
+ --md-sys-shape-corner-extra-extra-large: 48px;
8
17
  --md-sys-shape-corner-full: 9999px;
9
18
  }