@carbon/motion 11.48.0 → 11.49.0

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/index.scss CHANGED
@@ -5,7 +5,9 @@
5
5
  // LICENSE file in the root directory of this source tree.
6
6
  //
7
7
 
8
+ @use 'sass:list';
8
9
  @use 'sass:map';
10
+ @use 'scss/generated/surfaces' as generated;
9
11
 
10
12
  /// Common component easings
11
13
  /// @type Map
@@ -121,3 +123,134 @@ $slow-01: $duration-slow-01;
121
123
  /// @type Duration
122
124
  /// @group @carbon/motion
123
125
  $slow-02: $duration-slow-02;
126
+
127
+ /// Named motion intents shared across Carbon implementations
128
+ /// @type Map
129
+ /// @access public
130
+ /// @group @carbon/motion
131
+ $surfaces: generated.$surfaces;
132
+
133
+ /// Get a named motion surface or one of its properties
134
+ /// @param {String} $name - The motion surface name
135
+ /// @param {String | Null} $property [null] - An optional surface property
136
+ /// @access public
137
+ /// @group @carbon/motion
138
+ /// @return {Map | *} The surface definition or requested property
139
+ @function surface($name, $property: null) {
140
+ @if not map.has-key($surfaces, $name) {
141
+ @error 'Unable to find a motion surface named #{$name}.';
142
+ }
143
+
144
+ $definition: map.get($surfaces, $name);
145
+
146
+ @if not $property {
147
+ @return $definition;
148
+ }
149
+
150
+ @if not map.has-key($definition, $property) {
151
+ @error 'Unable to find a property named #{$property} on the #{$name} motion surface.';
152
+ }
153
+
154
+ @return map.get($definition, $property);
155
+ }
156
+
157
+ /// Surface duration tokens mapped to their duration values
158
+ /// @access private
159
+ /// @group @carbon/motion
160
+ $-durations: (
161
+ 'fast-01': $duration-fast-01,
162
+ 'fast-02': $duration-fast-02,
163
+ 'moderate-01': $duration-moderate-01,
164
+ 'moderate-02': $duration-moderate-02,
165
+ 'slow-01': $duration-slow-01,
166
+ 'slow-02': $duration-slow-02,
167
+ );
168
+
169
+ /// Apply a named reveal surface in CSS from the shared surface map.
170
+ ///
171
+ /// Resting / `[data-carbon-surface-state='enter']` use the surface enter
172
+ /// keyframes. `[data-carbon-surface-state='exit']` uses the exit keyframes.
173
+ /// Transitions (and `@starting-style` for first-mount enter) are guarded
174
+ /// behind `prefers-reduced-motion: no-preference` - users who prefer reduced
175
+ /// motion get the resting styles with no animation at all.
176
+ ///
177
+ /// Typical usage with controlled open/close:
178
+ ///
179
+ /// ```scss
180
+ /// [data-carbon-surface='contextual'] {
181
+ /// @include motion.surface(contextual);
182
+ /// }
183
+ /// ```
184
+ ///
185
+ /// Shared-element surfaces morph one element into another and have no
186
+ /// CSS-only form; they need a JavaScript engine (Motion in React, View
187
+ /// Transitions for web components), so this mixin rejects them
188
+ /// @param {String} $name - The motion surface name
189
+ /// @access public
190
+ /// @group @carbon/motion
191
+ @mixin surface($name) {
192
+ $definition: surface($name);
193
+ $kind: map.get($definition, kind);
194
+
195
+ @if $kind != 'reveal' {
196
+ @error 'The #{$name} surface is a shared-element morph with no CSS-only form. Pair it with a JavaScript engine instead.';
197
+ }
198
+
199
+ $enter: map.get($definition, enter);
200
+ $exit: map.get($definition, exit);
201
+ $duration: map.get($-durations, map.get($definition, duration));
202
+ $enter-easing: map.get($definition, enter-easing);
203
+ $exit-easing: map.get($definition, exit-easing);
204
+ $properties: ();
205
+
206
+ @each $property, $value in $enter {
207
+ $properties: list.append($properties, $property, $separator: comma);
208
+ }
209
+
210
+ // resting / enter styles apply regardless of motion preference
211
+ &,
212
+ &[data-carbon-surface-state='enter'] {
213
+ @each $property, $value in $enter {
214
+ #{$property}: #{$value};
215
+ }
216
+ }
217
+
218
+ &[data-carbon-surface-state='exit'] {
219
+ @each $property, $value in $exit {
220
+ #{$property}: #{$value};
221
+ }
222
+ }
223
+
224
+ @media (prefers-reduced-motion: no-preference) {
225
+ // `auto` sizes, e.g. disclosure block-size, interpolate where
226
+ // supported
227
+ interpolate-size: allow-keywords;
228
+ transition-duration: $duration;
229
+ transition-property: $properties;
230
+
231
+ &,
232
+ &[data-carbon-surface-state='enter'] {
233
+ transition-timing-function: motion(
234
+ list.nth($enter-easing, 1),
235
+ list.nth($enter-easing, 2)
236
+ );
237
+ }
238
+
239
+ &[data-carbon-surface-state='exit'] {
240
+ transition-timing-function: motion(
241
+ list.nth($exit-easing, 1),
242
+ list.nth($exit-easing, 2)
243
+ );
244
+ }
245
+
246
+ // the styles the element enters from when it is first rendered
247
+ @starting-style {
248
+ &,
249
+ &[data-carbon-surface-state='enter'] {
250
+ @each $property, $value in $exit {
251
+ #{$property}: #{$value};
252
+ }
253
+ }
254
+ }
255
+ }
256
+ }
package/lib/index.d.ts CHANGED
@@ -4,21 +4,5 @@
4
4
  * This source code is licensed under the Apache-2.0 license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- export declare const fast01 = "70ms";
