mtrl 0.8.0-next.12 → 0.8.0-next.13

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.
@@ -27,8 +27,8 @@ interface CanvasComponent {
27
27
  hide?: () => void;
28
28
  show?: () => void;
29
29
  isVisible?: () => boolean;
30
- startIndeterminateAnimation?: () => void;
31
- stopIndeterminateAnimation?: () => void;
30
+ setIndeterminate?: (indeterminate: boolean) => void;
31
+ resize?: () => void;
32
32
  }
33
33
  /**
34
34
  * API configuration options for canvas-based progress component
@@ -1,143 +1,162 @@
1
- /**
2
- * Progress component variants
3
- */
4
1
  export declare const PROGRESS_VARIANTS: {
5
- /** Standard horizontal progress bar */
6
2
  readonly LINEAR: "linear";
7
- /** Circular spinner progress indicator */
8
3
  readonly CIRCULAR: "circular";
9
4
  };
10
- /**
11
- * Progress component shapes (linear only)
12
- */
13
5
  export declare const PROGRESS_SHAPES: {
14
- /** Standard flat progress */
15
6
  readonly FLAT: "flat";
16
- /** Wavy animated progress */
17
7
  readonly WAVY: "wavy";
18
8
  };
19
- /**
20
- * Progress component events
21
- */
22
9
  export declare const PROGRESS_EVENTS: {
23
- /** Fired when progress value changes */
24
10
  readonly CHANGE: "change";
25
- /** Fired when progress reaches 100% */
26
11
  readonly COMPLETE: "complete";
27
12
  };
28
- /**
29
- * Default configuration values
30
- */
31
13
  export declare const PROGRESS_DEFAULTS: {
32
- /** Default progress variant */
33
14
  readonly VARIANT: "linear";
34
- /** Initial progress value */
35
15
  readonly VALUE: 0;
36
- /** Maximum progress value */
37
16
  readonly MAX: 100;
38
- /** Buffer value for linear progress with buffer */
39
17
  readonly BUFFER: 0;
40
- /** Default shape for linear indeterminate progress */
41
18
  readonly SHAPE: "flat";
42
- /** Whether to show percentage label */
43
19
  readonly SHOW_LABEL: false;
44
- /** Whether progress is indeterminate */
45
20
  readonly INDETERMINATE: false;
21
+ /** Accessible name when none is given */
22
+ readonly LABEL: "Loading";
46
23
  };
47
- /**
48
- * CSS classes for progress elements
49
- */
50
24
  export declare const PROGRESS_CLASSES: {
51
- /** Container element class */
52
25
  readonly CONTAINER: "progress";
53
- /** Linear variant class */
54
26
  readonly LINEAR: "progress--linear";
55
- /** Circular variant class */
56
27
  readonly CIRCULAR: "progress--circular";
57
- /** Track element (unfilled part) class */
58
28
  readonly TRACK: "progress__track";
59
- /** Indicator element (filled part) class */
60
29
  readonly INDICATOR: "progress__indicator";
61
- /** Buffer element class */
62
30
  readonly BUFFER: "progress__buffer";
63
- /** Label element class */
64
31
  readonly LABEL: "progress__label";
65
- /** Indeterminate state class */
66
32
  readonly INDETERMINATE: "progress--indeterminate";
67
- /** Disabled state class */
68
33
  readonly DISABLED: "progress--disabled";
69
- /** Test state class */
70
34
  readonly TEST: "progress--test";
71
35
  readonly TRANSITION: "progress--transition";
72
36
  };
73
37
  /**
74
- * Progress component measurements
38
+ * Colour roles (ProgressIndicatorTokens): the active indicator and the stop
39
+ * indicator take primary, the track secondary-container. A circular
40
+ * indeterminate indicator has no track.
75
41
  */
