fimo-react 2.2.0-staging.7 → 2.2.0-staging.9

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.
@@ -6,7 +6,9 @@ export { DateTime } from './react/primitives/editable/DateTime.js';
6
6
  export { Boolean } from './react/primitives/editable/Boolean.js';
7
7
  export { Json } from './react/primitives/editable/Json.js';
8
8
  export { RichText } from './react/primitives/editable/RichText.js';
9
- export { FimoString, FimoDate, FimoMedia, FimoBoolean, FimoRichText, type FimoPolymorphicReference, type FimoReference, type FimoSource, type FimoPart, type FimoRichTextContent, FIMO_SOURCE, FIMO_PARTS, isFimoString, isFimoDate, hasFimoSource, getFimoSource, getFimoParts, fimo, } from 'fimo/primitives';
9
+ export { FimoString, FimoDate, FimoMedia, FimoBoolean, FimoRichText, type FimoPolymorphicReference, type FimoReference, type FimoSource, type FimoPart, type FimoRichTextContent, type FimoSourceContext, type FimoSourceContextItem, FIMO_SOURCE, FIMO_SOURCE_CONTEXT, FIMO_PARTS, isFimoString, isFimoDate, hasFimoSource, getFimoSource, getFimoSourceContext, getFimoParts, fimo, } from 'fimo/primitives';
10
+ export { getFimoSourceAttributes } from './react/primitives/source-attributes.js';
11
+ export type { FimoSourceAttributes } from './react/primitives/source-attributes.js';
10
12
  export type { BaseImageProps, BaseVideoProps, BooleanProps, DateProps, FimoRichTextComponents, FimoRichTextMarkProps, FimoRichTextNodeProps, ImageProps, JsonProps, RichTextProps, StaticImageProps, TextProps, VideoProps, } from './react/primitives/contracts.js';
11
13
  export { useFimoLiveValue } from './react/useFimoLiveValue.js';
12
14
  export { DateRenderer } from './react/primitives/renderers/DateRenderer.js';
@@ -10,7 +10,8 @@ export { Boolean } from './react/primitives/editable/Boolean.js';
10
10
  export { Json } from './react/primitives/editable/Json.js';
11
11
  export { RichText } from './react/primitives/editable/RichText.js';
12
12
  // Primitives & utilities
13
- export { FimoString, FimoDate, FimoMedia, FimoBoolean, FimoRichText, FIMO_SOURCE, FIMO_PARTS, isFimoString, isFimoDate, hasFimoSource, getFimoSource, getFimoParts, fimo, } from 'fimo/primitives';
13
+ export { FimoString, FimoDate, FimoMedia, FimoBoolean, FimoRichText, FIMO_SOURCE, FIMO_SOURCE_CONTEXT, FIMO_PARTS, isFimoString, isFimoDate, hasFimoSource, getFimoSource, getFimoSourceContext, getFimoParts, fimo, } from 'fimo/primitives';
14
+ export { getFimoSourceAttributes } from './react/primitives/source-attributes.js';
14
15
  export { useFimoLiveValue } from './react/useFimoLiveValue.js';
15
16
  export { DateRenderer } from './react/primitives/renderers/DateRenderer.js';
16
17
  export { ImageRenderer } from './react/primitives/renderers/ImageRenderer.js';
@@ -1,11 +1,12 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { FIMO_SOURCE } from 'fimo/primitives';
2
+ import { FIMO_SOURCE, getFimoSourceContext } from 'fimo/primitives';
3
3
  import { useFimoLiveValue } from '../../useFimoLiveValue.js';
4
+ import { getFimoSourceAttributes } from '../source-attributes.js';
4
5
  export function Boolean({ value, as, children, ...props }) {
5
6
  const Component = as || 'span';
6
7
  const { value: liveValue, ref } = useFimoLiveValue(value ? value.valueOf() : false);
7
8
  if (!value) {
8
9
  return null;
9
10
  }
10
- return (_jsx(Component, { ref: ref, ...props, "data-fimo-source": value[FIMO_SOURCE], children: children ? children(liveValue) : String(liveValue) }));
11
+ return (_jsx(Component, { ref: ref, ...props, ...getFimoSourceAttributes(value[FIMO_SOURCE], getFimoSourceContext(value)), children: children ? children(liveValue) : String(liveValue) }));
11
12
  }
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { FIMO_SOURCE } from 'fimo/primitives';
2
+ import { FIMO_SOURCE, getFimoSourceContext } from 'fimo/primitives';
3
3
  import { useFimoLiveValue } from '../../useFimoLiveValue.js';