8
- export declare const fast02 = "110ms";
9
- export declare const moderate01 = "150ms";
10
- export declare const moderate02 = "240ms";
11
- export declare const slow01 = "400ms";
12
- export declare const slow02 = "700ms";
13
- export declare const durationFast01 = "70ms";
14
- export declare const durationFast02 = "110ms";
15
- export declare const durationModerate01 = "150ms";
16
- export declare const durationModerate02 = "240ms";
17
- export declare const durationSlow01 = "400ms";
18
- export declare const durationSlow02 = "700ms";
19
- export declare const unstable_tokens: readonly ["fast01", "fast02", "moderate01", "moderate02", "slow01", "slow02", "durationFast01", "durationFast02", "durationModerate01", "durationModerate02", "durationSlow01", "durationSlow02"];
20
- export type EasingName = 'standard' | 'entrance' | 'exit';
21
- export type EasingMode = 'productive' | 'expressive';
22
- export type EasingMap = Record<EasingName, Record<EasingMode, string>>;
23
- export declare const easings: EasingMap;
24
- export declare const motion: (name: EasingName, mode: EasingMode) => string;
7
+ export * from './tokens';
8
+ export * from './surfaces';
package/lib/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- //#region src/index.ts
2
+ //#region src/tokens.ts
3
3
  /**
4
4
  * Copyright IBM Corp. 2018, 2026
5
5
  *
@@ -32,18 +32,71 @@ const unstable_tokens = [
32
32
  "durationSlow01",
33
33
  "durationSlow02"
34
34
  ];
35
+ const durations = {
36
+ "fast-01": durationFast01,
37
+ "fast-02": durationFast02,
38
+ "moderate-01": durationModerate01,
39
+ "moderate-02": durationModerate02,
40
+ "slow-01": durationSlow01,
41
+ "slow-02": durationSlow02
42
+ };
43
+ const easingCurves = {
44
+ standard: {
45
+ productive: [
46
+ .2,
47
+ 0,
48
+ .38,
49
+ .9
50
+ ],
51
+ expressive: [
52
+ .4,
53
+ .14,
54
+ .3,
55
+ 1
56
+ ]
57
+ },
58
+ entrance: {
59
+ productive: [
60
+ 0,
61
+ 0,
62
+ .38,
63
+ .9
64
+ ],
65
+ expressive: [
66
+ 0,
67
+ 0,
68
+ .3,
69
+ 1
70
+ ]
71
+ },
72
+ exit: {
73
+ productive: [
74
+ .2,
75
+ 0,
76
+ 1,
77
+ .9
78
+ ],
79
+ expressive: [
80
+ .4,
81
+ .14,
82
+ 1,
83
+ 1
84
+ ]
85
+ }
86
+ };
87
+ const formatEasing = (curve) => `cubic-bezier(${curve.join(", ")})`;
35
88
  const easings = {
36
89
  standard: {
37
- productive: "cubic-bezier(0.2, 0, 0.38, 0.9)",
38
- expressive: "cubic-bezier(0.4, 0.14, 0.3, 1)"
90
+ productive: formatEasing(easingCurves.standard.productive),
91
+ expressive: formatEasing(easingCurves.standard.expressive)
39
92
  },
40
93
  entrance: {
41
- productive: "cubic-bezier(0, 0, 0.38, 0.9)",
42
- expressive: "cubic-bezier(0, 0, 0.3, 1)"
94
+ productive: formatEasing(easingCurves.entrance.productive),
95
+ expressive: formatEasing(easingCurves.entrance.expressive)
43
96
  },
44
97
  exit: {
45
- productive: "cubic-bezier(0.2, 0, 1, 0.9)",
46
- expressive: "cubic-bezier(0.4, 0.14, 1, 1)"
98
+ productive: formatEasing(easingCurves.exit.productive),
99
+ expressive: formatEasing(easingCurves.exit.expressive)
47
100
  }
48
101
  };
49
102
  const motion = (name, mode) => {
@@ -52,6 +105,97 @@ const motion = (name, mode) => {
52
105
  if (!easing[mode]) throw new Error(`Unable to find a mode for the easing \`${name}\` called: \`${mode}\`. Expected one of: ${Object.keys(easing).join(", ")}`);
53
106
  return easing[mode];
54
107
  };
108
+ const resolveEasing = (name, mode) => {
109
+ if (!easingCurves[name]) throw new Error(`Unable to find easing \`${name}\` in our supported easings. Expected one of: ${Object.keys(easingCurves).join(", ")}`);
110
+ const easing = easingCurves[name];
111
+ if (!easing[mode]) throw new Error(`Unable to find a mode for the easing \`${name}\` called: \`${mode}\`. Expected one of: ${Object.keys(easing).join(", ")}`);
112
+ return easing[mode];
113
+ };
114
+ const resolveDuration = (name) => {
115
+ const duration = durations[name];
116
+ if (!duration) throw new Error(`Unable to find duration \`${name}\` in our supported durations. Expected one of: ${Object.keys(durations).join(", ")}`);
117
+ return duration;
118
+ };
119
+ //#endregion
120
+ //#region src/surfaces.ts
121
+ /**
122
+ * Named motion intents. These definitions are engine and framework agnostic.
123
+ *
124
+ * `prefers-reduced-motion` is intentionally not represented here: surfaces
125
+ * never animate when the users request reduced motion. Framework adapters
126
+ * bail before running, and the Sass output is wrapped in a
127
+ * `prefers-reduced-motion: no-preference` media query
128
+ */
129
+ const surfaces = {
130
+ disclosure: {
131
+ kind: "reveal",
132
+ duration: "moderate-01",
133
+ enter: {
134
+ blockSize: "auto",
135
+ opacity: 1
136
+ },
137
+ exit: {
138
+ blockSize: 0,
139
+ opacity: 0
140
+ },
141
+ enterEasing: ["entrance", "productive"],
142
+ exitEasing: ["exit", "productive"]
143
+ },
144
+ contextual: {
145
+ kind: "reveal",
146
+ duration: "fast-02",
147
+ enter: {
148
+ opacity: 1,
149
+ transform: "scale(1)"
150
+ },
151
+ exit: {
152
+ opacity: 0,
153
+ transform: "scale(0.96)"
154
+ },
155
+ enterEasing: ["entrance", "expressive"],
156
+ exitEasing: ["exit", "expressive"]
157
+ },
158
+ stretch: {
159
+ kind: "reveal",
160
+ duration: "slow-01",
161
+ enter: {
162
+ opacity: 1,
163
+ clipPath: "inset(0 0 0 0)"
164
+ },
165
+ exit: {
166
+ opacity: 0,
167
+ clipPath: "inset(50% 0 50% 0)"
168
+ },
169
+ enterEasing: ["entrance", "expressive"],
170
+ exitEasing: ["exit", "expressive"]
171
+ },
172
+ expand: {
173
+ kind: "shared-element",
174
+ duration: "moderate-02",
175
+ enter: {
176
+ opacity: 1,
177
+ transform: "scale(1)"
178
+ },
179
+ exit: {
180
+ opacity: 0,
181
+ transform: "scale(0.96)"
182
+ },
183
+ enterEasing: ["standard", "productive"],
184
+ exitEasing: ["standard", "productive"]
185
+ },
186
+ invoke: {
187
+ kind: "shared-element",
188
+ origin: "trigger",
189
+ duration: "moderate-02",
190
+ enterEasing: ["standard", "expressive"],
191
+ exitEasing: ["standard", "expressive"]
192
+ }
193
+ };
194
+ const getMotionSurface = (name) => {
195
+ const surface = surfaces[name];
196
+ if (!surface) throw new Error(`Unable to find motion surface \`${name}\`. Expected one of: ` + Object.keys(surfaces).join(", "));
197
+ return surface;
198
+ };
55
199
  //#endregion
