@reliability-design/web 1.4.8 → 1.4.10

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 (54) hide show
  1. package/CHANGELOG.md +214 -0
  2. package/custom-elements.json +18600 -0
  3. package/dist/components/rel-accordion/README.md +9 -2
  4. package/dist/components/rel-alert/README.md +5 -8
  5. package/dist/components/rel-autocomplete/README.md +209 -208
  6. package/dist/components/rel-avatar/README.md +228 -118
  7. package/dist/components/rel-breadcrumb/README.md +1 -0
  8. package/dist/components/rel-button/README.md +9 -9
  9. package/dist/components/rel-calendar/README.md +111 -109
  10. package/dist/components/rel-cardmedia/README.md +1 -1
  11. package/dist/components/rel-carousel/README.md +187 -186
  12. package/dist/components/rel-checkbox/README.md +159 -146
  13. package/dist/components/rel-chip/README.md +141 -138
  14. package/dist/components/rel-container/README.md +1 -1
  15. package/dist/components/rel-date-picker/README.md +221 -200
  16. package/dist/components/rel-drawer/README.md +4 -4
  17. package/dist/components/rel-kbd/README.md +188 -141
  18. package/dist/components/rel-layout/README.md +34 -34
  19. package/dist/components/rel-menu/README.md +17 -10
  20. package/dist/components/rel-menubar/README.md +218 -218
  21. package/dist/components/rel-otp/README.md +4 -8
  22. package/dist/components/rel-pagination/README.md +141 -100
  23. package/dist/components/rel-popover/README.md +220 -203
  24. package/dist/components/rel-radio/README.md +142 -131
  25. package/dist/components/rel-range-picker/README.md +194 -165
  26. package/dist/components/rel-resizable/README.md +220 -199
  27. package/dist/components/rel-segmented-button/README.md +158 -156
  28. package/dist/components/rel-select/README.md +22 -16
  29. package/dist/components/rel-sheet/README.md +3 -2
  30. package/dist/components/rel-signature-pad/README.md +161 -0
  31. package/dist/components/rel-slider/README.md +140 -131
  32. package/dist/components/rel-snackbar/README.md +170 -168
  33. package/dist/components/rel-split-button/README.md +129 -0
  34. package/dist/components/rel-stepper/README.md +171 -162
  35. package/dist/components/rel-switch/README.md +122 -117
  36. package/dist/components/rel-tab/README.md +184 -173
  37. package/dist/components/rel-textfield/README.md +23 -30
  38. package/dist/components/rel-time-picker/README.md +188 -164
  39. package/dist/components/rel-toast/README.md +20 -11
  40. package/dist/components/rel-tooltip/README.md +5 -4
  41. package/dist/components/rel-tree/README.md +157 -0
  42. package/dist/components/rel-upload/README.md +8 -5
  43. package/dist/index.d.mts +1698 -607
  44. package/dist/index.d.ts +1698 -607
  45. package/dist/index.js +12276 -6347
  46. package/dist/index.js.map +1 -1
  47. package/dist/index.mjs +12218 -6296
  48. package/dist/index.mjs.map +1 -1
  49. package/dist/styles/motion.css +31 -0
  50. package/dist/styles/motion.tokens.json +38 -0
  51. package/dist/styles/vars.css +88 -64
  52. package/dist/{vars-DXX6QOAG.css → vars-E22LYFMV.css} +88 -64
  53. package/package.json +60 -37
  54. package/dist/styles/focus-ring.ts +0 -84
