mtrl 0.6.2 → 0.7.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.
Files changed (48) hide show
  1. package/README.md +39 -0
  2. package/dist/README.md +39 -0
  3. package/dist/components/badge/index.d.ts +2 -2
  4. package/dist/components/button/index.d.ts +1 -0
  5. package/dist/components/card/index.d.ts +0 -1
  6. package/dist/components/chips/index.d.ts +3 -4
  7. package/dist/components/datepicker/index.d.ts +3 -3
  8. package/dist/components/dialog/index.d.ts +2 -2
  9. package/dist/components/drawer/api.d.ts +54 -0
  10. package/dist/components/drawer/config.d.ts +106 -0
  11. package/dist/components/drawer/constants.d.ts +97 -0
  12. package/dist/components/drawer/drawer.d.ts +59 -0
  13. package/dist/components/drawer/features/headline.d.ts +17 -0
  14. package/dist/components/drawer/features/index.d.ts +3 -0
  15. package/dist/components/drawer/features/items.d.ts +18 -0
  16. package/dist/components/drawer/features/state.d.ts +18 -0
  17. package/dist/components/drawer/index.d.ts +6 -0
  18. package/dist/components/drawer/types.d.ts +233 -0
  19. package/dist/components/fab/index.d.ts +2 -2
  20. package/dist/components/index.d.ts +38 -47
  21. package/dist/components/menu/constants.d.ts +2 -0
  22. package/dist/components/menu/features/opener.d.ts +1 -1
  23. package/dist/components/menu/types.d.ts +14 -0
  24. package/dist/components/progress/index.d.ts +2 -3
  25. package/dist/components/progress/types.d.ts +8 -0
  26. package/dist/components/search/index.d.ts +0 -1
  27. package/dist/components/segmented-button/index.d.ts +3 -4
  28. package/dist/components/slider/index.d.ts +2 -3
  29. package/dist/components/snackbar/index.d.ts +2 -3
  30. package/dist/components/textfield/index.d.ts +0 -1
  31. package/dist/index.cjs +10 -20
  32. package/dist/index.cjs.map +52 -70
  33. package/dist/index.d.ts +0 -1
  34. package/dist/index.js +10 -20
  35. package/dist/index.js.map +52 -70
  36. package/dist/package.json +1 -1
  37. package/dist/styles.css +2 -2
  38. package/package.json +23 -5
  39. package/src/styles/components/_button-group.scss +1 -1
  40. package/src/styles/components/_button.scss +1 -1
  41. package/src/styles/components/_drawer.scss +611 -0
  42. package/src/styles/components/_extended-fab.scss +1 -1
  43. package/src/styles/components/_fab.scss +1 -1
  44. package/src/styles/components/_icon-button.scss +1 -1
  45. package/src/styles/components/_menu.scss +25 -0
  46. package/src/styles/components/_segmented-button.scss +1 -1
  47. package/src/styles/main.scss +1 -0
  48. package/dist/constants.d.ts +0 -30
package/README.md CHANGED
@@ -61,6 +61,45 @@ yarn add mtrl
61
61
  bun add mtrl
62
62
  ```
63
63
 
64
+ ## Tree-Shaking Optimized Imports
65
+
66
+ mtrl is optimized for tree-shaking. Constants are exported separately from component creators to minimize bundle size.
67
+
68
+ ### Import Patterns
69
+
70
+ | Import Type | Path |
71
+ |-------------|------|
72
+ | Component creators | `import { createButton } from 'mtrl'` |
73
+ | Button constants | `import { BUTTON_VARIANTS } from 'mtrl/components/button/constants'` |
74
+ | Slider constants | `import { SLIDER_SIZES } from 'mtrl/components/slider/constants'` |
75
+ | Card constants | `import { CARD_VARIANTS } from 'mtrl/components/card/constants'` |
76
+ | Direct component import | `import createButton from 'mtrl/components/button'` |
77
+ | Core utilities | `import { addClass, removeClass } from 'mtrl/core/dom'` |
78
+
79
+ ### Example
80
+
81
+ ```typescript
82
+ // ✅ Optimal - only imports what you need
83
+ import { createButton } from 'mtrl';
84
+ import { BUTTON_VARIANTS, BUTTON_SIZES } from 'mtrl/components/button/constants';
85
+
86
+ const button = createButton({
87
+ text: 'Submit',
88
+ variant: BUTTON_VARIANTS.FILLED,
89
+ size: BUTTON_SIZES.LARGE
90
+ });
91
+
92
+ // ✅ Also optimal - direct component import
93
+ import createSlider from 'mtrl/components/slider';
94
+ import { SLIDER_COLORS } from 'mtrl/components/slider/constants';
95
+
96
+ const slider = createSlider({
97
+ color: SLIDER_COLORS.PRIMARY
98
+ });
99
+ ```
100
+
101
+ **Note:** Constants are NOT exported from main entry points. Always import them from the component's constants file.
102
+
64
103
  ## Component Architecture
65
104
 
66
105
  Let's look at how mtrl components are constructed:
package/dist/README.md CHANGED
@@ -61,6 +61,45 @@ yarn add mtrl
61
61
  bun add mtrl
62
62
  ```
