@webority-technologies/mobile 0.0.5 → 0.0.7

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.
Files changed (62) hide show
  1. package/README.md +3 -435
  2. package/lib/commonjs/components/Accordion/Accordion.js +20 -1
  3. package/lib/commonjs/components/Banner/Banner.js +17 -5
  4. package/lib/commonjs/components/Button/Button.js +5 -2
  5. package/lib/commonjs/components/Carousel/Carousel.js +18 -1
  6. package/lib/commonjs/components/Chip/Chip.js +27 -15
  7. package/lib/commonjs/components/ImageGallery/ImageGallery.js +19 -9
  8. package/lib/commonjs/components/Rating/Rating.js +11 -1
  9. package/lib/commonjs/components/Skeleton/Skeleton.js +20 -12
  10. package/lib/commonjs/components/Skeleton/SkeletonContent.js +25 -9
  11. package/lib/commonjs/components/Skeleton/SkeletonList.js +7 -2
  12. package/lib/commonjs/components/Skeleton/SkeletonProvider.js +48 -0
  13. package/lib/commonjs/components/Skeleton/SkeletonSkip.js +37 -0
  14. package/lib/commonjs/components/Skeleton/index.js +20 -0
  15. package/lib/commonjs/components/Stepper/Stepper.js +13 -3
  16. package/lib/commonjs/components/index.js +18 -0
  17. package/lib/module/components/Accordion/Accordion.js +20 -1
  18. package/lib/module/components/Banner/Banner.js +17 -5
  19. package/lib/module/components/Button/Button.js +6 -3
  20. package/lib/module/components/Carousel/Carousel.js +18 -1
  21. package/lib/module/components/Chip/Chip.js +27 -15
  22. package/lib/module/components/ImageGallery/ImageGallery.js +11 -1
  23. package/lib/module/components/Rating/Rating.js +11 -1
  24. package/lib/module/components/Skeleton/Skeleton.js +20 -12
  25. package/lib/module/components/Skeleton/SkeletonContent.js +25 -9
  26. package/lib/module/components/Skeleton/SkeletonList.js +7 -2
  27. package/lib/module/components/Skeleton/SkeletonProvider.js +41 -0
  28. package/lib/module/components/Skeleton/SkeletonSkip.js +31 -0
  29. package/lib/module/components/Skeleton/index.js +2 -0
  30. package/lib/module/components/Stepper/Stepper.js +13 -3
  31. package/lib/module/components/index.js +1 -1
  32. package/lib/typescript/commonjs/components/Accordion/Accordion.d.ts +7 -0
  33. package/lib/typescript/commonjs/components/Banner/Banner.d.ts +6 -0
  34. package/lib/typescript/commonjs/components/Button/Button.d.ts +5 -0
  35. package/lib/typescript/commonjs/components/Carousel/Carousel.d.ts +7 -0
  36. package/lib/typescript/commonjs/components/Chip/Chip.d.ts +6 -0
  37. package/lib/typescript/commonjs/components/ImageGallery/ImageGallery.d.ts +6 -0
  38. package/lib/typescript/commonjs/components/Rating/Rating.d.ts +6 -0
  39. package/lib/typescript/commonjs/components/Skeleton/Skeleton.d.ts +9 -0
  40. package/lib/typescript/commonjs/components/Skeleton/SkeletonContent.d.ts +6 -0
  41. package/lib/typescript/commonjs/components/Skeleton/SkeletonList.d.ts +3 -0
  42. package/lib/typescript/commonjs/components/Skeleton/SkeletonProvider.d.ts +32 -0
  43. package/lib/typescript/commonjs/components/Skeleton/SkeletonSkip.d.ts +25 -0
  44. package/lib/typescript/commonjs/components/Skeleton/index.d.ts +4 -0
  45. package/lib/typescript/commonjs/components/Stepper/Stepper.d.ts +6 -0
  46. package/lib/typescript/commonjs/components/index.d.ts +2 -2
  47. package/lib/typescript/module/components/Accordion/Accordion.d.ts +7 -0
  48. package/lib/typescript/module/components/Banner/Banner.d.ts +6 -0
  49. package/lib/typescript/module/components/Button/Button.d.ts +5 -0
  50. package/lib/typescript/module/components/Carousel/Carousel.d.ts +7 -0
  51. package/lib/typescript/module/components/Chip/Chip.d.ts +6 -0
  52. package/lib/typescript/module/components/ImageGallery/ImageGallery.d.ts +6 -0
  53. package/lib/typescript/module/components/Rating/Rating.d.ts +6 -0
  54. package/lib/typescript/module/components/Skeleton/Skeleton.d.ts +9 -0
  55. package/lib/typescript/module/components/Skeleton/SkeletonContent.d.ts +6 -0
  56. package/lib/typescript/module/components/Skeleton/SkeletonList.d.ts +3 -0
  57. package/lib/typescript/module/components/Skeleton/SkeletonProvider.d.ts +32 -0
  58. package/lib/typescript/module/components/Skeleton/SkeletonSkip.d.ts +25 -0
  59. package/lib/typescript/module/components/Skeleton/index.d.ts +4 -0
  60. package/lib/typescript/module/components/Stepper/Stepper.d.ts +6 -0
  61. package/lib/typescript/module/components/index.d.ts +2 -2
  62. package/package.json +1 -1
