@skhema/embed 0.1.5 → 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.es.js CHANGED
@@ -73,6 +73,16 @@ const SHARED_CARD_STYLES = `
73
73
  flex-shrink: 0;
74
74
  }
75
75
 
76
+ .skhema-author-link {
77
+ color: inherit;
78
+ text-decoration: none;
79
+ }
80
+
81
+ .skhema-author-link:hover {
82
+ color: var(--skhema-text);
83
+ text-decoration: underline;
84
+ }
85
+
76
86
  /* Save button — primary brand color */
77
87
  .skhema-save-btn {
78
88
  display: inline-flex;
@@ -110,6 +120,40 @@ const SHARED_CARD_STYLES = `
110
120
  }
111
121
  `;
112
122
  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>`;
123
+ function readAuthorAttribution(element) {
124
+ const authorName = element.getAttribute("author-name") || element.getAttribute("contributor-name");
125
+ if (!authorName?.trim()) {
126
+ return null;
127
+ }
128
+ const authorSlug = element.getAttribute("author-slug")?.trim();
129
+ return {
130
+ authorName: authorName.trim(),
131
+ authorSlug: authorSlug || void 0
132
+ };
133
+ }
134
+ function escapeHtml(text) {
135
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
136
+ }
137
+ function formatAuthorAttributionHtml(authorName, authorSlug) {
138
+ const label = `By ${escapeHtml(authorName)}`;
139
+ if (authorSlug) {
140
+ return `<a href="https://skhema.com/contributors/${encodeURIComponent(authorSlug)}" class="skhema-author-link" target="_blank" rel="noopener noreferrer">${label}</a>`;
141
+ }
142
+ return `<span class="skhema-author-text">${label}</span>`;
143
+ }
144
+ function formatContributorIdFallback(contributorId) {
145
+ return contributorId.split(/[_-]/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
146
+ }
147
+ function resolveAuthorFooterHtml(element, contributorId) {
148
+ const attribution = readAuthorAttribution(element);
149
+ if (attribution) {
150
+ return formatAuthorAttributionHtml(
151
+ attribution.authorName,
152
+ attribution.authorSlug
153
+ );
154
+ }
155
+ return `<span class="skhema-author-text">By ${escapeHtml(formatContributorIdFallback(contributorId))}</span>`;
156
+ }
113
157
  const ANALYTICS_ENDPOINT = "https://analytics.skhema.com/functions/v1/embed-manage";
114
158
  const TRACKING_COOKIE_NAME = "_sk";
115
159
  const TRACKING_EXPIRY_HOURS = 24;
@@ -1029,6 +1073,8 @@ class SkhemaComponent extends HTMLElement {
1029
1073
  return [
1030
1074
  "component-type",
1031
1075
  "contributor-id",
1076
+ "author-name",
1077
+ "author-slug",
1032
1078
  "contributor-name",
1033
1079
  "title",
1034
1080
  "theme",
@@ -1169,8 +1215,7 @@ class SkhemaComponent extends HTMLElement {
1169
1215
  const componentLabel = getComponentTypeLabel(component_type);
1170
1216
  const acronym = getComponentTypeAcronym(component_type);
1171
1217
  const colors = COMPONENT_COLORS[component_type];
1172
- const contributorName = this.getAttribute("contributor-name");
1173
- const displayName = contributorName || this.formatContributorName(contributor_id);
1218
+ const authorFooterHtml = resolveAuthorFooterHtml(this, contributor_id);
1174
1219
  const themeAttribute = this.getAttribute("theme") || "auto";
1175
1220
  const actualTheme = this.getActualTheme(themeAttribute);
1176
1221
  const redirectUrl = generateComponentRedirectUrl(
@@ -1219,7 +1264,7 @@ class SkhemaComponent extends HTMLElement {
1219
1264
  <div class="skhema-footer-row">
1220
1265
  <span class="skhema-contributor-line">
1221
1266
  ${USER_ICON_SVG}
1222
- ${displayName}
1267
+ ${authorFooterHtml}
1223
1268
  </span>
1224
1269
  <a href="${redirectUrl}"
1225
1270
  class="skhema-save-btn"
@@ -1283,9 +1328,6 @@ class SkhemaComponent extends HTMLElement {
1283
1328
  }
1284
1329
  return "light";
1285
1330
  }
1286
- formatContributorName(contributorId) {
1287
- return contributorId.split(/[_-]/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
1288
- }
1289
1331
  addPreconnectHints() {
1290
1332
  if (document.querySelector(
1291
1333
  'link[rel="preconnect"][href*="analytics.skhema.com"]'
@@ -1728,6 +1770,8 @@ class SkhemaElement extends HTMLElement {
1728
1770
  return [
1729
1771
  "element-type",
1730
1772
  "contributor-id",
1773
+ "author-name",
1774
+ "author-slug",
1731
1775
  "contributor-name",
1732
1776
  "content",
1733
1777
  "source-url",
@@ -1849,8 +1893,7 @@ class SkhemaElement extends HTMLElement {
1849
1893
  );
1850
1894
  const themeAttribute = this.getAttribute("theme") || "auto";
1851
1895
  const actualTheme = this.getActualTheme(themeAttribute);
1852
- const contributorName = this.getAttribute("contributor-name");
1853
- const displayName = contributorName || this.formatContributorName(contributor_id);
1896
+ const authorFooterHtml = resolveAuthorFooterHtml(this, contributor_id);
1854
1897
  const componentType = resolveComponentType(element_type);
1855
1898
  const acronym = getComponentTypeAcronym(componentType);
1856
1899
  const colors = COMPONENT_COLORS[componentType];
@@ -1878,7 +1921,7 @@ class SkhemaElement extends HTMLElement {
1878
1921
  <div class="skhema-footer-row">
1879
1922
  <span class="skhema-contributor-line">
1880
1923
  ${USER_ICON_SVG}
1881
- ${displayName}
1924
+ ${authorFooterHtml}
1882
1925
  </span>
1883
1926
  <a href="${redirectUrl}"
1884
1927
  class="skhema-save-btn"
@@ -1925,9 +1968,6 @@ class SkhemaElement extends HTMLElement {
1925
1968
  }
1926
1969
  return "light";
1927
1970
  }
1928
- formatContributorName(contributorId) {
1929
- return contributorId.split(/[_-]/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
1930
- }
1931
1971
  addPreconnectHints() {
1932
1972
  if (document.querySelector(
1933
1973
  'link[rel="preconnect"][href*="analytics.skhema.com"]'