@forthtilliath/react-native-kit 0.7.0 → 0.7.2

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
@@ -30,7 +30,7 @@ import { ChangelogNotes } from "@forthtilliath/react-native-kit/ChangelogNotes";
30
30
 
31
31
  This is the recommended way to import: Metro (React Native's bundler) doesn't reliably tree-shake, so pulling from a single deep-import path keeps peer dependencies you don't use (`expo-image-picker`, `expo-speech-recognition`, `react-native-gesture-handler`...) out of your bundle entirely, rather than merely unused.
32
32
 
33
- A root barrel is also available for convenience when you don't mind that trade-off:
33
+ A root barrel is also available for convenience:
34
34
 
35
35
  ```ts
36
36
  import {
@@ -39,6 +39,8 @@ import {
39
39
  } from "@forthtilliath/react-native-kit";
40
40
  ```
41
41
 
42
+ **Avoid the barrel under Jest (or any other CommonJS `require` consumer).** `export * from` re-exports are evaluated eagerly on `require()` — unlike Metro's ESM bundling, there's no tree-shaking to skip the unused ones. Requiring the barrel from _any_ file, even one that only wants a framework-agnostic util like `getMostRecentIds`, pulls in every component's module graph, including native-module imports (`expo-speech-recognition` via `VoiceSearchButton`/`PickerModal`) that don't exist in a Jest environment — this throws `Cannot find native module '...'` at require time, not just at runtime for an unrendered component. Deep imports only ever load the one module you asked for, so they don't have this problem in any environment.
43
+
42
44
  ### `<ChangelogNotes notes={...} styles={...} />`
43
45
 
44
46
  Renders GitHub-style release notes — as produced by `@forthtilliath/expo-release-updates`'s `parseChangelogNotes` — as headings, bulleted items, and bold-aware text, instead of showing the raw Markdown syntax in a plain `Text`.
@@ -1 +1 @@
1
- {"version":3,"file":"ChangelogNotes.d.ts","sourceRoot":"","sources":["../src/ChangelogNotes.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAMpE,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC/B,MAAM,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC9B,QAAQ,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC5B,IAAI,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,mBAAmB;IAClC,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,MAAM,CAAC,EAAE,oBAAoB,CAAC;CAC/B;AA0BD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,mBAAmB,+BAoCpE"}
1
+ {"version":3,"file":"ChangelogNotes.d.ts","sourceRoot":"","sources":["../src/ChangelogNotes.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAMpE,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC/B,MAAM,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC9B,QAAQ,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC5B,IAAI,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,mBAAmB;IAClC,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,MAAM,CAAC,EAAE,oBAAoB,CAAC;CAC/B;AA0BD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,mBAAmB,+BA+CpE"}
@@ -22,7 +22,18 @@ function renderSegments(segments, boldStyle) {
22
22
  * Markdown syntax in a plain `<Text>`.
23
23
  */
24
24
  export function ChangelogNotes({ notes, styles }) {
25
- const merged = { ...defaultStyles, ...styles };
25
+ // Each field is merged as a style array (default, then override) rather
26
+ // than the override replacing the whole default outright — so passing e.g.
27
+ // `styles={{ heading: { color: "red" } }}` only changes the color instead
28
+ // of silently dropping the default's fontSize/fontWeight/marginTop too.
29
+ const merged = {
30
+ heading: [defaultStyles.heading, styles?.heading],
31
+ itemRow: [defaultStyles.itemRow, styles?.itemRow],
32
+ bullet: [defaultStyles.bullet, styles?.bullet],
33
+ itemText: [defaultStyles.itemText, styles?.itemText],
34
+ text: [defaultStyles.text, styles?.text],
35
+ bold: [defaultStyles.bold, styles?.bold],
36
+ };
26
37
  const blocks = parseChangelogNotes(notes);
27
38
  return (_jsx(_Fragment, { children: blocks.map((block, index) => {
28
39
  // Blocks have no stable identity of their own (plain parsed lines),
@@ -1 +1 @@
1
- {"version":3,"file":"PhotoPicker.d.ts","sourceRoot":"","sources":["../src/PhotoPicker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAKhF,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACnC,YAAY,CAAC,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;IACrC,gBAAgB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACxC,oBAAoB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC5C,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;IAC5C,sBAAsB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;IACxD,qBAAqB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;IACvD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACvC,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAClD,0EAA0E;IAC1E,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B;AAkDD,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,UAAU,EACV,MAAM,EACN,MAAM,GACP,EAAE,gBAAgB,+BAoGlB"}
1
+ {"version":3,"file":"PhotoPicker.d.ts","sourceRoot":"","sources":["../src/PhotoPicker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAKhF,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACnC,YAAY,CAAC,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;IACrC,gBAAgB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACxC,oBAAoB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC5C,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;IAC5C,sBAAsB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;IACxD,qBAAqB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC;IACvD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACvC,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAClD,0EAA0E;IAC1E,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B;AAkDD,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,UAAU,EACV,MAAM,EACN,MAAM,GACP,EAAE,gBAAgB,+BAoHlB"}
@@ -47,7 +47,23 @@ const defaultLabels = {
47
47
  };
48
48
  // Photo picker (camera or library) with a preview.
49
49
  export function PhotoPicker({ photoUri, onChange, savePhoto, photoLabel, labels, styles, }) {
50
- const mergedStyles = { ...defaultStyles, ...styles };
50
+ // Style fields are merged as arrays (default, then override) so a partial
51
+ // override only changes the properties it specifies instead of replacing
52
+ // the whole default style object.
53
+ const mergedStyles = {
54
+ photoPicker: [defaultStyles.photoPicker, styles?.photoPicker],
55
+ photoPreview: [defaultStyles.photoPreview, styles?.photoPreview],
56
+ photoPlaceholder: [
57
+ defaultStyles.photoPlaceholder,
58
+ styles?.photoPlaceholder,
59
+ ],
60
+ photoPlaceholderText: [
61
+ defaultStyles.photoPlaceholderText,
62
+ styles?.photoPlaceholderText,
63
+ ],
64
+ clearLink: [defaultStyles.clearLink, styles?.clearLink],
65
+ iconColor: styles?.iconColor ?? defaultStyles.iconColor,
66
+ };
51
67
  const t = { ...defaultLabels, ...labels };
52
68
  async function pickFromCamera() {
53
69
  const permission = await ImagePicker.requestCameraPermissionsAsync();
@@ -1 +1 @@
1
- {"version":3,"file":"PickerModal.d.ts","sourceRoot":"","sources":["../src/PickerModal.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAchF,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC9B,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC9B,GAAG,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC3B,YAAY,CAAC,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;IACrC,uBAAuB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC/C,QAAQ,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAChC,WAAW,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACnC,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,aAAa,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACrC,YAAY,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACpC,gBAAgB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACxC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,gCAAgC,CAAC,EAAE,MAAM,CAAC;IAC1C,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,6BAA6B,CAAC,EAAE,MAAM,CAAC;IACvC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,QAAQ,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;IACrC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sDAAsD;IACtD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8FAA8F;IAC9F,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,MAAM,KAAK,UAAU,EAAE,CAAC;IACnE,qFAAqF;IACrF,YAAY,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,IAAI,CAAA;KAAE,EAAE,CAAC;IACxD;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B;AAwFD,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,KAAK,EACL,KAAK,EACL,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,UAAU,EACV,MAAM,EACN,MAAM,GACP,EAAE,gBAAgB,+BA4JlB"}
1
+ {"version":3,"file":"PickerModal.d.ts","sourceRoot":"","sources":["../src/PickerModal.tsx"],"names":[],"mappings":"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"}
@@ -88,7 +88,37 @@ const defaultLabels = {
88
88
  // Full-screen picker: search (typed or dictated), optional sections, and
89
89
  // "add" actions always visible above the results.
90
90
  export function PickerModal({ visible, title, items, onSelect, onClose, emptyMessage, initialQuery, filterItems, extraActions, groupOrder, labels, styles, }) {
91
- const merged = useMemo(() => ({ ...defaultStyles, ...styles }), [styles]);
91
+ // Style fields are merged as arrays (default, then override) so a partial
92
+ // override only changes the properties it specifies instead of replacing
93
+ // the whole default style object (e.g. losing rowThumbnailPlaceholder's
94
+ // alignItems/justifyContent by only overriding its backgroundColor).
95
+ const merged = useMemo(() => ({
96
+ container: [defaultStyles.container, styles?.container],
97
+ header: [defaultStyles.header, styles?.header],
98
+ title: [defaultStyles.title, styles?.title],
99
+ close: [defaultStyles.close, styles?.close],
100
+ searchRow: [defaultStyles.searchRow, styles?.searchRow],
101
+ search: [defaultStyles.search, styles?.search],
102
+ row: [defaultStyles.row, styles?.row],
103
+ rowThumbnail: [defaultStyles.rowThumbnail, styles?.rowThumbnail],
104
+ rowThumbnailPlaceholder: [
105
+ defaultStyles.rowThumbnailPlaceholder,
106
+ styles?.rowThumbnailPlaceholder,
107
+ ],
108
+ rowLabel: [defaultStyles.rowLabel, styles?.rowLabel],
109
+ rowSubtitle: [defaultStyles.rowSubtitle, styles?.rowSubtitle],
110
+ empty: [defaultStyles.empty, styles?.empty],
111
+ sectionHeader: [defaultStyles.sectionHeader, styles?.sectionHeader],
112
+ extraActions: [defaultStyles.extraActions, styles?.extraActions],
113
+ extraActionLabel: [
114
+ defaultStyles.extraActionLabel,
115
+ styles?.extraActionLabel,
116
+ ],
117
+ extraActionIconColor: styles?.extraActionIconColor ?? defaultStyles.extraActionIconColor,
118
+ rowThumbnailPlaceholderIconColor: styles?.rowThumbnailPlaceholderIconColor ??
119
+ defaultStyles.rowThumbnailPlaceholderIconColor,
120
+ placeholderTextColor: styles?.placeholderTextColor ?? defaultStyles.placeholderTextColor,
121
+ }), [styles]);
92
122
  const t = useMemo(() => ({ ...defaultLabels, ...labels }), [labels]);
93
123
  const [query, setQuery] = useState(initialQuery ?? "");
94
124
  // Reset the search each time the modal (re-)opens — adjusted during render
@@ -1 +1 @@
1
- {"version":3,"file":"SwipeableRow.d.ts","sourceRoot":"","sources":["../src/SwipeableRow.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAKpE,MAAM,WAAW,kBAAkB;IACjC,YAAY,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACpC,gBAAgB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACxC,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,SAAS,CAAC;IACpB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,kBAAkB,CAAC;CAC7B;AAiBD,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,UAAqB,EACrB,MAAM,GACP,EAAE,iBAAiB,+BA6BnB"}
1
+ {"version":3,"file":"SwipeableRow.d.ts","sourceRoot":"","sources":["../src/SwipeableRow.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAKpE,MAAM,WAAW,kBAAkB;IACjC,YAAY,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACpC,gBAAgB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACxC,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,SAAS,CAAC;IACpB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,kBAAkB,CAAC;CAC7B;AAiBD,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,UAAqB,EACrB,MAAM,GACP,EAAE,iBAAiB,+BAuCnB"}
@@ -18,7 +18,17 @@ const defaultStyles = {
18
18
  };
19
19
  // Swipe a list row left to reveal a delete button, on top of a tap to edit it.
20
20
  export function SwipeableRow({ children, onDelete, deleteLabel, deleteText = "Delete", styles, }) {
21
- const merged = { ...defaultStyles, ...styles };
21
+ // Style fields are merged as arrays (default, then override) so a partial
22
+ // override (e.g. just backgroundColor) doesn't drop the default's
23
+ // width/borderRadius/marginBottom/gap too.
24
+ const merged = {
25
+ deleteAction: [defaultStyles.deleteAction, styles?.deleteAction],
26
+ deleteActionText: [
27
+ defaultStyles.deleteActionText,
28
+ styles?.deleteActionText,
29
+ ],
30
+ deleteIconColor: styles?.deleteIconColor ?? defaultStyles.deleteIconColor,
31
+ };
22
32
  const swipeableRef = useRef(null);
23
33
  return (_jsx(Swipeable, { ref: swipeableRef, renderRightActions: () => (_jsxs(Pressable, { style: merged.deleteAction, onPress: () => {
24
34
  swipeableRef.current?.close();
@@ -1 +1 @@
1
- {"version":3,"file":"ThemeToggle.d.ts","sourceRoot":"","sources":["../src/ThemeToggle.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC9B,YAAY,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACpC,UAAU,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAClC,gBAAgB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,eAAe,CAAC;IACvB,QAAQ,EAAE,CAAC,UAAU,EAAE,eAAe,KAAK,IAAI,CAAC;IAChD,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B;AA2BD,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,QAAQ,EACR,MAAM,EACN,MAAM,GACP,EAAE,gBAAgB,+BA6BlB"}
1
+ {"version":3,"file":"ThemeToggle.d.ts","sourceRoot":"","sources":["../src/ThemeToggle.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC9B,YAAY,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACpC,UAAU,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAClC,gBAAgB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,eAAe,CAAC;IACvB,QAAQ,EAAE,CAAC,UAAU,EAAE,eAAe,KAAK,IAAI,CAAC;IAChD,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B;AA2BD,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,QAAQ,EACR,MAAM,EACN,MAAM,GACP,EAAE,gBAAgB,+BAyClB"}
@@ -23,7 +23,19 @@ const defaultLabels = {
23
23
  };
24
24
  // 3-way segmented control for a light/dark/system theme preference.
25
25
  export function ThemeToggle({ value, onChange, labels, styles, }) {
26
- const merged = { ...defaultStyles, ...styles };
26
+ // Style fields are merged as arrays (default, then override) so a partial
27
+ // override only changes the properties it specifies instead of replacing
28
+ // the whole default style object.
29
+ const merged = {
30
+ container: [defaultStyles.container, styles?.container],
31
+ option: [defaultStyles.option, styles?.option],
32
+ optionActive: [defaultStyles.optionActive, styles?.optionActive],
33
+ optionText: [defaultStyles.optionText, styles?.optionText],
34
+ optionTextActive: [
35
+ defaultStyles.optionTextActive,
36
+ styles?.optionTextActive,
37
+ ],
38
+ };
27
39
  const t = { ...defaultLabels, ...labels };
28
40
  return (_jsx(View, { style: merged.container, children: OPTIONS.map((option) => {
29
41
  const active = option === value;
@@ -1 +1 @@
1
- {"version":3,"file":"Thumbnail.d.ts","sourceRoot":"","sources":["../src/Thumbnail.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAErE,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;IAClC,WAAW,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,iFAAiF;IACjF,eAAe,EAAE,MAAM,OAAO,QAAQ,CAAC,QAAQ,CAAC;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B;AAgBD,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,eAAe,EACf,IAAmB,EACnB,MAAM,GACP,EAAE,cAAc,+BAuBhB"}
1
+ {"version":3,"file":"Thumbnail.d.ts","sourceRoot":"","sources":["../src/Thumbnail.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAErE,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;IAClC,WAAW,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,iFAAiF;IACjF,eAAe,EAAE,MAAM,OAAO,QAAQ,CAAC,QAAQ,CAAC;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B;AAgBD,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,eAAe,EACf,IAAmB,EACnB,MAAM,GACP,EAAE,cAAc,+BA+BhB"}
package/dist/Thumbnail.js CHANGED
@@ -14,7 +14,15 @@ const defaultStyles = {
14
14
  };
15
15
  // List-row thumbnail (photo, or a placeholder icon when there is none).
16
16
  export function Thumbnail({ photoUri, placeholderIcon, size = DEFAULT_SIZE, styles, }) {
17
- const merged = { ...defaultStyles, ...styles };
17
+ // Style fields are merged as arrays (default, then override) so a partial
18
+ // override (e.g. just backgroundColor) doesn't drop the default's
19
+ // borderRadius, or the placeholder's alignItems/justifyContent that center
20
+ // the icon.
21
+ const merged = {
22
+ thumbnail: [defaultStyles.thumbnail, styles?.thumbnail],
23
+ placeholder: [defaultStyles.placeholder, styles?.placeholder],
24
+ iconColor: styles?.iconColor ?? defaultStyles.iconColor,
25
+ };
18
26
  const dimensions = { width: size, height: size };
19
27
  if (photoUri) {
20
28
  return (_jsx(Image, { source: { uri: photoUri }, style: [dimensions, merged.thumbnail], accessibilityIgnoresInvertColors: true }));
@@ -1 +1 @@
1
- {"version":3,"file":"UpdateAvailableBanner.d.ts","sourceRoot":"","sources":["../src/UpdateAvailableBanner.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAGhE,MAAM,WAAW,2BAA2B;IAC1C,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC9B,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,KAAK,CAAC,EAAE,oBAAoB,CAAC;IAC7B,YAAY,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACpC,gBAAgB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACxC,aAAa,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACrC,iBAAiB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,2BAA2B;IAC1C,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,2BAA2B,CAAC;IACrC,MAAM,CAAC,EAAE,2BAA2B,CAAC;CACtC;AAwCD,wBAAgB,qBAAqB,CAAC,EACpC,OAAO,EACP,KAAK,EACL,OAAO,EACP,SAAS,EACT,MAAM,EACN,MAAM,GACP,EAAE,0BAA0B,+BA4B5B"}
1
+ {"version":3,"file":"UpdateAvailableBanner.d.ts","sourceRoot":"","sources":["../src/UpdateAvailableBanner.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAGhE,MAAM,WAAW,2BAA2B;IAC1C,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC9B,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,KAAK,CAAC,EAAE,oBAAoB,CAAC;IAC7B,YAAY,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACpC,gBAAgB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACxC,aAAa,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACrC,iBAAiB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,2BAA2B;IAC1C,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,2BAA2B,CAAC;IACrC,MAAM,CAAC,EAAE,2BAA2B,CAAC;CACtC;AAwCD,wBAAgB,qBAAqB,CAAC,EACpC,OAAO,EACP,KAAK,EACL,OAAO,EACP,SAAS,EACT,MAAM,EACN,MAAM,GACP,EAAE,0BAA0B,+BA+C5B"}
@@ -38,7 +38,26 @@ const defaultLabels = {
38
38
  // what "action" does (e.g. navigate to an update screen) or on how/whether
39
39
  // dismissal is persisted — both are left entirely to the caller.
40
40
  export function UpdateAvailableBanner({ version, notes, onPress, onDismiss, labels, styles, }) {
41
- const merged = { ...defaultStyles, ...styles };
41
+ // Style fields are merged as arrays (default, then override) so a partial
42
+ // override only changes the properties it specifies instead of replacing
43
+ // the whole default style object. `notes` is forwarded as-is to
44
+ // ChangelogNotes, which does its own equivalent merge against its defaults.
45
+ const merged = {
46
+ container: [defaultStyles.container, styles?.container],
47
+ header: [defaultStyles.header, styles?.header],
48
+ title: [defaultStyles.title, styles?.title],
49
+ notes: styles?.notes ?? defaultStyles.notes,
50
+ actionButton: [defaultStyles.actionButton, styles?.actionButton],
51
+ actionButtonText: [
52
+ defaultStyles.actionButtonText,
53
+ styles?.actionButtonText,
54
+ ],
55
+ dismissButton: [defaultStyles.dismissButton, styles?.dismissButton],
56
+ dismissButtonText: [
57
+ defaultStyles.dismissButtonText,
58
+ styles?.dismissButtonText,
59
+ ],
60
+ };
42
61
  const t = { ...defaultLabels, ...labels };
43
62
  return (_jsxs(View, { style: merged.container, children: [_jsxs(View, { style: merged.header, children: [_jsx(Text, { style: merged.title, children: t.title(version) }), _jsx(Pressable, { style: merged.dismissButton, onPress: onDismiss, accessibilityRole: "button", accessibilityLabel: t.dismissAccessibilityLabel, children: _jsx(Text, { style: merged.dismissButtonText, children: t.dismiss }) })] }), notes ? _jsx(ChangelogNotes, { notes: notes, styles: merged.notes }) : null, _jsx(Pressable, { style: merged.actionButton, onPress: onPress, accessibilityRole: "button", accessibilityLabel: t.action, children: _jsx(Text, { style: merged.actionButtonText, children: t.action }) })] }));
44
63
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forthtilliath/react-native-kit",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -8,11 +8,11 @@
8
8
  },
9
9
  "repository": {
10
10
  "type": "git",
11
- "url": "https://github.com/Forthtilliath/turborepo.git",
11
+ "url": "https://github.com/Forthtilliath/forthtilliath-packages.git",
12
12
  "directory": "packages/react-native-kit"
13
13
  },
14
- "homepage": "https://github.com/Forthtilliath/turborepo/tree/main/packages/react-native-kit#readme",
15
- "bugs": "https://github.com/Forthtilliath/turborepo/issues",
14
+ "homepage": "https://github.com/Forthtilliath/forthtilliath-packages/tree/main/packages/react-native-kit#readme",
15
+ "bugs": "https://github.com/Forthtilliath/forthtilliath-packages/issues",
16
16
  "files": [
17
17
  "dist"
18
18
  ],
@@ -44,8 +44,8 @@
44
44
  "react-test-renderer": "19.2.3",
45
45
  "typescript": "^5.9.3",
46
46
  "vitest": "^4.1.10",
47
- "@forthtilliath/typescript-config": "0.0.0",
48
- "@forthtilliath/eslint-config": "0.0.0"
47
+ "@forthtilliath/eslint-config": "0.0.0",
48
+ "@forthtilliath/typescript-config": "0.0.0"
49
49
  },
50
50
  "scripts": {
51
51
  "lint": "eslint . --max-warnings 0",