package/README.md CHANGED
@@ -1,443 +1,11 @@
1
1
  # @webority-technologies/mobile
2
2
 
3
- The single React Native package for Webority projects: 41 UI components, theme, API client, auth, logging, storage, formatters, validators, network, permissions, and version-check — all in one import path.
4
-
5
- `v0.0.1` · MIT · React Native 0.81+ · React 19 · TypeScript strict
6
-
7
- ---
8
-
9
- ## Install
3
+ Internal React Native foundation for Webority projects UI components, theme, API client, auth, logging, storage, formatters, validators, network, permissions, and version-check in one package.
10
4
 
11
5
  ```bash
12
6
  npm install @webority-technologies/mobile
13
7
  ```
14
8
 
15
- ### Peer dependencies
16
-
17
- `react` 19.1 and `react-native` 0.81+ are required. Everything else is **optional** — install only what the modules you use need:
18
-
19
- | Peer dep | Needed for |
20
- | ------------------------------------------------- | ----------------------------------------------------------------- |
21
- | `react-native-reanimated` (3.x) | `BottomSheet`, `Drawer`, `Swipeable` (others use native Animated) |
22
- | `react-native-gesture-handler` (2.x) | `BottomSheet`, swipe-to-dismiss interactions |
23
- | `react-native-safe-area-context` (5.x) | Layout components, modals, toast positioning |
24
- | `react-native-vector-icons` (10.x) | Icon-bearing components (`Button`, `Avatar`, etc.) |
25
- | `@react-native-async-storage/async-storage` (2.x) | `Storage` module + token persistence |
26
- | `react-native-keychain` (9.x) | Secure credential storage (`storeToken` / `getToken`) |
27
- | `react-native-device-info` (14.x) | `versionCheck` helpers |
28
- | `@react-native-community/netinfo` (11.x) | `useNetworkStatus`, `NetworkStatusBanner` |
29
- | `react-native-permissions` (4.x) | `Permissions` module |
30
- | `react-native-compressor` (1.10+) | `compressImage` utility |
31
-
32
- ```bash
33
- npm install react-native-reanimated \
34
- react-native-gesture-handler \
35
- react-native-safe-area-context \
36
- react-native-vector-icons \
37
- @react-native-async-storage/async-storage \
38
- react-native-keychain \
39
- react-native-device-info \
40
- @react-native-community/netinfo \
41
- react-native-permissions \
42
- react-native-compressor
43
- ```
44
-
45
- Follow each library's native-setup steps (Reanimated babel plugin, Gesture Handler import at the top of the entry file, vector-icons font linking, etc.).
46
-
47
- ---
48
-
49
- ## Setup
50
-
51
- Wrap the app with `GestureHandlerRootView`, `SafeAreaProvider`, `ThemeProvider`, and `ToastProvider`. Initialize the SDK once at module scope.
52
-
53
- ```tsx
54
- // App.tsx
55
- import 'react-native-gesture-handler';
56
- import React from 'react';
57
- import { GestureHandlerRootView } from 'react-native-gesture-handler';
58
- import { SafeAreaProvider } from 'react-native-safe-area-context';
59
- import {
60
- initWebority,
61
- initUserAuth,
62
- ThemeProvider,
63
- ToastProvider,
64
- NetworkStatusBanner
65
- } from '@webority-technologies/mobile';
66
- import store from './store';
67
- import { logout, refreshToken } from './store/auth';
68
-
69
- initWebority({
70
- baseUrl: 'https://api.example.com',
71
- environment: __DEV__ ? 'Development' : 'Production',
72
- country: 'in' // optional, defaults to 'in'
73
- });
74
-
75
- initUserAuth(store, { logout, refreshToken });
76
-
77
- export default function App(): JSX.Element {
78
- return (
79
- <GestureHandlerRootView style={{ flex: 1 }}>
80
- <SafeAreaProvider>
81
- <ThemeProvider>
82
- <ToastProvider>
83
- <NetworkStatusBanner />
84
- {/* your screens */}
85
- </ToastProvider>
86
- </ThemeProvider>
87
- </SafeAreaProvider>
88
- </GestureHandlerRootView>
89
- );
90
- }
91
- ```
92
-
93
- `initUI` is also exported for advanced setups that need to register UI-only globals (theme overrides, default color mode) without the API/auth side of the SDK.
94
-
95
- ---
96
-
97
- ## API surface
98
-
99
- ```ts
100
- import {
101
- // bootstrap
102
- initWebority,
103
- initUserAuth,
104
- initUI,
105
-
106
- // configuration
107
- setConfig,
108
- getConfig,
109
- getConfigValue,
110
- resetConfig,
111
-
112
- // theme
113
- ThemeProvider,
114
- useTheme,
115
- useThemeMode,
116
- mergeTheme,
117
- lightTheme,
118
- darkTheme,
119
-
120
- // hooks
121
- useToggle,
122
- useDebounce,
123
- usePressAnimation,
124
-
125
- // http
126
- publicClient,
127
- userClient,
128
-
129
- // auth
130
- storeToken,
131
- getToken,
132
- removeToken,
133
- decodeJWT,
134
- isJWTExpired,
135
- getJWTExpiry,
136
-
137
- // storage
138
- Storage,
139
- setStorageImplementation,
140
-
141
- // logger + remote sink (Crashlytics / Sentry adapter)
142
- Logger,
143
- setRemoteLogger,
144
-
145
- // version + force update
146
- VersionCheck,
147
- useVersionCheck,
148
- ForceUpdateDialog,
149
-
150
- // network
151
- useNetworkStatus,
152
- getNetworkStatus,
153
- NetworkStatusBanner,
154
-
155
- // permissions
156
- Permissions,
157
-
158
- // formatters
159
- formatDate,
160
- formatTime,
161
- formatRelativeTime,
162
- formatPhone,
163
- formatCurrency,
164
- formatNumber,
165
- formatPercent,
166
- formatCompactNumber,
167
- getInitials,
168
-
169
- // validators
170
- isEmail,
171
- isIndianMobile,
172
- isPhone,
173
- isUrl,
174
- isStrongPassword,
175
- isPan,
176
- isGstin,
177
- isAadhaar,
178
- isIfsc,
179
- isIndianPincode,
180
- isHexColor,
181
- isNumeric,
182
- isInteger,
183
- isAlphanumeric,
184
- isBetween,
185
- minLength,
186
- maxLength,
187
-
188
- // utilities
189
- Responsive,
190
- Spacing,
191
- Padding,
192
- Margin,
193
- isTablet,
194
- shadowStyle,
195
- triggerHaptic,
196
- compressImage,
197
-
198
- // toast
199
- ToastProvider,
200
- toast,
201
- useToast
202
-
203
- // …41 UI components
204
- } from '@webority-technologies/mobile';
205
- ```
206
-
207
- ---
208
-
209
- ## HTTP clients
210
-
211
- ### `publicClient`
212
-
213
- Axios instance for unauthenticated calls. Handles retries (network errors, 429, 503), 30s timeout, environment-aware base URL, and standard headers (including gzip `Accept-Encoding`).
214
-
215
- ### `userClient`
216
-
217
- Axios instance for authenticated calls. Injects a Bearer token from Keychain, queues concurrent 401s while a single refresh is in flight, and replays them on success. Wires into the host app's Redux store via `initUserAuth(store, { logout, refreshToken })`.
218
-
219
- ---
220
-
221
- ## Auth & tokens
222
-
223
- ```ts
224
- import {
225
- storeToken,
226
- getToken,
227
- removeToken,
228
- decodeJWT,
229
- isJWTExpired
230
- } from '@webority-technologies/mobile';
231
-
232
- await storeToken('accessToken', token, expiry);
233
- const stored = await getToken('accessToken'); // { token, expiry } | null
234
- if (stored && isJWTExpired(stored.token)) {
235
- /* refresh */
236
- }
237
- const claims = decodeJWT<{ sub: string; role: string }>(stored.token);
238
- ```
239
-
240
- Tokens are persisted via `react-native-keychain` with biometry-friendly defaults and graceful recovery from "Key permanently invalidated" errors.
241
-
242
- ---
243
-
244
- ## Storage
245
-
246
- Typed `AsyncStorage` wrapper with safe JSON helpers. All operations swallow errors (logging them) and return falsy results so storage failures never crash the app.
247
-
248
- ```ts
249
- import { Storage } from '@webority-technologies/mobile';
250
-
251
- await Storage.setItem('lang', 'en');
252
- const lang = await Storage.getItem('lang'); // string | null
253
-
254
- await Storage.setJson('user', { id: '1', name: 'Navneet' });
255
- const user = await Storage.getJson<User>('user'); // User | null
256
-
257
- await Storage.multiSet({ pushToken: '…', deviceId: '…' });
258
- await Storage.multiRemove(['pushToken']);
259
- ```
260
-
261
- Override the backend (e.g. with MMKV) via `setStorageImplementation()`.
262
-
263
- ---
264
-
265
- ## Logger & crash reporting
266
-
267
- `Logger.info / warn / error` write to the console. `Logger.recordError`, `Logger.breadcrumb`, `Logger.setUser`, and `Logger.setAttribute` forward to an optional **remote sink** that you wire from your app — keeping the library Firebase- and Sentry-agnostic.
268
-
269
- ```ts
270
- import { Logger, setRemoteLogger } from '@webority-technologies/mobile';
271
- import crashlytics from '@react-native-firebase/crashlytics';
272
-
273
- setRemoteLogger({
274
- log: (level, message) => crashlytics().log(`[${level}] ${message}`),
275
- recordError: (error, ctx) => {
276
- if (ctx) Object.entries(ctx).forEach(([k, v]) => crashlytics().setAttribute(k, String(v)));
277
- crashlytics().recordError(error instanceof Error ? error : new Error(String(error)));
278
- },
279
- breadcrumb: (msg, data) => crashlytics().log(data ? `${msg} ${JSON.stringify(data)}` : msg),
280
- setUser: (id) => crashlytics().setUserId(id ?? ''),
281
- setAttribute: (k, v) => crashlytics().setAttribute(k, v == null ? '' : String(v))
282
- });
283
-
284
- Logger.recordError(new Error('boom'), { route: '/checkout', orderId: 42 });
285
- ```
286
-
287
- The same shape works for Sentry, Bugsnag, Datadog, or any custom backend — implement only the methods you need.
288
-
289
- ---
290
-
291
- ## Version check & force update
292
-
293
- ```tsx
294
- import { useVersionCheck, ForceUpdateDialog } from '@webority-technologies/mobile';
295
-
296
- const { isUpdateRequired, updateUrl } = useVersionCheck(isAppReady);
297
- return <ForceUpdateDialog visible={isUpdateRequired} mandatory updateUrl={updateUrl} />;
298
- ```
299
-
300
- `useVersionCheck` only runs in `'Production'`. Country code (used for App Store / Play Store lookups) is configurable via `initWebority({ country: 'us' })`; defaults to `'in'`.
301
-
302
- ---
303
-
304
- ## Network status
305
-
306
- ```tsx
307
- import { useNetworkStatus, NetworkStatusBanner } from '@webority-technologies/mobile';
308
-
309
- // Mount once near the app root
310
- <NetworkStatusBanner />;
311
-
312
- // Or read it inside a screen
313
- const { isConnected, isInternetReachable, type } = useNetworkStatus();
314
- ```
315
-
316
- Falls back to an optimistic "online" status when `@react-native-community/netinfo` is not installed.
317
-
318
- ---
319
-
320
- ## Permissions
321
-
322
- ```ts
323
- import { Permissions } from '@webority-technologies/mobile';
324
-
325
- await Permissions.isAuthorized('camera'); // boolean
326
- const status = await Permissions.ensure('photos'); // 'granted' | 'denied' | 'limited' | 'blocked' | 'unavailable'
327
- if (status === 'blocked') await Permissions.openSettings();
328
- ```
329
-
330
- Maps an abstract `PermissionKind` (camera, microphone, photos, location, contacts, calendar, notifications, bluetooth, …) to the right iOS / Android permission string under the hood.
331
-
332
- ---
333
-
334
- ## Formatters
335
-
336
- ```ts
337
- formatDate(new Date(), 'medium'); // '8 Apr 2026'
338
- formatRelativeTime(then, now); // '5 minutes ago'
339
- formatPhone('9876512345'); // '+91 98765 12345'
340
- formatCurrency(150000); // '₹1,50,000'
341
- formatCurrency(99, { currency: 'USD', locale: 'en-US' }); // '$99.00'
342
- formatCompactNumber(1500000); // '15L' (en-IN)
343
- getInitials('Navneet Singh'); // 'NS'
344
- ```
345
-
346
- All formatters default to `en-IN` locale (Indian numbering / DD-MMM-YYYY style) and accept overrides.
347
-
348
- ---
349
-
350
- ## Validators
351
-
352
- Pragmatic regex-based validators that match common Indian-app needs:
353
-
354
- ```ts
355
- isEmail('a@b.co'); // true
356
- isIndianMobile('+919876512345'); // true
357
- isPan('ABCDE1234F'); // true
358
- isGstin('27AAPFU0939F1ZV'); // true
359
- isIfsc('HDFC0001234'); // true
360
- isIndianPincode('110001'); // true
361
- isStrongPassword('Aa1!@#$%', { requireSymbol: true }); // true
362
- ```
363
-
364
- Plus generic helpers: `isUrl`, `isNumeric`, `isInteger`, `isAlphanumeric`, `isHexColor`, `isBetween`, `minLength`, `maxLength`.
365
-
366
- ---
367
-
368
- ## Theme
369
-
370
- `ThemeProvider` exposes the design-token surface (colors, typography, spacing, radius, shadows, motion) and tracks the system color-scheme automatically. Read it via `useTheme()`. Every shipped component reads from the active theme — no hard-coded colors anywhere. Customize with `mergeTheme` or `initUI({ light, dark })`.
371
-
372
- ---
373
-
374
- ## Toast
375
-
376
- Imperative `toast.success(...)` / `toast.error(...)` from anywhere in the tree, or `useToast().show(...)` inside components.
377
-
378
- ```ts
379
- toast.success('Saved.');
380
- toast.error('Network is down', { description: 'Check your connection.' });
381
- ```
382
-
383
- Mount `<ToastProvider>` once near the app root.
384
-
385
- ---
386
-
387
- ## Components
388
-
389
- 41 components across Layout, Forms & Inputs, Feedback & Status, Overlay, Navigation, and Data Display.
390
-
391
- For the full catalog with props tables and minimal usage examples, see [`docs/COMPONENTS.md`](../../docs/COMPONENTS.md).
392
-
393
- For runnable usage of every component, see [`example/`](../../example/).
394
-
395
- ---
396
-
397
- ## Designing skeleton-aware components
398
-
399
- Presentational primitives (`Card`, `ListItem`, `Avatar`, `Badge`) accept an optional
400
- `loading?: boolean` prop. When `true`, the component renders its normal layout wrapped
401
- in `<SkeletonContent loading mode="auto">` — the walker replaces every `<Text>`,
402
- `<Image>`, and sized leaf `<View>` with a shimmer block matching the element's
403
- dimensions. When `loading` is `false` or omitted, behaviour is unchanged.
404
-
405
- Conventions for components that opt into this pattern:
406
-
407
- - **Render gracefully with undefined data.** Use optional chaining and string defaults
408
- so the auto walker has leaves to skeletonize even before data arrives:
409
- `{item?.title ?? ' '}`, `{item?.subtitle ?? ' '}`. Never let a `<Text>` render `undefined`.
410
- - **Use explicit dimensions on visual elements.** Set `width`/`height` on `<Image>` and
411
- `<View>` leaves, and `fontSize` on `<Text>`, so the walker can size each shimmer
412
- block correctly. Inline styles, `StyleSheet.create`, and arrays all work — they get
413
- flattened.
414
- - **Wrap once at the top.** Don't sprinkle `<SkeletonContent>` inside subtrees; wrap the
415
- component's final return so the entire layout becomes a single coherent placeholder.
416
- - **For data-driven lists, prefer `<SkeletonList>`.** It owns the "show N placeholder
417
- rows while loading, then real data" branching so callers don't hand-roll it.
418
-
419
- Before / after with `Card`:
420
-
421
- ```tsx
422
- // Before — caller hand-rolls a placeholder branch
423
- {loading ? (
424
- <SkeletonCard />
425
- ) : (
426
- <Card>
427
- <Text>{site.name}</Text>
428
- <Text>{site.address}</Text>
429
- </Card>
430
- )}
431
-
432
- // After — Card itself is skeleton-aware
433
- <Card loading={loading}>
434
- <Text>{site?.name ?? ' '}</Text>
435
- <Text>{site?.address ?? ' '}</Text>
436
- </Card>
437
- ```
438
-
439
- ---
440
-
441
- ## License
9
+ This package is published for use inside Webority repositories. Documentation is maintained internally.
442
10
 
