@delacour/react-native-ui 0.1.0-alpha.20261004035233 → 0.1.0-alpha.20261005222904

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/README.md CHANGED
@@ -82,7 +82,7 @@ import { IconArrowRight } from "@delacour/react-native-ui/icons/central";
82
82
  | --- | --- | --- |
83
83
  | Accordion | `@delacour/react-native-ui/accordion` | Selection modes, measured panels, indicators |
84
84
  | Badge | `@delacour/react-native-ui/badge` | Variants, colours, sizes, dismiss |
85
- | BottomSheet | `@delacour/react-native-ui/bottom-sheet` | Detents, keyboard, sticky footer, scrollables, steps, detached, teleported portal |
85
+ | BottomSheet | `@delacour/react-native-ui/bottom-sheet` | Snap points, keyboard, sticky footer, scrollables, steps, detached, teleported portal |
86
86
  | Button | `@delacour/react-native-ui/button` | Variants, sizes, icons, loading |
87
87
  | Checkbox | `@delacour/react-native-ui/checkbox` | Colours, sizes, indeterminate, groups |
88
88
  | Field | `@delacour/react-native-ui/field` | Form layout, grouping, state cascade |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@delacour/react-native-ui",
3
- "version": "0.1.0-alpha.20261004035233",
3
+ "version": "0.1.0-alpha.20261005222904",
4
4
  "description": "React Native UI components — Uniwind, Reanimated, Gesture Handler",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -100,8 +100,8 @@
100
100
  },