56
200
  exports.durationFast01 = durationFast01;
57
201
  exports.durationFast02 = durationFast02;
@@ -62,9 +206,13 @@ exports.durationSlow02 = durationSlow02;
62
206
  exports.easings = easings;
63
207
  exports.fast01 = fast01;
64
208
  exports.fast02 = fast02;
209
+ exports.getMotionSurface = getMotionSurface;
65
210
  exports.moderate01 = moderate01;
66
211
  exports.moderate02 = moderate02;
67
212
  exports.motion = motion;
213
+ exports.resolveDuration = resolveDuration;
214
+ exports.resolveEasing = resolveEasing;
68
215
  exports.slow01 = slow01;
69
216
  exports.slow02 = slow02;
217
+ exports.surfaces = surfaces;
70
218
  exports.unstable_tokens = unstable_tokens;
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Copyright IBM Corp. 2026
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ import type { DurationName, EasingMode, EasingName } from './tokens';
8
+ type MotionEasing = readonly [EasingName, EasingMode];
9
+ /**
10
+ * from/to styles for reveal surface - plain CSS property/value pairs
11
+ * keep values engine-neutral so CSS, WAAPI, and Motion can all consume
12
+ * them
13
+ */
14
+ type RevealKeyframe = Record<string, string | number>;
15
+ interface MotionSurfaceBase {
16
+ duration: DurationName;
17
+ enterEasing: MotionEasing;
18
+ exitEasing: MotionEasing;
19
+ }
20
+ interface RevealSurface extends MotionSurfaceBase {
21
+ kind: 'reveal';
22
+ enter: RevealKeyframe;
23
+ exit: RevealKeyframe;
24
+ }
25
+ interface SharedElementSurface extends MotionSurfaceBase {
26
+ kind: 'shared-element';
27
+ enter?: RevealKeyframe;
28
+ exit?: RevealKeyframe;
29
+ origin?: 'trigger';
30
+ }
31
+ export type MotionSurfaceDefinition = SharedElementSurface | RevealSurface;
32
+ /**
33
+ * Named motion intents. These definitions are engine and framework agnostic.
34
+ *
35
+ * `prefers-reduced-motion` is intentionally not represented here: surfaces
36
+ * never animate when the users request reduced motion. Framework adapters
37
+ * bail before running, and the Sass output is wrapped in a
38
+ * `prefers-reduced-motion: no-preference` media query
39
+ */
40
+ export declare const surfaces: {
41
+ readonly disclosure: {
42
+ readonly kind: "reveal";
43
+ readonly duration: "moderate-01";
44
+ readonly enter: {
45
+ readonly blockSize: "auto";
46
+ readonly opacity: 1;
47
+ };
48
+ readonly exit: {
49
+ readonly blockSize: 0;
50
+ readonly opacity: 0;
51
+ };
52
+ readonly enterEasing: readonly ["entrance", "productive"];
53
+ readonly exitEasing: readonly ["exit", "productive"];
54
+ };
55
+ readonly contextual: {
56
+ readonly kind: "reveal";
57
+ readonly duration: "fast-02";
58
+ readonly enter: {
59
+ readonly opacity: 1;
60
+ readonly transform: "scale(1)";
61
+ };
62
+ readonly exit: {
63
+ readonly opacity: 0;
64
+ readonly transform: "scale(0.96)";
65
+ };
66
+ readonly enterEasing: readonly ["entrance", "expressive"];
67
+ readonly exitEasing: readonly ["exit", "expressive"];
68
+ };
69
+ readonly stretch: {
70
+ readonly kind: "reveal";
71
+ readonly duration: "slow-01";
72
+ readonly enter: {
73
+ readonly opacity: 1;
74
+ readonly clipPath: "inset(0 0 0 0)";
75
+ };
76
+ readonly exit: {
77
+ readonly opacity: 0;
78
+ readonly clipPath: "inset(50% 0 50% 0)";
79
+ };
80
+ readonly enterEasing: readonly ["entrance", "expressive"];
81
+ readonly exitEasing: readonly ["exit", "expressive"];
82
+ };
83
+ readonly expand: {
84
+ readonly kind: "shared-element";
85
+ readonly duration: "moderate-02";
86
+ readonly enter: {
87
+ readonly opacity: 1;
88
+ readonly transform: "scale(1)";
89
+ };
90
+ readonly exit: {
91
+ readonly opacity: 0;
92
+ readonly transform: "scale(0.96)";
93
+ };
94
+ readonly enterEasing: readonly ["standard", "productive"];
95
+ readonly exitEasing: readonly ["standard", "productive"];
96
+ };
97
+ readonly invoke: {
98
+ readonly kind: "shared-element";
99
+ readonly origin: "trigger";
100
+ readonly duration: "moderate-02";
101
+ readonly enterEasing: readonly ["standard", "expressive"];
102
+ readonly exitEasing: readonly ["standard", "expressive"];
103
+ };
104
+ };
105
+ export type MotionSurfaceName = keyof typeof surfaces;
106
+ export declare const getMotionSurface: (name: MotionSurfaceName) => {
107
+ readonly kind: "reveal";
108
+ readonly duration: "moderate-01";
109
+ readonly enter: {
110
+ readonly blockSize: "auto";
111
+ readonly opacity: 1;
112
+ };
113
+ readonly exit: {
114
+ readonly blockSize: 0;
115
+ readonly opacity: 0;
116
+ };
117
+ readonly enterEasing: readonly ["entrance", "productive"];
118
+ readonly exitEasing: readonly ["exit", "productive"];
119
+ } | {
120
+ readonly kind: "reveal";
121
+ readonly duration: "fast-02";
122
+ readonly enter: {
123
+ readonly opacity: 1;
124
+ readonly transform: "scale(1)";
125
+ };
126
+ readonly exit: {
127
+ readonly opacity: 0;
128
+ readonly transform: "scale(0.96)";
129
+ };
130
+ readonly enterEasing: readonly ["entrance", "expressive"];
131
+ readonly exitEasing: readonly ["exit", "expressive"];
132
+ } | {
133
+ readonly kind: "reveal";
134
+ readonly duration: "slow-01";
135
+ readonly enter: {
136
+ readonly opacity: 1;
137
+ readonly clipPath: "inset(0 0 0 0)";
138
+ };
139
+ readonly exit: {
140
+ readonly opacity: 0;
141
+ readonly clipPath: "inset(50% 0 50% 0)";
142
+ };
143
+ readonly enterEasing: readonly ["entrance", "expressive"];
144
+ readonly exitEasing: readonly ["exit", "expressive"];
145
+ } | {
146
+ readonly kind: "shared-element";
147
+ readonly duration: "moderate-02";
148
+ readonly enter: {
149
+ readonly opacity: 1;
150
+ readonly transform: "scale(1)";
151
+ };
152
+ readonly exit: {
153
+ readonly opacity: 0;
154
+ readonly transform: "scale(0.96)";
155
+ };
156
+ readonly enterEasing: readonly ["standard", "productive"];
157
+ readonly exitEasing: readonly ["standard", "productive"];
158
+ } | {
159
+ readonly kind: "shared-element";
160
+ readonly origin: "trigger";
161
+ readonly duration: "moderate-02";
162
+ readonly enterEasing: readonly ["standard", "expressive"];
163
+ readonly exitEasing: readonly ["standard", "expressive"];
164
+ };
165
+ export {};
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Copyright IBM Corp. 2018, 2026
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ export declare const fast01 = "70ms";
8
+ export declare const fast02 = "110ms";
9
+ export declare const moderate01 = "150ms";
10
+ export declare const moderate02 = "240ms";
11
+ export declare const slow01 = "400ms";
12
+ export declare const slow02 = "700ms";
13
+ export declare const durationFast01 = "70ms";
14
+ export declare const durationFast02 = "110ms";
15
+ export declare const durationModerate01 = "150ms";
16
+ export declare const durationModerate02 = "240ms";
17
+ export declare const durationSlow01 = "400ms";
18
+ export declare const durationSlow02 = "700ms";
19
+ export declare const unstable_tokens: readonly ["fast01", "fast02", "moderate01", "moderate02", "slow01", "slow02", "durationFast01", "durationFast02", "durationModerate01", "durationModerate02", "durationSlow01", "durationSlow02"];
20
+ export type DurationName = 'fast-01' | 'fast-02' | 'moderate-01' | 'moderate-02' | 'slow-01' | 'slow-02';
21
+ export type EasingName = 'standard' | 'entrance' | 'exit';
22
+ export type EasingMode = 'productive' | 'expressive';
23
+ export type CubicBezier = readonly [number, number, number, number];
24
+ export type EasingMap = Record<EasingName, Record<EasingMode, string>>;
25
+ export declare const easings: EasingMap;
26
+ export declare const motion: (name: EasingName, mode: EasingMode) => string;
27
+ export declare const resolveEasing: (name: EasingName, mode: EasingMode) => CubicBezier;
28
+ export declare const resolveDuration: (name: DurationName) => string;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@carbon/motion",
3
3
  "description": "Motion helpers for digital and software products using the Carbon Design System",