4
4
  import { DateRenderer } from '../renderers/DateRenderer.js';
5
5
  export function Date({ value, ...props }) {
@@ -8,5 +8,5 @@ export function Date({ value, ...props }) {
8
8
  return null;
9
9
  }
10
10
  const source = typeof value === 'object' && FIMO_SOURCE in value ? (value[FIMO_SOURCE] ?? undefined) : undefined;
11
- return _jsx(DateRenderer, { ...props, value: liveValue, source: source, elementRef: ref });
11
+ return (_jsx(DateRenderer, { ...props, value: liveValue, source: source, context: getFimoSourceContext(value), elementRef: ref }));
12
12
  }
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { FIMO_SOURCE } from 'fimo/primitives';
2
+ import { FIMO_SOURCE, getFimoSourceContext } from 'fimo/primitives';
3
3
  import { useFimoLiveValue } from '../../useFimoLiveValue.js';
4
4
  import { DateRenderer } from '../renderers/DateRenderer.js';
5
5
  /** Renders a `datetime` field: the `dateTime` attribute keeps the whole instant. */
@@ -9,5 +9,5 @@ export function DateTime({ value, ...props }) {
9
9
  return null;
10
10
  }
11
11
  const source = typeof value === 'object' && FIMO_SOURCE in value ? (value[FIMO_SOURCE] ?? undefined) : undefined;
12
- return _jsx(DateRenderer, { ...props, value: liveValue, source: source, precision: "instant", elementRef: ref });
12
+ return (_jsx(DateRenderer, { ...props, value: liveValue, source: source, context: getFimoSourceContext(value), precision: "instant", elementRef: ref }));
13
13
  }
@@ -1,11 +1,12 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { getFimoSource } from 'fimo/primitives';
2
+ import { getFimoSource, getFimoSourceContext } from 'fimo/primitives';
3
3
  import { useFimoLiveValue } from '../../useFimoLiveValue.js';
4
+ import { getFimoSourceAttributes } from '../source-attributes.js';
4
5
  export function Json({ value, as, children, ...props }) {
5
6
  const Component = as || 'span';
6
7
  const { value: liveValue, ref } = useFimoLiveValue(value);
7
8
  if (value === null || value === undefined) {
8
9
  return null;
9
10
  }
10
- return (_jsx(Component, { ref: ref, ...props, "data-fimo-source": getFimoSource(value), children: children ? children(liveValue) : JSON.stringify(liveValue) }));
11
+ return (_jsx(Component, { ref: ref, ...props, ...getFimoSourceAttributes(getFimoSource(value), getFimoSourceContext(value)), children: children ? children(liveValue) : JSON.stringify(liveValue) }));
11
12
  }
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { FIMO_SOURCE } from 'fimo/primitives';
2
+ import { FIMO_SOURCE, getFimoSourceContext } from 'fimo/primitives';
3
3
  import { useFimoLiveValue } from '../../useFimoLiveValue.js';
4
4
  import { RichTextRenderer } from '../renderers/RichTextRenderer.js';
