@hzblj/kara-components 0.8.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/CHANGELOG.md +60 -26
  2. package/README.md +8 -8
  3. package/lib/module/atoms/color-picker/color-picker.android.js +32 -5
  4. package/lib/module/atoms/color-picker/color-picker.android.js.map +1 -1
  5. package/lib/module/atoms/icon-button/icon-button.ios.js +17 -4
  6. package/lib/module/atoms/icon-button/icon-button.ios.js.map +1 -1
  7. package/lib/module/atoms/pressable/pressable.js +45 -22
  8. package/lib/module/atoms/pressable/pressable.js.map +1 -1
  9. package/lib/module/atoms/progress/progress.ios.js +10 -4
  10. package/lib/module/atoms/progress/progress.ios.js.map +1 -1
  11. package/lib/module/atoms/surface/surface.ios.js +3 -0
  12. package/lib/module/atoms/surface/surface.ios.js.map +1 -1
  13. package/lib/module/atoms/text-field/text-field.android.js +19 -4
  14. package/lib/module/atoms/text-field/text-field.android.js.map +1 -1
  15. package/lib/module/atoms/text-field/text-field.ios.js +7 -2
  16. package/lib/module/atoms/text-field/text-field.ios.js.map +1 -1
  17. package/lib/typescript/atoms/activity-indicator/activity-indicator.types.d.ts +1 -1
  18. package/lib/typescript/atoms/avatar/avatar.types.d.ts +2 -2
  19. package/lib/typescript/atoms/badge/badge.types.d.ts +1 -1
  20. package/lib/typescript/atoms/blur-view/blur-view.types.d.ts +6 -6
  21. package/lib/typescript/atoms/button/button.types.d.ts +7 -7
  22. package/lib/typescript/atoms/card/card.types.d.ts +1 -1
  23. package/lib/typescript/atoms/checkbox/checkbox.types.d.ts +2 -2
  24. package/lib/typescript/atoms/chip/chip.types.d.ts +1 -1
  25. package/lib/typescript/atoms/color-picker/color-picker.types.d.ts +4 -3
  26. package/lib/typescript/atoms/date-picker/date-picker.types.d.ts +4 -4
  27. package/lib/typescript/atoms/divider/divider.types.d.ts +2 -2
  28. package/lib/typescript/atoms/fab/fab.types.d.ts +2 -2
  29. package/lib/typescript/atoms/glass-view/glass-view.types.d.ts +5 -5
  30. package/lib/typescript/atoms/h-stack/h-stack.types.d.ts +3 -3
  31. package/lib/typescript/atoms/icon/icon.types.d.ts +4 -4
  32. package/lib/typescript/atoms/icon-button/icon-button.types.d.ts +7 -3
  33. package/lib/typescript/atoms/island/island.types.d.ts +4 -4
  34. package/lib/typescript/atoms/list/list.types.d.ts +5 -5
  35. package/lib/typescript/atoms/picker/picker.types.d.ts +1 -1
  36. package/lib/typescript/atoms/pressable/pressable.types.d.ts +21 -5
  37. package/lib/typescript/atoms/progress/progress.types.d.ts +2 -2
  38. package/lib/typescript/atoms/rn-flat-list/rn-flat-list.types.d.ts +2 -2
  39. package/lib/typescript/atoms/rn-icon/rn-icon.types.d.ts +1 -1
  40. package/lib/typescript/atoms/rn-scroll-view/rn-scroll-view.types.d.ts +2 -2
  41. package/lib/typescript/atoms/rn-section-list/rn-section-list.types.d.ts +2 -2
  42. package/lib/typescript/atoms/rn-text/rn-text.types.d.ts +2 -2
  43. package/lib/typescript/atoms/rn-view/rn-view.types.d.ts +3 -3
  44. package/lib/typescript/atoms/scroll-view/scroll-view.types.d.ts +3 -3
  45. package/lib/typescript/atoms/segmented-control/segmented-control.types.d.ts +3 -3
  46. package/lib/typescript/atoms/skeleton/skeleton.types.d.ts +2 -2
  47. package/lib/typescript/atoms/spacer/spacer.types.d.ts +1 -1
  48. package/lib/typescript/atoms/surface/surface.types.d.ts +2 -2
  49. package/lib/typescript/atoms/switch/switch.types.d.ts +1 -1
  50. package/lib/typescript/atoms/text/text.types.d.ts +1 -1
  51. package/lib/typescript/atoms/text-field/text-field.types.d.ts +8 -4
  52. package/lib/typescript/atoms/v-stack/v-stack.types.d.ts +1 -1
  53. package/lib/typescript/atoms/z-stack/z-stack.types.d.ts +1 -1
  54. package/lib/typescript/glyph/glyph-button.types.d.ts +1 -1
  55. package/lib/typescript/glyph/glyph.types.d.ts +1 -1
  56. package/lib/typescript/molecules/collapsible/collapsible.types.d.ts +1 -1
  57. package/lib/typescript/molecules/empty-state/empty-state.types.d.ts +1 -1
  58. package/lib/typescript/molecules/label/label.types.d.ts +1 -1
  59. package/lib/typescript/molecules/labeled-content/labeled-content.types.d.ts +2 -2
  60. package/lib/typescript/molecules/list-item/list-item.types.d.ts +2 -2
  61. package/lib/typescript/molecules/navigation-bar/navigation-bar.types.d.ts +8 -8
  62. package/lib/typescript/molecules/pager/pager.types.d.ts +2 -2
  63. package/lib/typescript/molecules/radio-group/radio-group.types.d.ts +2 -2
  64. package/lib/typescript/molecules/rn-list-item/rn-list-item.types.d.ts +1 -1
  65. package/lib/typescript/molecules/rn-tooltip/rn-tooltip.types.d.ts +7 -7
  66. package/lib/typescript/molecules/scroll-edge-container/scroll-edge-container.types.d.ts +3 -3
  67. package/lib/typescript/molecules/search-bar/search-bar.types.d.ts +2 -2
  68. package/lib/typescript/molecules/stepper/stepper.types.d.ts +2 -2
  69. package/lib/typescript/molecules/tooltip/tooltip.types.d.ts +6 -6
  70. package/lib/typescript/organisms/action-sheet/action-sheet.types.d.ts +3 -3
  71. package/lib/typescript/organisms/alert/alert.types.d.ts +3 -3
  72. package/lib/typescript/organisms/context-menu/context-menu.types.d.ts +9 -9
  73. package/lib/typescript/organisms/fab-menu/fab-menu.types.d.ts +5 -5
  74. package/lib/typescript/organisms/form/form.types.d.ts +1 -1
  75. package/lib/typescript/organisms/menu/menu.types.d.ts +2 -2
  76. package/lib/typescript/organisms/sheet/sheet.types.d.ts +12 -12
  77. package/lib/typescript/organisms/snackbar/snackbar.types.d.ts +1 -1
  78. package/lib/typescript/organisms/swipe-actions/swipe-actions.types.d.ts +5 -5
  79. package/lib/typescript/templates/screen/screen.types.d.ts +2 -2
  80. package/package.json +4 -4
  81. package/src/atoms/activity-indicator/activity-indicator.types.ts +1 -1
  82. package/src/atoms/avatar/avatar.types.ts +2 -2
  83. package/src/atoms/badge/badge.types.ts +1 -1
  84. package/src/atoms/blur-view/blur-view.types.ts +6 -6
  85. package/src/atoms/button/button.types.ts +7 -7
  86. package/src/atoms/card/card.types.ts +1 -1
  87. package/src/atoms/checkbox/checkbox.types.ts +2 -2
  88. package/src/atoms/chip/chip.types.ts +1 -1
  89. package/src/atoms/color-picker/color-picker.android.tsx +26 -6
  90. package/src/atoms/color-picker/color-picker.types.ts +4 -3
  91. package/src/atoms/date-picker/date-picker.types.ts +4 -4
  92. package/src/atoms/divider/divider.types.ts +2 -2
  93. package/src/atoms/fab/fab.types.ts +2 -2
  94. package/src/atoms/glass-view/glass-view.types.ts +5 -5
  95. package/src/atoms/h-stack/h-stack.types.ts +3 -3
  96. package/src/atoms/icon/icon.types.ts +4 -4
  97. package/src/atoms/icon-button/icon-button.ios.tsx +12 -2
  98. package/src/atoms/icon-button/icon-button.types.ts +7 -3
  99. package/src/atoms/island/island.types.ts +4 -4
  100. package/src/atoms/list/list.types.ts +5 -5
  101. package/src/atoms/picker/picker.types.ts +1 -1
  102. package/src/atoms/pressable/pressable.tsx +39 -18
  103. package/src/atoms/pressable/pressable.types.ts +22 -5
  104. package/src/atoms/progress/progress.ios.tsx +14 -5
  105. package/src/atoms/progress/progress.types.ts +2 -2
  106. package/src/atoms/rn-flat-list/rn-flat-list.types.ts +2 -2
  107. package/src/atoms/rn-icon/rn-icon.types.ts +1 -1
  108. package/src/atoms/rn-scroll-view/rn-scroll-view.types.ts +2 -2
  109. package/src/atoms/rn-section-list/rn-section-list.types.ts +2 -2
  110. package/src/atoms/rn-text/rn-text.types.ts +2 -2
  111. package/src/atoms/rn-view/rn-view.types.ts +3 -3
  112. package/src/atoms/scroll-view/scroll-view.types.ts +3 -3
  113. package/src/atoms/segmented-control/segmented-control.types.ts +3 -3
  114. package/src/atoms/skeleton/skeleton.types.ts +2 -2
  115. package/src/atoms/spacer/spacer.types.ts +1 -1
  116. package/src/atoms/surface/surface.ios.tsx +2 -1
  117. package/src/atoms/surface/surface.types.ts +2 -2
  118. package/src/atoms/switch/switch.types.ts +1 -1
  119. package/src/atoms/text/text.types.ts +1 -1
  120. package/src/atoms/text-field/text-field.android.tsx +19 -3
  121. package/src/atoms/text-field/text-field.ios.tsx +7 -1
  122. package/src/atoms/text-field/text-field.types.ts +8 -4
  123. package/src/atoms/v-stack/v-stack.types.ts +1 -1
  124. package/src/atoms/z-stack/z-stack.types.ts +1 -1
  125. package/src/glyph/glyph-button.types.ts +1 -1
  126. package/src/glyph/glyph.types.ts +1 -1
  127. package/src/molecules/collapsible/collapsible.types.ts +1 -1
  128. package/src/molecules/empty-state/empty-state.types.ts +1 -1
  129. package/src/molecules/label/label.types.ts +1 -1
  130. package/src/molecules/labeled-content/labeled-content.types.ts +2 -2
  131. package/src/molecules/list-item/list-item.types.ts +2 -2
  132. package/src/molecules/navigation-bar/navigation-bar.types.ts +8 -8
  133. package/src/molecules/pager/pager.types.ts +2 -2
  134. package/src/molecules/radio-group/radio-group.types.ts +2 -2
  135. package/src/molecules/rn-list-item/rn-list-item.types.ts +1 -1
  136. package/src/molecules/rn-tooltip/rn-tooltip.types.ts +7 -7
  137. package/src/molecules/scroll-edge-container/scroll-edge-container.types.ts +3 -3
  138. package/src/molecules/search-bar/search-bar.types.ts +2 -2
  139. package/src/molecules/stepper/stepper.types.ts +2 -2
  140. package/src/molecules/tooltip/tooltip.types.ts +6 -6
  141. package/src/organisms/action-sheet/action-sheet.types.ts +3 -3
  142. package/src/organisms/alert/alert.types.ts +3 -3
  143. package/src/organisms/context-menu/context-menu.types.ts +9 -9
  144. package/src/organisms/fab-menu/fab-menu.types.ts +5 -5
  145. package/src/organisms/form/form.types.ts +1 -1
  146. package/src/organisms/menu/menu.types.ts +2 -2
  147. package/src/organisms/sheet/sheet.types.ts +12 -12
  148. package/src/organisms/snackbar/snackbar.types.ts +1 -1
  149. package/src/organisms/swipe-actions/swipe-actions.types.ts +5 -5
  150. package/src/templates/screen/screen.types.ts +2 -2
  151. package/lib/module/platform-support.js +0 -19
  152. package/lib/module/platform-support.js.map +0 -1
  153. package/lib/typescript/platform-support.d.ts +0 -8
  154. package/src/platform-support.ts +0 -20
