@reliability-design/web 1.3.1 → 1.4.1
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/CHANGELOG.md +22 -0
- package/dist/components/rel-accordion/README.md +13 -13
- package/dist/components/rel-accordion/rel-accordion.ts +80 -45
- package/dist/components/rel-alert/README.md +15 -15
- package/dist/components/rel-alert/rel-alert.ts +149 -158
- package/dist/components/rel-avatar/README.md +15 -15
- package/dist/components/rel-avatar/rel-avatar.ts +42 -38
- package/dist/components/rel-badge/README.md +5 -5
- package/dist/components/rel-badge/rel-badge.ts +46 -11
- package/dist/components/rel-breadcrumb/README.md +7 -7
- package/dist/components/rel-breadcrumb/rel-breadcrumb.ts +16 -13
- package/dist/components/rel-button/README.md +20 -20
- package/dist/components/rel-button/rel-button.ts +292 -105
- package/dist/components/rel-calendar/README.md +5 -5
- package/dist/components/rel-calendar/rel-calendar.ts +68 -45
- package/dist/components/rel-card/README.md +6 -6
- package/dist/components/rel-card/rel-card.ts +88 -35
- package/dist/components/rel-cardmedia/README.md +9 -9
- package/dist/components/rel-cardmedia/rel-cardmedia.ts +27 -20
- package/dist/components/rel-carousel/README.md +3 -3
- package/dist/components/rel-carousel/rel-carousel.ts +174 -90
- package/dist/components/rel-chart/README.md +8 -8
- package/dist/components/rel-chart/rel-chart.ts +59 -41
- package/dist/components/rel-checkbox/README.md +7 -7
- package/dist/components/rel-checkbox/rel-checkbox.ts +61 -61
- package/dist/components/rel-chip/README.md +16 -16
- package/dist/components/rel-chip/rel-chip.ts +143 -111
- package/dist/components/rel-container/README.md +11 -11
- package/dist/components/rel-container/rel-container.ts +35 -9
- package/dist/components/rel-date-picker/README.md +43 -7
- package/dist/components/rel-date-picker/date-format.test.ts +43 -0
- package/dist/components/rel-date-picker/date-format.ts +47 -0
- package/dist/components/rel-date-picker/rel-date-picker.ts +154 -82
- package/dist/components/rel-divider/README.md +9 -9
- package/dist/components/rel-divider/rel-divider.ts +10 -9
- package/dist/components/rel-drawer/README.md +1 -1
- package/dist/components/rel-drawer/rel-drawer-footer.ts +1 -1
- package/dist/components/rel-drawer/rel-drawer.ts +88 -25
- package/dist/components/rel-kbd/README.md +20 -20
- package/dist/components/rel-kbd/rel-kbd.ts +119 -25
- package/dist/components/rel-layout/README.md +1 -1
- package/dist/components/rel-layout/rel-layout.ts +2 -2
- package/dist/components/rel-menu/README.md +15 -15
- package/dist/components/rel-menu/rel-menu.ts +155 -88
- package/dist/components/rel-menubar/README.md +20 -20
- package/dist/components/rel-menubar/rel-menubar.ts +47 -31
- package/dist/components/rel-nav-menu/README.md +21 -21
- package/dist/components/rel-nav-menu/rel-nav-menu-item.ts +17 -14
- package/dist/components/rel-nav-menu/rel-nav-menu-panel.ts +33 -14
- package/dist/components/rel-nav-menu/rel-nav-menu.ts +14 -7
- package/dist/components/rel-navbar/README.md +7 -7
- package/dist/components/rel-navbar/rel-navbar.ts +12 -11
- package/dist/components/rel-otp/README.md +3 -3
- package/dist/components/rel-otp/rel-otp.ts +46 -30
- package/dist/components/rel-pagination/README.md +18 -18
- package/dist/components/rel-pagination/rel-pagination.ts +141 -90
- package/dist/components/rel-popover/README.md +13 -13
- package/dist/components/rel-popover/rel-popover-content.ts +39 -14
- package/dist/components/rel-popover/rel-popover.ts +18 -7
- package/dist/components/rel-progress/README.md +5 -5
- package/dist/components/rel-progress/rel-progress.ts +16 -12
- package/dist/components/rel-radio/README.md +9 -9
- package/dist/components/rel-radio/rel-radio.ts +64 -50
- package/dist/components/rel-range-picker/rel-range-picker.ts +120 -117
- package/dist/components/rel-resizable/README.md +4 -4
- package/dist/components/rel-resizable/rel-resizable-group.ts +15 -4
- package/dist/components/rel-resizable/rel-resizable-handle.ts +13 -9
- package/dist/components/rel-resizable/rel-resizable-panel.ts +11 -0
- package/dist/components/rel-segmented-button/README.md +10 -10
- package/dist/components/rel-segmented-button/rel-segmented-button.ts +39 -40
- package/dist/components/rel-select/README.md +14 -14
- package/dist/components/rel-select/rel-select.ts +120 -188
- package/dist/components/rel-sheet/README.md +10 -10
- package/dist/components/rel-sheet/rel-sheet.ts +82 -23
- package/dist/components/rel-sidebar/README.md +5 -5
- package/dist/components/rel-sidebar/rel-sidebar.ts +75 -60
- package/dist/components/rel-skeleton/rel-skeleton.ts +8 -13
- package/dist/components/rel-slider/README.md +10 -10
- package/dist/components/rel-slider/rel-slider.ts +230 -57
- package/dist/components/rel-snackbar/README.md +9 -9
- package/dist/components/rel-snackbar/rel-snackbar.ts +44 -32
- package/dist/components/rel-stepper/README.md +10 -10
- package/dist/components/rel-stepper/rel-stepper.ts +110 -46
- package/dist/components/rel-switch/README.md +5 -5
- package/dist/components/rel-switch/rel-switch.ts +23 -12
- package/dist/components/rel-tab/README.md +13 -13
- package/dist/components/rel-tab/rel-tab.ts +63 -19
- package/dist/components/rel-table/README.md +7 -7
- package/dist/components/rel-table/rel-table-body.ts +2 -1
- package/dist/components/rel-table/rel-table-caption.ts +10 -7
- package/dist/components/rel-table/rel-table-cell.ts +7 -6
- package/dist/components/rel-table/rel-table-footer.ts +4 -3
- package/dist/components/rel-table/rel-table-head.ts +11 -9
- package/dist/components/rel-table/rel-table-header.ts +2 -1
- package/dist/components/rel-table/rel-table-row.ts +5 -4
- package/dist/components/rel-table/rel-table.ts +16 -7
- package/dist/components/rel-textfield/README.md +11 -11
- package/dist/components/rel-textfield/rel-textfield.ts +218 -92
- package/dist/components/rel-toast/README.md +11 -11
- package/dist/components/rel-toast/rel-toast.ts +33 -30
- package/dist/components/rel-tooltip/README.md +7 -7
- package/dist/components/rel-tooltip/rel-tooltip.ts +160 -123
- package/dist/components/rel-topbar/rel-topbar-actions.ts +1 -2
- package/dist/components/rel-topbar/rel-topbar-brand.ts +8 -5
- package/dist/components/rel-topbar/rel-topbar-dropdown-item.ts +10 -8
- package/dist/components/rel-topbar/rel-topbar-dropdown.ts +4 -5
- package/dist/components/rel-topbar/rel-topbar-item.ts +23 -22
- package/dist/components/rel-topbar/rel-topbar-mobile-panel.ts +0 -1
- package/dist/components/rel-topbar/rel-topbar-profile.ts +68 -50
- package/dist/components/rel-topbar/rel-topbar-utilities.ts +1 -2
- package/dist/components/rel-topbar/rel-topbar.ts +31 -29
- package/dist/index.d.mts +159 -39
- package/dist/index.d.ts +159 -39
- package/dist/index.js +3600 -2269
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3930 -2600
- package/dist/index.mjs.map +1 -1
- package/dist/styles/vars.css +866 -363
- package/dist/vars-BYCEEKWJ.css +866 -0
- package/package.json +5 -3
- package/dist/components/rel-range-picker/rel-range-picker.css +0 -349
- package/dist/styles/vars-v2.css +0 -525
- package/dist/vars-F54UGCHM.css +0 -363
- package/dist/vars-v2-VMGWTFJZ.css +0 -525
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { LitElement, html, css, nothing } from "lit";
|
|
2
2
|
import { customElement, property, state } from "lit/decorators.js";
|
|
3
|
-
import "../../styles/vars-v2.css";
|
|
4
3
|
|
|
5
4
|
interface CalendarDay {
|
|
6
5
|
date: Date;
|
|
@@ -9,6 +8,7 @@ interface CalendarDay {
|
|
|
9
8
|
isToday: boolean;
|
|
10
9
|
isSelected: boolean;
|
|
11
10
|
isDisabled: boolean;
|
|
11
|
+
isWeekend: boolean;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
@customElement("rel-calendar")
|
|
@@ -30,17 +30,24 @@ export class RelCalendar extends LitElement {
|
|
|
30
30
|
static styles = css`
|
|
31
31
|
:host {
|
|
32
32
|
display: block;
|
|
33
|
-
font-family: var(--rel-
|
|
34
|
-
background: var(--rel-
|
|
35
|
-
border: 1px solid var(--rel-border-default
|
|
36
|
-
border-radius: var(--rel-
|
|
37
|
-
padding: var(--rel-spacing-
|
|
33
|
+
font-family: var(--rel-fonts-font-family, sans-serif);
|
|
34
|
+
background: var(--rel-bg-neutral);
|
|
35
|
+
border: 1px solid var(--rel-border-default);
|
|
36
|
+
border-radius: var(--rel-border-radius-sm, 8px);
|
|
37
|
+
padding: var(--rel-spacing-md, 16px);
|
|
38
38
|
max-width: 320px;
|
|
39
|
-
color: var(--rel-text-
|
|
39
|
+
color: var(--rel-text-default);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
:host([disabled]) {
|
|
43
43
|
opacity: 0.6;
|
|
44
|
+
cursor: not-allowed;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/* Block interaction on the inner controls (JS also guards clicks), but keep
|
|
48
|
+
pointer-events on the host so its not-allowed cursor shows through. */
|
|
49
|
+
:host([disabled]) .day-button,
|
|
50
|
+
:host([disabled]) .nav-button {
|
|
44
51
|
pointer-events: none;
|
|
45
52
|
}
|
|
46
53
|
|
|
@@ -48,16 +55,19 @@ export class RelCalendar extends LitElement {
|
|
|
48
55
|
display: flex;
|
|
49
56
|
align-items: center;
|
|
50
57
|
justify-content: space-between;
|
|
51
|
-
margin-bottom: var(--rel-spacing-
|
|
58
|
+
margin-bottom: var(--rel-spacing-sm);
|
|
52
59
|
}
|
|
53
60
|
|
|
54
61
|
.header-center {
|
|
55
62
|
display: flex;
|
|
56
63
|
align-items: center;
|
|
57
|
-
gap: var(--rel-spacing-
|
|
58
|
-
|
|
59
|
-
font-
|
|
60
|
-
|
|
64
|
+
gap: var(--rel-spacing-xs);
|
|
65
|
+
color: var(--rel-text-label);
|
|
66
|
+
font-family: var(--rel-body-lg-semibold-font-family);
|
|
67
|
+
font-weight: var(--rel-body-lg-semibold-font-weight);
|
|
68
|
+
font-size: var(--rel-body-lg-regular-font-size);
|
|
69
|
+
line-height: var(--rel-body-lg-regular-line-height);
|
|
70
|
+
letter-spacing: var(--rel-body-lg-regular-letter-spacing);
|
|
61
71
|
}
|
|
62
72
|
|
|
63
73
|
.nav-button {
|
|
@@ -65,75 +75,85 @@ export class RelCalendar extends LitElement {
|
|
|
65
75
|
border: none;
|
|
66
76
|
width: 32px;
|
|
67
77
|
height: 32px;
|
|
68
|
-
border-radius: var(--rel-
|
|
78
|
+
border-radius: var(--rel-border-radius-sm);
|
|
69
79
|
display: flex;
|
|
70
80
|
align-items: center;
|
|
71
81
|
justify-content: center;
|
|
72
82
|
cursor: pointer;
|
|
73
|
-
color: var(--rel-
|
|
83
|
+
color: var(--rel-action-neutral-label-icons-ghost);
|
|
74
84
|
transition: background-color 0.15s ease;
|
|
75
85
|
}
|
|
76
86
|
|
|
77
87
|
.nav-button:hover {
|
|
78
|
-
background: var(--rel-
|
|
88
|
+
background: var(--rel-bg-neutral-elevated-2);
|
|
79
89
|
}
|
|
80
90
|
|
|
81
91
|
.nav-button:focus-visible {
|
|
82
|
-
outline: 2px solid var(--rel-
|
|
92
|
+
outline: 2px solid var(--rel-border-focus);
|
|
83
93
|
outline-offset: 2px;
|
|
84
94
|
}
|
|
85
95
|
|
|
86
96
|
.calendar-grid {
|
|
87
97
|
display: grid;
|
|
88
98
|
grid-template-columns: repeat(7, 1fr);
|
|
89
|
-
gap: var(--rel-spacing-
|
|
99
|
+
gap: var(--rel-spacing-2xs);
|
|
90
100
|
}
|
|
91
101
|
|
|
92
102
|
.weekday {
|
|
93
103
|
text-align: center;
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
color: var(--rel-gray-text-placeholder);
|
|
97
|
-
padding: var(--rel-spacing-space-xs);
|
|
104
|
+
color: var(--rel-text-placeholder);
|
|
105
|
+
padding: var(--rel-spacing-xs);
|
|
98
106
|
text-transform: uppercase;
|
|
107
|
+
font-family: var(--rel-body-sm-regular-font-family);
|
|
108
|
+
font-weight: var(--rel-body-xs-medium-font-weight);
|
|
109
|
+
font-size: var(--rel-body-sm-medium-font-size);
|
|
110
|
+
line-height: var(--rel-body-sm-medium-line-height);
|
|
111
|
+
letter-spacing: var(--rel-body-sm-medium-letter-spacing);
|
|
99
112
|
}
|
|
100
113
|
|
|
101
114
|
.day-button {
|
|
102
115
|
aspect-ratio: 1;
|
|
103
116
|
border: none;
|
|
104
117
|
background: transparent;
|
|
105
|
-
border-radius: var(--rel-
|
|
106
|
-
|
|
107
|
-
font-weight: var(--rel-fontWeights-medium);
|
|
108
|
-
color: var(--rel-text-primary);
|
|
118
|
+
border-radius: var(--rel-border-radius-sm);
|
|
119
|
+
color: var(--rel-text-default);
|
|
109
120
|
cursor: pointer;
|
|
110
121
|
position: relative;
|
|
111
122
|
transition: all 0.15s ease;
|
|
112
|
-
font-family: var(--rel-
|
|
123
|
+
font-family: var(--rel-body-md-regular-font-family);
|
|
124
|
+
font-weight: var(--rel-body-md-regular-font-weight);
|
|
125
|
+
font-size: var(--rel-body-md-regular-font-size);
|
|
126
|
+
line-height: var(--rel-body-md-regular-line-height);
|
|
127
|
+
letter-spacing: var(--rel-body-md-regular-letter-spacing);
|
|
113
128
|
}
|
|
114
129
|
|
|
115
130
|
.day-button:hover:not(:disabled):not(.selected) {
|
|
116
|
-
background: var(--rel-
|
|
131
|
+
background: var(--rel-bg-neutral-elevated-1);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/* Weekend (Figma Day of a week=Weekend): same color at 70% — full opacity when selected */
|
|
135
|
+
.day-button.weekend:not(.selected) {
|
|
136
|
+
opacity: 0.7;
|
|
117
137
|
}
|
|
118
138
|
|
|
119
139
|
.day-button:focus-visible {
|
|
120
|
-
outline: 2px solid var(--rel-
|
|
140
|
+
outline: 2px solid var(--rel-border-focus);
|
|
121
141
|
outline-offset: -2px;
|
|
122
142
|
z-index: 1;
|
|
123
143
|
}
|
|
124
144
|
|
|
125
145
|
.day-button.today:not(.selected) {
|
|
126
|
-
border: 2px solid var(--rel-
|
|
146
|
+
border: 2px solid var(--rel-border-brand);
|
|
127
147
|
}
|
|
128
148
|
|
|
129
149
|
.day-button.selected {
|
|
130
|
-
background: var(--rel-
|
|
131
|
-
color:
|
|
132
|
-
font-weight: var(--rel-
|
|
150
|
+
background: var(--rel-bg-neutral-inverse-2);
|
|
151
|
+
color: var(--rel-text-inverse);
|
|
152
|
+
font-weight: var(--rel-body-md-semibold-font-weight);
|
|
133
153
|
}
|
|
134
154
|
|
|
135
155
|
.day-button.other-month {
|
|
136
|
-
color: var(--rel-
|
|
156
|
+
color: var(--rel-text-placeholder);
|
|
137
157
|
opacity: 0.5;
|
|
138
158
|
}
|
|
139
159
|
|
|
@@ -149,8 +169,8 @@ export class RelCalendar extends LitElement {
|
|
|
149
169
|
|
|
150
170
|
:host-context([data-theme="dark"]) :host,
|
|
151
171
|
:host-context(.dark) :host {
|
|
152
|
-
background: var(--rel-
|
|
153
|
-
border-color: var(--rel-
|
|
172
|
+
background: var(--rel-bg-neutral);
|
|
173
|
+
border-color: var(--rel-border-default);
|
|
154
174
|
}
|
|
155
175
|
`;
|
|
156
176
|
|
|
@@ -239,6 +259,7 @@ export class RelCalendar extends LitElement {
|
|
|
239
259
|
isToday: this.isSameDay(date, today),
|
|
240
260
|
isSelected: selectedDate ? this.isSameDay(date, selectedDate) : false,
|
|
241
261
|
isDisabled: this.isDateDisabledInternal(date),
|
|
262
|
+
isWeekend: date.getDay() === 0 || date.getDay() === 6,
|
|
242
263
|
});
|
|
243
264
|
}
|
|
244
265
|
|
|
@@ -252,6 +273,7 @@ export class RelCalendar extends LitElement {
|
|
|
252
273
|
isToday: this.isSameDay(date, today),
|
|
253
274
|
isSelected: selectedDate ? this.isSameDay(date, selectedDate) : false,
|
|
254
275
|
isDisabled: this.isDateDisabledInternal(date),
|
|
276
|
+
isWeekend: date.getDay() === 0 || date.getDay() === 6,
|
|
255
277
|
});
|
|
256
278
|
}
|
|
257
279
|
|
|
@@ -266,6 +288,7 @@ export class RelCalendar extends LitElement {
|
|
|
266
288
|
isToday: this.isSameDay(date, today),
|
|
267
289
|
isSelected: selectedDate ? this.isSameDay(date, selectedDate) : false,
|
|
268
290
|
isDisabled: this.isDateDisabledInternal(date),
|
|
291
|
+
isWeekend: date.getDay() === 0 || date.getDay() === 6,
|
|
269
292
|
});
|
|
270
293
|
}
|
|
271
294
|
|
|
@@ -409,9 +432,9 @@ export class RelCalendar extends LitElement {
|
|
|
409
432
|
|
|
410
433
|
return html`
|
|
411
434
|
<div role="grid" aria-label="Calendar">
|
|
412
|
-
<div class="header">
|
|
435
|
+
<div part="header" class="header">
|
|
413
436
|
<button
|
|
414
|
-
class="nav-button"
|
|
437
|
+
part="action" class="nav-button"
|
|
415
438
|
@click=${this.previousMonth}
|
|
416
439
|
aria-label="Previous month"
|
|
417
440
|
?disabled=${this.disabled}
|
|
@@ -421,13 +444,13 @@ export class RelCalendar extends LitElement {
|
|
|
421
444
|
</svg>
|
|
422
445
|
</button>
|
|
423
446
|
|
|
424
|
-
<div class="header-center">
|
|
447
|
+
<div part="label" class="header-center">
|
|
425
448
|
<span>${this.getMonthName()}</span>
|
|
426
449
|
<span>${this.viewYear}</span>
|
|
427
450
|
</div>
|
|
428
451
|
|
|
429
452
|
<button
|
|
430
|
-
class="nav-button"
|
|
453
|
+
part="action" class="nav-button"
|
|
431
454
|
@click=${this.nextMonth}
|
|
432
455
|
aria-label="Next month"
|
|
433
456
|
?disabled=${this.disabled}
|
|
@@ -438,27 +461,27 @@ export class RelCalendar extends LitElement {
|
|
|
438
461
|
</button>
|
|
439
462
|
</div>
|
|
440
463
|
|
|
441
|
-
<div class="calendar-grid" role="row">
|
|
464
|
+
<div part="list" class="calendar-grid" role="row">
|
|
442
465
|
${weekdayLabels.map(
|
|
443
466
|
(label) => html`
|
|
444
|
-
<div class="weekday" role="columnheader" aria-label="${label}">
|
|
467
|
+
<div part="label" class="weekday" role="columnheader" aria-label="${label}">
|
|
445
468
|
${label}
|
|
446
469
|
</div>
|
|
447
470
|
`
|
|
448
471
|
)}
|
|
449
472
|
</div>
|
|
450
473
|
|
|
451
|
-
<div class="calendar-grid">
|
|
474
|
+
<div part="list" class="calendar-grid">
|
|
452
475
|
${days.map(
|
|
453
476
|
(day, index) => html`
|
|
454
477
|
<button
|
|
455
|
-
class="day-button ${day.isSelected ? "selected" : ""} ${day.isToday
|
|
478
|
+
part="item" class="day-button ${day.isSelected ? "selected" : ""} ${day.isToday
|
|
456
479
|
? "today"
|
|
457
|
-
: ""} ${!day.isCurrentMonth ? "other-month" : ""}"
|
|
480
|
+
: ""} ${!day.isCurrentMonth ? "other-month" : ""} ${day.isWeekend ? "weekend" : ""}"
|
|
458
481
|
role="gridcell"
|
|
459
482
|
aria-label="${this.formatISODate(day.date)}"
|
|
460
483
|
aria-selected="${day.isSelected}"
|
|
461
|
-
?disabled=${day.isDisabled
|
|
484
|
+
?disabled=${day.isDisabled}
|
|
462
485
|
@click=${() => this.selectDay(day)}
|
|
463
486
|
@keydown=${(e: KeyboardEvent) => this.handleKeyDown(e, day, index)}
|
|
464
487
|
tabindex="${day.isSelected || (index === 0 && !this.focusedDate) ? 0 : -1}"
|
|
@@ -55,21 +55,21 @@ None exposed.
|
|
|
55
55
|
## Tokens / CSS Variables
|
|
56
56
|
|
|
57
57
|
### Semantic Tokens
|
|
58
|
-
- `--rel-
|
|
58
|
+
- `--rel-fonts-font-family` - Font family
|
|
59
59
|
|
|
60
60
|
### Color Tokens
|
|
61
|
-
- `--rel-
|
|
62
|
-
- `--rel-text-
|
|
61
|
+
- `--rel-bg-surface` - Card background color
|
|
62
|
+
- `--rel-text-default` - Text color
|
|
63
63
|
|
|
64
64
|
### Shadow Tokens
|
|
65
65
|
- `--rel-shadows-shadow-200` - Default elevation shadow
|
|
66
66
|
- `--rel-shadows-shadow-300` - Hover elevation shadow (larger)
|
|
67
67
|
|
|
68
68
|
### Border Tokens
|
|
69
|
-
- `--rel-
|
|
69
|
+
- `--rel-border-radius-md` - Card border radius
|
|
70
70
|
|
|
71
71
|
### Spacing Tokens
|
|
72
|
-
- `--rel-spacing-
|
|
72
|
+
- `--rel-spacing-md` - Internal padding
|
|
73
73
|
|
|
74
74
|
## Accessibility
|
|
75
75
|
- The card itself has no specific ARIA role (it's a generic container)
|
|
@@ -88,7 +88,7 @@ None exposed.
|
|
|
88
88
|
- **Hover effect**: Translates the card upward by 3px (`translateY(-3px)`) and increases shadow depth
|
|
89
89
|
- **Animation**: Uses `transition: transform 0.2s ease, box-shadow 0.2s ease`
|
|
90
90
|
- **Motion preferences**: When `prefers-reduced-motion: reduce`, both hover transform and transitions are disabled
|
|
91
|
-
- The card has consistent padding on all sides via `--rel-spacing-
|
|
91
|
+
- The card has consistent padding on all sides via `--rel-spacing-md`
|
|
92
92
|
- The internal `.card` wrapper is where all styling is applied
|
|
93
93
|
- The component provides no default content styling—you control the layout of slotted elements
|
|
94
94
|
- Works well with CSS Grid or Flexbox for creating card layouts
|
|
@@ -1,35 +1,88 @@
|
|
|
1
|
-
import { LitElement, html, css } from "lit";
|
|
2
|
-
import { customElement } from "lit/decorators.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
1
|
+
import { LitElement, html, css, nothing } from "lit";
|
|
2
|
+
import { customElement, property } from "lit/decorators.js";
|
|
3
|
+
|
|
4
|
+
@customElement("rel-card")
|
|
5
|
+
export class RelCard extends LitElement {
|
|
6
|
+
/**
|
|
7
|
+
* Figma "Type" axis: custom (default) renders slotted content with card
|
|
8
|
+
* padding; media adds a flush media region (slot name="media") above the
|
|
9
|
+
* content — pair it with <rel-card-media>.
|
|
10
|
+
*/
|
|
11
|
+
@property({ type: String, reflect: true })
|
|
12
|
+
type: "custom" | "media" = "custom";
|
|
13
|
+
|
|
14
|
+
static styles = css`
|
|
15
|
+
:host {
|
|
16
|
+
color: var(--rel-text-default);
|
|
17
|
+
display: block;
|
|
18
|
+
font-family: var(--rel-body-lg-regular-font-family);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/* Default typography for slotted card content (Figma card roles) */
|
|
22
|
+
::slotted(h1), ::slotted(h2), ::slotted(h3), ::slotted(h4) {
|
|
23
|
+
font-family: var(--rel-headings-md-font-family);
|
|
24
|
+
font-weight: var(--rel-headings-md-font-weight);
|
|
25
|
+
font-size: var(--rel-headings-md-font-size);
|
|
26
|
+
line-height: var(--rel-headings-md-line-height);
|
|
27
|
+
letter-spacing: var(--rel-headings-md-letter-spacing);
|
|
28
|
+
color: var(--rel-text-default);
|
|
29
|
+
margin: 0 0 var(--rel-spacing-2xs) 0;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
::slotted(p) {
|
|
33
|
+
font-family: var(--rel-body-lg-regular-font-family);
|
|
34
|
+
font-weight: var(--rel-body-lg-regular-font-weight);
|
|
35
|
+
font-size: var(--rel-body-lg-regular-font-size);
|
|
36
|
+
line-height: var(--rel-body-lg-regular-line-height);
|
|
37
|
+
letter-spacing: var(--rel-body-lg-regular-letter-spacing);
|
|
38
|
+
color: var(--rel-text-body);
|
|
39
|
+
margin: 0 0 var(--rel-spacing-xs) 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.card {
|
|
43
|
+
background-color: var(--rel-bg-surface);
|
|
44
|
+
color: var(--rel-text-default);
|
|
45
|
+
border-radius: var(--rel-border-radius-sm);
|
|
46
|
+
border: 1px solid var(--rel-border-default);
|
|
47
|
+
padding: var(--rel-spacing-lg) var(--rel-spacing-md);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* Media type: media sits flush against the card edges, content keeps padding */
|
|
51
|
+
:host([type="media"]) .card {
|
|
52
|
+
padding: 0;
|
|
53
|
+
overflow: hidden;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.media {
|
|
57
|
+
display: block;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.media ::slotted(*) {
|
|
61
|
+
display: block;
|
|
62
|
+
width: 100%;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
:host([type="media"]) .content {
|
|
66
|
+
padding: var(--rel-spacing-lg) var(--rel-spacing-md);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
:host-context([data-theme="dark"]) .card,
|
|
70
|
+
:host-context(.dark) .card {
|
|
71
|
+
background-color: var(--rel-bg-surface);
|
|
72
|
+
border-color: var(--rel-border-default);
|
|
73
|
+
}
|
|
74
|
+
`;
|
|
75
|
+
|
|
76
|
+
render() {
|
|
77
|
+
return html`
|
|
78
|
+
<div part="base" class="card">
|
|
79
|
+
${this.type === "media"
|
|
80
|
+
? html`<div part="header" class="media"><slot name="media"></slot></div>`
|
|
81
|
+
: nothing}
|
|
82
|
+
<div part="content" class="content">
|
|
83
|
+
<slot></slot>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
`;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -79,25 +79,25 @@ None exposed.
|
|
|
79
79
|
## Tokens / CSS Variables
|
|
80
80
|
|
|
81
81
|
### Semantic Tokens
|
|
82
|
-
- `--rel-
|
|
83
|
-
- `--rel-
|
|
84
|
-
- `--rel-
|
|
85
|
-
- `--rel-
|
|
82
|
+
- `--rel-fonts-font-family` - Font family
|
|
83
|
+
- `--rel-body-md-regular-font-size` - Title font size
|
|
84
|
+
- `--rel-body-sm-regular-font-size` - Subtitle font size
|
|
85
|
+
- `--rel-fonts-weight-body-semibold` - Title font weight
|
|
86
86
|
|
|
87
87
|
### Color Tokens
|
|
88
|
-
- `--rel-
|
|
89
|
-
- `--rel-text-
|
|
90
|
-
- `--rel-text-
|
|
88
|
+
- `--rel-bg-surface` - Card background color
|
|
89
|
+
- `--rel-text-default` - General text color
|
|
90
|
+
- `--rel-text-label` - Title color
|
|
91
91
|
|
|
92
92
|
### Shadow Tokens
|
|
93
93
|
- `--rel-shadows-shadow-200` - Default elevation shadow
|
|
94
94
|
- `--rel-shadows-shadow-300` - Hover elevation shadow (larger)
|
|
95
95
|
|
|
96
96
|
### Border Tokens
|
|
97
|
-
- `--rel-
|
|
97
|
+
- `--rel-border-radius-md` - Card border radius
|
|
98
98
|
|
|
99
99
|
### Spacing Tokens
|
|
100
|
-
- `--rel-spacing-
|
|
100
|
+
- `--rel-spacing-md` - Content area padding
|
|
101
101
|
|
|
102
102
|
## Accessibility
|
|
103
103
|
- Image has `alt` attribute for screen reader support
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { LitElement, html, css } from "lit";
|
|
2
2
|
import { customElement, property } from "lit/decorators.js";
|
|
3
|
-
import "../../styles/vars-v2.css";
|
|
4
3
|
|
|
5
4
|
@customElement("rel-card-media")
|
|
6
5
|
export class RelCardMedia extends LitElement {
|
|
@@ -11,15 +10,16 @@ export class RelCardMedia extends LitElement {
|
|
|
11
10
|
|
|
12
11
|
static styles = css`
|
|
13
12
|
:host {
|
|
13
|
+
color: var(--rel-text-default);
|
|
14
14
|
display: block;
|
|
15
|
-
font-family: var(--rel-
|
|
15
|
+
font-family: var(--rel-fonts-font-family, sans-serif);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
.card-media {
|
|
19
|
-
background-color: var(--rel-
|
|
20
|
-
color: var(--rel-
|
|
21
|
-
border-radius: var(--rel-
|
|
22
|
-
border: 1px solid var(--rel-
|
|
19
|
+
background-color: var(--rel-bg-surface);
|
|
20
|
+
color: var(--rel-text-default);
|
|
21
|
+
border-radius: var(--rel-border-radius-sm);
|
|
22
|
+
border: 1px solid var(--rel-border-default);
|
|
23
23
|
overflow: hidden;
|
|
24
24
|
}
|
|
25
25
|
|
|
@@ -31,46 +31,53 @@ export class RelCardMedia extends LitElement {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
.card-content {
|
|
34
|
-
padding: var(--rel-spacing-
|
|
34
|
+
padding: var(--rel-spacing-md);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
.card-content h3 {
|
|
38
|
-
margin: 0 0 4px 0;
|
|
39
|
-
|
|
40
|
-
font-
|
|
41
|
-
|
|
38
|
+
margin: 0 0 4px 0;
|
|
39
|
+
color: var(--rel-text-label);
|
|
40
|
+
font-family: var(--rel-body-md-semibold-font-family);
|
|
41
|
+
font-weight: var(--rel-body-md-semibold-font-weight);
|
|
42
|
+
font-size: var(--rel-body-md-semibold-font-size);
|
|
43
|
+
line-height: var(--rel-body-md-semibold-line-height);
|
|
44
|
+
letter-spacing: var(--rel-body-md-semibold-letter-spacing);
|
|
42
45
|
}
|
|
43
46
|
|
|
44
47
|
.card-content p {
|
|
45
|
-
margin: 0 0 8px 0;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
+
margin: 0 0 8px 0;
|
|
49
|
+
color: var(--rel-text-default);
|
|
50
|
+
font-family: var(--rel-body-sm-regular-font-family);
|
|
51
|
+
font-weight: var(--rel-body-sm-regular-font-weight);
|
|
52
|
+
font-size: var(--rel-body-sm-regular-font-size);
|
|
53
|
+
line-height: var(--rel-body-sm-regular-line-height);
|
|
54
|
+
letter-spacing: var(--rel-body-sm-regular-letter-spacing);
|
|
48
55
|
}
|
|
49
56
|
|
|
50
57
|
:host-context([data-theme="dark"]) .card-media,
|
|
51
58
|
:host-context(.dark) .card-media {
|
|
52
|
-
background-color: var(--rel-
|
|
53
|
-
border-color: var(--rel-
|
|
59
|
+
background-color: var(--rel-bg-surface);
|
|
60
|
+
border-color: var(--rel-border-default);
|
|
54
61
|
}
|
|
55
62
|
|
|
56
63
|
:host-context([data-theme="dark"]) .card-content h3,
|
|
57
64
|
:host-context(.dark) .card-content h3 {
|
|
58
|
-
color: var(--rel-
|
|
65
|
+
color: var(--rel-text-label);
|
|
59
66
|
}
|
|
60
67
|
`;
|
|
61
68
|
|
|
62
69
|
render() {
|
|
63
70
|
return html`
|
|
64
|
-
<div class="card-media">
|
|
71
|
+
<div part="base" class="card-media">
|
|
65
72
|
${this.imageSrc
|
|
66
73
|
? html`
|
|
67
|
-
<div class="card-image">
|
|
74
|
+
<div part="icon" class="card-image">
|
|
68
75
|
<img src=${this.imageSrc} alt=${this.imageAlt} />
|
|
69
76
|
</div>
|
|
70
77
|
`
|
|
71
78
|
: null}
|
|
72
79
|
|
|
73
|
-
<div class="card-content">
|
|
80
|
+
<div part="content" class="card-content">
|
|
74
81
|
${this.title ? html`<h3>${this.title}</h3>` : null}
|
|
75
82
|
${this.subtitle ? html`<p>${this.subtitle}</p>` : null}
|
|
76
83
|
<slot></slot>
|
|
@@ -140,12 +140,12 @@ Available parts:
|
|
|
140
140
|
The component uses design tokens from the Reliability Design System. All colors, spacing, and typography are inherited from CSS variables.
|
|
141
141
|
|
|
142
142
|
Key tokens used:
|
|
143
|
-
- `--rel-
|
|
143
|
+
- `--rel-bg-*` / `--rel-text-*` / `--rel-border-*` semantic colors
|
|
144
144
|
- `--rel-spacing-*` for spacing
|
|
145
145
|
- `--rel-shadows-*` for shadows
|
|
146
146
|
- `--rel-border-*` for borders
|
|
147
|
-
- Focus outline uses `--rel-
|
|
148
|
-
- Active dot uses `--rel-
|
|
147
|
+
- Focus outline uses `--rel-bg-info`
|
|
148
|
+
- Active dot uses `--rel-bg-brand`
|
|
149
149
|
|
|
150
150
|
## Interaction
|
|
151
151
|
|