63
63
 
64
+ ## Tree-Shaking Optimized Imports
65
+
66
+ mtrl is optimized for tree-shaking. Constants are exported separately from component creators to minimize bundle size.
67
+
68
+ ### Import Patterns
69
+
70
+ | Import Type | Path |
71
+ |-------------|------|
72
+ | Component creators | `import { createButton } from 'mtrl'` |
73
+ | Button constants | `import { BUTTON_VARIANTS } from 'mtrl/components/button/constants'` |
74
+ | Slider constants | `import { SLIDER_SIZES } from 'mtrl/components/slider/constants'` |
75
+ | Card constants | `import { CARD_VARIANTS } from 'mtrl/components/card/constants'` |
76
+ | Direct component import | `import createButton from 'mtrl/components/button'` |
77
+ | Core utilities | `import { addClass, removeClass } from 'mtrl/core/dom'` |
78
+
79
+ ### Example
80
+
81
+ ```typescript
82
+ // ✅ Optimal - only imports what you need
83
+ import { createButton } from 'mtrl';
84
+ import { BUTTON_VARIANTS, BUTTON_SIZES } from 'mtrl/components/button/constants';
85
+
86
+ const button = createButton({
87
+ text: 'Submit',
88
+ variant: BUTTON_VARIANTS.FILLED,
89
+ size: BUTTON_SIZES.LARGE
90
+ });
91
+
92
+ // ✅ Also optimal - direct component import
93
+ import createSlider from 'mtrl/components/slider';
94
+ import { SLIDER_COLORS } from 'mtrl/components/slider/constants';
95
+
96
+ const slider = createSlider({
97
+ color: SLIDER_COLORS.PRIMARY
98
+ });
99
+ ```
100
+
101
+ **Note:** Constants are NOT exported from main entry points. Always import them from the component's constants file.
102
+
64
103
  ## Component Architecture
65
104
 
66
105
  Let's look at how mtrl components are constructed:
@@ -4,5 +4,5 @@
4
4
  * @description A small element that communicates status, shows a count,
5
5
  * or highlights an element requiring attention.
6
6
  */
7
- export { default } from './badge';
8
- export type { BadgeConfig, BadgeComponent, BadgeVariant, BadgeColor, BadgePosition } from './types';
7
+ export { default } from "./badge";
8
+ export type { BadgeConfig, BadgeComponent, BadgeVariant, BadgeColor, BadgePosition, } from "./types";
@@ -4,3 +4,4 @@
4
4
  */
5
5
  export { default } from "./button";
6
6
  export type { ButtonConfig, ButtonComponent, ButtonVariant } from "./types";