42
+ export declare const PROGRESS_COLORS: {
43
+ readonly INDICATOR: "sys-color-primary";
44
+ readonly TRACK: "sys-color-secondary-container";
45
+ readonly STOP: "sys-color-primary";
46
+ /** Not an M3 role: the buffer is this library's own extension */
47
+ readonly BUFFER: "sys-color-primary-container";
48
+ };
76
49
  export declare const PROGRESS_MEASUREMENTS: {
77
50
  readonly LINEAR: {
78
- readonly MIN_HEIGHT: 4;
51
+ /** Track and active indicator thickness (LinearProgressIndicatorTokens.Height) */
52
+ readonly HEIGHT: 4;
53
+ /** Space between the active indicator and the track (TrackActiveSpace) */
79
54
  readonly GAP: 4;
55
+ /** The dot that marks the end of the track (StopSize) */
80
56
  readonly STOP_INDICATOR: 4;
81
- readonly HEIGHT: 4;
57
+ /** How far the stop indicator sits from the trailing edge, at most */
58
+ readonly STOP_TRAILING_SPACE: 6;
59
+ /** Container height of a wavy linear indicator (WaveHeight) */
60
+ readonly WAVE_HEIGHT: 10;
61
+ /** Inset from the edge of the element (m3.material.io: 4dp minimum) */
62
+ readonly EDGE_INSET: 4;
63
+ readonly MIN_HEIGHT: 4;
82
64
  };
83
65
  readonly CIRCULAR: {
84
- readonly SIZE: 48;
85
- readonly GAP: 8;
66
+ /** Flat container size (CircularProgressIndicatorTokens.Size) */
67
+ readonly SIZE: 40;
68
+ /** Wavy container size (CircularProgressIndicatorTokens.WaveSize) */
69
+ readonly WAVE_SIZE: 48;
70
+ /** Space between the active indicator and the track (TrackActiveSpace) */
71
+ readonly GAP: 4;
72
+ /** The guidelines' range for a circular indicator */
73
+ readonly MIN_SIZE: 24;
74
+ readonly MAX_SIZE: 240;
86
75
  };
87
76
  readonly COMMON: {
88
77
  readonly STROKE_WIDTH: 4;
89
78
  };
90
79
  };
91
- /**
92
- * Thickness presets for progress component
93
- * These are the standard thickness options following Material Design 3
94
- */
95
80
  export declare const PROGRESS_THICKNESS: {
96
- /** Thin stroke width (4px) - default */
97
81
  readonly THIN: 4;
98
- /** Thick stroke width (8px) */
99
82
  readonly THICK: 8;
100
83
  };
101
84
  /**
102
- * Wave animation parameters for progress components
85
+ * Wave geometry (LinearProgressIndicatorTokens, CircularProgressIndicatorTokens).
86
+ * Wavelengths and amplitudes are in dp at the default 4dp thickness and scale
87
+ * with the indicator's size.
103
88
  */
