mtrl 0.7.0 → 0.8.0-next.4

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 (48) hide show
  1. package/dist/components/button/api.d.ts +4 -0
  2. package/dist/components/button/features/toggle.d.ts +42 -0
  3. package/dist/components/button/types.d.ts +30 -0
  4. package/dist/components/button-group/button-group.d.ts +6 -4
  5. package/dist/components/button-group/config.d.ts +15 -7
  6. package/dist/components/button-group/constants.d.ts +85 -17
  7. package/dist/components/button-group/index.d.ts +1 -1
  8. package/dist/components/button-group/types.d.ts +68 -4
  9. package/dist/components/carousel/api.d.ts +11 -30
  10. package/dist/components/carousel/arrangement.d.ts +23 -0
  11. package/dist/components/carousel/carousel.d.ts +13 -63
  12. package/dist/components/carousel/config.d.ts +2 -31
  13. package/dist/components/carousel/constants.d.ts +25 -151
  14. package/dist/components/carousel/features/index.d.ts +2 -5
  15. package/dist/components/carousel/features/scroll.d.ts +19 -0
  16. package/dist/components/carousel/features/slides.d.ts +18 -8
  17. package/dist/components/carousel/index.d.ts +3 -37
  18. package/dist/components/carousel/keylines.d.ts +65 -0
  19. package/dist/components/carousel/strategy.d.ts +36 -0
  20. package/dist/components/carousel/types.d.ts +36 -242
  21. package/dist/components/dialog/api.d.ts +1 -1
  22. package/dist/components/index.d.ts +2 -0
  23. package/dist/components/slider/constants.d.ts +8 -8
  24. package/dist/components/slider/types.d.ts +4 -1
  25. package/dist/components/snackbar/api.d.ts +1 -1
  26. package/dist/components/snackbar/config.d.ts +2 -1
  27. package/dist/components/snackbar/constants.d.ts +18 -0
  28. package/dist/components/snackbar/index.d.ts +2 -1
  29. package/dist/components/snackbar/queue.d.ts +10 -2
  30. package/dist/components/snackbar/types.d.ts +37 -1
  31. package/dist/index.cjs +20 -10
  32. package/dist/index.cjs.map +54 -38
  33. package/dist/index.js +20 -10
  34. package/dist/index.js.map +54 -38
  35. package/dist/package.json +1 -1
  36. package/dist/styles.css +2 -2
  37. package/package.json +3 -6
  38. package/src/styles/abstract/_theme.scss +4 -2
  39. package/src/styles/abstract/_variables.scss +59 -12
  40. package/src/styles/components/_button-group.scss +122 -349
  41. package/src/styles/components/_button.scss +333 -591
  42. package/src/styles/components/_carousel.scss +131 -611
  43. package/src/styles/components/_icon-button.scss +23 -23
  44. package/src/styles/components/_select.scss +9 -1
  45. package/src/styles/components/_slider.scss +10 -9
  46. package/src/styles/themes/_index.scss +1 -0
  47. package/src/styles/themes/_legacy.scss +73 -0
  48. package/dist/components/carousel/features/drag.d.ts +0 -8
@@ -1,165 +1,39 @@
1
1
  /**
2
- * Carousel layout types as defined by Material Design 3
3
- *
4
- * Material Design 3 defines specific layout patterns for carousels
5
- * to accommodate different content presentation needs.
6
- *
7
- * @category Components
8
- * @see https://material.io/components/carousel
2
+ * Material 3 carousel layouts (m3.material.io carousel specs)
9
3
  */
