nn-widgets 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,353 @@
1
+ /**
2
+ * Widget family types for iOS WidgetKit
3
+ */
4
+ export type WidgetFamily = "systemSmall" | "systemMedium" | "systemLarge" | "systemExtraLarge" | "accessoryCircular" | "accessoryRectangular" | "accessoryInline";
5
+ /**
6
+ * Widget display type.
7
+ *
8
+ * - `"single"` – Icon + Title + Subtitle centered layout (default for backward compat)
9
+ * - `"list"` – Vertical list of items, each with icon + title + description
10
+ * - `"grid"` – Grid of items, each column with icon on top + title at bottom
11
+ * - `"image"` – Full-bleed background image (legacy `image` prop is auto-detected)
12
+ */
13
+ export type WidgetType = "single" | "list" | "grid" | "image";
14
+ /**
15
+ * System font size keys (maps to SwiftUI Font / Android sp values).
16
+ *
17
+ * | Key | iOS (SwiftUI) | Android (sp) |
18
+ * |--------------|-----------------|-------------|
19
+ * | caption2 | .caption2 (11) | 11 |
20
+ * | caption | .caption (12) | 12 |
21
+ * | footnote | .footnote (13) | 13 |
22
+ * | subheadline | .subheadline (15)| 15 |
23
+ * | body | .body (17) | 17 |
24
+ * | headline | .headline (17b) | 17 bold |
25
+ * | title3 | .title3 (20) | 20 |
26
+ * | title2 | .title2 (22) | 22 |
27
+ * | title | .title (28) | 28 |
28
+ */
29
+ export type WidgetFontSize = "caption2" | "caption" | "footnote" | "subheadline" | "body" | "headline" | "title3" | "title2" | "title";
30
+ /**
31
+ * Font weight keys (maps to SwiftUI Font.Weight / Android Typeface).
32
+ */
33
+ export type WidgetFontWeight = "regular" | "medium" | "semibold" | "bold";
34
+ /**
35
+ * Icon configuration for a list/single item.
36
+ * Can be a simple string (system icon name) or an object with extra styling.
37
+ */
38
+ export type WidgetItemIcon = string | {
39
+ /** Icon name: SF Symbol (iOS) or bundled image name */
40
+ url: string;
41
+ /** Icon size in points/dp @default 32 */
42
+ size?: number;
43
+ /** Border radius (0 = square, size/2 = circle) @default 0 */
44
+ radius?: number;
45
+ /** Background color behind the icon (hex) */
46
+ backgroundColor?: string;
47
+ };
48
+ /**
49
+ * Text configuration for a list/single item.
50
+ * Can be a simple string or an object with styling.
51
+ */
52
+ export type WidgetItemText = string | {
53
+ /** The text content */
54
+ text: string;
55
+ /** Text color (hex). Falls back to widget-level style colors. */
56
+ color?: string;
57
+ /** Font size key @default "body" for title, "caption" for description */
58
+ fontSize?: WidgetFontSize;
59
+ /** Font weight @default "semibold" for title, "regular" for description */
60
+ fontWeight?: WidgetFontWeight;
61
+ };
62
+ /**
63
+ * A single item in a list-type widget.
64
+ */
65
+ export interface WidgetListItem {
66
+ /** Left icon (SF Symbol name, bundled image, or object with styling) */
67
+ icon?: WidgetItemIcon;
68
+ /** Right icon (SF Symbol name, bundled image, or object with styling) */
69
+ rightIcon?: WidgetItemIcon;
70
+ /** Title text (string or styled object) */
71
+ title: WidgetItemText;
72
+ /** Description text (string or styled object) */
73
+ description?: WidgetItemText;
74
+ /** Per-item deep link URL (overrides widget-level deepLink when tapped) */
75
+ deepLink?: string;
76
+ }
77
+ /**
78
+ * Data payload for `setWidgetData()`. Shape depends on widget type.
79
+ */
80
+ export interface WidgetDataPayload {
81
+ /** For type: "single" */
82
+ icon?: WidgetItemIcon;
83
+ title?: WidgetItemText;
84
+ subtitle?: WidgetItemText;
85
+ /** For type: "list" */
86
+ items?: WidgetListItem[];
87
+ }
88
+ /**
89
+ * Per-widget configuration (used in the widgets[] array)
90
+ */
91
+ export interface WidgetConfig {
92
+ /**
93
+ * Unique name for this widget (used as Swift/Kotlin identifier)
94
+ * Must be a valid identifier (no spaces, starts with letter)
95
+ */
96
+ name: string;
97
+ /**
98
+ * Display name shown in widget gallery
99
+ */
100
+ displayName: string;
101
+ /**
102
+ * Widget description shown in widget gallery
103
+ * @default "A widget for your app"
104
+ */
105
+ description?: string;
106
+ /**
107
+ * Widget display type.
108
+ * - `"single"` – Icon + Title + Subtitle (default)
109
+ * - `"list"` – Vertical list of items
110
+ * - `"image"` – Full-bleed background image
111
+ *
112
+ * If `image` prop is set and `type` is omitted, type is auto-detected as "image".
113
+ * @default "single"
114
+ */
115
+ type?: WidgetType;
116
+ /**
117
+ * Deep link URL opened when widget is tapped
118
+ * Example: "myapp://widget/play" or "myapp://widget/brainstorm"
119
+ */
120
+ deepLinkUrl?: string;
121
+ /**
122
+ * Show app icon in widget UI
123
+ * @default true
124
+ */
125
+ showAppIcon?: boolean;
126
+ /**
127
+ * Supported widget families (iOS only)
128
+ * @default ["systemSmall", "systemMedium", "systemLarge"]
129
+ */
130
+ widgetFamilies?: WidgetFamily[];
131
+ /**
132
+ * Background images for the widget, per size.
133
+ * Path relative to project root (e.g. "./assets/widgets/main-small.png").
134
+ * If provided and type is not set, widget type auto-detects to "image".
135
+ */
136
+ image?: {
137
+ small?: string;
138
+ medium?: string;
139
+ large?: string;
140
+ } | string;
141
+ /**
142
+ * Grid layout configuration for type: "grid".
143
+ * Format: "COLUMNSxROWS" (e.g. "2x2", "3x2", "4x2").
144
+ * - Columns: number of columns in the grid
145
+ * - Rows: max number of rows (items beyond columns*rows are hidden)
146
+ *
147
+ * If not set, columns are auto-detected based on widget family:
148
+ * - systemSmall: 2 columns
149
+ * - systemMedium: 4 columns
150
+ * - systemLarge: 4 columns
151
+ *
152
+ * @example "3x2" → 3 columns, 2 rows → max 6 items
153
+ * @example "2x2" → 2 columns, 2 rows → max 4 items
154
+ */
155
+ gridLayout?: string;
156
+ /**
157
+ * Bundled icon images for use in list/single items at runtime.
158
+ * Keys are icon names, values are paths to .png files.
159
+ * These are copied to Assets.xcassets (iOS) / res/drawable (Android) at prebuild.
160
+ *
161
+ * @example
162
+ * ```json
163
+ * { "brainstorm": "./assets/widgets/icons/brainstorm.png" }
164
+ * ```
165
+ */
166
+ icons?: Record<string, string>;
167
+ /**
168
+ * Widget-level style (colors). Items inherit from these unless overridden.
169
+ * Colors are hex strings (e.g. "#1E1E2E").
170
+ */
171
+ style?: {
172
+ /** Background color of the widget */
173
+ backgroundColor?: string;
174
+ /** Title text color */
175
+ titleColor?: string;
176
+ /** Subtitle / description text color */
177
+ subtitleColor?: string;
178
+ /** Accent color (used for icons, values) */
179
+ accentColor?: string;
180
+ };
181
+ /**
182
+ * Fallback title shown when no data has been set via setWidgetData().
183
+ * @default displayName
184
+ */
185
+ fallbackTitle?: string;
186
+ /**
187
+ * Fallback subtitle shown when no data has been set via setWidgetData().
188
+ * @default "Open app to start"
189
+ */
190
+ fallbackSubtitle?: string;
191
+ /**
192
+ * Android-specific overrides for this widget
193
+ */
194
+ android?: {
195
+ minWidth?: number;
196
+ minHeight?: number;
197
+ resizeMode?: "none" | "horizontal" | "vertical" | "horizontal|vertical";
198
+ };
199
+ }
200
+ /**
201
+ * Configuration options for nn-widgets plugin
202
+ *
203
+ * Supports two formats:
204
+ * 1. Legacy single widget: { widgetName, displayName, ios, android }
205
+ * 2. Multi-widget: { widgets: [...], ios, android }
206
+ */
207
+ export interface NNWidgetsPluginProps {
208
+ /**
209
+ * Array of widget configurations.
210
+ * When provided, widgetName/displayName/description are ignored.
211
+ */
212
+ widgets?: WidgetConfig[];
213
+ /**
214
+ * @deprecated Use widgets[] instead
215
+ */
216
+ widgetName?: string;
217
+ /**
218
+ * @deprecated Use widgets[] instead
219
+ */
220
+ displayName?: string;
221
+ /**
222
+ * @deprecated Use widgets[] instead
223
+ */
224
+ description?: string;
225
+ /**
226
+ * iOS shared configuration
227
+ */
228
+ ios?: {
229
+ /**
230
+ * Deployment target for widget extension
231
+ * @default "17.0"
232
+ */
233
+ deploymentTarget?: string;
234
+ /**
235
+ * Enable App Groups for data sharing between app and widget
236
+ * Set to false for local development without provisioning profile setup
237
+ * @default true
238
+ */
239
+ useAppGroups?: boolean;
240
+ /**
241
+ * App group identifier for data sharing
242
+ * If not provided, will be auto-generated as group.{bundleIdentifier}
243
+ * Only used when useAppGroups is true
244
+ */
245
+ appGroupIdentifier?: string;
246
+ /**
247
+ * Development team ID for signing
248
+ */
249
+ devTeam?: string;
250
+ /**
251
+ * Supported widget families (applies to legacy single-widget format)
252
+ * For multi-widget, set widgetFamilies per widget in widgets[]
253
+ * @default ["systemSmall", "systemMedium", "systemLarge"]
254
+ */
255
+ widgetFamilies?: WidgetFamily[];
256
+ /**
257
+ * Deep link URL (applies to legacy single-widget format)
258
+ * For multi-widget, set deepLinkUrl per widget in widgets[]
259
+ */
260
+ deepLinkUrl?: string;
261
+ /**
262
+ * Show app icon (applies to legacy single-widget format)
263
+ * For multi-widget, set showAppIcon per widget in widgets[]
264
+ * @default true
265
+ */
266
+ showAppIcon?: boolean;
267
+ };
268
+ /**
269
+ * Android shared configuration
270
+ */
271
+ android?: {
272
+ /**
273
+ * Minimum SDK for widget
274
+ * @default 26
275
+ */
276
+ minSdkVersion?: number;
277
+ /**
278
+ * Widget update interval in milliseconds (minimum 30 minutes)
279
+ * @default 1800000 (30 minutes)
280
+ */
281
+ updatePeriodMillis?: number;
282
+ /**
283
+ * Widget minimum width in dp (applies to legacy single-widget format)
284
+ * @default 110
285
+ */
286
+ minWidth?: number;
287
+ /**
288
+ * Widget minimum height in dp (applies to legacy single-widget format)
289
+ * @default 40
290
+ */
291
+ minHeight?: number;
292
+ /**
293
+ * Widget resize mode (applies to legacy single-widget format)
294
+ * @default "horizontal|vertical"
295
+ */
296
+ resizeMode?: "none" | "horizontal" | "vertical" | "horizontal|vertical";
297
+ };
298
+ }
299
+ /**
300
+ * Resolved per-widget config with all defaults applied
301
+ */
302
+ export interface ResolvedWidgetConfig {
303
+ name: string;
304
+ displayName: string;
305
+ description: string;
306
+ type: WidgetType;
307
+ deepLinkUrl?: string;
308
+ showAppIcon: boolean;
309
+ widgetFamilies: string[];
310
+ fallbackTitle: string;
311
+ fallbackSubtitle: string;
312
+ /** Resolved image paths per size (absolute paths, or undefined if not set) */
313
+ image?: {
314
+ small?: string;
315
+ medium?: string;
316
+ large?: string;
317
+ };
318
+ /** Grid layout "COLUMNSxROWS" (e.g. "3x2") for grid-type widgets */
319
+ gridLayout?: string;
320
+ /** Bundled icon images (name → path) */
321
+ icons?: Record<string, string>;
322
+ /** Resolved style options */
323
+ style?: {
324
+ backgroundColor?: string;
325
+ titleColor?: string;
326
+ subtitleColor?: string;
327
+ accentColor?: string;
328
+ };
329
+ android: {
330
+ minWidth: number;
331
+ minHeight: number;
332
+ resizeMode: string;
333
+ };
334
+ }
335
+ /**
336
+ * Resolved configuration with all defaults applied
337
+ */
338
+ export interface ResolvedPluginProps {
339
+ /** The shared extension name (iOS) */
340
+ extensionName: string;
341
+ widgets: ResolvedWidgetConfig[];
342
+ ios: {
343
+ deploymentTarget: string;
344
+ useAppGroups: boolean;
345
+ appGroupIdentifier?: string;
346
+ devTeam?: string;
347
+ };
348
+ android: {
349
+ minSdkVersion: number;
350
+ updatePeriodMillis: number;
351
+ };
352
+ }
353
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,5 @@
1
+ import { ConfigPlugin } from "@expo/config-plugins";
2
+ import type { NNWidgetsPluginProps } from "./types";
3
+ export declare const withAndroidWidget: ConfigPlugin<NNWidgetsPluginProps>;
4
+ export default withAndroidWidget;
5
+ //# sourceMappingURL=withAndroidWidget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"withAndroidWidget.d.ts","sourceRoot":"","sources":["../src/withAndroidWidget.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAuB,MAAM,sBAAsB,CAAC;AAGzE,OAAO,KAAK,EACV,oBAAoB,EAGrB,MAAM,SAAS,CAAC;AA+hBjB,eAAO,MAAM,iBAAiB,EAAE,YAAY,CAAC,oBAAoB,CAuNhE,CAAC;AAEF,eAAe,iBAAiB,CAAC"}