brainerce 1.1.0 → 1.3.0

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.
@@ -563,16 +563,58 @@ const suggestions = await client.getSearchSuggestions('blue', 5);
563
563
 
564
564
  Products may have custom fields defined by the store owner (e.g., "Material", "Care Instructions", "Warranty").
565
565
 
566
+ **Important:** Each metafield has a `type` field. When rendering, you **must** check `field.type` and render accordingly:
567
+
568
+ | Type | Rendering |
569
+ | ---------------------------------- | ------------------------------------------------------- |
570
+ | `IMAGE` | `<img>` thumbnail (value is URL) |
571
+ | `GALLERY` | Row of `<img>` thumbnails (value is JSON array of URLs) |
572
+ | `URL` | `<a>` clickable link |
573
+ | `COLOR` | Color swatch + hex value |
574
+ | `BOOLEAN` | "Yes" / "No" |
575
+ | `DATE` | `new Date(value).toLocaleDateString()` |
576
+ | `DATETIME` | `new Date(value).toLocaleString()` |
577
+ | `TEXT`, `TEXTAREA`, `NUMBER`, etc. | Plain text |
578
+
566
579
  ```typescript
567
580
  import { getProductMetafield, getProductMetafieldValue } from 'brainerce';
581
+ import type { ProductMetafield } from 'brainerce';
568
582
 
569
583
  // Access metafields on a product
570
584
  const product = await client.getProductBySlug('blue-shirt');
571
585
 
572
- // Get all custom fields
573
- product.metafields?.forEach((field) => {
574
- console.log(`${field.definitionName}: ${field.value}`);
575
- });
586
+ // ⚠️ MUST render based on type! Don't just show field.value as text for all types.
587
+ function MetafieldValue({ field }: { field: ProductMetafield }) {
588
+ switch (field.type) {
589
+ case 'IMAGE':
590
+ return field.value ? <img src={field.value} alt={field.definitionName} className="h-16 w-16 rounded object-cover" /> : <>-</>;
591
+ case 'GALLERY': {
592
+ let urls: string[] = [];
593
+ try { urls = JSON.parse(field.value); } catch { urls = field.value ? [field.value] : []; }
594
+ return <div className="flex gap-2">{urls.map((url, i) => <img key={i} src={url} className="h-16 w-16 rounded object-cover" />)}</div>;
595
+ }
596
+ case 'URL':
597
+ return field.value ? <a href={field.value} target="_blank" rel="noopener noreferrer">{field.value}</a> : <>-</>;
598
+ case 'COLOR':
599
+ return <span><span className="inline-block h-4 w-4 rounded-full border" style={{ backgroundColor: field.value }} /> {field.value}</span>;
600
+ case 'BOOLEAN':
601
+ return <>{field.value === 'true' ? 'Yes' : 'No'}</>;
602
+ case 'DATE':
603
+ return <>{field.value ? new Date(field.value).toLocaleDateString() : '-'}</>;
604
+ case 'DATETIME':
605
+ return <>{field.value ? new Date(field.value).toLocaleString() : '-'}</>;
606
+ default:
607
+ return <>{field.value || '-'}</>;
608
+ }
609
+ }
610
+
611
+ // Display in spec table
612
+ {product.metafields?.map(mf => (
613
+ <tr key={mf.id}>
614
+ <td>{mf.definitionName}</td>
615
+ <td><MetafieldValue field={mf} /></td>
616
+ </tr>
617
+ ))}
576
618
 
577
619
  // Get specific field by key
578
620
  const material = getProductMetafieldValue(product, 'material');