mtrl 0.3.3 → 0.3.6

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 (41) hide show
  1. package/package.json +1 -1
  2. package/src/components/menu/api.ts +143 -268
  3. package/src/components/menu/config.ts +84 -40
  4. package/src/components/menu/features/anchor.ts +159 -0
  5. package/src/components/menu/features/controller.ts +970 -0
  6. package/src/components/menu/features/index.ts +4 -0
  7. package/src/components/menu/index.ts +31 -63
  8. package/src/components/menu/menu.ts +107 -97
  9. package/src/components/menu/types.ts +263 -447
  10. package/src/components/segmented-button/config.ts +59 -20
  11. package/src/components/segmented-button/index.ts +1 -1
  12. package/src/components/segmented-button/segment.ts +51 -97
  13. package/src/components/segmented-button/segmented-button.ts +114 -2
  14. package/src/components/segmented-button/types.ts +52 -0
  15. package/src/core/compose/features/icon.ts +15 -13
  16. package/src/core/dom/classes.ts +81 -9
  17. package/src/core/dom/create.ts +30 -19
  18. package/src/core/layout/README.md +531 -166
  19. package/src/core/layout/array.ts +3 -4
  20. package/src/core/layout/config.ts +193 -0
  21. package/src/core/layout/create.ts +1 -2
  22. package/src/core/layout/index.ts +12 -2
  23. package/src/core/layout/object.ts +2 -3
  24. package/src/core/layout/processor.ts +60 -12
  25. package/src/core/layout/result.ts +1 -2
  26. package/src/core/layout/types.ts +105 -50
  27. package/src/core/layout/utils.ts +69 -61
  28. package/src/index.ts +2 -1
  29. package/src/styles/components/_button.scss +6 -0
  30. package/src/styles/components/_chip.scss +4 -5
  31. package/src/styles/components/_menu.scss +20 -8
  32. package/src/styles/components/_segmented-button.scss +173 -63
  33. package/src/styles/main.scss +23 -23
  34. package/src/styles/utilities/_layout.scss +665 -0
  35. package/src/components/menu/features/items-manager.ts +0 -457
  36. package/src/components/menu/features/keyboard-navigation.ts +0 -133
  37. package/src/components/menu/features/positioning.ts +0 -127
  38. package/src/components/menu/features/visibility.ts +0 -230
  39. package/src/components/menu/menu-item.ts +0 -86
  40. package/src/components/menu/utils.ts +0 -67
  41. /package/src/{core/build → styles/utilities}/_ripple.scss +0 -0
@@ -1,26 +1,40 @@
1
- # Layout Module
2
-
3
- A lightweight, flexible system for creating and managing visual arrangements and component hierarchies.
1
+ # Layout Module Documentation
4
2
 
5
3
  ## Overview
6
4
 
7
- The Layout Module provides a declarative approach to building UI layouts using either arrays or objects. It efficiently handles DOM operations, component instantiation, and visual arrangement in a bundle-optimized way.
5
+ The Layout Module is a lightweight, flexible system for creating and managing visual arrangements and component hierarchies. It provides a declarative approach to building UI layouts using either arrays or objects, with efficient DOM operations, component instantiation, and visual arrangement.
8
6
 
9
7
  ## Features
10
8
 
11
9
  - **Multiple Schema Formats** - Support for array-based, object-based, and HTML string schemas
12
10
  - **Efficient DOM Operations** - Batched DOM manipulations with DocumentFragment
13
11
  - **Component Management** - Easy access to component instances via consistent API
12
+ - **Layout System Integration** - Direct access to powerful CSS layout classes
14
13
  - **Customizable Creation** - Control class prefixing and specify default creators
15
14
  - **Optimized for Bundle Size** - Minimal footprint with maximum functionality
16
15
  - **TypeScript Support** - Full type definitions for developer experience
