@grasco/profile-picture 0.1.4 → 0.1.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.
package/dist/angular.cjs CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';var _documentCurrentScript=typeof document!=='undefined'?document.currentScript:null;var s="grasco-profile-picture-styles",n=false;function i(){if(n||typeof document>"u")return;if(document.getElementById(s)){n=true;return}if(document.querySelector('link[href*="profile-picture"][href$="styles.css"]')){n=true;return}let t=o();if(!t)return;let e=document.createElement("link");e.id=s,e.rel="stylesheet",e.href=t,document.head.appendChild(e),n=true;}function o(){if(typeof window<"u"&&window.__GRASCO_PROFILE_PICTURE_CSS__)return window.__GRASCO_PROFILE_PICTURE_CSS__;try{let t=(typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('angular.cjs', document.baseURI).href));if(t)return `${t.substring(0,t.lastIndexOf("/")+1)}dist/styles.css`}catch{}let r=document.currentScript;if(r?.src){let t=new URL(r.src);return `${t.href.substring(0,t.href.lastIndexOf("/")+1)}dist/styles.css`}return null}i();//# sourceMappingURL=angular.cjs.map
1
+ 'use strict';var _documentCurrentScript=typeof document!=='undefined'?document.currentScript:null;var r="grasco-profile-picture-styles",n=false,s=false;function i(){if(n||typeof document>"u")return;if(document.getElementById(r)){n=true;return}if(document.querySelector('link[href*="profile-picture"][href$="styles.css"]')){n=true;return}s||(s=true,l());}function l(){(typeof requestIdleCallback<"u"?requestIdleCallback:e=>setTimeout(e,1))(()=>u());}function u(){if(n||typeof document>"u")return;if(document.getElementById(r)){n=true;return}let t=c();if(!t)return;let e=document.createElement("link");e.id=r,e.rel="stylesheet",e.href=t,document.head.appendChild(e),n=true;}function c(){if(typeof window<"u"&&window.__GRASCO_PROFILE_PICTURE_CSS__)return window.__GRASCO_PROFILE_PICTURE_CSS__;try{let e=(typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('angular.cjs', document.baseURI).href));if(e)return `${e.substring(0,e.lastIndexOf("/")+1)}dist/styles.css`}catch{}let t=document.currentScript;if(t?.src){let e=new URL(t.src);return `${e.href.substring(0,e.href.lastIndexOf("/")+1)}dist/styles.css`}return null}i();//# sourceMappingURL=angular.cjs.map
2
2
  //# sourceMappingURL=angular.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/loadStyles.ts","../src/angular.ts"],"names":["LINK_ID","loaded","loadStyles","cssUrl","getCssUrl","link","metaUrl","currentScript","scriptUrl"],"mappings":"kGAaA,IAAMA,CAAAA,CAAU,+BAAA,CAEZC,CAAAA,CAAS,KAAA,CAMN,SAASC,CAAAA,EAAmB,CAOjC,GALID,CAAAA,EAKA,OAAO,QAAA,CAAa,GAAA,CACtB,OAIF,GAAI,QAAA,CAAS,cAAA,CAAeD,CAAO,CAAA,CAAG,CACpCC,CAAAA,CAAS,IAAA,CACT,MACF,CAMA,GAHqB,QAAA,CAAS,aAAA,CAC5B,mDACF,CAAA,CACkB,CAChBA,EAAS,IAAA,CACT,MACF,CAGA,IAAME,CAAAA,CAASC,CAAAA,EAAU,CACzB,GAAI,CAACD,CAAAA,CACH,OAIF,IAAME,CAAAA,CAAO,QAAA,CAAS,aAAA,CAAc,MAAM,EAC1CA,CAAAA,CAAK,EAAA,CAAKL,CAAAA,CACVK,CAAAA,CAAK,GAAA,CAAM,YAAA,CACXA,CAAAA,CAAK,IAAA,CAAOF,CAAAA,CACZ,QAAA,CAAS,IAAA,CAAK,WAAA,CAAYE,CAAI,CAAA,CAE9BJ,CAAAA,CAAS,KACX,CAKA,SAASG,CAAAA,EAA2B,CAElC,GACE,OAAO,MAAA,CAAW,GAAA,EACjB,MAAA,CAA6C,8BAAA,CAE9C,OAAQ,MAAA,CACL,8BAAA,CAIL,GAAI,CACF,IAAME,CAAAA,CAAU,6PAAY,CAC5B,GAAIA,CAAAA,CAEF,OAAO,CAAA,EADUA,CAAAA,CAAQ,SAAA,CAAU,CAAA,CAAGA,CAAAA,CAAQ,WAAA,CAAY,GAAG,CAAA,CAAI,CAAC,CAChD,CAAA,eAAA,CAEtB,CAAA,KAAQ,CAER,CAGA,IAAMC,CAAAA,CAAgB,QAAA,CAAS,aAAA,CAC/B,GAAIA,CAAAA,EAAe,GAAA,CAAK,CACtB,IAAMC,CAAAA,CAAY,IAAI,GAAA,CAAID,CAAAA,CAAc,GAAG,CAAA,CAK3C,OAAO,CAAA,EAJUC,CAAAA,CAAU,IAAA,CAAK,SAAA,CAC9B,CAAA,CACAA,CAAAA,CAAU,IAAA,CAAK,WAAA,CAAY,GAAG,CAAA,CAAI,CACpC,CACkB,CAAA,eAAA,CACpB,CAEA,OAAO,IACT,CC5FAN,CAAAA,EAAW","file":"angular.cjs","sourcesContent":["/**\n * Idempotent CSS loader for @grasco/profile-picture\n *\n * Auto-injects the component's CSS via <link> tag when the module is imported.\n * Uses relative URL detection to find styles.css in the same directory as the JS file.\n *\n * Idempotency is guaranteed through 4 layers:\n * 1. Module-level flag - prevents multiple calls in same bundle\n * 2. ID check - prevents duplicates across bundles\n * 3. href pattern check - catches manually added links\n * 4. SSR guard - prevents errors in Node.js\n */\n\nconst LINK_ID = \"grasco-profile-picture-styles\";\n\nlet loaded = false;\n\n/**\n * Load the component's CSS stylesheet\n * Safe to call multiple times - will only inject once\n */\nexport function loadStyles(): void {\n // Skip if already loaded (module-level)\n if (loaded) {\n return;\n }\n\n // Skip if SSR (no document)\n if (typeof document === \"undefined\") {\n return;\n }\n\n // Skip if link already exists by ID (idempotency across bundles)\n if (document.getElementById(LINK_ID)) {\n loaded = true;\n return;\n }\n\n // Check if any link already points to our CSS (by href pattern)\n const existingLink = document.querySelector(\n 'link[href*=\"profile-picture\"][href$=\"styles.css\"]'\n );\n if (existingLink) {\n loaded = true;\n return;\n }\n\n // Get CSS URL relative to current script\n const cssUrl = getCssUrl();\n if (!cssUrl) {\n return;\n }\n\n // Inject link tag\n const link = document.createElement(\"link\");\n link.id = LINK_ID;\n link.rel = \"stylesheet\";\n link.href = cssUrl;\n document.head.appendChild(link);\n\n loaded = true;\n}\n\n/**\n * Get the CSS file URL based on the current script's location\n */\nfunction getCssUrl(): string | null {\n // Allow custom override via global variable\n if (\n typeof window !== \"undefined\" &&\n (window as unknown as Record<string, string>).__GRASCO_PROFILE_PICTURE_CSS__\n ) {\n return (window as unknown as Record<string, string>)\n .__GRASCO_PROFILE_PICTURE_CSS__;\n }\n\n // Try import.meta.url first (ESM - most reliable for bundlers)\n try {\n const metaUrl = import.meta.url;\n if (metaUrl) {\n const basePath = metaUrl.substring(0, metaUrl.lastIndexOf(\"/\") + 1);\n return `${basePath}dist/styles.css`;\n }\n } catch {\n // import.meta.url not available\n }\n\n // Fallback: Get current script URL\n const currentScript = document.currentScript as HTMLScriptElement | null;\n if (currentScript?.src) {\n const scriptUrl = new URL(currentScript.src);\n const basePath = scriptUrl.href.substring(\n 0,\n scriptUrl.href.lastIndexOf(\"/\") + 1\n );\n return `${basePath}dist/styles.css`;\n }\n\n return null;\n}\n","/**\n * Angular entry point\n */\n\n// Auto-load styles when module is imported\nimport { loadStyles } from \"./core/loadStyles\";\n\nloadStyles();\n\nexport * from \"./wrappers/angular\";\n"]}