4
- "version": "11.48.0",
4
+ "version": "11.49.0",
5
5
  "license": "Apache-2.0",
6
6
  "main": "lib/index.js",
7
7
  "module": "es/index.js",
@@ -28,12 +28,12 @@
28
28
  },
29
29
  "scripts": {
30
30
  "build:types": "tsc -p tsconfig.types.json",
31
- "build": "yarn clean && carbon-cli bundle src/index.ts --name CarbonMotion && yarn build:types",
32
- "clean": "rimraf es lib umd",
31
+ "build": "yarn clean && carbon-cli bundle src/index.ts --name CarbonMotion && node tasks/build.mjs && yarn build:types",
32
+ "clean": "rimraf es lib umd scss/generated",
33
33
  "postinstall": "ibmtelemetry --config=telemetry.yml"
34
34
  },
35
35
  "devDependencies": {
36
- "@carbon/cli": "^11.46.0",
36
+ "@carbon/cli": "^11.47.0",
37
37
  "rimraf": "^6.0.1",
38
38
  "typescript": "^6.0.3",
39
39
  "typescript-config-carbon": "^0.11.0"
@@ -41,5 +41,5 @@
41
41
  "dependencies": {
42
42
  "@ibm/telemetry-js": "^1.5.0"
43
43
  },
44
- "gitHead": "5102bd860864c2580048183ffaf50d1ffd4400b5"
44
+ "gitHead": "a57cf8a896fe3fe09c5ab27648cd58947f37360a"
45
45
  }
