@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.
Files changed (145) hide show
  1. package/dist/components/rel-accordion/README.md +132 -0
  2. package/dist/components/rel-accordion/rel-accordion.ts +61 -29
  3. package/dist/components/rel-alert/README.md +141 -0
  4. package/dist/components/rel-alert/rel-alert.ts +110 -67
  5. package/dist/components/rel-avatar/README.md +119 -0
  6. package/dist/components/rel-avatar/rel-avatar.ts +8 -15
  7. package/dist/components/rel-badge/README.md +86 -0
  8. package/dist/components/rel-badge/rel-badge.ts +28 -21
  9. package/dist/components/rel-breadcrumb/README.md +102 -0
  10. package/dist/components/rel-breadcrumb/rel-breadcrumb.ts +24 -18
  11. package/dist/components/rel-button/README.md +130 -0
  12. package/dist/components/rel-button/rel-button.ts +39 -59
  13. package/dist/components/rel-calendar/README.md +109 -0
  14. package/dist/components/rel-calendar/index.ts +1 -0
  15. package/dist/components/rel-calendar/rel-calendar.ts +467 -0
  16. package/dist/components/rel-card/README.md +94 -0
  17. package/dist/components/rel-card/rel-card.ts +21 -11
  18. package/dist/components/rel-cardmedia/README.md +127 -0
  19. package/dist/components/rel-cardmedia/rel-cardmedia.ts +22 -18
  20. package/dist/components/rel-carousel/README.md +166 -0
  21. package/dist/components/rel-carousel/index.ts +1 -0
  22. package/dist/components/rel-carousel/rel-carousel.ts +469 -0
  23. package/dist/components/rel-chart/README.md +286 -0
  24. package/dist/components/rel-chart/index.ts +1 -0
  25. package/dist/components/rel-chart/rel-chart.ts +736 -0
  26. package/dist/components/rel-checkbox/README.md +77 -0
  27. package/dist/components/rel-checkbox/rel-checkbox.ts +36 -45
  28. package/dist/components/rel-chip/README.md +114 -0
  29. package/dist/components/rel-chip/rel-chip.ts +47 -122
  30. package/dist/components/rel-container/README.md +99 -0
  31. package/dist/components/rel-container/rel-container.ts +1 -6
  32. package/dist/components/rel-date-picker/README.md +253 -0
  33. package/dist/components/rel-date-picker/index.ts +1 -0
  34. package/dist/components/rel-date-picker/rel-date-picker.ts +916 -0
  35. package/dist/components/rel-divider/README.md +100 -0
  36. package/dist/components/rel-divider/rel-divider.ts +37 -37
  37. package/dist/components/rel-drawer/README.md +200 -0
  38. package/dist/components/rel-drawer/index.ts +1 -0
  39. package/dist/components/rel-drawer/rel-drawer.ts +621 -0
  40. package/dist/components/rel-kbd/README.md +151 -0
  41. package/dist/components/rel-kbd/rel-kbd.ts +118 -0
  42. package/dist/components/rel-layout/README.md +88 -0
  43. package/dist/components/rel-layout/rel-layout.ts +12 -14
  44. package/dist/components/rel-menu/README.md +151 -0
  45. package/dist/components/rel-menu/rel-menu.ts +18 -10
  46. package/dist/components/rel-menubar/README.md +329 -0
  47. package/dist/components/rel-menubar/index.ts +2 -0
  48. package/dist/components/rel-menubar/rel-menubar-menu.ts +16 -0
  49. package/dist/components/rel-menubar/rel-menubar.ts +576 -0
  50. package/dist/components/rel-nav-menu/README.md +289 -0
  51. package/dist/components/rel-nav-menu/index.ts +3 -0
  52. package/dist/components/rel-nav-menu/rel-nav-menu-item.ts +143 -0
  53. package/dist/components/rel-nav-menu/rel-nav-menu-panel.ts +53 -0
  54. package/dist/components/rel-nav-menu/rel-nav-menu.ts +331 -0
  55. package/dist/components/rel-navbar/README.md +126 -0
  56. package/dist/components/rel-navbar/rel-navbar.ts +91 -0
  57. package/dist/components/rel-otp/README.md +440 -0
  58. package/dist/components/rel-otp/index.ts +1 -0
  59. package/dist/components/rel-otp/rel-otp.ts +504 -0
  60. package/dist/components/rel-pagination/README.md +410 -0
  61. package/dist/components/rel-pagination/index.ts +1 -0
  62. package/dist/components/rel-pagination/rel-pagination.ts +376 -0
  63. package/dist/components/rel-popover/README.md +568 -0
  64. package/dist/components/rel-popover/index.ts +2 -0
  65. package/dist/components/rel-popover/rel-popover-content.ts +55 -0
  66. package/dist/components/rel-popover/rel-popover.ts +327 -0
  67. package/dist/components/rel-progress/README.md +110 -0
  68. package/dist/components/rel-progress/rel-progress.ts +58 -20
  69. package/dist/components/rel-quote-page/README.md +166 -0
  70. package/dist/components/rel-quote-page/rel-quote-page.ts +816 -0
  71. package/dist/components/rel-radio/README.md +120 -0
  72. package/dist/components/rel-radio/rel-radio.ts +41 -73
  73. package/dist/components/rel-resizable/README.md +140 -0
  74. package/dist/components/rel-resizable/index.ts +3 -0
  75. package/dist/components/rel-resizable/rel-resizable-group.ts +374 -0
  76. package/dist/components/rel-resizable/rel-resizable-handle.ts +149 -0
  77. package/dist/components/rel-resizable/rel-resizable-panel.ts +47 -0
  78. package/dist/components/rel-segmented-button/README.md +141 -0
  79. package/dist/components/rel-segmented-button/rel-segmented-button.ts +18 -13
  80. package/dist/components/rel-select/README.md +107 -0
  81. package/dist/components/rel-select/rel-select.ts +14 -14
  82. package/dist/components/rel-sheet/README.md +224 -0
  83. package/dist/components/rel-sheet/rel-sheet.ts +683 -0
  84. package/dist/components/rel-sidebar/README.md +209 -0
  85. package/dist/components/rel-sidebar/rel-sidebar.ts +1158 -0
  86. package/dist/components/rel-slider/README.md +135 -0
  87. package/dist/components/rel-slider/rel-slider.ts +19 -7
  88. package/dist/components/rel-snackbar/README.md +134 -0
  89. package/dist/components/rel-snackbar/rel-snackbar.ts +73 -2
  90. package/dist/components/rel-stepper/README.md +160 -0
  91. package/dist/components/rel-stepper/rel-stepper.ts +29 -8
  92. package/dist/components/rel-switch/README.md +102 -0
  93. package/dist/components/rel-switch/rel-switch.ts +22 -11
  94. package/dist/components/rel-tab/README.md +163 -0
  95. package/dist/components/rel-tab/rel-tab.ts +46 -22
  96. package/dist/components/rel-table/README.md +178 -0
  97. package/dist/components/rel-table/rel-table-body.ts +16 -0
  98. package/dist/components/rel-table/rel-table-caption.ts +22 -0
  99. package/dist/components/rel-table/rel-table-cell.ts +49 -0
  100. package/dist/components/rel-table/rel-table-footer.ts +18 -0
  101. package/dist/components/rel-table/rel-table-head.ts +33 -0
  102. package/dist/components/rel-table/rel-table-header.ts +16 -0
  103. package/dist/components/rel-table/rel-table-row.ts +32 -0
  104. package/dist/components/rel-table/rel-table.ts +47 -0
  105. package/dist/components/rel-textfield/README.md +90 -0
  106. package/dist/components/rel-textfield/rel-textfield.ts +37 -21
  107. package/dist/components/rel-toast/README.md +148 -0
  108. package/dist/components/rel-toast/rel-toast.ts +32 -14
  109. package/dist/components/rel-tooltip/README.md +103 -0
  110. package/dist/components/rel-tooltip/rel-tooltip.ts +9 -9
  111. package/dist/index.d.mts +846 -7
  112. package/dist/index.d.ts +846 -7
  113. package/dist/index.js +10860 -1803
  114. package/dist/index.js.map +1 -1
  115. package/dist/index.mjs +10820 -1809
  116. package/dist/index.mjs.map +1 -1
  117. package/dist/styles/vars.css +293 -183
  118. package/dist/vars-ITL2K3KO.css +294 -0
  119. package/package.json +2 -2
  120. package/dist/components/rel-accordion/rel-accordion.stories.ts +0 -313
  121. package/dist/components/rel-alert/rel-alert.stories.ts +0 -412
  122. package/dist/components/rel-avatar/rel-avatar.stories.ts +0 -327
  123. package/dist/components/rel-badge/rel-badge.stories.ts +0 -350
  124. package/dist/components/rel-breadcrumb/rel-breadcrumb.stories.ts +0 -306
  125. package/dist/components/rel-button/rel-button.stories.ts +0 -356
  126. package/dist/components/rel-card/rel-card.stories.ts +0 -299
  127. package/dist/components/rel-cardmedia/rel-cardmedia.stories.ts +0 -368
  128. package/dist/components/rel-checkbox/rel-checkbox.stories.ts +0 -414
  129. package/dist/components/rel-chip/rel-chip.stories.ts +0 -552
  130. package/dist/components/rel-container/rel-container.stories.ts +0 -239
  131. package/dist/components/rel-divider/rel-divider.stories.ts +0 -229
  132. package/dist/components/rel-layout/rel-layout.stories.ts +0 -713
  133. package/dist/components/rel-menu/rel-menu.stories.ts +0 -910
  134. package/dist/components/rel-progress/rel-progress.stories.ts +0 -817
  135. package/dist/components/rel-radio/rel-radio.stories.ts +0 -1048
  136. package/dist/components/rel-segmented-button/rel-segmented-button.stories.ts +0 -1079
  137. package/dist/components/rel-select/rel-select.stories.ts +0 -1201
  138. package/dist/components/rel-slider/rel-slider.stories.ts +0 -730
  139. package/dist/components/rel-snackbar/rel-snackbar.stories.ts +0 -808
  140. package/dist/components/rel-stepper/rel-stepper.stories.ts +0 -752
  141. package/dist/components/rel-switch/rel-switch.stories.ts +0 -441
  142. package/dist/components/rel-tab/rel-tab.stories.ts +0 -492
  143. package/dist/components/rel-textfield/rel-textfield.stories.ts +0 -710
  144. package/dist/components/rel-toast/rel-toast.stories.ts +0 -394
  145. 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-colors-gray-heading);
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
- /* CHECKED */
60
- .checked .box {
61
- background: var(--rel-colors-gray-heading);
62
- border-color: var(--rel-colors-gray-heading);
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 !important;
89
+ cursor: not-allowed;
95
90
  }
