@skhema/embed 0.1.6 → 0.1.8

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/index.cjs CHANGED
@@ -75,6 +75,16 @@ const SHARED_CARD_STYLES = `
75
75
  flex-shrink: 0;
76
76
  }
77
77
 
78
+ .skhema-author-link {
79
+ color: inherit;
80
+ text-decoration: none;
81
+ }
82
+
83
+ .skhema-author-link:hover {
84
+ color: var(--skhema-text);
85
+ text-decoration: underline;
86
+ }
87
+
78
88
  /* Save button — primary brand color */
79
89
  .skhema-save-btn {
80
90
  display: inline-flex;
@@ -112,6 +122,40 @@ const SHARED_CARD_STYLES = `
112
122
  }
113
123
  `;
114
124
  const USER_ICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>`;
125
+ function readAuthorAttribution(element) {
126
+ const authorName = element.getAttribute("author-name") || element.getAttribute("contributor-name");
127
+ if (!authorName?.trim()) {
128
+ return null;
129
+ }
130
+ const authorSlug = element.getAttribute("author-slug")?.trim();
131
+ return {
132
+ authorName: authorName.trim(),
133
+ authorSlug: authorSlug || void 0
134
+ };
135
+ }
136
+ function escapeHtml(text) {
137
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
138
+ }
139
+ function formatAuthorAttributionHtml(authorName, authorSlug) {
140
+ const label = `By ${escapeHtml(authorName)}`;
141
+ if (authorSlug) {
142
+ return `<a href="https://skhema.com/contributors/${encodeURIComponent(authorSlug)}" class="skhema-author-link" target="_blank" rel="noopener noreferrer">${label}</a>`;
143
+ }
144
+ return `<span class="skhema-author-text">${label}</span>`;
145
+ }
146
+ function formatContributorIdFallback(contributorId) {
147
+ return contributorId.split(/[_-]/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
148
+ }
149
+ function resolveAuthorFooterHtml(element, contributorId) {
150
+ const attribution = readAuthorAttribution(element);
151
+ if (attribution) {
152
+ return formatAuthorAttributionHtml(
153
+ attribution.authorName,
154
+ attribution.authorSlug
155
+ );
156
+ }
157
+ return `<span class="skhema-author-text">By ${escapeHtml(formatContributorIdFallback(contributorId))}</span>`;
158
+ }
115
159
  const ANALYTICS_ENDPOINT = "https://analytics.skhema.com/functions/v1/embed-manage";
116
160
  const TRACKING_COOKIE_NAME = "_sk";
117
161
  const TRACKING_EXPIRY_HOURS = 24;
@@ -1031,6 +1075,8 @@ class SkhemaComponent extends HTMLElement {
1031
1075
  return [
1032
1076
  "component-type",
1033
1077
  "contributor-id",
1078
+ "author-name",
1079
+ "author-slug",
1034
1080
  "contributor-name",
1035
1081
  "title",
1036
1082
  "theme",
@@ -1171,8 +1217,7 @@ class SkhemaComponent extends HTMLElement {
1171
1217
  const componentLabel = getComponentTypeLabel(component_type);
1172
1218
  const acronym = getComponentTypeAcronym(component_type);
1173
1219
  const colors = COMPONENT_COLORS[component_type];
1174
- const contributorName = this.getAttribute("contributor-name");
1175
- const displayName = contributorName || this.formatContributorName(contributor_id);
1220
+ const authorFooterHtml = resolveAuthorFooterHtml(this, contributor_id);
1176
1221
  const themeAttribute = this.getAttribute("theme") || "auto";
1177
1222
  const actualTheme = this.getActualTheme(themeAttribute);
1178
1223
  const redirectUrl = generateComponentRedirectUrl(
@@ -1221,7 +1266,7 @@ class SkhemaComponent extends HTMLElement {
1221
1266
  <div class="skhema-footer-row">
1222
1267
  <span class="skhema-contributor-line">
1223
1268
  ${USER_ICON_SVG}
1224
- ${displayName}
1269
+ ${authorFooterHtml}
1225
1270
  </span>
1226
1271
  <a href="${redirectUrl}"
1227
1272
  class="skhema-save-btn"
@@ -1285,9 +1330,6 @@ class SkhemaComponent extends HTMLElement {
1285
1330
  }
1286
1331
  return "light";
1287
1332
  }
1288
- formatContributorName(contributorId) {
1289
- return contributorId.split(/[_-]/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
1290
- }
1291
1333
  addPreconnectHints() {
1292
1334
  if (document.querySelector(
1293
1335
  'link[rel="preconnect"][href*="analytics.skhema.com"]'
@@ -1730,6 +1772,8 @@ class SkhemaElement extends HTMLElement {
1730
1772
  return [
1731
1773
  "element-type",
1732
1774
  "contributor-id",
1775
+ "author-name",
1776
+ "author-slug",
1733
1777
  "contributor-name",
1734
1778
  "content",
1735
1779
  "source-url",
@@ -1851,8 +1895,7 @@ class SkhemaElement extends HTMLElement {
1851
1895
  );
1852
1896
  const themeAttribute = this.getAttribute("theme") || "auto";
1853
1897
  const actualTheme = this.getActualTheme(themeAttribute);
1854
- const contributorName = this.getAttribute("contributor-name");
1855
- const displayName = contributorName || this.formatContributorName(contributor_id);
1898
+ const authorFooterHtml = resolveAuthorFooterHtml(this, contributor_id);
1856
1899
  const componentType = resolveComponentType(element_type);
1857
1900
  const acronym = getComponentTypeAcronym(componentType);
1858
1901
  const colors = COMPONENT_COLORS[componentType];
@@ -1880,7 +1923,7 @@ class SkhemaElement extends HTMLElement {
1880
1923
  <div class="skhema-footer-row">
1881
1924
  <span class="skhema-contributor-line">
1882
1925
  ${USER_ICON_SVG}
1883
- ${displayName}
1926
+ ${authorFooterHtml}
1884
1927
  </span>
1885
1928
  <a href="${redirectUrl}"
1886
1929
  class="skhema-save-btn"
@@ -1927,9 +1970,6 @@ class SkhemaElement extends HTMLElement {
1927
1970
  }
1928
1971
  return "light";
1929
1972
  }
1930
- formatContributorName(contributorId) {
1931
- return contributorId.split(/[_-]/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
1932
- }
1933
1973
  addPreconnectHints() {
1934
1974
  if (document.querySelector(
1935
1975
  'link[rel="preconnect"][href*="analytics.skhema.com"]'