package/CHANGELOG.md CHANGED
@@ -1,26 +1,60 @@
1
1
  # @hzblj/kara-components
2
2
 
3
+ ## 0.10.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#23](https://github.com/hzblj/kara-ui/pull/23) [`26f1651`](https://github.com/hzblj/kara-ui/commit/26f1651b6a8be9fc2d7af6bbe29bd2335605a717) Thanks [@hzblj](https://github.com/hzblj)! - `ColorPicker` works on Android. Compose ships no colour picker, so kara draws its own in the iOS picker's shape: a well with a rainbow ring beside the label, and a Material bottom sheet with a grid of swatches, a spectrum and RGB sliders, an opacity slider with `supportsOpacity`, and the colour with its hex at the foot. It reports every change through `onValueChange`, as `#RRGGBB` or, with opacity, `#RRGGBBAA`. It needs no extra dependency.
8
+
9
+ `Pressable` takes a `pressEffect`: `scale` springs the content down to `pressedScale` (0.96), `opacity` dims it to `pressedOpacity` (`o60`), `none` holds it still. Each platform keeps its own by default, a spring on iOS and the ripple on Android, and Android keeps the ripple on top of any effect unless `ripple` is off.
10
+
11
+ `IconButton` on iOS sits in a 44pt tap target with the icon centred, as Android's sits in Material's 48dp, so a row of them spaces itself the same way on both. A disabled one is dimmed once, by SwiftUI, instead of twice.
12
+
13
+ ### Patch Changes
14
+
15
+ - Updated dependencies [[`26f1651`](https://github.com/hzblj/kara-ui/commit/26f1651b6a8be9fc2d7af6bbe29bd2335605a717), [`26f1651`](https://github.com/hzblj/kara-ui/commit/26f1651b6a8be9fc2d7af6bbe29bd2335605a717)]:
16
+ - @hzblj/kara-native@0.10.0
17
+ - @hzblj/kara-theme@0.10.0
18
+ - @hzblj/kara-sx@0.10.0
19
+
20
+ ## 0.9.0
21
+
22
+ ### Minor Changes
23
+
24
+ - [#21](https://github.com/hzblj/kara-ui/pull/21) [`356c00f`](https://github.com/hzblj/kara-ui/commit/356c00f76eee8323c4eb65ed4cbcda121c3af627) Thanks [@hzblj](https://github.com/hzblj)! - `TextField`'s `error` takes a message: `error="A postcode has five digits."` shows it under the field (Material's supporting text beside its error icon on Android), so an error never rests on colour alone, which in dark mode Material draws a pale red. `error` alone still marks the field. kara's glyphs gain `error` for it.
25
+
26
+ `Tabs` on iOS tint their icons: the selected one takes the accent and the rest the label colour. Expo Router tints an asset-catalog icon only when both states have an icon colour, so with the accent alone every icon kept its SVG's black, selected or not, in dark mode too.
27
+
28
+ `Surface` on iOS sits on `surface.primary` unless told otherwise, as it does on Android; a plain one drew nothing behind its content. `Progress` with `circular` and a `value` is a ring that fills on iOS (a SwiftUI capacity `Gauge`), where a circular `ProgressView` ignored the value and spun.
29
+
30
+ ### Patch Changes
31
+
32
+ - Updated dependencies [[`356c00f`](https://github.com/hzblj/kara-ui/commit/356c00f76eee8323c4eb65ed4cbcda121c3af627)]:
33
+ - @hzblj/kara-native@0.9.0
34
+ - @hzblj/kara-theme@0.9.0
35
+ - @hzblj/kara-sx@0.9.0
36
+
3
37
  ## 0.8.0
4
38
 
5
39
  ### Minor Changes
6
40
 
7
- - [#17](https://github.com/hzblj/kara-ui/pull/17) [`4c7eaa0`](https://github.com/hzblj/kara-ui/commit/4c7eaa021ee4a4b0475e1dfb420fa5803c21ba29) Thanks [@hzblj](https://github.com/hzblj)! - `ActivityIndicator` plays Material 3's expressive `LoadingIndicator` on Android — its shapes morph as it turns — in a host of its own, so it still renders anywhere; iOS keeps UIKit's spinner. It takes the design system's props now, not React Native's: `color` is a token (`fill.accent.primary` by default), `size` is `small` or `large`.
41
+ - [#17](https://github.com/hzblj/kara-ui/pull/17) [`4c7eaa0`](https://github.com/hzblj/kara-ui/commit/4c7eaa021ee4a4b0475e1dfb420fa5803c21ba29) Thanks [@hzblj](https://github.com/hzblj)! - `ActivityIndicator` plays Material 3's expressive `LoadingIndicator` on Android (its shapes morph as it turns), in a host of its own, so it still renders anywhere; iOS keeps UIKit's spinner. It takes the design system's props now, not React Native's: `color` is a token (`fill.accent.primary` by default), `size` is `small` or `large`.
8
42
 
9
43
  `Collapsible` on Android spans its parent, the chevron at the far end, and its row is never shorter than Material's 48dp touch target; the chevron sat right after the label. `Pager`'s dots on Android are centred under the pages.
10
44
 
11
45
  - [#17](https://github.com/hzblj/kara-ui/pull/17) [`4c7eaa0`](https://github.com/hzblj/kara-ui/commit/4c7eaa021ee4a4b0475e1dfb420fa5803c21ba29) Thanks [@hzblj](https://github.com/hzblj)! - Android gets glass and a scroll edge of its own.
12
46
 
13
- - `GlassView` is frosted glass on Android: what lies behind the capsule, blurred (Android 12+), under a translucent tonal surface — or its `tint` — and a light hairline, the blurred surfaces Android 16 gives its own system UI. It was an almost clear capsule that left its content unreadable over a photo. Below Android 12 the same colours are drawn near-opaque. kara-native's new `BackdropBlurView` (`/jetpack-compose`) does the blur — blurred, then saturated, as iOS lifts the colour under its materials: a plain view, no host, and an idle screen draws no frames.
14
- - `ScrollEdgeContainer` on Android behaves like a Material top app bar on scroll: the bars stay transparent at rest and fill with the scrolled container colour once content scrolls under the top one, the bottom one while there is more below. Its scroll view also takes the room between the bars now — it grew to its content's height, ran under the bottom bar and could not scroll.
15
- - New token `surface.secondary`: Material's `surfaceContainer` on Android, `tertiarySystemGroupedBackgroundColor` on iOS — a step above `surface.primary`.
47
+ - `GlassView` is frosted glass on Android: what lies behind the capsule, blurred (Android 12+), under a translucent tonal surface (or its `tint`) and a light hairline, the blurred surfaces Android 16 gives its own system UI. It was an almost clear capsule that left its content unreadable over a photo. Below Android 12 the same colours are drawn near-opaque. kara-native's new `BackdropBlurView` (`/jetpack-compose`) does the blur (blurred, then saturated, as iOS lifts the colour under its materials): a plain view, no host, and an idle screen draws no frames.
48
+ - `ScrollEdgeContainer` on Android behaves like a Material top app bar on scroll: the bars stay transparent at rest and fill with the scrolled container colour once content scrolls under the top one, the bottom one while there is more below. Its scroll view also takes the room between the bars now; before, it grew to its content's height, ran under the bottom bar and could not scroll.
49
+ - New token `surface.secondary`, a step above `surface.primary`: Material's `surfaceContainer` on Android, `tertiarySystemGroupedBackgroundColor` on iOS.
16
50
 
17
- - [#17](https://github.com/hzblj/kara-ui/pull/17) [`4c7eaa0`](https://github.com/hzblj/kara-ui/commit/4c7eaa021ee4a4b0475e1dfb420fa5803c21ba29) Thanks [@hzblj](https://github.com/hzblj)! - `Pressable` on Android presses the Material way: a ripple over the content — the pressed state layer — clipped to the pressable's shape, and nothing scales. iOS keeps its spring to 96%. Give the `Pressable` the `borderRadius` of what it wraps (`full` around a `GlassView`) and the ripple follows it.
51
+ - [#17](https://github.com/hzblj/kara-ui/pull/17) [`4c7eaa0`](https://github.com/hzblj/kara-ui/commit/4c7eaa021ee4a4b0475e1dfb420fa5803c21ba29) Thanks [@hzblj](https://github.com/hzblj)! - `Pressable` on Android presses the Material way: a ripple over the content (the pressed state layer), clipped to the pressable's shape, and nothing scales. iOS keeps its spring to 96%. Give the `Pressable` the `borderRadius` of what it wraps (`full` around a `GlassView`) and the ripple follows it.
18
52
 
19
53
  `Collapsible` on Android expands down from its row with a fade, and its chevron turns toward the content; it grew from a corner and the chevron jumped.
20
54
 
21
- - [#17](https://github.com/hzblj/kara-ui/pull/17) [`4c7eaa0`](https://github.com/hzblj/kara-ui/commit/4c7eaa021ee4a4b0475e1dfb420fa5803c21ba29) Thanks [@hzblj](https://github.com/hzblj)! - New `BlurView`: the system materials, by SwiftUI's names — `ultraThin`, `thin`, `regular`, `thick`, `ultraThick`.
55
+ - [#17](https://github.com/hzblj/kara-ui/pull/17) [`4c7eaa0`](https://github.com/hzblj/kara-ui/commit/4c7eaa021ee4a4b0475e1dfb420fa5803c21ba29) Thanks [@hzblj](https://github.com/hzblj)! - New `BlurView`: the system materials, by SwiftUI's names (`ultraThin`, `thin`, `regular`, `thick`, `ultraThick`).
22
56
 
23
- - iOS: UIKit's `system*Material` blur as a plain view — no SwiftUI host, cheap enough for a list cell — with `vibrancy` (`primary` to `quaternary`, `fill`, `separator`) to draw the content the way iOS draws its own on a material.
57
+ - iOS: UIKit's `system*Material` blur as a plain view (no SwiftUI host, cheap enough for a list cell), with `vibrancy` (`primary` to `quaternary`, `fill`, `separator`) to draw the content the way iOS draws its own on a material.
24
58
  - Android: what lies behind, blurred and saturated (Android 12+), under a Material tonal surface that rises from `surface` to `surfaceContainerHighest` as the material thickens; below Android 12 the surface alone.
25
59
  - `appearance` pins a material to light or dark whatever the app's; `borderRadius` shapes it and clips the content.
26
60
 
@@ -28,8 +62,8 @@
28
62
 
29
63
  - [#17](https://github.com/hzblj/kara-ui/pull/17) [`4c7eaa0`](https://github.com/hzblj/kara-ui/commit/4c7eaa021ee4a4b0475e1dfb420fa5803c21ba29) Thanks [@hzblj](https://github.com/hzblj)! - `sx` reaches the components that still took raw styles or none:
30
64
 
31
- - `Text` takes the native `sx` surface — padding, a background, a frame (`wide` puts the text on the side `align` names) and the `ios` bucket. `ios.contentTransition` with the new `ios.animation` rolls a number to its next value, and `ios.monospacedDigit` keeps it from shifting what follows. `Stepper` on iOS is built on it.
32
- - `RnText` takes `Box`'s `sx` props for its own box — margins, `flex`, padding — all but `align`, which still aligns its lines.
65
+ - `Text` takes the native `sx` surface: padding, a background, a frame (`wide` puts the text on the side `align` names) and the `ios` bucket. `ios.contentTransition` with the new `ios.animation` rolls a number to its next value, and `ios.monospacedDigit` keeps it from shifting what follows. `Stepper` on iOS is built on it.
66
+ - `RnText` takes `Box`'s `sx` props for its own box (margins, `flex`, padding), all but `align`, which still aligns its lines.
33
67
  - `Image` is `sx(expo-image)`, the way `Box` is `sx(View)`: `w`, `h`, `aspectRatio`, `borderRadius`, `position`… instead of a `style` object. Its props are exported as `ImageProps`.
34
68
  - `Island` takes the same `sx` props for where it sits in React Native layout: `<Island h={240} matchContents={false}>`. An explicit `style` still wins.
35
69
  - `Skeleton` is sized with the `sx` names, `h` and `w` (was `height` and `width`), and `w` takes a percentage: `<Skeleton h={12} w="60%" />` for a line that ends early.
@@ -46,7 +80,7 @@
46
80
 
47
81
  ### Minor Changes
48
82
 
49
- - [#12](https://github.com/hzblj/kara-ui/pull/12) [`2a6595f`](https://github.com/hzblj/kara-ui/commit/2a6595f79176a3450610d361a02001aac9530490) Thanks [@hzblj](https://github.com/hzblj)! - `SwipeActions` works on Android, and takes its buttons as data. **Breaking:** `SwipeActions.Actions` and its `Button` children are gone — pass `leading` and/or `trailing`, each a list of `{icon, label, onPress, destructive?, tint?}`, and `allowsFullSwipe` on the row:
83
+ - [#12](https://github.com/hzblj/kara-ui/pull/12) [`2a6595f`](https://github.com/hzblj/kara-ui/commit/2a6595f79176a3450610d361a02001aac9530490) Thanks [@hzblj](https://github.com/hzblj)! - `SwipeActions` works on Android, and takes its buttons as data. **Breaking:** `SwipeActions.Actions` and its `Button` children are gone. Pass `leading` and/or `trailing`, each a list of `{icon, label, onPress, destructive?, tint?}`, and `allowsFullSwipe` on the row:
50
84
 
51
85
  ```tsx
52
86
  <SwipeActions
@@ -58,33 +92,33 @@
58
92
  </SwipeActions>
59
93
  ```
60
94
 
61
- iOS renders SwiftUI's `swipeActions`, each action its icon on a button in its tint — round, with the label under it, on iOS 26. Android, where Compose has no swipe actions, gets kara's own `SwipeActionsBox` (`@hzblj/kara-native/jetpack-compose`): the row slides on an anchored drag, and filled icon buttons with their labels show in the strip it leaves. One row is open at a time on both, and a tap on an open row closes it.
95
+ iOS renders SwiftUI's `swipeActions`, each action its icon on a button in its tint (round, with the label under it, on iOS 26). Android, where Compose has no swipe actions, gets kara's own `SwipeActionsBox` (`@hzblj/kara-native/jetpack-compose`): the row slides on an anchored drag, and filled icon buttons with their labels show in the strip it leaves. One row is open at a time on both, and a tap on an open row closes it.
62
96
 
63
- - [#12](https://github.com/hzblj/kara-ui/pull/12) [`2a6595f`](https://github.com/hzblj/kara-ui/commit/2a6595f79176a3450610d361a02001aac9530490) Thanks [@hzblj](https://github.com/hzblj)! - **Breaking:** `FlashList` is gone, and `@shopify/flash-list` is no longer a peer dependency. kara's list for React Native content is `RnFlatList` (and `RnSectionList`): React Native's own virtualized lists, whose cells stay in normal flow, so rows that host native views keep them in place — a recycling list moves its cells, which an `@expo/ui` host does not survive. An app that wants FlashList for plain data rows installs and imports it itself.
97
+ - [#12](https://github.com/hzblj/kara-ui/pull/12) [`2a6595f`](https://github.com/hzblj/kara-ui/commit/2a6595f79176a3450610d361a02001aac9530490) Thanks [@hzblj](https://github.com/hzblj)! - **Breaking:** `FlashList` is gone, and `@shopify/flash-list` is no longer a peer dependency. kara's list for React Native content is `RnFlatList` (and `RnSectionList`): React Native's own virtualized lists, whose cells stay in normal flow, so rows that host native views keep them in place; a recycling list moves its cells, which an `@expo/ui` host does not survive. An app that wants FlashList for plain data rows installs and imports it itself.
64
98
 
65
- - [#12](https://github.com/hzblj/kara-ui/pull/12) [`2a6595f`](https://github.com/hzblj/kara-ui/commit/2a6595f79176a3450610d361a02001aac9530490) Thanks [@hzblj](https://github.com/hzblj)! - `Tooltip` is controlled on Android too: `visible` shows Material's plain tooltip, centred above the anchor and kept inside the window, and `onDismiss` reports a touch outside it or the anchor scrolling away. It used to open only on a long press and hide itself, ignoring both props — and Material's own placement let it run off the edge of the screen. Nothing opens it on a long press any more; wire one to `visible` if you want it.
99
+ - [#12](https://github.com/hzblj/kara-ui/pull/12) [`2a6595f`](https://github.com/hzblj/kara-ui/commit/2a6595f79176a3450610d361a02001aac9530490) Thanks [@hzblj](https://github.com/hzblj)! - `Tooltip` is controlled on Android too: `visible` shows Material's plain tooltip, centred above the anchor and kept inside the window, and `onDismiss` reports a touch outside it or the anchor scrolling away. It used to open only on a long press and hide itself, ignoring both props, and Material's own placement let it run off the edge of the screen. Nothing opens it on a long press any more; wire one to `visible` if you want it.
66
100
 
67
101
  `TooltipBox` (`@hzblj/kara-native/jetpack-compose`) takes `plain` for that style, and hides when `isPresented` turns false.
68
102
 
69
103
  ### Patch Changes
70
104
 
71
- - [#12](https://github.com/hzblj/kara-ui/pull/12) [`2a6595f`](https://github.com/hzblj/kara-ui/commit/2a6595f79176a3450610d361a02001aac9530490) Thanks [@hzblj](https://github.com/hzblj)! - `ActionSheet` on Android renders its rows in a host of its own — they were Compose views straight inside the sheet, which has none, and threw "must be rendered inside a Host". The rows are Material's bottom-sheet menu now: full width, with each action's `icon` before its label.
105
+ - [#12](https://github.com/hzblj/kara-ui/pull/12) [`2a6595f`](https://github.com/hzblj/kara-ui/commit/2a6595f79176a3450610d361a02001aac9530490) Thanks [@hzblj](https://github.com/hzblj)! - `ActionSheet` on Android renders its rows in a host of its own. They were Compose views straight inside the sheet, which has none, and threw "must be rendered inside a Host". The rows are Material's bottom-sheet menu now: full width, with each action's `icon` before its label.
72
106
 
73
107
  `SearchBar` on iOS centres its text beside the magnifier. The type scale's line height sat the text at the bottom of a taller line in a single-line `UITextField`.
74
108
 
75
109
  - [#12](https://github.com/hzblj/kara-ui/pull/12) [`2a6595f`](https://github.com/hzblj/kara-ui/commit/2a6595f79176a3450610d361a02001aac9530490) Thanks [@hzblj](https://github.com/hzblj)! - Android layout fixes:
76
110
 
77
- - `Screen` keeps its content clear of the status bar when nothing sits above it, as a SwiftUI host keeps to the safe area — it drew under it. Under a navigation bar nothing changes; the background still runs to the edges.
78
- - `Form` is inset from its container on every side, with section titles and footers indented to the cards' content, like SwiftUI's grouped form — in a `Screen` its cards ran into the screen's edges.
111
+ - `Screen` keeps its content clear of the status bar when nothing sits above it, as a SwiftUI host keeps to the safe area; it used to draw under it. Under a navigation bar nothing changes; the background still runs to the edges.
112
+ - `Form` is inset from its container on every side, with section titles and footers indented to the cards' content, like SwiftUI's grouped form; in a `Screen` its cards used to run into the screen's edges.
79
113
  - A disabled or read-only `Checkbox` or `Switch` keeps Material's 48dp touch target, so it lines up with the enabled ones instead of shifting toward the edge.
80
114
 
81
- - [#12](https://github.com/hzblj/kara-ui/pull/12) [`2a6595f`](https://github.com/hzblj/kara-ui/commit/2a6595f79176a3450610d361a02001aac9530490) Thanks [@hzblj](https://github.com/hzblj)! - `DatePicker` on iOS sizes itself to its value. Its host took the width it was given and laid the compact field out against the far edge of it — past its container's, in a row. The calendar is in the accent now.
115
+ - [#12](https://github.com/hzblj/kara-ui/pull/12) [`2a6595f`](https://github.com/hzblj/kara-ui/commit/2a6595f79176a3450610d361a02001aac9530490) Thanks [@hzblj](https://github.com/hzblj)! - `DatePicker` on iOS sizes itself to its value. Its host took the width it was given and laid the compact field out against the far edge of it, past its container's, in a row. The calendar is in the accent now.
82
116
 
83
- - [#12](https://github.com/hzblj/kara-ui/pull/12) [`2a6595f`](https://github.com/hzblj/kara-ui/commit/2a6595f79176a3450610d361a02001aac9530490) Thanks [@hzblj](https://github.com/hzblj)! - `Alert` and `ActionSheet` appear on iOS. Both hung their SwiftUI presentation on an `EmptyView` — `@expo/ui` uses one when there is no trigger, and SwiftUI never presents from it — so `visible` changed nothing. Each now has a trigger that takes no room, and `ActionSheet` passes its buttons through the dialog's `Actions` slot.
117
+ - [#12](https://github.com/hzblj/kara-ui/pull/12) [`2a6595f`](https://github.com/hzblj/kara-ui/commit/2a6595f79176a3450610d361a02001aac9530490) Thanks [@hzblj](https://github.com/hzblj)! - `Alert` and `ActionSheet` appear on iOS. Both hung their SwiftUI presentation on an `EmptyView` (`@expo/ui` uses one when there is no trigger, and SwiftUI never presents from it), so `visible` changed nothing. Each now has a trigger that takes no room, and `ActionSheet` passes its buttons through the dialog's `Actions` slot.
84
118
 
85
119
  - [#12](https://github.com/hzblj/kara-ui/pull/12) [`2a6595f`](https://github.com/hzblj/kara-ui/commit/2a6595f79176a3450610d361a02001aac9530490) Thanks [@hzblj](https://github.com/hzblj)! - `RnFlatList` and `RnSectionList` keep rows that host native views on Android. React Native's Android default, `removeClippedSubviews`, detached a host measured at zero height before its first layout, and the row stayed empty; it is off unless you turn it on.
86
120
 
87
- - [#12](https://github.com/hzblj/kara-ui/pull/12) [`2a6595f`](https://github.com/hzblj/kara-ui/commit/2a6595f79176a3450610d361a02001aac9530490) Thanks [@hzblj](https://github.com/hzblj)! - `SegmentedControl` draws its selected segment in the accent on both platforms. iOS renders kara's own `UISegmentedControl` (`SegmentedControl` in `@hzblj/kara-native/swift-ui`), whose pill, labels and track take colours — the system control tints only the pill, SwiftUI's segmented picker not even that. Android colours Material's segmented buttons, equal widths. `onChange` now fires for a new segment only on Android too.
121
+ - [#12](https://github.com/hzblj/kara-ui/pull/12) [`2a6595f`](https://github.com/hzblj/kara-ui/commit/2a6595f79176a3450610d361a02001aac9530490) Thanks [@hzblj](https://github.com/hzblj)! - `SegmentedControl` draws its selected segment in the accent on both platforms. iOS renders kara's own `UISegmentedControl` (`SegmentedControl` in `@hzblj/kara-native/swift-ui`), whose pill, labels and track take colours; the system control tints only the pill, SwiftUI's segmented picker not even that. Android colours Material's segmented buttons, equal widths. `onChange` now fires for a new segment only on Android too.
88
122
 
89
123
  - Updated dependencies [[`2a6595f`](https://github.com/hzblj/kara-ui/commit/2a6595f79176a3450610d361a02001aac9530490), [`2a6595f`](https://github.com/hzblj/kara-ui/commit/2a6595f79176a3450610d361a02001aac9530490), [`2a6595f`](https://github.com/hzblj/kara-ui/commit/2a6595f79176a3450610d361a02001aac9530490), [`2a6595f`](https://github.com/hzblj/kara-ui/commit/2a6595f79176a3450610d361a02001aac9530490), [`2a6595f`](https://github.com/hzblj/kara-ui/commit/2a6595f79176a3450610d361a02001aac9530490)]:
90
124
  - @hzblj/kara-native@0.7.0
@@ -97,13 +131,13 @@
97
131
 
98
132
  - [#10](https://github.com/hzblj/kara-ui/pull/10) [`62b7131`](https://github.com/hzblj/kara-ui/commit/62b713143bd03872ecdd89ca8de42d98fe589617) Thanks [@hzblj](https://github.com/hzblj)! - Haptics: kara's own, native on both platforms, named for what happened.
99
133
 
100
- - `haptics.success()`, `haptics.selection()`, … — one function per haptic — and `haptics.play(name)` for a name that arrives as data. `selection`, `tick`, `toggleOn`/`toggleOff`, `success`/`warning`/`error`, `longPress`, `dragStart`, `thresholdActivate`/`thresholdDeactivate`, `keyPress`, and the impacts `soft`, `light`, `medium`, `rigid`, `heavy` (`intensity` scales them on iOS). Synchronous, nothing to await.
101
- - iOS: UIKit's feedback generators, kept alive and warmed up with `haptics.prepare` — `Pressable` prepares its haptic on press-in. Android: the system's own haptic feedback (`View.performHapticFeedback`), with Android 14's constants falling back to older ones — never a raw vibration. Both follow the user's system setting.
134
+ - One function per haptic (`haptics.success()`, `haptics.selection()`, …) and `haptics.play(name)` for a name that arrives as data. `selection`, `tick`, `toggleOn`/`toggleOff`, `success`/`warning`/`error`, `longPress`, `dragStart`, `thresholdActivate`/`thresholdDeactivate`, `keyPress`, and the impacts `soft`, `light`, `medium`, `rigid`, `heavy` (`intensity` scales them on iOS). Synchronous, nothing to await.
135
+ - iOS: UIKit's feedback generators, kept alive and warmed up with `haptics.prepare` (`Pressable` prepares its haptic on press-in). Android: the system's own haptic feedback (`View.performHapticFeedback`), with Android 14's constants falling back to older ones, never a raw vibration. Both follow the user's system setting.
102
136
  - `useHapticFeedback(trigger, haptic)` plays on every change of a value, never on mount; a function of the previous and next value picks a haptic per change.
103
137
  - `haptics.setEnabled(false)` silences every kara haptic, the components' own included.
104
138
  - `Pressable`'s `haptic` takes a name as well as `true` (a `light` impact); `Chip` plays `selection`.
105
139
  - On Android, where Compose's Material controls play nothing: `Switch` plays `toggleOn`/`toggleOff`, a stepped `Slider` ticks at every stop, `SegmentedControl` plays `selection`. iOS keeps its native controls' own feedback.
106
- - `Slider`: `step` is the increment on Android too — it was passed to Compose as the number of stops.
140
+ - `Slider`: `step` is the increment on Android too. It was passed to Compose as the number of stops.
107
141
  - `expo-haptics` is no longer a peer dependency.
108
142
 
109
143
  ### Patch Changes
@@ -164,7 +198,7 @@
164
198
 
165
199
  ### Minor Changes
166
200
 
167
- - [`f84ffd5`](https://github.com/hzblj/kara-ui/commit/f84ffd52954a5e7052541c8682787137de205a28) Thanks [@hzblj](https://github.com/hzblj)! - Native sheets with a native header. `Sheet` is now a TrueSheet (`@lodev09/react-native-true-sheet`, a new peer dependency) with `<Sheet.Header>` — a real navigation bar with a centred, leading or large title that hands over to the bar as it scrolls away, items on either side, and on iOS 26 the content scrolls under it with the soft edge effect — plus `<Sheet.ScrollView>`, `useSheetScroll`, detents, a footer and a ref (`present`/`dismiss`/`resize`). It is React Native tier now: no host, native atoms inside go in an `Island`. `fitToContents` is replaced by `detents` (`['auto']` by default).
201
+ - [`f84ffd5`](https://github.com/hzblj/kara-ui/commit/f84ffd52954a5e7052541c8682787137de205a28) Thanks [@hzblj](https://github.com/hzblj)! - Native sheets with a native header. `Sheet` is now a TrueSheet (`@lodev09/react-native-true-sheet`, a new peer dependency) with `<Sheet.Header>`, `<Sheet.ScrollView>`, `useSheetScroll`, detents, a footer and a ref (`present`/`dismiss`/`resize`). `<Sheet.Header>` is a real navigation bar with a centred, leading or large title that hands over to the bar as it scrolls away, items on either side, and on iOS 26 the content scrolls under it with the soft edge effect. It is React Native tier now: no host, native atoms inside go in an `Island`. `fitToContents` is replaced by `detents` (`['auto']` by default).
168
202
 
169
203
  `NavigationBar` takes `leadingItems` / `trailingItems` instead of `onBack` / `onClose`: `back`, `close` or an app `icon`, on either side and in any order; on iOS 26 neighbours share a glass capsule unless an item is `separated`. Also `titleAlignment`, `titleVisible`, `inverted` and an iOS `search` field. On Android it is now Material's native top app bar.
170
204
 
@@ -192,12 +226,12 @@
192
226
 
193
227
  - [`c30bef6`](https://github.com/hzblj/kara-ui/commit/c30bef6be2639deb6d385ad209d1a2799b5b656f) Thanks [@hzblj](https://github.com/hzblj)! - Icons are now fully native and the app's own: `plugins: [['@hzblj/kara-ui', {icons: {source: './assets/icons'}}]]` turns every SVG in the folder into an iOS asset-catalog template image and an Android vector drawable at prebuild (`x.ios.svg` / `x.android.svg` for per-platform glyphs), and writes `kara-icons.d.ts` so `name` only accepts icons that exist; `npx kara-icons` does the same for CI. `Icon` draws them in a host, the new `RnIcon` anywhere, and `Tabs` passes them as `xcasset` / `drawable`. The built-in SF Symbol / Material icon names and the `@expo/vector-icons` peer dependency are gone.
194
228
 
195
- - [`c30bef6`](https://github.com/hzblj/kara-ui/commit/c30bef6be2639deb6d385ad209d1a2799b5b656f) Thanks [@hzblj](https://github.com/hzblj)! - Leaner, reusable-only components. `Countdown` is gone, with its native views. There is one `ContextMenu` now — the native module's long-press menu on React Native content, with a custom preview on iOS (formerly `RnContextMenu`); the `@expo/ui`-based one is removed.
229
+ - [`c30bef6`](https://github.com/hzblj/kara-ui/commit/c30bef6be2639deb6d385ad209d1a2799b5b656f) Thanks [@hzblj](https://github.com/hzblj)! - Leaner, reusable-only components. `Countdown` is gone, with its native views. There is one `ContextMenu` now: the native module's long-press menu on React Native content, with a custom preview on iOS (formerly `RnContextMenu`); the `@expo/ui`-based one is removed.
196
230
 
197
231
  Android, reworked to look and behave like Material while honouring the theme:
198
232
 
199
233
  - `Button`, `Badge` and `Alert` render their labels; `Button` keeps Material's own shape (no iOS ring), takes `tint` as its fill with a label that contrasts with it, and draws `glass` as Material's outlined button.
200
- - `Alert` is built from `AlertDialog`'s slots — title, message, the confirm action (destructive when asked) and Cancel — instead of drawing empty.
234
+ - `Alert` is built from `AlertDialog`'s slots instead of drawing empty: title, message, the confirm action (destructive when asked) and Cancel.
201
235
  - `Menu` presents its actions in Material's dropdown popup, with their icons, instead of laying them out over the trigger.
202
236
  - `Picker` is a themed Material exposed dropdown the width of its container.
203
237
  - `Switch`, `Checkbox` and `RadioGroup` are tinted with the accent, and with a label are full-width rows that toggle as a whole; `Form` sections span the form's width.
@@ -215,7 +249,7 @@
215
249
 
216
250
  ### Minor Changes
217
251
 
218
- - [`f919c7b`](https://github.com/hzblj/kara-ui/commit/f919c7b06f3798cebd58eef1581076bf1ee61cd1) Thanks [@hzblj](https://github.com/hzblj)! - First release of the kara-ui design system: theme and tokens, the `sx` engine, atoms, molecules, organisms and `Screen`, native tabs (`@hzblj/kara-ui/router`), the KaraUI native module (Liquid Glass, scroll edge effect, native countdown, context menu with preview, rich tooltip, FAB menu), and `KaraProvider` with theme overrides — colours, the app's own fonts, the Material seed, and Material You dynamic colour on Android. Text uses the platform's face by default. Install `@hzblj/kara-ui`; the scoped packages are its building blocks.
252
+ - [`f919c7b`](https://github.com/hzblj/kara-ui/commit/f919c7b06f3798cebd58eef1581076bf1ee61cd1) Thanks [@hzblj](https://github.com/hzblj)! - First release of the kara-ui design system: theme and tokens, the `sx` engine, atoms, molecules, organisms and `Screen`, native tabs (`@hzblj/kara-ui/router`), the KaraUI native module (Liquid Glass, scroll edge effect, native countdown, context menu with preview, rich tooltip, FAB menu), and `KaraProvider` with theme overrides (colours, the app's own fonts, the Material seed, and Material You dynamic colour on Android). Text uses the platform's face by default. Install `@hzblj/kara-ui`; the scoped packages are its building blocks.
219
253
 
220
254
  ### Patch Changes
221
255
 
package/README.md CHANGED
@@ -8,25 +8,25 @@
8
8
  [license-badge]: https://img.shields.io/badge/license-MIT-ff5700?labelColor=27272a
9
9
  [license-url]: https://github.com/hzblj/kara-ui/blob/main/LICENSE
10
10
 
11
- <a href="https://www.kara.janblazej.dev"><img src="https://www.kara.janblazej.dev/og.png" alt="Kara — native UI for Expo: real SwiftUI and Jetpack Compose views" width="720"></a>
11
+ <a href="https://www.kara.janblazej.dev"><img src="https://www.kara.janblazej.dev/og.png" alt="Kara, native UI for Expo: real SwiftUI and Jetpack Compose views" width="720"></a>
12
12
 
13
- The components of [Kara UI](https://www.kara.janblazej.dev) — a native-first design system for Expo.
13
+ The components of [Kara UI](https://www.kara.janblazej.dev), a native-first design system for Expo.
14
14
 
15
15
  > **Install [`@hzblj/kara-ui`](https://www.npmjs.com/package/@hzblj/kara-ui) instead.** This package is one of its
16
16
  > building blocks, published so its types resolve; everything here is re-exported from `@hzblj/kara-ui`.
17
17
 
18
18
  ## What's inside
19
19
 
20
- - **Native components** — real SwiftUI views on iOS and Jetpack Compose on Android, through `@expo/ui`: a `Switch` is
20
+ - **Native components**: real SwiftUI views on iOS and Jetpack Compose on Android, through `@expo/ui`. A `Switch` is
21
21
  a SwiftUI `Toggle` on one and a Material `Switch` on the other.
22
- - **`Screen` and `Island`** — the hosts native views render in.
23
- - **The React Native tier** — `RnView`, `RnText`, `RnScrollView` and the rest: plain React Native views with the same
24
- `sx` props, for long lists and for content around the native islands.
25
- - **Haptics** — the platform's own feedback, named for what happened.
22
+ - **`Screen` and `Island`**: the hosts native views render in.
23
+ - **The React Native tier**: `RnView`, `RnText`, `RnScrollView` and the rest are plain React Native views with the
24
+ same `sx` props, for long lists and for content around the native islands.
25
+ - **Haptics**: the platform's own feedback, named for what happened.
26
26
 
27
27
  ## Documentation
28
28
 
29
- - [Components](https://www.kara.janblazej.dev/docs/components) — every one photographed on iOS and Android, with its props
29
+ - [Components](https://www.kara.janblazej.dev/docs/components): every one on iOS and Android, with its props
30
30
  - [Screen and Island](https://www.kara.janblazej.dev/docs/hosts)
31
31
  - [Haptics](https://www.kara.janblazej.dev/docs/haptics)
32
32
 
@@ -1,9 +1,36 @@
1
1
  "use strict";
2
2
 
3
- import { warnUnsupported } from "../../platform-support.js";
4
- /** Compose has no colour picker, and there is nothing sane to degrade a colour wheel into. */
5
- export const ColorPicker = () => {
6
- warnUnsupported('ColorPicker', 'Android');
7
- return null;
3
+ import { ColorWell } from '@hzblj/kara-native/jetpack-compose';
4
+ import { useHostGuard } from "../../host-context.js";
5
+ import { HStack } from "../h-stack/index.js";
6
+ import { Spacer } from "../spacer/index.js";
7
+ import { Text } from "../text/index.js";
8
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
9
+ /**
10
+ * The row SwiftUI's `ColorPicker` lays out on iOS, the label leading and the well trailing, around kara's own Compose
11
+ * well: Compose ships no colour picker, so the sheet behind it draws the iOS picker's grid, spectrum and sliders.
12
+ */
13
+ export const ColorPicker = ({
14
+ label,
15
+ onValueChange,
16
+ supportsOpacity = false,
17
+ testID,
18
+ value
19
+ }) => {
20
+ useHostGuard('ColorPicker');
21
+ return /*#__PURE__*/_jsxs(HStack, {
22
+ align: "center",
23
+ spacing: "s12",
24
+ testID: testID,
25
+ wide: true,
26
+ children: [label ? /*#__PURE__*/_jsx(Text, {
27
+ children: label
28
+ }) : null, /*#__PURE__*/_jsx(Spacer, {}), /*#__PURE__*/_jsx(ColorWell, {
29
+ onValueChange: onValueChange,
30
+ supportsOpacity: supportsOpacity,
31
+ title: label,
32
+ value: value
33
+ })]
34
+ });
8
35
  };
9
36
  //# sourceMappingURL=color-picker.android.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["warnUnsupported","ColorPicker"],"sourceRoot":"../../../../src","sources":["atoms/color-picker/color-picker.android.tsx"],"mappings":";;AAAA,SAAQA,eAAe,QAAO,2BAAwB;AAGtD;AACA,OAAO,MAAMC,WAAiC,GAAGA,CAAA,KAAM;EACrDD,eAAe,CAAC,aAAa,EAAE,SAAS,CAAC;EAEzC,OAAO,IAAI;AACb,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["ColorWell","useHostGuard","HStack","Spacer","Text","jsx","_jsx","jsxs","_jsxs","ColorPicker","label","onValueChange","supportsOpacity","testID","value","align","spacing","wide","children","title"],"sourceRoot":"../../../../src","sources":["atoms/color-picker/color-picker.android.tsx"],"mappings":";;AAAA,SAAQA,SAAS,QAAO,oCAAoC;AAE5D,SAAQC,YAAY,QAAO,uBAAoB;AAC/C,SAAQC,MAAM,QAAO,qBAAY;AACjC,SAAQC,MAAM,QAAO,oBAAW;AAChC,SAAQC,IAAI,QAAO,kBAAS;AAAA,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAG5B;AACA;AACA;AACA;AACA,OAAO,MAAMC,WAAiC,GAAGA,CAAC;EAChDC,KAAK;EACLC,aAAa;EACbC,eAAe,GAAG,KAAK;EACvBC,MAAM;EACNC;AACgB,CAAC,KAAK;EACtBb,YAAY,CAAC,aAAa,CAAC;EAE3B,oBACEO,KAAA,CAACN,MAAM;IAACa,KAAK,EAAC,QAAQ;IAACC,OAAO,EAAC,KAAK;IAACH,MAAM,EAAEA,MAAO;IAACI,IAAI;IAAAC,QAAA,GACtDR,KAAK,gBAAGJ,IAAA,CAACF,IAAI;MAAAc,QAAA,EAAER;IAAK,CAAO,CAAC,GAAG,IAAI,eACpCJ,IAAA,CAACH,MAAM,IAAE,CAAC,eACVG,IAAA,CAACN,SAAS;MAACW,aAAa,EAAEA,aAAc;MAACC,eAAe,EAAEA,eAAgB;MAACO,KAAK,EAAET,KAAM;MAACI,KAAK,EAAEA;IAAM,CAAE,CAAC;EAAA,CACnG,CAAC;AAEb,CAAC","ignoreList":[]}
@@ -1,11 +1,19 @@
1
1
  "use strict";
2
2
 
3
3
  import { Button } from '@expo/ui/swift-ui';
4
- import { buttonStyle, disabled as disabledModifier } from '@expo/ui/swift-ui/modifiers';
4
+ import { buttonStyle, contentShape, disabled as disabledModifier, shapes } from '@expo/ui/swift-ui/modifiers';
5
5
  import { useMemo } from 'react';
6
6
  import { useHostGuard } from "../../host-context.js";
7
7
  import { Icon } from "../icon/index.js";
8
+ import { ZStack } from "../z-stack/index.js";
8
9
  import { jsx as _jsx } from "react/jsx-runtime";
10
+ /** Apple's least tap target. Android's `IconButton` is Material's 48dp; this is the same idea in points. */
11
+ const TARGET = 44;
12
+
13
+ /** The whole square takes the tap, not only the glyph's own pixels. */
14
+ const WHOLE_TARGET = {
15
+ modifiers: [contentShape(shapes.circle())]
16
+ };
9
17
  export const IconButton = ({
10
18
  disabled = false,
11
19
  name,
@@ -24,9 +32,14 @@ export const IconButton = ({
24
32
  modifiers: modifiers,
25
33
  onPress: onPress,
26
34
  testID: testID,
27
- children: /*#__PURE__*/_jsx(Icon, {
28
- color: disabled ? 'btn.content.disabled' : 'content.primary',
29
- name: name
35
+ children: /*#__PURE__*/_jsx(ZStack, {
36
+ h: TARGET,
37
+ ios: WHOLE_TARGET,
38
+ w: TARGET,
39
+ children: /*#__PURE__*/_jsx(Icon, {
40
+ color: "content.primary",
41
+ name: name
42
+ })
30
43
  })
31
44
  });
32
45
  };
@@ -1 +1 @@
1
- {"version":3,"names":["Button","buttonStyle","disabled","disabledModifier","useMemo","useHostGuard","Icon","jsx","_jsx","IconButton","name","onPress","testID","modifiers","list","push","children","color"],"sourceRoot":"../../../../src","sources":["atoms/icon-button/icon-button.ios.tsx"],"mappings":";;AAAA,SAAQA,MAAM,QAAO,mBAAmB;AACxC,SAAQC,WAAW,EAAEC,QAAQ,IAAIC,gBAAgB,QAAO,6BAA6B;AACrF,SAAQC,OAAO,QAAO,OAAO;AAE7B,SAAQC,YAAY,QAAO,uBAAoB;AAC/C,SAAQC,IAAI,QAAO,kBAAS;AAAA,SAAAC,GAAA,IAAAC,IAAA;AAG5B,OAAO,MAAMC,UAA+B,GAAGA,CAAC;EAACP,QAAQ,GAAG,KAAK;EAAEQ,IAAI;EAAEC,OAAO;EAAEC;AAAuB,CAAC,KAAK;EAC7GP,YAAY,CAAC,YAAY,CAAC;EAE1B,MAAMQ,SAAS,GAAGT,OAAO,CAAC,MAAM;IAC9B,MAAMU,IAAI,GAAG,CAACb,WAAW,CAAC,OAAO,CAAC,CAAC;IAEnC,IAAIC,QAAQ,EAAE;MACZY,IAAI,CAACC,IAAI,CAACZ,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACnC;IAEA,OAAOW,IAAI;EACb,CAAC,EAAE,CAACZ,QAAQ,CAAC,CAAC;EAEd,oBACEM,IAAA,CAACR,MAAM;IAACa,SAAS,EAAEA,SAAU;IAACF,OAAO,EAAEA,OAAQ;IAACC,MAAM,EAAEA,MAAO;IAAAI,QAAA,eAC7DR,IAAA,CAACF,IAAI;MAACW,KAAK,EAAEf,QAAQ,GAAG,sBAAsB,GAAG,iBAAkB;MAACQ,IAAI,EAAEA;IAAK,CAAE;EAAC,CAC5E,CAAC;AAEb,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["Button","buttonStyle","contentShape","disabled","disabledModifier","shapes","useMemo","useHostGuard","Icon","ZStack","jsx","_jsx","TARGET","WHOLE_TARGET","modifiers","circle","IconButton","name","onPress","testID","list","push","children","h","ios","w","color"],"sourceRoot":"../../../../src","sources":["atoms/icon-button/icon-button.ios.tsx"],"mappings":";;AAAA,SAAQA,MAAM,QAAO,mBAAmB;AACxC,SAAQC,WAAW,EAAEC,YAAY,EAAEC,QAAQ,IAAIC,gBAAgB,EAAEC,MAAM,QAAO,6BAA6B;AAC3G,SAAQC,OAAO,QAAO,OAAO;AAE7B,SAAQC,YAAY,QAAO,uBAAoB;AAC/C,SAAQC,IAAI,QAAO,kBAAS;AAC5B,SAAQC,MAAM,QAAO,qBAAY;AAAA,SAAAC,GAAA,IAAAC,IAAA;AAGjC;AACA,MAAMC,MAAM,GAAG,EAAE;;AAEjB;AACA,MAAMC,YAAY,GAAG;EAACC,SAAS,EAAE,CAACZ,YAAY,CAACG,MAAM,CAACU,MAAM,CAAC,CAAC,CAAC;AAAC,CAAC;AAEjE,OAAO,MAAMC,UAA+B,GAAGA,CAAC;EAACb,QAAQ,GAAG,KAAK;EAAEc,IAAI;EAAEC,OAAO;EAAEC;AAAuB,CAAC,KAAK;EAC7GZ,YAAY,CAAC,YAAY,CAAC;EAE1B,MAAMO,SAAS,GAAGR,OAAO,CAAC,MAAM;IAC9B,MAAMc,IAAI,GAAG,CAACnB,WAAW,CAAC,OAAO,CAAC,CAAC;IAEnC,IAAIE,QAAQ,EAAE;MACZiB,IAAI,CAACC,IAAI,CAACjB,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACnC;IAEA,OAAOgB,IAAI;EACb,CAAC,EAAE,CAACjB,QAAQ,CAAC,CAAC;EAEd,oBACEQ,IAAA,CAACX,MAAM;IAACc,SAAS,EAAEA,SAAU;IAACI,OAAO,EAAEA,OAAQ;IAACC,MAAM,EAAEA,MAAO;IAAAG,QAAA,eAC7DX,IAAA,CAACF,MAAM;MAACc,CAAC,EAAEX,MAAO;MAACY,GAAG,EAAEX,YAAa;MAACY,CAAC,EAAEb,MAAO;MAAAU,QAAA,eAE9CX,IAAA,CAACH,IAAI;QAACkB,KAAK,EAAC,iBAAiB;QAACT,IAAI,EAAEA;MAAK,CAAE;IAAC,CACtC;EAAC,CACH,CAAC;AAEb,CAAC","ignoreList":[]}
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
 
3
3
  import { useSplitSx } from '@hzblj/kara-sx';
4
- import { useAppTheme, withOpacity } from '@hzblj/kara-theme';
4
+ import { duration, opacity, useAppTheme, withOpacity } from '@hzblj/kara-theme';
5
5
  import { useCallback, useMemo } from 'react';
6
- import { Platform, Pressable as RNPressable, View } from 'react-native';
7
- import Animated, { useAnimatedStyle, useSharedValue, withSpring } from 'react-native-reanimated';
6
+ import { Platform, Pressable as RNPressable } from 'react-native';
7
+ import Animated, { useAnimatedStyle, useSharedValue, withSpring, withTiming } from 'react-native-reanimated';
8
8
  import { haptics } from "../../haptics/index.js";
9
9
  import { splitForRipple } from "../../ripple-clip.js";
10
10
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -12,48 +12,70 @@ const SPRING = {
12
12
  damping: 20,
13
13
  stiffness: 400
14
14
  };
15
+
16
+ /** A dim comes in quickly and leaves a little slower, as UIKit's own highlight does. */
17
+ const DIM_IN = {
18
+ duration: duration.d100
19
+ };
20
+ const DIM_OUT = {
21
+ duration: duration.d200
22
+ };
23
+ const PLATFORM_EFFECT = Platform.OS === 'ios' ? 'scale' : 'none';
15
24
  const AnimatedPressable = Animated.createAnimatedComponent(RNPressable);
16
25
  export const Pressable = ({
17
26
  children,
18
27
  disabled = false,
19
28
  haptic = false,
20
29
  onPress,
30
+ pressEffect = PLATFORM_EFFECT,
31
+ pressedOpacity = 'o60',
32
+ pressedScale = 0.96,
33
+ ripple: withRipple = true,
21
34
  testID,
22
35
  ...props
23
36
  }) => {
24
37
  const [resolved, rest] = useSplitSx(props);
25
- const scale = useSharedValue(1);
38
+ // 0 at rest, 1 held: one value drives whichever effect is picked, so a change of effect needs no second animation.
39
+ const pressed = useSharedValue(0);
26
40
  const feedback = haptic === true ? 'light' : haptic || undefined;
41
+ const dimmed = opacity[pressedOpacity];
27
42
  const theme = useAppTheme();
28
43
  const isAndroid = Platform.OS === 'android';
29
- const rStyle = useAnimatedStyle(() => ({
30
- transform: [{
31
- scale: scale.value
32
- }]
33
- }), []);
44
+ const rStyle = useAnimatedStyle(() => {
45
+ if (pressEffect === 'scale') {
46
+ return {
47
+ transform: [{
48
+ scale: 1 - (1 - pressedScale) * pressed.value
49
+ }]
50
+ };
51
+ }
52
+ return pressEffect === 'opacity' ? {
53
+ opacity: 1 - (1 - dimmed) * pressed.value
54
+ } : {};
55
+ }, [dimmed, pressEffect, pressedScale]);
34
56
 
35
- // Android's press is Material's: a ripple over the content — the pressed state layer, `onSurface` at 10 % — clipped to
36
- // the shape by an outer view (`splitForRipple`), and nothing moves. iOS springs down.
37
- const ripple = useMemo(() => isAndroid ? {
57
+ // Android's press is Material's: a ripple over the content (the pressed state layer, `onSurface` at 10 %) clipped to
58
+ // the shape by an outer view (`splitForRipple`). The effect, when there is one, moves that outer view, ripple and all.
59
+ const ripple = useMemo(() => isAndroid && withRipple ? {
38
60
  color: withOpacity(String(theme.color('content.primary')), 'o10'),
39
61
  foreground: true
40
- } : undefined, [isAndroid, theme]);
62
+ } : undefined, [isAndroid, theme, withRipple]);
41
63
  const androidStyle = useMemo(() => isAndroid ? splitForRipple(resolved) : undefined, [isAndroid, resolved]);
42
64
 
43
65
  // The finger is down: the Taptic Engine has until the release to wake, so the haptic lands with the press.
44
66
  const onPressIn = useCallback(() => {
45
- if (!isAndroid) {
46
- scale.value = withSpring(0.96, SPRING);
67
+ if (pressEffect === 'scale') {
68
+ pressed.value = withSpring(1, SPRING);
69
+ } else if (pressEffect === 'opacity') {
70
+ pressed.value = withTiming(1, DIM_IN);
47
71
  }
48
72
  if (feedback) {
49
73
  haptics.prepare(feedback);
50
74
  }
51
- }, [feedback, isAndroid, scale]);
75
+ }, [feedback, pressEffect, pressed]);
52
76
  const onPressOut = useCallback(() => {
53
- if (!isAndroid) {
54
- scale.value = withSpring(1, SPRING);
55
- }
56
- }, [isAndroid, scale]);
77
+ pressed.value = pressEffect === 'scale' ? withSpring(0, SPRING) : withTiming(0, DIM_OUT);
78
+ }, [pressEffect, pressed]);
57
79
  const onPressWithHaptic = useCallback(() => {
58
80
  if (feedback) {
59
81
  haptics.play(feedback);
@@ -61,14 +83,15 @@ export const Pressable = ({
61
83
  onPress?.();
62
84
  }, [feedback, onPress]);
63
85
  if (androidStyle) {
64
- return /*#__PURE__*/_jsx(View, {
65
- style: androidStyle.outer,
86
+ return /*#__PURE__*/_jsx(Animated.View, {
87
+ style: [androidStyle.outer, rStyle],
66
88
  children: /*#__PURE__*/_jsx(RNPressable, {
67
89
  android_ripple: ripple,
68
90
  disabled: disabled,
69
91
  hitSlop: 8,
70
92
  onPress: onPressWithHaptic,
71
93
  onPressIn: onPressIn,
94
+ onPressOut: onPressOut,
72
95
  style: androidStyle.inner,
73
96
  testID: testID,
74
97
  ...rest,
@@ -1 +1 @@
1
- {"version":3,"names":["useSplitSx","useAppTheme","withOpacity","useCallback","useMemo","Platform","Pressable","RNPressable","View","Animated","useAnimatedStyle","useSharedValue","withSpring","haptics","splitForRipple","jsx","_jsx","SPRING","damping","stiffness","AnimatedPressable","createAnimatedComponent","children","disabled","haptic","onPress","testID","props","resolved","rest","scale","feedback","undefined","theme","isAndroid","OS","rStyle","transform","value","ripple","color","String","foreground","androidStyle","onPressIn","prepare","onPressOut","onPressWithHaptic","play","style","outer","android_ripple","hitSlop","inner"],"sourceRoot":"../../../../src","sources":["atoms/pressable/pressable.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["useSplitSx","duration","opacity","useAppTheme","withOpacity","useCallback","useMemo","Platform","Pressable","RNPressable","Animated","useAnimatedStyle","useSharedValue","withSpring","withTiming","haptics","splitForRipple","jsx","_jsx","SPRING","damping","stiffness","DIM_IN","d100","DIM_OUT","d200","PLATFORM_EFFECT","OS","AnimatedPressable","createAnimatedComponent","children","disabled","haptic","onPress","pressEffect","pressedOpacity","pressedScale","ripple","withRipple","testID","props","resolved","rest","pressed","feedback","undefined","dimmed","theme","isAndroid","rStyle","transform","scale","value","color","String","foreground","androidStyle","onPressIn","prepare","onPressOut","onPressWithHaptic","play","View","style","outer","android_ripple","hitSlop","inner"],"sourceRoot":"../../../../src","sources":["atoms/pressable/pressable.tsx"],"mappings":";;AAAA,SAAQA,UAAU,QAAO,gBAAgB;AACzC,SAAQC,QAAQ,EAAEC,OAAO,EAAEC,WAAW,EAAEC,WAAW,QAAO,mBAAmB;AAC7E,SAAQC,WAAW,EAAEC,OAAO,QAAO,OAAO;AAC1C,SAAQC,QAAQ,EAAEC,SAAS,IAAIC,WAAW,QAAuB,cAAc;AAC/E,OAAOC,QAAQ,IAAGC,gBAAgB,EAAEC,cAAc,EAAEC,UAAU,EAAEC,UAAU,QAAO,yBAAyB;AAE1G,SAAQC,OAAO,QAAO,wBAAe;AACrC,SAAQC,cAAc,QAAO,sBAAmB;AAAA,SAAAC,GAAA,IAAAC,IAAA;AAGhD,MAAMC,MAAM,GAAG;EAACC,OAAO,EAAE,EAAE;EAAEC,SAAS,EAAE;AAAG,CAAC;;AAE5C;AACA,MAAMC,MAAM,GAAG;EAACrB,QAAQ,EAAEA,QAAQ,CAACsB;AAAI,CAAC;AACxC,MAAMC,OAAO,GAAG;EAACvB,QAAQ,EAAEA,QAAQ,CAACwB;AAAI,CAAC;AAEzC,MAAMC,eAAe,GAAGnB,QAAQ,CAACoB,EAAE,KAAK,KAAK,GAAG,OAAO,GAAG,MAAM;AAEhE,MAAMC,iBAAiB,GAAGlB,QAAQ,CAACmB,uBAAuB,CAACpB,WAAW,CAAC;AAEvE,OAAO,MAAMD,SAA6B,GAAGA,CAAC;EAC5CsB,QAAQ;EACRC,QAAQ,GAAG,KAAK;EAChBC,MAAM,GAAG,KAAK;EACdC,OAAO;EACPC,WAAW,GAAGR,eAAe;EAC7BS,cAAc,GAAG,KAAK;EACtBC,YAAY,GAAG,IAAI;EACnBC,MAAM,EAAEC,UAAU,GAAG,IAAI;EACzBC,MAAM;EACN,GAAGC;AACW,CAAC,KAAK;EACpB,MAAM,CAACC,QAAQ,EAAEC,IAAI,CAAC,GAAG1C,UAAU,CAACwC,KAAK,CAAC;EAC1C;EACA,MAAMG,OAAO,GAAG/B,cAAc,CAAC,CAAC,CAAC;EACjC,MAAMgC,QAAQ,GAAGZ,MAAM,KAAK,IAAI,GAAG,OAAO,GAAGA,MAAM,IAAIa,SAAS;EAChE,MAAMC,MAAM,GAAG5C,OAAO,CAACiC,cAAc,CAAC;EAEtC,MAAMY,KAAK,GAAG5C,WAAW,CAAC,CAAC;EAC3B,MAAM6C,SAAS,GAAGzC,QAAQ,CAACoB,EAAE,KAAK,SAAS;EAE3C,MAAMsB,MAAM,GAAGtC,gBAAgB,CAAC,MAAM;IACpC,IAAIuB,WAAW,KAAK,OAAO,EAAE;MAC3B,OAAO;QAACgB,SAAS,EAAE,CAAC;UAACC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,GAAGf,YAAY,IAAIO,OAAO,CAACS;QAAK,CAAC;MAAC,CAAC;IACvE;IAEA,OAAOlB,WAAW,KAAK,SAAS,GAAG;MAAChC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG4C,MAAM,IAAIH,OAAO,CAACS;IAAK,CAAC,GAAG,CAAC,CAAC;EACrF,CAAC,EAAE,CAACN,MAAM,EAAEZ,WAAW,EAAEE,YAAY,CAAC,CAAC;;EAEvC;EACA;EACA,MAAMC,MAAM,GAAG/B,OAAO,CACpB,MACE0C,SAAS,IAAIV,UAAU,GACnB;IAACe,KAAK,EAAEjD,WAAW,CAACkD,MAAM,CAACP,KAAK,CAACM,KAAK,CAAC,iBAAiB,CAAC,CAAC,EAAE,KAAK,CAAC;IAAEE,UAAU,EAAE;EAAI,CAAC,GACrFV,SAAS,EACf,CAACG,SAAS,EAAED,KAAK,EAAET,UAAU,CAC/B,CAAC;EACD,MAAMkB,YAAY,GAAGlD,OAAO,CAC1B,MAAO0C,SAAS,GAAGhC,cAAc,CAACyB,QAAqB,CAAC,GAAGI,SAAU,EACrE,CAACG,SAAS,EAAEP,QAAQ,CACtB,CAAC;;EAED;EACA,MAAMgB,SAAS,GAAGpD,WAAW,CAAC,MAAM;IAClC,IAAI6B,WAAW,KAAK,OAAO,EAAE;MAC3BS,OAAO,CAACS,KAAK,GAAGvC,UAAU,CAAC,CAAC,EAAEM,MAAM,CAAC;IACvC,CAAC,MAAM,IAAIe,WAAW,KAAK,SAAS,EAAE;MACpCS,OAAO,CAACS,KAAK,GAAGtC,UAAU,CAAC,CAAC,EAAEQ,MAAM,CAAC;IACvC;IAEA,IAAIsB,QAAQ,EAAE;MACZ7B,OAAO,CAAC2C,OAAO,CAACd,QAAQ,CAAC;IAC3B;EACF,CAAC,EAAE,CAACA,QAAQ,EAAEV,WAAW,EAAES,OAAO,CAAC,CAAC;EAEpC,MAAMgB,UAAU,GAAGtD,WAAW,CAAC,MAAM;IACnCsC,OAAO,CAACS,KAAK,GAAGlB,WAAW,KAAK,OAAO,GAAGrB,UAAU,CAAC,CAAC,EAAEM,MAAM,CAAC,GAAGL,UAAU,CAAC,CAAC,EAAEU,OAAO,CAAC;EAC1F,CAAC,EAAE,CAACU,WAAW,EAAES,OAAO,CAAC,CAAC;EAE1B,MAAMiB,iBAAiB,GAAGvD,WAAW,CAAC,MAAM;IAC1C,IAAIuC,QAAQ,EAAE;MACZ7B,OAAO,CAAC8C,IAAI,CAACjB,QAAQ,CAAC;IACxB;IAEAX,OAAO,GAAG,CAAC;EACb,CAAC,EAAE,CAACW,QAAQ,EAAEX,OAAO,CAAC,CAAC;EAEvB,IAAIuB,YAAY,EAAE;IAChB,oBACEtC,IAAA,CAACR,QAAQ,CAACoD,IAAI;MAACC,KAAK,EAAE,CAACP,YAAY,CAACQ,KAAK,EAAEf,MAAM,CAAE;MAAAnB,QAAA,eACjDZ,IAAA,CAACT,WAAW;QACVwD,cAAc,EAAE5B,MAAO;QACvBN,QAAQ,EAAEA,QAAS;QACnBmC,OAAO,EAAE,CAAE;QACXjC,OAAO,EAAE2B,iBAAkB;QAC3BH,SAAS,EAAEA,SAAU;QACrBE,UAAU,EAAEA,UAAW;QACvBI,KAAK,EAAEP,YAAY,CAACW,KAAM;QAC1B5B,MAAM,EAAEA,MAAO;QAAA,GACXG,IAAI;QAAAZ,QAAA,EAEPA;MAAQ,CACE;IAAC,CACD,CAAC;EAEpB;EAEA,oBACEZ,IAAA,CAACU,iBAAiB;IAChBG,QAAQ,EAAEA,QAAS;IACnBmC,OAAO,EAAE,CAAE;IACXjC,OAAO,EAAE2B,iBAAkB;IAC3BH,SAAS,EAAEA,SAAU;IACrBE,UAAU,EAAEA,UAAW;IACvBI,KAAK,EAAE,CAACtB,QAAQ,EAAEQ,MAAM,CAAE;IAC1BV,MAAM,EAAEA,MAAO;IAAA,GACXG,IAAI;IAAAZ,QAAA,EAEPA;EAAQ,CACQ,CAAC;AAExB,CAAC","ignoreList":[]}
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
 
3
- import { ProgressView } from '@expo/ui/swift-ui';
4
- import { progressViewStyle, tint } from '@expo/ui/swift-ui/modifiers';
3
+ import { Gauge, ProgressView } from '@expo/ui/swift-ui';
4
+ import { gaugeStyle, progressViewStyle, tint } from '@expo/ui/swift-ui/modifiers';
5
5
  import { useAppTheme } from '@hzblj/kara-theme';
6
6
  import { useMemo } from 'react';
7
7
  import { useHostGuard } from "../../host-context.js";
@@ -12,8 +12,14 @@ export const Progress = ({
12
12
  }) => {
13
13
  useHostGuard('Progress');
14
14
  const theme = useAppTheme();
15
- const modifiers = useMemo(() => [progressViewStyle(circular ? 'circular' : 'linear'), tint(theme.color('fill.accent.primary'))], [circular, theme]);
16
- return /*#__PURE__*/_jsx(ProgressView, {
15
+ const ring = circular && value !== undefined;
16
+ const modifiers = useMemo(() => [ring ? gaugeStyle('circularCapacity') : progressViewStyle(circular ? 'circular' : 'linear'), tint(theme.color('fill.accent.primary'))], [circular, ring, theme]);
17
+
18
+ // SwiftUI's circular `ProgressView` ignores its value on iOS and spins; a ring that fills is a capacity `Gauge`.
19
+ return ring ? /*#__PURE__*/_jsx(Gauge, {
20
+ modifiers: modifiers,
21
+ value: value
22
+ }) : /*#__PURE__*/_jsx(ProgressView, {
17
23
  modifiers: modifiers,
18
24
  value: value ?? null
19
25
  });
@@ -1 +1 @@
1
- {"version":3,"names":["ProgressView","progressViewStyle","tint","useAppTheme","useMemo","useHostGuard","jsx","_jsx","Progress","circular","value","theme","modifiers","color"],"sourceRoot":"../../../../src","sources":["atoms/progress/progress.ios.tsx"],"mappings":";;AAAA,SAAQA,YAAY,QAAO,mBAAmB;AAC9C,SAAQC,iBAAiB,EAAEC,IAAI,QAAO,6BAA6B;AACnE,SAAQC,WAAW,QAAO,mBAAmB;AAC7C,SAAQC,OAAO,QAAO,OAAO;AAE7B,SAAQC,YAAY,QAAO,uBAAoB;AAAA,SAAAC,GAAA,IAAAC,IAAA;AAG/C,OAAO,MAAMC,QAA2B,GAAGA,CAAC;EAACC,QAAQ,GAAG,KAAK;EAAEC;AAAoB,CAAC,KAAK;EACvFL,YAAY,CAAC,UAAU,CAAC;EACxB,MAAMM,KAAK,GAAGR,WAAW,CAAC,CAAC;EAE3B,MAAMS,SAAS,GAAGR,OAAO,CACvB,MAAM,CAACH,iBAAiB,CAACQ,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC,EAAEP,IAAI,CAACS,KAAK,CAACE,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC,EACrG,CAACJ,QAAQ,EAAEE,KAAK,CAClB,CAAC;EAED,oBAAOJ,IAAA,CAACP,YAAY;IAACY,SAAS,EAAEA,SAAU;IAACF,KAAK,EAAEA,KAAK,IAAI;EAAK,CAAE,CAAC;AACrE,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["Gauge","ProgressView","gaugeStyle","progressViewStyle","tint","useAppTheme","useMemo","useHostGuard","jsx","_jsx","Progress","circular","value","theme","ring","undefined","modifiers","color"],"sourceRoot":"../../../../src","sources":["atoms/progress/progress.ios.tsx"],"mappings":";;AAAA,SAAQA,KAAK,EAAEC,YAAY,QAAO,mBAAmB;AACrD,SAAQC,UAAU,EAAEC,iBAAiB,EAAEC,IAAI,QAAO,6BAA6B;AAC/E,SAAQC,WAAW,QAAO,mBAAmB;AAC7C,SAAQC,OAAO,QAAO,OAAO;AAE7B,SAAQC,YAAY,QAAO,uBAAoB;AAAA,SAAAC,GAAA,IAAAC,IAAA;AAG/C,OAAO,MAAMC,QAA2B,GAAGA,CAAC;EAACC,QAAQ,GAAG,KAAK;EAAEC;AAAoB,CAAC,KAAK;EACvFL,YAAY,CAAC,UAAU,CAAC;EACxB,MAAMM,KAAK,GAAGR,WAAW,CAAC,CAAC;EAE3B,MAAMS,IAAI,GAAGH,QAAQ,IAAIC,KAAK,KAAKG,SAAS;EAC5C,MAAMC,SAAS,GAAGV,OAAO,CACvB,MAAM,CACJQ,IAAI,GAAGZ,UAAU,CAAC,kBAAkB,CAAC,GAAGC,iBAAiB,CAACQ,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC,EAC3FP,IAAI,CAACS,KAAK,CAACI,KAAK,CAAC,qBAAqB,CAAC,CAAC,CACzC,EACD,CAACN,QAAQ,EAAEG,IAAI,EAAED,KAAK,CACxB,CAAC;;EAED;EACA,OAAOC,IAAI,gBACTL,IAAA,CAACT,KAAK;IAACgB,SAAS,EAAEA,SAAU;IAACJ,KAAK,EAAEA;EAAM,CAAE,CAAC,gBAE7CH,IAAA,CAACR,YAAY;IAACe,SAAS,EAAEA,SAAU;IAACJ,KAAK,EAAEA,KAAK,IAAI;EAAK,CAAE,CAC5D;AACH,CAAC","ignoreList":[]}
@@ -11,7 +11,10 @@ export const Surface = ({
11
11
  ...sx
12
12
  }) => {
13
13
  useHostGuard('Surface');
14
+
15
+ // `surface.primary` unless told otherwise, as Material's `Surface` is on Android — without it a plain one drew nothing.
14
16
  const modifiers = useSxModifiers({
17
+ bg: 'surface.primary',
15
18
  borderRadius: 'large',
16
19
  p: 's16',
17
20
  ...sx
@@ -1 +1 @@
1
- {"version":3,"names":["GlassEffectContainer","VStack","useSxModifiers","useHostGuard","jsx","_jsx","Surface","children","glass","testID","sx","modifiers","borderRadius","p","content","alignment"],"sourceRoot":"../../../../src","sources":["atoms/surface/surface.ios.tsx"],"mappings":";;AAAA,SAAQA,oBAAoB,EAAEC,MAAM,QAAO,mBAAmB;AAC9D,SAAQC,cAAc,QAAO,gBAAgB;AAC7C,SAAQC,YAAY,QAAO,uBAAoB;AAAA,SAAAC,GAAA,IAAAC,IAAA;AAG/C,OAAO,MAAMC,OAAyB,GAAGA,CAAC;EAACC,QAAQ;EAAEC,KAAK,GAAG,KAAK;EAAEC,MAAM;EAAE,GAAGC;AAAgB,CAAC,KAAK;EACnGP,YAAY,CAAC,SAAS,CAAC;EAEvB,MAAMQ,SAAS,GAAGT,cAAc,CAAC;IAACU,YAAY,EAAE,OAAO;IAAEC,CAAC,EAAE,KAAK;IAAE,GAAGH;EAAE,CAAC,CAAC;EAC1E,MAAMI,OAAO,gBACXT,IAAA,CAACJ,MAAM;IAACc,SAAS,EAAC,SAAS;IAACJ,SAAS,EAAEA,SAAU;IAACF,MAAM,EAAEA,MAAO;IAAAF,QAAA,EAC9DA;EAAQ,CACH,CACT;EAED,IAAI,CAACC,KAAK,EAAE;IACV,OAAOM,OAAO;EAChB;EAEA,oBAAOT,IAAA,CAACL,oBAAoB;IAAAO,QAAA,EAAEO;EAAO,CAAuB,CAAC;AAC/D,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["GlassEffectContainer","VStack","useSxModifiers","useHostGuard","jsx","_jsx","Surface","children","glass","testID","sx","modifiers","bg","borderRadius","p","content","alignment"],"sourceRoot":"../../../../src","sources":["atoms/surface/surface.ios.tsx"],"mappings":";;AAAA,SAAQA,oBAAoB,EAAEC,MAAM,QAAO,mBAAmB;AAC9D,SAAQC,cAAc,QAAO,gBAAgB;AAC7C,SAAQC,YAAY,QAAO,uBAAoB;AAAA,SAAAC,GAAA,IAAAC,IAAA;AAG/C,OAAO,MAAMC,OAAyB,GAAGA,CAAC;EAACC,QAAQ;EAAEC,KAAK,GAAG,KAAK;EAAEC,MAAM;EAAE,GAAGC;AAAgB,CAAC,KAAK;EACnGP,YAAY,CAAC,SAAS,CAAC;;EAEvB;EACA,MAAMQ,SAAS,GAAGT,cAAc,CAAC;IAACU,EAAE,EAAE,iBAAiB;IAAEC,YAAY,EAAE,OAAO;IAAEC,CAAC,EAAE,KAAK;IAAE,GAAGJ;EAAE,CAAC,CAAC;EACjG,MAAMK,OAAO,gBACXV,IAAA,CAACJ,MAAM;IAACe,SAAS,EAAC,SAAS;IAACL,SAAS,EAAEA,SAAU;IAACF,MAAM,EAAEA,MAAO;IAAAF,QAAA,EAC9DA;EAAQ,CACH,CACT;EAED,IAAI,CAACC,KAAK,EAAE;IACV,OAAOO,OAAO;EAChB;EAEA,oBAAOV,IAAA,CAACL,oBAAoB;IAAAO,QAAA,EAAEQ;EAAO,CAAuB,CAAC;AAC/D,CAAC","ignoreList":[]}
@@ -3,6 +3,7 @@
3
3
  import { Column, Text as ComposeText, OutlinedTextField, useNativeState } from '@expo/ui/jetpack-compose';
4
4
  import { useSxModifiers } from '@hzblj/kara-sx';
5
5
  import { useAppTheme } from '@hzblj/kara-theme';
6
+ import { Glyph } from "../../glyph/index.js";
6
7
  import { useHostGuard } from "../../host-context.js";
7
8
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
9
  export const TextField = ({
@@ -20,17 +21,19 @@ export const TextField = ({
20
21
  const modifiers = useSxModifiers({
21
22
  wide: true
22
23
  });
24
+ const invalid = Boolean(error);
25
+ const message = typeof error === 'string' && error ? error : undefined;
23
26
  return /*#__PURE__*/_jsxs(Column, {
24
27
  verticalArrangement: {
25
28
  spacedBy: 4
26
29
  },
27
30
  children: [label ? /*#__PURE__*/_jsx(ComposeText, {
28
- color: theme.colorString(error ? 'content.destructive' : 'content.secondary'),
31
+ color: theme.colorString(invalid ? 'content.destructive' : 'content.secondary'),
29
32
  style: theme.typography.labelMedium,
30
33
  children: label
31
- }) : null, /*#__PURE__*/_jsx(OutlinedTextField, {
34
+ }) : null, /*#__PURE__*/_jsxs(OutlinedTextField, {
32
35
  enabled: !disabled,
33
- isError: error,
36
+ isError: invalid,
34
37
  modifiers: modifiers,
35
38
  onValueChange: onChangeText,
36
39
  singleLine: !multiline,
@@ -40,7 +43,19 @@ export const TextField = ({
40
43
  fontWeight: theme.typography.body.fontWeight
41
44
  },
42
45
  value: value,
43
- visualTransformation: secure ? 'password' : 'none'
46
+ visualTransformation: secure ? 'password' : 'none',
47
+ children: [invalid ? /*#__PURE__*/_jsx(OutlinedTextField.TrailingIcon, {
48
+ children: /*#__PURE__*/_jsx(Glyph, {
49
+ color: "content.destructive",
50
+ name: "error"
51
+ })
52
+ }) : null, message ? /*#__PURE__*/_jsx(OutlinedTextField.SupportingText, {
53
+ children: /*#__PURE__*/_jsx(ComposeText, {
54
+ color: theme.colorString('content.destructive'),
55
+ style: theme.typography.footnote,
56
+ children: message
57
+ })
58
+ }) : null]
44
59
  })]
45
60
  });
46
61
  };