@fluixi-ui/skin-material 0.2.1-alpha.1 → 0.3.0-alpha.2

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 (2) hide show
  1. package/material.css +219 -1
  2. package/package.json +1 -1
package/material.css CHANGED
@@ -60,6 +60,9 @@
60
60
  content: '';
61
61
  position: absolute;
62
62
  inset: 0;
63
+ /* Follow the button's own shape so the hover layer is rounded even where the
64
+ button isn't clipping (e.g. a glow button, which overflows). */
65
+ border-radius: inherit;
63
66
  background: currentColor;
64
67
  opacity: 0;
65
68
  pointer-events: none;
@@ -212,15 +215,230 @@
212
215
  opacity: 0.4;
213
216
  }
214
217
 
218
+ /* ---- Surface & Card: M3 elevation (softer than the raw shadow tokens, which
219
+ are tuned for pop-overs; on a plain container they read too heavy) ------- */
220
+ [data-ui='material'] :where([data-surface]) {
221
+ border-radius: 12px;
222
+ }
223
+ [data-ui='material'] :where([data-surface][data-elevation='0']) {
224
+ box-shadow: none;
225
+ }
226
+ [data-ui='material'] :where([data-surface][data-elevation='1']),
227
+ [data-ui='material'] :where([data-card]) {
228
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.14), 0 1px 3px rgba(0, 0, 0, 0.08);
229
+ }
230
+ [data-ui='material'] :where([data-surface][data-elevation='2']) {
231
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.13), 0 2px 6px rgba(0, 0, 0, 0.1);
232
+ }
233
+ [data-ui='material'] :where([data-surface][data-elevation='3']) {
234
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.14), 0 4px 8px rgba(0, 0, 0, 0.1);
235
+ }
236
+ [data-ui='material'] :where([data-surface][data-elevation='4']) {
237
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.14), 0 6px 12px rgba(0, 0, 0, 0.1);
238
+ }
239
+ [data-ui='material'] :where([data-card]) {
240
+ border-radius: 12px;
241
+ }
242
+
243
+ /* ---- Calendar: M3 date grid — circular days, outlined "today", state-layer
244
+ nav, and a tonal band across a selected range. ------------------------- */
245
+ [data-ui='material'] :where([data-calendar-day]) {
246
+ border-radius: 9999px;
247
+ font-weight: 500;
248
+ }
249
+ [data-ui='material'] :where([data-calendar-day]:hover:not([data-disabled]):not([data-selected])) {
250
+ background: color-mix(in oklab, var(--flx-ui-color-primary) 10%, transparent);
251
+ color: inherit;
252
+ }
253
+ [data-ui='material'] :where([data-calendar-day][data-today]:not([data-selected])) {
254
+ border: 1px solid var(--flx-ui-color-primary);
255
+ color: var(--flx-ui-color-primary);
256
+ }
257
+ [data-ui='material'] :where([data-calendar-nav]) {
258
+ border: none;
259
+ border-radius: 9999px;
260
+ }
261
+ [data-ui='material'] :where([data-calendar-nav]:hover:not([disabled])) {
262
+ background: color-mix(in oklab, currentColor 8%, transparent);
263
+ }
264
+ /* Range: circular ends, a flat secondary-container band through the middle. */
265
+ [data-ui='material'] :where([data-range] [data-calendar-day][data-selected]) {
266
+ border-radius: 0;
267
+ background: var(--flx-ui-color-primary-subtle);
268
+ color: var(--flx-ui-color-primary-active);
269
+ }
270
+ [data-ui='material'] :where([data-range] [data-calendar-day][data-selection-start]) {
271
+ border-radius: 9999px 0 0 9999px;
272
+ }
273
+ [data-ui='material'] :where([data-range] [data-calendar-day][data-selection-end]) {
274
+ border-radius: 0 9999px 9999px 0;
275
+ }
276
+ [data-ui='material'] :where([data-range] [data-calendar-day][data-selection-start][data-selection-end]) {
277
+ border-radius: 9999px;
278
+ }
279
+ [data-ui='material'] :where([data-calendar-day][data-selection-start], [data-calendar-day][data-selection-end]) {
280
+ background: var(--flx-ui-color-primary);
281
+ color: var(--flx-ui-color-primary-fg);
282
+ }
283
+
284
+ /* ---- Date field & date picker: filled segmented control + M3 date-picker
285
+ surface, matching the filled text-field language above. ---------------- */
286
+ /* The field frame carries the filled fill + underline; the segment input nested
287
+ inside the picker control stays transparent so the underline isn't doubled. */
288
+ [data-ui='material'] :where([data-date-field-input], [data-date-picker-control]) {
289
+ background: var(--flx-ui-color-bg-muted);
290
+ border: none;
291
+ border-bottom: 1px solid var(--flx-ui-color-border-strong);
292
+ border-radius: 4px 4px 0 0;
293
+ }
294
+ [data-ui='material'] :where([data-date-field-input]:focus-within, [data-date-picker-control]:focus-within) {
295
+ border-bottom: 2px solid var(--flx-ui-color-primary);
296
+ box-shadow: none;
297
+ outline: none;
298
+ }
299
+ [data-ui='material'] :where([data-date-picker-input]) {
300
+ background: transparent;
301
+ border: none;
302
+ }
303
+ [data-ui='material'] :where([data-date-picker-content]) {
304
+ border-radius: 16px;
305
+ box-shadow: 0 4px 8px 3px rgba(0, 0, 0, 0.12), 0 1px 3px rgba(0, 0, 0, 0.2);
306
+ }
307
+
308
+ /* ---- Accordion: flat M3 list — no outer frame, dividers between items, a
309
+ state-layer on the header rather than a filled hover. ------------------ */
310
+ [data-ui='material'] :where([data-accordion]) {
311
+ border: none;
312
+ border-radius: 0;
313
+ }
314
+ [data-ui='material'] :where([data-accordion-item]:not(:last-child)) {
315
+ border-bottom: 1px solid var(--flx-ui-color-border);
316
+ }
317
+ [data-ui='material'] :where([data-accordion-trigger]) {
318
+ padding: 16px var(--flx-ui-space-4);
319
+ font-weight: 500;
320
+ }
321
+ [data-ui='material'] :where([data-accordion-trigger]:hover:not([data-disabled])) {
322
+ background: color-mix(in oklab, var(--flx-ui-color-fg) 6%, transparent);
323
+ }
324
+
325
+ /* ---- Radio: M3 20px target ---------------------------------------------- */
326
+ [data-ui='material'] :where([role='radio']) {
327
+ width: 20px;
328
+ height: 20px;
329
+ border-width: 2px;
330
+ }
331
+
332
+ /* ---- Toggle / segmented button: selected = secondary-container ----------- */
333
+ [data-ui='material'] :where([aria-pressed][data-state='on']) {
334
+ background: var(--flx-ui-color-primary-subtle);
335
+ border-color: transparent;
336
+ color: var(--flx-ui-color-primary-active);
337
+ }
338
+
339
+ /* ---- Number field: filled control row to match the text fields ---------- */
340
+ [data-ui='material'] :where([data-number-field-input-row]) {
341
+ background: var(--flx-ui-color-bg-muted);
342
+ border: none;
343
+ border-bottom: 1px solid var(--flx-ui-color-border-strong);
344
+ border-radius: 4px 4px 0 0;
345
+ }
346
+ [data-ui='material'] :where([data-number-field-input-row]:focus-within) {
347
+ border-bottom: 2px solid var(--flx-ui-color-primary);
348
+ }
349
+
350
+ /* ---- Linear progress: 4dp fully-rounded track, tonal remainder ---------- */
351
+ [data-ui='material'] :where([role='progressbar']) {
352
+ height: 4px;
353
+ border-radius: 9999px;
354
+ background: var(--flx-ui-color-primary-subtle);
355
+ }
356
+
357
+ /* ---- Sidenav: M3 navigation drawer — full-pill items, state-layer hover,
358
+ secondary-container active. ------------------------------------------- */
359
+ [data-ui='material'] :where([data-sidenav-link]) {
360
+ border-radius: 9999px;
361
+ font-weight: 500;
362
+ }
363
+ [data-ui='material'] :where([data-sidenav-link]:hover:not([data-active])) {
364
+ background: color-mix(in oklab, var(--flx-ui-color-fg) 8%, transparent);
365
+ color: inherit;
366
+ }
367
+ [data-ui='material'] :where([data-sidenav-link][data-active]) {
368
+ background: var(--flx-ui-color-primary-subtle);
369
+ color: var(--flx-ui-color-primary-active);
370
+ }
371
+
372
+ /* ---- Pagination: circular pages, filled current ------------------------- */
373
+ [data-ui='material'] :where([data-pagination-page], [data-pagination-prev], [data-pagination-next]) {
374
+ border-radius: 9999px;
375
+ }
376
+ [data-ui='material'] :where([data-pagination-page]:hover:not([data-current])) {
377
+ background: color-mix(in oklab, var(--flx-ui-color-fg) 8%, transparent);
378
+ }
379
+ [data-ui='material'] :where([data-pagination-page][data-current]) {
380
+ background: var(--flx-ui-color-primary);
381
+ color: var(--flx-ui-color-primary-fg);
382
+ border-color: transparent;
383
+ }
384
+
385
+ /* ---- Stepper: circular numbered indicators ------------------------------ */
386
+ [data-ui='material'] :where([data-stepper-indicator]) {
387
+ border-radius: 9999px;
388
+ }
389
+
390
+ /* ---- Breadcrumb: state-layer link affordance ---------------------------- */
391
+ [data-ui='material'] :where([data-breadcrumb-link]:hover) {
392
+ background: color-mix(in oklab, var(--flx-ui-color-fg) 8%, transparent);
393
+ border-radius: 4px;
394
+ }
395
+
396
+ /* ---- Navigation menu & menubar: state-layer triggers, rounded ----------- */
397
+ [data-ui='material'] :where([data-navigation-menu-trigger]:hover),
398
+ [data-ui='material'] :where([role='menubar'] > [role='menuitem']:hover) {
399
+ background: color-mix(in oklab, var(--flx-ui-color-fg) 8%, transparent);
400
+ border-radius: 8px;
401
+ }
402
+
403
+ /* ---- Command & menu rows: M3 state layer over the flat rows -------------- */
404
+ [data-ui='material'] :where([data-command-item][data-active]) {
405
+ background: color-mix(in oklab, var(--flx-ui-color-fg) 8%, transparent);
406
+ }
407
+
408
+ /* ---- Table: subtle row state layer, medium-weight header ---------------- */
409
+ [data-ui='material'] :where([data-table-head]) {
410
+ font-weight: 500;
411
+ }
412
+ [data-ui='material'] :where([data-table-row]:hover) {
413
+ background: color-mix(in oklab, var(--flx-ui-color-fg) 4%, transparent);
414
+ }
415
+
416
+ /* ---- Toast: M3 snackbar shape + elevation (keeps the type accent) -------- */
417
+ [data-ui='material'] :where([data-toast]) {
418
+ border-radius: 4px;
419
+ box-shadow: 0 3px 5px rgba(0, 0, 0, 0.2), 0 1px 18px rgba(0, 0, 0, 0.12);
420
+ }
421
+
422
+ /* ---- Alert: M3 medium radius ------------------------------------------- */
423
+ [data-ui='material'] :where([data-alert]) {
424
+ border-radius: 12px;
425
+ }
426
+
215
427
  /* ---- Click-origin ripple (installed by the ripple primitive) ------------- */
216
428
  [data-ui='material'] :where([data-variant], [role='menuitem'], [role='option'], [role='tab']) {
217
429
  position: relative;
218
430
  overflow: hidden;
219
431
  }
432
+ /* A glow button draws its ring on ::after at the border edge; the ripple's
433
+ overflow:hidden would clip it, so let a glow button overflow. */
434
+ [data-ui='material'] :where([data-variant][data-glow]) {
435
+ overflow: visible;
436
+ }
220
437
  [data-ui='material'] .flx-mat-ripple {
221
438
  position: absolute;
222
439
  border-radius: 50%;
223
- background: currentColor;
440
+ /* Overridable per-control via --flx-mat-ripple-color; defaults to the ink. */
441
+ background: var(--flx-mat-ripple-color, currentColor);
224
442
  opacity: 0;
225
443
  transform: scale(0);
226
444
  pointer-events: none;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluixi-ui/skin-material",
3
- "version": "0.2.1-alpha.1",
3
+ "version": "0.3.0-alpha.2",
4
4
  "description": "Material Design skin for Fluixi UI — activate with data-ui=\"material\"",
5
5
  "license": "MIT",
6
6
  "private": false,