@@ -0,0 +1,103 @@
1
+ // Code generated by @carbon/motion. DO NOT EDIT.
2
+ //
3
+ // Copyright IBM Corp. 2026
4
+ //
5
+ // This source code is licensed under the Apache-2.0 license found in the
6
+ // LICENSE file in the root directory of this source tree.
7
+ //
8
+
9
+ $surfaces: (
10
+ disclosure: (
11
+ kind: 'reveal',
12
+ duration: 'moderate-01',
13
+ enter: (
14
+ block-size: 'auto',
15
+ opacity: 1,
16
+ ),
17
+ exit: (
18
+ block-size: 0,
19
+ opacity: 0,
20
+ ),
21
+ enter-easing: (
22
+ 'entrance',
23
+ 'productive',
24
+ ),
25
+ exit-easing: (
26
+ 'exit',
27
+ 'productive',
28
+ ),
29
+ ),
30
+ contextual: (
31
+ kind: 'reveal',
32
+ duration: 'fast-02',
33
+ enter: (
34
+ opacity: 1,
35
+ transform: 'scale(1)',
36
+ ),
37
+ exit: (
38
+ opacity: 0,
39
+ transform: 'scale(0.96)',
40
+ ),
41
+ enter-easing: (
42
+ 'entrance',
43
+ 'expressive',
44
+ ),
45
+ exit-easing: (
46
+ 'exit',
47
+ 'expressive',
48
+ ),
49
+ ),
50
+ stretch: (
51
+ kind: 'reveal',
52
+ duration: 'slow-01',
53
+ enter: (
54
+ opacity: 1,
55
+ clip-path: 'inset(0 0 0 0)',
56
+ ),
57
+ exit: (
58
+ opacity: 0,
59
+ clip-path: 'inset(50% 0 50% 0)',
60
+ ),
61
+ enter-easing: (
62
+ 'entrance',
63
+ 'expressive',
64
+ ),
65
+ exit-easing: (
66
+ 'exit',
67
+ 'expressive',
68
+ ),
69
+ ),
70
+ expand: (
71
+ kind: 'shared-element',
72
+ duration: 'moderate-02',
73
+ enter: (
74
+ opacity: 1,
75
+ transform: 'scale(1)',
76
+ ),
77
+ exit: (
78
+ opacity: 0,
79
+ transform: 'scale(0.96)',
80
+ ),
81
+ enter-easing: (
82
+ 'standard',
83
+ 'productive',
84
+ ),
85
+ exit-easing: (
86
+ 'standard',
87
+ 'productive',
88
+ ),
89
+ ),
90
+ invoke: (
91
+ kind: 'shared-element',
92
+ origin: 'trigger',
93
+ duration: 'moderate-02',
94
+ enter-easing: (
95
+ 'standard',
96
+ 'expressive',
97
+ ),
98
+ exit-easing: (
99
+ 'standard',
100
+ 'expressive',
101
+ ),
102
+ ),
103
+ );