{"id":4806,"url":"https://github.com/matejkriz/react-native-today-widget","last_synced_at":"2025-04-05T06:10:41.214Z","repository":{"id":21359402,"uuid":"87564675","full_name":"matejkriz/react-native-today-widget","owner":"matejkriz","description":"iOS Today Widget in React Native","archived":false,"fork":false,"pushed_at":"2022-12-08T18:51:56.000Z","size":3517,"stargazers_count":412,"open_issues_count":62,"forks_count":28,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-04-15T07:42:08.518Z","etag":null,"topics":["ios","ios-extension","react-native","react-native-ios","today-widget","widget"],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/matejkriz.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-04-07T16:14:12.000Z","updated_at":"2024-04-02T17:40:45.000Z","dependencies_parsed_at":"2023-01-12T03:45:31.614Z","dependency_job_id":null,"html_url":"https://github.com/matejkriz/react-native-today-widget","commit_stats":null,"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matejkriz%2Freact-native-today-widget","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matejkriz%2Freact-native-today-widget/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matejkriz%2Freact-native-today-widget/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matejkriz%2Freact-native-today-widget/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/matejkriz","download_url":"https://codeload.github.com/matejkriz/react-native-today-widget/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247294541,"owners_count":20915340,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ios","ios-extension","react-native","react-native-ios","today-widget","widget"],"created_at":"2024-01-05T20:17:24.775Z","updated_at":"2025-04-05T06:10:41.197Z","avatar_url":"https://github.com/matejkriz.png","language":"Ruby","funding_links":[],"categories":["Components"],"sub_categories":["Extension"],"readme":"# React Native Today Widget\n\u003e Experimental library investigating limits of implementation iOS App Extensions using React Native.\n\nSample result from [Complex](https://github.com/matejkriz/react-native-today-widget/tree/master/Examples/Complex) example:\n\n![today_widget_example](./screenshots/complex_example.png)\n\nWhat is [Today Widget](https://developer.apple.com/ios/human-interface-guidelines/extensions/widgets/)?\n\n## Getting started\n\nThis library will help you to add iOS Today Widget App Extension without need to open XCode.\n\n### Dependencies\n\n- `xcodeproj` for linking script:\n```bash\n$ gem install xcodeproj\n```\nYou may need to use `sudo gem install xcodeproj` or `sudo gem install -n /usr/local/bin xcodeproj` depends on your Ruby installation.\n\n- For React Native compatibility, check peerDependencies in [package.json](./package.json#L50)\n\n### Setup\n\n```bash\n$ yarn add react-native-today-widget\n$ react-native link\n```\nYou could use `$ npm i react-native-today-widget --save` as well, but don't forget to save it in `package.json` dependencies. Otherwise RN will not link it.\n\n\u003e Whenever you change Bundle Identifier (CFBundleIdentifier) for main app, you have to run `./node_modules/.bin/bundle-id` script or reinstall the module (`rm -rf node_modules/react-native-today-widget \u0026\u0026 yarn`)\n\n#### Manual linking\n`react-native link` should works, but in case of some troubles, you could follow [general guide for linking libraries](https://facebook.github.io/react-native/docs/linking-libraries-ios.html#manual-linking).\n\n- file for [Step 1](https://facebook.github.io/react-native/docs/linking-libraries-ios.html#step-1) is `/node_modules/react-native-today-widget/ios/RNTodayWidgetExtension.xcodeproj`\n- as a [Step 2](https://facebook.github.io/react-native/docs/linking-libraries-ios.html#step-2), add `TodayWidgetExtension.appex` to Embedded Binaries on the General tab for your main target\n- in [Step 3](https://facebook.github.io/react-native/docs/linking-libraries-ios.html#step-3), add `$(SRCROOT)/../node_modules/react-native-today-widget/ios/TodayWidgetExtension` to Header Search Paths\n\n\n### Usage\n\nAll you need is to create an `index.widget.js` file at the root and register there your component for key `TodayWidgetExtension`:\n\n```jsx\nconst TodayWidget = () =\u003e (\n  \u003cView\u003e\n    \u003cText\u003e\n      Hello Today Widget!\n    \u003c/Text\u003e\n  \u003c/View\u003e\n);\n\nAppRegistry.registerComponent('TodayWidgetExtension', () =\u003e TodayWidget);\n```\n\n\u003e Please note that registering both the widget and the main app in `index.js` file can cause memory issues. Because the app is also bundled (even if you don't use it in your widget), and it causes 'Unable to load' error. When we split the registration into two different files, the widget and the main app are bundled seperately. See [blog post from Maxim Toyberman](https://medium.com/@maximtoyberman/building-a-react-native-today-widget-in-ios-102830825e42).\n\nIn place of `TodayWidget` component, you could use any JSX component. See [Basic example](./Examples/Basic/index.ios.js#L34).\n\nRun your app as usual:\n```bash\nreact-native run-ios\n```\n\nDisplay new widget on Search screen or by force touch on your app icon (on devices supporting 3D Touch).\n\nIf you need to see logs from TodayWidgetExtension, use:\n```bash\nreact-native log-ios\n```\n\u003e In your extension scheme’s Run phase, you specify a `host app` as the executable\n\n### Memory limitation\nThe memory limit for Today Widget on device is 16 MB. (Great explanation is in this [talk by Conrad Kramer](https://cocoaheads.tv/memory-use-in-extensions-by-conrad-kramer/))\n\nVerified experimentally using [XCode debugger](https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/debugging_with_xcode/chapters/debugging_tools.html#//apple_ref/doc/uid/TP40015022-CH8-SW16) - while loading big image, Today Widget crashes as soon as it reaches 16 MB memory usage.\n\nMemory usage of [Basic](https://github.com/matejkriz/react-native-today-widget/tree/master/Examples/Basic) example with just one Text element is about 11 MB. Up to 13 MB during content rendering.\n\n\u003e For running Today Widget on device you have to use [`Release` build configuration](http://facebook.github.io/react-native/releases/0.48/docs/running-on-device.html#2-configure-release-scheme). Development mode adds too much overhead. Only possibility to run the widget on device in development mode is using [Instruments](https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/index.html#//apple_ref/doc/uid/TP40004652-CH3-SW1) tool to temporarily disable the limit.\n\n\n### Notes\n- Every native change on widget project is only in `node_modules` so probably gitignored!\n- For recommended transparent background simply don't set any `backgroundColor` for your Today Widget component.\n- [Human Interface Guidelines](https://developer.apple.com/ios/human-interface-guidelines/extensions/widgets/)\n- More about: [iOS App Extensions](https://developer.apple.com/app-extensions/)\n- [Today Widget in App Extension Programming Guide](https://developer.apple.com/library/content/documentation/General/Conceptual/ExtensibilityPG/Today.html#//apple_ref/doc/uid/TP40014214-CH11-SW1)\n\nTo investigate more iOS App Extensions with React Native check those:\n- [react-native-share-extension](https://github.com/alinz/react-native-share-extension)\n- [react-native-share-menu](https://github.com/meedan/react-native-share-menu)\n- [Messages App/App Extension (iOS10) with React Native](https://medium.com/rendez-voo/messages-app-app-extension-ios10-with-react-native-6d22ece64598)\n\n\n### API Reference\n\n#### `DevMenu`\nDefault dev menu is not available in widget, but you could use `DevSettings` from `NativeModules` or this prepared `DevMenu` component to enable Live/Hot reload or remote JS debugging.\n\n- `children` - trigger element (TouchableOpacity by default)\n- `style` - overriding default style for trigger element\n- `title` - set trigger text ('DM' by default)\n\n##### Example\n```jsx\nimport { DevMenu } from 'react-native-today-widget';\n\nconst TodayWidget = () =\u003e (\n  \u003cView\u003e\n    \u003cText\u003eHello Today Widget!\u003c/Text\u003e\n    {__DEV__ \u0026\u0026 \u003cDevMenu /\u003e\n      /* Has to be a last element to be clickable,\n      because it has absolute position */\n    }\n  \u003c/View\u003e\n);\n```\n\nScreenshot of opened Developer Menu:\n\n![developer_menu](./screenshots/developer_menu.png)\n\n#### `openURL([url:string])`\nAsks the system open a URL on behalf of the currently running app extension.\n\n- `url` - the URL to open\n\n\u003e If you employ this method to open other apps from your widget, your App Store submission might entail additional review to ensure compliance with the intent of widgets.\n\n#### `setExpandable([expandable:boolean = true], [maxHeight:number = 110])`\nEnables to display native Show More / Less button in top right corner of the widget (iOS 10).\n\n- `expandable` - if `false` Show More / Less button is hidden\n- `maxHeight` - height of expanded widget\n\nHeight of collapsed Today Widget is always 110px on iOS 10.\n\n##### Example\n```jsx\nimport { setExpandable } from 'react-native-today-widget';\n\nconst TodayWidget = () =\u003e {\n  const isExpandable = true;\n  const maxHeight = 500;\n  setExpandable(isExpandable, maxHeight);\n  const onLayout = (event) =\u003e {\n    const height = event.nativeEvent.layout.height;\n    if (height \u003c= 110) {\n      console.log('widget is in compact mode');\n    }\n    else if (height \u003e 110) {\n      console.log('widget is in expanded mode');\n    }\n  }\n  return (\n    \u003cView onLayout={onLayout}\u003e\n      \u003cText\u003e\n        Hello Today Widget!\n      \u003c/Text\u003e\n    \u003c/View\u003e\n  );\n};\n```\n\nYou could try [Expandable example](./Examples/Expandable)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatejkriz%2Freact-native-today-widget","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmatejkriz%2Freact-native-today-widget","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatejkriz%2Freact-native-today-widget/lists"}