@heedkit/sdk-react-native 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,691 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.FeedbackButton = FeedbackButton;
7
+ exports.FeedbackScreen = FeedbackScreen;
8
+ exports.HeedKit = void 0;
9
+ Object.defineProperty(exports, "HeedKitClient", {
10
+ enumerable: true,
11
+ get: function () {
12
+ return _client.HeedKitClient;
13
+ }
14
+ });
15
+ exports.HeedKitProvider = HeedKitProvider;
16
+ exports.useHeedKit = useHeedKit;
17
+ var React = _interopRequireWildcard(require("react"));
18
+ var _reactNative = require("react-native");
19
+ var _client = require("./client.js");
20
+ var _jsxRuntime = require("react/jsx-runtime");
21
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
22
+ // ---------------------------------------------------------------------------
23
+ // Per-kind metadata. Kept here (not the client) because it's view-layer copy.
24
+ // ---------------------------------------------------------------------------
25
+
26
+ const KIND_META = {
27
+ feature_request: {
28
+ label: "Features",
29
+ placeholder: "What should we build?",
30
+ tabIcon: "💡"
31
+ },
32
+ bug_report: {
33
+ label: "Bugs",
34
+ placeholder: "What's broken?",
35
+ tabIcon: "🐞"
36
+ },
37
+ improvement: {
38
+ label: "Improvements",
39
+ placeholder: "What could be better?",
40
+ tabIcon: "✨"
41
+ },
42
+ appreciation: {
43
+ label: "Appreciation",
44
+ placeholder: "What did you love?",
45
+ tabIcon: "❤️"
46
+ },
47
+ other: {
48
+ label: "Other",
49
+ placeholder: "Tell us anything",
50
+ tabIcon: "💬"
51
+ }
52
+ };
53
+ const INTERACTION_META = {
54
+ upvote: {
55
+ icon: "▲",
56
+ label: "Upvote"
57
+ },
58
+ downvote: {
59
+ icon: "▼",
60
+ label: "Downvote"
61
+ },
62
+ plus_one: {
63
+ icon: "+1",
64
+ label: "+1"
65
+ },
66
+ like: {
67
+ icon: "♥",
68
+ label: "Like"
69
+ }
70
+ };
71
+ const FONT_SIZES = {
72
+ sm: 13,
73
+ md: 14,
74
+ lg: 16
75
+ };
76
+
77
+ // ---------------------------------------------------------------------------
78
+ // Context
79
+ // ---------------------------------------------------------------------------
80
+
81
+ const HeedKitContext = /*#__PURE__*/React.createContext(null);
82
+ function HeedKitProvider({
83
+ projectKey,
84
+ apiUrl,
85
+ user,
86
+ children
87
+ }) {
88
+ const [client] = React.useState(() => new _client.HeedKitClient({
89
+ projectKey,
90
+ apiUrl,
91
+ user
92
+ }));
93
+ const [ready, setReady] = React.useState(false);
94
+ const [theme, setTheme] = React.useState({});
95
+ React.useEffect(() => {
96
+ client.init({
97
+ ...user,
98
+ platform: user?.platform || "react-native"
99
+ }).then(() => {
100
+ setTheme(client.getTheme());
101
+ setReady(true);
102
+ });
103
+ }, [client]); // eslint-disable-line react-hooks/exhaustive-deps
104
+
105
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(HeedKitContext.Provider, {
106
+ value: {
107
+ client,
108
+ ready,
109
+ theme
110
+ },
111
+ children: children
112
+ });
113
+ }
114
+ function useHeedKit() {
115
+ const ctx = React.useContext(HeedKitContext);
116
+ if (!ctx) throw new Error("useHeedKit must be used inside <HeedKitProvider>");
117
+ return ctx;
118
+ }
119
+
120
+ // Mobile-friendly singleton for users who don't want a provider.
121
+ const HeedKit = exports.HeedKit = {
122
+ _instance: null,
123
+ async init(config) {
124
+ this._instance = new _client.HeedKitClient(config);
125
+ return this._instance.init({
126
+ ...config.user,
127
+ platform: config.user?.platform || "react-native"
128
+ });
129
+ },
130
+ client() {
131
+ if (!this._instance) throw new Error("HeedKit.init not called");
132
+ return this._instance;
133
+ }
134
+ };
135
+
136
+ // ---------------------------------------------------------------------------
137
+ // Theme palette derived from the server theme + the device color scheme when
138
+ // the user picked "system".
139
+ // ---------------------------------------------------------------------------
140
+
141
+ function usePalette(theme) {
142
+ const [systemScheme, setSystemScheme] = React.useState(_reactNative.Appearance.getColorScheme());
143
+ React.useEffect(() => {
144
+ const sub = _reactNative.Appearance.addChangeListener(({
145
+ colorScheme
146
+ }) => setSystemScheme(colorScheme));
147
+ return () => sub.remove();
148
+ }, []);
149
+ const mode = theme.mode === "system" ? systemScheme === "dark" ? "dark" : "light" : theme.mode || "light";
150
+ const dark = mode === "dark";
151
+ return {
152
+ primary: theme.primary || "#0D9488",
153
+ radius: theme.radius ?? 12,
154
+ fs: FONT_SIZES[theme.font_size ?? "md"] ?? 14,
155
+ bg: dark ? "#0F172A" : "#FFFFFF",
156
+ fg: dark ? "#F1F5F9" : "#0F172A",
157
+ muted: dark ? "#94A3B8" : "#64748B",
158
+ row: dark ? "#1E293B" : "#F8FAFC",
159
+ border: dark ? "#1E293B" : "#E2E8F0",
160
+ inputBorder: dark ? "#334155" : "#CBD5E1",
161
+ inputBg: dark ? "#0F172A" : "#FFFFFF",
162
+ dark
163
+ };
164
+ }
165
+
166
+ // ---------------------------------------------------------------------------
167
+ // Public components
168
+ // ---------------------------------------------------------------------------
169
+
170
+ function FeedbackButton({
171
+ label = "Feedback"
172
+ }) {
173
+ const ctx = React.useContext(HeedKitContext);
174
+ const [open, setOpen] = React.useState(false);
175
+ const p = usePalette(ctx?.theme || {});
176
+ if (!ctx?.ready) return null;
177
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
178
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
179
+ onPress: () => setOpen(true),
180
+ style: [styles.fab, {
181
+ backgroundColor: p.primary
182
+ }],
183
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
184
+ style: [styles.fabLabel, {
185
+ fontSize: p.fs
186
+ }],
187
+ children: label
188
+ })
189
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Modal, {
190
+ visible: open,
191
+ animationType: "slide",
192
+ onRequestClose: () => setOpen(false),
193
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(FeedbackScreen, {
194
+ onClose: () => setOpen(false)
195
+ })
196
+ })]
197
+ });
198
+ }
199
+ function FeedbackScreen({
200
+ onClose
201
+ }) {
202
+ const ctx = React.useContext(HeedKitContext);
203
+ const p = usePalette(ctx?.theme || {});
204
+ if (!ctx?.ready) {
205
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
206
+ style: [styles.center, {
207
+ backgroundColor: p.bg,
208
+ flex: 1
209
+ }],
210
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, {
211
+ color: p.primary
212
+ })
213
+ });
214
+ }
215
+ const enabledKinds = ctx.client.getEnabledKinds();
216
+ const groupMode = ctx.theme.group_mode || "tabs";
217
+ const showCounts = ctx.theme.show_counts || {};
218
+ const [mode, setMode] = React.useState("browse");
219
+ const [activeKind, setActiveKind] = React.useState(groupMode === "tabs" && enabledKinds.length > 0 ? enabledKinds[0] : "all");
220
+ const [features, setFeatures] = React.useState([]);
221
+ const [loading, setLoading] = React.useState(true);
222
+ async function refresh() {
223
+ setLoading(true);
224
+ try {
225
+ const opts = {
226
+ sort: "top"
227
+ };
228
+ if (activeKind !== "all") opts.kind = activeKind;
229
+ setFeatures(await ctx.client.list(opts));
230
+ } finally {
231
+ setLoading(false);
232
+ }
233
+ }
234
+ React.useEffect(() => {
235
+ refresh();
236
+ // eslint-disable-next-line react-hooks/exhaustive-deps
237
+ }, [activeKind]);
238
+ async function performInteraction(f, _i) {
239
+ // Backend currently has one vote toggle endpoint per feature; richer
240
+ // per-interaction storage can be wired here later.
241
+ const r = await ctx.client.vote(f.id);
242
+ setFeatures(arr => arr.map(x => x.id === f.id ? {
243
+ ...x,
244
+ voted: r.voted,
245
+ vote_count: r.vote_count
246
+ } : x));
247
+ }
248
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
249
+ style: [styles.container, {
250
+ backgroundColor: p.bg
251
+ }],
252
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
253
+ style: [styles.header, {
254
+ borderColor: p.border
255
+ }],
256
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
257
+ style: [styles.title, {
258
+ color: p.fg,
259
+ fontSize: p.fs + 6
260
+ }],
261
+ children: ctx.client.getProjectName() || "Feedback"
262
+ }), onClose && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
263
+ onPress: onClose,
264
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
265
+ style: {
266
+ color: p.primary,
267
+ fontWeight: "600",
268
+ fontSize: p.fs
269
+ },
270
+ children: "Close"
271
+ })
272
+ })]
273
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
274
+ style: styles.modeRow,
275
+ children: ["browse", "suggest"].map(m => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
276
+ onPress: () => setMode(m),
277
+ style: [styles.modeBtn, {
278
+ backgroundColor: mode === m ? p.primary : "transparent"
279
+ }],
280
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
281
+ style: {
282
+ color: mode === m ? "#fff" : p.muted,
283
+ fontWeight: "600",
284
+ fontSize: p.fs - 1
285
+ },
286
+ children: m === "browse" ? "Browse" : "Suggest"
287
+ })
288
+ }, m))
289
+ }), mode === "browse" && groupMode === "tabs" && enabledKinds.length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
290
+ horizontal: true,
291
+ showsHorizontalScrollIndicator: false,
292
+ style: [styles.tabRow, {
293
+ borderColor: p.border
294
+ }],
295
+ contentContainerStyle: {
296
+ gap: 6,
297
+ paddingHorizontal: 16,
298
+ paddingVertical: 10
299
+ },
300
+ children: ["all", ...enabledKinds].map(k => {
301
+ const active = activeKind === k;
302
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
303
+ onPress: () => setActiveKind(k),
304
+ style: [styles.tab, {
305
+ backgroundColor: active ? p.primary : p.row
306
+ }],
307
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
308
+ style: {
309
+ color: active ? "#fff" : p.fg,
310
+ fontSize: p.fs - 1,
311
+ fontWeight: "500"
312
+ },
313
+ children: k === "all" ? "All" : `${KIND_META[k].tabIcon} ${KIND_META[k].label}`
314
+ })
315
+ }, k);
316
+ })
317
+ }), mode === "browse" ? loading ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
318
+ style: [styles.center, {
319
+ flex: 1
320
+ }],
321
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, {
322
+ color: p.primary
323
+ })
324
+ }) : features.length === 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
325
+ style: [styles.center, {
326
+ flex: 1
327
+ }],
328
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
329
+ style: {
330
+ color: p.muted,
331
+ fontSize: p.fs
332
+ },
333
+ children: "No items yet \u2014 be the first!"
334
+ })
335
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.FlatList, {
336
+ data: features,
337
+ keyExtractor: f => f.id,
338
+ contentContainerStyle: {
339
+ padding: 16,
340
+ gap: 8
341
+ },
342
+ renderItem: ({
343
+ item
344
+ }) => /*#__PURE__*/(0, _jsxRuntime.jsx)(Row, {
345
+ feature: item,
346
+ palette: p,
347
+ interactions: ctx.client.getInteractionsFor(item.kind),
348
+ showCount: showCounts[item.kind] !== false,
349
+ onInteraction: i => performInteraction(item, i)
350
+ })
351
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(SubmitForm, {
352
+ palette: p,
353
+ enabledKinds: enabledKinds.length > 0 ? enabledKinds : ["other"],
354
+ onSubmitted: async () => {
355
+ setMode("browse");
356
+ await refresh();
357
+ }
358
+ })]
359
+ });
360
+ }
361
+
362
+ // ---------------------------------------------------------------------------
363
+ // Row + form (private)
364
+ // ---------------------------------------------------------------------------
365
+
366
+ function Row({
367
+ feature: f,
368
+ palette: p,
369
+ interactions,
370
+ showCount,
371
+ onInteraction
372
+ }) {
373
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
374
+ style: [styles.row, {
375
+ backgroundColor: p.row,
376
+ borderRadius: p.radius
377
+ }],
378
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
379
+ style: styles.actionCol,
380
+ children: interactions.length === 0 ? showCount && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
381
+ style: [styles.actBtn, {
382
+ borderColor: p.border,
383
+ borderRadius: p.radius - 4
384
+ }],
385
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
386
+ style: {
387
+ color: p.fg,
388
+ fontWeight: "600",
389
+ fontSize: p.fs - 1
390
+ },
391
+ children: f.vote_count
392
+ })
393
+ }) : interactions.map(i => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Pressable, {
394
+ onPress: () => onInteraction(i),
395
+ style: [styles.actBtn, {
396
+ borderRadius: p.radius - 4,
397
+ borderColor: f.voted ? p.primary : p.border,
398
+ borderWidth: f.voted ? 2 : 1,
399
+ backgroundColor: f.voted ? p.primary + "22" : "transparent"
400
+ }],
401
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
402
+ style: {
403
+ color: f.voted ? p.primary : p.fg,
404
+ fontSize: p.fs + 1
405
+ },
406
+ children: INTERACTION_META[i].icon
407
+ }), showCount && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
408
+ style: {
409
+ color: f.voted ? p.primary : p.fg,
410
+ fontSize: p.fs - 2,
411
+ fontWeight: "600"
412
+ },
413
+ children: f.vote_count
414
+ })]
415
+ }, i))
416
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
417
+ style: {
418
+ flex: 1
419
+ },
420
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
421
+ style: {
422
+ color: p.fg,
423
+ fontWeight: "600",
424
+ fontSize: p.fs
425
+ },
426
+ children: f.title
427
+ }), !!f.description && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
428
+ style: {
429
+ color: p.muted,
430
+ fontSize: p.fs - 1,
431
+ marginTop: 4
432
+ },
433
+ numberOfLines: 3,
434
+ children: f.description
435
+ }), (f.status !== "open" || f.tag) && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
436
+ style: styles.badges,
437
+ children: [f.status !== "open" && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
438
+ style: [styles.badge, {
439
+ backgroundColor: p.border,
440
+ color: p.muted,
441
+ fontSize: p.fs - 3
442
+ }],
443
+ children: f.status.replace("_", " ")
444
+ }), !!f.tag && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
445
+ style: [styles.badge, {
446
+ backgroundColor: p.border,
447
+ color: p.muted,
448
+ fontSize: p.fs - 3
449
+ }],
450
+ children: f.tag
451
+ })]
452
+ })]
453
+ })]
454
+ });
455
+ }
456
+ function SubmitForm({
457
+ palette: p,
458
+ enabledKinds,
459
+ onSubmitted
460
+ }) {
461
+ const ctx = React.useContext(HeedKitContext);
462
+ const [kind, setKind] = React.useState(enabledKinds[0]);
463
+ const [title, setTitle] = React.useState("");
464
+ const [description, setDescription] = React.useState("");
465
+ const [submitting, setSubmitting] = React.useState(false);
466
+ async function submit() {
467
+ if (!title.trim()) return;
468
+ setSubmitting(true);
469
+ try {
470
+ await ctx.client.submit({
471
+ title,
472
+ description,
473
+ kind
474
+ });
475
+ setTitle("");
476
+ setDescription("");
477
+ onSubmitted();
478
+ } finally {
479
+ setSubmitting(false);
480
+ }
481
+ }
482
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.ScrollView, {
483
+ contentContainerStyle: {
484
+ padding: 16,
485
+ gap: 12
486
+ },
487
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
488
+ style: {
489
+ color: p.fg,
490
+ fontWeight: "500",
491
+ fontSize: p.fs - 1
492
+ },
493
+ children: "What's this about?"
494
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
495
+ style: [styles.segmented, {
496
+ backgroundColor: p.row
497
+ }],
498
+ children: enabledKinds.map(k => {
499
+ const active = k === kind;
500
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
501
+ onPress: () => setKind(k),
502
+ style: [styles.seg, {
503
+ backgroundColor: active ? p.bg : "transparent",
504
+ borderRadius: 999
505
+ }],
506
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
507
+ style: {
508
+ color: active ? p.fg : p.muted,
509
+ fontWeight: "500",
510
+ fontSize: p.fs - 2
511
+ },
512
+ children: KIND_META[k].label
513
+ })
514
+ }, k);
515
+ })
516
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
517
+ style: {
518
+ color: p.fg,
519
+ fontWeight: "500",
520
+ fontSize: p.fs - 1
521
+ },
522
+ children: "Title"
523
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
524
+ value: title,
525
+ onChangeText: setTitle,
526
+ placeholder: KIND_META[kind].placeholder,
527
+ placeholderTextColor: p.muted,
528
+ style: [styles.input, {
529
+ borderColor: p.inputBorder,
530
+ color: p.fg,
531
+ backgroundColor: p.inputBg,
532
+ borderRadius: p.radius - 2
533
+ }]
534
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
535
+ style: {
536
+ color: p.fg,
537
+ fontWeight: "500",
538
+ fontSize: p.fs - 1
539
+ },
540
+ children: "Description"
541
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
542
+ value: description,
543
+ onChangeText: setDescription,
544
+ placeholder: "Any extra context helps.",
545
+ placeholderTextColor: p.muted,
546
+ multiline: true,
547
+ numberOfLines: 4,
548
+ style: [styles.input, {
549
+ borderColor: p.inputBorder,
550
+ color: p.fg,
551
+ backgroundColor: p.inputBg,
552
+ borderRadius: p.radius - 2,
553
+ height: 100
554
+ }]
555
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
556
+ disabled: !title || submitting,
557
+ onPress: submit,
558
+ style: [styles.submit, {
559
+ backgroundColor: p.primary,
560
+ opacity: !title || submitting ? 0.6 : 1,
561
+ borderRadius: p.radius
562
+ }],
563
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
564
+ style: {
565
+ color: "#fff",
566
+ fontWeight: "600",
567
+ fontSize: p.fs
568
+ },
569
+ children: submitting ? "Submitting…" : "Submit"
570
+ })
571
+ })]
572
+ });
573
+ }
574
+
575
+ // ---------------------------------------------------------------------------
576
+ // Styles
577
+ // ---------------------------------------------------------------------------
578
+
579
+ const styles = _reactNative.StyleSheet.create({
580
+ container: {
581
+ flex: 1
582
+ },
583
+ center: {
584
+ alignItems: "center",
585
+ justifyContent: "center"
586
+ },
587
+ header: {
588
+ flexDirection: "row",
589
+ justifyContent: "space-between",
590
+ alignItems: "center",
591
+ paddingHorizontal: 16,
592
+ paddingVertical: 14,
593
+ borderBottomWidth: 1
594
+ },
595
+ title: {
596
+ fontWeight: "700"
597
+ },
598
+ modeRow: {
599
+ flexDirection: "row",
600
+ gap: 6,
601
+ paddingHorizontal: 16,
602
+ paddingTop: 10
603
+ },
604
+ modeBtn: {
605
+ paddingHorizontal: 14,
606
+ paddingVertical: 6,
607
+ borderRadius: 999
608
+ },
609
+ tabRow: {
610
+ maxHeight: 48,
611
+ borderBottomWidth: 1
612
+ },
613
+ tab: {
614
+ paddingHorizontal: 12,
615
+ paddingVertical: 6,
616
+ borderRadius: 999
617
+ },
618
+ row: {
619
+ flexDirection: "row",
620
+ gap: 12,
621
+ padding: 12,
622
+ alignItems: "flex-start"
623
+ },
624
+ actionCol: {
625
+ gap: 4
626
+ },
627
+ actBtn: {
628
+ minWidth: 44,
629
+ paddingHorizontal: 8,
630
+ paddingVertical: 6,
631
+ alignItems: "center",
632
+ justifyContent: "center",
633
+ borderWidth: 1
634
+ },
635
+ badges: {
636
+ flexDirection: "row",
637
+ gap: 6,
638
+ marginTop: 6,
639
+ flexWrap: "wrap"
640
+ },
641
+ badge: {
642
+ paddingHorizontal: 8,
643
+ paddingVertical: 2,
644
+ borderRadius: 999,
645
+ textTransform: "uppercase",
646
+ letterSpacing: 0.4
647
+ },
648
+ segmented: {
649
+ flexDirection: "row",
650
+ padding: 4,
651
+ borderRadius: 999,
652
+ gap: 4,
653
+ alignSelf: "flex-start",
654
+ flexWrap: "wrap"
655
+ },
656
+ seg: {
657
+ paddingHorizontal: 12,
658
+ paddingVertical: 6
659
+ },
660
+ input: {
661
+ borderWidth: 1,
662
+ padding: 12,
663
+ fontSize: 14
664
+ },
665
+ submit: {
666
+ padding: 14,
667
+ alignItems: "center",
668
+ marginTop: 8
669
+ },
670
+ fab: {
671
+ position: "absolute",
672
+ bottom: 24,
673
+ right: 24,
674
+ paddingHorizontal: 18,
675
+ paddingVertical: 12,
676
+ borderRadius: 999,
677
+ shadowColor: "#000",
678
+ shadowOpacity: 0.2,
679
+ shadowRadius: 8,
680
+ shadowOffset: {
681
+ width: 0,
682
+ height: 4
683
+ },
684
+ elevation: 6
685
+ },
686
+ fabLabel: {
687
+ color: "#fff",
688
+ fontWeight: "600"
689
+ }
690
+ });
691
+ //# sourceMappingURL=index.js.map