17
16
 
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install mtrl
21
+ ```
22
+
23
+ ## Core Concepts
24
+
25
+ The Layout Module consists of several key parts:
26
+
27
+ 1. **Schema Definition** - A declarative way to describe your layout
28
+ 2. **Layout Processing** - Converting the schema into DOM elements
29
+ 3. **Layout Configuration** - Setting up responsive layouts and grids
30
+ 4. **Component Instance Management** - Accessing and controlling created components
31
+
18
32
  ## Basic Usage
19
33
 
20
34
  ### Array-based Layout
21
35
 
22
36
  ```javascript
23
- import { createLayout, createButton, createDialog, createList, createListItem } from 'mtrl';
37
+ import { createLayout, createButton, createDialog } from 'mtrl';
24
38
 
25
39
  const layout = createLayout([
26
40
  // Root level contains primary components
@@ -34,15 +48,6 @@ const layout = createLayout([
34
48
  }
35
49
  ]);
36
50
 
37
- // Add content to the dialog separately
38
- const dialogContent = createLayout([
39
- createList, 'actionsList', {},
40
- [
41
- createListItem, 'confirmAction', { text: 'Confirm', leading: 'check' },
42
- createListItem, 'cancelAction', { text: 'Cancel', leading: 'close' }
43
- ]
44
- ], layout.get('confirmDialog').contentElement);
45
-
46
51
  // Access components
47
52
  const submitButton = layout.get('submitButton');
48
53
  const confirmDialog = layout.get('confirmDialog');
@@ -54,7 +59,7 @@ submitButton.on('click', () => confirmDialog.open());
54
59
  ### Object-based Layout
55
60
 
56
61
  ```javascript
57
- import { createLayout, createTopAppBar, createNavigation, createList, createListItem, createTextfield, createButton } from 'mtrl';
62
+ import { createLayout, createTopAppBar, createList, createListItem } from 'mtrl';
58
63
 
59
64
  const layout = createLayout({
60
65
  element: {
@@ -66,7 +71,16 @@ const layout = createLayout({
66
71
  children: {
67
72
  navigation: {
68
73
  creator: createNavigation,
69
- options: { variant: 'drawer', persistent: true },
74
+ options: {
75
+ variant: 'drawer',
76
+ persistent: true,
77
+ // CSS layout configuration
78
+ layout: {
79
+ type: 'stack',
80
+ gap: 4,
81
+ align: 'stretch'
82
+ }
83
+ },
70
84
  children: {
71
85
  navList: {
72
86
  creator: createList,
@@ -79,51 +93,33 @@ const layout = createLayout({
79
93
  settingsLink: {
80
94
  creator: createListItem,
81
95
  options: { text: 'Settings', leading: 'settings' }
82
- },
83
- logoutLink: {
84
- creator: createListItem,
85
- options: { text: 'Logout', leading: 'logout' }
86
96
  }
87
97
  }
88
98
  }
89
99
  }
90
100
  },
91
- form: {
92
- creator: createElement,
93
- options: { tag: 'form', className: 'profile-form' },
94
- children: {
95
- nameField: {
96
- creator: createTextfield,
97
- options: { label: 'Full Name', required: true }
98
- },
99
- emailField: {
100
- creator: createTextfield,
101
- options: { label: 'Email', type: 'email', required: true }
102
- },
103
- saveButton: {
104
- creator: createButton,
105
- options: { text: 'Save Changes', variant: 'filled' }
101
+ content: {
102
+ options: {
103
+ tag: 'main',
104
+ className: 'content',
105
+ // Grid layout configuration
106
+ layout: {
107
+ type: 'grid',
108
+ columns: 3,
109
+ gap: 6,
110
+ autoHeight: true
106
111
  }
107
112
  }
108
113
  }
109
114
  }
110
115
  }
111
116
  });
112
-
113
- // Access components
114
- const topAppBar = layout.element;
115
- const nameField = layout.get('nameField');
116
- const saveButton = layout.get('saveButton');
117
-
118
- // Use the components
119
- nameField.setValue('John Doe');
120
- saveButton.on('click', () => console.log('Profile updated'));
121
117
  ```
122
118
 
123
119
  ### HTML String Layout
124
120
 
125
121
  ```javascript
126
- import createLayout from 'core/layout';
122
+ import { createLayout } from 'mtrl';
127
123
 
128
124
  const layout = createLayout(`
129
125
  <div class="notification">
@@ -137,173 +133,446 @@ const notification = layout.element;
137
133
  document.body.appendChild(notification);
138
134
  ```
139
135
 
140
- ### Using Options Parameter
136
+ ## Layout Configuration
141
137
 
142
- ```javascript
143
- import { createLayout, createButton, createTextfield, createCard, createChip, createTopAppBar, createBottomAppBar } from 'mtrl';
138
+ The layout module supports direct integration with the CSS layout system through the `layout` property:
144
139
 
145
- // With default creator and disabled prefix
146
- const formLayout = createLayout(
147
- [
148
- // Using string keys relies on the default creator
149
- 'nameField', { label: 'Name', required: true },
150
- 'emailField', { label: 'Email', type: 'email', required: true },
151
- 'phoneField', { label: 'Phone', type: 'tel' },
152
-
153
- // Explicitly override the default creator
154
- createButton, 'submitButton', { text: 'Submit', variant: 'filled' }
155
- ],
156
- document.getElementById('form-container'),
157
- {
158
- creator: createTextfield, // Default creator for all elements without a specific constructor
159
- prefix: false // Disable automatic class prefixing
160
- }
161
- );
140
+ ### Grid Layout
162
141
 
163
- // With theme options for a complete dashboard layout
164
- const dashboardLayout = createLayout(
165
- [
166
- createTopAppBar, 'header', {
167
- title: 'Dashboard',
168
- actions: ['notifications', 'account']
169
- },
170
-
171
- createCard, 'statsCard', {
172
- title: 'Performance Metrics',
173
- outlined: true
142
+ ```javascript
143
+ createLayout({
144
+ gridContainer: {
145
+ options: {
146
+ className: 'container',
147
+ layout: {
148
+ type: 'grid',
149
+ columns: 3, // Number of columns
150
+ gap: 4, // Gap size (using the gap scale)
151
+ autoHeight: true, // Allow natural heights
152
+ dense: true, // Dense packing algorithm
153
+ align: 'center' // Alignment of items
154
+ }
174
155
  },
175
- [
176
- createChip, 'visitsChip', { text: 'Visits: 1.2K', leadingIcon: 'visibility' },
177
- createChip, 'conversionChip', { text: 'Conversion: 5.4%', leadingIcon: 'trending_up' }
178
- ],
179
-
180
- createCard, 'activityCard', {
181
- title: 'Recent Activity',
182
- outlined: true
156
+ children: {
157
+ item1: {
158
+ options: {
159
+ text: 'Item 1',
160
+ // Individual item layout configuration
161
+ layoutItem: {
162
+ span: 2, // Span 2 columns
163
+ rowSpan: 1, // Span 1 row
164
+ align: 'start' // Self-alignment
165
+ }
166
+ }
167
+ }
168
+ }
169
+ }
170
+ });
171
+ ```
172
+
173
+ ### Stack Layout (Vertical)
174
+
175
+ ```javascript
176
+ createLayout({
177
+ stack: {
178
+ options: {
179
+ layout: {
180
+ type: 'stack',
181
+ gap: 4, // Space between items
182
+ align: 'center', // Center items horizontally
183
+ justify: 'between' // Space between items vertically
184
+ }
183
185
  },
184
-
185
- createBottomAppBar, 'footer', {
186
- actions: [
187
- { icon: 'home', label: 'Home' },
188
- { icon: 'search', label: 'Search' },
189
- { icon: 'settings', label: 'Settings' }
190
- ]
186
+ children: {
187
+ header: { options: { text: 'Header' } },
188
+ content: { options: { text: 'Content' } },
189
+ footer: { options: { text: 'Footer' } }
191
190
  }
192
- ],
193
- document.getElementById('app'),
194
- {
195
- theme: 'dark', // Custom theme option
196
- density: 'comfortable', // Custom density option
197
- animations: true // Custom animation option
198
191
  }
199
- );
192
+ });
193
+ ```
200
194
 
201
- // Access and use the layout
202
- const nameField = formLayout.get('nameField');
203
- nameField.setValue('John Doe');
195
+ ### Row Layout (Horizontal)
204
196
 
205
- const statsCard = dashboardLayout.get('statsCard');
206
- statsCard.setTitle('Updated Metrics - ' + new Date().toLocaleDateString());
197
+ ```javascript
198
+ createLayout({
199
+ row: {
200
+ options: {
201
+ layout: {
202
+ type: 'row',
203
+ gap: 4, // Space between items
204
+ align: 'center', // Center items vertically
205
+ justify: 'between', // Space between items horizontally
206
+ wrap: true, // Allow wrapping
207
+ mobileStack: true // Stack on mobile devices
208
+ }
209
+ },
210
+ children: {
211
+ // Row items...
212
+ }
213
+ }
214
+ });
207
215
  ```
208
216
 
209
- ## API Reference
217
+ ## Layout Types
218
+
219
+ The layout system supports several layout types that can be used in the `layout.type` property:
220
+
221
+ | Type | Description | Key Options |
222
+ |------|-------------|------------|
223
+ | `stack` | Vertical column of elements | `align`, `justify`, `gap` |
224
+ | `row` | Horizontal row of elements | `align`, `justify`, `wrap`, `gap`, `mobileStack` |
225
+ | `grid` | CSS Grid-based layout | `columns`, `gap`, `autoHeight`, `dense` |
226
+ | `masonry` | Masonry-style layout | `masonryColumns`, `gap` |
227
+ | `split` | Two-column split layout | `ratio`, `gap` |
228
+ | `sidebar` | Sidebar with main content | `sidebarPosition`, `sidebarWidth` |
210
229
 
211
- ### Core Functions
230
+ ## Layout Item Properties
212
231
 
213
- #### `createLayout(schema, parentElement?, options?)`
232
+ When using the `layoutItem` property to configure individual items:
233
+
234
+ | Property | Description | Example Values |
235
+ |----------|-------------|----------------|
236
+ | `width` | Column width in 12-column grid | `1` through `12` |
237
+ | `span` | Grid column span | `1` through `12` |
238
+ | `rowSpan` | Grid row span | `1` through `12` |
239
+ | `sm`, `md`, `lg`, `xl` | Responsive widths | `1` through `12` |
240
+ | `order` | Item ordering | `'first'`, `'last'`, or a number |
241
+ | `align` | Self-alignment | `'start'`, `'center'`, `'end'`, `'stretch'` |
242
+ | `auto` | Auto width (flex) | `true`, `false` |
243
+
244
+ ## Layout Functions
245
+
246
+ ### `createLayout(schema, parentElement?, options?)`
214
247
 
215
248
  Creates a layout from a schema definition.
216
249
 
217
250
  - **Parameters**:
218
251
  - `schema`: Array, object, HTML string, or function returning one of these
219
252
  - `parentElement` (optional): Parent element to attach the layout to
220
- - `options` (optional): Configuration options for layout creation:
221
- - `creator`: Default creator function to use when not specified in schema
222
- - `prefix`: Boolean to control whether CSS class prefixing is applied (default: true)
223
- - Custom options can be added and accessed in component creators
253
+ - `options` (optional): Configuration options for layout creation
224
254
  - **Returns**: Layout result object with components and utility methods
225
255
 
226
- #### `processSchema(schema, parentElement?, level?, options?)`
256
+ ```javascript
257
+ const layout = createLayout(schema, document.getElementById('container'), {
258
+ creator: createCard, // Default creator for elements without a specific one
259
+ prefix: true, // Whether to apply automatic class prefixing
260
+ theme: 'dark' // Custom options (passed to components)
261
+ });
262
+ ```
227
263
 
228
- Low-level function for processing schemas directly.
264
+ ### Layout Result Object
229
265
 
230
- - **Parameters**:
231
- - `schema`: Array or object schema
232
- - `parentElement` (optional): Parent element to attach to
233
- - `level` (optional): Current recursion level
234
- - `options` (optional): Layout creation options
235
- - **Returns**: Layout result object
266
+ The object returned by `createLayout` contains:
236
267
 
237
- #### `createComponentInstance(Component, options?, layoutOptions?)`
268
+ - `layout`: Raw layout object with all components
269
+ - `element`: Reference to the root element
270
+ - `component`: Flattened component map for easy access
271
+ - `get(name)`: Function to get a component by name
272
+ - `getAll()`: Function to get all components
273
+ - `destroy()`: Function to clean up the layout
238
274
 
239
- Creates a component instance from a constructor or factory function.
275
+ ```javascript
276
+ // Access components in different ways
277
+ const header = layout.get('header'); // By name
278
+ const footer = layout.component.footer; // Via flattened map
279
+ const rootElement = layout.element; // Root element
280
+ ```
240
281
 
241
- - **Parameters**:
242
- - `Component`: Constructor or factory function
243
- - `options` (optional): Options to pass to the component
244
- - `layoutOptions` (optional): Global layout options
245
- - **Returns**: Component instance
282
+ ## Examples
246
283
 
247
- ### Utility Functions
284
+ ### Array Schema Examples
248
285
 
249
- #### `isComponent(value)`
286
+ #### Grid Layout with Array Schema
250
287
 
251
- Checks if a value is a component-like object.
288
+ ```javascript
289
+ import { createLayout, createElement, createCard } from 'mtrl';
290
+
291
+ // Create a grid layout using array syntax
292
+ const dashboard = createLayout([
293
+ // Container element with layout configuration
294
+ 'dashboardGrid', {
295
+ className: 'dashboard-grid',
296
+ layout: {
297
+ type: 'grid',
298
+ columns: 3,
299
+ gap: 4,
300
+ autoHeight: true
301
+ }
302
+ },
303
+ [
304
+ // First card
305
+ createCard, 'statsCard', {
306
+ title: 'Statistics',
307
+ outlined: true,
308
+ layoutItem: {
309
+ span: 2, // Span 2 columns
310
+ sm: 12, // Full width on small screens
311
+ md: 6 // Half width on medium screens
312
+ }
313
+ },
314
+ // Second card
315
+ createCard, 'activityCard', {
316
+ title: 'Recent Activity',
317
+ outlined: true,
318
+ layoutItem: {
319
+ span: 1, // Span 1 column
320
+ sm: 12, // Full width on small screens
321
+ md: 6 // Half width on medium screens
322
+ }
323
+ },
324
+ // Third card
325
+ createCard, 'revenueCard', {
326
+ title: 'Revenue',
327
+ outlined: true,
328
+ layoutItem: {
329
+ span: 3, // Full width
330
+ md: 6 // Half width on medium screens
331
+ }
332
+ }
333
+ ]
334
+ ]);
252
335
 
253
- - **Parameters**:
254
- - `value`: Value to check
255
- - **Returns**: Boolean indicating if the value is a component
336
+ // Access components
337
+ const statsCard = dashboard.get('statsCard');
338
+ statsCard.update({ content: 'Updated statistics data' });
339
+ ```
256
340
 
257
- #### `processClassNames(options, skipPrefix?)`
341
+ #### Application Layout with Array Schema
258
342
 
259
- Processes class names in options to add prefixes.
343
+ ```javascript
344
+ import { createLayout, createTopAppBar, createDrawer, createList, createListItem, createElement } from 'mtrl';
260
345
 
261
- - **Parameters**:
262
- - `options`: Element options containing className
263
- - `skipPrefix` (optional): Whether to skip adding prefixes
264
- - **Returns**: Updated options with prefixed classNames
346
+ // Create an application layout using array syntax
347
+ const appLayout = createLayout([
348
+ // Create a container element
349
+ 'appContainer', {
350
+ className: 'app-container',
351
+ layout: { type: 'stack', gap: 0 }
352
+ },
353
+ [
354
+ // Header
355
+ createTopAppBar, 'header', {
356
+ title: 'My Application',
357
+ actions: ['menu', 'account']
358
+ },
359
+
360
+ // Main content area
361
+ 'main', {
362
+ className: 'app-main',
363
+ layout: { type: 'row', gap: 0 }
364
+ },
365
+ [
366
+ // Sidebar
367
+ createDrawer, 'sidebar', {
368
+ persistent: true,
369
+ layout: { type: 'stack', gap: 2 }
370
+ },
371
+ [
372
+ // Navigation list
373
+ createList, 'nav', { interactive: true },
374
+ [
375
+ createListItem, 'homeLink', { text: 'Home', leading: 'home' },
376
+ createListItem, 'settingsLink', { text: 'Settings', leading: 'settings' }
377
+ ]
378
+ ],
379
+
380
+ // Main content
381
+ 'content', {
382
+ tag: 'main',
383
+ className: 'app-content',
384
+ layout: {
385
+ type: 'grid',
386
+ columns: 'auto-fit',
387
+ gap: 4
388
+ }
389
+ }
390
+ ]
391
+ ]
392
+ ]);
265
393
 
266
- #### `flattenLayout(layout)`
394
+ // Access and modify components
395
+ const header = appLayout.get('header');
396
+ header.setTitle('Dashboard');
267
397
 
268
- Flattens a nested layout for easier component access.
398
+ // Add items to the grid content area
399
+ const content = appLayout.get('content');
400
+ const card = createCard({ title: 'Statistics', content: 'App usage data...' });
401
+ content.appendChild(card.element);
402
+ ```
269
403
 
270
- - **Parameters**:
271
- - `layout`: Layout object to flatten
272
- - **Returns**: Flattened layout with components
404
+ #### Form Layout with Array Schema
273
405
 
274
- ### Result Object
406
+ ```javascript
407
+ import { createLayout, createTextfield, createButton } from 'mtrl';
408
+
409
+ // Create a form with fields and submit button using array syntax
410
+ const form = createLayout([
411
+ 'formContainer', {
412
+ tag: 'form',
413
+ className: 'login-form',
414
+ layout: { type: 'stack', gap: 4 }
415
+ },
416
+ [
417
+ createTextfield, 'username', {
418
+ label: 'Username',
419
+ required: true,
420
+ layoutItem: {
421
+ width: 12 // Full width
422
+ }
423
+ },
424
+ createTextfield, 'password', {
425
+ label: 'Password',
426
+ type: 'password',
427
+ required: true,
428
+ layoutItem: {
429
+ width: 12 // Full width
430
+ }
431
+ },
432
+ 'buttonRow', {
433
+ layout: {
434
+ type: 'row',
435
+ justify: 'end',
436
+ gap: 2
437
+ }
438
+ },
439
+ [
440
+ createButton, 'resetButton', {
441
+ text: 'Reset',
442
+ variant: 'text'
443
+ },
444
+ createButton, 'submitButton', {
445
+ text: 'Login',
446
+ variant: 'filled'
447
+ }
448
+ ]
449
+ ]
450
+ ]);
275
451
 
276
- The layout result object contains:
452
+ // Access form elements
453
+ const usernameField = form.get('username');
454
+ const submitButton = form.get('submitButton');
277
455
 
278
- - `layout`: Raw layout object with all components
279
- - `element`: Reference to the root element
280
- - `component`: Flattened component map for easy access
281
- - `get(name)`: Function to get a component by name
282
- - `getAll()`: Function to get all components
283
- - `destroy()`: Function to clean up the layout
456
+ // Add event handlers
457
+ submitButton.on('click', (e) => {
458
+ e.preventDefault();
459
+ console.log('Username:', usernameField.getValue());
460
+ });
461
+ ```
284
462
 
285
- ## Integrating with Layout Manager
463
+ ### Object Schema Examples
286
464
 
287
- This module works well with the Layout Manager for advanced application layouts:
465
+ #### Dashboard Grid with Object Schema
288
466
 
289
467
  ```javascript
290
- import createLayout from 'core/layout';
291
- import createLayoutManager from 'client/core/layout/layout-manager';
468
+ import { createLayout, createElement, createCard } from 'mtrl';
469
+
470
+ const dashboard = createLayout({
471
+ dashboardGrid: {
472
+ options: {
473
+ className: 'dashboard-grid',
474
+ layout: {
475
+ type: 'grid',
476
+ columns: 3,
477
+ gap: 4,
478
+ autoHeight: true
479
+ }
480
+ },
481
+ children: {
482
+ statsCard: {
483
+ creator: createCard,
484
+ options: {
485
+ title: 'Statistics',
486
+ outlined: true,
487
+ layoutItem: {
488
+ span: 2, // Span 2 columns
489
+ sm: 12, // Full width on small screens
490
+ md: 6 // Half width on medium screens
491
+ }
492
+ }
493
+ },
494
+ activityCard: {
495
+ creator: createCard,
496
+ options: {
497
+ title: 'Recent Activity',
498
+ outlined: true,
499
+ layoutItem: {
500
+ span: 1, // Span 1 column
501
+ sm: 12, // Full width on small screens
502
+ md: 6 // Half width on medium screens
503
+ }
504
+ }
505
+ },
506
+ // More dashboard cards...
507
+ }
508
+ }
509
+ });
510
+ ```
292
511
 
293
- // Create application layout
294
- const appLayout = createLayout([
295
- // Application components...
296
- ]);
512
+ #### Application Layout with Object Schema
297
513
 
298
- // Create layout manager with the layout
299
- const layoutManager = createLayoutManager({
300
- layout: appLayout.layout,
301
- layoutAPI: appLayout
302
- });
514
+ ```javascript
515
+ import { createLayout, createTopAppBar, createDrawer, createList, createListItem, createButton } from 'mtrl';
303
516
 
304
- // Use layout manager API
305
- layoutManager.setContent('<h1>Welcome to the app</h1>');
306
- layoutManager.setPageTitle('Dashboard');
517
+ const appLayout = createLayout({
518
+ app: {
519
+ options: {
520
+ className: 'app-container',
521
+ layout: { type: 'stack', gap: 0 }
522
+ },
523
+ children: {
524
+ header: {
525
+ creator: createTopAppBar,
526
+ options: {
527
+ title: 'My Application',
528
+ actions: ['menu', 'account']
529
+ }
530
+ },
531
+ main: {
532
+ options: {
533
+ className: 'app-main',
534
+ layout: { type: 'row', gap: 0 }
535
+ },
536
+ children: {
537
+ sidebar: {
538
+ creator: createDrawer,
539
+ options: {
540
+ persistent: true,
541
+ layout: { type: 'stack', gap: 2 }
542
+ },
543
+ children: {
544
+ nav: {
545
+ creator: createList,
546
+ options: { interactive: true },
547
+ children: {
548
+ home: {
549
+ creator: createListItem,
550
+ options: { text: 'Home', leading: 'home' }
551
+ },
552
+ settings: {
553
+ creator: createListItem,
554
+ options: { text: 'Settings', leading: 'settings' }
555
+ }
556
+ }
557
+ }
558
+ }
559
+ },
560
+ content: {
561
+ options: {
562
+ tag: 'main',
563
+ className: 'app-content',
564
+ layout: {
565
+ type: 'grid',
566
+ columns: 'auto-fit',
567
+ gap: 4
568
+ }
569
+ }
570
+ }
571
+ }
572
+ }
573
+ }
574
+ }
575
+ });
307
576
  ```
308
577
 
309
578
  ## Performance Considerations
@@ -341,6 +610,102 @@ layoutManager.setPageTitle('Dashboard');
341
610
  - Consider memoizing frequently created layouts
342
611
  - For large applications, lazy-load secondary layouts
343
612
 
613
+ ## Responsive Design
614
+
615
+ The layout system provides several ways to create responsive designs:
616
+
617
+ ### Responsive Grid
618
+
619
+ ```javascript
620
+ createLayout({
621
+ grid: {
622
+ options: {
623
+ layout: {
624
+ type: 'grid',
625
+ // Different columns at different breakpoints using CSS media queries
626
+ class: 'md:layout--grid-cols-2 lg:layout--grid-cols-3 xl:layout--grid-cols-4'
627
+ }
628
+ }
629
+ }
630
+ });
631
+ ```
632
+
633
+ ### Layout Items with Responsive Widths
634
+
635
+ ```javascript
636
+ createLayout({
637
+ row: {
638
+ options: {
639
+ layout: { type: 'row', gap: 4 }
640
+ },
641
+ children: {
642
+ sidebar: {
643
+ options: {
644
+ layoutItem: {
645
+ width: 3, // Default: 3/12 (25%)
646
+ sm: 12, // Small screens: 12/12 (100%)
647
+ md: 4, // Medium screens: 4/12 (33.3%)
648
+ lg: 3 // Large screens: 3/12 (25%)
649
+ }
650
+ }
651
+ },
652
+ main: {
653
+ options: {
654
+ layoutItem: {
655
+ width: 9, // Default: 9/12 (75%)
656
+ sm: 12, // Small screens: 12/12 (100%)
657
+ md: 8, // Medium screens: 8/12 (66.6%)
658
+ lg: 9 // Large screens: 9/12 (75%)
659
+ }
660
+ }
661
+ }
662
+ }
663
+ }
664
+ });
665
+ ```
666
+
667
+ ### Mobile Behavior Options
668
+
669
+ ```javascript
670
+ createLayout({
671
+ row: {
672
+ options: {
673
+ layout: {
674
+ type: 'row',
675
+ gap: 4,
676
+ mobileStack: true, // Stack on mobile instead of row
677
+ // OR
678
+ mobileScroll: true // Enable horizontal scrolling on mobile
679
+ }
680
+ },
681
+ children: {
682
+ // Row items...
683
+ }
684
+ }
685
+ });
686
+ ```
687
+
688
+ ## Layout CSS Classes
689
+
690
+ The layout system uses a consistent naming convention for CSS classes:
691
+
692
+ ### Layout Container Classes
693
+
694
+ - **Base Layout**: `.layout--[type]` (e.g., `.layout--stack`, `.layout--grid`)
695
+ - **Alignment**: `.layout--[type]-[align]` (e.g., `.layout--stack-center`)
696
+ - **Justification**: `.layout--[type]-justify-[justify]` (e.g., `.layout--row-justify-between`)
697
+ - **Spacing**: `.layout--[type]-gap-[size]` (e.g., `.layout--grid-gap-4`)
698
+ - **Specific Options**: `.layout--[type]-[option]` (e.g., `.layout--grid-dense`)
699
+
700
+ ### Layout Item Classes
701
+
702
+ - **Base Item**: `.layout__item`
703
+ - **Width**: `.layout__item--[width]` (e.g., `.layout__item--4` for 4/12 width)
704
+ - **Responsive Widths**: `.layout__item--[breakpoint]-[width]` (e.g., `.layout__item--md-6`)
705
+ - **Ordering**: `.layout__item--order-[order]` (e.g., `.layout__item--order-first`)
706
+ - **Alignment**: `.layout__item--self-[align]` (e.g., `.layout__item--self-center`)
707
+ - **Grid Span**: `.layout__item--span-[span]` (e.g., `.layout__item--span-2`)
708
+
344
709
  ## Browser Compatibility
345
710
 
346
711
  The Layout Module is compatible with all modern browsers (Chrome, Firefox, Safari, Edge).