443
- MIT. Copyright © Webority Technologies.
11
+ MIT © Webority Technologies.
@@ -8,6 +8,7 @@ var _react = _interopRequireWildcard(require("react"));
8
8
  var _reactNative = require("react-native");
9
9
  var _index = require("../../theme/index.js");
10
10
  var _hapticUtils = require("../../utils/hapticUtils.js");
11
+ var _index2 = require("../Skeleton/index.js");
11
12
  var _jsxRuntime = require("react/jsx-runtime");
12
13
  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); }
13
14
  const AccordionGroupContext = /*#__PURE__*/(0, _react.createContext)(null);
@@ -92,7 +93,8 @@ const Accordion = props => {
92
93
  style,
93
94
  headerStyle,
94
95
  contentStyle,
95
- testID
96
+ testID,
97
+ loading = false
96
98
  } = props;
97
99
  const theme = (0, _index.useTheme)();
98
100
  const styles = (0, _react.useMemo)(() => buildStyles(theme), [theme]);
@@ -158,6 +160,23 @@ const Accordion = props => {
158
160
  backgroundColor: theme.colors.background.elevated,
159
161
  borderRadius: theme.radius.md
160
162
  }] : null;
163
+ if (loading) {
164
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_index2.SkeletonContent, {
165
+ loading: true,
166
+ mode: "auto",
167
+ style: [cardStyle, style],
168
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
169
+ style: styles.header,
170
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
171
+ style: [styles.title, {
172
+ fontSize: theme.typography.fontSize.base
173
+ }],
174
+ numberOfLines: 1,
175
+ children: title ?? ' '
176
+ })
177
+ })
178
+ });
179
+ }
161
180
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
162
181
  style: [cardStyle, style],