1
+ {"version":3,"sources":["../src/core/loadStyles.ts","../src/angular.ts"],"names":["LINK_ID","loaded","loadScheduled","loadStyles","scheduleStyleInjection","cb","injectStyleLink","cssUrl","getCssUrl","link","metaUrl","currentScript","scriptUrl"],"mappings":"kGAkBA,IAAMA,EAAU,+BAAA,CAEZC,CAAAA,CAAS,MACTC,CAAAA,CAAgB,KAAA,CAOb,SAASC,CAAAA,EAAmB,CAOjC,GALIF,CAAAA,EAKA,OAAO,QAAA,CAAa,GAAA,CACtB,OAIF,GAAI,QAAA,CAAS,eAAeD,CAAO,CAAA,CAAG,CACpCC,CAAAA,CAAS,KACT,MACF,CAMA,GAHqB,QAAA,CAAS,aAAA,CAC5B,mDACF,CAAA,CACkB,CAChBA,EAAS,IAAA,CACT,MACF,CAGKC,CAAAA,GACHA,CAAAA,CAAgB,KAChBE,CAAAA,EAAuB,EAE3B,CAMA,SAASA,CAAAA,EAA+B,CAAA,CAEpC,OAAO,oBAAwB,GAAA,CAC3B,mBAAA,CACCC,GAAmB,UAAA,CAAWA,CAAAA,CAAI,CAAC,CAAA,EAEpC,IAAMC,CAAAA,EAAiB,EAC/B,CAKA,SAASA,GAAwB,CAE/B,GAAIL,GAAU,OAAO,QAAA,CAAa,GAAA,CAChC,OAGF,GAAI,QAAA,CAAS,cAAA,CAAeD,CAAO,CAAA,CAAG,CACpCC,EAAS,IAAA,CACT,MACF,CAGA,IAAMM,CAAAA,CAASC,GAAU,CACzB,GAAI,CAACD,CAAAA,CACH,OAIF,IAAME,CAAAA,CAAO,QAAA,CAAS,aAAA,CAAc,MAAM,EAC1CA,CAAAA,CAAK,EAAA,CAAKT,EACVS,CAAAA,CAAK,GAAA,CAAM,aACXA,CAAAA,CAAK,IAAA,CAAOF,CAAAA,CACZ,QAAA,CAAS,KAAK,WAAA,CAAYE,CAAI,EAE9BR,CAAAA,CAAS,KACX,CAKA,SAASO,CAAAA,EAA2B,CAElC,GACE,OAAO,MAAA,CAAW,GAAA,EACjB,OAA6C,8BAAA,CAE9C,OAAQ,OACL,8BAAA,CAIL,GAAI,CACF,IAAME,CAAAA,CAAU,6PAAY,CAC5B,GAAIA,EAEF,OAAO,CAAA,EADUA,EAAQ,SAAA,CAAU,CAAA,CAAGA,CAAAA,CAAQ,WAAA,CAAY,GAAG,CAAA,CAAI,CAAC,CAChD,CAAA,eAAA,CAEtB,CAAA,KAAQ,CAER,CAGA,IAAMC,CAAAA,CAAgB,QAAA,CAAS,cAC/B,GAAIA,CAAAA,EAAe,IAAK,CACtB,IAAMC,EAAY,IAAI,GAAA,CAAID,CAAAA,CAAc,GAAG,EAK3C,OAAO,CAAA,EAJUC,EAAU,IAAA,CAAK,SAAA,CAC9B,EACAA,CAAAA,CAAU,IAAA,CAAK,YAAY,GAAG,CAAA,CAAI,CACpC,CACkB,CAAA,eAAA,CACpB,CAEA,OAAO,IACT,CCrIAT,CAAAA,EAAW","file":"angular.cjs","sourcesContent":["/**\n * Idempotent CSS loader for @grasco/profile-picture\n *\n * Auto-injects the component's CSS via <link> tag when the module is imported.\n * Uses relative URL detection to find styles.css in the same directory as the JS file.\n *\n * Idempotency is guaranteed through 4 layers:\n * 1. Module-level flag - prevents multiple calls in same bundle\n * 2. ID check - prevents duplicates across bundles\n * 3. href pattern check - catches manually added links\n * 4. SSR guard - prevents errors in Node.js\n *\n * SSR Hydration Safety:\n * Style injection is deferred using requestIdleCallback (with setTimeout fallback)\n * to avoid DOM mutations during React/framework hydration, which would cause\n * hydration mismatch errors.\n */\n\nconst LINK_ID = \"grasco-profile-picture-styles\";\n\nlet loaded = false;\nlet loadScheduled = false;\n\n/**\n * Load the component's CSS stylesheet\n * Safe to call multiple times - will only inject once\n * Defers injection to avoid SSR hydration mismatch\n */\nexport function loadStyles(): void {\n // Skip if already loaded (module-level)\n if (loaded) {\n return;\n }\n\n // Skip if SSR (no document)\n if (typeof document === \"undefined\") {\n return;\n }\n\n // Skip if link already exists by ID (idempotency across bundles)\n if (document.getElementById(LINK_ID)) {\n loaded = true;\n return;\n }\n\n // Check if any link already points to our CSS (by href pattern)\n const existingLink = document.querySelector(\n 'link[href*=\"profile-picture\"][href$=\"styles.css\"]'\n );\n if (existingLink) {\n loaded = true;\n return;\n }\n\n // Schedule deferred injection (after hydration completes)\n if (!loadScheduled) {\n loadScheduled = true;\n scheduleStyleInjection();\n }\n}\n\n/**\n * Schedule style injection after hydration using requestIdleCallback\n * Falls back to setTimeout for browsers without requestIdleCallback support\n */\nfunction scheduleStyleInjection(): void {\n const defer =\n typeof requestIdleCallback !== \"undefined\"\n ? requestIdleCallback\n : (cb: () => void) => setTimeout(cb, 1);\n\n defer(() => injectStyleLink());\n}\n\n/**\n * Actually inject the <link> tag into the document head\n */\nfunction injectStyleLink(): void {\n // Re-check conditions in case something changed\n if (loaded || typeof document === \"undefined\") {\n return;\n }\n\n if (document.getElementById(LINK_ID)) {\n loaded = true;\n return;\n }\n\n // Get CSS URL relative to current script\n const cssUrl = getCssUrl();\n if (!cssUrl) {\n return;\n }\n\n // Inject link tag\n const link = document.createElement(\"link\");\n link.id = LINK_ID;\n link.rel = \"stylesheet\";\n link.href = cssUrl;\n document.head.appendChild(link);\n\n loaded = true;\n}\n\n/**\n * Get the CSS file URL based on the current script's location\n */\nfunction getCssUrl(): string | null {\n // Allow custom override via global variable\n if (\n typeof window !== \"undefined\" &&\n (window as unknown as Record<string, string>).__GRASCO_PROFILE_PICTURE_CSS__\n ) {\n return (window as unknown as Record<string, string>)\n .__GRASCO_PROFILE_PICTURE_CSS__;\n }\n\n // Try import.meta.url first (ESM - most reliable for bundlers)\n try {\n const metaUrl = import.meta.url;\n if (metaUrl) {\n const basePath = metaUrl.substring(0, metaUrl.lastIndexOf(\"/\") + 1);\n return `${basePath}dist/styles.css`;\n }\n } catch {\n // import.meta.url not available\n }\n\n // Fallback: Get current script URL\n const currentScript = document.currentScript as HTMLScriptElement | null;\n if (currentScript?.src) {\n const scriptUrl = new URL(currentScript.src);\n const basePath = scriptUrl.href.substring(\n 0,\n scriptUrl.href.lastIndexOf(\"/\") + 1\n );\n return `${basePath}dist/styles.css`;\n }\n\n return null;\n}\n","/**\n * Angular entry point\n */\n\n// Auto-load styles when module is imported\nimport { loadStyles } from \"./core/loadStyles\";\n\nloadStyles();\n\nexport * from \"./wrappers/angular\";\n"]}
@@ -19,18 +19,6 @@ interface PresenceConfig {
19
19
  /** Ring thickness (1-3) */
20
20
  thickness?: 1 | 2 | 3;
21
21
  }
