mtrl 0.3.6 → 0.3.8
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/package.json +2 -2
- package/src/components/button/api.ts +16 -0
- package/src/components/button/types.ts +9 -0
- package/src/components/menu/api.ts +61 -22
- package/src/components/menu/config.ts +10 -8
- package/src/components/menu/features/anchor.ts +254 -19
- package/src/components/menu/features/controller.ts +724 -271
- package/src/components/menu/features/index.ts +11 -2
- package/src/components/menu/features/position.ts +353 -0
- package/src/components/menu/index.ts +5 -5
- package/src/components/menu/menu.ts +21 -61
- package/src/components/menu/types.ts +30 -16
- package/src/components/select/api.ts +78 -0
- package/src/components/select/config.ts +76 -0
- package/src/components/select/features.ts +331 -0
- package/src/components/select/index.ts +38 -0
- package/src/components/select/select.ts +73 -0
- package/src/components/select/types.ts +355 -0
- package/src/components/textfield/api.ts +78 -6
- package/src/components/textfield/features/index.ts +17 -0
- package/src/components/textfield/features/leading-icon.ts +127 -0
- package/src/components/textfield/features/placement.ts +149 -0
- package/src/components/textfield/features/prefix-text.ts +107 -0
- package/src/components/textfield/features/suffix-text.ts +100 -0
- package/src/components/textfield/features/supporting-text.ts +113 -0
- package/src/components/textfield/features/trailing-icon.ts +108 -0
- package/src/components/textfield/textfield.ts +51 -15
- package/src/components/textfield/types.ts +70 -0
- package/src/core/collection/adapters/base.ts +62 -0
- package/src/core/collection/collection.ts +300 -0
- package/src/core/collection/index.ts +57 -0
- package/src/core/collection/list-manager.ts +333 -0
- package/src/index.ts +4 -45
- package/src/styles/abstract/_variables.scss +18 -0
- package/src/styles/components/_button.scss +21 -5
- package/src/styles/components/{_chip.scss → _chips.scss} +118 -4
- package/src/styles/components/_menu.scss +97 -24
- package/src/styles/components/_select.scss +272 -0
- package/src/styles/components/_textfield.scss +233 -42
- package/src/styles/main.scss +2 -1
- package/src/components/textfield/features.ts +0 -322
- package/src/core/collection/adapters/base.js +0 -26
- package/src/core/collection/collection.js +0 -259
- package/src/core/collection/list-manager.js +0 -157
- /package/src/core/collection/adapters/{route.js → route.ts} +0 -0
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
// src/core/collection/list-manager.ts
|
|
2
|
+
|
|
3
|
+
import { createRouteAdapter, RouteAdapter, QueryDefinition } from './adapters/route';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* List item interface
|
|
7
|
+
*/
|
|
8
|
+
export interface ListItem {
|
|
9
|
+
id: string;
|
|
10
|
+
[key: string]: any;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* List with items setter
|
|
15
|
+
*/
|
|
16
|
+
export interface List {
|
|
17
|
+
setItems: (items: any[]) => void;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Metadata for pagination
|
|
22
|
+
*/
|
|
23
|
+
export interface PaginationMeta {
|
|
24
|
+
cursor: string | null;
|
|
25
|
+
hasNext: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Response format from loadItems
|
|
30
|
+
*/
|
|
31
|
+
export interface LoadItemsResponse<T = any> {
|
|
32
|
+
items: T[];
|
|
33
|
+
meta: PaginationMeta;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Load status callback data
|
|
38
|
+
*/
|
|
39
|
+
export interface LoadStatus<T = any> {
|
|
40
|
+
loading: boolean;
|
|
41
|
+
hasNext?: boolean;
|
|
42
|
+
hasPrev?: boolean;
|
|
43
|
+
items?: T[];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Page loader configuration
|
|
48
|
+
*/
|
|
49
|
+
export interface PageLoaderConfig<T = any> {
|
|
50
|
+
onLoad?: (status: LoadStatus<T>) => void;
|
|
51
|
+
pageSize?: number;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Page loader interface
|
|
56
|
+
*/
|
|
57
|
+
export interface PageLoader<T = any> {
|
|
58
|
+
/**
|
|
59
|
+
* Load a specific page by cursor
|
|
60
|
+
* @param cursor - Cursor pointing to the page
|
|
61
|
+
* @param addToHistory - Whether to add current cursor to history
|
|
62
|
+
* @returns Page status
|
|
63
|
+
*/
|
|
64
|
+
load: (cursor?: string | null, addToHistory?: boolean) => Promise<{
|
|
65
|
+
hasNext: boolean;
|
|
66
|
+
hasPrev: boolean;
|
|
67
|
+
} | undefined>;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Load next page
|
|
71
|
+
* @returns Page status
|
|
72
|
+
*/
|
|
73
|
+
loadNext: () => Promise<{
|
|
74
|
+
hasNext: boolean;
|
|
75
|
+
hasPrev: boolean;
|
|
76
|
+
} | undefined>;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Load previous page
|
|
80
|
+
* @returns Page status
|
|
81
|
+
*/
|
|
82
|
+
loadPrev: () => Promise<{
|
|
83
|
+
hasNext: boolean;
|
|
84
|
+
hasPrev: boolean;
|
|
85
|
+
} | undefined>;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Current loading state
|
|
89
|
+
*/
|
|
90
|
+
readonly loading: boolean;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Current cursor
|
|
94
|
+
*/
|
|
95
|
+
readonly cursor: string | null;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* List manager config
|
|
100
|
+
*/
|
|
101
|
+
export interface ListManagerConfig<T = any> {
|
|
102
|
+
/**
|
|
103
|
+
* Transform function to convert API items to app format
|
|
104
|
+
*/
|
|
105
|
+
transform?: (item: any) => T;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Base URL for API requests
|
|
109
|
+
*/
|
|
110
|
+
baseUrl?: string;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* List manager interface
|
|
115
|
+
*/
|
|
116
|
+
export interface ListManager<T = any> {
|
|
117
|
+
/**
|
|
118
|
+
* Load items with optional parameters
|
|
119
|
+
* @param params - Query parameters
|
|
120
|
+
* @returns Loaded items with pagination metadata
|
|
121
|
+
*/
|
|
122
|
+
loadItems: (params?: Record<string, any>) => Promise<LoadItemsResponse<T>>;
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Create a page loader for the specified list
|
|
126
|
+
* @param list - List to manage
|
|
127
|
+
* @param config - Page loader configuration
|
|
128
|
+
* @returns Page loader
|
|
129
|
+
*/
|
|
130
|
+
createPageLoader: (list: List, config?: PageLoaderConfig<T>) => PageLoader<T>;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Creates a list manager for a specific collection
|
|
135
|
+
* @param collection - Collection name
|
|
136
|
+
* @param config - Configuration options
|
|
137
|
+
* @returns List manager methods
|
|
138
|
+
*/
|
|
139
|
+
export const createListManager = <T = any>(
|
|
140
|
+
collection: string,
|
|
141
|
+
config: ListManagerConfig<T> = {}
|
|
142
|
+
): ListManager<T> => {
|
|
143
|
+
const {
|
|
144
|
+
transform = (item: any) => item as T,
|
|
145
|
+
baseUrl = 'http://localhost:4000/api'
|
|
146
|
+
} = config;
|
|
147
|
+
|
|
148
|
+
// Initialize route adapter
|
|
149
|
+
const adapter: RouteAdapter = createRouteAdapter({
|
|
150
|
+
base: baseUrl,
|
|
151
|
+
endpoints: {
|
|
152
|
+
list: `/${collection}`
|
|
153
|
+
},
|
|
154
|
+
headers: {
|
|
155
|
+
'Content-Type': 'application/json'
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Load items with cursor pagination
|
|
161
|
+
* @param params - Query parameters
|
|
162
|
+
* @returns Loaded items with pagination metadata
|
|
163
|
+
*/
|
|
164
|
+
const loadItems = async (params: Record<string, any> = {}): Promise<LoadItemsResponse<T>> => {
|
|
165
|
+
try {
|
|
166
|
+
const response = await adapter.read(params as QueryDefinition);
|
|
167
|
+
|
|
168
|
+
return {
|
|
169
|
+
items: response.items.map(transform),
|
|
170
|
+
meta: response.meta as PaginationMeta
|
|
171
|
+
};
|
|
172
|
+
} catch (error) {
|
|
173
|
+
console.error(`Error loading ${collection}:`, error);
|
|
174
|
+
return {
|
|
175
|
+
items: [],
|
|
176
|
+
meta: {
|
|
177
|
+
cursor: null,
|
|
178
|
+
hasNext: false
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Create a page loader for the specified list
|
|
186
|
+
* @param list - List to manage
|
|
187
|
+
* @param config - Page loader configuration
|
|
188
|
+
* @returns Page loader
|
|
189
|
+
*/
|
|
190
|
+
const createPageLoader = (
|
|
191
|
+
list: List,
|
|
192
|
+
{ onLoad, pageSize = 20 }: PageLoaderConfig<T> = {}
|
|
193
|
+
): PageLoader<T> => {
|
|
194
|
+
let currentCursor: string | null = null;
|
|
195
|
+
let loading = false;
|
|
196
|
+
const pageHistory: Array<string | null> = [];
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Load a specific page by cursor
|
|
200
|
+
* @param cursor - Cursor pointing to the page
|
|
201
|
+
* @param addToHistory - Whether to add current cursor to history
|
|
202
|
+
* @returns Page status
|
|
203
|
+
*/
|
|
204
|
+
const load = async (
|
|
205
|
+
cursor: string | null = null,
|
|
206
|
+
addToHistory = true
|
|
207
|
+
): Promise<{ hasNext: boolean; hasPrev: boolean } | undefined> => {
|
|
208
|
+
if (loading) return;
|
|
209
|
+
|
|
210
|
+
loading = true;
|
|
211
|
+
onLoad?.({ loading: true });
|
|
212
|
+
|
|
213
|
+
const { items, meta } = await loadItems({
|
|
214
|
+
limit: pageSize,
|
|
215
|
+
cursor
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
if (addToHistory && cursor) {
|
|
219
|
+
pageHistory.push(currentCursor);
|
|
220
|
+
}
|
|
221
|
+
currentCursor = meta.cursor;
|
|
222
|
+
|
|
223
|
+
list.setItems(items);
|
|
224
|
+
loading = false;
|
|
225
|
+
|
|
226
|
+
const status = {
|
|
227
|
+
loading: false,
|
|
228
|
+
hasNext: meta.hasNext,
|
|
229
|
+
hasPrev: pageHistory.length > 0,
|
|
230
|
+
items
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
onLoad?.(status);
|
|
234
|
+
|
|
235
|
+
return {
|
|
236
|
+
hasNext: meta.hasNext,
|
|
237
|
+
hasPrev: pageHistory.length > 0
|
|
238
|
+
};
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Load next page
|
|
243
|
+
* @returns Page status
|
|
244
|
+
*/
|
|
245
|
+
const loadNext = (): Promise<{ hasNext: boolean; hasPrev: boolean } | undefined> =>
|
|
246
|
+
load(currentCursor);
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Load previous page
|
|
250
|
+
* @returns Page status
|
|
251
|
+
*/
|
|
252
|
+
const loadPrev = (): Promise<{ hasNext: boolean; hasPrev: boolean } | undefined> => {
|
|
253
|
+
const previousCursor = pageHistory.pop();
|
|
254
|
+
return load(previousCursor, false);
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
return {
|
|
258
|
+
load,
|
|
259
|
+
loadNext,
|
|
260
|
+
loadPrev,
|
|
261
|
+
get loading(): boolean { return loading; },
|
|
262
|
+
get cursor(): string | null { return currentCursor; }
|
|
263
|
+
};
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
return {
|
|
267
|
+
loadItems,
|
|
268
|
+
createPageLoader
|
|
269
|
+
};
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Transform functions for common collections
|
|
274
|
+
*/
|
|
275
|
+
export const transforms = {
|
|
276
|
+
/**
|
|
277
|
+
* Transform track data
|
|
278
|
+
* @param track - Raw track data
|
|
279
|
+
* @returns Formatted track data
|
|
280
|
+
*/
|
|
281
|
+
track: (track: any): ListItem => ({
|
|
282
|
+
id: track._id,
|
|
283
|
+
headline: track.title || 'Untitled',
|
|
284
|
+
supportingText: track.artist || 'Unknown Artist',
|
|
285
|
+
meta: track.year?.toString() || ''
|
|
286
|
+
}),
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Transform playlist data
|
|
290
|
+
* @param playlist - Raw playlist data
|
|
291
|
+
* @returns Formatted playlist data
|
|
292
|
+
*/
|
|
293
|
+
playlist: (playlist: any): ListItem => ({
|
|
294
|
+
id: playlist._id,
|
|
295
|
+
headline: playlist.name || 'Untitled Playlist',
|
|
296
|
+
supportingText: `${playlist.tracks?.length || 0} tracks`,
|
|
297
|
+
meta: playlist.creator || ''
|
|
298
|
+
}),
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Transform country data
|
|
302
|
+
* @param country - Raw country data
|
|
303
|
+
* @returns Formatted country data
|
|
304
|
+
*/
|
|
305
|
+
country: (country: any): ListItem => ({
|
|
306
|
+
id: country._id,
|
|
307
|
+
headline: country.name || country.code,
|
|
308
|
+
supportingText: country.continent || '',
|
|
309
|
+
meta: country.code || ''
|
|
310
|
+
})
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Usage example:
|
|
315
|
+
*
|
|
316
|
+
* const trackManager = createListManager<TrackItem>('track', {
|
|
317
|
+
* transform: transforms.track
|
|
318
|
+
* });
|
|
319
|
+
*
|
|
320
|
+
* const loader = trackManager.createPageLoader(list, {
|
|
321
|
+
* onLoad: ({ loading, hasNext, items }) => {
|
|
322
|
+
* updateNavigation({ loading, hasNext });
|
|
323
|
+
* logEvent(`Loaded ${items.length} tracks`);
|
|
324
|
+
* }
|
|
325
|
+
* });
|
|
326
|
+
*
|
|
327
|
+
* // Initial load
|
|
328
|
+
* await loader.load();
|
|
329
|
+
*
|
|
330
|
+
* // Navigation
|
|
331
|
+
* nextButton.onclick = () => loader.loadNext();
|
|
332
|
+
* prevButton.onclick = () => loader.loadPrev();
|
|
333
|
+
*/
|
package/src/index.ts
CHANGED
|
@@ -12,7 +12,7 @@ import createBadge from './components/badge';
|
|
|
12
12
|
import createBottomAppBar from './components/bottom-app-bar';
|
|
13
13
|
import createButton from './components/button';
|
|
14
14
|
import createCard from './components/card';
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
16
|
createCardContent,
|
|
17
17
|
createCardHeader,
|
|
18
18
|
createCardActions,
|
|
@@ -36,6 +36,7 @@ import createSegmentedButton, { createSegment } from './components/segmented-but
|
|
|
36
36
|
import createSheet from './components/sheet';
|
|
37
37
|
import createSlider from './components/slider';
|
|
38
38
|
import createSnackbar from './components/snackbar';
|
|
39
|
+
import createSelect from './components/select';
|
|
39
40
|
import createSwitch from './components/switch';
|
|
40
41
|
import createTabs, { createTab } from './components/tabs';
|
|
41
42
|
import createTextfield from './components/textfield';
|
|
@@ -59,7 +60,7 @@ export {
|
|
|
59
60
|
createCarousel,
|
|
60
61
|
createCheckbox,
|
|
61
62
|
createChip,
|
|
62
|
-
|
|
63
|
+
createChips,
|
|
63
64
|
createDatePicker,
|
|
64
65
|
createDialog,
|
|
65
66
|
createDivider,
|
|
@@ -73,6 +74,7 @@ export {
|
|
|
73
74
|
createProgress,
|
|
74
75
|
createRadios,
|
|
75
76
|
createSearch,
|
|
77
|
+
createSelect,
|
|
76
78
|
createSegmentedButton,
|
|
77
79
|
createSegment,
|
|
78
80
|
createSheet,
|
|
@@ -85,47 +87,4 @@ export {
|
|
|
85
87
|
createTimePicker,
|
|
86
88
|
createTopAppBar,
|
|
87
89
|
createTooltip
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
// Export all "f*" aliases
|
|
91
|
-
export {
|
|
92
|
-
createElement as fElement,
|
|
93
|
-
createLayout as fLayout,
|
|
94
|
-
createBadge as fBadge,
|
|
95
|
-
createBottomAppBar as fBottomAppBar,
|
|
96
|
-
createButton as fButton,
|
|
97
|
-
createCard as fCard,
|
|
98
|
-
createCardContent as fCardContent,
|
|
99
|
-
createCardHeader as fCardHeader,
|
|
100
|
-
createCardActions as fCardActions,
|
|
101
|
-
createCardMedia as fCardMedia,
|
|
102
|
-
createCarousel as fCarousel,
|
|
103
|
-
createCheckbox as fCheckbox,
|
|
104
|
-
createChip as fChip,
|
|
105
|
-
createChips as fChips,
|
|
106
|
-
createDatePicker as fDatePicker,
|
|
107
|
-
createDialog as fDialog,
|
|
108
|
-
createDivider as fDivider,
|
|
109
|
-
createFab as fFab,
|
|
110
|
-
createExtendedFab as fExtendedFab,
|
|
111
|
-
createList as fList,
|
|
112
|
-
createListItem as fListItem,
|
|
113
|
-
createMenu as fMenu,
|
|
114
|
-
createNavigation as fNavigation,
|
|
115
|
-
createNavigationSystem as fNavigationSystem,
|
|
116
|
-
createProgress as fProgress,
|
|
117
|
-
createRadios as fRadios,
|
|
118
|
-
createSearch as fSearch,
|
|
119
|
-
createSegmentedButton as fSegmentedButton,
|
|
120
|
-
createSegment as fSegment,
|
|
121
|
-
createSheet as fSheet,
|
|
122
|
-
createSlider as fSlider,
|
|
123
|
-
createSnackbar as fSnackbar,
|
|
124
|
-
createSwitch as fSwitch,
|
|
125
|
-
createTabs as fTabs,
|
|
126
|
-
createTab as fTab,
|
|
127
|
-
createTextfield as fTextfield,
|
|
128
|
-
createTimePicker as fTimePicker,
|
|
129
|
-
createTopAppBar as fTopAppBar,
|
|
130
|
-
createTooltip as fTooltip
|
|
131
90
|
};
|
|
@@ -284,4 +284,22 @@ $spacing-scale: (
|
|
|
284
284
|
@return map.get($chip-config, $key);
|
|
285
285
|
}
|
|
286
286
|
@return $fallback;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// Textfield configuration
|
|
290
|
+
$textfield: (
|
|
291
|
+
'height': 56px,
|
|
292
|
+
'height-small': 48px,
|
|
293
|
+
'height-large': 64px,
|
|
294
|
+
'padding-horizontal': 16px,
|
|
295
|
+
'padding-vertical': 16px,
|
|
296
|
+
'border-radius': map.get($shape, 'extra-small'),
|
|
297
|
+
'border-width': 1px,
|
|
298
|
+
'label-offset': 16px,
|
|
299
|
+
'icon-size': 24px
|
|
300
|
+
) !default;
|
|
301
|
+
|
|
302
|
+
// Add textfield function
|
|
303
|
+
@function textfield($key) {
|
|
304
|
+
@return map.get($textfield, $key);
|
|
287
305
|
}
|
|
@@ -106,6 +106,17 @@ $component: '#{base.$prefix}-button';
|
|
|
106
106
|
opacity: 0.38
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
+
// Active state - applied when the button has a menu open
|
|
110
|
+
&--active {
|
|
111
|
+
// Common active state styling for all variants
|
|
112
|
+
box-shadow: none;
|
|
113
|
+
|
|
114
|
+
// ARIA attribute to indicate active state for accessibility
|
|
115
|
+
&[aria-expanded="true"] {
|
|
116
|
+
// For compatibility with ARIA
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
109
120
|
// Variants
|
|
110
121
|
&--filled {
|
|
111
122
|
background-color: t.color('primary');
|
|
@@ -116,7 +127,8 @@ $component: '#{base.$prefix}-button';
|
|
|
116
127
|
@include m.elevation(1);
|
|
117
128
|
}
|
|
118
129
|
|
|
119
|
-
&:active
|
|
130
|
+
&:active,
|
|
131
|
+
&.#{$component}--active {
|
|
120
132
|
@include m.state-layer(t.color('on-primary'), 'pressed');
|
|
121
133
|
@include m.elevation(0);
|
|
122
134
|
}
|
|
@@ -133,7 +145,8 @@ $component: '#{base.$prefix}-button';
|
|
|
133
145
|
@include m.elevation(2);
|
|
134
146
|
}
|
|
135
147
|
|
|
136
|
-
&:active
|
|
148
|
+
&:active,
|
|
149
|
+
&.#{$component}--active {
|
|
137
150
|
@include m.state-layer(t.color('primary'), 'pressed');
|
|
138
151
|
@include m.elevation(1);
|
|
139
152
|
}
|
|
@@ -160,7 +173,8 @@ $component: '#{base.$prefix}-button';
|
|
|
160
173
|
@include m.elevation(1);
|
|
161
174
|
}
|
|
162
175
|
|
|
163
|
-
&:active
|
|
176
|
+
&:active,
|
|
177
|
+
&.#{$component}--active {
|
|
164
178
|
@include m.state-layer(t.color('on-secondary-container'), 'pressed');
|
|
165
179
|
@include m.elevation(0);
|
|
166
180
|
}
|
|
@@ -175,7 +189,8 @@ $component: '#{base.$prefix}-button';
|
|
|
175
189
|
background-color: t.alpha('primary', 0.08);
|
|
176
190
|
}
|
|
177
191
|
|
|
178
|
-
&:active
|
|
192
|
+
&:active,
|
|
193
|
+
&.#{$component}--active {
|
|
179
194
|
@include m.state-layer(t.color('primary'), 'pressed');
|
|
180
195
|
}
|
|
181
196
|
}
|
|
@@ -189,7 +204,8 @@ $component: '#{base.$prefix}-button';
|
|
|
189
204
|
background-color: t.alpha('primary', 0.08);
|
|
190
205
|
}
|
|
191
206
|
|
|
192
|
-
&:active
|
|
207
|
+
&:active,
|
|
208
|
+
&.#{$component}--active {
|
|
193
209
|
background-color: t.alpha('primary', 0.12);
|
|
194
210
|
}
|
|
195
211
|
|
|
@@ -44,6 +44,17 @@ $container: '#{base.$prefix}-chips';
|
|
|
44
44
|
outline-offset: 2px;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
// Active state - applied when the chip has a menu open
|
|
48
|
+
&--active {
|
|
49
|
+
// Base active state styling
|
|
50
|
+
// Will use variant-specific implementations below
|
|
51
|
+
|
|
52
|
+
// ARIA attribute to indicate active state for accessibility
|
|
53
|
+
&[aria-expanded="true"] {
|
|
54
|
+
// For compatibility with ARIA
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
47
58
|
// Disabled state
|
|
48
59
|
&--disabled {
|
|
49
60
|
opacity: 0.38;
|
|
@@ -127,7 +138,8 @@ $container: '#{base.$prefix}-chips';
|
|
|
127
138
|
border-radius: v.chip('border-radius');
|
|
128
139
|
}
|
|
129
140
|
|
|
130
|
-
&:active::after
|
|
141
|
+
&:active::after,
|
|
142
|
+
&.#{$component}--active::after {
|
|
131
143
|
content: '';
|
|
132
144
|
position: absolute;
|
|
133
145
|
inset: 0;
|
|
@@ -151,7 +163,8 @@ $container: '#{base.$prefix}-chips';
|
|
|
151
163
|
border-radius: inherit;
|
|
152
164
|
}
|
|
153
165
|
|
|
154
|
-
&:active::after
|
|
166
|
+
&:active::after,
|
|
167
|
+
&.#{$component}--active::after {
|
|
155
168
|
content: '';
|
|
156
169
|
position: absolute;
|
|
157
170
|
inset: 0;
|
|
@@ -182,7 +195,8 @@ $container: '#{base.$prefix}-chips';
|
|
|
182
195
|
border-color: t.alpha('outline', v.chip('outlined-border-focus-opacity'));
|
|
183
196
|
}
|
|
184
197
|
|
|
185
|
-
&:active::after
|
|
198
|
+
&:active::after,
|
|
199
|
+
&.#{$component}--active::after {
|
|
186
200
|
content: '';
|
|
187
201
|
position: absolute;
|
|
188
202
|
inset: 0;
|
|
@@ -206,6 +220,17 @@ $container: '#{base.$prefix}-chips';
|
|
|
206
220
|
pointer-events: none;
|
|
207
221
|
border-radius: inherit;
|
|
208
222
|
}
|
|
223
|
+
|
|
224
|
+
&:active::after,
|
|
225
|
+
&.#{$component}--active::after {
|
|
226
|
+
content: '';
|
|
227
|
+
position: absolute;
|
|
228
|
+
inset: 0;
|
|
229
|
+
background-color: t.color('on-secondary-container');
|
|
230
|
+
opacity: 0.12;
|
|
231
|
+
pointer-events: none;
|
|
232
|
+
border-radius: inherit;
|
|
233
|
+
}
|
|
209
234
|
}
|
|
210
235
|
}
|
|
211
236
|
|
|
@@ -225,7 +250,8 @@ $container: '#{base.$prefix}-chips';
|
|
|
225
250
|
border-radius: inherit;
|
|
226
251
|
}
|
|
227
252
|
|
|
228
|
-
&:active::after
|
|
253
|
+
&:active::after,
|
|
254
|
+
&.#{$component}--active::after {
|
|
229
255
|
content: '';
|
|
230
256
|
position: absolute;
|
|
231
257
|
inset: 0;
|
|
@@ -248,6 +274,17 @@ $container: '#{base.$prefix}-chips';
|
|
|
248
274
|
pointer-events: none;
|
|
249
275
|
border-radius: inherit;
|
|
250
276
|
}
|
|
277
|
+
|
|
278
|
+
&:active::after,
|
|
279
|
+
&.#{$component}--active::after {
|
|
280
|
+
content: '';
|
|
281
|
+
position: absolute;
|
|
282
|
+
inset: 0;
|
|
283
|
+
background-color: t.color('on-secondary-container');
|
|
284
|
+
opacity: 0.12;
|
|
285
|
+
pointer-events: none;
|
|
286
|
+
border-radius: inherit;
|
|
287
|
+
}
|
|
251
288
|
}
|
|
252
289
|
}
|
|
253
290
|
|
|
@@ -268,6 +305,17 @@ $container: '#{base.$prefix}-chips';
|
|
|
268
305
|
border-radius: calc(v.chip('border-radius') - 1px);
|
|
269
306
|
}
|
|
270
307
|
|
|
308
|
+
&:active::after,
|
|
309
|
+
&.#{$component}--active::after {
|
|
310
|
+
content: '';
|
|
311
|
+
position: absolute;
|
|
312
|
+
inset: 0;
|
|
313
|
+
background-color: t.color('on-surface');
|
|
314
|
+
opacity: 0.12;
|
|
315
|
+
pointer-events: none;
|
|
316
|
+
border-radius: calc(v.chip('border-radius') - 1px);
|
|
317
|
+
}
|
|
318
|
+
|
|
271
319
|
&.#{$component}--selected {
|
|
272
320
|
|
|
273
321
|
padding-left: 8px;
|
|
@@ -310,6 +358,17 @@ $container: '#{base.$prefix}-chips';
|
|
|
310
358
|
pointer-events: none;
|
|
311
359
|
border-radius: calc(v.chip('border-radius') - 1px);
|
|
312
360
|
}
|
|
361
|
+
|
|
362
|
+
&:active::after,
|
|
363
|
+
&.#{$component}--active::after {
|
|
364
|
+
content: '';
|
|
365
|
+
position: absolute;
|
|
366
|
+
inset: 0;
|
|
367
|
+
background-color: t.color('on-secondary-container');
|
|
368
|
+
opacity: 0.12;
|
|
369
|
+
pointer-events: none;
|
|
370
|
+
border-radius: calc(v.chip('border-radius') - 1px);
|
|
371
|
+
}
|
|
313
372
|
}
|
|
314
373
|
}
|
|
315
374
|
|
|
@@ -332,6 +391,17 @@ $container: '#{base.$prefix}-chips';
|
|
|
332
391
|
border-radius: v.chip('border-radius');
|
|
333
392
|
}
|
|
334
393
|
|
|
394
|
+
&:active::after,
|
|
395
|
+
&.#{$component}--active::after {
|
|
396
|
+
content: '';
|
|
397
|
+
position: absolute;
|
|
398
|
+
inset: 0;
|
|
399
|
+
background-color: t.color('on-surface');
|
|
400
|
+
opacity: 0.12;
|
|
401
|
+
pointer-events: none;
|
|
402
|
+
border-radius: v.chip('border-radius');
|
|
403
|
+
}
|
|
404
|
+
|
|
335
405
|
&.#{$component}--selected {
|
|
336
406
|
background-color: t.color('secondary-container');
|
|
337
407
|
color: t.color('on-secondary-container');
|
|
@@ -349,6 +419,17 @@ $container: '#{base.$prefix}-chips';
|
|
|
349
419
|
pointer-events: none;
|
|
350
420
|
border-radius: inherit;
|
|
351
421
|
}
|
|
422
|
+
|
|
423
|
+
&:active::after,
|
|
424
|
+
&.#{$component}--active::after {
|
|
425
|
+
content: '';
|
|
426
|
+
position: absolute;
|
|
427
|
+
inset: 0;
|
|
428
|
+
background-color: t.color('on-secondary-container');
|
|
429
|
+
opacity: 0.12;
|
|
430
|
+
pointer-events: none;
|
|
431
|
+
border-radius: inherit;
|
|
432
|
+
}
|
|
352
433
|
}
|
|
353
434
|
}
|
|
354
435
|
|
|
@@ -375,6 +456,17 @@ $container: '#{base.$prefix}-chips';
|
|
|
375
456
|
pointer-events: none;
|
|
376
457
|
border-radius: inherit;
|
|
377
458
|
}
|
|
459
|
+
|
|
460
|
+
&:active::after,
|
|
461
|
+
&.#{$component}--active::after {
|
|
462
|
+
content: '';
|
|
463
|
+
position: absolute;
|
|
464
|
+
inset: 0;
|
|
465
|
+
background-color: t.color('on-surface');
|
|
466
|
+
opacity: 0.12;
|
|
467
|
+
pointer-events: none;
|
|
468
|
+
border-radius: inherit;
|
|
469
|
+
}
|
|
378
470
|
}
|
|
379
471
|
|
|
380
472
|
// Suggestion chip
|
|
@@ -403,6 +495,17 @@ $container: '#{base.$prefix}-chips';
|
|
|
403
495
|
border-radius: inherit;
|
|
404
496
|
}
|
|
405
497
|
|
|
498
|
+
&:active::after,
|
|
499
|
+
&.#{$component}--active::after {
|
|
500
|
+
content: '';
|
|
501
|
+
position: absolute;
|
|
502
|
+
inset: 0;
|
|
503
|
+
background-color: t.color('on-surface');
|
|
504
|
+
opacity: 0.12;
|
|
505
|
+
pointer-events: none;
|
|
506
|
+
border-radius: inherit;
|
|
507
|
+
}
|
|
508
|
+
|
|
406
509
|
&.#{$component}--selected {
|
|
407
510
|
background-color: t.color('secondary-container');
|
|
408
511
|
color: t.color('on-secondary-container');
|
|
@@ -416,6 +519,17 @@ $container: '#{base.$prefix}-chips';
|
|
|
416
519
|
pointer-events: none;
|
|
417
520
|
border-radius: inherit;
|
|
418
521
|
}
|
|
522
|
+
|
|
523
|
+
&:active::after,
|
|
524
|
+
&.#{$component}--active::after {
|
|
525
|
+
content: '';
|
|
526
|
+
position: absolute;
|
|
527
|
+
inset: 0;
|
|
528
|
+
background-color: t.color('on-secondary-container');
|
|
529
|
+
opacity: 0.12;
|
|
530
|
+
pointer-events: none;
|
|
531
|
+
border-radius: inherit;
|
|
532
|
+
}
|
|
419
533
|
}
|
|
420
534
|
}
|
|
421
535
|
}
|