10
- export declare const CAROUSEL_LAYOUTS: {
11
- /**
12
- * Multi-browse layout: Best for browsing many visual items at once
13
- * Ideal for photo galleries, product collections, or event feeds
14
- * Shows multiple items in a single view with varying sizes
15
- */
4
+ export declare const CAROUSEL_VARIANTS: {
5
+ /** At least one large, one medium and one small item; the default */
16
6
  readonly MULTI_BROWSE: "multi-browse";
17
- /**
18
- * Uncontained layout: For highly customized or text-heavy carousels
19
- * Traditional horizontal scrolling behavior without special styling
20
- * Content can extend beyond viewport edges with consistent sizing
21
- */
7
+ /** Items keep one size and run off the trailing edge */
22
8
  readonly UNCONTAINED: "uncontained";
23
- /**
24
- * Hero layout: For spotlighting very large visual items
25
- * Highlights featured content with a large central item
26
- * Shows a partial preview of the next/previous items
27
- */
9
+ /** One large item and a small preview of the next */
28
10
  readonly HERO: "hero";
29
- /**
30
- * Full-screen layout: For immersive vertical-scrolling experiences
31
- * Takes up entire viewport with snap scrolling between items
32
- * Suited for immersive content or focused presentations
33
- */
11
+ /** One large item centred between two small ones */
12
+ readonly HERO_CENTER: "hero-center";
13
+ /** One edge-to-edge item at a time, scrolling vertically */
34
14
  readonly FULL_SCREEN: "full-screen";
35
15
  };
36
- /**
37
- * Carousel scroll behaviors
38
- *
39
- * Controls how scrolling behaves when moving between items.
40
- * Each layout type has a recommended default behavior.
41
- *
42
- * @category Components
43
- */
44
- export declare const CAROUSEL_SCROLL_BEHAVIORS: {
45
- /**
46
- * Default: Standard smooth scrolling without snapping
47
- * Users can stop at any position between items
48
- * Recommended for uncontained layouts and content browsing
49
- */
50
- readonly DEFAULT: "default";
51
- /**
52
- * Snap: Items snap to predefined positions when scrolling
53
- * Ensures items are properly aligned for viewing
54
- * Recommended for multi-browse, hero, and full-screen layouts
55
- */
56
- readonly SNAP: "snap";
57
- };
58
- /**
59
- * Carousel item size constants
60
- *
61
- * Defines the available sizes for carousel items.
62
- * These are used to control the relative sizing of
63
- * items within different carousel layouts.
64
- *
65
- * @category Components
66
- */
67
- export declare const CAROUSEL_ITEM_SIZES: {
68
- /** Large featured items (primary content) */
69
- readonly LARGE: "large";
70
- /** Medium-sized items (secondary content) */
71
- readonly MEDIUM: "medium";
72
- /** Small items (tertiary content or thumbnails) */
73
- readonly SMALL: "small";
74
- };
75
- /**
76
- * Transition effects for carousel slides
77
- *
78
- * Controls the visual transition when moving between slides.
79
- *
80
- * @category Components
81
- */
82
- export declare const CAROUSEL_TRANSITIONS: {
83
- /** Horizontal sliding animation (default) */
84
- readonly SLIDE: "slide";
85
- /** Fade in/out transition between slides */
86
- readonly FADE: "fade";
87
- /** No animation, immediate change */
88
- readonly NONE: "none";
89
- };
90
- /**
91
- * Event names for the carousel component
92
- *
93
- * These events can be listened to using the carousel's
94
- * `on()` method for custom behavior.
95
- *
96
- * @example
97
- * carousel.on(CAROUSEL_EVENTS.SLIDE_CHANGED, (index) => {
98
- * console.log(`Now showing slide ${index}`);
99
- * });
100
- *
101
- * @category Components
102
- */
103
16
  export declare const CAROUSEL_EVENTS: {
104
- /** Fired when a slide change begins */
105
- readonly SLIDE_CHANGE: "slide-change";
106
- /** Fired when a slide change completes */
107
- readonly SLIDE_CHANGED: "slide-changed";
108
- /** Fired when the carousel is resized */
109
- readonly RESIZE: "resize";
17
+ /** The snapped item changed; detail carries the index */
18
+ readonly CHANGE: "change";
110
19
  };
111
20
  /**
112
- * Default values for carousel configuration
113
- *
114
- * These values will be used when not explicitly specified
115
- * in the configuration object passed to createCarousel().
116
- *
117
- * @category Components
21
+ * Defaults from the Compose Material 3 carousel (CarouselDefaults) and the
22
+ * carousel specs: 8dp between items, 16dp container padding, 28dp corners,
23
+ * small items between 40 and 56dp, 10dp anchors just outside the container.
118
24
  */
119
25
  export declare const CAROUSEL_DEFAULTS: {
120
- /** Start displaying from the first slide (index 0) */
121
- readonly INITIAL_SLIDE: 0;
122
- /** Enable infinite looping by default */
123
- readonly LOOP: true;
124
- /** Default transition effect is sliding */
125
- readonly TRANSITION: "slide";
126
- /** Transition duration in milliseconds */
127
- readonly TRANSITION_DURATION: 300;
128
- /** Border radius for slides following Material Design 3 */
129
- readonly BORDER_RADIUS: 16;
130
- /** Gap between slides in pixels */
26
+ readonly VARIANT: "multi-browse";
27
+ /** Preferred width of a large item; hero layouts use it as a maximum */
28
+ readonly ITEM_WIDTH: 280;
131
29
  readonly GAP: 8;
132
- /** Default layout is multi-browse for browsing visual content */
133
- readonly LAYOUT: "multi-browse";
134
- /** Default scroll behavior is snap for controlled movement */
135
- readonly SCROLL_BEHAVIOR: "snap";
136
- /** Small item width in pixels (40-56dp range per MD3 guidelines) */
137
- readonly SMALL_ITEM_WIDTH: 48;
138
- /**
139
- * Item widths for different layouts in pixels
140
- * These values are optimized for each layout type
141
- * based on Material Design 3 guidelines
142
- */
143
- readonly ITEM_WIDTHS: {
144
- readonly "multi-browse": {
145
- readonly LARGE: 240;
146
- readonly MEDIUM: 180;
147
- readonly SMALL: 48;
148
- };
149
- readonly uncontained: {
150
- readonly LARGE: 240;
151
- readonly MEDIUM: 240;
152
- readonly SMALL: 240;
153
- };
154
- readonly hero: {
155
- readonly LARGE: 300;
156
- readonly MEDIUM: 240;
157
- readonly SMALL: 48;
158
- };
159
- readonly "full-screen": {
160
- readonly LARGE: "100%";
161
- readonly MEDIUM: "100%";
162
- readonly SMALL: "100%";
163
- };
164
- };
30
+ /** Full-screen layouts space items 16dp apart */
31
+ readonly GAP_FULL_SCREEN: 16;
32
+ readonly PADDING: 16;
33
+ readonly CORNER_RADIUS: 28;
34
+ readonly MIN_SMALL_ITEM_WIDTH: 40;
35
+ readonly MAX_SMALL_ITEM_WIDTH: 56;
36
+ readonly ANCHOR_SIZE: 10;
37
+ readonly MEDIUM_LARGE_THRESHOLD: 0.85;
38
+ readonly INITIAL_SLIDE: 0;
165
39
  };
@@ -1,5 +1,2 @@
1
- /**
2
- * Entry point for Carousel component features
3
- */
4
- export { withSlides } from './slides';
5
- export { withDrag } from './drag';
1
+ export { withSlides } from "./slides";
2
+ export { withScroll } from "./scroll";
@@ -0,0 +1,19 @@
1
+ import { CarouselConfig, CarouselVariant } from "../types";
2
+ import type { SlidesComponent } from "./slides";
3
+ interface ScrollComponent {
4
+ getCurrentSlide: () => number;
5
+ getVariant: () => CarouselVariant;
6
+ next: () => void;
7
+ prev: () => void;
8
+ goTo: (index: number) => void;
9
+ lifecycle: {
10
+ destroy: () => void;
11
+ };
12
+ }
13
+ export declare const withScroll: (config: CarouselConfig) => <C extends SlidesComponent & {
14
+ emit?: (event: string, data?: unknown) => unknown;
15
+ lifecycle?: {
16
+ destroy: () => void;
17
+ };
18
+ }>(component: C) => C & ScrollComponent;
19
+ export {};
@@ -1,8 +1,18 @@
1
- import { CarouselConfig } from "../types";
2
- /**
3
- * Adds slide functionality to the carousel component with Material Design 3 layout types support
4
- *
5
- * @param {CarouselConfig} config - Carousel configuration
6
- * @returns {Function} Higher-order function that adds slides feature
7
- */
8
- export declare const withSlides: (config: CarouselConfig) => (component: any) => any;
1
+ import { CarouselConfig, SlidesAPI } from "../types";
2
+ export interface SlidesComponent {
3
+ element: HTMLElement;
4
+ getClass: (name: string) => string;
5
+ /** Scroll container holding the track */
6
+ scroller: HTMLElement;
7
+ /** Positioned parent of the items */
8
+ track: HTMLElement;
9
+ slides: SlidesAPI;
10
+ slideElements: HTMLElement[];
11
+ /** Registers the callback run when items are added or removed (the scroll feature rebuilds) */
12
+ onSlidesChanged: (handler: () => void) => void;
13
+ [key: string]: unknown;
14
+ }
15
+ export declare const withSlides: (config: CarouselConfig) => <C extends {
16
+ element: HTMLElement;
17
+ getClass: (name: string) => string;
18
+ }>(component: C) => C & SlidesComponent;
@@ -1,37 +1,3 @@
1
- /**
2
- * Carousel Component Module
3
- *
4
- * A Material Design 3 compatible carousel implementation that supports
5
- * various layout types and scroll behaviors to accommodate different
6
- * content presentation needs.
7
- *
8
- * @module components/carousel
9
- * @category Components
10
- */
11
- export { default } from './carousel';
12
- /**
13
- * Constants for carousel configuration
14
- *
15
- * Use these constants instead of string literals for better
16
- * code completion, type safety, and to follow best practices.
17
- *
18
- * @example
19
- * import { createCarousel, CAROUSEL_LAYOUTS } from 'mtrl';
20
- *
21
- * const carousel = createCarousel({
22
- * layout: CAROUSEL_LAYOUTS.MULTI_BROWSE,
23
- * // Other configuration options...
24
- * });
25
- *
26
- * @category Components
27
- */
28
- export { CAROUSEL_LAYOUTS, CAROUSEL_SCROLL_BEHAVIORS, CAROUSEL_TRANSITIONS, CAROUSEL_EVENTS, CAROUSEL_DEFAULTS, CAROUSEL_ITEM_SIZES } from './constants';
29
- /**
30
- * TypeScript types and interfaces for the Carousel component
31
- *
32
- * These provide proper type checking and IntelliSense support
33
- * when using the carousel component in TypeScript projects.
34
- *
35
- * @category Components
36
- */
37
- export { CarouselConfig, CarouselComponent, CarouselSlide, CarouselLayout, CarouselScrollBehavior } from './types';
1
+ export { default, createCarousel } from "./carousel";
2
+ export { CAROUSEL_VARIANTS, CAROUSEL_EVENTS, CAROUSEL_DEFAULTS, } from "./constants";
3
+ export type { CarouselConfig, CarouselComponent, CarouselSlide, CarouselVariant, SlidesAPI, } from "./types";
@@ -0,0 +1,65 @@
1
+ export interface Keyline {
2
+ size: number;
3
+ /** Centre of the item along the axis, in container coordinates */
4
+ offset: number;
5
+ /** Centre the item would have if every item were large */
6
+ unadjustedOffset: number;
7
+ isFocal: boolean;
8
+ isAnchor: boolean;
9
+ isPivot: boolean;
10
+ /** How much of the item hangs outside the container */
11
+ cutoff: number;
12
+ }
13
+ export type KeylineList = Keyline[];
14
+ interface TmpKeyline {
15
+ size: number;
16
+ isAnchor: boolean;
17
+ }
18
+ export interface KeylineRules {
19
+ minSmallSize: number;
20
+ maxSmallSize: number;
21
+ anchorSize: number;
22
+ /** A medium item wider than this share of a large one is cut differently in uncontained layouts */
23
+ mediumLargeThreshold: number;
24
+ }
25
+ export declare const firstFocalIndex: (list: KeylineList) => number;
26
+ export declare const lastFocalIndex: (list: KeylineList) => number;
27
+ export declare const firstNonAnchorIndex: (list: KeylineList) => number;
28
+ export declare const lastNonAnchorIndex: (list: KeylineList) => number;
29
+ export declare const pivotIndex: (list: KeylineList) => number;
30
+ export declare const focalCount: (list: KeylineList) => number;
31
+ export declare const minSize: (list: KeylineList) => number;
32
+ export declare const maxSize: (list: KeylineList) => number;
33
+ export declare const isFirstFocalItemAtStartOfContainer: (list: KeylineList) => boolean;
34
+ export declare const isLastFocalItemAtEndOfContainer: (list: KeylineList, containerSize: number) => boolean;
35
+ export declare const firstIndexAfterFocalRangeWithSize: (list: KeylineList, size: number) => number;
36
+ export declare const lastIndexBeforeFocalRangeWithSize: (list: KeylineList, size: number) => number;
37
+ export declare const keylineBefore: (list: KeylineList, unadjustedOffset: number) => Keyline;
38
+ export declare const keylineAfter: (list: KeylineList, unadjustedOffset: number) => Keyline;
39
+ export declare const lerpKeyline: (a: Keyline, b: Keyline, t: number) => Keyline;
40
+ export declare const lerpKeylineList: (from: KeylineList, to: KeylineList, t: number) => KeylineList;
41
+ /** Builds a keyline list with an explicit pivot (used for the shifted start and end steps) */
42
+ export declare const keylineListWithPivot: (containerSize: number, gap: number, pivotIdx: number, pivotOffset: number, tmp: TmpKeyline[]) => KeylineList;
43
+ /** Builds a keyline list aligned to the start or centre of the container */
44
+ export declare const keylineListAligned: (containerSize: number, gap: number, alignment: "start" | "center", tmp: TmpKeyline[]) => KeylineList;
45
+ /**
46
+ * Multi-browse: at least one large, one medium and one small item; a small
47
+ * item aims for a third of a large one within the 40–56dp range and the
48
+ * medium item sits halfway. More large items appear as the container grows.
49
+ */
50
+ export declare const multiBrowseKeylines: (containerSize: number, preferredItemSize: number, gap: number, count: number, rules: KeylineRules) => KeylineList;
51
+ /**
52
+ * Hero: one large item (or more on wide containers) and one small item; the
53
+ * centred variant places the large item between two small ones.
54
+ */
55
+ export declare const heroKeylines: (containerSize: number, maxItemSize: number | null, gap: number, count: number, centered: boolean, rules: KeylineRules) => KeylineList;
56
+ /**
57
+ * Uncontained: every item keeps its width and the last visible one is cut
58
+ * off at the trailing edge, about a third of it hidden. Compose folds the
59
+ * spacing into the item size; here the gaps stay between the items so the
60
+ * spec's 8dp holds and the cut-off item keeps two thirds visible.
61
+ */
62
+ export declare const uncontainedKeylines: (containerSize: number, itemSize: number, gap: number, rules: KeylineRules) => KeylineList;
63
+ /** Full-screen: one item fills the container edge to edge */
64
+ export declare const fullScreenKeylines: (containerSize: number, gap: number, rules: KeylineRules) => KeylineList;
65
+ export {};
@@ -0,0 +1,36 @@
1
+ import { Keyline, KeylineList } from './keylines';
2
+ export interface Strategy {
3
+ defaultKeylines: KeylineList;
4
+ startSteps: KeylineList[];
5
+ endSteps: KeylineList[];
6
+ availableSpace: number;
7
+ gap: number;
8
+ beforePadding: number;
9
+ afterPadding: number;
10
+ /** Size of a large item: the unit every item is measured in before adjustment */
11
+ itemSize: number;
12
+ minItemSize: number;
13
+ maxItemSize: number;
14
+ valid: boolean;
15
+ startShiftDistance: number;
16
+ endShiftDistance: number;
17
+ startShiftPoints: number[];
18
+ endShiftPoints: number[];
19
+ }
20
+ export interface ItemPlacement {
21
+ /** Visible size of the item along the axis */
22
+ size: number;
23
+ /** Centre of the visible part, in container coordinates */
24
+ center: number;
25
+ /** Interpolated keyline the item sits on */
26
+ keyline: Keyline;
27
+ }
28
+ export declare const createStrategy: (defaultKeylines: KeylineList, availableSpace: number, gap: number, beforePadding: number, afterPadding: number) => Strategy;
29
+ /** Keylines in effect for a scroll offset: default, or interpolated within the start or end shift range */
30
+ export declare const keylinesForScrollOffset: (s: Strategy, scrollOffset: number, maxScrollOffset: number, roundToNearestStep?: boolean) => KeylineList;
31
+ /** Distance from the container start to an item's start when that item is snapped */
32
+ export declare const snapPositionOffset: (s: Strategy, index: number, count: number) => number;
33
+ /** Largest scroll offset: the content laid out at large size minus the container */
34
+ export declare const maxScrollOffset: (s: Strategy, count: number) => number;
35
+ /** Where an item sits and how much of it shows for the keylines in effect */
36
+ export declare const placeItem: (s: Strategy, keylines: KeylineList, index: number, scrollOffset: number) => ItemPlacement;