@@ -1,118 +1,228 @@
1
- # rel-avatar
2
-
3
- `<rel-avatar>` is the circular identity mark of the Figma "Avatar" component: a 20–40px disc that shows a photo (`type="image"`), uppercase initials (`type="text"`) or a slotted icon (`type="icon"`), in a solid `fill`, a neutral `subtle` or a bordered `outline` variant. Use it wherever a person, team or account needs a compact visual identity — user menus, comment threads, assignee columns, stacked avatar groups. It is purely presentational: it takes no focus and emits no events, so wrap it in a button or link when it should be clickable, and overlay a `rel-badge` when it needs a status or count.
4
-
5
- ## Usage
6
-
7
- ```html
8
- <!-- Image avatar (always pass a meaningful alt) -->
9
- <rel-avatar type="image" src="./user-photo.jpg" alt="Priya Natarajan"></rel-avatar>
10
-
11
- <!-- Initials -->
12
- <rel-avatar type="text" text="PN"></rel-avatar>
13
-
14
- <!-- Slotted icon -->
15
- <rel-avatar type="icon">
16
- <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
17
- <path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/>
18
- </svg>
19
- </rel-avatar>
20
-
21
- <!-- Sizes: xs 20px, sm 24px, md 32px (default), lg 40px -->
22
- <rel-avatar type="text" text="XS" size="extra-small"></rel-avatar>
23
- <rel-avatar type="text" text="SM" size="small"></rel-avatar>
24
- <rel-avatar type="text" text="MD" size="medium"></rel-avatar>
25
- <rel-avatar type="text" text="LG" size="large"></rel-avatar>
26
-
27
- <!-- Variants -->
28
- <rel-avatar type="text" text="AA" variant="fill"></rel-avatar>
29
- <rel-avatar type="text" text="AA" variant="subtle"></rel-avatar>
30
- <rel-avatar type="text" text="AA" variant="outline"></rel-avatar>
31
-
32
- <!-- Inline colour overrides (any CSS colour) -->
33
- <rel-avatar type="text" text="JD" bg="#1d4ed8" color="#ffffff"></rel-avatar>
34
-
35
- <!-- Stacked group -->
36
- <div style="display: flex; padding-left: 8px;">
37
- <rel-avatar type="text" text="A" style="margin-left: -8px;"></rel-avatar>
38
- <rel-avatar type="text" text="B" style="margin-left: -8px;"></rel-avatar>
39
- <rel-avatar type="text" text="C" style="margin-left: -8px;"></rel-avatar>
40
- </div>
41
- ```
42
-
43
- <!-- readme-gen:start -->
44
-
45
- <!-- Generated from rel-avatar.ts — do not edit; run readme-generate.mjs -->
46
-
47
- ## API
48
-
49
- ### Attributes / Properties
50
-
51
- | Property | Attribute | Type | Default | Description |
52
- | --- | --- | --- | --- | --- |
53
- | `size` | `size` | `"large" \| "medium" \| "small" \| "extra-small" \| "lg" \| "md" \| "sm" \| "xs"` | `"medium"` | Diameter step: `large` 40px, `medium` 32px, `small` 24px, `extra-small` 20px; each binds the matching body-*-semibold text role for initials. `lg` / `md` / `sm` / `xs` are alternative spellings and stay supported — they are normalised to the full words, not deprecated. Reflected. |
54
- | `type` | `type` | `"image" \| "text" \| "icon"` | `"image"` | What is rendered inside the circle: `image` shows `src`, `text` shows the `text` initials, `icon` shows the default slot. Reflected. |
55
- | `variant` | `variant` | `"fill" \| "subtle" \| "outline"` | `"fill"` | Fill style: `fill` = solid inverse background with light text, `subtle` = elevated neutral background, `outline` = transparent with a 1px border. Reflected. |
56
- | `src` | `src` | `string` | `""` | Image URL for `type="image"`; when empty nothing is rendered inside the circle (there is no fallback to initials). |
57
- | `text` | `text` | `string` | `""` | Initials shown for `type="text"`; rendered uppercase via `text-transform`. |
58
- | `alt` | `alt` | `string` | `"Avatar"` | Alt text of the `<img>` for `type="image"`; the default is the generic word "Avatar", so pass the person's name. |
59
- | `bg` | `bg` | `string` | `""` | Any CSS colour applied inline as `background-color` on the circle, overriding the variant background. |
60
- | `color` | `color` | `string` | `""` | Any CSS colour applied inline as `color` on the circle (initials / icon), overriding the variant text colour. |
61
-
62
- ## Events
63
-
64
- | Event | Detail | Bubbles / composed | Description |
65
- | --- | --- | --- | --- |
66
- | — | — | — | This element emits no custom events. |
67
-
68
- ## Slots
69
-
70
- | Slot | Description |
71
- | --- | --- |
72
- | (default) | Icon content rendered when `type="icon"` (typically an inline SVG, sized 20 / 18 / 16 / 12px by `size`) |
73
-
74
- ## CSS Parts
75
-
76
- | Part | Description |
77
- | --- | --- |
78
- | `base` | The circular wrapper that carries the size, variant and inline `bg` / `color` overrides |
79
- | `icon` | The `<img>` (`type="image"`) or the icon wrapper span around the slot (`type="icon"`) |
80
- | `label` | The `<span>` holding the initials when `type="text"` |
81
-
82
- ## Tokens / CSS Variables
83
-
84
- ### Component hooks
85
-
86
- Set these on the host (or an ancestor) to customise the element without touching design tokens.
87
-
88
- | Custom property | Default | Description |
89
- | --- | --- | --- |
90
- | `--rel-avatar-bg-fill` | `var(--rel-bg-neutral-inverse-2)` | Background colour of the `fill` variant |
91
- | `--rel-avatar-bg-outline` | `var(--rel-bg-neutral)` | Background colour of the `outline` variant; defaults to --rel-bg-neutral |
92
- | `--rel-avatar-bg-subtle` | `var(--rel-bg-neutral-elevated-1)` | Background colour of the `subtle` variant |
93
- | `--rel-avatar-border-outline` | `var(--rel-border-default)` | 1px border colour of the `outline` variant |
94
- | `--rel-avatar-color-fill` | `var(--rel-text-inverse)` | Text / icon colour of the `fill` variant |
95
- | `--rel-avatar-color-outline` | `var(--rel-text-default)` | Text / icon colour of the `outline` variant |
96
- | `--rel-avatar-color-subtle` | `var(--rel-text-default)` | Text / icon colour of the `subtle` variant |
97
- | `--rel-avatar-font-size` | `var(--_rel-avatar-font-size)` | Overrides the initials' font-size, for use alongside `--rel-avatar-size`; defaults to the preset's text role |
98
- | `--rel-avatar-icon-size` | `var(--_rel-avatar-icon-size)` | Overrides the slotted icon's size; defaults to the preset ramp (20 / 18 / 16 / 12px) |
99
- | `--rel-avatar-size` | `var(--_rel-avatar-size)` | Overrides the circle's width/height for sizes between (or below) the `size` presets; defaults to the preset's diameter |
100
-
101
- <!-- readme-gen:end -->
102
-
103
- ## Accessibility
104
-
105
- - The host has no ARIA role and no keyboard handling, and it is never focusable. Put it inside a `<button>` or `<a>` when it should be interactive and give that element the accessible name.
106
- - `type="image"` renders a real `<img>` whose alt text comes from the `alt` prop. The default is the generic word "Avatar" — pass the person's name, or an empty string when the avatar sits next to visible text with the same name.
107
- - `type="text"` renders the initials as plain text in the `label` part, so screen readers read the letters ("P N"). If the initials alone are meaningless, add `aria-hidden="true"` and keep the full name in nearby text.
108
- - `type="icon"` slots your SVG unchanged; add `aria-hidden="true"` to decorative icons or a `<title>` to meaningful ones.
109
- - The three variants differ only by colour; every colour used has a dark-mode value in `vars.css`, so no extra theming is needed.
110
-
111
- ## Notes / Edge Cases
112
-
113
- - The disc is `border-radius: 50%` with `overflow: hidden`; images use `object-fit: cover`, so non-square sources are centre-cropped rather than stretched.
114
- - `type="image"` with an empty `src` renders an empty circle — there is no automatic fallback to initials. Switch `type` yourself when the photo is missing.
115
- - Every variant keeps a 1px border (`--rel-stroke-sm`); `fill` and `subtle` make it transparent so the outer size is identical across variants.
116
- - `bg` and `color` are written as inline styles on the `base` part, so they win over both the `--rel-avatar-*` hooks and the variant tokens.
117
- - Initials are forced uppercase and `user-select: none`. `size`, `type` and `variant` are reflected, so `rel-avatar[size="large"]` works as a selector. Because `lg` / `md` / `sm` / `xs` are normalised to the full words before reflection, the selector matches whichever spelling was written.
118
- - The `icon` part name is shared by the `<img>` (`type="image"`) and the slot wrapper (`type="icon"`); `::part(icon)` matches whichever one is rendered.
1
+ # rel-avatar
2
+
3
+ `<rel-avatar>` is the circular identity mark of the Figma "Avatar" component: a 20–40px disc that shows a photo (`type="image"`), uppercase initials (`type="text"`) or a slotted icon (`type="icon"`), in a solid `fill`, a neutral `subtle` or a bordered `outline` variant. Use it wherever a person, team or account needs a compact visual identity — user menus, comment threads, assignee columns, stacked avatar groups. It is purely presentational: it takes no focus and emits no events, so wrap it in a button or link when it should be clickable, and overlay a `rel-badge` when it needs a status or count.
4
+
5
+ ## Usage
6
+
7
+ ```html
8
+ <!-- Image avatar (always pass a meaningful alt) -->
9
+ <rel-avatar type="image" src="./user-photo.jpg" alt="Priya Natarajan"></rel-avatar>
10
+
11
+ <!-- Initials -->
12
+ <rel-avatar type="text" text="PN"></rel-avatar>
13
+
14
+ <!-- Slotted icon -->
15
+ <rel-avatar type="icon">
16
+ <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
17
+ <path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/>
18
+ </svg>
19
+ </rel-avatar>
20
+
21
+ <!-- Sizes: xs 20px, sm 24px, md 32px (default), lg 40px -->
22
+ <rel-avatar type="text" text="XS" size="extra-small"></rel-avatar>
23
+ <rel-avatar type="text" text="SM" size="small"></rel-avatar>
24
+ <rel-avatar type="text" text="MD" size="medium"></rel-avatar>
25
+ <rel-avatar type="text" text="LG" size="large"></rel-avatar>
26
+
27
+ <!-- Variants -->
28
+ <rel-avatar type="text" text="AA" variant="fill"></rel-avatar>
29
+ <rel-avatar type="text" text="AA" variant="subtle"></rel-avatar>
30
+ <rel-avatar type="text" text="AA" variant="outline"></rel-avatar>
31
+
32
+ <!-- Inline colour overrides (any CSS colour) -->
33
+ <rel-avatar type="text" text="JD" bg="#1d4ed8" color="#ffffff"></rel-avatar>
34
+
35
+ <!-- New in 1.5.0. Icon by name instead of a slotted SVG (Figma "Icon" swap) -->
36
+ <rel-avatar type="icon" icon="person" variant="subtle"></rel-avatar>
37
+
38
+ <!-- New in 1.5.0. Status badge (Figma "Show Badge"): a green dot, or an icon disc -->
39
+ <rel-avatar type="image" src="./user-photo.jpg" alt="Priya Natarajan" badge="dot" badge-label="Online"></rel-avatar>
40
+ <rel-avatar type="text" text="PN" badge="icon" badge-icon="edit-square" badge-label="Can edit"></rel-avatar>
41
+
42
+ <!-- New in 1.5.0. Ring (Figma "Show Ring"): separates avatars that overlap -->
43
+ <rel-avatar type="text" text="AB" ring></rel-avatar>
44
+ ```
45
+
46
+ <!-- @unreleased-begin 1.5.0 -->
47
+ ### Avatar group
48
+
49
+ ```html
50
+ <!-- New in 1.5.0. <rel-avatar-group> (Figma "Avatar Group"): overlapping avatars with a "+N" circle.
51
+ The group sets size and ring on every avatar; max hides the rest and counts them. -->
52
+ <rel-avatar-group size="medium" max="3" label="Project members">
53
+ <rel-avatar type="image" src="./priya.jpg" alt="Priya Natarajan"></rel-avatar>
54
+ <rel-avatar type="text" text="JD"></rel-avatar>
55
+ <rel-avatar type="text" text="MK"></rel-avatar>
56
+ <rel-avatar type="text" text="LS"></rel-avatar>
57
+ <rel-avatar type="text" text="TO"></rel-avatar>
58
+ </rel-avatar-group>
59
+
60
+ <!-- Only some people loaded: total counts everyone else -->
61
+ <rel-avatar-group total="57">
62
+ <rel-avatar type="text" text="AB"></rel-avatar>
63
+ <rel-avatar type="text" text="CD"></rel-avatar>
64
+ <rel-avatar type="text" text="EF"></rel-avatar>
65
+ </rel-avatar-group>
66
+ ```
67
+
68
+ `<rel-avatar-group>` (new in 1.5.0) lays its slotted `<rel-avatar>` elements in a row, each overlapping the previous one by a quarter of the diameter (Figma's 10 / 8 / 6 / 4px), later ones on top. It gives every avatar its `size` and turns their `ring` on. Avatars beyond `max` are hidden and counted, with anyone beyond the slotted avatars when `total` is larger, in a "+N" circle: the fill style, the same text role as the initials, and its own ring.
69
+ <!-- @unreleased-end -->
70
+
71
+ <!-- readme-gen:start -->
72
+
73
+ <!-- Generated from rel-avatar.ts — do not edit; run readme-generate.mjs -->
74
+
75
+ ## Elements
76
+
77
+ | Element | Class | Source |
78
+ | --- | --- | --- |
79
+ | `<rel-avatar>` | `RelAvatar` | `rel-avatar.ts` |
80
+
81
+ <!-- @unreleased-begin 1.5.0 -->
82
+ | Element | Class | Source |
83
+ | --- | --- | --- |
84
+ | `<rel-avatar-group>` | `RelAvatarGroup` | `rel-avatar-group.ts` |
85
+ <!-- @unreleased-end -->
86
+
87
+ ## API
88
+
89
+ ### `<rel-avatar>`
90
+
91
+ #### Attributes / Properties
92
+
93
+ | Property | Attribute | Type | Default | Description |
94
+ | --- | --- | --- | --- | --- |
95
+ | `size` | `size` | `"large" \| "medium" \| "small" \| "extra-small" \| "lg" \| "md" \| "sm" \| "xs"` | `"medium"` | Diameter step: `large` 40px, `medium` 32px, `small` 24px, `extra-small` 20px; each binds the matching body-*-semibold text role for initials. `lg` / `md` / `sm` / `xs` are alternative spellings and stay supported — they are normalised to the full words, not deprecated. Reflected. |
96
+ | `type` | `type` | `"image" \| "text" \| "icon"` | `"image"` | What is rendered inside the circle: `image` shows `src`, `text` shows the `text` initials, `icon` shows the default slot. Reflected. |
97
+ | `variant` | `variant` | `"fill" \| "subtle" \| "outline"` | `"fill"` | Fill style: `fill` = solid inverse background with light text, `subtle` = elevated neutral background, `outline` = transparent with a 1px border. Reflected. |
98
+ | `src` | `src` | `string` | `""` | Image URL for `type="image"`; when empty nothing is rendered inside the circle (there is no fallback to initials). |
99
+ | `text` | `text` | `string` | `""` | Initials shown for `type="text"`; rendered uppercase via `text-transform`. |
100
+ | `alt` | `alt` | `string` | `"Avatar"` | Alt text of the `<img>` for `type="image"`; the default is the generic word "Avatar", so pass the person's name. |
101
+ | `bg` | `bg` | `string` | `""` | Any CSS colour applied inline as `background-color` on the circle, overriding the variant background. |
102
+ | `color` | `color` | `string` | `""` | Any CSS colour applied inline as `color` on the circle (initials / icon), overriding the variant text colour. |
103
+ | `icon` | `icon` | `string` | `""` | New in 1.5.0. rel-icon name shown for `type="icon"` (Figma's "Icon" swap, e.g. `person`), as an alternative to slotting an SVG. When set it replaces the slot. |
104
+ | `ring` | `ring` | `boolean` | `false` | New in 1.5.0. Figma "Show Ring": a 2px ring in `--rel-border-inverse` just outside the circle, which separates overlapping avatars. It does not change the avatar's size. Reflected. |
105
+ | `badge` | `badge` | `"" \| "dot" \| "icon"` | `""` | New in 1.5.0. Figma "Show Badge": a status badge on the bottom-right edge with a 1px `--rel-border-inverse` edge. `dot` is a `--rel-bg-success` disc; `icon` is a `--rel-bg-neutral-elevated-2` disc holding `badge-icon`. 12 / 10 / 8 / 6px for large / medium / small / extra-small. Empty (the default) renders none. |
106
+ | `badgeIcon` | `badge-icon` | `string` | `"edit-square"` | New in 1.5.0. rel-icon name inside a `badge="icon"` badge. |
107
+ | `badgeLabel` | `badge-label` | `string` | `""` | New in 1.5.0. What the badge means, for screen readers (e.g. "Online"). Without it the badge is decorative and hidden from assistive technology, because a dot conveys its meaning by colour alone. |
108
+
109
+ ### Events
110
+
111
+ | Event | Detail | Bubbles / composed | Description |
112
+ | --- | --- | --- | --- |
113
+ | — | — | — | This element emits no custom events. |
114
+
115
+ ### Slots
116
+
117
+ | Slot | Description |
118
+ | --- | --- |
119
+ | (default) | Icon content rendered when `type="icon"` (typically an inline SVG, sized 20 / 18 / 16 / 12px by `size`); not rendered when the `icon` attribute is set |
120
+
121
+ ### CSS Parts
122
+
123
+ | Part | Description |
124
+ | --- | --- |
125
+ | `base` | The circular wrapper that carries the size, variant and inline `bg` / `color` overrides |
126
+ | `icon` | The `<img>` (`type="image"`) or the icon wrapper span around the slot (`type="icon"`) |
127
+ | `label` | The `<span>` holding the initials when `type="text"` |
128
+ | `badge` | The status badge on the bottom-right edge, rendered when `badge` is set (new in 1.5.0) |
129
+
130
+ ### Tokens / CSS Variables
131
+
132
+ #### Component hooks
133
+
134
+ Set these on the host (or an ancestor) to customise the element without touching design tokens.
135
+
136
+ | Custom property | Default | Description |
137
+ | --- | --- | --- |
138
+ | `--rel-avatar-badge-bg` | `var(--rel-bg-success)` | Fill of the `badge`; defaults to `--rel-bg-success` for `dot` and `--rel-bg-neutral-elevated-2` for `icon` (new in 1.5.0) |
139
+ | `--rel-avatar-bg-fill` | `var(--rel-bg-neutral-inverse-2)` | Background colour of the `fill` variant |
140
+ | `--rel-avatar-bg-outline` | `var(--rel-bg-neutral)` | Background colour of the `outline` variant; defaults to --rel-bg-neutral |
141
+ | `--rel-avatar-bg-subtle` | `var(--rel-bg-neutral-elevated-1)` | Background colour of the `subtle` variant |
142
+ | `--rel-avatar-border-outline` | `var(--rel-border-default)` | 1px border colour of the `outline` variant |
143
+ | `--rel-avatar-color-fill` | `var(--rel-text-inverse)` | Text / icon colour of the `fill` variant |
144
+ | `--rel-avatar-color-outline` | `var(--rel-text-default)` | Text / icon colour of the `outline` variant |
145
+ | `--rel-avatar-color-subtle` | `var(--rel-text-default)` | Text / icon colour of the `subtle` variant |
146
+ | `--rel-avatar-font-size` | `var(--_rel-avatar-font-size)` | Overrides the initials' font-size, for use alongside `--rel-avatar-size`; defaults to the preset's text role |
147
+ | `--rel-avatar-icon-size` | `var(--_rel-avatar-icon-size)` | Overrides the slotted icon's size; defaults to the preset ramp (20 / 18 / 16 / 12px) |
148
+ | `--rel-avatar-ring-color` | `var(--rel-border-inverse)` | Colour of the `ring`; defaults to `--rel-border-inverse` (new in 1.5.0) |
149
+ | `--rel-avatar-size` | `var(--_rel-avatar-size)` | Overrides the circle's width/height for sizes between (or below) the `size` presets; defaults to the preset's diameter |
150
+
151
+ <!-- @unreleased-begin 1.5.0 -->
152
+ ### `<rel-avatar-group>`
153
+
154
+ #### Attributes / Properties
155
+
156
+ | Property | Attribute | Type | Default | Description |
157
+ | --- | --- | --- | --- | --- |
158
+ | `size` | `size` | `"large" \| "medium" \| "small" \| "extra-small" \| "lg" \| "md" \| "sm" \| "xs"` | `"medium"` | Diameter step given to every avatar in the group and to the "+N" circle: `large` 40px, `medium` 32px, `small` 24px, `extra-small` 20px. `lg` / `md` / `sm` / `xs` are accepted and normalised to the full words. Reflected. |
159
+ | `max` | `max` | `number` | `0` | Most avatars to show; the rest are hidden and counted in the "+N" circle. `0` (the default) shows them all. |
160
+ | `total` | `total` | `number` | `0` | The full number of people when only some avatars are slotted (e.g. 3 slotted of 57). The "+N" circle then counts everyone not shown. `0` (the default) counts the slotted avatars only. |
161
+ | `label` | `label` | `string` | `""` | Accessible name of the group (e.g. "Project members"). No default: without it the group has no name. |
162
+ | `overflowLabel` | `overflow-label` | `string` | `"{n} more"` | Accessible name of the "+N" circle; `{n}` is replaced by the count. |
163
+
164
+ #### Public fields / accessors
165
+
166
+ | Name | Type | Description |
167
+ | --- | --- | --- |
168
+ | `overflowCount` | `number` | People counted in the "+N" circle. |
169
+
170
+ ### Events
171
+
172
+ | Event | Detail | Bubbles / composed | Description |
173
+ | --- | --- | --- | --- |
174
+ | — | — | — | This element emits no custom events. |
175
+
176
+ ### Slots
177
+
178
+ | Slot | Description |
179
+ | --- | --- |
180
+ | (default) | The `rel-avatar` elements, in display order |
181
+
182
+ ### CSS Parts
183
+
184
+ | Part | Description |
185
+ | --- | --- |
186
+ | `base` | The `role="group"` row holding the avatars and the overflow circle |
187
+ | `overflow` | The "+N" circle (a `rel-avatar` of `type="text"`, `variant="fill"`) shown when people are not displayed |
188
+
189
+ ### Tokens / CSS Variables
190
+
191
+ #### Component hooks
192
+
193
+ Set these on the host (or an ancestor) to customise the element without touching design tokens.
194
+
195
+ | Custom property | Default | Description |
196
+ | --- | --- | --- |
197
+ | `--rel-avatar-group-overlap` | `var(--_rel-avatar-group-overlap)` | How far each avatar overlaps the previous one (a positive length); defaults to Figma's 10 / 8 / 6 / 4px for large / medium / small / extra-small |
198
+ <!-- @unreleased-end -->
199
+
200
+ <!-- readme-gen:end -->
201
+
202
+ ## Accessibility
203
+
204
+ - The host has no ARIA role and no keyboard handling, and it is never focusable. Put it inside a `<button>` or `<a>` when it should be interactive and give that element the accessible name.
205
+ - `type="image"` renders a real `<img>` whose alt text comes from the `alt` prop. The default is the generic word "Avatar" — pass the person's name, or an empty string when the avatar sits next to visible text with the same name.
206
+ - `type="text"` renders the initials as plain text in the `label` part, so screen readers read the letters ("P N"). If the initials alone are meaningless, add `aria-hidden="true"` and keep the full name in nearby text.
207
+ - `type="icon"` slots your SVG unchanged; add `aria-hidden="true"` to decorative icons or a `<title>` to meaningful ones. The `icon` attribute (new in 1.5.0) renders a decorative `rel-icon`, hidden from assistive technology.
208
+ - The badge (new in 1.5.0) shows a status by colour, or by a tiny icon, so it is not readable by itself. Set `badge-label` ("Online", "Away") and it is read right after the avatar's own name. Without `badge-label` the badge is hidden from assistive technology: say the status in nearby text instead.
209
+ - The ring and the badge edge use `--rel-border-inverse`, the page-colour edge Figma draws. In forced-colours mode the badge is drawn in `CanvasText`, so a status dot stays visible.
210
+ - The three variants differ only by colour; every colour used has a dark-mode value in `vars.css`, so no extra theming is needed.
211
+ <!-- @unreleased-begin 1.5.0 -->
212
+ - `<rel-avatar-group>` is a `role="group"` named by `label`; give it one ("Project members") so the list of names has context. Each avatar keeps its own name (image `alt`, initials). The "+N" circle is a `role="img"` named by `overflow-label` (default "{n} more", e.g. "54 more") with the exact count, even when it shows "99+". Hidden avatars are `display: none`, so they are not read. The group takes no focus and has no keyboard handling.
213
+ <!-- @unreleased-end -->
214
+
215
+ ## Notes / Edge Cases
216
+
217
+ - The disc is `border-radius: 50%` with `overflow: hidden`; images use `object-fit: cover`, so non-square sources are centre-cropped rather than stretched.
218
+ - `type="image"` with an empty `src` renders an empty circle — there is no automatic fallback to initials. Switch `type` yourself when the photo is missing.
219
+ - Every variant keeps a 1px border (`--rel-stroke-sm`); `fill` and `subtle` make it transparent so the outer size is identical across variants.
220
+ - `bg` and `color` are written as inline styles on the `base` part, so they win over both the `--rel-avatar-*` hooks and the variant tokens.
221
+ - Initials are forced uppercase and `user-select: none`. `size`, `type` and `variant` are reflected, so `rel-avatar[size="large"]` works as a selector. Because `lg` / `md` / `sm` / `xs` are normalised to the full words before reflection, the selector matches whichever spelling was written.
222
+ - The `icon` part name is shared by the `<img>` (`type="image"`) and the slot wrapper (`type="icon"`); `::part(icon)` matches whichever one is rendered.
223
+ - **Ring** (new in 1.5.0): a 2px outline just outside the circle, so the avatar keeps its 40 / 32 / 24 / 20px box and neighbours are not pushed apart. It is meant for avatars that overlap, on any surface; recolour it with `--rel-avatar-ring-color` when the surface is not the page colour.
224
+ - **Badge** (new in 1.5.0): 12 / 10 / 8 / 6px by size, flush with the bottom-right of the avatar's box, with a 1px outside edge. `dot` fills with `--rel-bg-success` (Figma has only the green dot); `icon` fills with `--rel-bg-neutral-elevated-2` and draws `badge-icon` at two thirds of the disc. Recolour either with `--rel-avatar-badge-bg`. At the two smallest sizes an icon badge is too small to read; prefer `dot` there.
225
+ - **`icon` vs the slot:** when `icon` is set it replaces the slot; leave it empty to slot your own SVG.
226
+ <!-- @unreleased-begin 1.5.0 -->
227
+ - **Avatar group.** The group writes `size` and `ring` on its avatars, so a size set on an avatar inside a group is replaced by the group's. It hides avatars beyond `max` with a `data-rel-group-hidden` attribute it manages itself; your own `hidden` attributes are left alone. The "+N" text steps down to 36% of the diameter from two digits ("+10"), and counts above 99 show "99+". Change the overlap with `--rel-avatar-group-overlap`.
228
+ <!-- @unreleased-end -->
@@ -54,6 +54,7 @@ The `BreadcrumbItem` shape is `{ label: string; url?: string }`; the type is exp
54
54
  | Property | Attribute | Type | Default | Description |
55
55
  | --- | --- | --- | --- | --- |
56
56
  | `items` | `items` | `BreadcrumbItem[]` | `[]` | Ordered trail, root first: `{ label: string; url?: string }[]`. Items with a `url` render as links except the last one, which is always the current page (and never a link). Set as a property — arrays do not survive attribute serialisation. |
57
+ | `ariaLabel` | `aria-label` | `string` | `"Breadcrumb"` | Name the trail when several breadcrumb landmarks share a page. |
57
58
 
58
59
  ## Events
59
60
 
@@ -6,7 +6,7 @@ Action button implementing the Figma "Button" component: a native `<button>` wit
6
6
 
7
7
  ```html
8
8
  <!-- Styles (Figma "Style") -->
9
- <rel-button variant="primary">Primary</rel-button>
9
+ <rel-button variant="primary" tone="brand">Primary</rel-button>
10
10
  <rel-button variant="secondary">Secondary</rel-button>
11
11
  <rel-button variant="ghost">Ghost</rel-button>
12
12
  <rel-button variant="link">Link style</rel-button>
@@ -33,7 +33,7 @@ Action button implementing the Figma "Button" component: a native `<button>` wit
33
33
  <rel-button border="no-corner-radius">Square</rel-button>
34
34
 
35
35
  <!-- Icon + label, and icon-only (needs an accessible name) -->
36
- <rel-button variant="primary">
36
+ <rel-button variant="primary" tone="brand">
37
37
  <rel-icon name="plus"></rel-icon>
38
38
  Add item
39
39
  </rel-button>
@@ -41,21 +41,21 @@ Action button implementing the Figma "Button" component: a native `<button>` wit
41
41
  <rel-icon name="settings"></rel-icon>
42
42
  </rel-button>
43
43
  <rel-button variant="ghost" icon-only size="small" aria-label="Close">
44
- <rel-icon name="x"></rel-icon>
44
+ <rel-icon name="close"></rel-icon>
45
45
  </rel-button>
46
46
 
47
47
  <!-- States -->
48
- <rel-button variant="primary" loading>Saving</rel-button>
49
- <rel-button variant="primary" disabled>Unavailable</rel-button>
48
+ <rel-button variant="primary" tone="brand" loading>Saving</rel-button>
49
+ <rel-button variant="primary" tone="brand" disabled>Unavailable</rel-button>
50
50
 
51
51
  <!-- Corner badges -->
52
52
  <rel-button variant="secondary" badge="3">Inbox</rel-button>
53
53
  <rel-button variant="ghost" icon-only badge-dot aria-label="Notifications">
54
- <rel-icon name="bell"></rel-icon>
54
+ <rel-icon name="notification-on"></rel-icon>
55
55
  </rel-button>
56
56
 
57
57
  <!-- Listen for clicks (native click bubbles through the shadow root) -->
58
- <rel-button id="save" variant="primary">Save</rel-button>
58
+ <rel-button id="save" variant="primary" tone="brand">Save</rel-button>
59
59
  <script>
60
60
  document.getElementById('save').addEventListener('click', () => {
61
61
  console.log('saved');
@@ -63,7 +63,7 @@ Action button implementing the Figma "Button" component: a native `<button>` wit
63
63
  </script>
64
64
 
65
65
  <!-- Per-instance minimum width -->
66
- <rel-button variant="primary" style="--rel-button-min-width: 160px;">Wide</rel-button>
66
+ <rel-button variant="primary" tone="brand" style="--rel-button-min-width: 160px;">Wide</rel-button>
67
67
  ```
68
68
 
69
69
  ### Deprecated aliases
@@ -182,7 +182,7 @@ Figma populates only part of the grid. Combinations outside it have no design-sy
182
182
  - **Events.** The element dispatches no custom events. The native `click` is `composed`, so a listener on `<rel-button>` (or an ancestor) receives exactly one event per activation — do not re-dispatch it.
183
183
  - **Minimum widths** come from the Figma master: small/medium/large = 80/100/120px, static = 40/50/60px. `link` has no minimum, `icon-only` is a fixed square (32/40/48px) and the legacy `icon` variant is always a 40px circle regardless of `size`. Override per instance with `--rel-button-min-width`.
184
184
  - **`border`** exposes `small-corner-radius` and `no-corner-radius`, which have no design-system backing — every one of Figma's 624 button nodes is fully rounded. They are a code-only extension, kept for existing layouts.
185
- - **Legacy `icon` variant vs `icon-only`.** `variant="icon"` keeps its pre-2.0 look (40px circle, tone-driven fill, `tone="secondary"` gives it an outline) and ignores `size` and `border`. `icon-only` is an axis that composes with any style and size — prefer it.
185
+ - **Legacy `icon` variant vs `icon-only`.** `variant="icon"` keeps its pre-2.0 look (40px circle, tone-driven fill, `tone="secondary"` gives it an outline) and ignores `size` and `border`. Since 1.5.0 the neutral tone's hover and pressed state is the Icon Only (ghost) hover tint laid over its grey fill; before, its hover showed no change. `icon-only` is an axis that composes with any style and size — prefer it.
186
186
  - **`tone` on `secondary` / `ghost` / `link`** changes the label, border or text colour only; the fill stays on the surface. The destructive outline border is deliberately subtle at rest and only goes solid on hover/pressed, matching Figma.
187
187
  - **`static`** is a neutral-only style meant for coloured or dark backgrounds; other tones have no static treatment.
188
188
  - **`success`** is a legacy tone without a Figma counterpart; it renders a green fill/outline/ghost tint but is not part of the current spec.