163
182
  testID: testID,
@@ -7,6 +7,7 @@ exports.default = exports.Banner = void 0;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
8
  var _reactNative = require("react-native");
9
9
  var _index = require("../../theme/index.js");
10
+ var _index2 = require("../Skeleton/index.js");
10
11
  var _jsxRuntime = require("react/jsx-runtime");
11
12
  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); }
12
13
  const Banner = exports.Banner = /*#__PURE__*/(0, _react.forwardRef)((props, ref) => {
@@ -20,6 +21,7 @@ const Banner = exports.Banner = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
20
21
  onDismiss,
21
22
  visible = true,
22
23
  animateMount = true,
24
+ loading = false,
23
25
  accessibilityLabel,
24
26
  style,
25
27
  testID
@@ -64,6 +66,8 @@ const Banner = exports.Banner = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
64
66
  // eslint-disable-next-line react-hooks/exhaustive-deps
65
67
  }, [visible]);
66
68
  if (!mounted) return null;
69
+ const safeTitle = title ?? ' ';
70
+ const safeMessageString = typeof message === 'string' ? message ?? ' ' : '';
67
71
  const renderIcon = () => {
68
72
  if (icon === false) return null;
69
73
  if (icon) return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
@@ -86,7 +90,7 @@ const Banner = exports.Banner = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
86
90
  const messageString = typeof message === 'string' ? message : '';
87
91
  const builtA11y = accessibilityLabel ?? (title ? `${title}. ${messageString}` : messageString || undefined);
88
92
  const liveRegion = variant === 'error' ? 'assertive' : 'polite';
89
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Animated.View, {
93
+ const rendered = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Animated.View, {
90
94
  ref: ref,
91
95
  accessibilityRole: 'alert',
92
96
  accessibilityLiveRegion: liveRegion,
@@ -109,7 +113,7 @@ const Banner = exports.Banner = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
109
113
  style: styles.row,
110
114
  children: [renderIcon(), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
111
115
  style: styles.textBlock,
112
- children: [title ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
116
+ children: [title || loading ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
113
117
  style: {
114
118
  color: theme.colors.text.primary,
115
119
  fontSize: theme.typography.fontSize.base,
@@ -117,15 +121,15 @@ const Banner = exports.Banner = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
117
121
  lineHeight: 20
118
122
  },
119
123
  numberOfLines: 2,
120
- children: title
121
- }) : null, typeof message === 'string' ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
124
+ children: safeTitle
125
+ }) : null, typeof message === 'string' || loading ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
122
126
  style: {
123
127
  color: theme.colors.text.secondary,
124
128
  fontSize: theme.typography.fontSize.sm,
125
129
  lineHeight: 18,
126
130
  marginTop: title ? 2 : 0
127
131
  },
128
- children: message
132
+ children: safeMessageString || ' '
129
133
  }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
130
134
  style: {
131
135
  marginTop: title ? 2 : 0
@@ -179,6 +183,14 @@ const Banner = exports.Banner = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
179
183
  })