101
101
  "peerDependencies": {
102
102
  "@central-icons-react-native/round-outlined-radius-1-stroke-1.5": "^1.1",
103
- "@delacour/react-native-bottom-sheet": "0.1.0-alpha.20261004035233",
104
- "@delacour/react-native-charts": "0.1.0-alpha.20261004035233",
103
+ "@delacour/react-native-bottom-sheet": "0.1.0-alpha.20261005222904",
104
+ "@delacour/react-native-charts": "0.1.0-alpha.20261005222904",
105
105
  "@legendapp/list": ">=3.3",
106
106
  "expo-linear-gradient": ">=15",
107
107
  "expo-router": ">=57",
@@ -71,7 +71,7 @@ engine's names win everywhere; this skin aliases nothing.
71
71
  ## What the engine owns
72
72
 
73
73
  Everything that is not a class. The open state and the intent queue; the
74
- height-space geometry and the detents; the handle and content pans and how a
74
+ height-space geometry and the snap points; the handle and content pans and how a
75
75
  list shares a finger with them; the keyboard — who owns it, `interactive` /
76
76
  `extend` / `fillParent` / `none`, the lift and the restore; the sticky footer's
77
77
  line and the safe-area band under it; the teleport portal, the hosts, the
@@ -92,7 +92,7 @@ read those before touching behaviour, because behaviour is not here.
92
92
  components applies: the engine is another package.
93
93
  - **Where the classes land.** `Content`, `Footer` and `Steps` hand `style` to
94
94
  the engine's *measured* inner view, so a class there is height the dynamic
95
- detent counts. `ScrollView` puts its content classes on an inner `View`
95
+ snap point counts. `ScrollView` puts its content classes on an inner `View`
96
96
  rather than the content container, so the one style this file writes there —
97
97
  the gap above a pinned footer — has a single writer. The three virtualised
98
98
  lists have no inner box, so theirs go on `contentContainerClassName`; the
@@ -115,16 +115,16 @@ read those before touching behaviour, because behaviour is not here.
115
115
  `fade` and an 8pt slop, for `Badge.CloseButton`'s and `Checkbox`'s reasons.
116
116
  - **The root fills in three defaults.** `bottomInset` is `useSafeAreaInsets().bottom`,
117
117
  so the engine reserves the home-indicator band and nobody pads for it by
118
- hand. `onDetentHaptic` is `Presets.System.selection` and `onCloseHaptic` is
118
+ hand. `onSnapPointHaptic` is `Presets.System.selection` and `onCloseHaptic` is
119
119
  `Presets.System.impactLight` — pulsar's presets are worklets, so they are
120
120
  passed as they are; a JS function there is `undefined is not a function` on
121
121
  the UI thread. And `useKeyboardAnimationGuard()` runs on mount, the same
122
122
  stale-keyboard repair `Screen.Footer` runs. `topInset` stays at the engine's
123
- zero, so a `%` detent is the fraction of the window it always was.
123
+ zero, so a `%` snap point is the fraction of the window it always was.
124
124
  - **`Footer.sticky` defaults to `false`**, matching `Screen.Footer`, and this is
125
125
  the one engine default the skin overrides. A pinned footer takes
126
126
  `padding={BOTTOM_SHEET_FOOTER_PADDING}` through the engine's prop rather
127
- than a class, so the padding is inside the box the detent measures; the
127
+ than a class, so the padding is inside the box the snap point measures; the
128
128
  `stickyFooter` slot carries the gutter, the surface and the hairline, and
129
129
  the test asserts it carries no vertical padding.
130
130
  - **The overlay's opacity is 1**, because `--overlay` carries its own alpha and
@@ -178,7 +178,7 @@ problem it has:
178
178
  - nesting a sheet in a sheet — the registry stacks them; `stackBehavior` and
179
179
  `dismissAll` are for exactly that
180
180
  - `ScrollView` needing `dynamicSizing={false}` and `snapPoints` — a list's
181
- content size is the dynamic detent
181
+ content size is the dynamic snap point
182
182
  - lifting `Overlay` and a sticky `Footer` out of the tree as render props —
183
183
  every part renders where it is written
184
184
  - a `Content` inside a `Container` paying the safe-area band by hand — the
@@ -37,7 +37,7 @@ export type BottomSheetFlatListProps<ItemT> = HeadlessProps<ItemT> & {
37
37
  * A virtualised body.
38
38
  *
39
39
  * The engine's `FlatList` — the scroll lock, the drag budget and content size
40
- * as the dynamic detent are all its — with the library's gutter on the content
40
+ * as the dynamic snap point are all its — with the library's gutter on the content
41
41
  * container. A virtualised list has no inner box to put the classes on, so
42
42
  * here they go on `contentContainerClassName`; the engine flattens the
43
43
  * resulting style to one object before the list measures it.
@@ -36,7 +36,7 @@ export type BottomSheetFooterProps = HeadlessProps & {
36
36
  * geometry's footer line, which the core proves holds still through a keyboard
37
37
  * animation, so its buttons land on the keyboard's top edge without moving;
38
38
  * the safe-area band under it is a spacer the geometry owns; and its measured
39
- * height is what the body reserves and the dynamic detent counts. The
39
+ * height is what the body reserves and the dynamic snap point counts. The
40
40
  * `padding` goes to the engine rather than a class for that reason — it has to
41
41
  * be inside the measured box.
42
42
  *
@@ -25,7 +25,7 @@ export type BottomSheetHandleProps = HeadlessProps & {
25
25
  *
26
26
  * The engine's handle draws nothing of its own: it owns the pan, measures
27
27
  * itself into the sheet's height, and is the adjustable element a screen
28
- * reader steps through the detents with. This puts the pill inside it, and
28
+ * reader steps through the snap points with. This puts the pill inside it, and
29
29
  * classes on both.
30
30
  *
31
31
  * Pass children to replace the pill; the row, the pan and the accessibility
@@ -44,7 +44,7 @@ export type BottomSheetLegendListProps<ItemT> = Omit<AnimatedLegendListProps<Ite
44
44
  * Built here rather than in the engine because `@legendapp/list` is this
45
45
  * library's optional peer, not the engine's: the engine exports the factory,
46
46
  * and this is what the factory is for. The same scroll lock, drag budget and
47
- * content-size detent as the other three bodies.
47
+ * content-size snap point as the other three bodies.
48
48
  *
49
49
  * @example
50
50
  * <BottomSheet.LegendList data={rows} keyExtractor={(row) => row.id} renderItem={renderRow} />
@@ -36,13 +36,13 @@ export type BottomSheetScrollViewProps = Omit<HeadlessProps, "children"> & {
36
36
  * A scrolling body.
37
37
  *
38
38
  * Use this rather than a plain `ScrollView`: the engine's scrollable and the
39
- * sheet's pan share a finger — below the highest detent the list is held and
39
+ * sheet's pan share a finger — below the highest snap point the list is held and
40
40
  * the drag moves the sheet, at the highest the list scrolls, and a drag down
41
41
  * from the top hands back to the sheet. A React Native `ScrollView` in here has
42
42
  * no such arrangement.
43
43
  *
44
44
  * **It needs no `snapPoints` and no `dynamicSizing={false}`.** The list
45
- * reports its content size, and that is the dynamic detent: six rows make a
45
+ * reports its content size, and that is the dynamic snap point: six rows make a
46
46
  * short sheet, forty make one capped at `maxDynamicContentSize` that scrolls
47
47
  * inside the cap. Explicit `snapPoints` on the root still work, for a height
48
48
  * that is a decision rather than a measurement.
@@ -38,11 +38,11 @@ export type BottomSheetProps = HeadlessBottomSheetProps;
38
38
  * Both run on the UI thread from inside the engine's pan, so they are
39
39
  * `Presets.System.*` — themselves worklets — and nothing else: a JS function
40
40
  * here would be `undefined is not a function` at the moment a finger crosses a
41
- * detent. `selection` on a detent because that is what a picker's tick feels
41
+ * snap point. `selection` on a snap point because that is what a picker's tick feels
42
42
  * like, and `impactLight` on a close because letting go of a sheet is a
43
43
  * heavier event than passing a stop, but not by much.
44
44
  */
45
- const detentHaptic = Presets.System.selection;
45
+ const snapPointHaptic = Presets.System.selection;
46
46
  const closeHaptic = Presets.System.impactLight;
47
47
 
48
48
  /**
@@ -55,19 +55,19 @@ const closeHaptic = Presets.System.impactLight;
55
55
  * `useSafeAreaInsets()`. The engine reserves that band under the body or the
56
56
  * sticky footer and gives it back to the keyboard as it arrives; a caller
57
57
  * never pads for the home indicator by hand.
58
- * - **The haptics are on by default.** Pass `onDetentHaptic={undefined}` to
58
+ * - **The haptics are on by default.** Pass `onSnapPointHaptic={undefined}` to
59
59
  * turn one off, or a worklet of your own to change it.
60
60
  * - **The stale-keyboard guard runs on mount.** A sheet mounted while
61
61
  * `KeyboardProvider`'s shared values are pinned open by a keyboard that
62
62
  * vanished without a `will` event would lift for a keyboard that is not
63
63
  * there; `Screen.Footer` runs the same repair for the same reason.
64
64
  *
65
- * `topInset` is left at the engine's zero, so a `%` detent is a fraction of the
65
+ * `topInset` is left at the engine's zero, so a `%` snap point is a fraction of the
66
66
  * whole window — the same fraction it was before this rewrite.
67
67
  */
68
68
  function BottomSheetRoot({
69
69
  bottomInset,
70
- onDetentHaptic = detentHaptic,
70
+ onSnapPointHaptic = snapPointHaptic,
71
71
  onCloseHaptic = closeHaptic,
72
72
  ...props
73
73
  }: BottomSheetProps): ReactElement {
@@ -78,7 +78,7 @@ function BottomSheetRoot({
78
78
  <Headless
79
79
  bottomInset={bottomInset ?? insets.bottom}
80
80
  onCloseHaptic={onCloseHaptic}
81
- onDetentHaptic={onDetentHaptic}
81
+ onSnapPointHaptic={onSnapPointHaptic}
82
82
  {...props}
83
83
  />
84
84
  );
@@ -112,7 +112,7 @@ describe("every token the slots name", () => {
112
112
  });
113
113
 
114
114
  describe("the backdrop indices", () => {
115
- test("show the scrim from the first detent and hide it only when closed", () => {
115
+ test("show the scrim from the first snap point and hide it only when closed", () => {
116
116
  // A modal sheet has no resting state: presented or gone.
117
117
  expect(BOTTOM_SHEET_BACKDROP_INDICES.appearsOnIndex).toBe(0);
118
118
  expect(BOTTOM_SHEET_BACKDROP_INDICES.disappearsOnIndex).toBe(-1);
@@ -198,7 +198,7 @@ describe("bottomSheetVariants slots", () => {
198
198
  test("a pinned footer writes its vertical padding as the engine's prop, never a class", () => {
199
199
  // The engine measures the footer's inner box into the sheet's height, and
200
200
  // padding handed to its `padding` prop lands on that box. A class on the
201
- // outer view would be height the detent never counts.
201
+ // outer view would be height the snap point never counts.
202
202
  expect(SLOTS.stickyFooter()).not.toMatch(/\bp[tby]?-[\d.]+\b/);
203
203
  expect(BOTTOM_SHEET_FOOTER_PADDING).toBeGreaterThan(0);
204
204
  });
@@ -21,10 +21,10 @@ export const BOTTOM_SHEET_OVERLAY_TOKEN = "overlay";
21
21
  export const BOTTOM_SHEET_OVERLAY_OPACITY = 1;
22
22
 
23
23
  /**
24
- * The detent indices the scrim appears and disappears on.
24
+ * The snap point indices the scrim appears and disappears on.
25
25
  *
26
26
  * A modal sheet has no resting state: it is either presented or gone, so the
27
- * scrim belongs from the FIRST detent (`0`) and is only absent when the sheet
27
+ * scrim belongs from the FIRST snap point (`0`) and is only absent when the sheet
28
28
  * is closed (`-1`). These are the engine's own defaults too; they are named
29
29
  * here so the test that pins them has something to read.
30
30
  */
@@ -43,7 +43,7 @@ export const BOTTOM_SHEET_CLOSE_HIT_SLOP = 8;
43
43
  * The padding a pinned footer's measured box carries.
44
44
  *
45
45
  * A number rather than a `p-4`, because it is handed to the engine's `padding`
46
- * prop: the engine measures the footer's inner box into the dynamic detent,
46
+ * prop: the engine measures the footer's inner box into the dynamic snap point,
47
47
  * and padding written there is counted where a class on the outer view would
48
48
  * not be. The horizontal gutter still comes from the `stickyFooter` slot, which
49
49
  * is merged after it.