22
- interface RibbonConfig {
23
- /** Text displayed on the ribbon */
24
- text: string;
25
- /** Position of the ribbon */
26
- position?: Position;
27
- /** Text color (CSS color) */
28
- color?: string;
29
- /** Background color (CSS color or gradient) */
30
- bgColor?: string;
31
- /** Icon before text (emoji or symbol) */
32
- icon?: string;
33
- }
34
22
  interface BadgeConfig {
35
23
  /** Badge content (text, number, or empty for dot) */
36
24
  content?: string | number;
@@ -123,8 +111,6 @@ interface ProfilePictureProps {
123
111
  ring?: RingConfig;
124
112
  /** Presence indicator configuration */
125
113
  presence?: PresenceConfig;
126
- /** Ribbon configuration */
127
- ribbon?: RibbonConfig;
128
114
  /** Badge configuration */
129
115
  badge?: BadgeConfig;
130
116
  /** Loading strategy */
@@ -159,6 +145,8 @@ interface GroupUserData {
159
145
  name: string;
160
146
  /** Image source URL */
161
147
  src?: string;
148
+ /** External customer ID for CDN image loading */
149
+ extCustomerId?: string;
162
150
  /** Presence status from data-status attribute */
163
151
  status?: PresenceStatus;
164
152
  /** Reference to the profile-picture element */
@@ -243,7 +231,6 @@ declare class ProfilePicture extends LitElement {
243
231
  ring?: RingConfig;
244
232
  presence?: PresenceConfig;
245
233
  glow?: GlowConfig;
246
- ribbon?: RibbonConfig;
247
234
  badge?: BadgeConfig;
248
235
  loading: LoadingStrategy;
249
236
  placeholder: PlaceholderType;
@@ -276,9 +263,13 @@ declare class ProfilePicture extends LitElement {
276
263
  private renderFallback;
277
264
  private renderImage;
278
265
  private renderRing;
266
+ /**
267
+ * Calculate corner offset based on variant
268
+ * Returns the inset from container edge where badges/presence should be positioned
269
+ */
270
+ private getCornerOffset;
279
271
  private renderPresence;
280
272
  private renderBadge;
281
- private renderRibbon;
282
273
  render(): lit_html.TemplateResult<1>;
283
274
  }
284
275
 
@@ -348,4 +339,4 @@ declare global {
348
339
  }
349
340
  }
350
341
 
351
- export type { BadgeConfig, DropdownConfig, GlowConfig, GroupUserData, InteractionConfig, LoadingStrategy, PlaceholderType, Position, PresenceConfig, PresenceStatus, ProfilePictureGroupProps, ProfilePictureProps, RibbonConfig, RingConfig, ShadowPreset, Size, StackDirection, TooltipConfig, TooltipPosition, Variant };
342
+ export type { BadgeConfig, DropdownConfig, GlowConfig, GroupUserData, InteractionConfig, LoadingStrategy, PlaceholderType, Position, PresenceConfig, PresenceStatus, ProfilePictureGroupProps, ProfilePictureProps, RingConfig, ShadowPreset, Size, StackDirection, TooltipConfig, TooltipPosition, Variant };
package/dist/angular.d.ts CHANGED
@@ -19,18 +19,6 @@ interface PresenceConfig {
19
19
  /** Ring thickness (1-3) */
20
20
  thickness?: 1 | 2 | 3;
21
21
  }
22
- interface RibbonConfig {
23
- /** Text displayed on the ribbon */
24
- text: string;
25
- /** Position of the ribbon */
26
- position?: Position;
27
- /** Text color (CSS color) */
28
- color?: string;
29
- /** Background color (CSS color or gradient) */
30
- bgColor?: string;
31
- /** Icon before text (emoji or symbol) */
32
- icon?: string;
33
- }
34
22
  interface BadgeConfig {
35
23
  /** Badge content (text, number, or empty for dot) */
36
24
  content?: string | number;
@@ -123,8 +111,6 @@ interface ProfilePictureProps {
123
111
  ring?: RingConfig;
124
112
  /** Presence indicator configuration */
125
113
  presence?: PresenceConfig;
126
- /** Ribbon configuration */
127
- ribbon?: RibbonConfig;
128
114
  /** Badge configuration */
129
115
  badge?: BadgeConfig;
130
116
  /** Loading strategy */
@@ -159,6 +145,8 @@ interface GroupUserData {
159
145
  name: string;
160
146
  /** Image source URL */
161
147
  src?: string;
148
+ /** External customer ID for CDN image loading */
149
+ extCustomerId?: string;
162
150
  /** Presence status from data-status attribute */
163
151
  status?: PresenceStatus;
164
152
  /** Reference to the profile-picture element */
@@ -243,7 +231,6 @@ declare class ProfilePicture extends LitElement {
243
231
  ring?: RingConfig;
244
232
  presence?: PresenceConfig;
245
233
  glow?: GlowConfig;
246
- ribbon?: RibbonConfig;
247
234
  badge?: BadgeConfig;
248
235
  loading: LoadingStrategy;
249
236
  placeholder: PlaceholderType;
@@ -276,9 +263,13 @@ declare class ProfilePicture extends LitElement {
276
263
  private renderFallback;
277
264
  private renderImage;
278
265
  private renderRing;
266
+ /**
267
+ * Calculate corner offset based on variant
268
+ * Returns the inset from container edge where badges/presence should be positioned
269
+ */
270
+ private getCornerOffset;
279
271
  private renderPresence;
280
272
  private renderBadge;
281
- private renderRibbon;
282
273
  render(): lit_html.TemplateResult<1>;
283
274
  }
284
275
 
@@ -348,4 +339,4 @@ declare global {
348
339
  }
349
340
  }
350
341
 
351
- export type { BadgeConfig, DropdownConfig, GlowConfig, GroupUserData, InteractionConfig, LoadingStrategy, PlaceholderType, Position, PresenceConfig, PresenceStatus, ProfilePictureGroupProps, ProfilePictureProps, RibbonConfig, RingConfig, ShadowPreset, Size, StackDirection, TooltipConfig, TooltipPosition, Variant };
342
+ export type { BadgeConfig, DropdownConfig, GlowConfig, GroupUserData, InteractionConfig, LoadingStrategy, PlaceholderType, Position, PresenceConfig, PresenceStatus, ProfilePictureGroupProps, ProfilePictureProps, RingConfig, ShadowPreset, Size, StackDirection, TooltipConfig, TooltipPosition, Variant };
package/dist/angular.js CHANGED
@@ -1,2 +1,2 @@
1
- var s="grasco-profile-picture-styles",n=false;function i(){if(n||typeof document>"u")return;if(document.getElementById(s)){n=true;return}if(document.querySelector('link[href*="profile-picture"][href$="styles.css"]')){n=true;return}let t=o();if(!t)return;let e=document.createElement("link");e.id=s,e.rel="stylesheet",e.href=t,document.head.appendChild(e),n=true;}function o(){if(typeof window<"u"&&window.__GRASCO_PROFILE_PICTURE_CSS__)return window.__GRASCO_PROFILE_PICTURE_CSS__;try{let t=import.meta.url;if(t)return `${t.substring(0,t.lastIndexOf("/")+1)}dist/styles.css`}catch{}let r=document.currentScript;if(r?.src){let t=new URL(r.src);return `${t.href.substring(0,t.href.lastIndexOf("/")+1)}dist/styles.css`}return null}i();//# sourceMappingURL=angular.js.map
1
+ var r="grasco-profile-picture-styles",n=false,s=false;function i(){if(n||typeof document>"u")return;if(document.getElementById(r)){n=true;return}if(document.querySelector('link[href*="profile-picture"][href$="styles.css"]')){n=true;return}s||(s=true,l());}function l(){(typeof requestIdleCallback<"u"?requestIdleCallback:e=>setTimeout(e,1))(()=>u());}function u(){if(n||typeof document>"u")return;if(document.getElementById(r)){n=true;return}let t=c();if(!t)return;let e=document.createElement("link");e.id=r,e.rel="stylesheet",e.href=t,document.head.appendChild(e),n=true;}function c(){if(typeof window<"u"&&window.__GRASCO_PROFILE_PICTURE_CSS__)return window.__GRASCO_PROFILE_PICTURE_CSS__;try{let e=import.meta.url;if(e)return `${e.substring(0,e.lastIndexOf("/")+1)}dist/styles.css`}catch{}let t=document.currentScript;if(t?.src){let e=new URL(t.src);return `${e.href.substring(0,e.href.lastIndexOf("/")+1)}dist/styles.css`}return null}i();//# sourceMappingURL=angular.js.map
2
2
  //# sourceMappingURL=angular.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/loadStyles.ts","../src/angular.ts"],"names":["LINK_ID","loaded","loadStyles","cssUrl","getCssUrl","link","metaUrl","currentScript","scriptUrl"],"mappings":"AAaA,IAAMA,CAAAA,CAAU,+BAAA,CAEZC,CAAAA,CAAS,KAAA,CAMN,SAASC,CAAAA,EAAmB,CAOjC,GALID,CAAAA,EAKA,OAAO,QAAA,CAAa,GAAA,CACtB,OAIF,GAAI,QAAA,CAAS,cAAA,CAAeD,CAAO,CAAA,CAAG,CACpCC,CAAAA,CAAS,IAAA,CACT,MACF,CAMA,GAHqB,QAAA,CAAS,aAAA,CAC5B,mDACF,CAAA,CACkB,CAChBA,EAAS,IAAA,CACT,MACF,CAGA,IAAME,CAAAA,CAASC,CAAAA,EAAU,CACzB,GAAI,CAACD,CAAAA,CACH,OAIF,IAAME,CAAAA,CAAO,QAAA,CAAS,aAAA,CAAc,MAAM,EAC1CA,CAAAA,CAAK,EAAA,CAAKL,CAAAA,CACVK,CAAAA,CAAK,GAAA,CAAM,YAAA,CACXA,CAAAA,CAAK,IAAA,CAAOF,CAAAA,CACZ,QAAA,CAAS,IAAA,CAAK,WAAA,CAAYE,CAAI,CAAA,CAE9BJ,CAAAA,CAAS,KACX,CAKA,SAASG,CAAAA,EAA2B,CAElC,GACE,OAAO,MAAA,CAAW,GAAA,EACjB,MAAA,CAA6C,8BAAA,CAE9C,OAAQ,MAAA,CACL,8BAAA,CAIL,GAAI,CACF,IAAME,CAAAA,CAAU,YAAY,GAAA,CAC5B,GAAIA,CAAAA,CAEF,OAAO,CAAA,EADUA,CAAAA,CAAQ,SAAA,CAAU,CAAA,CAAGA,CAAAA,CAAQ,WAAA,CAAY,GAAG,CAAA,CAAI,CAAC,CAChD,CAAA,eAAA,CAEtB,CAAA,KAAQ,CAER,CAGA,IAAMC,CAAAA,CAAgB,QAAA,CAAS,aAAA,CAC/B,GAAIA,CAAAA,EAAe,GAAA,CAAK,CACtB,IAAMC,CAAAA,CAAY,IAAI,GAAA,CAAID,CAAAA,CAAc,GAAG,CAAA,CAK3C,OAAO,CAAA,EAJUC,CAAAA,CAAU,IAAA,CAAK,SAAA,CAC9B,CAAA,CACAA,CAAAA,CAAU,IAAA,CAAK,WAAA,CAAY,GAAG,CAAA,CAAI,CACpC,CACkB,CAAA,eAAA,CACpB,CAEA,OAAO,IACT,CC5FAN,CAAAA,EAAW","file":"angular.js","sourcesContent":["/**\n * Idempotent CSS loader for @grasco/profile-picture\n *\n * Auto-injects the component's CSS via <link> tag when the module is imported.\n * Uses relative URL detection to find styles.css in the same directory as the JS file.\n *\n * Idempotency is guaranteed through 4 layers:\n * 1. Module-level flag - prevents multiple calls in same bundle\n * 2. ID check - prevents duplicates across bundles\n * 3. href pattern check - catches manually added links\n * 4. SSR guard - prevents errors in Node.js\n */\n\nconst LINK_ID = \"grasco-profile-picture-styles\";\n\nlet loaded = false;\n\n/**\n * Load the component's CSS stylesheet\n * Safe to call multiple times - will only inject once\n */\nexport function loadStyles(): void {\n // Skip if already loaded (module-level)\n if (loaded) {\n return;\n }\n\n // Skip if SSR (no document)\n if (typeof document === \"undefined\") {\n return;\n }\n\n // Skip if link already exists by ID (idempotency across bundles)\n if (document.getElementById(LINK_ID)) {\n loaded = true;\n return;\n }\n\n // Check if any link already points to our CSS (by href pattern)\n const existingLink = document.querySelector(\n 'link[href*=\"profile-picture\"][href$=\"styles.css\"]'\n );\n if (existingLink) {\n loaded = true;\n return;\n }\n\n // Get CSS URL relative to current script\n const cssUrl = getCssUrl();\n if (!cssUrl) {\n return;\n }\n\n // Inject link tag\n const link = document.createElement(\"link\");\n link.id = LINK_ID;\n link.rel = \"stylesheet\";\n link.href = cssUrl;\n document.head.appendChild(link);\n\n loaded = true;\n}\n\n/**\n * Get the CSS file URL based on the current script's location\n */\nfunction getCssUrl(): string | null {\n // Allow custom override via global variable\n if (\n typeof window !== \"undefined\" &&\n (window as unknown as Record<string, string>).__GRASCO_PROFILE_PICTURE_CSS__\n ) {\n return (window as unknown as Record<string, string>)\n .__GRASCO_PROFILE_PICTURE_CSS__;\n }\n\n // Try import.meta.url first (ESM - most reliable for bundlers)\n try {\n const metaUrl = import.meta.url;\n if (metaUrl) {\n const basePath = metaUrl.substring(0, metaUrl.lastIndexOf(\"/\") + 1);\n return `${basePath}dist/styles.css`;\n }\n } catch {\n // import.meta.url not available\n }\n\n // Fallback: Get current script URL\n const currentScript = document.currentScript as HTMLScriptElement | null;\n if (currentScript?.src) {\n const scriptUrl = new URL(currentScript.src);\n const basePath = scriptUrl.href.substring(\n 0,\n scriptUrl.href.lastIndexOf(\"/\") + 1\n );\n return `${basePath}dist/styles.css`;\n }\n\n return null;\n}\n","/**\n * Angular entry point\n */\n\n// Auto-load styles when module is imported\nimport { loadStyles } from \"./core/loadStyles\";\n\nloadStyles();\n\nexport * from \"./wrappers/angular\";\n"]}
1
+ {"version":3,"sources":["../src/core/loadStyles.ts","../src/angular.ts"],"names":["LINK_ID","loaded","loadScheduled","loadStyles","scheduleStyleInjection","cb","injectStyleLink","cssUrl","getCssUrl","link","metaUrl","currentScript","scriptUrl"],"mappings":"AAkBA,IAAMA,EAAU,+BAAA,CAEZC,CAAAA,CAAS,MACTC,CAAAA,CAAgB,KAAA,CAOb,SAASC,CAAAA,EAAmB,CAOjC,GALIF,CAAAA,EAKA,OAAO,QAAA,CAAa,GAAA,CACtB,OAIF,GAAI,QAAA,CAAS,eAAeD,CAAO,CAAA,CAAG,CACpCC,CAAAA,CAAS,KACT,MACF,CAMA,GAHqB,QAAA,CAAS,aAAA,CAC5B,mDACF,CAAA,CACkB,CAChBA,EAAS,IAAA,CACT,MACF,CAGKC,CAAAA,GACHA,CAAAA,CAAgB,KAChBE,CAAAA,EAAuB,EAE3B,CAMA,SAASA,CAAAA,EAA+B,CAAA,CAEpC,OAAO,oBAAwB,GAAA,CAC3B,mBAAA,CACCC,GAAmB,UAAA,CAAWA,CAAAA,CAAI,CAAC,CAAA,EAEpC,IAAMC,CAAAA,EAAiB,EAC/B,CAKA,SAASA,GAAwB,CAE/B,GAAIL,GAAU,OAAO,QAAA,CAAa,GAAA,CAChC,OAGF,GAAI,QAAA,CAAS,cAAA,CAAeD,CAAO,CAAA,CAAG,CACpCC,EAAS,IAAA,CACT,MACF,CAGA,IAAMM,CAAAA,CAASC,GAAU,CACzB,GAAI,CAACD,CAAAA,CACH,OAIF,IAAME,CAAAA,CAAO,QAAA,CAAS,aAAA,CAAc,MAAM,EAC1CA,CAAAA,CAAK,EAAA,CAAKT,EACVS,CAAAA,CAAK,GAAA,CAAM,aACXA,CAAAA,CAAK,IAAA,CAAOF,CAAAA,CACZ,QAAA,CAAS,KAAK,WAAA,CAAYE,CAAI,EAE9BR,CAAAA,CAAS,KACX,CAKA,SAASO,CAAAA,EAA2B,CAElC,GACE,OAAO,MAAA,CAAW,GAAA,EACjB,OAA6C,8BAAA,CAE9C,OAAQ,OACL,8BAAA,CAIL,GAAI,CACF,IAAME,CAAAA,CAAU,YAAY,GAAA,CAC5B,GAAIA,EAEF,OAAO,CAAA,EADUA,EAAQ,SAAA,CAAU,CAAA,CAAGA,CAAAA,CAAQ,WAAA,CAAY,GAAG,CAAA,CAAI,CAAC,CAChD,CAAA,eAAA,CAEtB,CAAA,KAAQ,CAER,CAGA,IAAMC,CAAAA,CAAgB,QAAA,CAAS,cAC/B,GAAIA,CAAAA,EAAe,IAAK,CACtB,IAAMC,EAAY,IAAI,GAAA,CAAID,CAAAA,CAAc,GAAG,EAK3C,OAAO,CAAA,EAJUC,EAAU,IAAA,CAAK,SAAA,CAC9B,EACAA,CAAAA,CAAU,IAAA,CAAK,YAAY,GAAG,CAAA,CAAI,CACpC,CACkB,CAAA,eAAA,CACpB,CAEA,OAAO,IACT,CCrIAT,CAAAA,EAAW","file":"angular.js","sourcesContent":["/**\n * Idempotent CSS loader for @grasco/profile-picture\n *\n * Auto-injects the component's CSS via <link> tag when the module is imported.\n * Uses relative URL detection to find styles.css in the same directory as the JS file.\n *\n * Idempotency is guaranteed through 4 layers:\n * 1. Module-level flag - prevents multiple calls in same bundle\n * 2. ID check - prevents duplicates across bundles\n * 3. href pattern check - catches manually added links\n * 4. SSR guard - prevents errors in Node.js\n *\n * SSR Hydration Safety:\n * Style injection is deferred using requestIdleCallback (with setTimeout fallback)\n * to avoid DOM mutations during React/framework hydration, which would cause\n * hydration mismatch errors.\n */\n\nconst LINK_ID = \"grasco-profile-picture-styles\";\n\nlet loaded = false;\nlet loadScheduled = false;\n\n/**\n * Load the component's CSS stylesheet\n * Safe to call multiple times - will only inject once\n * Defers injection to avoid SSR hydration mismatch\n */\nexport function loadStyles(): void {\n // Skip if already loaded (module-level)\n if (loaded) {\n return;\n }\n\n // Skip if SSR (no document)\n if (typeof document === \"undefined\") {\n return;\n }\n\n // Skip if link already exists by ID (idempotency across bundles)\n if (document.getElementById(LINK_ID)) {\n loaded = true;\n return;\n }\n\n // Check if any link already points to our CSS (by href pattern)\n const existingLink = document.querySelector(\n 'link[href*=\"profile-picture\"][href$=\"styles.css\"]'\n );\n if (existingLink) {\n loaded = true;\n return;\n }\n\n // Schedule deferred injection (after hydration completes)\n if (!loadScheduled) {\n loadScheduled = true;\n scheduleStyleInjection();\n }\n}\n\n/**\n * Schedule style injection after hydration using requestIdleCallback\n * Falls back to setTimeout for browsers without requestIdleCallback support\n */\nfunction scheduleStyleInjection(): void {\n const defer =\n typeof requestIdleCallback !== \"undefined\"\n ? requestIdleCallback\n : (cb: () => void) => setTimeout(cb, 1);\n\n defer(() => injectStyleLink());\n}\n\n/**\n * Actually inject the <link> tag into the document head\n */\nfunction injectStyleLink(): void {\n // Re-check conditions in case something changed\n if (loaded || typeof document === \"undefined\") {\n return;\n }\n\n if (document.getElementById(LINK_ID)) {\n loaded = true;\n return;\n }\n\n // Get CSS URL relative to current script\n const cssUrl = getCssUrl();\n if (!cssUrl) {\n return;\n }\n\n // Inject link tag\n const link = document.createElement(\"link\");\n link.id = LINK_ID;\n link.rel = \"stylesheet\";\n link.href = cssUrl;\n document.head.appendChild(link);\n\n loaded = true;\n}\n\n/**\n * Get the CSS file URL based on the current script's location\n */\nfunction getCssUrl(): string | null {\n // Allow custom override via global variable\n if (\n typeof window !== \"undefined\" &&\n (window as unknown as Record<string, string>).__GRASCO_PROFILE_PICTURE_CSS__\n ) {\n return (window as unknown as Record<string, string>)\n .__GRASCO_PROFILE_PICTURE_CSS__;\n }\n\n // Try import.meta.url first (ESM - most reliable for bundlers)\n try {\n const metaUrl = import.meta.url;\n if (metaUrl) {\n const basePath = metaUrl.substring(0, metaUrl.lastIndexOf(\"/\") + 1);\n return `${basePath}dist/styles.css`;\n }\n } catch {\n // import.meta.url not available\n }\n\n // Fallback: Get current script URL\n const currentScript = document.currentScript as HTMLScriptElement | null;\n if (currentScript?.src) {\n const scriptUrl = new URL(currentScript.src);\n const basePath = scriptUrl.href.substring(\n 0,\n scriptUrl.href.lastIndexOf(\"/\") + 1\n );\n return `${basePath}dist/styles.css`;\n }\n\n return null;\n}\n","/**\n * Angular entry point\n */\n\n// Auto-load styles when module is imported\nimport { loadStyles } from \"./core/loadStyles\";\n\nloadStyles();\n\nexport * from \"./wrappers/angular\";\n"]}