@reliability-design/web 1.0.2 → 1.0.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.
- package/dist/components/rel-accordion/README.md +132 -0
- package/dist/components/rel-accordion/rel-accordion.ts +61 -29
- package/dist/components/rel-alert/README.md +141 -0
- package/dist/components/rel-alert/rel-alert.ts +110 -67
- package/dist/components/rel-avatar/README.md +119 -0
- package/dist/components/rel-avatar/rel-avatar.ts +8 -15
- package/dist/components/rel-badge/README.md +86 -0
- package/dist/components/rel-badge/rel-badge.ts +28 -21
- package/dist/components/rel-breadcrumb/README.md +102 -0
- package/dist/components/rel-breadcrumb/rel-breadcrumb.ts +24 -18
- package/dist/components/rel-button/README.md +130 -0
- package/dist/components/rel-button/rel-button.ts +39 -59
- package/dist/components/rel-calendar/README.md +109 -0
- package/dist/components/rel-calendar/index.ts +1 -0
- package/dist/components/rel-calendar/rel-calendar.ts +467 -0
- package/dist/components/rel-card/README.md +94 -0
- package/dist/components/rel-card/rel-card.ts +21 -11
- package/dist/components/rel-cardmedia/README.md +127 -0
- package/dist/components/rel-cardmedia/rel-cardmedia.ts +22 -18
- package/dist/components/rel-carousel/README.md +166 -0
- package/dist/components/rel-carousel/index.ts +1 -0
- package/dist/components/rel-carousel/rel-carousel.ts +469 -0
- package/dist/components/rel-chart/README.md +286 -0
- package/dist/components/rel-chart/index.ts +1 -0
- package/dist/components/rel-chart/rel-chart.ts +736 -0
- package/dist/components/rel-checkbox/README.md +77 -0
- package/dist/components/rel-checkbox/rel-checkbox.ts +36 -45
- package/dist/components/rel-chip/README.md +114 -0
- package/dist/components/rel-chip/rel-chip.ts +47 -122
- package/dist/components/rel-container/README.md +99 -0
- package/dist/components/rel-container/rel-container.ts +1 -6
- package/dist/components/rel-date-picker/README.md +253 -0
- package/dist/components/rel-date-picker/index.ts +1 -0
- package/dist/components/rel-date-picker/rel-date-picker.ts +916 -0
- package/dist/components/rel-divider/README.md +100 -0
- package/dist/components/rel-divider/rel-divider.ts +37 -37
- package/dist/components/rel-drawer/README.md +200 -0
- package/dist/components/rel-drawer/index.ts +1 -0
- package/dist/components/rel-drawer/rel-drawer.ts +621 -0
- package/dist/components/rel-kbd/README.md +151 -0
- package/dist/components/rel-kbd/rel-kbd.ts +118 -0
- package/dist/components/rel-layout/README.md +88 -0
- package/dist/components/rel-layout/rel-layout.ts +12 -14
- package/dist/components/rel-menu/README.md +151 -0
- package/dist/components/rel-menu/rel-menu.ts +18 -10
- package/dist/components/rel-menubar/README.md +329 -0
- package/dist/components/rel-menubar/index.ts +2 -0
- package/dist/components/rel-menubar/rel-menubar-menu.ts +16 -0
- package/dist/components/rel-menubar/rel-menubar.ts +576 -0
- package/dist/components/rel-nav-menu/README.md +289 -0
- package/dist/components/rel-nav-menu/index.ts +3 -0
- package/dist/components/rel-nav-menu/rel-nav-menu-item.ts +143 -0
- package/dist/components/rel-nav-menu/rel-nav-menu-panel.ts +53 -0
- package/dist/components/rel-nav-menu/rel-nav-menu.ts +331 -0
- package/dist/components/rel-navbar/README.md +126 -0
- package/dist/components/rel-navbar/rel-navbar.ts +91 -0
- package/dist/components/rel-otp/README.md +440 -0
- package/dist/components/rel-otp/index.ts +1 -0
- package/dist/components/rel-otp/rel-otp.ts +504 -0
- package/dist/components/rel-pagination/README.md +410 -0
- package/dist/components/rel-pagination/index.ts +1 -0
- package/dist/components/rel-pagination/rel-pagination.ts +376 -0
- package/dist/components/rel-popover/README.md +568 -0
- package/dist/components/rel-popover/index.ts +2 -0
- package/dist/components/rel-popover/rel-popover-content.ts +55 -0
- package/dist/components/rel-popover/rel-popover.ts +327 -0
- package/dist/components/rel-progress/README.md +110 -0
- package/dist/components/rel-progress/rel-progress.ts +58 -20
- package/dist/components/rel-quote-page/README.md +166 -0
- package/dist/components/rel-quote-page/rel-quote-page.ts +816 -0
- package/dist/components/rel-radio/README.md +120 -0
- package/dist/components/rel-radio/rel-radio.ts +41 -73
- package/dist/components/rel-resizable/README.md +140 -0
- package/dist/components/rel-resizable/index.ts +3 -0
- package/dist/components/rel-resizable/rel-resizable-group.ts +374 -0
- package/dist/components/rel-resizable/rel-resizable-handle.ts +149 -0
- package/dist/components/rel-resizable/rel-resizable-panel.ts +47 -0
- package/dist/components/rel-segmented-button/README.md +141 -0
- package/dist/components/rel-segmented-button/rel-segmented-button.ts +18 -13
- package/dist/components/rel-select/README.md +107 -0
- package/dist/components/rel-select/rel-select.ts +14 -14
- package/dist/components/rel-sheet/README.md +224 -0
- package/dist/components/rel-sheet/rel-sheet.ts +683 -0
- package/dist/components/rel-sidebar/README.md +209 -0
- package/dist/components/rel-sidebar/rel-sidebar.ts +1158 -0
- package/dist/components/rel-slider/README.md +135 -0
- package/dist/components/rel-slider/rel-slider.ts +19 -7
- package/dist/components/rel-snackbar/README.md +134 -0
- package/dist/components/rel-snackbar/rel-snackbar.ts +73 -2
- package/dist/components/rel-stepper/README.md +160 -0
- package/dist/components/rel-stepper/rel-stepper.ts +29 -8
- package/dist/components/rel-switch/README.md +102 -0
- package/dist/components/rel-switch/rel-switch.ts +22 -11
- package/dist/components/rel-tab/README.md +163 -0
- package/dist/components/rel-tab/rel-tab.ts +46 -22
- package/dist/components/rel-table/README.md +178 -0
- package/dist/components/rel-table/rel-table-body.ts +16 -0
- package/dist/components/rel-table/rel-table-caption.ts +22 -0
- package/dist/components/rel-table/rel-table-cell.ts +49 -0
- package/dist/components/rel-table/rel-table-footer.ts +18 -0
- package/dist/components/rel-table/rel-table-head.ts +33 -0
- package/dist/components/rel-table/rel-table-header.ts +16 -0
- package/dist/components/rel-table/rel-table-row.ts +32 -0
- package/dist/components/rel-table/rel-table.ts +47 -0
- package/dist/components/rel-textfield/README.md +90 -0
- package/dist/components/rel-textfield/rel-textfield.ts +37 -21
- package/dist/components/rel-toast/README.md +148 -0
- package/dist/components/rel-toast/rel-toast.ts +32 -14
- package/dist/components/rel-tooltip/README.md +103 -0
- package/dist/components/rel-tooltip/rel-tooltip.ts +9 -9
- package/dist/index.d.mts +846 -7
- package/dist/index.d.ts +846 -7
- package/dist/index.js +10860 -1803
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +10820 -1809
- package/dist/index.mjs.map +1 -1
- package/dist/styles/vars.css +293 -183
- package/dist/vars-ITL2K3KO.css +294 -0
- package/package.json +2 -2
- package/dist/components/rel-accordion/rel-accordion.stories.ts +0 -313
- package/dist/components/rel-alert/rel-alert.stories.ts +0 -412
- package/dist/components/rel-avatar/rel-avatar.stories.ts +0 -327
- package/dist/components/rel-badge/rel-badge.stories.ts +0 -350
- package/dist/components/rel-breadcrumb/rel-breadcrumb.stories.ts +0 -306
- package/dist/components/rel-button/rel-button.stories.ts +0 -356
- package/dist/components/rel-card/rel-card.stories.ts +0 -299
- package/dist/components/rel-cardmedia/rel-cardmedia.stories.ts +0 -368
- package/dist/components/rel-checkbox/rel-checkbox.stories.ts +0 -414
- package/dist/components/rel-chip/rel-chip.stories.ts +0 -552
- package/dist/components/rel-container/rel-container.stories.ts +0 -239
- package/dist/components/rel-divider/rel-divider.stories.ts +0 -229
- package/dist/components/rel-layout/rel-layout.stories.ts +0 -713
- package/dist/components/rel-menu/rel-menu.stories.ts +0 -910
- package/dist/components/rel-progress/rel-progress.stories.ts +0 -817
- package/dist/components/rel-radio/rel-radio.stories.ts +0 -1048
- package/dist/components/rel-segmented-button/rel-segmented-button.stories.ts +0 -1079
- package/dist/components/rel-select/rel-select.stories.ts +0 -1201
- package/dist/components/rel-slider/rel-slider.stories.ts +0 -730
- package/dist/components/rel-snackbar/rel-snackbar.stories.ts +0 -808
- package/dist/components/rel-stepper/rel-stepper.stories.ts +0 -752
- package/dist/components/rel-switch/rel-switch.stories.ts +0 -441
- package/dist/components/rel-tab/rel-tab.stories.ts +0 -492
- package/dist/components/rel-textfield/rel-textfield.stories.ts +0 -710
- package/dist/components/rel-toast/rel-toast.stories.ts +0 -394
- package/dist/components/rel-tooltip/rel-tooltip.stories.ts +0 -364
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# rel-checkbox
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
A tri-state checkbox component supporting checked, unchecked, and indeterminate states. Includes label and supporting text with built-in error and disabled states for form validation scenarios.
|
|
5
|
+
|
|
6
|
+
## Usage
|
|
7
|
+
```html
|
|
8
|
+
<!-- Basic example -->
|
|
9
|
+
<rel-checkbox label="Accept terms"></rel-checkbox>
|
|
10
|
+
|
|
11
|
+
<!-- Example with common options -->
|
|
12
|
+
<rel-checkbox
|
|
13
|
+
label="Subscribe to newsletter"
|
|
14
|
+
supportingtext="We'll send you weekly updates"
|
|
15
|
+
status="unchecked"
|
|
16
|
+
state="default">
|
|
17
|
+
</rel-checkbox>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## API
|
|
21
|
+
|
|
22
|
+
### Attributes/Properties
|
|
23
|
+
| Name | Type | Default | Description |
|
|
24
|
+
|------|------|---------|-------------|
|
|
25
|
+
| `label` | `string` | `"Label"` | Label text displayed next to the checkbox |
|
|
26
|
+
| `supportingtext` | `string` | `""` | Helper text displayed below the checkbox and label |
|
|
27
|
+
| `state` | `"default" \| "error" \| "disabled"` | `"default"` | Visual and interaction state of the checkbox |
|
|
28
|
+
| `status` | `"unchecked" \| "checked" \| "indeterminate"` | `"unchecked"` | Current checked state of the checkbox |
|
|
29
|
+
|
|
30
|
+
## Events
|
|
31
|
+
| Event | Detail | Description |
|
|
32
|
+
|-------|--------|-------------|
|
|
33
|
+
| `change` | `{ checked: boolean, indeterminate: boolean }` | Fired when checkbox state changes through user interaction |
|
|
34
|
+
|
|
35
|
+
## Slots
|
|
36
|
+
Default slot not used.
|
|
37
|
+
|
|
38
|
+
## CSS Parts
|
|
39
|
+
None exposed.
|
|
40
|
+
|
|
41
|
+
## Tokens / CSS Variables
|
|
42
|
+
|
|
43
|
+
### Semantic Tokens
|
|
44
|
+
- `--rel-fontFamilies-primary` - Font family
|
|
45
|
+
- `--rel-fontSizes-md`, `--rel-fontSizes-sm` - Font sizes for label and supporting text
|
|
46
|
+
- `--rel-fontWeights-medium` - Font weight for label
|
|
47
|
+
|
|
48
|
+
### Color Tokens
|
|
49
|
+
- `--rel-text-heading` - Checkbox border and checked background color
|
|
50
|
+
- `--rel-colors-white` - Checkbox background and checkmark color
|
|
51
|
+
- `--rel-text-primary` - Label text color
|
|
52
|
+
- `--rel-text-placeholder` - Supporting text color
|
|
53
|
+
- `--rel-colors-red-primary` - Error state border and background color
|
|
54
|
+
- `--rel-border-info` - Focus outline color
|
|
55
|
+
|
|
56
|
+
## Accessibility
|
|
57
|
+
- Uses visually hidden native checkbox input for screen reader support
|
|
58
|
+
- Custom visual checkbox with proper focus indicators
|
|
59
|
+
- Focus visible state with outline offset for keyboard users
|
|
60
|
+
- Label click targets the checkbox for larger interaction area
|
|
61
|
+
- Disabled state communicated through opacity reduction and cursor change
|
|
62
|
+
|
|
63
|
+
### Keyboard Interactions
|
|
64
|
+
- `Space` - Toggle checkbox state
|
|
65
|
+
- `Tab` - Move focus to/from checkbox
|
|
66
|
+
|
|
67
|
+
### Focus Behavior
|
|
68
|
+
- Focus outline appears with offset around the custom checkbox box
|
|
69
|
+
- Uses info border color for high contrast
|
|
70
|
+
|
|
71
|
+
## Notes / Edge Cases
|
|
72
|
+
- Clicking cycles through three states in order: unchecked → checked → indeterminate → unchecked (repeating)
|
|
73
|
+
- When `state="disabled"`, click events are blocked and opacity is reduced to 0.55
|
|
74
|
+
- The indeterminate state displays a horizontal line instead of a checkmark
|
|
75
|
+
- In error state, the checkbox border and checked background use error color
|
|
76
|
+
- Supporting text is positioned below with left padding to align with checkbox content
|
|
77
|
+
- Native checkbox input is visually hidden but maintains accessibility features
|
|
@@ -40,75 +40,65 @@ export class RelCheckbox extends LitElement {
|
|
|
40
40
|
width: 18px;
|
|
41
41
|
height: 18px;
|
|
42
42
|
border-radius: 4px;
|
|
43
|
-
border: 2px solid var(--rel-
|
|
44
|
-
background: var(--rel-colors-white);
|
|
43
|
+
border: 2px solid var(--rel-text-heading, #2b2b2b);
|
|
44
|
+
background: var(--rel-colors-white, #fff);
|
|
45
45
|
display: flex;
|
|
46
46
|
align-items: center;
|
|
47
47
|
justify-content: center;
|
|
48
48
|
transition: all 0.2s;
|
|
49
|
+
flex-shrink: 0;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
input:focus-visible + .box {
|
|
53
|
+
outline: 2px solid var(--rel-border-info, #0091ea);
|
|
54
|
+
outline-offset: 2px;
|
|
49
55
|
}
|
|
50
56
|
|
|
51
|
-
/* ICONS FIXED SIZE */
|
|
52
57
|
svg {
|
|
53
58
|
width: 12px;
|
|
54
59
|
height: 12px;
|
|
55
60
|
display: none;
|
|
56
|
-
pointer-events: none;
|
|
57
61
|
}
|
|
58
62
|
|
|
59
|
-
|
|
60
|
-
.
|
|
61
|
-
background: var(--rel-
|
|
62
|
-
border-color: var(--rel-
|
|
63
|
+
.checked .box,
|
|
64
|
+
.indeterminate .box {
|
|
65
|
+
background: var(--rel-text-heading, #2b2b2b);
|
|
66
|
+
border-color: var(--rel-text-heading, #2b2b2b);
|
|
63
67
|
}
|
|
68
|
+
|
|
64
69
|
.checked .check-icon {
|
|
65
70
|
display: block;
|
|
66
71
|
}
|
|
67
72
|
|
|
68
|
-
/* INDETERMINATE */
|
|
69
|
-
.indeterminate .box {
|
|
70
|
-
background: var(--rel-colors-gray-heading);
|
|
71
|
-
border-color: var(--rel-colors-gray-heading);
|
|
72
|
-
}
|
|
73
73
|
.indeterminate .indeterminate-icon {
|
|
74
74
|
display: block;
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
/* ERROR */
|
|
78
77
|
.error .box {
|
|
79
78
|
border-color: var(--rel-colors-red-primary);
|
|
80
79
|
}
|
|
80
|
+
|
|
81
81
|
.error.checked .box,
|
|
82
82
|
.error.indeterminate .box {
|
|
83
83
|
background: var(--rel-colors-red-primary);
|
|
84
84
|
border-color: var(--rel-colors-red-primary);
|
|
85
85
|
}
|
|
86
|
-
.error .label,
|
|
87
|
-
.error .text {
|
|
88
|
-
color: var(--rel-colors-red-primary);
|
|
89
|
-
}
|
|
90
86
|
|
|
91
|
-
/* DISABLED */
|
|
92
87
|
.disabled {
|
|
93
88
|
opacity: 0.55;
|
|
94
|
-
cursor: not-allowed
|
|
89
|
+
cursor: not-allowed;
|
|
95
90
|
}
|
|
96
91
|
|
|
97
92
|
.label {
|
|
98
|
-
font-size: var(--rel-fontSizes-md);
|
|
99
|
-
|
|
100
|
-
|
|
93
|
+
font-size: var(--rel-fontSizes-md, 14px);
|
|
94
|
+
font-weight: var(--rel-fontWeights-medium, 500);
|
|
95
|
+
color: var(--rel-text-primary, #333);
|
|
101
96
|
}
|
|
102
97
|
|
|
103
98
|
.text {
|
|
104
|
-
font-size: var(--rel-fontSizes-sm);
|
|
105
|
-
color: var(--rel-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
/* Focus ring */
|
|
109
|
-
input:focus-visible + .box {
|
|
110
|
-
outline: 2px solid var(--rel-colors-blue-primary);
|
|
111
|
-
outline-offset: 2px;
|
|
99
|
+
font-size: var(--rel-fontSizes-sm, 12px);
|
|
100
|
+
color: var(--rel-text-placeholder, #a9a9a9);
|
|
101
|
+
padding-left: 28px;
|
|
112
102
|
}
|
|
113
103
|
`;
|
|
114
104
|
|
|
@@ -119,35 +109,36 @@ export class RelCheckbox extends LitElement {
|
|
|
119
109
|
else if (this.status === "checked") this.status = "indeterminate";
|
|
120
110
|
else this.status = "unchecked";
|
|
121
111
|
|
|
122
|
-
this.dispatchEvent(
|
|
112
|
+
this.dispatchEvent(
|
|
113
|
+
new CustomEvent("change", {
|
|
114
|
+
detail: {
|
|
115
|
+
checked: this.status === "checked",
|
|
116
|
+
indeterminate: this.status === "indeterminate",
|
|
117
|
+
},
|
|
118
|
+
bubbles: true,
|
|
119
|
+
composed: true,
|
|
120
|
+
})
|
|
121
|
+
);
|
|
123
122
|
}
|
|
124
123
|
|
|
125
124
|
render() {
|
|
126
|
-
const className = `
|
|
127
|
-
wrapper
|
|
128
|
-
${this.state}
|
|
129
|
-
${this.status}
|
|
130
|
-
`;
|
|
131
|
-
|
|
132
125
|
return html`
|
|
133
|
-
<div class="${
|
|
126
|
+
<div class="wrapper ${this.state} ${this.status}">
|
|
134
127
|
<label class="row">
|
|
135
128
|
<input
|
|
136
129
|
type="checkbox"
|
|
137
|
-
@
|
|
130
|
+
@click=${this.toggle}
|
|
138
131
|
?disabled=${this.state === "disabled"}
|
|
139
132
|
/>
|
|
140
133
|
|
|
141
134
|
<span class="box">
|
|
142
|
-
|
|
143
|
-
<svg class="check-icon" viewBox="0 0 18 14" fill="white">
|
|
135
|
+
<svg class="check-icon" viewBox="0 0 18 14" fill="var(--rel-colors-white, #fff)">
|
|
144
136
|
<path
|
|
145
|
-
d="M6.
|
|
137
|
+
d="M6.44 14L0.5 7.36l1.49-1.66L6.44 10.68 16.01 0 17.5 1.66z"
|
|
146
138
|
/>
|
|
147
139
|
</svg>
|
|
148
140
|
|
|
149
|
-
|
|
150
|
-
<svg class="indeterminate-icon" viewBox="0 0 16 2" fill="white">
|
|
141
|
+
<svg class="indeterminate-icon" viewBox="0 0 16 2" fill="var(--rel-colors-white, #fff)">
|
|
151
142
|
<rect width="16" height="2" />
|
|
152
143
|
</svg>
|
|
153
144
|
</span>
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# rel-chip
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
A compact chip component for displaying tags, labels, or selected options. Supports multiple color tones, avatar/icon decorations, outline variants, and removable functionality. Automatically hides when removed via the `removed` reflected attribute.
|
|
5
|
+
|
|
6
|
+
## Usage
|
|
7
|
+
```html
|
|
8
|
+
<!-- Basic chip -->
|
|
9
|
+
<rel-chip label="Active"></rel-chip>
|
|
10
|
+
|
|
11
|
+
<!-- Colored tones -->
|
|
12
|
+
<rel-chip label="Info" tone="blue"></rel-chip>
|
|
13
|
+
<rel-chip label="Warning" tone="yellow"></rel-chip>
|
|
14
|
+
<rel-chip label="Error" tone="red"></rel-chip>
|
|
15
|
+
<rel-chip label="Success" tone="green"></rel-chip>
|
|
16
|
+
|
|
17
|
+
<!-- Outline variant -->
|
|
18
|
+
<rel-chip label="Outline Style" tone="blue" outline></rel-chip>
|
|
19
|
+
|
|
20
|
+
<!-- With avatar -->
|
|
21
|
+
<rel-chip id="avatarChip" label="John Doe" avatar="./user.jpg"></rel-chip>
|
|
22
|
+
|
|
23
|
+
<!-- With leading icon (SVG string via JS) -->
|
|
24
|
+
<rel-chip id="iconChip" label="Tagged"></rel-chip>
|
|
25
|
+
<script>
|
|
26
|
+
const chip = document.getElementById('iconChip');
|
|
27
|
+
chip.leadingIcon = '<svg viewBox="0 0 16 16"><path d="M8 0l2 6h6l-5 4 2 6-5-4-5 4 2-6-5-4h6z"/></svg>';
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<!-- Removable chip -->
|
|
31
|
+
<rel-chip id="removableChip" label="Removable" removable></rel-chip>
|
|
32
|
+
<script>
|
|
33
|
+
const removableChip = document.getElementById('removableChip');
|
|
34
|
+
removableChip.addEventListener('removed', () => {
|
|
35
|
+
console.log('Chip was removed');
|
|
36
|
+
});
|
|
37
|
+
</script>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## API
|
|
41
|
+
|
|
42
|
+
### Attributes/Properties
|
|
43
|
+
| Name | Type | Default | Description |
|
|
44
|
+
|------|------|---------|-------------|
|
|
45
|
+
| `label` | `string` | `"Label"` | Text displayed on the chip |
|
|
46
|
+
| `tone` | `"default" \| "blue" \| "yellow" \| "red" \| "green"` | `"default"` | Color tone variant |
|
|
47
|
+
| `leadingIcon` | `string` | - | SVG or HTML string for leading icon |
|
|
48
|
+
| `trailingIcon` | `string` | - | SVG or HTML string for trailing icon |
|
|
49
|
+
| `avatar` | `string` | - | Image URL for avatar (circular image before label) |
|
|
50
|
+
| `removable` | `boolean` | `false` | Shows a remove button (✕) |
|
|
51
|
+
| `outline` | `boolean` | `false` | Applies outline styling (transparent background) |
|
|
52
|
+
| `removed` | `boolean` (reflected) | `false` | When true, component hides via `:host([removed])` |
|
|
53
|
+
|
|
54
|
+
## Events
|
|
55
|
+
| Event | Detail | Description |
|
|
56
|
+
|-------|--------|-------------|
|
|
57
|
+
| `removed` | None | Fired when the remove button is clicked (sets `removed` to true) |
|
|
58
|
+
|
|
59
|
+
## Slots
|
|
60
|
+
Default slot not used.
|
|
61
|
+
|
|
62
|
+
## CSS Parts
|
|
63
|
+
None exposed.
|
|
64
|
+
|
|
65
|
+
## Tokens / CSS Variables
|
|
66
|
+
|
|
67
|
+
### Semantic Tokens
|
|
68
|
+
- `--rel-fontFamilies-primary` - Font family
|
|
69
|
+
- `--rel-fontSizes-md` - Font size
|
|
70
|
+
- `--rel-fontWeights-medium` - Font weight
|
|
71
|
+
|
|
72
|
+
### Spacing Tokens
|
|
73
|
+
- `--rel-spacing-space-2xs` - Padding and internal gaps
|
|
74
|
+
- `--rel-spacing-space-sm` - Horizontal padding
|
|
75
|
+
- `--rel-spacing-space-3xs` - Remove button margin
|
|
76
|
+
|
|
77
|
+
### Color Tokens (by tone)
|
|
78
|
+
- **default**: `--rel-colors-gray-border` (background), `--rel-colors-black` (text)
|
|
79
|
+
- **blue**: `--rel-colors-blue-tertiary` (background), `--rel-colors-white` (text)
|
|
80
|
+
- **yellow**: `--rel-colors-yellow-pending` (background), `--rel-colors-black` (text)
|
|
81
|
+
- **red**: `--rel-colors-red-secondary` (background), `--rel-colors-white` (text)
|
|
82
|
+
- **green**: `--rel-colors-green-success` (background), `--rel-colors-white` (text)
|
|
83
|
+
|
|
84
|
+
### Border & Shadow Tokens
|
|
85
|
+
- `--rel-borders-radius-border-radius-500` - Border radius (pill shape)
|
|
86
|
+
- `--rel-borders-width-stroke-100` - Border width (used in outline mode)
|
|
87
|
+
- `--rel-shadows-shadow-100` - Hover shadow
|
|
88
|
+
- `--rel-colors-blue-primary` - Focus outline color
|
|
89
|
+
|
|
90
|
+
## Accessibility
|
|
91
|
+
- Uses `role="button"` and `tabindex="0"` on the main chip element
|
|
92
|
+
- `aria-label` set to the chip's label
|
|
93
|
+
- Remove button has proper `aria-label="Remove {label}"`
|
|
94
|
+
- Focus visible states on chip and remove button with distinct outlines
|
|
95
|
+
- Remove button focus uses white outline for contrast against colored backgrounds
|
|
96
|
+
|
|
97
|
+
### Keyboard Interactions
|
|
98
|
+
- `Tab` - Focus the chip (or remove button if present)
|
|
99
|
+
- No built-in activation behavior on Enter/Space (purely informational/decorative)
|
|
100
|
+
|
|
101
|
+
### Focus Behavior
|
|
102
|
+
- Chip focus: 2px blue outline with 2px offset
|
|
103
|
+
- Remove button focus: 2px white outline with 1px offset
|
|
104
|
+
|
|
105
|
+
## Notes / Edge Cases
|
|
106
|
+
- Icons (`leadingIcon`, `trailingIcon`) must be passed as raw HTML/SVG strings via JavaScript (see examples)
|
|
107
|
+
- Icons are injected using `renderIcon()` which creates a template element and clones the content
|
|
108
|
+
- Avatar images are 20px × 20px circular (`border-radius: 50%`, `object-fit: cover`)
|
|
109
|
+
- When `removed` is set to `true`, the component applies `display: none` via `:host([removed])`
|
|
110
|
+
- `removed` is a reflected attribute, meaning it appears in the HTML when true
|
|
111
|
+
- Clicking the remove button stops propagation to prevent triggering chip-level click handlers
|
|
112
|
+
- **Outline mode** removes the background color but keeps the same text color
|
|
113
|
+
- Hover effect applies `filter: brightness(0.92)` and box-shadow
|
|
114
|
+
- The component is `display: inline-block`, so chips flow inline by default
|
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
import { LitElement, html, css } from "lit";
|
|
2
|
-
import { customElement, property
|
|
2
|
+
import { customElement, property } from "lit/decorators.js";
|
|
3
3
|
|
|
4
4
|
@customElement("rel-chip")
|
|
5
5
|
export class RelChip extends LitElement {
|
|
6
|
-
@property({ type: String }) label
|
|
6
|
+
@property({ type: String }) label = "Label";
|
|
7
7
|
|
|
8
|
-
@property({ type: String })
|
|
8
|
+
@property({ type: String })
|
|
9
|
+
tone: "default" | "blue" | "yellow" | "red" | "green" = "default";
|
|
9
10
|
|
|
10
11
|
@property({ type: String }) leadingIcon?: string;
|
|
11
|
-
|
|
12
12
|
@property({ type: String }) trailingIcon?: string;
|
|
13
|
-
|
|
14
13
|
@property({ type: String }) avatar?: string;
|
|
15
14
|
|
|
16
|
-
@property({ type: Boolean }) removable
|
|
15
|
+
@property({ type: Boolean }) removable = false;
|
|
16
|
+
@property({ type: Boolean }) outline = false;
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
@state() private removed: boolean = false;
|
|
18
|
+
/** IMPORTANT: reflected so CSS + Angular can see it */
|
|
19
|
+
@property({ type: Boolean, reflect: true }) removed = false;
|
|
21
20
|
|
|
22
21
|
static styles = css`
|
|
23
22
|
:host {
|
|
@@ -38,123 +37,60 @@ export class RelChip extends LitElement {
|
|
|
38
37
|
padding: var(--rel-spacing-space-2xs) var(--rel-spacing-space-sm);
|
|
39
38
|
gap: var(--rel-spacing-space-2xs);
|
|
40
39
|
cursor: pointer;
|
|
41
|
-
transition: all 0.2s ease-in-out;
|
|
42
40
|
border: var(--rel-borders-width-stroke-100) solid transparent;
|
|
43
41
|
user-select: none;
|
|
44
42
|
white-space: nowrap;
|
|
43
|
+
background: transparent;
|
|
45
44
|
}
|
|
46
45
|
|
|
47
46
|
.chip:hover {
|
|
48
47
|
filter: brightness(0.92);
|
|
49
|
-
transform: translateY(-1px);
|
|
50
48
|
box-shadow: var(--rel-shadows-shadow-100);
|
|
51
49
|
}
|
|
52
50
|
|
|
53
|
-
.chip:focus
|
|
54
|
-
outline:
|
|
51
|
+
.chip:focus-visible {
|
|
52
|
+
outline: 2px solid var(--rel-colors-blue-primary, #0091ea);
|
|
53
|
+
outline-offset: 2px;
|
|
55
54
|
}
|
|
56
55
|
|
|
57
|
-
|
|
58
|
-
transform: scale(0.97) translateY(0);
|
|
59
|
-
box-shadow: none;
|
|
60
|
-
filter: brightness(0.88);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/* Tone Variants - Filled */
|
|
56
|
+
/* TONES */
|
|
64
57
|
.chip-default {
|
|
65
58
|
background: var(--rel-colors-gray-border);
|
|
66
59
|
color: var(--rel-colors-black);
|
|
67
60
|
}
|
|
68
61
|
|
|
69
|
-
.chip-default:focus {
|
|
70
|
-
outline: var(--rel-borders-width-stroke-200) solid var(--rel-colors-gray-primary);
|
|
71
|
-
outline-offset: var(--rel-spacing-space-3xs);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
62
|
.chip-blue {
|
|
75
63
|
background: var(--rel-colors-blue-tertiary);
|
|
76
64
|
color: var(--rel-colors-white);
|
|
77
65
|
}
|
|
78
66
|
|
|
79
|
-
.chip-blue:focus {
|
|
80
|
-
outline: var(--rel-borders-width-stroke-200) solid var(--rel-colors-blue-tertiary);
|
|
81
|
-
outline-offset: var(--rel-spacing-space-3xs);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
67
|
.chip-yellow {
|
|
85
68
|
background: var(--rel-colors-yellow-pending);
|
|
86
69
|
color: var(--rel-colors-black);
|
|
87
70
|
}
|
|
88
71
|
|
|
89
|
-
.chip-yellow:focus {
|
|
90
|
-
outline: var(--rel-borders-width-stroke-200) solid var(--rel-colors-yellow-pending);
|
|
91
|
-
outline-offset: var(--rel-spacing-space-3xs);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
72
|
.chip-red {
|
|
95
73
|
background: var(--rel-colors-red-secondary);
|
|
96
74
|
color: var(--rel-colors-white);
|
|
97
75
|
}
|
|
98
76
|
|
|
99
|
-
.chip-red:focus {
|
|
100
|
-
outline: var(--rel-borders-width-stroke-200) solid var(--rel-colors-red-secondary);
|
|
101
|
-
outline-offset: var(--rel-spacing-space-3xs);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
77
|
.chip-green {
|
|
105
78
|
background: var(--rel-colors-green-success);
|
|
106
79
|
color: var(--rel-colors-white);
|
|
107
80
|
}
|
|
108
81
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
outline-offset: var(--rel-spacing-space-3xs);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/* Outline Variants */
|
|
115
|
-
.chip-outline.chip-default {
|
|
116
|
-
background: transparent;
|
|
117
|
-
border-color: var(--rel-colors-gray-border);
|
|
118
|
-
color: var(--rel-colors-black);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
.chip-outline.chip-blue {
|
|
122
|
-
background: transparent;
|
|
123
|
-
border-color: var(--rel-colors-blue-tertiary);
|
|
124
|
-
color: var(--rel-colors-blue-tertiary);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
.chip-outline.chip-yellow {
|
|
82
|
+
/* OUTLINE */
|
|
83
|
+
.chip-outline {
|
|
128
84
|
background: transparent;
|
|
129
|
-
border-color: var(--rel-colors-yellow-pending);
|
|
130
|
-
color: var(--rel-colors-yellow-pending);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
.chip-outline.chip-red {
|
|
134
|
-
background: transparent;
|
|
135
|
-
border-color: var(--rel-colors-red-secondary);
|
|
136
|
-
color: var(--rel-colors-red-secondary);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
.chip-outline.chip-green {
|
|
140
|
-
background: transparent;
|
|
141
|
-
border-color: var(--rel-colors-green-success);
|
|
142
|
-
color: var(--rel-colors-green-success);
|
|
143
85
|
}
|
|
144
86
|
|
|
145
87
|
.chip-avatar {
|
|
146
88
|
width: 20px;
|
|
147
89
|
height: 20px;
|
|
148
|
-
border-radius:
|
|
90
|
+
border-radius: 50%;
|
|
149
91
|
object-fit: cover;
|
|
150
92
|
}
|
|
151
93
|
|
|
152
|
-
.chip-icon {
|
|
153
|
-
display: flex;
|
|
154
|
-
align-items: center;
|
|
155
|
-
line-height: 0;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
94
|
.chip-icon ::slotted(svg),
|
|
159
95
|
.chip-icon svg {
|
|
160
96
|
width: 16px;
|
|
@@ -162,24 +98,26 @@ export class RelChip extends LitElement {
|
|
|
162
98
|
fill: currentColor;
|
|
163
99
|
}
|
|
164
100
|
|
|
165
|
-
.chip-label {
|
|
166
|
-
line-height: var(--rel-lineHeights-md);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
101
|
.chip-remove {
|
|
170
|
-
|
|
102
|
+
margin-left: var(--rel-spacing-space-3xs);
|
|
103
|
+
cursor: pointer;
|
|
104
|
+
opacity: 0.7;
|
|
105
|
+
background: none;
|
|
171
106
|
border: none;
|
|
172
107
|
color: inherit;
|
|
173
|
-
font
|
|
174
|
-
cursor: pointer;
|
|
175
|
-
display: flex;
|
|
176
|
-
align-items: center;
|
|
108
|
+
font: inherit;
|
|
177
109
|
padding: 0;
|
|
178
|
-
|
|
110
|
+
line-height: 1;
|
|
179
111
|
}
|
|
180
112
|
|
|
181
113
|
.chip-remove:hover {
|
|
182
|
-
opacity:
|
|
114
|
+
opacity: 1;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.chip-remove:focus-visible {
|
|
118
|
+
outline: 2px solid var(--rel-colors-white, #fff);
|
|
119
|
+
outline-offset: 1px;
|
|
120
|
+
border-radius: 2px;
|
|
183
121
|
}
|
|
184
122
|
`;
|
|
185
123
|
|
|
@@ -194,6 +132,7 @@ export class RelChip extends LitElement {
|
|
|
194
132
|
private handleRemove(event: Event) {
|
|
195
133
|
event.stopPropagation();
|
|
196
134
|
this.removed = true;
|
|
135
|
+
|
|
197
136
|
this.dispatchEvent(
|
|
198
137
|
new CustomEvent("removed", {
|
|
199
138
|
bubbles: true,
|
|
@@ -202,60 +141,46 @@ export class RelChip extends LitElement {
|
|
|
202
141
|
);
|
|
203
142
|
}
|
|
204
143
|
|
|
205
|
-
private handleKeyDown(event: KeyboardEvent) {
|
|
206
|
-
if (!this.removable) return;
|
|
207
|
-
|
|
208
|
-
if (event.key === "Backspace" || event.key === "Delete") {
|
|
209
|
-
event.preventDefault();
|
|
210
|
-
this.handleRemove(event);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
144
|
render() {
|
|
215
|
-
if (this.removed) {
|
|
216
|
-
return null;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
145
|
return html`
|
|
220
|
-
<
|
|
146
|
+
<span
|
|
221
147
|
class="${this.classes}"
|
|
222
|
-
type="button"
|
|
223
148
|
role="button"
|
|
224
|
-
aria-label="${this.label}"
|
|
225
|
-
@keydown=${this.handleKeyDown}
|
|
226
149
|
tabindex="0"
|
|
150
|
+
aria-label="${this.label}"
|
|
227
151
|
>
|
|
228
152
|
${this.avatar
|
|
229
|
-
? html`<img src
|
|
230
|
-
:
|
|
153
|
+
? html`<img src=${this.avatar} alt="" class="chip-avatar" />`
|
|
154
|
+
: null}
|
|
231
155
|
${this.leadingIcon
|
|
232
|
-
? html`<span class="chip-icon
|
|
233
|
-
|
|
156
|
+
? html`<span class="chip-icon">
|
|
157
|
+
${this.renderIcon(this.leadingIcon)}
|
|
234
158
|
</span>`
|
|
235
|
-
:
|
|
159
|
+
: null}
|
|
160
|
+
|
|
236
161
|
<span class="chip-label">${this.label}</span>
|
|
162
|
+
|
|
237
163
|
${this.trailingIcon
|
|
238
|
-
? html`<span class="chip-icon
|
|
239
|
-
|
|
164
|
+
? html`<span class="chip-icon">
|
|
165
|
+
${this.renderIcon(this.trailingIcon)}
|
|
240
166
|
</span>`
|
|
241
|
-
:
|
|
167
|
+
: null}
|
|
242
168
|
${this.removable
|
|
243
169
|
? html`<button
|
|
244
|
-
type="button"
|
|
245
170
|
class="chip-remove"
|
|
171
|
+
aria-label="Remove ${this.label}"
|
|
246
172
|
@click=${this.handleRemove}
|
|
247
|
-
aria-label="Remove chip"
|
|
248
173
|
>
|
|
249
|
-
|
|
174
|
+
✕
|
|
250
175
|
</button>`
|
|
251
|
-
:
|
|
252
|
-
</
|
|
176
|
+
: null}
|
|
177
|
+
</span>
|
|
253
178
|
`;
|
|
254
179
|
}
|
|
255
180
|
|
|
256
181
|
private renderIcon(iconString: string) {
|
|
257
182
|
const template = document.createElement("template");
|
|
258
183
|
template.innerHTML = iconString.trim();
|
|
259
|
-
return
|
|
184
|
+
return template.content.cloneNode(true);
|
|
260
185
|
}
|
|
261
186
|
}
|