Skip to content

Commit 83c261f

Browse files
hhkaosclaude
andcommitted
style(embed): give <ote-subscribe> badges the colored-pill icon look
layout="badges" triggers now match the icon+solid-color badge design this element was ported from (calendar icon on blue, feed icon on RSS orange), with per-group colors overridable via --ote-subscribe-ics-color/ -rss-color/-ote-color. layout="menu"'s single trigger is unchanged. Left under CHANGELOG's Unreleased heading rather than folded into the already-tagged/published v0.5.0. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
1 parent ab8c29a commit 83c261f

3 files changed

Lines changed: 96 additions & 1 deletion

File tree

apps/embed/CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22

33
## Unreleased
44

5+
### Changed
6+
7+
- `<ote-subscribe layout="badges">` triggers now match the colored-pill
8+
icon+text badge design this element was ported from (a distinct
9+
currentColor icon and solid background per group — calendar icon on
10+
`--ote-subscribe-ics-color`/`--ote-subscribe-ote-color`, feed icon on
11+
`--ote-subscribe-rss-color`), instead of the plain neutral soft-accent
12+
button. `layout="menu"`'s single trigger is unchanged — it's a generic
13+
action button, not a feed-type-branded badge. All three colors are
14+
overridable via those CSS custom properties.
15+
516
## 0.5.0
617

718
### Added