5
5
  export function RichText({ value, components, ...props }) {
@@ -7,5 +7,5 @@ export function RichText({ value, components, ...props }) {
7
7
  if (!value) {
8
8
  return null;
9
9
  }
10
- return (_jsx(RichTextRenderer, { ...props, document: liveContent, source: value[FIMO_SOURCE], components: components, elementRef: ref }));
10
+ return (_jsx(RichTextRenderer, { ...props, document: liveContent, source: value[FIMO_SOURCE], context: getFimoSourceContext(value), components: components, elementRef: ref }));
11
11
  }
@@ -1,7 +1,8 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { getFimoParts, getFimoSource } from 'fimo/primitives';
2
+ import { getFimoParts, getFimoSource, getFimoSourceContext } from 'fimo/primitives';
3
3
  import { Fragment } from 'react';
4
4
  import { useFimoLiveValue } from '../../useFimoLiveValue.js';
5
+ import { getFimoSourceAttributes } from '../source-attributes.js';
5
6
  /**
6
7
  * Text component for rendering text with source tracking
7
8
  *
@@ -21,6 +22,7 @@ export function Text({ value, as, children, ...props }) {
21
22
  const Component = as || 'span';
22
23
  const parts = getFimoParts(value);
23
24
  const source = getFimoSource(value);
25
+ const context = getFimoSourceContext(value);
24
26
  const { value: liveValue, ref } = useFimoLiveValue(String(value));
25
27
  // Composed fimo value with parts — decompose into individually tracked spans
26
28
  if (parts && parts.length > 1 && !children) {
@@ -28,9 +30,9 @@ export function Text({ value, as, children, ...props }) {
28
30
  }
29
31
  // Use render function if provided, otherwise display raw value
30
32
  const content = children ? children(liveValue) : liveValue;
31
- return (_jsx(Component, { ref: ref, ...props, "data-fimo-source": source, children: content }));
33
+ return (_jsx(Component, { ref: ref, ...props, ...getFimoSourceAttributes(source, context), children: content }));
32
34
  }
33
35
  function TextPart({ part }) {
34
36
  const { value: liveText, ref } = useFimoLiveValue(part.text);
35
- return (_jsx("span", { ref: ref, "data-fimo-source": part.source, children: liveText }));
37
+ return (_jsx("span", { ref: ref, ...getFimoSourceAttributes(part.source, part.context), children: liveText }));
36
38
  }
@@ -1,8 +1,9 @@
1
- import type { FimoDate, FimoString } from 'fimo/primitives';
1
+ import { type FimoDate, type FimoSourceContext, type FimoString } from 'fimo/primitives';
2
2
  import { type ReactNode, type Ref } from 'react';
3
3
  export interface DateRendererProps {
4
4
  value: FimoDate | FimoString | Date | string | number;
5
5
  source: string | undefined;
6
+ context?: FimoSourceContext;
6
7
  /**
7
8
  * `day` emits the calendar day in `dateTime`; `instant` keeps the full ISO
8
9
  * instant, which is the whole point of a `datetime` field. Defaults to `day`
@@ -13,5 +14,5 @@ export interface DateRendererProps {
13
14
  className?: string;
14
15
  elementRef?: Ref<HTMLTimeElement>;
15
16
  }
16
- export declare function DateRenderer({ value, source, precision, children, className, elementRef }: DateRendererProps): import("react/jsx-runtime").JSX.Element;
17
+ export declare function DateRenderer({ value, source, context, precision, children, className, elementRef, }: DateRendererProps): import("react/jsx-runtime").JSX.Element;
17
18
  //# sourceMappingURL=DateRenderer.d.ts.map
@@ -1,6 +1,9 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- export function DateRenderer({ value, source, precision = 'day', children, className, elementRef }) {
2
+ import { getFimoSourceContext } from 'fimo/primitives';
3
+ import { getFimoSourceAttributes } from '../source-attributes.js';
4
+ export function DateRenderer({ value, source, context, precision = 'day', children, className, elementRef, }) {
3
5
  const rawValue = value instanceof String ? value.toString() : value;
6
+ const sourceContext = context ?? getFimoSourceContext(value);
4
7
  const dateValue = new globalThis.Date(rawValue);
5
8
  const iso = dateValue.toISOString();
6
9
  const dateTime = precision === 'instant' ? iso : iso.split('T')[0];
@@ -13,5 +16,5 @@ export function DateRenderer({ value, source, precision = 'day', children, class
13
16
  month: 'short',
14
17
  day: 'numeric',
15
18
  });
16
- return (_jsx("time", { ref: elementRef, dateTime: dateTime, className: className, "data-fimo-source": source, children: content }));
19
+ return (_jsx("time", { ref: elementRef, dateTime: dateTime, className: className, ...getFimoSourceAttributes(source, sourceContext), children: content }));
17
20
  }
@@ -1,9 +1,11 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { FIMO_SOURCE, resolveImagePresentation } from 'fimo/primitives';
2
+ import { FIMO_SOURCE, getFimoSourceContext, resolveImagePresentation } from 'fimo/primitives';
3
+ import { getFimoSourceAttributes } from '../source-attributes.js';
3
4
  export function ImageRenderer({ value: media, children, quality, unoptimized = false, fit, width, height, alt: altOverride, overrideSrc, srcSet: srcSetOverride, sizes, style, hostSuffixes, elementRef, ...imgProps }) {
4
5
  const mediaSource = media[FIMO_SOURCE];
6
+ const sourceAttributes = getFimoSourceAttributes(mediaSource, getFimoSourceContext(media));
5
7
  if (children) {
6
- return (_jsx("span", { ref: elementRef, "data-fimo-source": mediaSource, children: children(media) }));
8
+ return (_jsx("span", { ref: elementRef, ...sourceAttributes, children: children(media) }));
7
9
  }
8
10
  const image = resolveImagePresentation({
9
11
  src: media.url,
@@ -26,5 +28,5 @@ export function ImageRenderer({ value: media, children, quality, unoptimized = f
26
28
  ...style,
27
29
  objectFit: image.objectFit,
28
30
  };
29
- return (_jsx("img", { ref: elementRef, src: image.src, alt: image.alt, width: image.width, height: image.height, style: finalStyle, sizes: image.sizes, srcSet: image.srcSet, ...imgProps, "data-fimo-source": mediaSource }));
31
+ return (_jsx("img", { ref: elementRef, src: image.src, alt: image.alt, width: image.width, height: image.height, style: finalStyle, sizes: image.sizes, srcSet: image.srcSet, ...imgProps, ...sourceAttributes }));
30
32
  }
@@ -1,12 +1,13 @@
1
- import type { FimoRichTextContent } from 'fimo/primitives';
1
+ import type { FimoRichTextContent, FimoSourceContext } from 'fimo/primitives';
2
2
  import { type ComponentPropsWithoutRef, type Ref } from 'react';
3
3
  import type { FimoRichTextComponents } from '../contracts.js';
4
4
  interface RichTextRendererProps extends Omit<ComponentPropsWithoutRef<'div'>, 'children'> {
5
5
  document: FimoRichTextContent | null | undefined;
6
6
  source: string | undefined;
7
+ context?: FimoSourceContext;
7
8
  components?: FimoRichTextComponents;
8
9
  elementRef?: Ref<HTMLDivElement>;
9
10
  }
10
- export declare function RichTextRenderer({ document, source, components, elementRef, ...props }: RichTextRendererProps): import("react/jsx-runtime").JSX.Element | null;
11
+ export declare function RichTextRenderer({ document, source, context, components, elementRef, ...props }: RichTextRendererProps): import("react/jsx-runtime").JSX.Element | null;
11
12
  export {};
12
13
  //# sourceMappingURL=RichTextRenderer.d.ts.map
@@ -1,5 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Fragment } from 'react';
3
+ import { getFimoSourceAttributes } from '../source-attributes.js';
3
4
  function DefaultParagraph({ children }) {
4
5
  return _jsx("p", { children: children });
5
6
  }
@@ -127,9 +128,9 @@ function renderNode(node, components, key) {
127
128
  }
128
129
  return _jsx(Fragment, { children: children }, key);
129
130
  }
130
- export function RichTextRenderer({ document, source, components, elementRef, ...props }) {
131
+ export function RichTextRenderer({ document, source, context, components, elementRef, ...props }) {
131
132
  if (!document) {
132
133
  return null;
133
134
  }
134
- return (_jsx("div", { ref: elementRef, ...props, "data-fimo-source": source, "data-fimo-richtext": "", children: renderNode(document, components, 0) }));
135
+ return (_jsx("div", { ref: elementRef, ...props, ...getFimoSourceAttributes(source, context), "data-fimo-richtext": "", children: renderNode(document, components, 0) }));
135
136
  }
@@ -1,10 +1,12 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { FIMO_SOURCE } from 'fimo/primitives';
2
+ import { FIMO_SOURCE, getFimoSourceContext } from 'fimo/primitives';
3
+ import { getFimoSourceAttributes } from '../source-attributes.js';
3
4
  export function VideoRenderer({ value: media, children, overrideSrc, autoPlay = true, loop = true, muted = true, playsInline = true, style, elementRef, ...videoProps }) {
4
5
  const mediaSource = media[FIMO_SOURCE];
6
+ const sourceAttributes = getFimoSourceAttributes(mediaSource, getFimoSourceContext(media));
5
7
  if (children) {
6
- return (_jsx("span", { ref: elementRef, "data-fimo-source": mediaSource, children: children(media) }));
8
+ return (_jsx("span", { ref: elementRef, ...sourceAttributes, children: children(media) }));
7
9
  }
8
10
  const finalSrc = overrideSrc ?? media.url;
9
- return (_jsx("video", { ref: elementRef, src: finalSrc, width: media.width, height: media.height, autoPlay: autoPlay, loop: loop, muted: muted, playsInline: playsInline, style: style, ...videoProps, "data-fimo-source": mediaSource }));
11
+ return (_jsx("video", { ref: elementRef, src: finalSrc, width: media.width, height: media.height, autoPlay: autoPlay, loop: loop, muted: muted, playsInline: playsInline, style: style, ...videoProps, ...sourceAttributes }));
10
12
  }
@@ -0,0 +1,7 @@
1
+ import type { FimoSourceContext } from 'fimo/primitives';
2
+ export type FimoSourceAttributes = {
3
+ 'data-fimo-source': string | undefined;
4
+ 'data-fimo-source-context'?: string;
5
+ };
6
+ export declare function getFimoSourceAttributes(source: string | null | undefined, context?: FimoSourceContext): FimoSourceAttributes;
7
+ //# sourceMappingURL=source-attributes.d.ts.map
@@ -0,0 +1,19 @@
1
+ const MAX_SOURCE_CONTEXT_MARKER_LENGTH = 4096;
2
+ export function getFimoSourceAttributes(source, context) {
3
+ let contextMarker;
4
+ if (context && context.length > 0) {
5
+ try {
6
+ const encoded = JSON.stringify(context);
7
+ if (encoded.length <= MAX_SOURCE_CONTEXT_MARKER_LENGTH) {
8
+ contextMarker = encoded;
9
+ }
10
+ }
11
+ catch {
12
+ contextMarker = undefined;
13
+ }
14
+ }
15
+ return {
16
+ 'data-fimo-source': source ?? undefined,
17
+ ...(contextMarker ? { 'data-fimo-source-context': contextMarker } : {}),
18
+ };
19
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fimo-react",
3
- "version": "2.2.0-staging.7",
3
+ "version": "2.2.0-staging.9",
4
4
  "description": "Fimo React runtime: content clients, labels, and source-tracked primitives.",
5
5
  "files": [
6
6
  "dist/",
@@ -43,21 +43,21 @@
43
43
  "test:watch": "vitest"
44
44
  },
45
45
  "devDependencies": {
46
- "@fimo/tsconfig": "2.2.0-staging.7",
46
+ "@fimo/tsconfig": "2.2.0-staging.9",
47
47
  "@tanstack/react-query": "^5.80.6",
48
48
  "@types/node": "22.18.6",
49
49
  "@types/react": "19.2.14",
50
50
  "@types/react-dom": "19.2.3",
51
- "fimo": "2.2.0-staging.7",
51
+ "fimo": "2.2.0-staging.9",
52
52
  "react": "19.2.4",
53
53
  "react-dom": "19.2.4",
54
54
  "typescript": "7.0.2",
55
55
  "vite": "^8.0.13",
56
- "vitest": "4.1.10"
56
+ "vitest": "4.1.11"
57
57
  },
58
58
  "peerDependencies": {
59
59
  "@tanstack/react-query": "^5.80.6",
60
- "fimo": "2.2.0-staging.7",
60
+ "fimo": "2.2.0-staging.9",
61
61
  "react": "^18.2.0 || ^19.0.0",
62
62
  "react-dom": "^18.2.0 || ^19.0.0"
63
63
  },