180
184
  }) : null]
181
185
  });
186
+ if (loading) {
187
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_index2.SkeletonContent, {
188
+ loading: true,
189
+ mode: "auto",
190
+ children: rendered
191
+ });
192
+ }
193
+ return rendered;
182
194
  });
183
195
  Banner.displayName = 'Banner';
184
196
  const tintFor = (theme, variant) => {
@@ -9,6 +9,7 @@ var _reactNative = require("react-native");
9
9
  var _index = require("../../theme/index.js");
10
10
  var _usePressAnimation = require("../../hooks/usePressAnimation.js");
11
11
  var _hapticUtils = require("../../utils/hapticUtils.js");
12
+ var _index2 = require("../Spinner/index.js");
12
13
  var _jsxRuntime = require("react/jsx-runtime");
13
14
  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); }
14
15
  const Button = exports.Button = /*#__PURE__*/(0, _react.forwardRef)((props, ref) => {
@@ -55,9 +56,11 @@ const Button = exports.Button = /*#__PURE__*/(0, _react.forwardRef)((props, ref)
55
56
  const accessibleLabel = accessibilityLabel ?? title;
56
57
  const content = /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
57
58
  style: styles.contentRow,
58
- children: loading ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, {
59
+ children: loading ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_index2.Spinner, {
60
+ variant: "circular",
61
+ size: "small",
59
62
  color: variantStyles.textColor,
60
- size: size === 'xs' || size === 'sm' ? 'small' : 'small'
63
+ accessibilityLabel: "Loading"
61
64
  }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
62
65
  children: [leftIcon ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
63
66
  style: styles.iconLeft,
@@ -8,6 +8,7 @@ var _react = _interopRequireWildcard(require("react"));
8
8
  var _reactNative = require("react-native");
9
9
  var _index = require("../../theme/index.js");
10
10
  var _index2 = require("../../utils/index.js");
11
+ var _index3 = require("../Skeleton/index.js");
11
12
  var _jsxRuntime = require("react/jsx-runtime");
12
13
  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); }
13
14
  /**
@@ -54,7 +55,8 @@ const CarouselInner = /*#__PURE__*/(0, _react.forwardRef)((props, ref) => {
54
55
  accessibilityLabel,
55
56
  testID,
56
57
  showThumbnails = false,
57
- renderThumbnail
58
+ renderThumbnail,
59
+ loading = false
58
60
  } = props;
59
61
  const theme = (0, _index.useTheme)();
60
62
  const isControlled = typeof controlledIndex === 'number';
@@ -215,6 +217,21 @@ const CarouselInner = /*#__PURE__*/(0, _react.forwardRef)((props, ref) => {
215
217
  offset: slideStride * i,
216
218
  index: i
217
219
  }), [slideStride]);
220
+ if (loading) {
221
+ const slideWidth = itemWidth === 'screen' ? containerWidth || 320 : itemWidth;
222
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_index3.SkeletonContent, {
223
+ loading: true,
224
+ mode: "auto",
225
+ style: [styles.container, containerStyle],
226
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
227
+ style: {
228
+ width: slideWidth,
229
+ height: 160,
230
+ borderRadius: 12
231
+ }
232
+ })
233
+ });
234
+ }
218
235
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
219
236
  style: [styles.container, containerStyle],
220
237
  onLayout: e => setContainerWidth(e.nativeEvent.layout.width),