apps/embed/src/subscribe-render.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ const STRINGS = {
1717
calendarGroup: "Calendar",
1818
rssGroup: "RSS",
1919
oteGroup: "OTE feed",
20+
icsBadge: "ICS",
21+
rssBadge: "RSS feed",
22+
oteBadge: "OTE feed",
2023
google: "Subscribe with Google Calendar",
2124
webcal: "Subscribe with app (Apple Calendar, Outlook desktop…)",
2225
icsDownload: "Open/download ICS",
@@ -33,6 +36,9 @@ const STRINGS = {
3336
calendarGroup: "Calendario",
3437
rssGroup: "RSS",
3538
oteGroup: "Feed OTE",
39+
icsBadge: "ICS",
40+
rssBadge: "Feed RSS",
41+
oteBadge: "Feed OTE",
3642
google: "Suscribirse con Google Calendar",
3743
webcal: "Suscribirse con app (Apple Calendar, Outlook de escritorio…)",
3844
icsDownload: "Abrir/descargar ICS",
@@ -59,6 +65,13 @@ interface RenderGroup {
5965
items: RenderItem[];
6066
}
6167

68+
// Simple currentColor outline icons, small enough to inline directly — no icon font/sprite dependency for a widget that has to work standalone in a Shadow DOM.
69+
const ICONS: Record<GroupKey, string> = {
70+
ics: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="4.5" width="18" height="16" rx="2"/><path d="M8 2.5v4M16 2.5v4M3 9.5h18"/></svg>`,
71+
rss: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 11a9 9 0 0 1 9 9"/><path d="M4 4a16 16 0 0 1 16 16"/><circle cx="5" cy="19" r="1" fill="currentColor" stroke="none"/></svg>`,
72+
ote: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 11a9 9 0 0 1 9 9"/><path d="M4 4a16 16 0 0 1 16 16"/><circle cx="5" cy="19" r="1" fill="currentColor" stroke="none"/></svg>`,
73+
};
74+
6275
const ICS_TOKENS: readonly ShowToken[] = ["google", "webcal", "ics-download"];
6376
const RSS_TOKENS: readonly ShowToken[] = ["feedly", "feed-protocol", "rss-download"];
6477
const OTE_TOKENS: readonly ShowToken[] = ["ote-reader", "ote-preview", "json-download"];
@@ -139,6 +152,7 @@ function renderTrigger(
139152
disabled: boolean;
140153
open: boolean;
141154
menuId: string;
155+
iconSvg?: string;
142156
buildMenuContent: () => HTMLElement;
143157
onClick: () => void;
144158
},
@@ -152,6 +166,12 @@ function renderTrigger(
152166
trigger.setAttribute("aria-expanded", String(options.open));
153167
trigger.setAttribute("aria-label", options.ariaLabel);
154168

169+
if (options.iconSvg) {
170+
const icon = el("span", "icon");
171+
icon.innerHTML = options.iconSvg;
172+
trigger.append(icon);
173+
}
174+
155175
const slot = document.createElement("slot");
156176
slot.name = options.slotName;
157177
slot.textContent = options.fallbackLabel;
@@ -192,15 +212,21 @@ export function renderSubscribe(container: HTMLElement, state: SubscribeState):
192212
}
193213

194214
if (state.layout === "badges") {
215+
const badgeLabel: Record<GroupKey, string> = {
216+
ics: strings.icsBadge,
217+
rss: strings.rssBadge,
218+
ote: strings.oteBadge,
219+
};
195220
for (const group of groups) {
196221
renderTrigger(container, {
197222
groupKey: group.key,
198223
slotName: `${group.key}-trigger`,
199-
fallbackLabel: group.label,
224+
fallbackLabel: badgeLabel[group.key],
200225
ariaLabel: group.label,
201226
disabled: false,
202227
open: state.openGroup === group.key,
203228
menuId: `menu-${state.instanceId}-${group.key}`,
229+
iconSvg: ICONS[group.key],
204230
buildMenuContent: () => buildMenu(`menu-${state.instanceId}-${group.key}`, group.items),
205231
onClick: () => state.onToggle(group.key),
206232
});

apps/embed/src/subscribe.css.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ export const SUBSCRIBE_CSS = `
1818
--ote-accent-hover: #2a46a8;
1919
--ote-accent-soft: #eef1fb;
2020
--ote-radius: 8px;
21+
--ote-subscribe-ics-color: var(--ote-accent);
22+
--ote-subscribe-rss-color: #ee7203;
23+
--ote-subscribe-ote-color: var(--ote-accent);
2124
font-family: var(--ote-font-family, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif);
2225
font-size: var(--ote-font-size, 1rem);
2326
color: var(--ote-text);
@@ -58,6 +61,7 @@ export const SUBSCRIBE_CSS = `
5861
.trigger {
5962
display: inline-flex;
6063
align-items: center;
64+
justify-content: center;
6165
gap: 0.35rem;
6266
min-height: 2rem;
6367
padding: 0.35rem 0.65rem;
@@ -69,6 +73,7 @@ export const SUBSCRIBE_CSS = `
6973
font-size: 0.8125rem;
7074
font-weight: 600;
7175
line-height: 1.2;
76+
text-align: center;
7277
cursor: pointer;
7378
}
7479
@@ -85,6 +90,59 @@ export const SUBSCRIBE_CSS = `
8590
opacity: 0.5;
8691
}
8792
93+
.icon {
94+
display: inline-flex;
95+
width: 1.1em;
96+
height: 1.1em;
97+
flex: 0 0 auto;
98+
}
99+
100+
.icon svg {
101+
width: 100%;
102+
height: 100%;
103+
display: block;
104+
}
105+
106+
/* The colored-pill "badge" look (layout="badges"), matching the icon+text
107+
badge design this element was ported from. The plain layout="menu"
108+
trigger keeps the neutral soft-accent style above — it's a generic
109+
action button, not a feed-type-branded badge. */
110+
.trigger[data-group="ics"],
111+
.trigger[data-group="rss"],
112+
.trigger[data-group="ote"] {
113+
border-radius: 999px;
114+
border-color: transparent;
115+
padding: 0.4rem 0.9rem;
116+
color: #fff;
117+
}
118+
119+
.trigger[data-group="ics"] {
120+
background: var(--ote-subscribe-ics-color);
121+
}
122+
123+
.trigger[data-group="rss"] {
124+
background: var(--ote-subscribe-rss-color);
125+
}
126+
127+
.trigger[data-group="ote"] {
128+
background: var(--ote-subscribe-ote-color);
129+
}
130+
131+
.trigger[data-group="ics"]:hover,
132+
.trigger[data-group="ics"]:focus-visible,
133+
.trigger[data-group="ics"][aria-expanded="true"],
134+
.trigger[data-group="rss"]:hover,
135+
.trigger[data-group="rss"]:focus-visible,
136+
.trigger[data-group="rss"][aria-expanded="true"],
137+
.trigger[data-group="ote"]:hover,
138+
.trigger[data-group="ote"]:focus-visible,
139+
.trigger[data-group="ote"][aria-expanded="true"] {
140+
border-color: transparent;
141+
color: #fff;
142+
filter: brightness(0.92);
143+
outline: none;
144+
}
145+
88146
.menu {
89147
position: absolute;
90148
inset-block-start: calc(100% + 0.25rem);

0 commit comments

Comments
 (0)