expo-widgets 55.0.2 → 55.0.4

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/CHANGELOG.md CHANGED
@@ -10,11 +10,29 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 55.0.4 — 2026-03-11
14
+
15
+ ### 🛠 Breaking changes
16
+
17
+ - Pass environment to Widgets and Live Activities. ([#43681](https://github.com/expo/expo/pull/43681) by [@jakex7](https://github.com/jakex7))
18
+
19
+ ### 🐛 Bug fixes
20
+
21
+ - Filter out invalid children. ([#43720](https://github.com/expo/expo/pull/43720) by [@jakex7](https://github.com/jakex7))
22
+
23
+ ## 55.0.3 — 2026-03-05
24
+
25
+ ### 🐛 Bug fixes
26
+
27
+ - [plugin] Fix reading undefined when config is not provided. ([#43568](https://github.com/expo/expo/pull/43568) by [@jakex7](https://github.com/jakex7))
28
+ - Skip server bundling in `export:embed` call for `expo-widgets` bundle ([#43602](https://github.com/expo/expo/pull/43602) by [@kitten](https://github.com/kitten))
29
+
13
30
  ## 55.0.2 — 2026-02-26
14
31
 
15
32
  ### 🎉 New features
16
33
 
17
34
  - Add support for `after(date)` dismissal policy, final content state, and `contentDate` when ending a Live Activity. ([#43472](https://github.com/expo/expo/pull/43472) by [@jakex7](https://github.com/jakex7))
35
+ - [plugin] Add `contentMarginsDisabled`. ([#43799](https://github.com/expo/expo/pull/43799) by [@jakex7](https://github.com/jakex7))
18
36
 
19
37
  ### 🐛 Bug fixes
20
38
 
@@ -1,12 +1,12 @@
1
1
  import { type EventSubscription } from 'expo-modules-core';
2
- import type { ExpoWidgetsEvents, LiveActivityComponent, LiveActivityDismissalPolicy, NativeLiveActivity, PushTokenEvent, WidgetBase, WidgetTimelineEntry } from './Widgets.types';
2
+ import type { ExpoWidgetsEvents, LiveActivityComponent, LiveActivityDismissalPolicy, NativeLiveActivity, PushTokenEvent, WidgetEnvironment, WidgetTimelineEntry } from './Widgets.types';
3
3
  /**
4
4
  * Represents a widget instance. Provides methods to manage the widget's timeline.
5
5
  */
6
6
  export declare class Widget<T extends object = object> {
7
7
  /** @hidden */
8
8
  private nativeWidgetObject;
9
- constructor(name: string, layout: (p: WidgetBase<T>) => React.JSX.Element);
9
+ constructor(name: string, layout: (props: T, environment: WidgetEnvironment) => React.JSX.Element);
10
10
  /**
11
11
  * Force reloads the widget, causing it to refresh its content and timeline.
12
12
  */
@@ -91,7 +91,7 @@ export declare function after(date: Date): {
91
91
  * @param name The widget name. Must match the `'name'` field in your widget configuration in the app config.
92
92
  * @param widget The widget component, marked with the `'widget'` directive.
93
93
  */
94
- export declare function createWidget<T extends object = object>(name: string, widget: (props: WidgetBase<T>) => React.JSX.Element): Widget<T>;
94
+ export declare function createWidget<T extends object = object>(name: string, widget: (props: T, context: WidgetEnvironment) => React.JSX.Element): Widget<T>;
95
95
  /**
96
96
  * Creates a Live Activity Factory for managing Live Activities of a specific type.
97
97
  * @param name The Live Activity name. Must match the `'name'` field in your widget configuration in the app config.
@@ -1 +1 @@
1
- {"version":3,"file":"Widgets.d.ts","sourceRoot":"","sources":["../src/Widgets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAG3D,OAAO,KAAK,EACV,iBAAiB,EACjB,qBAAqB,EACrB,2BAA2B,EAC3B,kBAAkB,EAGlB,cAAc,EACd,UAAU,EACV,mBAAmB,EACpB,MAAM,iBAAiB,CAAC;AAEzB;;GAEG;AACH,qBAAa,MAAM,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IAC3C,cAAc;IACd,OAAO,CAAC,kBAAkB,CAAqB;gBACnC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,OAAO;IAIzE;;OAEG;IACH,MAAM;IAIN;;;OAGG;IACH,cAAc,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,EAAE;IAMhD;;;OAGG;IACH,cAAc,CAAC,KAAK,EAAE,CAAC;IAIvB;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,CAAC;CAMvD;AAED;;GAEG;AACH,qBAAa,YAAY,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IACjD,cAAc;IACd,OAAO,CAAC,kBAAkB,CAAqB;gBACnC,kBAAkB,EAAE,kBAAkB;IAIlD;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/B;;;;;;OAMG;IACH,GAAG,CAAC,eAAe,CAAC,EAAE,2BAA2B,EAAE,KAAK,CAAC,EAAE,CAAC,EAAE,WAAW,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBhG;;;OAGG;IACH,YAAY,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAItC;;;;;OAKG;IACH,oBAAoB,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,GAAG,iBAAiB;CAGnF;AAED;;GAEG;AACH,qBAAa,mBAAmB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IACxD,cAAc;IACd,OAAO,CAAC,yBAAyB,CAA4B;gBACjD,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAO1D;;;;;OAKG;IACH,KAAK,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM;IAI5B;;OAEG;IACH,YAAY;CAKb;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG;IAAE,KAAK,EAAE,IAAI,CAAA;CAAE,CAEjD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EACpD,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,OAAO,GAClD,MAAM,CAAC,CAAC,CAAC,CAEX;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAC1D,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,qBAAqB,CAAC,CAAC,CAAC,GACrC,mBAAmB,CAAC,CAAC,CAAC,CAExB;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,iBAAiB,CAAC,8BAA8B,CAAC,GAC1D,iBAAiB,CAEnB;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,iBAAiB,CAAC,uCAAuC,CAAC,GACnE,iBAAiB,CAEnB"}
1
+ {"version":3,"file":"Widgets.d.ts","sourceRoot":"","sources":["../src/Widgets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAG3D,OAAO,KAAK,EACV,iBAAiB,EACjB,qBAAqB,EACrB,2BAA2B,EAC3B,kBAAkB,EAGlB,cAAc,EACd,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,iBAAiB,CAAC;AAEzB;;GAEG;AACH,qBAAa,MAAM,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IAC3C,cAAc;IACd,OAAO,CAAC,kBAAkB,CAAqB;gBAE7C,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,WAAW,EAAE,iBAAiB,KAAK,KAAK,CAAC,GAAG,CAAC,OAAO;IAKzE;;OAEG;IACH,MAAM;IAIN;;;OAGG;IACH,cAAc,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,EAAE;IAMhD;;;OAGG;IACH,cAAc,CAAC,KAAK,EAAE,CAAC;IAIvB;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,CAAC;CAMvD;AAED;;GAEG;AACH,qBAAa,YAAY,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IACjD,cAAc;IACd,OAAO,CAAC,kBAAkB,CAAqB;gBACnC,kBAAkB,EAAE,kBAAkB;IAIlD;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/B;;;;;;OAMG;IACH,GAAG,CAAC,eAAe,CAAC,EAAE,2BAA2B,EAAE,KAAK,CAAC,EAAE,CAAC,EAAE,WAAW,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBhG;;;OAGG;IACH,YAAY,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAItC;;;;;OAKG;IACH,oBAAoB,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,GAAG,iBAAiB;CAGnF;AAED;;GAEG;AACH,qBAAa,mBAAmB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IACxD,cAAc;IACd,OAAO,CAAC,yBAAyB,CAA4B;gBACjD,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAO1D;;;;;OAKG;IACH,KAAK,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM;IAI5B;;OAEG;IACH,YAAY;CAKb;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG;IAAE,KAAK,EAAE,IAAI,CAAA;CAAE,CAEjD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EACpD,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,iBAAiB,KAAK,KAAK,CAAC,GAAG,CAAC,OAAO,GAClE,MAAM,CAAC,CAAC,CAAC,CAEX;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAC1D,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,qBAAqB,CAAC,CAAC,CAAC,GACrC,mBAAmB,CAAC,CAAC,CAAC,CAExB;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,iBAAiB,CAAC,8BAA8B,CAAC,GAC1D,iBAAiB,CAEnB;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,iBAAiB,CAAC,uCAAuC,CAAC,GACnE,iBAAiB,CAEnB"}
@@ -1 +1 @@
1
- {"version":3,"file":"Widgets.js","sourceRoot":"","sources":["../src/Widgets.ts"],"names":[],"mappings":"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","sourcesContent":["import { type EventSubscription } from 'expo-modules-core';\n\nimport ExpoWidgetsModule from './ExpoWidgets';\nimport type {\n ExpoWidgetsEvents,\n LiveActivityComponent,\n LiveActivityDismissalPolicy,\n NativeLiveActivity,\n NativeLiveActivityFactory,\n NativeWidgetObject,\n PushTokenEvent,\n WidgetBase,\n WidgetTimelineEntry,\n} from './Widgets.types';\n\n/**\n * Represents a widget instance. Provides methods to manage the widget's timeline.\n */\nexport class Widget<T extends object = object> {\n /** @hidden */\n private nativeWidgetObject: NativeWidgetObject;\n constructor(name: string, layout: (p: WidgetBase<T>) => React.JSX.Element) {\n this.nativeWidgetObject = new ExpoWidgetsModule.Widget(name, layout as unknown as string);\n }\n\n /**\n * Force reloads the widget, causing it to refresh its content and timeline.\n */\n reload() {\n this.nativeWidgetObject.reload();\n }\n\n /**\n * Schedules a series of updates for the widget's content and reloads the widget.\n * @param entries Timeline entries, each specifying a date and the props to display at that time.\n */\n updateTimeline(entries: WidgetTimelineEntry<T>[]) {\n this.nativeWidgetObject.updateTimeline(\n entries.map((entry) => ({ timestamp: entry.date.getTime(), props: entry.props }))\n );\n }\n\n /**\n * Sets the widget's content to the given props immediately, without scheduling a timeline.\n * @param props The properties to display in the widget.\n */\n updateSnapshot(props: T) {\n this.nativeWidgetObject.updateTimeline([{ timestamp: Date.now(), props }]);\n }\n\n /**\n * Returns the current timeline entries for the widget, including past and future entries.\n */\n async getTimeline(): Promise<WidgetTimelineEntry<T>[]> {\n return (await this.nativeWidgetObject.getTimeline()).map((entry) => ({\n date: new Date(entry.timestamp),\n props: entry.props as T,\n }));\n }\n}\n\n/**\n * Represents a Live Activity instance. Provides methods to update its content and end it.\n */\nexport class LiveActivity<T extends object = object> {\n /** @hidden */\n private nativeLiveActivity: NativeLiveActivity;\n constructor(nativeLiveActivity: NativeLiveActivity) {\n this.nativeLiveActivity = nativeLiveActivity;\n }\n\n /**\n * Updates the Live Activity's content. The UI reflects the new properties immediately.\n * @param props The updated content properties.\n */\n update(props: T): Promise<void> {\n return this.nativeLiveActivity.update(JSON.stringify(props));\n }\n\n /**\n * Ends the Live Activity.\n * @param dismissalPolicy Controls when the Live Activity is removed from the Lock Screen after ending.\n * Can be `'default'`, `'immediate'`, or `after(date)`.\n * @param props Final content properties to update after the activity ends.\n * @param contentDate The time the data in the payload was generated. If this is older than a previous update or push payload, the system ignores this update.\n */\n end(dismissalPolicy?: LiveActivityDismissalPolicy, props?: T, contentDate?: Date): Promise<void> {\n const serializedProps = props ? JSON.stringify(props) : undefined;\n if (\n typeof dismissalPolicy === 'object' &&\n dismissalPolicy !== null &&\n 'after' in dismissalPolicy\n ) {\n return this.nativeLiveActivity.end(\n 'after',\n dismissalPolicy.after?.getTime(),\n serializedProps,\n contentDate?.getTime()\n );\n }\n return this.nativeLiveActivity.end(\n dismissalPolicy,\n undefined,\n serializedProps,\n contentDate?.getTime()\n );\n }\n\n /**\n * Returns the push token for this Live Activity, used to send push notification updates via APNs.\n * Returns `null` if push notifications are not enabled or the token is not yet available.\n */\n getPushToken(): Promise<string | null> {\n return this.nativeLiveActivity.getPushToken();\n }\n\n /**\n * Adds a listener for push token update events on this Live Activity instance.\n * The token can be used to send content updates to this specific activity via APNs.\n * @param listener Callback invoked when a new push token is available.\n * @returns An event subscription that can be used to remove the listener.\n */\n addPushTokenListener(listener: (event: PushTokenEvent) => void): EventSubscription {\n return this.nativeLiveActivity.addListener('onExpoWidgetsTokenReceived', listener);\n }\n}\n\n/**\n * Manages Live Activity instances of a specific type. Use it to start new activities and retrieve currently active ones.\n */\nexport class LiveActivityFactory<T extends object = object> {\n /** @hidden */\n private nativeLiveActivityFactory: NativeLiveActivityFactory;\n constructor(name: string, layout: LiveActivityComponent<T>) {\n this.nativeLiveActivityFactory = new ExpoWidgetsModule.LiveActivityFactory(\n name,\n layout as unknown as string\n );\n }\n\n /**\n * Starts a new Live Activity with the given properties.\n * @param props The initial content properties for the Live Activity.\n * @param url An optional URL to associate with the Live Activity, used for deep linking.\n * @returns The new Live Activity instance.\n */\n start(props: T, url?: string) {\n return new LiveActivity<T>(this.nativeLiveActivityFactory.start(JSON.stringify(props), url));\n }\n\n /**\n * Returns all currently active instances of this Live Activity type.\n */\n getInstances() {\n return this.nativeLiveActivityFactory\n .getInstances()\n .map((instance) => new LiveActivity<T>(instance));\n }\n}\n\n/**\n * Creates a dismissal policy that removes the Live Activity at the specified time within a four-hour window.\n * @param date The date after which the Live Activity should be removed from the Lock Screen.\n * @hidden\n */\nexport function after(date: Date): { after: Date } {\n return { after: date };\n}\n\n/**\n * Creates a Widget instance.\n * @param name The widget name. Must match the `'name'` field in your widget configuration in the app config.\n * @param widget The widget component, marked with the `'widget'` directive.\n */\nexport function createWidget<T extends object = object>(\n name: string,\n widget: (props: WidgetBase<T>) => React.JSX.Element\n): Widget<T> {\n return new Widget<T>(name, widget);\n}\n\n/**\n * Creates a Live Activity Factory for managing Live Activities of a specific type.\n * @param name The Live Activity name. Must match the `'name'` field in your widget configuration in the app config.\n * @param liveActivity The Live Activity component, marked with the `'widget'` directive.\n */\nexport function createLiveActivity<T extends object = object>(\n name: string,\n liveActivity: LiveActivityComponent<T>\n): LiveActivityFactory<T> {\n return new LiveActivityFactory<T>(name, liveActivity);\n}\n\n/**\n * Adds a listener for widget interaction events (for example, button taps).\n * @param listener Callback function to handle user interaction events.\n * @return An event subscription that can be used to remove the listener.\n */\nexport function addUserInteractionListener(\n listener: ExpoWidgetsEvents['onExpoWidgetsUserInteraction']\n): EventSubscription {\n return ExpoWidgetsModule.addListener('onExpoWidgetsUserInteraction', listener);\n}\n\n/**\n * Adds a listener for push-to-start token events.\n * This token can be used to start live activities remotely via APNs.\n * @param listener Callback function to handle push-to-start token events.\n * @return An event subscription that can be used to remove the listener.\n */\nexport function addPushToStartTokenListener(\n listener: ExpoWidgetsEvents['onExpoWidgetsPushToStartTokenReceived']\n): EventSubscription {\n return ExpoWidgetsModule.addListener('onExpoWidgetsPushToStartTokenReceived', listener);\n}\n"]}
1
+ {"version":3,"file":"Widgets.js","sourceRoot":"","sources":["../src/Widgets.ts"],"names":[],"mappings":"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","sourcesContent":["import { type EventSubscription } from 'expo-modules-core';\n\nimport ExpoWidgetsModule from './ExpoWidgets';\nimport type {\n ExpoWidgetsEvents,\n LiveActivityComponent,\n LiveActivityDismissalPolicy,\n NativeLiveActivity,\n NativeLiveActivityFactory,\n NativeWidgetObject,\n PushTokenEvent,\n WidgetEnvironment,\n WidgetTimelineEntry,\n} from './Widgets.types';\n\n/**\n * Represents a widget instance. Provides methods to manage the widget's timeline.\n */\nexport class Widget<T extends object = object> {\n /** @hidden */\n private nativeWidgetObject: NativeWidgetObject;\n constructor(\n name: string,\n layout: (props: T, environment: WidgetEnvironment) => React.JSX.Element\n ) {\n this.nativeWidgetObject = new ExpoWidgetsModule.Widget(name, layout as unknown as string);\n }\n\n /**\n * Force reloads the widget, causing it to refresh its content and timeline.\n */\n reload() {\n this.nativeWidgetObject.reload();\n }\n\n /**\n * Schedules a series of updates for the widget's content and reloads the widget.\n * @param entries Timeline entries, each specifying a date and the props to display at that time.\n */\n updateTimeline(entries: WidgetTimelineEntry<T>[]) {\n this.nativeWidgetObject.updateTimeline(\n entries.map((entry) => ({ timestamp: entry.date.getTime(), props: entry.props }))\n );\n }\n\n /**\n * Sets the widget's content to the given props immediately, without scheduling a timeline.\n * @param props The properties to display in the widget.\n */\n updateSnapshot(props: T) {\n this.nativeWidgetObject.updateTimeline([{ timestamp: Date.now(), props }]);\n }\n\n /**\n * Returns the current timeline entries for the widget, including past and future entries.\n */\n async getTimeline(): Promise<WidgetTimelineEntry<T>[]> {\n return (await this.nativeWidgetObject.getTimeline()).map((entry) => ({\n date: new Date(entry.timestamp),\n props: entry.props as T,\n }));\n }\n}\n\n/**\n * Represents a Live Activity instance. Provides methods to update its content and end it.\n */\nexport class LiveActivity<T extends object = object> {\n /** @hidden */\n private nativeLiveActivity: NativeLiveActivity;\n constructor(nativeLiveActivity: NativeLiveActivity) {\n this.nativeLiveActivity = nativeLiveActivity;\n }\n\n /**\n * Updates the Live Activity's content. The UI reflects the new properties immediately.\n * @param props The updated content properties.\n */\n update(props: T): Promise<void> {\n return this.nativeLiveActivity.update(JSON.stringify(props));\n }\n\n /**\n * Ends the Live Activity.\n * @param dismissalPolicy Controls when the Live Activity is removed from the Lock Screen after ending.\n * Can be `'default'`, `'immediate'`, or `after(date)`.\n * @param props Final content properties to update after the activity ends.\n * @param contentDate The time the data in the payload was generated. If this is older than a previous update or push payload, the system ignores this update.\n */\n end(dismissalPolicy?: LiveActivityDismissalPolicy, props?: T, contentDate?: Date): Promise<void> {\n const serializedProps = props ? JSON.stringify(props) : undefined;\n if (\n typeof dismissalPolicy === 'object' &&\n dismissalPolicy !== null &&\n 'after' in dismissalPolicy\n ) {\n return this.nativeLiveActivity.end(\n 'after',\n dismissalPolicy.after?.getTime(),\n serializedProps,\n contentDate?.getTime()\n );\n }\n return this.nativeLiveActivity.end(\n dismissalPolicy,\n undefined,\n serializedProps,\n contentDate?.getTime()\n );\n }\n\n /**\n * Returns the push token for this Live Activity, used to send push notification updates via APNs.\n * Returns `null` if push notifications are not enabled or the token is not yet available.\n */\n getPushToken(): Promise<string | null> {\n return this.nativeLiveActivity.getPushToken();\n }\n\n /**\n * Adds a listener for push token update events on this Live Activity instance.\n * The token can be used to send content updates to this specific activity via APNs.\n * @param listener Callback invoked when a new push token is available.\n * @returns An event subscription that can be used to remove the listener.\n */\n addPushTokenListener(listener: (event: PushTokenEvent) => void): EventSubscription {\n return this.nativeLiveActivity.addListener('onExpoWidgetsTokenReceived', listener);\n }\n}\n\n/**\n * Manages Live Activity instances of a specific type. Use it to start new activities and retrieve currently active ones.\n */\nexport class LiveActivityFactory<T extends object = object> {\n /** @hidden */\n private nativeLiveActivityFactory: NativeLiveActivityFactory;\n constructor(name: string, layout: LiveActivityComponent<T>) {\n this.nativeLiveActivityFactory = new ExpoWidgetsModule.LiveActivityFactory(\n name,\n layout as unknown as string\n );\n }\n\n /**\n * Starts a new Live Activity with the given properties.\n * @param props The initial content properties for the Live Activity.\n * @param url An optional URL to associate with the Live Activity, used for deep linking.\n * @returns The new Live Activity instance.\n */\n start(props: T, url?: string) {\n return new LiveActivity<T>(this.nativeLiveActivityFactory.start(JSON.stringify(props), url));\n }\n\n /**\n * Returns all currently active instances of this Live Activity type.\n */\n getInstances() {\n return this.nativeLiveActivityFactory\n .getInstances()\n .map((instance) => new LiveActivity<T>(instance));\n }\n}\n\n/**\n * Creates a dismissal policy that removes the Live Activity at the specified time within a four-hour window.\n * @param date The date after which the Live Activity should be removed from the Lock Screen.\n * @hidden\n */\nexport function after(date: Date): { after: Date } {\n return { after: date };\n}\n\n/**\n * Creates a Widget instance.\n * @param name The widget name. Must match the `'name'` field in your widget configuration in the app config.\n * @param widget The widget component, marked with the `'widget'` directive.\n */\nexport function createWidget<T extends object = object>(\n name: string,\n widget: (props: T, context: WidgetEnvironment) => React.JSX.Element\n): Widget<T> {\n return new Widget<T>(name, widget);\n}\n\n/**\n * Creates a Live Activity Factory for managing Live Activities of a specific type.\n * @param name The Live Activity name. Must match the `'name'` field in your widget configuration in the app config.\n * @param liveActivity The Live Activity component, marked with the `'widget'` directive.\n */\nexport function createLiveActivity<T extends object = object>(\n name: string,\n liveActivity: LiveActivityComponent<T>\n): LiveActivityFactory<T> {\n return new LiveActivityFactory<T>(name, liveActivity);\n}\n\n/**\n * Adds a listener for widget interaction events (for example, button taps).\n * @param listener Callback function to handle user interaction events.\n * @return An event subscription that can be used to remove the listener.\n */\nexport function addUserInteractionListener(\n listener: ExpoWidgetsEvents['onExpoWidgetsUserInteraction']\n): EventSubscription {\n return ExpoWidgetsModule.addListener('onExpoWidgetsUserInteraction', listener);\n}\n\n/**\n * Adds a listener for push-to-start token events.\n * This token can be used to start live activities remotely via APNs.\n * @param listener Callback function to handle push-to-start token events.\n * @return An event subscription that can be used to remove the listener.\n */\nexport function addPushToStartTokenListener(\n listener: ExpoWidgetsEvents['onExpoWidgetsPushToStartTokenReceived']\n): EventSubscription {\n return ExpoWidgetsModule.addListener('onExpoWidgetsPushToStartTokenReceived', listener);\n}\n"]}
@@ -1,6 +1,27 @@
1
1
  import { SharedObject } from 'expo';
2
2
  import { ReactNode } from 'react';
3
3
  import { after } from './Widgets';
4
+ /**
5
+ * The rendering mode of the widget as provided by WidgetKit.
6
+ * - `fullColor` — Home screen widgets (default).
7
+ * - `accented` — Tinted widgets (iOS 18+) and watchOS.
8
+ * - `vibrant` — Lock screen widgets.
9
+ */
10
+ export type WidgetRenderingMode = 'fullColor' | 'accented' | 'vibrant';
11
+ /**
12
+ * The level of detail the view is recommended to have.
13
+ * The system can update the levelOfDetail value based on user proximity or other system specific factors and allow content customization adapting to show different levels of details.
14
+ * - `simplified` — The system recommends showing a simplified view with less details.
15
+ * - `default` — The system has no specific recommendation for the level of detail.
16
+ * @available iOS 26+
17
+ */
18
+ export type LevelOfDetail = 'simplified' | 'default';
19
+ /**
20
+ * The size family of the current Live Activity.
21
+ * A Live Activity you initiate on one device can also appear on a remote device that renders the Live Activity in a different family size. As a result, it renders for a specific family, depending on both the device and the location in which it appears.
22
+ * @available iOS 18+
23
+ */
24
+ export type ActivityFamily = 'small' | 'medium';
4
25
  /**
5
26
  * The widget family (size).
6
27
  * - `systemSmall` - Small square widget (2x2 grid).
@@ -12,10 +33,7 @@ import { after } from './Widgets';
12
33
  * - `accessoryInline` - Inline accessory widget for the Lock Screen.
13
34
  */
14
35
  export type WidgetFamily = 'systemSmall' | 'systemMedium' | 'systemLarge' | 'systemExtraLarge' | 'accessoryCircular' | 'accessoryRectangular' | 'accessoryInline';
15
- /**
16
- * Props passed to a widget component.
17
- */
18
- export type WidgetBase<T extends object = object> = {
36
+ export type WidgetEnvironment = {
19
37
  /**
20
38
  * The date of this timeline entry.
21
39
  */
@@ -23,8 +41,76 @@ export type WidgetBase<T extends object = object> = {
23
41
  /**
24
42
  * The widget family.
25
43
  */
26
- family: WidgetFamily;
27
- } & T;
44
+ widgetFamily: WidgetFamily;
45
+ /**
46
+ * The color scheme of the widget's environment.
47
+ */
48
+ colorScheme?: 'light' | 'dark';
49
+ /**
50
+ * A Boolean value that indicates whether the display or environment currently requires reduced luminance.
51
+ *
52
+ * When you detect this condition, lower the overall brightness of your view.
53
+ * For example, you can change large, filled shapes to be stroked, and choose less bright colors.
54
+ * @available iOS 16+
55
+ */
56
+ isLuminanceReduced?: boolean;
57
+ /**
58
+ * The widget's rendering mode, based on where the system is displaying it.
59
+ * @available iOS 16+
60
+ */
61
+ widgetRenderingMode?: WidgetRenderingMode;
62
+ /**
63
+ * A Boolean value that indicates whether an accessory family widget can display an accessory label.
64
+ * @available iOS 16+
65
+ */
66
+ showsWidgetLabel?: boolean;
67
+ /**
68
+ * The content margins for the widget.
69
+ * @available iOS 17+
70
+ */
71
+ widgetContentMargins?: {
72
+ top: number;
73
+ bottom: number;
74
+ leading: number;
75
+ trailing: number;
76
+ };
77
+ /**
78
+ * The level of detail the view is recommended to have.
79
+ * @available iOS 26+
80
+ */
81
+ levelOfDetail?: LevelOfDetail;
82
+ };
83
+ export type LiveActivityEnvironment = {
84
+ /**
85
+ * The color scheme of the activity's environment.
86
+ */
87
+ colorScheme: 'light' | 'dark';
88
+ /**
89
+ * Whether the activity is displayed in a context with reduced luminance.
90
+ * @available iOS 16+
91
+ */
92
+ isLuminanceReduced?: boolean;
93
+ /**
94
+ * Whether the activity is currently displayed in fullscreen.
95
+ * @available iOS 16.1+
96
+ */
97
+ isActivityFullscreen?: boolean;
98
+ /**
99
+ * A Boolean value that indicates whether the Live Activity update synchronization rate is reduced.
100
+ * @available iOS 18+
101
+ */
102
+ isActivityUpdateReduced?: boolean;
103
+ /**
104
+ * The size family of the current Live Activity.
105
+ * @available iOS 18+
106
+ */
107
+ activityFamily?: ActivityFamily;
108
+ /**
109
+ * The level of detail the view is recommended to have.
110
+ * @available iOS 26+
111
+ */
112
+ levelOfDetail?: LevelOfDetail;
113
+ };
28
114
  export type WidgetTimelineEntry<T extends object = object> = {
29
115
  /**
30
116
  * Date when widget should update.
@@ -83,7 +169,7 @@ export type LiveActivityLayout = {
83
169
  /**
84
170
  * A function that returns the layout for a Live Activity.
85
171
  */
86
- export type LiveActivityComponent<T extends object = object> = (props?: T) => LiveActivityLayout;
172
+ export type LiveActivityComponent<T extends object = object> = (props: T, environment: LiveActivityEnvironment) => LiveActivityLayout;
87
173
  /**
88
174
  * Event emitted when a user interacts with a widget.
89
175
  */
@@ -1 +1 @@
1
- {"version":3,"file":"Widgets.types.d.ts","sourceRoot":"","sources":["../src/Widgets.types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Widgets.types.d.ts","sourceRoot":"","sources":["../src/Widgets.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAElC,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAElC;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG,UAAU,GAAG,SAAS,CAAC;AAEvE;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,SAAS,CAAC;AAErD;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEhD;;;;;;;;;GASG;AACH,MAAM,MAAM,YAAY,GACpB,aAAa,GACb,cAAc,GACd,aAAa,GACb,kBAAkB,GAClB,mBAAmB,GACnB,sBAAsB,GACtB,iBAAiB,CAAC;AAEtB,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;OAEG;IACH,IAAI,EAAE,IAAI,CAAC;IACX;;OAEG;IACH,YAAY,EAAE,YAAY,CAAC;IAC3B;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC/B;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;OAGG;IACH,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;OAGG;IACH,oBAAoB,CAAC,EAAE;QACrB,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF;;;OAGG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC;;OAEG;IACH,WAAW,EAAE,OAAO,GAAG,MAAM,CAAC;IAC9B;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;OAGG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;OAGG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC;;;OAGG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC;;;OAGG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,mBAAmB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI;IAC3D;;OAEG;IACH,IAAI,EAAE,IAAI,CAAC;IACX;;OAEG;IACH,KAAK,EAAE,CAAC,CAAC;CACV,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC5B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B;;OAEG;IACH,MAAM,EAAE,SAAS,CAAC;IAClB;;OAEG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB;;OAEG;IACH,cAAc,CAAC,EAAE,SAAS,CAAC;IAC3B;;OAEG;IACH,eAAe,CAAC,EAAE,SAAS,CAAC;IAC5B;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,cAAc,CAAC,EAAE,SAAS,CAAC;IAC3B;;OAEG;IACH,eAAe,CAAC,EAAE,SAAS,CAAC;IAC5B;;OAEG;IACH,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAC7B;;OAEG;IACH,cAAc,CAAC,EAAE,SAAS,CAAC;CAC5B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,qBAAqB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI,CAC7D,KAAK,EAAE,CAAC,EACR,WAAW,EAAE,uBAAuB,KACjC,kBAAkB,CAAC;AAExB;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,IAAI,EAAE,4BAA4B,CAAC;CACpC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC;;OAEG;IACH,wBAAwB,EAAE,MAAM,CAAC;CAClC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,2BAA2B,GAAG,SAAS,GAAG,WAAW,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC;AAE7F,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;OAGG;IACH,4BAA4B,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACpE;;;OAGG;IACH,qCAAqC,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;CAC/E,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B;;;OAGG;IACH,0BAA0B,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;CAC7D,CAAC;AAEF,MAAM,CAAC,OAAO,OAAO,kBAAmB,SAAQ,YAAY;gBAC9C,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IACxC,MAAM,IAAI,IAAI;IACd,cAAc,CAAC,OAAO,EAAE,iBAAiB,EAAE,GAAG,IAAI;IAClD,WAAW,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC;CAC5C;AAED,MAAM,CAAC,OAAO,OAAO,yBAA0B,SAAQ,YAAY;gBACrD,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IACxC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,kBAAkB;IACtD,YAAY,IAAI,kBAAkB,EAAE;CACrC;AAED,MAAM,CAAC,OAAO,OAAO,kBAAmB,SAAQ,YAAY,CAAC,kBAAkB,CAAC;IAC9E,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IACpC,GAAG,CACD,eAAe,CAAC,EAAE,MAAM,EACxB,SAAS,CAAC,EAAE,MAAM,EAClB,KAAK,CAAC,EAAE,MAAM,EACd,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC;IAChB,YAAY,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CACvC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Widgets.types.js","sourceRoot":"","sources":["../src/Widgets.types.ts"],"names":[],"mappings":"","sourcesContent":["import { SharedObject } from 'expo';\nimport { ReactNode } from 'react';\n\nimport { after } from './Widgets';\n\n/**\n * The widget family (size).\n * - `systemSmall` - Small square widget (2x2 grid).\n * - `systemMedium` - Medium widget (4x2 grid).\n * - `systemLarge` - Large widget (4x4 grid).\n * - `systemExtraLarge` - Extra large widget (iPad only, 6x4 grid).\n * - `accessoryCircular` - Circular accessory widget for the Lock Screen.\n * - `accessoryRectangular` - Rectangular accessory widget for the Lock Screen.\n * - `accessoryInline` - Inline accessory widget for the Lock Screen.\n */\nexport type WidgetFamily =\n | 'systemSmall'\n | 'systemMedium'\n | 'systemLarge'\n | 'systemExtraLarge'\n | 'accessoryCircular'\n | 'accessoryRectangular'\n | 'accessoryInline';\n\n/**\n * Props passed to a widget component.\n */\nexport type WidgetBase<T extends object = object> = {\n /**\n * The date of this timeline entry.\n */\n date: Date;\n /**\n * The widget family.\n */\n family: WidgetFamily;\n} & T;\n\nexport type WidgetTimelineEntry<T extends object = object> = {\n /**\n * Date when widget should update.\n */\n date: Date;\n /**\n * Props to be passed to the widget.\n */\n props: T;\n};\n\nexport type ExpoTimelineEntry = {\n timestamp: number;\n props: Record<string, any>;\n};\n\n/**\n * Defines the layout sections for an iOS Live Activity.\n */\nexport type LiveActivityLayout = {\n /**\n * The main banner content displayed in Notifications Center.\n */\n banner: ReactNode;\n /**\n * The small banner content displayed in CarPlay and WatchOS. Falls back to `banner` if not provided.\n */\n bannerSmall?: ReactNode;\n /**\n * The leading content in the compact Dynamic Island presentation.\n */\n compactLeading?: ReactNode;\n /**\n * The trailing content in the compact Dynamic Island presentation.\n */\n compactTrailing?: ReactNode;\n /**\n * The minimal content shown when the Dynamic Island is in its smallest form.\n */\n minimal?: ReactNode;\n /**\n * The center content in the expanded Dynamic Island presentation.\n */\n expandedCenter?: ReactNode;\n /**\n * The leading content in the expanded Dynamic Island presentation.\n */\n expandedLeading?: ReactNode;\n /**\n * The trailing content in the expanded Dynamic Island presentation.\n */\n expandedTrailing?: ReactNode;\n /**\n * The bottom content in the expanded Dynamic Island presentation.\n */\n expandedBottom?: ReactNode;\n};\n\n/**\n * A function that returns the layout for a Live Activity.\n */\nexport type LiveActivityComponent<T extends object = object> = (props?: T) => LiveActivityLayout;\n\n/**\n * Event emitted when a user interacts with a widget.\n */\nexport type UserInteractionEvent = {\n /**\n * Widget that triggered the interaction.\n */\n source: string;\n /**\n * Button/toggle that was pressed.\n */\n target: string;\n /**\n * Timestamp of the event.\n */\n timestamp: number;\n /**\n * The event type identifier.\n */\n type: 'ExpoWidgetsUserInteraction';\n};\n\n/**\n * Event emitted when a push token is received for a live activity.\n */\nexport type PushTokenEvent = {\n /**\n * The ID of the live activity.\n */\n activityId: string;\n /**\n * The push token for the live activity.\n */\n pushToken: string;\n};\n\n/**\n * Event emitted when a push-to-start token is received.\n */\nexport type PushToStartTokenEvent = {\n /**\n * The push-to-start token for starting live activities remotely.\n */\n activityPushToStartToken: string;\n};\n\n/**\n * Dismissal policy for ending a live activity.\n * - `'default'` - The system’s default dismissal policy for the Live Activity.\n * - `'immediate'` - The system immediately removes the Live Activity that ended.\n * - `after(date)` - The system removes the Live Activity that ended at the specified time within a four-hour window.\n */\nexport type LiveActivityDismissalPolicy = 'default' | 'immediate' | ReturnType<typeof after>;\n\nexport type ExpoWidgetsEvents = {\n /**\n * Function that is invoked when user interacts with a widget.\n * @param event Interaction event details.\n */\n onExpoWidgetsUserInteraction: (event: UserInteractionEvent) => void;\n /**\n * Function that is invoked when a push-to-start token is received.\n * @param event Token event details.\n */\n onExpoWidgetsPushToStartTokenReceived: (event: PushToStartTokenEvent) => void;\n};\n\nexport type LiveActivityEvents = {\n /**\n * Function that is invoked when a push token is received for a live activity.\n * @param event Token event details.\n */\n onExpoWidgetsTokenReceived: (event: PushTokenEvent) => void;\n};\n\nexport declare class NativeWidgetObject extends SharedObject {\n constructor(name: string, layout: string);\n reload(): void;\n updateTimeline(entries: ExpoTimelineEntry[]): void;\n getTimeline(): Promise<ExpoTimelineEntry[]>;\n}\n\nexport declare class NativeLiveActivityFactory extends SharedObject {\n constructor(name: string, layout: string);\n start(props: string, url?: string): NativeLiveActivity;\n getInstances(): NativeLiveActivity[];\n}\n\nexport declare class NativeLiveActivity extends SharedObject<LiveActivityEvents> {\n update(props: string): Promise<void>;\n end(\n dismissalPolicy?: string,\n afterDate?: number,\n state?: string,\n contentDate?: number\n ): Promise<void>;\n getPushToken(): Promise<string | null>;\n}\n"]}
1
+ {"version":3,"file":"Widgets.types.js","sourceRoot":"","sources":["../src/Widgets.types.ts"],"names":[],"mappings":"","sourcesContent":["import { SharedObject } from 'expo';\nimport { ReactNode } from 'react';\n\nimport { after } from './Widgets';\n\n/**\n * The rendering mode of the widget as provided by WidgetKit.\n * - `fullColor` — Home screen widgets (default).\n * - `accented` — Tinted widgets (iOS 18+) and watchOS.\n * - `vibrant` — Lock screen widgets.\n */\nexport type WidgetRenderingMode = 'fullColor' | 'accented' | 'vibrant';\n\n/**\n * The level of detail the view is recommended to have.\n * The system can update the levelOfDetail value based on user proximity or other system specific factors and allow content customization adapting to show different levels of details.\n * - `simplified` — The system recommends showing a simplified view with less details.\n * - `default` — The system has no specific recommendation for the level of detail.\n * @available iOS 26+\n */\nexport type LevelOfDetail = 'simplified' | 'default';\n\n/**\n * The size family of the current Live Activity.\n * A Live Activity you initiate on one device can also appear on a remote device that renders the Live Activity in a different family size. As a result, it renders for a specific family, depending on both the device and the location in which it appears.\n * @available iOS 18+\n */\nexport type ActivityFamily = 'small' | 'medium';\n\n/**\n * The widget family (size).\n * - `systemSmall` - Small square widget (2x2 grid).\n * - `systemMedium` - Medium widget (4x2 grid).\n * - `systemLarge` - Large widget (4x4 grid).\n * - `systemExtraLarge` - Extra large widget (iPad only, 6x4 grid).\n * - `accessoryCircular` - Circular accessory widget for the Lock Screen.\n * - `accessoryRectangular` - Rectangular accessory widget for the Lock Screen.\n * - `accessoryInline` - Inline accessory widget for the Lock Screen.\n */\nexport type WidgetFamily =\n | 'systemSmall'\n | 'systemMedium'\n | 'systemLarge'\n | 'systemExtraLarge'\n | 'accessoryCircular'\n | 'accessoryRectangular'\n | 'accessoryInline';\n\nexport type WidgetEnvironment = {\n /**\n * The date of this timeline entry.\n */\n date: Date;\n /**\n * The widget family.\n */\n widgetFamily: WidgetFamily;\n /**\n * The color scheme of the widget's environment.\n */\n colorScheme?: 'light' | 'dark';\n /**\n * A Boolean value that indicates whether the display or environment currently requires reduced luminance.\n *\n * When you detect this condition, lower the overall brightness of your view.\n * For example, you can change large, filled shapes to be stroked, and choose less bright colors.\n * @available iOS 16+\n */\n isLuminanceReduced?: boolean;\n /**\n * The widget's rendering mode, based on where the system is displaying it.\n * @available iOS 16+\n */\n widgetRenderingMode?: WidgetRenderingMode;\n /**\n * A Boolean value that indicates whether an accessory family widget can display an accessory label.\n * @available iOS 16+\n */\n showsWidgetLabel?: boolean;\n /**\n * The content margins for the widget.\n * @available iOS 17+\n */\n widgetContentMargins?: {\n top: number;\n bottom: number;\n leading: number;\n trailing: number;\n };\n /**\n * The level of detail the view is recommended to have.\n * @available iOS 26+\n */\n levelOfDetail?: LevelOfDetail;\n};\n\nexport type LiveActivityEnvironment = {\n /**\n * The color scheme of the activity's environment.\n */\n colorScheme: 'light' | 'dark';\n /**\n * Whether the activity is displayed in a context with reduced luminance.\n * @available iOS 16+\n */\n isLuminanceReduced?: boolean;\n /**\n * Whether the activity is currently displayed in fullscreen.\n * @available iOS 16.1+\n */\n isActivityFullscreen?: boolean;\n /**\n * A Boolean value that indicates whether the Live Activity update synchronization rate is reduced.\n * @available iOS 18+\n */\n isActivityUpdateReduced?: boolean;\n /**\n * The size family of the current Live Activity.\n * @available iOS 18+\n */\n activityFamily?: ActivityFamily;\n /**\n * The level of detail the view is recommended to have.\n * @available iOS 26+\n */\n levelOfDetail?: LevelOfDetail;\n};\n\nexport type WidgetTimelineEntry<T extends object = object> = {\n /**\n * Date when widget should update.\n */\n date: Date;\n /**\n * Props to be passed to the widget.\n */\n props: T;\n};\n\nexport type ExpoTimelineEntry = {\n timestamp: number;\n props: Record<string, any>;\n};\n\n/**\n * Defines the layout sections for an iOS Live Activity.\n */\nexport type LiveActivityLayout = {\n /**\n * The main banner content displayed in Notifications Center.\n */\n banner: ReactNode;\n /**\n * The small banner content displayed in CarPlay and WatchOS. Falls back to `banner` if not provided.\n */\n bannerSmall?: ReactNode;\n /**\n * The leading content in the compact Dynamic Island presentation.\n */\n compactLeading?: ReactNode;\n /**\n * The trailing content in the compact Dynamic Island presentation.\n */\n compactTrailing?: ReactNode;\n /**\n * The minimal content shown when the Dynamic Island is in its smallest form.\n */\n minimal?: ReactNode;\n /**\n * The center content in the expanded Dynamic Island presentation.\n */\n expandedCenter?: ReactNode;\n /**\n * The leading content in the expanded Dynamic Island presentation.\n */\n expandedLeading?: ReactNode;\n /**\n * The trailing content in the expanded Dynamic Island presentation.\n */\n expandedTrailing?: ReactNode;\n /**\n * The bottom content in the expanded Dynamic Island presentation.\n */\n expandedBottom?: ReactNode;\n};\n\n/**\n * A function that returns the layout for a Live Activity.\n */\nexport type LiveActivityComponent<T extends object = object> = (\n props: T,\n environment: LiveActivityEnvironment\n) => LiveActivityLayout;\n\n/**\n * Event emitted when a user interacts with a widget.\n */\nexport type UserInteractionEvent = {\n /**\n * Widget that triggered the interaction.\n */\n source: string;\n /**\n * Button/toggle that was pressed.\n */\n target: string;\n /**\n * Timestamp of the event.\n */\n timestamp: number;\n /**\n * The event type identifier.\n */\n type: 'ExpoWidgetsUserInteraction';\n};\n\n/**\n * Event emitted when a push token is received for a live activity.\n */\nexport type PushTokenEvent = {\n /**\n * The ID of the live activity.\n */\n activityId: string;\n /**\n * The push token for the live activity.\n */\n pushToken: string;\n};\n\n/**\n * Event emitted when a push-to-start token is received.\n */\nexport type PushToStartTokenEvent = {\n /**\n * The push-to-start token for starting live activities remotely.\n */\n activityPushToStartToken: string;\n};\n\n/**\n * Dismissal policy for ending a live activity.\n * - `'default'` - The system’s default dismissal policy for the Live Activity.\n * - `'immediate'` - The system immediately removes the Live Activity that ended.\n * - `after(date)` - The system removes the Live Activity that ended at the specified time within a four-hour window.\n */\nexport type LiveActivityDismissalPolicy = 'default' | 'immediate' | ReturnType<typeof after>;\n\nexport type ExpoWidgetsEvents = {\n /**\n * Function that is invoked when user interacts with a widget.\n * @param event Interaction event details.\n */\n onExpoWidgetsUserInteraction: (event: UserInteractionEvent) => void;\n /**\n * Function that is invoked when a push-to-start token is received.\n * @param event Token event details.\n */\n onExpoWidgetsPushToStartTokenReceived: (event: PushToStartTokenEvent) => void;\n};\n\nexport type LiveActivityEvents = {\n /**\n * Function that is invoked when a push token is received for a live activity.\n * @param event Token event details.\n */\n onExpoWidgetsTokenReceived: (event: PushTokenEvent) => void;\n};\n\nexport declare class NativeWidgetObject extends SharedObject {\n constructor(name: string, layout: string);\n reload(): void;\n updateTimeline(entries: ExpoTimelineEntry[]): void;\n getTimeline(): Promise<ExpoTimelineEntry[]>;\n}\n\nexport declare class NativeLiveActivityFactory extends SharedObject {\n constructor(name: string, layout: string);\n start(props: string, url?: string): NativeLiveActivity;\n getInstances(): NativeLiveActivity[];\n}\n\nexport declare class NativeLiveActivity extends SharedObject<LiveActivityEvents> {\n update(props: string): Promise<void>;\n end(\n dismissalPolicy?: string,\n afterDate?: number,\n state?: string,\n contentDate?: number\n ): Promise<void>;\n getPushToken(): Promise<string | null>;\n}\n"]}
package/build/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export * from './Widgets';
2
- export { ExpoWidgetsEvents, LiveActivityComponent, LiveActivityDismissalPolicy, LiveActivityEvents, LiveActivityLayout, PushTokenEvent, PushToStartTokenEvent, UserInteractionEvent, WidgetBase, WidgetFamily, WidgetTimelineEntry, } from './Widgets.types';
2
+ export { ExpoWidgetsEvents, LevelOfDetail, LiveActivityComponent, LiveActivityDismissalPolicy, LiveActivityEvents, LiveActivityLayout, PushTokenEvent, PushToStartTokenEvent, UserInteractionEvent, WidgetEnvironment, WidgetFamily, WidgetRenderingMode, WidgetTimelineEntry, } from './Widgets.types';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,2BAA2B,EAC3B,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACpB,UAAU,EACV,YAAY,EACZ,mBAAmB,GACpB,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,qBAAqB,EACrB,2BAA2B,EAC3B,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACpB,iBAAiB,EACjB,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC","sourcesContent":["export * from './Widgets';\nexport {\n ExpoWidgetsEvents,\n LiveActivityComponent,\n LiveActivityDismissalPolicy,\n LiveActivityEvents,\n LiveActivityLayout,\n PushTokenEvent,\n PushToStartTokenEvent,\n UserInteractionEvent,\n WidgetBase,\n WidgetFamily,\n WidgetTimelineEntry,\n} from './Widgets.types';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC","sourcesContent":["export * from './Widgets';\nexport {\n ExpoWidgetsEvents,\n LevelOfDetail,\n LiveActivityComponent,\n LiveActivityDismissalPolicy,\n LiveActivityEvents,\n LiveActivityLayout,\n PushTokenEvent,\n PushToStartTokenEvent,\n UserInteractionEvent,\n WidgetEnvironment,\n WidgetFamily,\n WidgetRenderingMode,\n WidgetTimelineEntry,\n} from './Widgets.types';\n"]}
package/bundle/index.ts CHANGED
@@ -6,39 +6,35 @@ import * as modifiers from '@expo/ui/swift-ui/modifiers';
6
6
  import * as jsxRuntime from './jsx-runtime-stub';
7
7
  import * as React from './react-stub';
8
8
 
9
- type WidgetProps = Record<string, unknown>;
10
- type WidgetNode = { props?: WidgetProps };
9
+ type Dictionary = Record<string, unknown>;
11
10
 
12
11
  declare global {
13
- var __expoWidgetLayout: (props: WidgetProps) => WidgetNode;
14
- var __expoWidgetProps: WidgetProps | undefined;
15
- var __expoWidgetRender: (timestamp: number, family?: string) => WidgetProps;
12
+ var __expoWidgetLayout: (props: Dictionary, environment: Dictionary) => Dictionary;
13
+ var __expoWidgetRender: (props: Dictionary, environment: Dictionary) => Dictionary;
16
14
  var __expoWidgetHandlePress: (
17
- timestamp: number,
18
- family: string | undefined,
19
- target: string | undefined
20
- ) => WidgetProps | undefined;
15
+ environment: Dictionary & { target?: string }
16
+ ) => Dictionary | undefined;
21
17
  }
22
18
 
23
- const __expoWidgetRender = function (timestamp: number, family?: string) {
24
- if (family) {
25
- return globalThis.__expoWidgetLayout(
26
- Object.assign({ date: new Date(timestamp), family }, globalThis.__expoWidgetProps || {})
27
- );
19
+ const __expoWidgetRender = function (props: Dictionary, environment: Dictionary) {
20
+ const { timestamp, ...rest } = environment;
21
+ const decoratedEnvironment: Dictionary = { ...rest };
22
+ if (timestamp) {
23
+ decoratedEnvironment.date = new Date(timestamp as number);
28
24
  }
29
- return globalThis.__expoWidgetLayout(
30
- Object.assign({ date: new Date(timestamp) }, globalThis.__expoWidgetProps || {})
31
- );
25
+
26
+ return globalThis.__expoWidgetLayout(props, decoratedEnvironment as any);
32
27
  };
33
28
 
34
29
  const __expoWidgetHandlePress = function (
35
- timestamp: number,
36
- family: string | undefined,
37
- target: string | undefined
30
+ props: Dictionary,
31
+ environment: Dictionary & { target?: string }
38
32
  ) {
39
- function findAndCallOnPress(node?: WidgetNode): WidgetProps | undefined {
33
+ const { target, ...renderEnvironment } = environment;
34
+
35
+ function findAndCallOnPress(node?: Dictionary): Dictionary | undefined {
40
36
  const props = node?.props as {
41
- onButtonPress?: () => WidgetProps;
37
+ onButtonPress?: () => Dictionary;
42
38
  target?: string;
43
39
  children?: unknown;
44
40
  };
@@ -48,7 +44,7 @@ const __expoWidgetHandlePress = function (
48
44
 
49
45
  if (props?.children && Array.isArray(props.children)) {
50
46
  for (const child of props.children) {
51
- const result = findAndCallOnPress(child as WidgetNode);
47
+ const result = findAndCallOnPress(child as Dictionary);
52
48
  if (result) {
53
49
  return result;
54
50
  }
@@ -56,8 +52,8 @@ const __expoWidgetHandlePress = function (
56
52
  }
57
53
  }
58
54
 
59
- const node = globalThis.__expoWidgetRender(timestamp, family);
60
- return findAndCallOnPress(node as WidgetNode);
55
+ const node = globalThis.__expoWidgetRender(props, renderEnvironment);
56
+ return findAndCallOnPress(node as Dictionary);
61
57
  };
62
58
 
63
59
  Object.assign(globalThis, {
@@ -34,12 +34,15 @@ struct WidgetUserInteraction: AppIntent {
34
34
  let entryIndex,
35
35
  let entry = timeline[entryIndex] as? [String: Any],
36
36
  let props = entry["props"] as? [String: Any],
37
- let context = createWidgetContext(layout: layout, props: props) else {
37
+ let context = createWidgetContext(layout: layout) else {
38
38
  return .result()
39
39
  }
40
- let familyKey: String? = "systemSmall"
40
+ let pressEnvironment: [String: Any] = [
41
+ "timestamp": Int(Date.now.timeIntervalSince1970 * 1000),
42
+ "target": target as Any
43
+ ]
41
44
  let result = context.objectForKeyedSubscript("__expoWidgetHandlePress")?.call(
42
- withArguments: [Int(Date.now.timeIntervalSince1970 * 1000), familyKey as Any, target as Any]
45
+ withArguments: [props, pressEnvironment]
43
46
  )
44
47
  if let newProps = result?.toObject() as? [String: Any] {
45
48
  var newEntry = entry
@@ -127,8 +127,9 @@ public struct WidgetsDynamicView: View, ExpoSwiftUI.AnyChild {
127
127
  private func updateChildren<P>(_ initialProps: P) throws
128
128
  where P: UIBaseViewProps {
129
129
  if let props = node["props"] as? [String: Any] {
130
- if let children = props["children"] as? [[String: Any]] {
131
- initialProps.children = children.map { WidgetsDynamicView(source: source, kind: kind, node: $0, entryIndex: entryIndex) }
130
+ if let children = props["children"] as? [Any] {
131
+ let validChildren = children.compactMap { $0 as? [String: Any] }
132
+ initialProps.children = validChildren.map { WidgetsDynamicView(source: source, kind: kind, node: $0, entryIndex: entryIndex) }
132
133
  } else if let child = props["children"] as? [String: Any] {
133
134
  initialProps.children = [WidgetsDynamicView(source: source, kind: kind, node: child, entryIndex: entryIndex)]
134
135
  }
@@ -3,15 +3,24 @@ import ExpoModulesCore
3
3
  import WidgetKit
4
4
 
5
5
  public struct WidgetsEntryView: View {
6
- @Environment(\.widgetFamily) var widgetFamily
6
+ @Environment(\.self) var environment
7
7
  var entry: WidgetsTimelineProvider.Entry
8
8
 
9
9
  public init(entry: WidgetsTimelineProvider.Entry) {
10
10
  self.entry = entry
11
11
  }
12
12
 
13
+ private var widgetEnvironment: [String: Any] {
14
+ var env: [String: Any] = getWidgetEnvironment(environment: environment)
15
+ env["timestamp"] = Int(entry.date.timeIntervalSince1970 * 1000)
16
+ return env
17
+ }
18
+
13
19
  public var body: some View {
14
- if let node = entry.node {
20
+ let layout = WidgetsStorage.getString(forKey: "__expo_widgets_\(entry.source)_layout") ?? ""
21
+ let node = evaluateLayout(layout: layout, props: entry.props ?? [:], environment: widgetEnvironment)
22
+
23
+ if let node {
15
24
  if #available(iOS 17.0, *) {
16
25
  WidgetsDynamicView(source: entry.source, kind: .widget, node: node, entryIndex: entry.entryIndex)
17
26
  .containerBackground(.clear, for: .widget)
@@ -3,6 +3,6 @@ import WidgetKit
3
3
  public struct WidgetsTimelineEntry: WidgetKit.TimelineEntry {
4
4
  public let date: Date
5
5
  public let source: String
6
- public let node: [String: Any]?
6
+ public let props: [String: Any]?
7
7
  public let entryIndex: Int?
8
8
  }
@@ -2,7 +2,7 @@ import WidgetKit
2
2
 
3
3
  public struct WidgetsTimelineProvider: TimelineProvider {
4
4
  public func placeholder(in context: Context) -> WidgetsTimelineEntry {
5
- WidgetsTimelineEntry(date: Date(), source: name, node: nil, entryIndex: nil)
5
+ WidgetsTimelineEntry(date: Date(), source: name, props: nil, entryIndex: nil)
6
6
  }
7
7
 
8
8
  public func getSnapshot(
@@ -11,12 +11,12 @@ public struct WidgetsTimelineProvider: TimelineProvider {
11
11
  let groupIdentifier =
12
12
  Bundle.main.object(forInfoDictionaryKey: "ExpoWidgetsAppGroupIdentifier") as? String
13
13
  guard let groupIdentifier else {
14
- completion(WidgetsTimelineEntry(date: Date(), source: name, node: nil, entryIndex: nil))
14
+ completion(WidgetsTimelineEntry(date: Date(), source: name, props: nil, entryIndex: nil))
15
15
  return
16
16
  }
17
17
 
18
18
  let entries = parseTimeline(identifier: groupIdentifier, name: name, family: context.family)
19
- completion(entries.first ?? WidgetsTimelineEntry(date: Date(), source: name, node: nil, entryIndex: nil))
19
+ completion(entries.first ?? WidgetsTimelineEntry(date: Date(), source: name, props: nil, entryIndex: nil))
20
20
  }
21
21
 
22
22
  public func getTimeline(
@@ -4,16 +4,3 @@ public enum WidgetsKind {
4
4
  case widget
5
5
  case liveActivity
6
6
  }
7
-
8
- func getKeyFor(widgetFamily: WidgetFamily) -> String {
9
- switch widgetFamily {
10
- case .systemSmall: return "systemSmall"
11
- case .systemMedium: return "systemMedium"
12
- case .systemLarge: return "systemLarge"
13
- case .systemExtraLarge: return "systemExtraLarge"
14
- case .accessoryCircular: return "accessoryCircular"
15
- case .accessoryRectangular: return "accessoryRectangular"
16
- case .accessoryInline: return "accessoryInline"
17
- default: return "systemSmall"
18
- }
19
- }
@@ -1,17 +1,16 @@
1
+ import SwiftUI
1
2
  import WidgetKit
2
3
  import Foundation
3
4
 
4
5
  func parseTimeline(identifier: String, name: String, family: WidgetFamily) -> [WidgetsTimelineEntry] {
5
- let layout = WidgetsStorage.getString(forKey: "__expo_widgets_\(name)_layout") ?? ""
6
6
  let timeline = WidgetsStorage.getArray(forKey: "__expo_widgets_\(name)_timeline") ?? []
7
7
 
8
8
  let entries: [WidgetsTimelineEntry?] = timeline.enumerated().map { index, entry in
9
9
  if let entry = entry as? [String: Any], let timestamp = entry["timestamp"] as? Int, let props = entry["props"] as? [String: Any] {
10
- let node = evaluateLayout(layout: layout, props: props, timestamp: timestamp, family: family)
11
10
  return WidgetsTimelineEntry(
12
11
  date: Date(timeIntervalSince1970: Double(timestamp) / 1000),
13
12
  source: name,
14
- node: node,
13
+ props: props,
15
14
  entryIndex: index
16
15
  )
17
16
  }
@@ -24,30 +23,31 @@ func parseTimeline(identifier: String, name: String, family: WidgetFamily) -> [W
24
23
  func evaluateLayout(
25
24
  layout: String,
26
25
  props: [String: Any],
27
- timestamp: Int,
28
- family: WidgetFamily
26
+ environment: [String: Any]
29
27
  ) -> [String: Any]? {
30
- guard let context = createWidgetContext(layout: layout, props: props) else {
28
+ guard let context = createWidgetContext(layout: layout) else {
31
29
  return nil
32
30
  }
33
- let familyKey: String? = getKeyFor(widgetFamily: family)
34
31
 
35
32
  let result = context.objectForKeyedSubscript("__expoWidgetRender")?.call(
36
- withArguments: [timestamp, familyKey as Any]
33
+ withArguments: [props, environment]
37
34
  )
38
35
  return result?.toObject() as? [String: Any]
39
36
  }
40
37
 
41
- func getLiveActivityNodes(forName name: String, props: String = "{}") -> [String: Any] {
38
+ func getLiveActivityNodes(forName name: String, props: String = "{}", environment: [String: Any]) -> [String: Any] {
42
39
  let layout = WidgetsStorage.getString(forKey: "__expo_widgets_live_activity_\(name)_layout") ?? ""
43
40
  let propsData = props.data(using: .utf8)
44
- let propsDict = propsData.flatMap { try? JSONSerialization.jsonObject(with: $0, options: []) as? [String: Any] }
45
- guard let context = createWidgetContext(layout: layout, props: propsDict ?? [:]) else {
41
+ let propsDict = propsData.flatMap { try? JSONSerialization.jsonObject(with: $0, options: []) as? [String: Any] } ?? [:]
42
+ guard let context = createWidgetContext(layout: layout) else {
46
43
  return [:]
47
44
  }
48
45
 
46
+ var widgetEnvironment = environment
47
+ widgetEnvironment["timestamp"] = Int(Date.now.timeIntervalSince1970 * 1000)
48
+
49
49
  let result = context.objectForKeyedSubscript("__expoWidgetRender")?.call(
50
- withArguments: [Int(Date.now.timeIntervalSince1970 * 1000)]
50
+ withArguments: [propsDict, environment]
51
51
  )
52
52
  return result?.toObject() as? [String: Any] ?? [:]
53
53
  }
@@ -59,3 +59,50 @@ func getLiveActivityUrl(forName name: String) -> URL? {
59
59
  }
60
60
  return nil
61
61
  }
62
+
63
+ func getWidgetEnvironment(environment: EnvironmentValues) -> [String: Any] {
64
+ var env: [String: Any] = [
65
+ "showsContainerBackground": environment.showsWidgetContainerBackground,
66
+ "widgetFamily": environment.widgetFamily.description,
67
+ "colorScheme": "\(environment.colorScheme)"
68
+ ]
69
+
70
+ if #available(iOS 16.0, *) {
71
+ env["isLuminanceReduced"] = environment.isLuminanceReduced
72
+ env["widgetRenderingMode"] = environment.widgetRenderingMode.description
73
+ env["showsWidgetLabel"] = environment.showsWidgetLabel
74
+ }
75
+ if #available(iOS 17.0, *) {
76
+ env["widgetContentMargins"] = [
77
+ "top": environment.widgetContentMargins.top,
78
+ "bottom": environment.widgetContentMargins.bottom,
79
+ "leading": environment.widgetContentMargins.leading,
80
+ "trailing": environment.widgetContentMargins.trailing,
81
+ ]
82
+ }
83
+ if #available(iOS 26.0, *) {
84
+ env["levelOfDetail"] = environment.levelOfDetail == .simplified ? "simplified" : environment.levelOfDetail == .default ? "default" : nil
85
+ }
86
+ return env
87
+ }
88
+
89
+ func getLiveActivityEnvironment(environment: EnvironmentValues) -> [String: Any] {
90
+ var env: [String: Any] = [
91
+ "colorScheme": "\(environment.colorScheme)"
92
+ ]
93
+
94
+ if #available(iOS 16.0, *) {
95
+ env["isLuminanceReduced"] = environment.isLuminanceReduced
96
+ }
97
+ if #available(iOS 16.1, *) {
98
+ env["isActivityFullscreen"] = environment.isActivityFullscreen
99
+ }
100
+ if #available(iOS 18.0, *) {
101
+ env["isActivityUpdateReduced"] = environment.isActivityUpdateReduced
102
+ env["activityFamily"] = "\(environment.activityFamily)"
103
+ }
104
+ if #available(iOS 26.0, *) {
105
+ env["levelOfDetail"] = environment.levelOfDetail == .simplified ? "simplified" : environment.levelOfDetail == .default ? "default" : nil
106
+ }
107
+ return env
108
+ }
@@ -1,7 +1,7 @@
1
1
  import Foundation
2
2
  import JavaScriptCore
3
3
 
4
- func createWidgetContext(layout: String, props: [String: Any]) -> JSContext? {
4
+ func createWidgetContext(layout: String) -> JSContext? {
5
5
  guard let context = JSContext() else {
6
6
  return nil
7
7
  }
@@ -22,9 +22,8 @@ func createWidgetContext(layout: String, props: [String: Any]) -> JSContext? {
22
22
  }
23
23
  context.evaluateScript(bundleJS)
24
24
 
25
- // Inject layout and props
25
+ // Inject layout
26
26
  let layoutValue = context.evaluateScript("(\(layout))")
27
27
  context.setObject(layoutValue, forKeyedSubscript: "__expoWidgetLayout" as NSString)
28
- context.setObject(props, forKeyedSubscript: "__expoWidgetProps" as NSString)
29
28
  return context
30
29
  }
@@ -12,55 +12,84 @@ struct LiveActivityAttributes: ActivityAttributes {
12
12
 
13
13
  @available(iOS 16.1, *)
14
14
  public struct WidgetLiveActivity: Widget {
15
+ @Environment(\.self) var env
16
+
15
17
  let widgetContext: AppContext = AppContext()
18
+
19
+ var environment: [String: Any] {
20
+ return getLiveActivityEnvironment(environment: env)
21
+ }
16
22
 
17
23
  public init() {}
18
24
 
19
25
  public var body: some WidgetConfiguration {
20
26
  ActivityConfiguration(for: LiveActivityAttributes.self) { context in
21
- let nodes = getLiveActivityNodes(forName: context.state.name, props: context.state.props)
22
- if #available(iOS 18.0, *) {
23
- LiveActivityBanner(context: context, nodes: nodes)
24
- } else {
25
- liveActivitySection("banner", source: context.activityID, nodes: nodes)
26
- }
27
+ LiveActivityBannerView(context: context, environment: environment)
27
28
  } dynamicIsland: { context in
28
- let nodes = getLiveActivityNodes(forName: context.state.name, props: context.state.props)
29
- return DynamicIsland {
30
- expandedContent(source: context.activityID, nodes: nodes)
29
+ DynamicIsland {
30
+ DynamicIslandExpandedRegion(.center) {
31
+ LiveActivitySectionView(context: context, environment: environment, sectionName: "expandedCenter")
32
+ }
33
+ DynamicIslandExpandedRegion(.leading) {
34
+ LiveActivitySectionView(context: context, environment: environment, sectionName: "expandedLeading")
35
+ }
36
+ DynamicIslandExpandedRegion(.trailing) {
37
+ LiveActivitySectionView(context: context, environment: environment, sectionName: "expandedTrailing")
38
+ }
39
+ DynamicIslandExpandedRegion(.bottom) {
40
+ LiveActivitySectionView(context: context, environment: environment, sectionName: "expandedBottom")
41
+ }
31
42
  } compactLeading: {
32
- liveActivitySection("compactLeading", source: context.activityID, nodes: nodes)
43
+ LiveActivitySectionView(context: context, environment: environment, sectionName: "compactLeading")
33
44
  } compactTrailing: {
34
- liveActivitySection("compactTrailing", source: context.activityID, nodes: nodes)
45
+ LiveActivitySectionView(context: context, environment: environment, sectionName: "compactTrailing")
35
46
  } minimal: {
36
- liveActivitySection("minimal", source: context.activityID, nodes: nodes)
47
+ LiveActivitySectionView(context: context, environment: environment, sectionName: "minimal")
37
48
  }
38
49
  .widgetURL(getLiveActivityUrl(forName: context.state.name))
39
50
  }
40
51
  .supplementalActivityFamiliesIfAvailable()
41
52
  }
53
+ }
42
54
 
43
- @DynamicIslandExpandedContentBuilder
44
- private func expandedContent(source: String, nodes: [String: Any]?) -> DynamicIslandExpandedContent<some View> {
45
- DynamicIslandExpandedRegion(.center) {
46
- liveActivitySection("expandedCenter", source: source, nodes: nodes)
47
- }
48
- DynamicIslandExpandedRegion(.leading) {
49
- liveActivitySection("expandedLeading", source: source, nodes: nodes)
50
- }
51
- DynamicIslandExpandedRegion(.trailing) {
52
- liveActivitySection("expandedTrailing", source: source, nodes: nodes)
53
- }
54
- DynamicIslandExpandedRegion(.bottom) {
55
- liveActivitySection("expandedBottom", source: source, nodes: nodes)
55
+ @available(iOS 16.1, *)
56
+ private struct LiveActivitySectionView: View {
57
+ let context: ActivityViewContext<LiveActivityAttributes>
58
+ let environment: [String: Any]
59
+ let sectionName: String
60
+
61
+ var body: some View {
62
+ let nodes = getLiveActivityNodes(
63
+ forName: context.state.name,
64
+ props: context.state.props,
65
+ environment: environment
66
+ )
67
+ if let node = nodes[sectionName] as? [String: Any] {
68
+ WidgetsDynamicView(source: context.activityID, kind: .liveActivity, node: node)
69
+ } else {
70
+ EmptyView()
56
71
  }
57
72
  }
73
+ }
58
74
 
59
- private func liveActivitySection(_ sectionName: String, source: String, nodes: [String: Any]?) -> some View {
60
- guard let node = nodes?[sectionName] as? [String: Any] else {
61
- return AnyView(EmptyView())
75
+ @available(iOS 16.1, *)
76
+ private struct LiveActivityBannerView: View {
77
+ var context: ActivityViewContext<LiveActivityAttributes>
78
+ let environment: [String: Any]
79
+
80
+ var body: some View {
81
+ let nodes = getLiveActivityNodes(
82
+ forName: context.state.name,
83
+ props: context.state.props,
84
+ environment: environment
85
+ )
86
+ if #available(iOS 18.0, *) {
87
+ LiveActivityBanner(context: context, nodes: nodes)
88
+ } else if let node = nodes["banner"] as? [String: Any] {
89
+ WidgetsDynamicView(source: context.activityID, kind: .liveActivity, node: node)
90
+ } else {
91
+ EmptyView()
62
92
  }
63
- return AnyView(WidgetsDynamicView(source: source, kind: .liveActivity, node: node))
64
93
  }
65
94
  }
66
95
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-widgets",
3
- "version": "55.0.2",
3
+ "version": "55.0.4",
4
4
  "description": "Widgets.",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -33,7 +33,7 @@
33
33
  "homepage": "https://docs.expo.dev/versions/latest/sdk/widgets/",
34
34
  "dependencies": {
35
35
  "@expo/plist": "^0.5.2",
36
- "@expo/ui": "~55.0.1"
36
+ "@expo/ui": "~55.0.2"
37
37
  },
38
38
  "devDependencies": {
39
39
  "expo-module-scripts": "^55.0.2"
@@ -42,5 +42,5 @@
42
42
  "expo": "*",
43
43
  "react": "*"
44
44
  },
45
- "gitHead": "413b0450434d3e456eb391eca792ee9ac1e1efec"
45
+ "gitHead": "bcdd2c239f8a92cdf5140e35cde768352630acd6"
46
46
  }
@@ -7,5 +7,5 @@ type ExpoWidgetsConfigPluginProps = {
7
7
  frequentUpdates?: boolean;
8
8
  widgets?: WidgetConfig[];
9
9
  };
10
- declare const _default: ConfigPlugin<ExpoWidgetsConfigPluginProps>;
10
+ declare const _default: ConfigPlugin<ExpoWidgetsConfigPluginProps | undefined>;
11
11
  export default _default;
@@ -17,7 +17,7 @@ const withWidgets = (config, props) => {
17
17
  let plugins = [];
18
18
  const deploymentTarget = '16.2';
19
19
  const targetName = 'ExpoWidgetsTarget';
20
- let bundleIdentifier = props.bundleIdentifier;
20
+ let bundleIdentifier = props?.bundleIdentifier;
21
21
  if (!bundleIdentifier) {
22
22
  bundleIdentifier = `${config.ios?.bundleIdentifier}.${targetName}`;
23
23
  plugins.push([
@@ -28,7 +28,7 @@ const withWidgets = (config, props) => {
28
28
  },
29
29
  ]);
30
30
  }
31
- let groupIdentifier = props.groupIdentifier;
31
+ let groupIdentifier = props?.groupIdentifier;
32
32
  if (!groupIdentifier) {
33
33
  if (!config.ios?.bundleIdentifier) {
34
34
  throw new Error('iOS bundle identifier is required. Please set `ios.bundleIdentifier` in `app.json` or `app.config.js`');
@@ -42,9 +42,9 @@ const withWidgets = (config, props) => {
42
42
  },
43
43
  ]);
44
44
  }
45
- const widgets = props.widgets ?? [];
46
- const enablePushNotifications = props.enablePushNotifications ?? false;
47
- const frequentUpdates = props.frequentUpdates ?? false;
45
+ const widgets = props?.widgets ?? [];
46
+ const enablePushNotifications = props?.enablePushNotifications ?? false;
47
+ const frequentUpdates = props?.frequentUpdates ?? false;
48
48
  let sharedFiles = [];
49
49
  const setFiles = (files) => {
50
50
  sharedFiles = [...sharedFiles, ...files];
@@ -4,4 +4,5 @@ export type WidgetConfig = {
4
4
  supportedFamilies: WidgetFamily[];
5
5
  displayName: string;
6
6
  description: string;
7
+ contentMarginsDisabled: boolean;
7
8
  };
@@ -117,7 +117,7 @@ struct ${widget.name}: Widget {
117
117
  }
118
118
  .configurationDisplayName("${widget.displayName}")
119
119
  .description("${widget.description}")
120
- .supportedFamilies([.${widget.supportedFamilies.join(', .')}])
120
+ .supportedFamilies([.${widget.supportedFamilies.join(', .')}])${widget.contentMarginsDisabled ? '\n .contentMarginsDisabled()' : ''}
121
121
  }
122
122
  }`;
123
123
  const infoPlist = (groupIdentifier) => `<?xml version="1.0" encoding="UTF-8"?>
@@ -24,12 +24,12 @@ type ExpoWidgetsConfigPluginProps = {
24
24
  widgets?: WidgetConfig[];
25
25
  };
26
26
 
27
- const withWidgets: ConfigPlugin<ExpoWidgetsConfigPluginProps> = (config, props) => {
27
+ const withWidgets: ConfigPlugin<ExpoWidgetsConfigPluginProps | undefined> = (config, props) => {
28
28
  let plugins: (StaticPlugin | ConfigPlugin | string)[] = [];
29
29
  const deploymentTarget = '16.2';
30
30
  const targetName = 'ExpoWidgetsTarget';
31
31
 
32
- let bundleIdentifier = props.bundleIdentifier;
32
+ let bundleIdentifier = props?.bundleIdentifier;
33
33
  if (!bundleIdentifier) {
34
34
  bundleIdentifier = `${config.ios?.bundleIdentifier}.${targetName}`;
35
35
  plugins.push([
@@ -41,7 +41,7 @@ const withWidgets: ConfigPlugin<ExpoWidgetsConfigPluginProps> = (config, props)
41
41
  ]);
42
42
  }
43
43
 
44
- let groupIdentifier = props.groupIdentifier;
44
+ let groupIdentifier = props?.groupIdentifier;
45
45
  if (!groupIdentifier) {
46
46
  if (!config.ios?.bundleIdentifier) {
47
47
  throw new Error(
@@ -58,9 +58,9 @@ const withWidgets: ConfigPlugin<ExpoWidgetsConfigPluginProps> = (config, props)
58
58
  ]);
59
59
  }
60
60
 
61
- const widgets = props.widgets ?? [];
62
- const enablePushNotifications = props.enablePushNotifications ?? false;
63
- const frequentUpdates = props.frequentUpdates ?? false;
61
+ const widgets = props?.widgets ?? [];
62
+ const enablePushNotifications = props?.enablePushNotifications ?? false;
63
+ const frequentUpdates = props?.frequentUpdates ?? false;
64
64
 
65
65
  let sharedFiles: string[] = [];
66
66
  const setFiles = (files: string[]) => {
@@ -5,4 +5,5 @@ export type WidgetConfig = {
5
5
  supportedFamilies: WidgetFamily[];
6
6
  displayName: string;
7
7
  description: string;
8
+ contentMarginsDisabled: boolean;
8
9
  };
@@ -106,7 +106,7 @@ struct ${widget.name}: Widget {
106
106
  }
107
107
  .configurationDisplayName("${widget.displayName}")
108
108
  .description("${widget.description}")
109
- .supportedFamilies([.${widget.supportedFamilies.join(', .')}])
109
+ .supportedFamilies([.${widget.supportedFamilies.join(', .')}])${widget.contentMarginsDisabled ? '\n .contentMarginsDisabled()' : ''}
110
110
  }
111
111
  }`;
112
112
 
@@ -49,7 +49,8 @@ const result = await spawn(
49
49
  '--entry-file',
50
50
  path.join(__dirname, '../bundle/index.ts'),
51
51
  '--dev',
52
- false,
52
+ 'false',
53
+ '--skip-server',
53
54
  ...argv.slice(2),
54
55
  ],
55
56
  {
package/src/Widgets.ts CHANGED
@@ -9,7 +9,7 @@ import type {
9
9
  NativeLiveActivityFactory,
10
10
  NativeWidgetObject,
11
11
  PushTokenEvent,
12
- WidgetBase,
12
+ WidgetEnvironment,
13
13
  WidgetTimelineEntry,
14
14
  } from './Widgets.types';
15
15
 
@@ -19,7 +19,10 @@ import type {
19
19
  export class Widget<T extends object = object> {
20
20
  /** @hidden */
21
21
  private nativeWidgetObject: NativeWidgetObject;
22
- constructor(name: string, layout: (p: WidgetBase<T>) => React.JSX.Element) {
22
+ constructor(
23
+ name: string,
24
+ layout: (props: T, environment: WidgetEnvironment) => React.JSX.Element
25
+ ) {
23
26
  this.nativeWidgetObject = new ExpoWidgetsModule.Widget(name, layout as unknown as string);
24
27
  }
25
28
 
@@ -174,7 +177,7 @@ export function after(date: Date): { after: Date } {
174
177
  */
175
178
  export function createWidget<T extends object = object>(
176
179
  name: string,
177
- widget: (props: WidgetBase<T>) => React.JSX.Element
180
+ widget: (props: T, context: WidgetEnvironment) => React.JSX.Element
178
181
  ): Widget<T> {
179
182
  return new Widget<T>(name, widget);
180
183
  }
@@ -3,6 +3,30 @@ import { ReactNode } from 'react';
3
3
 
4
4
  import { after } from './Widgets';
5
5
 
6
+ /**
7
+ * The rendering mode of the widget as provided by WidgetKit.
8
+ * - `fullColor` — Home screen widgets (default).
9
+ * - `accented` — Tinted widgets (iOS 18+) and watchOS.
10
+ * - `vibrant` — Lock screen widgets.
11
+ */
12
+ export type WidgetRenderingMode = 'fullColor' | 'accented' | 'vibrant';
13
+
14
+ /**
15
+ * The level of detail the view is recommended to have.
16
+ * The system can update the levelOfDetail value based on user proximity or other system specific factors and allow content customization adapting to show different levels of details.
17
+ * - `simplified` — The system recommends showing a simplified view with less details.
18
+ * - `default` — The system has no specific recommendation for the level of detail.
19
+ * @available iOS 26+
20
+ */
21
+ export type LevelOfDetail = 'simplified' | 'default';
22
+
23
+ /**
24
+ * The size family of the current Live Activity.
25
+ * A Live Activity you initiate on one device can also appear on a remote device that renders the Live Activity in a different family size. As a result, it renders for a specific family, depending on both the device and the location in which it appears.
26
+ * @available iOS 18+
27
+ */
28
+ export type ActivityFamily = 'small' | 'medium';
29
+
6
30
  /**
7
31
  * The widget family (size).
8
32
  * - `systemSmall` - Small square widget (2x2 grid).
@@ -22,10 +46,7 @@ export type WidgetFamily =
22
46
  | 'accessoryRectangular'
23
47
  | 'accessoryInline';
24
48
 
25
- /**
26
- * Props passed to a widget component.
27
- */
28
- export type WidgetBase<T extends object = object> = {
49
+ export type WidgetEnvironment = {
29
50
  /**
30
51
  * The date of this timeline entry.
31
52
  */
@@ -33,8 +54,77 @@ export type WidgetBase<T extends object = object> = {
33
54
  /**
34
55
  * The widget family.
35
56
  */
36
- family: WidgetFamily;
37
- } & T;
57
+ widgetFamily: WidgetFamily;
58
+ /**
59
+ * The color scheme of the widget's environment.
60
+ */
61
+ colorScheme?: 'light' | 'dark';
62
+ /**
63
+ * A Boolean value that indicates whether the display or environment currently requires reduced luminance.
64
+ *
65
+ * When you detect this condition, lower the overall brightness of your view.
66
+ * For example, you can change large, filled shapes to be stroked, and choose less bright colors.
67
+ * @available iOS 16+
68
+ */
69
+ isLuminanceReduced?: boolean;
70
+ /**
71
+ * The widget's rendering mode, based on where the system is displaying it.
72
+ * @available iOS 16+
73
+ */
74
+ widgetRenderingMode?: WidgetRenderingMode;
75
+ /**
76
+ * A Boolean value that indicates whether an accessory family widget can display an accessory label.
77
+ * @available iOS 16+
78
+ */
79
+ showsWidgetLabel?: boolean;
80
+ /**
81
+ * The content margins for the widget.
82
+ * @available iOS 17+
83
+ */
84
+ widgetContentMargins?: {
85
+ top: number;
86
+ bottom: number;
87
+ leading: number;
88
+ trailing: number;
89
+ };
90
+ /**
91
+ * The level of detail the view is recommended to have.
92
+ * @available iOS 26+
93
+ */
94
+ levelOfDetail?: LevelOfDetail;
95
+ };
96
+
97
+ export type LiveActivityEnvironment = {
98
+ /**
99
+ * The color scheme of the activity's environment.
100
+ */
101
+ colorScheme: 'light' | 'dark';
102
+ /**
103
+ * Whether the activity is displayed in a context with reduced luminance.
104
+ * @available iOS 16+
105
+ */
106
+ isLuminanceReduced?: boolean;
107
+ /**
108
+ * Whether the activity is currently displayed in fullscreen.
109
+ * @available iOS 16.1+
110
+ */
111
+ isActivityFullscreen?: boolean;
112
+ /**
113
+ * A Boolean value that indicates whether the Live Activity update synchronization rate is reduced.
114
+ * @available iOS 18+
115
+ */
116
+ isActivityUpdateReduced?: boolean;
117
+ /**
118
+ * The size family of the current Live Activity.
119
+ * @available iOS 18+
120
+ */
121
+ activityFamily?: ActivityFamily;
122
+ /**
123
+ * The level of detail the view is recommended to have.
124
+ * @available iOS 26+
125
+ */
126
+ levelOfDetail?: LevelOfDetail;
127
+ };
38
128
 
39
129
  export type WidgetTimelineEntry<T extends object = object> = {
40
130
  /**
@@ -97,7 +187,10 @@ export type LiveActivityLayout = {
97
187
  /**
98
188
  * A function that returns the layout for a Live Activity.
99
189
  */
100
- export type LiveActivityComponent<T extends object = object> = (props?: T) => LiveActivityLayout;
190
+ export type LiveActivityComponent<T extends object = object> = (
191
+ props: T,
192
+ environment: LiveActivityEnvironment
193
+ ) => LiveActivityLayout;
101
194
 
102
195
  /**
103
196
  * Event emitted when a user interacts with a widget.
package/src/index.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from './Widgets';
2
2
  export {
3
3
  ExpoWidgetsEvents,
4
+ LevelOfDetail,
4
5
  LiveActivityComponent,
5
6
  LiveActivityDismissalPolicy,
6
7
  LiveActivityEvents,
@@ -8,7 +9,8 @@ export {
8
9
  PushTokenEvent,
9
10
  PushToStartTokenEvent,
10
11
  UserInteractionEvent,
11
- WidgetBase,
12
+ WidgetEnvironment,
12
13
  WidgetFamily,
14
+ WidgetRenderingMode,
13
15
  WidgetTimelineEntry,
14
16
  } from './Widgets.types';