7
+ export type { ButtonSize, ButtonShape } from "./constants";
@@ -69,4 +69,3 @@ export { CardVariant, CardElevationLevel, CardSchema, CardHeaderConfig, CardCont
69
69
  export { createCardContent, createCardHeader, createCardActions, createCardMedia, } from "./content";
70
70
  export { withAPI } from "./api";
71
71
  export { withLoading, withExpandable, withSwipeable, withElevation, } from "./features";
72
- export { CARD_VARIANTS, CARD_ELEVATIONS, CARD_WIDTHS, CARD_CORNER_RADIUS, CARD_ASPECT_RATIOS, CARD_ACTION_ALIGNMENT, CARD_MEDIA_POSITION, CARD_CLASSES, } from "./constants";
@@ -1,4 +1,3 @@
1
- export { default as createChip } from './chip';
2
- export { default as createChips } from './chips';
3
- export * from './constants';
4
- export type { ChipConfig, ChipComponent, ChipVariant, ChipsConfig, ChipsComponent } from './types';
1
+ export { default as createChip } from "./chip";
2
+ export { default as createChips } from "./chips";
3
+ export type { ChipConfig, ChipComponent, ChipVariant, ChipsConfig, ChipsComponent, } from "./types";
@@ -1,3 +1,3 @@
1
- export { default } from './datepicker';
2
- export type { DatePickerConfig, DatePickerComponent, DatePickerVariant, DatePickerView, DatePickerSelectionMode } from './types';
3
- export { DEFAULT_DATE_FORMAT } from './types';
1
+ export { default } from "./datepicker";
2
+ export type { DatePickerConfig, DatePickerComponent, DatePickerVariant, DatePickerView, DatePickerSelectionMode, } from "./types";
3
+ export { DEFAULT_DATE_FORMAT } from "./types";
@@ -10,5 +10,5 @@
10
10
  * @module components/dialog
11
11
  * @category Components
12
12
  */
13
- export { default } from './dialog';
14
- export { DialogConfig, DialogComponent, DialogButton, DialogEvent, DialogConfirmOptions, DialogSize, DialogAnimation, DialogFooterAlignment, DialogEventType } from './types';
13
+ export { default } from "./dialog";
14
+ export { DialogConfig, DialogComponent, DialogButton, DialogEvent, DialogConfirmOptions, DialogSize, DialogAnimation, DialogFooterAlignment, DialogEventType, } from "./types";
@@ -0,0 +1,54 @@
1
+ import { DrawerComponent, DrawerItemConfig } from './types';
2
+ /**
3
+ * API configuration options for drawer component
4
+ * @category Components
5
+ * @internal
6
+ */
7
+ interface ApiOptions {
8
+ state: {
9
+ open: () => void;
10
+ close: () => void;
11
+ toggle: () => void;
12
+ isOpen: () => boolean;
13
+ };
14
+ items: {
15
+ setActive: (id: string) => void;
16
+ getActive: () => string | null;
17
+ setItems: (items: DrawerItemConfig[] | undefined) => void;
18
+ getItems: () => DrawerItemConfig[] | undefined;
19
+ setBadge: (id: string, badge: string) => void;
20
+ };
21
+ headline: {
22
+ setHeadline: (text: string) => void;
23
+ getHeadline: () => string;
24
+ };
25
+ lifecycle: {
26
+ destroy: () => void;
27
+ };
28
+ }
29
+ /**
30
+ * Component with required elements and methods for API enhancement
31
+ * @category Components
32
+ * @internal
33
+ */
34
+ interface ComponentWithElements {
35
+ element: HTMLElement;
36
+ getClass: (name: string) => string;
37
+ on?: (event: string, handler: Function) => ComponentWithElements;
38
+ off?: (event: string, handler: Function) => ComponentWithElements;
39
+ addClass?: (...classes: string[]) => ComponentWithElements;
40
+ }
41
+ /**
42
+ * Enhances a drawer component with public API methods.
43
+ * This follows the higher-order function pattern to add public API methods
44
+ * to the component, making them available to the end user.
45
+ *
46
+ * All methods that modify the component return the component for chaining.
47
+ *
48
+ * @param {ApiOptions} options - API configuration options
49
+ * @returns {Function} Higher-order function that adds API methods to component
50
+ * @category Components
51
+ * @internal This is an internal utility for the Drawer component
52
+ */
53
+ export declare const withAPI: ({ state, items, headline, lifecycle }: ApiOptions) => (component: ComponentWithElements) => DrawerComponent;
54
+ export {};
@@ -0,0 +1,106 @@
1
+ import { DrawerConfig } from "./types";
2
+ /**
3
+ * Default configuration for the Drawer component.
4
+ * These values will be used when not explicitly specified by the user.
5
+ *
6
+ * @category Components
7
+ */
8
+ export declare const defaultConfig: DrawerConfig;
9
+ /**
10
+ * Creates the base configuration for the Drawer component by merging
11
+ * user-provided config with default values. Global configuration is
12
+ * automatically applied by createComponentConfig.
13
+ *
14
+ * @param {DrawerConfig} config - User provided configuration
15
+ * @returns {DrawerConfig} Complete configuration with defaults applied
16
+ * @category Components
17
+ * @internal
18
+ */
19
+ export declare const createBaseConfig: (config?: DrawerConfig) => DrawerConfig;
20
+ /**
21
+ * Generates element configuration for the Drawer component.
22
+ * This function creates the necessary attributes and configuration
23
+ * for the DOM element creation process.
24
+ *
25
+ * @param {DrawerConfig} config - Drawer configuration
26
+ * @returns {Object} Element configuration object for withElement
27
+ * @category Components
28
+ * @internal
29
+ */
30
+ export declare const getElementConfig: (config: DrawerConfig) => {
31
+ tag: string;
32
+ componentName: string;
33
+ attributes: Record<string, any>;
34
+ className: string[];
35
+ rawClass: string | string[];
36
+ id: string;
37
+ name: string;
38
+ title: string;
39
+ tabIndex: number;
40
+ style: string | Partial<CSSStyleDeclaration>;
41
+ data: Record<string, string>;
42
+ role: string;
43
+ ariaLabel: string;
44
+ ariaDescribedBy: string;
45
+ ariaLabelledBy: string;
46
+ ariaHidden: boolean;
47
+ html: string;
48
+ text: string;
49
+ forwardEvents: Record<string, boolean | ((component: any, event: Event) => boolean)>;
50
+ interactive: boolean;
51
+ };
52
+ /**
53
+ * Creates API configuration for the Drawer component.
54
+ * This connects the core component features (state, items, headline)
55
+ * to the public API methods exposed to users.
56
+ *
57
+ * @param {Object} comp - Component with all features applied
58
+ * @returns {Object} API configuration object
59
+ * @category Components
60
+ * @internal
61
+ */
62
+ export declare const getApiConfig: (comp: {
63
+ drawerState: {
64
+ open: () => void;
65
+ close: () => void;
66
+ toggle: () => void;
67
+ isOpen: () => boolean;
68
+ };
69
+ drawerItems: {
70
+ setActive: (id: string) => void;
71
+ getActive: () => string | null;
72
+ setItems: (items: DrawerConfig["items"]) => void;
73
+ getItems: () => DrawerConfig["items"];
74
+ setBadge: (id: string, badge: string) => void;
75
+ };
76
+ drawerHeadline: {
77
+ setHeadline: (text: string) => void;
78
+ getHeadline: () => string;
79
+ };
80
+ lifecycle: {
81
+ destroy: () => void;
82
+ };
83
+ _stateCleanup?: () => void;
84
+ }) => {
85
+ state: {
86
+ open: () => void;
87
+ close: () => void;
88
+ toggle: () => void;
89
+ isOpen: () => boolean;
90
+ };
91
+ items: {
92
+ setActive: (id: string) => void;
93
+ getActive: () => string;
94
+ setItems: (items: DrawerConfig["items"]) => void;
95
+ getItems: () => import("./types").DrawerItemConfig[];
96
+ setBadge: (id: string, badge: string) => void;
97
+ };
98
+ headline: {
99
+ setHeadline: (text: string) => void;
100
+ getHeadline: () => string;
101
+ };
102
+ lifecycle: {
103
+ destroy: () => void;
104
+ };
105
+ };
106
+ export default defaultConfig;
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Drawer variants matching MD3 navigation drawer specification
3
+ */
4
+ export declare const DRAWER_VARIANTS: {
5
+ /** Standard drawer — inline, can be permanently visible or toggled */
6
+ readonly STANDARD: "standard";
7
+ /** Modal drawer — overlays content with scrim, for compact/medium screens */
8
+ readonly MODAL: "modal";
9
+ };
10
+ /**
11
+ * Drawer positions (anchor edge)
12
+ */
13
+ export declare const DRAWER_POSITIONS: {
14
+ /** Start edge (left in LTR, right in RTL) — default per MD3 */
15
+ readonly START: "start";
16
+ /** End edge (right in LTR, left in RTL) */
17
+ readonly END: "end";
18
+ };
19
+ /**
20
+ * Drawer item types for the items configuration array
21
+ */
22
+ export declare const DRAWER_ITEM_TYPES: {
23
+ /** Navigation destination item */
24
+ readonly ITEM: "item";
25
+ /** Visual separator between groups */
26
+ readonly DIVIDER: "divider";
27
+ /** Section label / subhead for grouping */
28
+ readonly SECTION: "section";
29
+ };
30
+ /**
31
+ * Drawer events
32
+ */
33
+ export declare const DRAWER_EVENTS: {
34
+ /** Fired when the drawer opens */
35
+ readonly OPEN: "open";
36
+ /** Fired when the drawer closes */
37
+ readonly CLOSE: "close";
38
+ /** Fired when a navigation item is selected */
39
+ readonly SELECT: "select";
40
+ };
41
+ /**
42
+ * CSS classes used by the drawer component
43
+ */
44
+ export declare const DRAWER_CLASSES: {
45
+ /** Root container */
46
+ readonly ROOT: "drawer";
47
+ /** Scrim overlay (modal variant only) */
48
+ readonly SCRIM: "drawer__scrim";
49
+ /** Inner sheet / panel */
50
+ readonly SHEET: "drawer__sheet";
51
+ /** Headline text */
52
+ readonly HEADLINE: "drawer__headline";
53
+ /** Scrollable items container */
54
+ readonly ITEMS: "drawer__items";
55
+ /** Single navigation item */
56
+ readonly ITEM: "drawer__item";
57
+ /** Item icon */
58
+ readonly ITEM_ICON: "drawer__item-icon";
59
+ /** Item label text */
60
+ readonly ITEM_LABEL: "drawer__item-label";
61
+ /** Item badge */
62
+ readonly ITEM_BADGE: "drawer__item-badge";
63
+ /** Active indicator shape */
64
+ readonly ACTIVE_INDICATOR: "drawer__active-indicator";
65
+ /** Dense/compact variant */
66
+ readonly DENSE: "drawer--dense";
67
+ /** Divider separator */
68
+ readonly DIVIDER: "drawer__divider";
69
+ /** Section label */
70
+ readonly SECTION_LABEL: "drawer__section-label";
71
+ };
72
+ /**
73
+ * Default animation configuration
74
+ */
75
+ export declare const DRAWER_ANIMATION: {
76
+ /** Animation duration in milliseconds */
77
+ readonly DURATION: 300;
78
+ /** Easing for opening */
79
+ readonly EASING_OPEN: "cubic-bezier(0.0, 0.0, 0.2, 1.0)";
80
+ /** Easing for closing */
81
+ readonly EASING_CLOSE: "cubic-bezier(0.3, 0.0, 1.0, 1.0)";
82
+ };
83
+ /**
84
+ * Drawer default values
85
+ */
86
+ export declare const DRAWER_DEFAULTS: {
87
+ /** Default variant */
88
+ readonly VARIANT: "standard";
89
+ /** Default position */
90
+ readonly POSITION: "start";
91
+ /** Whether drawer is open by default */
92
+ readonly OPEN: false;
93
+ /** Whether modal can be dismissed via scrim */
94
+ readonly DISMISSIBLE: true;
95
+ /** Default drawer width in pixels */
96
+ readonly WIDTH: 360;
97
+ };
@@ -0,0 +1,59 @@
1
+ import { DrawerConfig } from "./types";
2
+ /**
3
+ * Creates a new Drawer component with the specified configuration.
4
+ *
5
+ * The Drawer component implements Material Design 3 navigation drawer with
6
+ * support for standard (inline) and modal (overlay) variants. It provides
7
+ * navigation destinations with icons, labels, badges, dividers, and section
8
+ * labels following the MD3 specification.
9
+ *
10
+ * The Drawer component is created using a functional composition pattern,
11
+ * applying various features through the pipe function.
12
+ *
13
+ * @param {DrawerConfig} config - Configuration options for the drawer
14
+ * This can include variant, items, headline, position, open state,
15
+ * and other drawer properties. See {@link DrawerConfig} for available options.
16
+ *
17
+ * @returns {DrawerComponent} A fully configured drawer component instance with
18
+ * all requested features applied. The returned component has methods for
19
+ * state management, item selection, and lifecycle management.
20
+ *
21
+ * @throws {Error} Throws an error if drawer creation fails for any reason
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * // Create a standard navigation drawer
26
+ * const drawer = createDrawer({
27
+ * variant: 'standard',
28
+ * headline: 'Mail',
29
+ * open: true,
30
+ * items: [
31
+ * { id: 'inbox', label: 'Inbox', icon: '<svg>...</svg>', badge: '24', active: true },
32
+ * { id: 'outbox', label: 'Outbox', icon: '<svg>...</svg>' },
33
+ * { type: 'divider' },
34
+ * { type: 'section', label: 'Labels' },
35
+ * { id: 'family', label: 'Family', icon: '<svg>...</svg>' },
36
+ * ],
37
+ * onSelect: (event) => console.log('Selected:', event.id),
38
+ * });
39
+ *
40
+ * document.body.appendChild(drawer.element);
41
+ *
42
+ * // Create a modal drawer
43
+ * const modalDrawer = createDrawer({
44
+ * variant: 'modal',
45
+ * headline: 'Navigation',
46
+ * items: [
47
+ * { id: 'home', label: 'Home', icon: '<svg>...</svg>', active: true },
48
+ * { id: 'settings', label: 'Settings', icon: '<svg>...</svg>' },
49
+ * ],
50
+ * });
51
+ *
52
+ * document.body.appendChild(modalDrawer.element);
53
+ * modalDrawer.open();
54
+ * ```
55
+ *
56
+ * @category Components
57
+ */
58
+ declare const createDrawer: (config?: DrawerConfig) => any;
59
+ export default createDrawer;
@@ -0,0 +1,17 @@
1
+ import { DrawerConfig } from "../types";
2
+ /**
3
+ * Component shape expected by withHeadline
4
+ */
5
+ interface HeadlineBaseComponent {
6
+ element: HTMLElement;
7
+ getClass: (name: string) => string;
8
+ [key: string]: unknown;
9
+ }
10
+ /**
11
+ * Adds headline management to the drawer component
12
+ *
13
+ * @param config - Drawer configuration
14
+ * @returns Component enhancer function
15
+ */
16
+ export declare const withHeadline: (config: DrawerConfig) => (component: HeadlineBaseComponent) => HeadlineBaseComponent;
17
+ export {};
@@ -0,0 +1,3 @@
1
+ export { withItems } from "./items";
2
+ export { withState } from "./state";
3
+ export { withHeadline } from "./headline";
@@ -0,0 +1,18 @@
1
+ import { DrawerConfig } from "../types";
2
+ /**
3
+ * Component shape expected by withItems
4
+ */
5
+ interface ItemsBaseComponent {
6
+ element: HTMLElement;
7
+ getClass: (name: string) => string;
8
+ emit: (event: string, data?: unknown) => void;
9
+ [key: string]: unknown;
10
+ }
11
+ /**
12
+ * Adds item management functionality to the drawer component
13
+ *
14
+ * @param config - Drawer configuration
15
+ * @returns Component enhancer function
16
+ */
17
+ export declare const withItems: (config: DrawerConfig) => (component: ItemsBaseComponent) => ItemsBaseComponent;
18
+ export {};
@@ -0,0 +1,18 @@
1
+ import { DrawerConfig } from "../types";
2
+ /**
3
+ * Component shape expected by withState
4
+ */
5
+ interface StateBaseComponent {
6
+ element: HTMLElement;
7
+ getClass: (name: string) => string;
8
+ emit: (event: string, data?: unknown) => void;
9
+ [key: string]: unknown;
10
+ }
11
+ /**
12
+ * Adds open/close state management, scrim, and keyboard dismiss to the drawer
13
+ *
14
+ * @param config - Drawer configuration
15
+ * @returns Component enhancer function
16
+ */
17
+ export declare const withState: (config: DrawerConfig) => (component: StateBaseComponent) => StateBaseComponent;
18
+ export {};
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Drawer component module
3
+ * @module components/drawer
4
+ */
5
+ export { default } from './drawer';
6
+ export type { DrawerConfig, DrawerComponent, DrawerVariant, DrawerPosition, DrawerItemConfig, DrawerSelectEvent, } from './types';