kyd-shared-badge 0.3.25 → 0.3.26

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kyd-shared-badge",
3
- "version": "0.3.25",
3
+ "version": "0.3.26",
4
4
  "private": false,
5
5
  "main": "./src/index.ts",
6
6
  "module": "./src/index.ts",
@@ -197,6 +197,24 @@ const Skills = ({ skillsCategoryRadar, headless }: { skillsMatrix?: SkillsMatrix
197
197
  return () => window.removeEventListener('resize', measure);
198
198
  }, []);
199
199
 
200
+ // Track container width changes more reliably (including print/headless layouts)
201
+ useEffect(() => {
202
+ const el = containerRef.current;
203
+ if (!el || typeof ResizeObserver === 'undefined') return;
204
+ try {
205
+ const ro = new ResizeObserver((entries) => {
206
+ for (const entry of entries) {
207
+ const width = entry.contentRect?.width || el.clientWidth || 0;
208
+ setContainerWidth(width);
209
+ }
210
+ });
211
+ ro.observe(el);
212
+ return () => ro.disconnect();
213
+ } catch {
214
+ // no-op: older engines
215
+ }
216
+ }, []);
217
+
200
218
  // Nudge layout for headless/print contexts so responsive containers measure correctly
201
219
  useEffect(() => {
202
220
  if (typeof window !== 'undefined') {
@@ -234,16 +252,29 @@ const Skills = ({ skillsCategoryRadar, headless }: { skillsMatrix?: SkillsMatrix
234
252
  <div className={'rounded-lg p-4 border kyd-avoid-break'} style={{ backgroundColor: 'var(--content-card-background)', borderColor: 'var(--icon-button-secondary)', breakInside: 'avoid', pageBreakInside: 'avoid' as unknown as undefined }}>
235
253
  <h4 className={'font-semibold mb-3'} style={{ color: 'var(--text-main)' }}>Skills Footprint</h4>
236
254
  <p className={'text-sm mb-4'} style={{ color: 'var(--text-secondary)' }}>The bubble chart visualizes individual skills, where bubble size reflects the weight of supporting evidence and placement indicates relative strength across the skill set.</p>
237
- <div ref={containerRef} className={'kyd-avoid-break'} style={{ width: '100%', height: 340, position: 'relative', breakInside: 'avoid', pageBreakInside: 'avoid' as unknown as undefined }}>
255
+ <div
256
+ ref={containerRef}
257
+ className={'kyd-avoid-break'}
258
+ style={{
259
+ width: '100%',
260
+ height: 340,
261
+ position: 'relative',
262
+ overflow: 'visible',
263
+ breakInside: 'avoid',
264
+ pageBreakInside: 'avoid' as unknown as undefined,
265
+ }}
266
+ >
238
267
  {(() => {
239
- const width = containerWidth || 600;
268
+ const measured = containerWidth || (containerRef.current?.clientWidth || 0);
269
+ const parentWidth = containerRef.current?.parentElement?.clientWidth || measured;
270
+ const width = Math.max(0, Math.min(measured, parentWidth));
240
271
  const height = 300;
241
272
  const innerWidth = Math.max(0, width);
242
273
  const innerHeight = Math.max(0, height);
243
- const packed = packBubbles(combinedBubbleData, innerWidth, innerHeight, 6);
274
+ const packed = packBubbles(combinedBubbleData, innerWidth, innerHeight, headless ? 10 : 6);
244
275
  return (
245
- <svg width={width} height={height} viewBox={`0 0 ${width} ${height}`}>
246
- <g transform={`translate(-25, -20)`}>
276
+ <svg width={'100%'} height={height} viewBox={`0 0 ${width} ${height}`} preserveAspectRatio="xMidYMid meet">
277
+ <g transform={headless ? 'translate(0, 0)' : 'translate(-25, -20)'}>
247
278
  {packed.map((b, idx) => {
248
279
  const clipId = `bubble-clip-${idx}`;
249
280
  const canShowText = b.r >= 14;