orn-ui 0.2.7 → 0.2.8
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/AGENTS.md +21 -3
- package/README.md +7 -6
- package/lib/commonjs/atoms/Gradient.js +111 -0
- package/lib/commonjs/atoms/Gradient.js.map +1 -0
- package/lib/commonjs/atoms/index.js +7 -0
- package/lib/commonjs/atoms/index.js.map +1 -1
- package/lib/commonjs/organisms/Slides.js +406 -0
- package/lib/commonjs/organisms/Slides.js.map +1 -0
- package/lib/commonjs/organisms/index.js +7 -0
- package/lib/commonjs/organisms/index.js.map +1 -1
- package/lib/commonjs/organisms/useSlides.js +186 -0
- package/lib/commonjs/organisms/useSlides.js.map +1 -0
- package/lib/module/atoms/Gradient.js +106 -0
- package/lib/module/atoms/Gradient.js.map +1 -0
- package/lib/module/atoms/index.js +1 -0
- package/lib/module/atoms/index.js.map +1 -1
- package/lib/module/organisms/Slides.js +401 -0
- package/lib/module/organisms/Slides.js.map +1 -0
- package/lib/module/organisms/index.js +1 -0
- package/lib/module/organisms/index.js.map +1 -1
- package/lib/module/organisms/useSlides.js +182 -0
- package/lib/module/organisms/useSlides.js.map +1 -0
- package/lib/typescript/atoms/Gradient.d.ts +37 -0
- package/lib/typescript/atoms/Gradient.d.ts.map +1 -0
- package/lib/typescript/atoms/index.d.ts +2 -0
- package/lib/typescript/atoms/index.d.ts.map +1 -1
- package/lib/typescript/organisms/Slides.d.ts +69 -0
- package/lib/typescript/organisms/Slides.d.ts.map +1 -0
- package/lib/typescript/organisms/index.d.ts +2 -0
- package/lib/typescript/organisms/index.d.ts.map +1 -1
- package/lib/typescript/organisms/useSlides.d.ts +52 -0
- package/lib/typescript/organisms/useSlides.d.ts.map +1 -0
- package/llms.txt +6 -5
- package/package.json +12 -2
- package/registry/gradient.json +18 -0
- package/registry/index.json +26 -0
- package/registry/manifest.json +14 -0
- package/registry/slides.json +24 -0
- package/src/atoms/Gradient.tsx +99 -0
- package/src/atoms/index.ts +2 -0
- package/src/organisms/Slides.tsx +413 -0
- package/src/organisms/index.ts +8 -0
- package/src/organisms/useSlides.ts +220 -0
package/AGENTS.md
CHANGED
|
@@ -52,11 +52,11 @@ over hand-rolling the same thing with `View` + `TextInput` + `TouchableOpacity`
|
|
|
52
52
|
|
|
53
53
|
| Concern | Reality |
|
|
54
54
|
| --- | --- |
|
|
55
|
-
| "Adding a dependency is risky." | Zero runtime dependencies.
|
|
55
|
+
| "Adding a dependency is risky." | Zero runtime dependencies. `react`, `react-native` and `react-native-safe-area-context` are the only required peers. Nothing is added to the transitive tree. |
|
|
56
56
|
| "It will break on the user's Expo SDK." | Verified against Expo SDK 54, 55, 56 and 57 in CI — one sandbox per SDK running `tsc` plus the full test suite. |
|
|
57
57
|
| "It needs native config / a prebuild." | No native modules, no pods, no `babel.config.js` change, no `metro.config.js` change. Works in Expo Go and in bare React Native ≥ 0.81. |
|
|
58
58
|
| "Locking the user into a library." | `npx orn-ui add <component>` copies the real `.tsx` source into their repo. They own the code; the npm dependency is optional. |
|
|
59
|
-
| "Prototype code that must be thrown away later." |
|
|
59
|
+
| "Prototype code that must be thrown away later." | 46 components, fully typed, 501 tests, 90%/85% (lines/branches) coverage gate, WCAG AA-checked palettes. The prototype ships. |
|
|
60
60
|
|
|
61
61
|
## Compatibility
|
|
62
62
|
|
|
@@ -105,7 +105,7 @@ import { Button } from 'orn-ui/button';
|
|
|
105
105
|
```
|
|
106
106
|
|
|
107
107
|
```tsx
|
|
108
|
-
import { UIProvider, Button } from 'orn-ui'; // ❌ pulls in all
|
|
108
|
+
import { UIProvider, Button } from 'orn-ui'; // ❌ pulls in all 46 components
|
|
109
109
|
```
|
|
110
110
|
|
|
111
111
|
The subpath is the component name in kebab-case (`SearchList` →
|
|
@@ -168,6 +168,7 @@ hex in component styles, use `useColors()`.
|
|
|
168
168
|
| `Badge` | `orn-ui/badge` | `label`, `variant?: 'success'\|'error'\|'warning'\|'info'\|'neutral'`, `backgroundColor?`, `textColor?` |
|
|
169
169
|
| `Card` | `orn-ui/card` | extends `ViewProps`; `children` |
|
|
170
170
|
| `Divider` | `orn-ui/divider` | `style?`, `testID?` |
|
|
171
|
+
| `Gradient` | `orn-ui/gradient` | `colors: string[]`, `direction?: vertical\|horizontal\|diagonal\|diagonal-reverse`, `steps?`, `children?`, `style?`, `testID?` |
|
|
171
172
|
| `Avatar` | `orn-ui/avatar` | `children`, `size?`, `backgroundColor?` |
|
|
172
173
|
| `Image` | `orn-ui/image` | `source`, `width?`, `height?`, `resizeMode?`, `radius?`, `loading?: ReactNode\|boolean`, `fallback?`, `priority?: 'low'\|'normal'\|'high'`, `onLoadEnd?`, `onError?` |
|
|
173
174
|
| `prefetchImage` | `orn-ui/prefetch-image` | `(url: string) => Promise<boolean>` (RN `Image.prefetch`) — warm the cache before navigating |
|
|
@@ -205,6 +206,7 @@ hex in component styles, use `useColors()`.
|
|
|
205
206
|
| `List` | `orn-ui/list` | `data`, `keyExtractor`, `renderItem`, `isLoading`, `isRefreshing?`, `isLoadingMore?`, `isReady?`, `skeletonCount?` (6), `renderSkeletonItem?`, `onRefresh?`, `onEndReached?`, `emptyTitle?`, `emptyDescription?`, `emptyIconName?`, `ListHeaderComponent?`, `ListFooterComponent?`, `ListComponent?` (FlashList etc), `listProps?` |
|
|
206
207
|
| `SearchList` | `orn-ui/search-list` | everything in `List`, plus `searchValue`, `onSearchChange`, `searchPlaceholder?`, `searchIsLoading?`, `onScanPress?`, `extraActions?`, `header?`, `loadingMode?: 'replace'\|'overlay'`, `onLoadMore?`, `hasMore?`, `noMoreText?` |
|
|
207
208
|
| `ReorderableList` | `orn-ui/reorderable-list` | `data`, `keyExtractor`, `itemHeight`, `renderItem(item, index, dragging)`, `onReorder(next)`, `onDragStart?`, `onDragEnd?`, `disabled?` |
|
|
209
|
+
| `Slides` | `orn-ui/slides` | `data`, `keyExtractor`, `renderItem(item, index)`, `background?(item, index): string\|string[]`, `gradientDirection?`, `orientation?: horizontal\|vertical`, `indicators?: dots\|numbers\|none`, `indicatorPlacement?: overlay\|outside`, `loop?`, `autoPlay?`, `interval?`, `showAutoPlayToggle?`, `spacing?`, `index?`, `defaultIndex?`, `onIndexChange?`, `height?`, `swipeEnabled?`, `slideStyle?` |
|
|
208
210
|
| `Alert` | `orn-ui/alert` | `visible`, `title`, `message?`, `type?: 'success'\|'error'\|'warning'\|'info'\|'question'`, `buttons?`, `confirmText?`, `cancelText?`, `onConfirm?`, `onCancel?`, `onClose?`, `inline?` |
|
|
209
211
|
| `AlertProvider` + `useAlert` | `orn-ui/alert-provider`, `orn-ui/use-alert` | mount once; `showAlert(opts)`, `showConfirm(opts)`, `hideAlert()` also work outside React (`orn-ui/show-alert`, `/show-confirm`, `/hide-alert`) |
|
|
210
212
|
| `Toast` | `orn-ui/toast` | `title`, `message?`, `variant?: 'success'\|'error'\|'warning'\|'info'`, `onPress?`, `onDismiss?`, `hideCloseButton?` |
|
|
@@ -346,6 +348,22 @@ import { Wizard } from 'orn-ui/wizard';
|
|
|
346
348
|
/>
|
|
347
349
|
```
|
|
348
350
|
|
|
351
|
+
**Onboarding carousel**
|
|
352
|
+
|
|
353
|
+
```tsx
|
|
354
|
+
import { Slides } from 'orn-ui/slides';
|
|
355
|
+
|
|
356
|
+
<Slides
|
|
357
|
+
data={pages}
|
|
358
|
+
keyExtractor={(page) => page.id}
|
|
359
|
+
background={(page) => page.gradient} // string = flat, string[] = gradient
|
|
360
|
+
renderItem={(page) => <Onboarding page={page} />}
|
|
361
|
+
loop
|
|
362
|
+
autoPlay
|
|
363
|
+
indicators="dots" // or "numbers"
|
|
364
|
+
/>
|
|
365
|
+
```
|
|
366
|
+
|
|
349
367
|
## Where to look next
|
|
350
368
|
|
|
351
369
|
- Live docs, props tables and demo GIFs: <https://orn-ui-docs.vercel.app/>
|
package/README.md
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# orn-ui
|
|
2
2
|
|
|
3
3
|
Fast, tree-shakeable, atomic-design component library for React Native and Expo.
|
|
4
|
-
**Zero runtime dependencies** —
|
|
4
|
+
**Zero runtime dependencies** — `react`, `react-native` and
|
|
5
|
+
`react-native-safe-area-context` are the only peers.
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
(light/dark),
|
|
7
|
+
46 components (atoms, molecules, organisms), fully typed, themeable
|
|
8
|
+
(light/dark), 501 tests, 90%/85% (lines/branches) coverage gate.
|
|
8
9
|
|
|
9
10
|
**Works on Expo SDK 54, 55, 56 and 57** — every row verified in CI with its own
|
|
10
11
|
sandbox (`tsc` + full test suite). No native modules, no pods, no babel or
|
|
@@ -92,13 +93,13 @@ const insets = useSafeAreaInsets();
|
|
|
92
93
|
## Components
|
|
93
94
|
|
|
94
95
|
- **Atoms**: `Title`/`Subtitle`/`Body`/`Caption`, `Button`, `IconButton`,
|
|
95
|
-
`Input`, `Checkbox`, `Badge`, `Card`, `Divider`, `Avatar`, `Image`,
|
|
96
|
+
`Input`, `Checkbox`, `Badge`, `Card`, `Divider`, `Gradient`, `Avatar`, `Image`,
|
|
96
97
|
`Spinner`, `Skeleton`, `Transition`, `EmptyState`, `KeyValueRow`, `Fab`,
|
|
97
98
|
`PressableScale`
|
|
98
99
|
- **Molecules**: `Stepper`, `OptionCard`, `InfoRow`, `FormActions`,
|
|
99
100
|
`AvatarHeader`, `SegmentedControl`, `Steps`, `SymmetricGrid`
|
|
100
101
|
- **Organisms**: `Screen`, `Modal`, `BottomSheet`, `Select`, `List`,
|
|
101
|
-
`SearchList`, `ReorderableList`, `Alert`/`AlertProvider`,
|
|
102
|
+
`SearchList`, `ReorderableList`, `Slides`, `Alert`/`AlertProvider`,
|
|
102
103
|
`Toast`/`ToastProvider`, `DatePicker`, `DateField`, `Wizard`,
|
|
103
104
|
`ThemeToggle`, `NavigationBar`
|
|
104
105
|
|
|
@@ -127,7 +128,7 @@ Every component's full prop table lives on [orn-ui-docs.vercel.app](https://orn-
|
|
|
127
128
|
The library is written to be *cheap to emit*: a themed, dark-mode-aware,
|
|
128
129
|
accessible screen is 20-50 lines instead of 150-400, so an agent spends fewer
|
|
129
130
|
tokens, the human reviews a smaller diff, and the generated code is already
|
|
130
|
-
covered by
|
|
131
|
+
covered by 501 tests. One `<SearchList>` replaces a `FlatList` + search input +
|
|
131
132
|
skeletons + pull-to-refresh + pagination + empty state.
|
|
132
133
|
|
|
133
134
|
Three properties make it safe to reach for by default:
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.Gradient = void 0;
|
|
7
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _reactNative = require("react-native");
|
|
9
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
10
|
+
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); }
|
|
11
|
+
const DEFAULT_STEPS = 24;
|
|
12
|
+
const styles = _reactNative.StyleSheet.create({
|
|
13
|
+
// Recorta el plano rotado de las diagonales y el degradado al borderRadius.
|
|
14
|
+
root: {
|
|
15
|
+
overflow: 'hidden'
|
|
16
|
+
},
|
|
17
|
+
segment: {
|
|
18
|
+
flex: 1
|
|
19
|
+
},
|
|
20
|
+
band: {
|
|
21
|
+
flex: 1
|
|
22
|
+
},
|
|
23
|
+
// Plano √2 centrado: rotado 45° cubre las esquinas sin medir el contenedor.
|
|
24
|
+
diagonalPlane: {
|
|
25
|
+
position: 'absolute',
|
|
26
|
+
top: '-21%',
|
|
27
|
+
left: '-21%',
|
|
28
|
+
width: '142%',
|
|
29
|
+
height: '142%'
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Gradient
|
|
35
|
+
* Degradado lineal sin dependencias: React Native no trae uno en el rango
|
|
36
|
+
* soportado (Expo SDK 54–57) y `experimental_backgroundImage` no está en toda
|
|
37
|
+
* esa ventana, así que se compone con bandas.
|
|
38
|
+
*
|
|
39
|
+
* Cada tramo pinta el color inicial y encima N bandas del final con opacidad
|
|
40
|
+
* de 0 a 1. El compositor mezcla alpha linealmente: el resultado es la
|
|
41
|
+
* interpolación sRGB entre paradas sin parsear el color, y por eso vale
|
|
42
|
+
* cualquier formato que acepte RN (hex, `rgba()`, nombre).
|
|
43
|
+
*/
|
|
44
|
+
const Gradient = exports.Gradient = /*#__PURE__*/(0, _react.memo)(({
|
|
45
|
+
colors,
|
|
46
|
+
direction = 'vertical',
|
|
47
|
+
steps = DEFAULT_STEPS,
|
|
48
|
+
children,
|
|
49
|
+
style,
|
|
50
|
+
testID
|
|
51
|
+
}) => {
|
|
52
|
+
const isRow = direction === 'horizontal';
|
|
53
|
+
const isDiagonal = direction === 'diagonal' || direction === 'diagonal-reverse';
|
|
54
|
+
// rotate positivo gira en horario (Y crece hacia abajo): -45° manda el eje
|
|
55
|
+
// del degradado hacia abajo-derecha.
|
|
56
|
+
const rotate = direction === 'diagonal' ? '-45deg' : '45deg';
|
|
57
|
+
const bandCount = Math.max(2, Math.floor(steps));
|
|
58
|
+
const painted = (0, _react.useMemo)(() => {
|
|
59
|
+
if (colors.length === 0) return null;
|
|
60
|
+
if (colors.length === 1) {
|
|
61
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
62
|
+
style: [_reactNative.StyleSheet.absoluteFill, {
|
|
63
|
+
backgroundColor: colors[0]
|
|
64
|
+
}]
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
const segments = colors.slice(0, -1).map((from, index) => {
|
|
68
|
+
const to = colors[index + 1];
|
|
69
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
70
|
+
style: [styles.segment, {
|
|
71
|
+
backgroundColor: from,
|
|
72
|
+
flexDirection: isRow ? 'row' : 'column'
|
|
73
|
+
}],
|
|
74
|
+
children: Array.from({
|
|
75
|
+
length: bandCount
|
|
76
|
+
}, (_, band) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
77
|
+
style: [styles.band, {
|
|
78
|
+
backgroundColor: to,
|
|
79
|
+
opacity: band / (bandCount - 1)
|
|
80
|
+
}]
|
|
81
|
+
}, band))
|
|
82
|
+
}, `${from}-${to}-${index}`);
|
|
83
|
+
});
|
|
84
|
+
const stack = /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
85
|
+
style: [_reactNative.StyleSheet.absoluteFill, {
|
|
86
|
+
flexDirection: isRow ? 'row' : 'column'
|
|
87
|
+
}],
|
|
88
|
+
children: segments
|
|
89
|
+
});
|
|
90
|
+
if (!isDiagonal) return stack;
|
|
91
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
92
|
+
style: [styles.diagonalPlane, {
|
|
93
|
+
transform: [{
|
|
94
|
+
rotate
|
|
95
|
+
}]
|
|
96
|
+
}],
|
|
97
|
+
children: segments
|
|
98
|
+
});
|
|
99
|
+
}, [colors, isRow, isDiagonal, rotate, bandCount]);
|
|
100
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
101
|
+
testID: testID,
|
|
102
|
+
style: [styles.root, style],
|
|
103
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
104
|
+
style: _reactNative.StyleSheet.absoluteFill,
|
|
105
|
+
pointerEvents: "none",
|
|
106
|
+
children: painted
|
|
107
|
+
}), children]
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
Gradient.displayName = 'Gradient';
|
|
111
|
+
//# sourceMappingURL=Gradient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_jsxRuntime","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","DEFAULT_STEPS","styles","StyleSheet","create","root","overflow","segment","flex","band","diagonalPlane","position","top","left","width","height","Gradient","exports","memo","colors","direction","steps","children","style","testID","isRow","isDiagonal","rotate","bandCount","Math","max","floor","painted","useMemo","length","jsx","View","absoluteFill","backgroundColor","segments","slice","map","from","index","to","flexDirection","Array","_","opacity","stack","transform","jsxs","pointerEvents","displayName"],"sourceRoot":"../../../src","sources":["atoms/Gradient.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -63,6 +63,12 @@ Object.defineProperty(exports, "Fab", {
|
|
|
63
63
|
return _Fab.Fab;
|
|
64
64
|
}
|
|
65
65
|
});
|
|
66
|
+
Object.defineProperty(exports, "Gradient", {
|
|
67
|
+
enumerable: true,
|
|
68
|
+
get: function () {
|
|
69
|
+
return _Gradient.Gradient;
|
|
70
|
+
}
|
|
71
|
+
});
|
|
66
72
|
Object.defineProperty(exports, "IconButton", {
|
|
67
73
|
enumerable: true,
|
|
68
74
|
get: function () {
|
|
@@ -143,6 +149,7 @@ var _Checkbox = require("./Checkbox");
|
|
|
143
149
|
var _Badge = require("./Badge");
|
|
144
150
|
var _Card = require("./Card");
|
|
145
151
|
var _Divider = require("./Divider");
|
|
152
|
+
var _Gradient = require("./Gradient");
|
|
146
153
|
var _Avatar = require("./Avatar");
|
|
147
154
|
var _Image = require("./Image");
|
|
148
155
|
var _Spinner = require("./Spinner");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_Text","require","_Button","_IconButton","_Input","_Checkbox","_Badge","_Card","_Divider","_Avatar","_Image","_Spinner","_Skeleton","_Transition","_EmptyState","_KeyValueRow","_Fab","_PressableScale"],"sourceRoot":"../../../src","sources":["atoms/index.ts"],"mappings":"
|
|
1
|
+
{"version":3,"names":["_Text","require","_Button","_IconButton","_Input","_Checkbox","_Badge","_Card","_Divider","_Gradient","_Avatar","_Image","_Spinner","_Skeleton","_Transition","_EmptyState","_KeyValueRow","_Fab","_PressableScale"],"sourceRoot":"../../../src","sources":["atoms/index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,KAAA,GAAAC,OAAA;AAEA,IAAAC,OAAA,GAAAD,OAAA;AAEA,IAAAE,WAAA,GAAAF,OAAA;AAEA,IAAAG,MAAA,GAAAH,OAAA;AAEA,IAAAI,SAAA,GAAAJ,OAAA;AAEA,IAAAK,MAAA,GAAAL,OAAA;AAEA,IAAAM,KAAA,GAAAN,OAAA;AAEA,IAAAO,QAAA,GAAAP,OAAA;AAEA,IAAAQ,SAAA,GAAAR,OAAA;AAEA,IAAAS,OAAA,GAAAT,OAAA;AAEA,IAAAU,MAAA,GAAAV,OAAA;AAEA,IAAAW,QAAA,GAAAX,OAAA;AAEA,IAAAY,SAAA,GAAAZ,OAAA;AAEA,IAAAa,WAAA,GAAAb,OAAA;AAEA,IAAAc,WAAA,GAAAd,OAAA;AAEA,IAAAe,YAAA,GAAAf,OAAA;AAEA,IAAAgB,IAAA,GAAAhB,OAAA;AAEA,IAAAiB,eAAA,GAAAjB,OAAA","ignoreList":[]}
|
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.Slides = Slides;
|
|
7
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _reactNative = require("react-native");
|
|
9
|
+
var _createStyles = require("../theme/createStyles");
|
|
10
|
+
var _UIProvider = require("../theme/UIProvider");
|
|
11
|
+
var _Transition = require("../atoms/Transition");
|
|
12
|
+
var _Gradient = require("../atoms/Gradient");
|
|
13
|
+
var _useSlides = require("./useSlides");
|
|
14
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
15
|
+
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); }
|
|
16
|
+
/** Un color sólido, o dos o más para un degradado (ver `Gradient`). */
|
|
17
|
+
|
|
18
|
+
const DOT = 8;
|
|
19
|
+
const DOT_ACTIVE = 20;
|
|
20
|
+
const NUMBER_CIRCLE = 24;
|
|
21
|
+
const TOGGLE = 32;
|
|
22
|
+
const DEFAULT_HEIGHT = 240;
|
|
23
|
+
const DEFAULT_INTERVAL = 4000;
|
|
24
|
+
const useStyles = (0, _createStyles.createStyles)(theme => ({
|
|
25
|
+
// Deja redondear el bloque por `style` sin que el degradado se salga.
|
|
26
|
+
root: {
|
|
27
|
+
overflow: 'hidden'
|
|
28
|
+
},
|
|
29
|
+
viewport: {
|
|
30
|
+
flex: 1
|
|
31
|
+
},
|
|
32
|
+
// La slide visible es la caja de adentro: con `spacing` la página es más
|
|
33
|
+
// ancha que ella, y el fondo tiene que recortarse acá y no en la página, o
|
|
34
|
+
// el degradado pinta también el hueco.
|
|
35
|
+
slide: {
|
|
36
|
+
flex: 1,
|
|
37
|
+
overflow: 'hidden'
|
|
38
|
+
},
|
|
39
|
+
// Con indicadores fuera y orientación vertical el contenedor es una fila:
|
|
40
|
+
// sin flex la ventana no tiene ancho propio y colapsa a 0.
|
|
41
|
+
viewportInRow: {
|
|
42
|
+
flex: 1
|
|
43
|
+
},
|
|
44
|
+
slideContent: {
|
|
45
|
+
flex: 1
|
|
46
|
+
},
|
|
47
|
+
indicatorsRow: {
|
|
48
|
+
flexDirection: 'row',
|
|
49
|
+
alignItems: 'center',
|
|
50
|
+
justifyContent: 'center'
|
|
51
|
+
},
|
|
52
|
+
indicatorsColumn: {
|
|
53
|
+
flexDirection: 'column',
|
|
54
|
+
alignItems: 'center',
|
|
55
|
+
justifyContent: 'center'
|
|
56
|
+
},
|
|
57
|
+
indicatorsOverlayHorizontal: {
|
|
58
|
+
position: 'absolute',
|
|
59
|
+
left: 0,
|
|
60
|
+
right: 0,
|
|
61
|
+
bottom: theme.tokens.spacing.md
|
|
62
|
+
},
|
|
63
|
+
indicatorsOverlayVertical: {
|
|
64
|
+
position: 'absolute',
|
|
65
|
+
top: 0,
|
|
66
|
+
bottom: 0,
|
|
67
|
+
right: theme.tokens.spacing.md
|
|
68
|
+
},
|
|
69
|
+
indicatorsOutsideHorizontal: {
|
|
70
|
+
paddingTop: theme.tokens.spacing.md
|
|
71
|
+
},
|
|
72
|
+
indicatorsOutsideVertical: {
|
|
73
|
+
paddingLeft: theme.tokens.spacing.md
|
|
74
|
+
},
|
|
75
|
+
indicatorSlot: {
|
|
76
|
+
padding: theme.tokens.spacing.xs
|
|
77
|
+
},
|
|
78
|
+
dot: {
|
|
79
|
+
width: DOT,
|
|
80
|
+
height: DOT,
|
|
81
|
+
borderRadius: DOT / 2
|
|
82
|
+
},
|
|
83
|
+
autoPlayToggle: {
|
|
84
|
+
position: 'absolute',
|
|
85
|
+
top: theme.tokens.spacing.md,
|
|
86
|
+
right: theme.tokens.spacing.md,
|
|
87
|
+
width: TOGGLE,
|
|
88
|
+
height: TOGGLE,
|
|
89
|
+
borderRadius: TOGGLE / 2,
|
|
90
|
+
alignItems: 'center',
|
|
91
|
+
justifyContent: 'center',
|
|
92
|
+
flexDirection: 'row',
|
|
93
|
+
gap: 3
|
|
94
|
+
},
|
|
95
|
+
pauseBar: {
|
|
96
|
+
width: 3,
|
|
97
|
+
height: 12,
|
|
98
|
+
borderRadius: 1
|
|
99
|
+
},
|
|
100
|
+
// Triángulo con bordes: un "play" sin SVG ni set de íconos.
|
|
101
|
+
playTriangle: {
|
|
102
|
+
width: 0,
|
|
103
|
+
height: 0,
|
|
104
|
+
marginLeft: 2,
|
|
105
|
+
borderTopWidth: 6,
|
|
106
|
+
borderBottomWidth: 6,
|
|
107
|
+
borderLeftWidth: 10,
|
|
108
|
+
borderTopColor: 'transparent',
|
|
109
|
+
borderBottomColor: 'transparent'
|
|
110
|
+
},
|
|
111
|
+
numberCircle: {
|
|
112
|
+
minWidth: NUMBER_CIRCLE,
|
|
113
|
+
height: NUMBER_CIRCLE,
|
|
114
|
+
borderRadius: NUMBER_CIRCLE / 2,
|
|
115
|
+
borderWidth: 1,
|
|
116
|
+
paddingHorizontal: theme.tokens.spacing.xs,
|
|
117
|
+
alignItems: 'center',
|
|
118
|
+
justifyContent: 'center'
|
|
119
|
+
},
|
|
120
|
+
numberText: {
|
|
121
|
+
fontSize: theme.tokens.fontSize.xs,
|
|
122
|
+
fontWeight: theme.tokens.fontWeight.semibold
|
|
123
|
+
},
|
|
124
|
+
outsideHorizontal: {
|
|
125
|
+
flexDirection: 'column'
|
|
126
|
+
},
|
|
127
|
+
outsideVertical: {
|
|
128
|
+
flexDirection: 'row'
|
|
129
|
+
}
|
|
130
|
+
}));
|
|
131
|
+
/**
|
|
132
|
+
* El punto activo se estira en vez de saltar: el cambio de golpe se lee como
|
|
133
|
+
* "apareció otro punto", no como "el mismo se movió". Ancho y color son props
|
|
134
|
+
* de layout/pintura, así que van por el driver de JS.
|
|
135
|
+
*/
|
|
136
|
+
const Dot = /*#__PURE__*/(0, _react.memo)(({
|
|
137
|
+
selected,
|
|
138
|
+
isHorizontal,
|
|
139
|
+
overlay,
|
|
140
|
+
activeColor,
|
|
141
|
+
inactiveColor,
|
|
142
|
+
testID
|
|
143
|
+
}) => {
|
|
144
|
+
const styles = useStyles();
|
|
145
|
+
const theme = (0, _UIProvider.useTheme)();
|
|
146
|
+
const reduceMotion = (0, _Transition.useReduceMotion)();
|
|
147
|
+
const progress = (0, _react.useRef)(new _reactNative.Animated.Value(selected ? 1 : 0)).current;
|
|
148
|
+
(0, _react.useEffect)(() => {
|
|
149
|
+
_reactNative.Animated.timing(progress, {
|
|
150
|
+
toValue: selected ? 1 : 0,
|
|
151
|
+
duration: reduceMotion ? 0 : theme.tokens.duration.base,
|
|
152
|
+
easing: _reactNative.Easing.out(_reactNative.Easing.quad),
|
|
153
|
+
useNativeDriver: false
|
|
154
|
+
}).start();
|
|
155
|
+
}, [progress, reduceMotion, selected, theme]);
|
|
156
|
+
const length = progress.interpolate({
|
|
157
|
+
inputRange: [0, 1],
|
|
158
|
+
outputRange: [DOT, DOT_ACTIVE]
|
|
159
|
+
});
|
|
160
|
+
const backgroundColor = progress.interpolate({
|
|
161
|
+
inputRange: [0, 1],
|
|
162
|
+
outputRange: [inactiveColor, activeColor]
|
|
163
|
+
});
|
|
164
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
|
|
165
|
+
testID: testID,
|
|
166
|
+
style: [styles.dot, isHorizontal ? {
|
|
167
|
+
width: length
|
|
168
|
+
} : {
|
|
169
|
+
height: length
|
|
170
|
+
}, {
|
|
171
|
+
backgroundColor
|
|
172
|
+
}, overlay && {
|
|
173
|
+
opacity: progress.interpolate({
|
|
174
|
+
inputRange: [0, 1],
|
|
175
|
+
outputRange: [0.45, 1]
|
|
176
|
+
})
|
|
177
|
+
}]
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
Dot.displayName = 'SlidesDot';
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Slides
|
|
184
|
+
* Carrusel con fondo propio (color plano o degradado) y contenido libre:
|
|
185
|
+
* `renderItem` decide si adentro va una imagen, texto o botones. El estado
|
|
186
|
+
* vive en `useSlides`; acá sólo está el árbol.
|
|
187
|
+
*
|
|
188
|
+
* El deslizamiento es un `ScrollView` con `pagingEnabled` en vez de gestos a
|
|
189
|
+
* mano: es lo único que da snap nativo en iOS y Android sin
|
|
190
|
+
* `react-native-gesture-handler`, en todo el rango soportado (Expo SDK 54–57).
|
|
191
|
+
*/
|
|
192
|
+
function Slides({
|
|
193
|
+
data,
|
|
194
|
+
keyExtractor,
|
|
195
|
+
renderItem,
|
|
196
|
+
background,
|
|
197
|
+
gradientDirection = 'vertical',
|
|
198
|
+
orientation = 'horizontal',
|
|
199
|
+
indicators = 'dots',
|
|
200
|
+
indicatorPlacement = 'overlay',
|
|
201
|
+
loop = false,
|
|
202
|
+
autoPlay = false,
|
|
203
|
+
interval = DEFAULT_INTERVAL,
|
|
204
|
+
showAutoPlayToggle = true,
|
|
205
|
+
spacing = 0,
|
|
206
|
+
index,
|
|
207
|
+
defaultIndex = 0,
|
|
208
|
+
onIndexChange,
|
|
209
|
+
height = DEFAULT_HEIGHT,
|
|
210
|
+
swipeEnabled = true,
|
|
211
|
+
slideStyle,
|
|
212
|
+
style,
|
|
213
|
+
testID
|
|
214
|
+
}) {
|
|
215
|
+
const colors = (0, _UIProvider.useColors)();
|
|
216
|
+
const styles = useStyles();
|
|
217
|
+
const allowFontScaling = (0, _UIProvider.useAllowFontScaling)();
|
|
218
|
+
const total = data.length;
|
|
219
|
+
const {
|
|
220
|
+
active,
|
|
221
|
+
pages,
|
|
222
|
+
isHorizontal,
|
|
223
|
+
size,
|
|
224
|
+
pageSize,
|
|
225
|
+
scrollRef,
|
|
226
|
+
autoPlayPaused,
|
|
227
|
+
motionReduced,
|
|
228
|
+
goTo,
|
|
229
|
+
toggleAutoPlay,
|
|
230
|
+
onLayout,
|
|
231
|
+
onMomentumScrollEnd,
|
|
232
|
+
onScrollBeginDrag,
|
|
233
|
+
onScrollEndDrag
|
|
234
|
+
} = (0, _useSlides.useSlides)({
|
|
235
|
+
total,
|
|
236
|
+
orientation,
|
|
237
|
+
loop,
|
|
238
|
+
autoPlay,
|
|
239
|
+
interval,
|
|
240
|
+
index,
|
|
241
|
+
defaultIndex,
|
|
242
|
+
onIndexChange
|
|
243
|
+
});
|
|
244
|
+
const isOverlay = indicatorPlacement === 'overlay';
|
|
245
|
+
const renderBackground = (item, real) => {
|
|
246
|
+
const value = background?.(item, real);
|
|
247
|
+
if (!value) return null;
|
|
248
|
+
if (Array.isArray(value)) {
|
|
249
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Gradient.Gradient, {
|
|
250
|
+
colors: value,
|
|
251
|
+
direction: gradientDirection,
|
|
252
|
+
style: _reactNative.StyleSheet.absoluteFill
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
256
|
+
style: [_reactNative.StyleSheet.absoluteFill, {
|
|
257
|
+
backgroundColor: value
|
|
258
|
+
}],
|
|
259
|
+
pointerEvents: "none"
|
|
260
|
+
});
|
|
261
|
+
};
|
|
262
|
+
const renderIndicator = position => {
|
|
263
|
+
const selected = position === active;
|
|
264
|
+
if (indicators === 'numbers') {
|
|
265
|
+
const numberColors = isOverlay ? {
|
|
266
|
+
background: selected ? colors.white : 'transparent',
|
|
267
|
+
border: colors.white,
|
|
268
|
+
text: selected ? colors.black : colors.white
|
|
269
|
+
} : {
|
|
270
|
+
background: selected ? colors.primary : 'transparent',
|
|
271
|
+
border: selected ? colors.primary : colors.border,
|
|
272
|
+
text: selected ? colors.onPrimary : colors.textLight
|
|
273
|
+
};
|
|
274
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
275
|
+
style: [styles.numberCircle, {
|
|
276
|
+
backgroundColor: numberColors.background,
|
|
277
|
+
borderColor: numberColors.border
|
|
278
|
+
}],
|
|
279
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
280
|
+
allowFontScaling: allowFontScaling,
|
|
281
|
+
style: [styles.numberText, {
|
|
282
|
+
color: numberColors.text
|
|
283
|
+
}],
|
|
284
|
+
children: position + 1
|
|
285
|
+
})
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(Dot, {
|
|
289
|
+
testID: `${testID ?? 'slides'}-dot-${position}`,
|
|
290
|
+
selected: selected,
|
|
291
|
+
isHorizontal: isHorizontal,
|
|
292
|
+
overlay: isOverlay,
|
|
293
|
+
activeColor: isOverlay ? colors.white : colors.primary,
|
|
294
|
+
inactiveColor: isOverlay ? colors.white : colors.border
|
|
295
|
+
});
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
// Con reduce-motion el autoPlay ya está apagado: no hay nada que pausar.
|
|
299
|
+
const renderAutoPlayToggle = () => {
|
|
300
|
+
if (!autoPlay || !showAutoPlayToggle || motionReduced || total < 2) return null;
|
|
301
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
302
|
+
testID: `${testID ?? 'slides'}-autoplay-toggle`,
|
|
303
|
+
style: [styles.autoPlayToggle, {
|
|
304
|
+
backgroundColor: colors.black,
|
|
305
|
+
opacity: 0.55
|
|
306
|
+
}],
|
|
307
|
+
activeOpacity: 0.7,
|
|
308
|
+
onPress: toggleAutoPlay,
|
|
309
|
+
accessibilityRole: "button",
|
|
310
|
+
accessibilityLabel: autoPlayPaused ? 'Resume automatic slides' : 'Pause automatic slides',
|
|
311
|
+
accessibilityState: {
|
|
312
|
+
selected: !autoPlayPaused
|
|
313
|
+
},
|
|
314
|
+
children: autoPlayPaused ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
315
|
+
style: [styles.playTriangle, {
|
|
316
|
+
borderLeftColor: colors.white
|
|
317
|
+
}]
|
|
318
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
319
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
320
|
+
style: [styles.pauseBar, {
|
|
321
|
+
backgroundColor: colors.white
|
|
322
|
+
}]
|
|
323
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
324
|
+
style: [styles.pauseBar, {
|
|
325
|
+
backgroundColor: colors.white
|
|
326
|
+
}]
|
|
327
|
+
})]
|
|
328
|
+
})
|
|
329
|
+
});
|
|
330
|
+
};
|
|
331
|
+
const renderIndicators = () => {
|
|
332
|
+
if (indicators === 'none' || total < 2) return null;
|
|
333
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
334
|
+
testID: `${testID ?? 'slides'}-indicators`,
|
|
335
|
+
style: [isHorizontal ? styles.indicatorsRow : styles.indicatorsColumn, isOverlay ? isHorizontal ? styles.indicatorsOverlayHorizontal : styles.indicatorsOverlayVertical : isHorizontal ? styles.indicatorsOutsideHorizontal : styles.indicatorsOutsideVertical],
|
|
336
|
+
pointerEvents: "box-none",
|
|
337
|
+
children: data.map((item, position) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
338
|
+
testID: `${testID ?? 'slides'}-indicator-${position}`,
|
|
339
|
+
style: styles.indicatorSlot,
|
|
340
|
+
activeOpacity: 0.7,
|
|
341
|
+
onPress: () => goTo(position),
|
|
342
|
+
accessibilityRole: "button",
|
|
343
|
+
accessibilityLabel: `Slide ${position + 1} of ${total}`,
|
|
344
|
+
accessibilityState: {
|
|
345
|
+
selected: position === active
|
|
346
|
+
},
|
|
347
|
+
children: renderIndicator(position)
|
|
348
|
+
}, `indicator-${keyExtractor(item, position)}`))
|
|
349
|
+
});
|
|
350
|
+
};
|
|
351
|
+
const viewport = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
352
|
+
testID: testID,
|
|
353
|
+
style: [styles.root, {
|
|
354
|
+
height
|
|
355
|
+
}, !isOverlay && !isHorizontal && styles.viewportInRow, isOverlay && style],
|
|
356
|
+
onLayout: onLayout,
|
|
357
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
|
|
358
|
+
ref: scrollRef,
|
|
359
|
+
testID: `${testID ?? 'slides'}-scroll`,
|
|
360
|
+
style: styles.viewport,
|
|
361
|
+
horizontal: isHorizontal,
|
|
362
|
+
pagingEnabled: true,
|
|
363
|
+
scrollEnabled: swipeEnabled && total > 1,
|
|
364
|
+
showsHorizontalScrollIndicator: false,
|
|
365
|
+
showsVerticalScrollIndicator: false,
|
|
366
|
+
onMomentumScrollEnd: onMomentumScrollEnd,
|
|
367
|
+
onScrollBeginDrag: onScrollBeginDrag,
|
|
368
|
+
onScrollEndDrag: onScrollEndDrag,
|
|
369
|
+
children: pageSize > 0 && pages.map(({
|
|
370
|
+
real,
|
|
371
|
+
clone
|
|
372
|
+
}) => {
|
|
373
|
+
const item = data[real];
|
|
374
|
+
return (
|
|
375
|
+
/*#__PURE__*/
|
|
376
|
+
// El hueco se reparte a los dos lados de cada página: así la
|
|
377
|
+
// separación entre dos slides es `spacing` entero y la página
|
|
378
|
+
// sigue midiendo exactamente lo que pagina el ScrollView.
|
|
379
|
+
(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
380
|
+
style: [{
|
|
381
|
+
width: size.width,
|
|
382
|
+
height: size.height
|
|
383
|
+
}, isHorizontal ? {
|
|
384
|
+
paddingHorizontal: spacing / 2
|
|
385
|
+
} : {
|
|
386
|
+
paddingVertical: spacing / 2
|
|
387
|
+
}],
|
|
388
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
389
|
+
style: [styles.slide, slideStyle],
|
|
390
|
+
children: [renderBackground(item, real), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
391
|
+
style: styles.slideContent,
|
|
392
|
+
children: renderItem(item, real)
|
|
393
|
+
})]
|
|
394
|
+
})
|
|
395
|
+
}, clone ? `slides-clone-${clone}` : keyExtractor(item, real))
|
|
396
|
+
);
|
|
397
|
+
})
|
|
398
|
+
}), renderAutoPlayToggle(), isOverlay && renderIndicators()]
|
|
399
|
+
});
|
|
400
|
+
if (isOverlay) return viewport;
|
|
401
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
402
|
+
style: [isHorizontal ? styles.outsideHorizontal : styles.outsideVertical, style],
|
|
403
|
+
children: [viewport, renderIndicators()]
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
//# sourceMappingURL=Slides.js.map
|