96
91
 
97
92
  .label {
98
- font-size: var(--rel-fontSizes-md);
99
- color: var(--rel-colors-gray-heading);
100
- font-weight: var(--rel-fontWeights-medium);
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-colors-gray-text);
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(new CustomEvent("changed", { detail: this.status }));
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="${className}">
126
+ <div class="wrapper ${this.state} ${this.status}">
134
127
  <label class="row">
135
128
  <input
136
129
  type="checkbox"
137
- @change=${this.toggle}
130
+ @click=${this.toggle}
138
131
  ?disabled=${this.state === "disabled"}
139
132
  />
140
133
 
141
134
  <span class="box">
142
- <!-- CHECK ICON -->
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.44479 14L0.5 7.36383L1.9862 5.70478L6.44479 10.6819L16.0138 0L17.5 1.65904L6.44479 14Z"
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
- <!-- INDETERMINATE ICON -->
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, state } from "lit/decorators.js";
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: string = "Label";
6
+ @property({ type: String }) label = "Label";
7
7
 
8
- @property({ type: String }) tone: "default" | "blue" | "yellow" | "red" | "green" = "default";
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: boolean = false;
15
+ @property({ type: Boolean }) removable = false;
16
+ @property({ type: Boolean }) outline = false;
17
17
 
18
- @property({ type: Boolean }) outline: boolean = false;
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:not(:focus-visible) {
54
- outline: none;
51
+ .chip:focus-visible {
52
+ outline: 2px solid var(--rel-colors-blue-primary, #0091ea);
53
+ outline-offset: 2px;
55
54
  }
56
55
 
57
- .chip:active {
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
- .chip-green:focus {
110
- outline: var(--rel-borders-width-stroke-200) solid var(--rel-colors-green-success);
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: var(--rel-borders-radius-border-radius-500);
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
- background: transparent;
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-size: var(--rel-fontSizes-md);
174
- cursor: pointer;
175
- display: flex;
176
- align-items: center;
108
+ font: inherit;
177
109
  padding: 0;
178
- margin-left: var(--rel-spacing-space-3xs);
110
+ line-height: 1;
179
111
  }
180
112
 
181
113
  .chip-remove:hover {
182
- opacity: 0.6;
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
- <button
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="${this.avatar}" alt="avatar" class="chip-avatar" />`
230
- : ""}
153
+ ? html`<img src=${this.avatar} alt="" class="chip-avatar" />`
154
+ : null}
231
155
  ${this.leadingIcon
232
- ? html`<span class="chip-icon leading">
233
- <slot name="leading-icon">${this.renderIcon(this.leadingIcon)}</slot>
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 trailing">
239
- <slot name="trailing-icon">${this.renderIcon(this.trailingIcon)}</slot>
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
- </button>
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 html`${template.content.cloneNode(true)}`;
184
+ return template.content.cloneNode(true);
260
185
  }
261
186
  }