104
89
  export declare const PROGRESS_WAVE: {
105
- /** Linear progress wave parameters */
106
90
  readonly LINEAR: {
107
- /** Base amplitude of the wave in pixels */
108
- readonly AMPLITUDE: 4;
109
- /** Speed of wave animation in waves per second (Hz) */
110
- readonly SPEED: 1;
111
- /** Number of complete waves per 100 pixels */
112
- readonly FREQUENCY: 2;
113
- /** Number of complete waves per 100 pixels for indeterminate */
114
- readonly INDETERMINATE_FREQUENCY: 4;
115
- /** Amplitude for indeterminate animation */
116
- readonly INDETERMINATE_AMPLITUDE: 2;
117
- /** Wave shape power (lower = rounder peaks, higher = sharper) */
118
- readonly POWER: 0.8;
119
- /** Percentage at which wave amplitude reaches full strength from start */
120
- readonly START_TRANSITION_END: 0;
121
- /** Percentage at which wave amplitude begins to decrease near end */
122
- readonly END_TRANSITION_START: 0.92;
91
+ /** ActiveWaveWavelength */
92
+ readonly WAVELENGTH: 40;
93
+ /** IndeterminateActiveWaveWavelength */
94
+ readonly INDETERMINATE_WAVELENGTH: 20;
95
+ /** ActiveWaveAmplitude */
96
+ readonly AMPLITUDE: 3;
97
+ };
98
+ readonly CIRCULAR: {
99
+ /** ActiveWaveWavelength */
100
+ readonly WAVELENGTH: 15;
101
+ /** ActiveWaveAmplitude */
102
+ readonly AMPLITUDE: 1.6;
103
+ };
104
+ /** The wave travels one wavelength per second (WavyProgressIndicatorDefaults) */
105
+ readonly SPEED: 1;
106
+ /**
107
+ * The wave flattens at both ends of the range
108
+ * (WavyProgressIndicatorDefaults.indicatorAmplitude)
109
+ */
110
+ readonly AMPLITUDE_START: 0.1;
111
+ readonly AMPLITUDE_END: 0.95;
112
+ /** How long the amplitude takes to appear or go (MotionTokens.DurationLong2) */
113
+ readonly AMPLITUDE_DURATION: 500;
114
+ };
115
+ /**
116
+ * Indeterminate motion (ProgressIndicator.kt)
117
+ */
118
+ export declare const PROGRESS_MOTION: {
119
+ readonly LINEAR: {
120
+ /** LinearAnimationDuration */
121
+ readonly DURATION: 1750;
122
+ readonly FIRST_HEAD_DELAY: 0;
123
+ readonly FIRST_HEAD_DURATION: 1000;
124
+ readonly FIRST_TAIL_DELAY: 250;
125
+ readonly FIRST_TAIL_DURATION: 1000;
126
+ readonly SECOND_HEAD_DELAY: 650;
127
+ readonly SECOND_HEAD_DURATION: 850;
128
+ readonly SECOND_TAIL_DELAY: 900;
129
+ readonly SECOND_TAIL_DURATION: 850;
123
130
  };
124
- /** Circular progress wave parameters */
125
131
  readonly CIRCULAR: {
126
- /** Amplitude as percentage of radius (7 = 7%) */
127
- readonly AMPLITUDE: 6;
128
- /** Amplitude as percentage of radius for indeterminate (4 = 4%) */
129
- readonly INDETERMINATE_AMPLITUDE: 4;
130
- /** Speed of wave rotation in rotations per second (Hz), negative value means clockwise */
131
- readonly SPEED: 1;
132
- /** Number of complete waves around the circle */
133
- readonly FREQUENCY: 10;
134
- /** Number of complete waves for indeterminate animation */
135
- readonly INDETERMINATE_FREQUENCY: 16;
136
- /** Wave shape power (lower = rounder peaks, higher = sharper) */
137
- readonly POWER: 0.8;
138
- /** Percentage at which wave amplitude reaches full strength from start */
139
- readonly START_TRANSITION_END: 0;
140
- /** Percentage at which wave amplitude begins to decrease near end */
141
- readonly END_TRANSITION_START: 0.92;
132
+ /** CircularAnimationProgressDuration */
133
+ readonly DURATION: 6000;
134
+ /** CircularAnimationAdditionalRotationDuration */
135
+ readonly ROTATION_DURATION: 300;
136
+ /** CircularAnimationAdditionalRotationDelay */
137
+ readonly ROTATION_DELAY: 1500;
138
+ /** CircularGlobalRotationDegreesTarget */
139
+ readonly GLOBAL_ROTATION: 1080;
140
+ /** CircularAdditionalRotationDegreesTarget */
141
+ readonly ADDITIONAL_ROTATION: 360;
142
+ /** CircularIndeterminateMinProgress */
143
+ readonly MIN_PROGRESS: 0.1;
144
+ /** CircularIndeterminateMaxProgress */
145
+ readonly MAX_PROGRESS: 0.87;
142
146
  };
147
+ /** How long a value change takes to animate (MotionTokens.DurationLong2) */
148
+ readonly VALUE_DURATION: 500;
149
+ };
150
+ /**
151
+ * Easing curves (MotionTokens), as cubic Bézier control points
152
+ */
153
+ export declare const PROGRESS_EASING: {
154
+ /** EasingEmphasizedAccelerateCubicBezier */
155
+ readonly EMPHASIZED_ACCELERATE: readonly [0.3, 0, 0.8, 0.15];
156
+ /** EasingEmphasizedDecelerateCubicBezier */
157
+ readonly EMPHASIZED_DECELERATE: readonly [0.05, 0.7, 0.1, 1];
158
+ /** EasingStandardCubicBezier */
159
+ readonly STANDARD: readonly [0.2, 0, 0, 1];
160
+ /** EasingLinearCubicBezier */
161
+ readonly LINEAR: readonly [0, 0, 1, 1];
143
162
  };
@@ -1,7 +1,4 @@
1
1
  import { ProgressConfig, ProgressThickness } from "../types";
2
- /**
3
- * Canvas dimensions and drawing context
4
- */
5
2
  export interface CanvasContext {
6
3
  canvas: HTMLCanvasElement;
7
4
  ctx: CanvasRenderingContext2D;
@@ -9,21 +6,6 @@ export interface CanvasContext {
9
6
  height: number;
10
7
  pixelRatio: number;
11
8
  }
12
- /**
13
- * Component with canvas capabilities
14
- */
15
- interface CanvasComponent {
16
- element: HTMLElement;
17
- canvas: HTMLCanvasElement;
18
- ctx: CanvasRenderingContext2D;
19
- getClass: (name: string) => string;
20
- draw: () => void;
21
- resize: () => void;
22
- [key: string]: unknown;
23
- }
24
- /**
25
- * Base component interface for withCanvas
26
- */
27
9
  interface BaseComponent {
28
10
  element: HTMLElement;
29
11
  getClass: (name: string) => string;
@@ -38,24 +20,31 @@ interface BaseComponent {
38
20
  indeterminate?: boolean;
39
21
  [key: string]: unknown;
40
22
  };
41
- animationId?: number | null;
42
- wavyAnimationId?: number | null;
43
- valueAnimationId?: number | null;
44
- animationTime?: number;
45
- setIndeterminate?: (indeterminate: boolean) => void;
46
23
  [key: string]: unknown;
47
24
  }
25
+ export interface CanvasComponent extends BaseComponent {
26
+ canvas: HTMLCanvasElement;
27
+ ctx?: CanvasRenderingContext2D;
28
+ draw: () => void;
29
+ resize: () => void;
30
+ }
48
31
  /**
49
- * Gets the stroke width for a given thickness preset or custom value
32
+ * Resolves a thickness preset or a number of pixels
50
33
  */
51
34
  export declare const getStrokeWidth: (thickness?: ProgressThickness) => number;
52
35
  /**
53
- * Calculates wave amplitude based on stroke width
54
- * Uses thickness 4 as the baseline (where amplitude is perfect)
36
+ * How tall the wave is, in pixels. The linear wave keeps the token's
37
+ * relationship to the track (3dp of wave to a 4dp track, which is the 10dp
38
+ * container the tokens describe), so a thicker track waves proportionally;
39
+ * the circular wave scales with the indicator's size, as the guidelines ask.
55
40
  */
56
- export declare const getWaveAmplitude: (strokeWidth: number, baseAmplitude: number, maxAmplitude?: number) => number;
41
+ export declare const getWaveAmplitude: (isCircular: boolean, strokeWidth: number, size: number) => number;
42
+ /** The container size of a circular indicator: 40dp flat, 48dp wavy */
43
+ export declare const getCircularSize: (config: ProgressConfig) => number;
44
+ /** The height of a linear indicator: the track, plus the wave on both sides */
45
+ export declare const getLinearHeight: (strokeWidth: number, isWavy: boolean) => number;
57
46
  /**
58
- * Adds canvas functionality to replace complex DOM structure
47
+ * Adds the canvas, the drawing routine and the animation loop
59
48
  */
60
49
  export declare const withCanvas: (config: ProgressConfig) => (component: BaseComponent) => CanvasComponent;
61
50
  export {};
@@ -1,9 +1,19 @@
1
- /**
2
- * Circular progress drawing functionality
3
- */
4
- import { ProgressConfig, ProgressShape } from "../types";
5
1
  import { CanvasContext } from "./canvas";
2
+ import { ProgressColors } from "./colors";
3
+ /** What a frame of the circular indicator needs */
4
+ export interface CircularFrame {
5
+ /** Progress from 0 to 1; ignored when indeterminate */
6
+ progress: number;
7
+ indeterminate: boolean;
8
+ /** Arc thickness in pixels */
9
+ strokeWidth: number;
10
+ /** Milliseconds since the animation started */
11
+ time: number;
12
+ /** Wave height in pixels; 0 draws a flat arc */
13
+ waveAmplitude: number;
14
+ colors: ProgressColors;
15
+ }
6
16
  /**
7
- * Draws circular progress on canvas
17
+ * Draws one frame of the circular indicator.
8
18
  */
9
- export declare const drawCircularProgress: (context: CanvasContext, config: ProgressConfig, value: number, max: number, isIndeterminate: boolean, animationTime?: number, currentShape?: ProgressShape) => void;
19
+ export declare const drawCircularProgress: (context: CanvasContext, frame: CircularFrame) => void;
@@ -0,0 +1,16 @@
1
+ export interface ProgressColors {
2
+ indicator: string;
3
+ track: string;
4
+ stop: string;
5
+ buffer: string;
6
+ }
7
+ /**
8
+ * Keeps the palette for one indicator, refreshed when the theme changes.
9
+ * @param onChange - called after the colours change, to redraw
10
+ * @returns the palette getter and a cleanup function
11
+ */
12
+ export declare const createColors: (onChange: () => void) => {
13
+ get: () => ProgressColors;
14
+ refresh: () => void;
15
+ destroy: () => void;
16
+ };
@@ -1,9 +1,25 @@
1
- /**
2
- * Linear progress drawing functionality
3
- */
4
- import { ProgressConfig, ProgressShape } from "../types";
5
1
  import { CanvasContext } from "./canvas";
2
+ import { ProgressColors } from "./colors";
3
+ /** What a frame of the linear indicator needs */
4
+ export interface LinearFrame {
5
+ /** Progress from 0 to 1; ignored when indeterminate */
6
+ progress: number;
7
+ /** Buffer from 0 to 1, this library's own extension; 0 for none */
8
+ buffer: number;
9
+ indeterminate: boolean;
10
+ /** Track and indicator thickness in pixels */
11
+ strokeWidth: number;
12
+ /** Milliseconds since the animation started */
13
+ time: number;
14
+ /** Wave height in pixels; 0 draws a flat indicator */
15
+ waveAmplitude: number;
16
+ /** Right to left, in which case the indicator runs from the right */
17
+ rtl: boolean;
18
+ colors: ProgressColors;
19
+ /** Whether to mark the end of the track with a dot */
20
+ showStopIndicator: boolean;
21
+ }
6
22
  /**
7
- * Draws linear progress on canvas with shape support
23
+ * Draws one frame of the linear indicator.
8
24
  */
9
- export declare const drawLinearProgress: (context: CanvasContext, config: ProgressConfig, value: number, max: number, buffer: number, isIndeterminate: boolean, animationTime?: number, showStopIndicator?: boolean, currentShape?: ProgressShape) => void;
25
+ export declare const drawLinearProgress: (context: CanvasContext, frame: LinearFrame) => void;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * A cubic Bézier easing, as CSS and Compose define it: the curve through
3
+ * (0,0), (x1,y1), (x2,y2), (1,1), solved for y at a given x.
4
+ */
5
+ export declare const cubicBezier: (x1: number, y1: number, x2: number, y2: number) => ((t: number) => number);
6
+ export declare const emphasizedAccelerate: (t: number) => number;
7
+ export declare const emphasizedDecelerate: (t: number) => number;
8
+ export declare const standardEasing: (t: number) => number;
9
+ /** Where the two indeterminate bars are, as fractions of the track */
10
+ export interface LinearIndeterminateFrame {
11
+ firstHead: number;
12
+ firstTail: number;
13
+ secondHead: number;
14
+ secondTail: number;
15
+ }
16
+ /**
17
+ * The linear indeterminate frame at `elapsed` milliseconds: two bars, each
18
+ * from its tail to its head, on the Compose keyframes over a 1750ms cycle.
19
+ */
20
+ export declare const linearIndeterminateFrame: (elapsed: number) => LinearIndeterminateFrame;
21
+ /** How far round the arc has turned, and how much of the circle it covers */
22
+ export interface CircularIndeterminateFrame {
23
+ /** Rotation of the arc's start, in degrees clockwise from 3 o'clock */
24
+ rotation: number;
25
+ /** Length of the arc as a fraction of the circle */
26
+ sweep: number;
27
+ }
28
+ /**
29
+ * The circular indeterminate frame at `elapsed` milliseconds: a 1080 degree
30
+ * linear turn over the 6 second cycle, four 90 degree kicks on top of it, and
31
+ * an arc that grows to 87% by half way and shrinks back to 10%.
32
+ */
33
+ export declare const circularIndeterminateFrame: (elapsed: number) => CircularIndeterminateFrame;
34
+ /**
35
+ * How tall the wave is for a determinate value: flat at both ends of the
36
+ * range, full in between (WavyProgressIndicatorDefaults.indicatorAmplitude).
37
+ */
38
+ export declare const waveAmplitudeTarget: (progress: number) => number;
39
+ /**
40
+ * The wave's height part way through a change: standard easing on the way in,
41
+ * emphasized accelerate on the way out, over 500ms either way.
42
+ */
43
+ export declare const waveAmplitudeAt: (from: number, target: number, elapsed: number) => number;
@@ -1,2 +1,2 @@
1
1
  export { default } from "./progress";
2
- export { ProgressConfig, ProgressComponent, ProgressShape } from "./types";
2
+ export type { ProgressConfig, ProgressComponent, ProgressShape } from "./types";
@@ -74,6 +74,19 @@ export interface ProgressConfig {
74
74
  * @default false
75
75
  */
76
76
  indeterminate?: boolean;
77
+ /**
78
+ * Whether to mark the end of a linear determinate track with a 4dp dot.
79
+ * The dot is required unless the track has at least 3:1 contrast with
80
+ * everything around it (M3 progress indicator accessibility), so it is on
81
+ * by default.
82
+ * @default true
83
+ */
84
+ showStopIndicator?: boolean;
85
+ /**
86
+ * Accessible name: what is loading, such as "Loading news article"
87
+ * @default 'Loading'
88
+ */
89
+ ariaLabel?: string;
77
90
  /**
78
91
  * Custom label formatter function
79
92
  */
@@ -111,6 +124,10 @@ export interface ProgressComponent {
111
124
  track: SVGElement;
112
125
  /** The indicator element (filled part) - always an SVG element */
113
126
  indicator: SVGElement;
127
+ /** The canvas the indicator is drawn on */
128
+ canvas?: HTMLCanvasElement;
129
+ /** Re-measures the canvas and redraws; the component does this on resize */
130
+ resize?: () => void;
114
131
  /** The buffer element for linear variant (pre-loaded state) - always an SVG element */
115
132
  buffer?: SVGElement;
116
133
  /**