@korsolutions/ui 0.0.87 → 0.0.89

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 (237) hide show
  1. package/dist/module/components/alert/components/alert-icon.js +0 -1
  2. package/dist/module/components/alert/components/alert-icon.js.map +1 -1
  3. package/dist/module/components/alert/variants/default.js +2 -1
  4. package/dist/module/components/alert/variants/default.js.map +1 -1
  5. package/dist/module/components/alert/variants/destructive.js +2 -1
  6. package/dist/module/components/alert/variants/destructive.js.map +1 -1
  7. package/dist/module/components/alert-dialog/variants/default.js +4 -1
  8. package/dist/module/components/alert-dialog/variants/default.js.map +1 -1
  9. package/dist/module/components/avatar/variants/default.js +1 -0
  10. package/dist/module/components/avatar/variants/default.js.map +1 -1
  11. package/dist/module/components/badge/variants/default.js +1 -0
  12. package/dist/module/components/badge/variants/default.js.map +1 -1
  13. package/dist/module/components/badge/variants/secondary.js +1 -0
  14. package/dist/module/components/badge/variants/secondary.js.map +1 -1
  15. package/dist/module/components/button/button.js +8 -3
  16. package/dist/module/components/button/button.js.map +1 -1
  17. package/dist/module/components/button/variants/default.js +1 -0
  18. package/dist/module/components/button/variants/default.js.map +1 -1
  19. package/dist/module/components/button/variants/ghost.js +1 -0
  20. package/dist/module/components/button/variants/ghost.js.map +1 -1
  21. package/dist/module/components/button/variants/secondary.js +1 -0
  22. package/dist/module/components/button/variants/secondary.js.map +1 -1
  23. package/dist/module/components/calendar/calendar/variants/default.js +3 -0
  24. package/dist/module/components/calendar/calendar/variants/default.js.map +1 -1
  25. package/dist/module/components/calendar/timeline/variants/default.js +1 -0
  26. package/dist/module/components/calendar/timeline/variants/default.js.map +1 -1
  27. package/dist/module/components/calendar/week-calendar/variants/default.js +3 -0
  28. package/dist/module/components/calendar/week-calendar/variants/default.js.map +1 -1
  29. package/dist/module/components/card/variants/default.js +1 -0
  30. package/dist/module/components/card/variants/default.js.map +1 -1
  31. package/dist/module/components/checkbox/variants/default.js +2 -0
  32. package/dist/module/components/checkbox/variants/default.js.map +1 -1
  33. package/dist/module/components/checkbox/variants/outlined.js +2 -0
  34. package/dist/module/components/checkbox/variants/outlined.js.map +1 -1
  35. package/dist/module/components/combobox/components/combobox-root.js +10 -11
  36. package/dist/module/components/combobox/components/combobox-root.js.map +1 -1
  37. package/dist/module/components/combobox/variants/default.js +3 -0
  38. package/dist/module/components/combobox/variants/default.js.map +1 -1
  39. package/dist/module/components/empty/variants/default.js +2 -0
  40. package/dist/module/components/empty/variants/default.js.map +1 -1
  41. package/dist/module/components/field/variants/default.js +3 -0
  42. package/dist/module/components/field/variants/default.js.map +1 -1
  43. package/dist/module/components/icon/icon.js +1 -2
  44. package/dist/module/components/icon/icon.js.map +1 -1
  45. package/dist/module/components/input/variants/default.js +2 -0
  46. package/dist/module/components/input/variants/default.js.map +1 -1
  47. package/dist/module/components/input/variants/secondary.js +2 -0
  48. package/dist/module/components/input/variants/secondary.js.map +1 -1
  49. package/dist/module/components/link/variants/default.js +1 -0
  50. package/dist/module/components/link/variants/default.js.map +1 -1
  51. package/dist/module/components/menu/variants/default.js +3 -0
  52. package/dist/module/components/menu/variants/default.js.map +1 -1
  53. package/dist/module/components/phone-input/variants/default.js +12 -1
  54. package/dist/module/components/phone-input/variants/default.js.map +1 -1
  55. package/dist/module/components/portal/portal.web.js +15 -0
  56. package/dist/module/components/portal/portal.web.js.map +1 -1
  57. package/dist/module/components/radio-group/variants/default.js +2 -0
  58. package/dist/module/components/radio-group/variants/default.js.map +1 -1
  59. package/dist/module/components/radio-group/variants/outlined.js +2 -0
  60. package/dist/module/components/radio-group/variants/outlined.js.map +1 -1
  61. package/dist/module/components/select/variants/default.js +3 -0
  62. package/dist/module/components/select/variants/default.js.map +1 -1
  63. package/dist/module/components/sidebar/variants/default.js +1 -0
  64. package/dist/module/components/sidebar/variants/default.js.map +1 -1
  65. package/dist/module/components/tabs/variants/default.js +1 -0
  66. package/dist/module/components/tabs/variants/default.js.map +1 -1
  67. package/dist/module/components/tabs/variants/line.js +1 -0
  68. package/dist/module/components/tabs/variants/line.js.map +1 -1
  69. package/dist/module/components/textarea/variants/default.js +1 -0
  70. package/dist/module/components/textarea/variants/default.js.map +1 -1
  71. package/dist/module/components/toast/components/toast-icon.js +0 -1
  72. package/dist/module/components/toast/components/toast-icon.js.map +1 -1
  73. package/dist/module/components/toast/variants/danger.js +7 -6
  74. package/dist/module/components/toast/variants/danger.js.map +1 -1
  75. package/dist/module/components/toast/variants/default.js +2 -0
  76. package/dist/module/components/toast/variants/default.js.map +1 -1
  77. package/dist/module/components/toast/variants/success.js +7 -6
  78. package/dist/module/components/toast/variants/success.js.map +1 -1
  79. package/dist/module/components/typography/typography.js +7 -2
  80. package/dist/module/components/typography/typography.js.map +1 -1
  81. package/dist/module/components/typography/variants/body.js +28 -0
  82. package/dist/module/components/typography/variants/body.js.map +1 -0
  83. package/dist/module/components/typography/variants/heading.js +29 -0
  84. package/dist/module/components/typography/variants/heading.js.map +1 -0
  85. package/dist/module/components/typography/variants/index.js +4 -12
  86. package/dist/module/components/typography/variants/index.js.map +1 -1
  87. package/dist/module/hooks/use-keyboard-height.js +36 -0
  88. package/dist/module/hooks/use-keyboard-height.js.map +1 -0
  89. package/dist/module/hooks/use-relative-position.js +12 -3
  90. package/dist/module/hooks/use-relative-position.js.map +1 -1
  91. package/dist/module/themes/default/colors.js +28 -28
  92. package/dist/module/themes/default/colors.js.map +1 -1
  93. package/dist/module/themes/default/index.js +2 -2
  94. package/dist/module/themes/default/index.js.map +1 -1
  95. package/dist/module/utils/hsla-utils.js +0 -10
  96. package/dist/module/utils/hsla-utils.js.map +1 -1
  97. package/dist/module/utils/size-scale.js +5 -3
  98. package/dist/module/utils/size-scale.js.map +1 -1
  99. package/dist/typescript/src/components/alert/variants/default.d.ts.map +1 -1
  100. package/dist/typescript/src/components/alert/variants/destructive.d.ts.map +1 -1
  101. package/dist/typescript/src/components/alert-dialog/variants/default.d.ts.map +1 -1
  102. package/dist/typescript/src/components/avatar/variants/default.d.ts.map +1 -1
  103. package/dist/typescript/src/components/badge/variants/default.d.ts.map +1 -1
  104. package/dist/typescript/src/components/badge/variants/secondary.d.ts.map +1 -1
  105. package/dist/typescript/src/components/button/button.d.ts.map +1 -1
  106. package/dist/typescript/src/components/button/types.d.ts +3 -2
  107. package/dist/typescript/src/components/button/types.d.ts.map +1 -1
  108. package/dist/typescript/src/components/button/variants/default.d.ts.map +1 -1
  109. package/dist/typescript/src/components/button/variants/ghost.d.ts.map +1 -1
  110. package/dist/typescript/src/components/button/variants/secondary.d.ts.map +1 -1
  111. package/dist/typescript/src/components/calendar/calendar/variants/default.d.ts.map +1 -1
  112. package/dist/typescript/src/components/calendar/timeline/variants/default.d.ts.map +1 -1
  113. package/dist/typescript/src/components/calendar/week-calendar/variants/default.d.ts.map +1 -1
  114. package/dist/typescript/src/components/card/variants/default.d.ts.map +1 -1
  115. package/dist/typescript/src/components/checkbox/variants/default.d.ts.map +1 -1
  116. package/dist/typescript/src/components/checkbox/variants/outlined.d.ts.map +1 -1
  117. package/dist/typescript/src/components/combobox/components/combobox-root.d.ts.map +1 -1
  118. package/dist/typescript/src/components/combobox/variants/default.d.ts.map +1 -1
  119. package/dist/typescript/src/components/empty/variants/default.d.ts.map +1 -1
  120. package/dist/typescript/src/components/field/variants/default.d.ts.map +1 -1
  121. package/dist/typescript/src/components/icon/icon.d.ts.map +1 -1
  122. package/dist/typescript/src/components/input/variants/default.d.ts.map +1 -1
  123. package/dist/typescript/src/components/input/variants/secondary.d.ts.map +1 -1
  124. package/dist/typescript/src/components/link/variants/default.d.ts.map +1 -1
  125. package/dist/typescript/src/components/menu/variants/default.d.ts.map +1 -1
  126. package/dist/typescript/src/components/phone-input/variants/default.d.ts.map +1 -1
  127. package/dist/typescript/src/components/portal/portal.web.d.ts.map +1 -1
  128. package/dist/typescript/src/components/radio-group/variants/default.d.ts.map +1 -1
  129. package/dist/typescript/src/components/radio-group/variants/outlined.d.ts.map +1 -1
  130. package/dist/typescript/src/components/select/variants/default.d.ts.map +1 -1
  131. package/dist/typescript/src/components/sidebar/variants/default.d.ts.map +1 -1
  132. package/dist/typescript/src/components/tabs/variants/default.d.ts.map +1 -1
  133. package/dist/typescript/src/components/tabs/variants/line.d.ts.map +1 -1
  134. package/dist/typescript/src/components/textarea/variants/default.d.ts.map +1 -1
  135. package/dist/typescript/src/components/toast/variants/danger.d.ts.map +1 -1
  136. package/dist/typescript/src/components/toast/variants/default.d.ts.map +1 -1
  137. package/dist/typescript/src/components/toast/variants/success.d.ts.map +1 -1
  138. package/dist/typescript/src/components/typography/typography.d.ts +2 -0
  139. package/dist/typescript/src/components/typography/typography.d.ts.map +1 -1
  140. package/dist/typescript/src/components/typography/variants/body.d.ts +4 -0
  141. package/dist/typescript/src/components/typography/variants/body.d.ts.map +1 -0
  142. package/dist/typescript/src/components/typography/variants/heading.d.ts +4 -0
  143. package/dist/typescript/src/components/typography/variants/heading.d.ts.map +1 -0
  144. package/dist/typescript/src/components/typography/variants/index.d.ts +4 -12
  145. package/dist/typescript/src/components/typography/variants/index.d.ts.map +1 -1
  146. package/dist/typescript/src/hooks/use-keyboard-height.d.ts +9 -0
  147. package/dist/typescript/src/hooks/use-keyboard-height.d.ts.map +1 -0
  148. package/dist/typescript/src/hooks/use-relative-position.d.ts.map +1 -1
  149. package/dist/typescript/src/types/props.types.d.ts +0 -1
  150. package/dist/typescript/src/types/props.types.d.ts.map +1 -1
  151. package/dist/typescript/src/utils/hsla-utils.d.ts +0 -1
  152. package/dist/typescript/src/utils/hsla-utils.d.ts.map +1 -1
  153. package/dist/typescript/src/utils/size-scale.d.ts +3 -1
  154. package/dist/typescript/src/utils/size-scale.d.ts.map +1 -1
  155. package/package.json +4 -5
  156. package/src/components/alert/components/alert-icon.tsx +1 -1
  157. package/src/components/alert/variants/default.tsx +2 -1
  158. package/src/components/alert/variants/destructive.tsx +2 -1
  159. package/src/components/alert-dialog/variants/default.tsx +4 -1
  160. package/src/components/avatar/variants/default.tsx +1 -0
  161. package/src/components/badge/variants/default.tsx +1 -0
  162. package/src/components/badge/variants/secondary.tsx +1 -0
  163. package/src/components/button/button.tsx +9 -3
  164. package/src/components/button/types.ts +3 -2
  165. package/src/components/button/variants/default.tsx +1 -0
  166. package/src/components/button/variants/ghost.tsx +1 -0
  167. package/src/components/button/variants/secondary.tsx +1 -0
  168. package/src/components/calendar/calendar/variants/default.tsx +3 -0
  169. package/src/components/calendar/timeline/variants/default.tsx +1 -0
  170. package/src/components/calendar/week-calendar/variants/default.tsx +3 -0
  171. package/src/components/card/variants/default.tsx +1 -0
  172. package/src/components/checkbox/variants/default.tsx +2 -0
  173. package/src/components/checkbox/variants/outlined.tsx +2 -0
  174. package/src/components/combobox/components/combobox-root.tsx +10 -11
  175. package/src/components/combobox/variants/default.tsx +3 -0
  176. package/src/components/empty/variants/default.tsx +2 -0
  177. package/src/components/field/variants/default.tsx +3 -0
  178. package/src/components/icon/icon.tsx +0 -1
  179. package/src/components/input/variants/default.tsx +2 -0
  180. package/src/components/input/variants/secondary.tsx +2 -0
  181. package/src/components/link/variants/default.tsx +1 -0
  182. package/src/components/menu/variants/default.tsx +3 -0
  183. package/src/components/phone-input/variants/default.tsx +11 -0
  184. package/src/components/portal/portal.web.tsx +15 -0
  185. package/src/components/radio-group/variants/default.tsx +2 -0
  186. package/src/components/radio-group/variants/outlined.tsx +2 -0
  187. package/src/components/select/variants/default.tsx +3 -0
  188. package/src/components/sidebar/variants/default.tsx +1 -0
  189. package/src/components/tabs/variants/default.tsx +1 -0
  190. package/src/components/tabs/variants/line.tsx +1 -0
  191. package/src/components/textarea/variants/default.tsx +1 -0
  192. package/src/components/toast/components/toast-icon.tsx +1 -1
  193. package/src/components/toast/variants/danger.tsx +6 -5
  194. package/src/components/toast/variants/default.tsx +2 -0
  195. package/src/components/toast/variants/success.tsx +6 -5
  196. package/src/components/typography/typography.tsx +5 -2
  197. package/src/components/typography/variants/body.tsx +26 -0
  198. package/src/components/typography/variants/heading.tsx +27 -0
  199. package/src/components/typography/variants/index.ts +4 -12
  200. package/src/hooks/use-keyboard-height.ts +42 -0
  201. package/src/hooks/use-relative-position.ts +17 -3
  202. package/src/themes/default/colors.ts +28 -28
  203. package/src/themes/default/index.ts +2 -2
  204. package/src/types/props.types.ts +0 -1
  205. package/src/utils/hsla-utils.ts +0 -11
  206. package/src/utils/size-scale.ts +8 -4
  207. package/README.md +0 -4
  208. package/dist/module/components/typography/variants/body-lg.js +0 -18
  209. package/dist/module/components/typography/variants/body-lg.js.map +0 -1
  210. package/dist/module/components/typography/variants/body-md.js +0 -18
  211. package/dist/module/components/typography/variants/body-md.js.map +0 -1
  212. package/dist/module/components/typography/variants/body-sm.js +0 -18
  213. package/dist/module/components/typography/variants/body-sm.js.map +0 -1
  214. package/dist/module/components/typography/variants/heading-lg.js +0 -19
  215. package/dist/module/components/typography/variants/heading-lg.js.map +0 -1
  216. package/dist/module/components/typography/variants/heading-md.js +0 -19
  217. package/dist/module/components/typography/variants/heading-md.js.map +0 -1
  218. package/dist/module/components/typography/variants/heading-sm.js +0 -19
  219. package/dist/module/components/typography/variants/heading-sm.js.map +0 -1
  220. package/dist/typescript/src/components/typography/variants/body-lg.d.ts +0 -3
  221. package/dist/typescript/src/components/typography/variants/body-lg.d.ts.map +0 -1
  222. package/dist/typescript/src/components/typography/variants/body-md.d.ts +0 -3
  223. package/dist/typescript/src/components/typography/variants/body-md.d.ts.map +0 -1
  224. package/dist/typescript/src/components/typography/variants/body-sm.d.ts +0 -3
  225. package/dist/typescript/src/components/typography/variants/body-sm.d.ts.map +0 -1
  226. package/dist/typescript/src/components/typography/variants/heading-lg.d.ts +0 -3
  227. package/dist/typescript/src/components/typography/variants/heading-lg.d.ts.map +0 -1
  228. package/dist/typescript/src/components/typography/variants/heading-md.d.ts +0 -3
  229. package/dist/typescript/src/components/typography/variants/heading-md.d.ts.map +0 -1
  230. package/dist/typescript/src/components/typography/variants/heading-sm.d.ts +0 -3
  231. package/dist/typescript/src/components/typography/variants/heading-sm.d.ts.map +0 -1
  232. package/src/components/typography/variants/body-lg.tsx +0 -14
  233. package/src/components/typography/variants/body-md.tsx +0 -14
  234. package/src/components/typography/variants/body-sm.tsx +0 -14
  235. package/src/components/typography/variants/heading-lg.tsx +0 -15
  236. package/src/components/typography/variants/heading-md.tsx +0 -15
  237. package/src/components/typography/variants/heading-sm.tsx +0 -15
@@ -1,4 +1,4 @@
1
- import React, { useCallback, useMemo, useRef, useState } from "react";
1
+ import React, { useEffect, useMemo, useRef, useState } from "react";
2
2
  import {
3
3
  type LayoutRectangle,
4
4
  type StyleProp,
@@ -45,20 +45,19 @@ export function ComboboxRoot(props: ComboboxRootProps) {
45
45
  const [isOpen, setIsOpen] = useState(false);
46
46
  const [contentLayout, setContentLayout] = useState<LayoutRectangle>(DEFAULT_LAYOUT);
47
47
  const [triggerPosition, setTriggerPosition] = useState<LayoutPosition>(DEFAULT_POSITION);
48
- const [inputValue, setInputValueInternal] = useState("");
48
+ const [inputValue, setInputValue] = useState("");
49
49
 
50
50
  const onInputChangeRef = useRef(props.onInputChange);
51
51
  onInputChangeRef.current = props.onInputChange;
52
52
 
53
- const setInputValue: React.Dispatch<React.SetStateAction<string>> = useCallback((action) => {
54
- setInputValueInternal((prev) => {
55
- const next = typeof action === "function" ? action(prev) : action;
56
- if (next !== prev) {
57
- onInputChangeRef.current?.(next);
58
- }
59
- return next;
60
- });
61
- }, []);
53
+ const isFirstRender = useRef(true);
54
+ useEffect(() => {
55
+ if (isFirstRender.current) {
56
+ isFirstRender.current = false;
57
+ return;
58
+ }
59
+ onInputChangeRef.current?.(inputValue);
60
+ }, [inputValue]);
62
61
 
63
62
  const state = calculateState(props);
64
63
  const composedStyles = StyleSheet.flatten([
@@ -27,6 +27,7 @@ export function useComboboxVariantDefault(size: Size): ComboboxStyles {
27
27
  minHeight: s.height,
28
28
  fontFamily,
29
29
  fontSize: s.fontSize,
30
+ lineHeight: s.lineHeight,
30
31
  color: colors.foreground,
31
32
  outlineWidth: 0,
32
33
  pointerEvents: "auto",
@@ -76,6 +77,7 @@ export function useComboboxVariantDefault(size: Size): ComboboxStyles {
76
77
  paddingHorizontal: s.paddingHorizontal,
77
78
  fontFamily,
78
79
  fontSize: s.fontSize,
80
+ lineHeight: s.lineHeight,
79
81
  color: colors.foreground,
80
82
  borderRadius: radius / 2,
81
83
  },
@@ -95,6 +97,7 @@ export function useComboboxVariantDefault(size: Size): ComboboxStyles {
95
97
  paddingHorizontal: s.paddingHorizontal,
96
98
  fontFamily,
97
99
  fontSize: s.fontSize,
100
+ lineHeight: s.lineHeight,
98
101
  color: colors.mutedForeground,
99
102
  textAlign: "center",
100
103
  },
@@ -20,6 +20,7 @@ export function useEmptyVariantDefault(): EmptyStyles {
20
20
  title: {
21
21
  fontFamily: fontFamily,
22
22
  fontSize: fontSize,
23
+ lineHeight: Math.round(fontSize * 1.25),
23
24
  color: colors.foreground,
24
25
  textAlign: "center",
25
26
  fontWeight: "600",
@@ -27,6 +28,7 @@ export function useEmptyVariantDefault(): EmptyStyles {
27
28
  description: {
28
29
  fontFamily: fontFamily,
29
30
  fontSize: fontSize * 0.875,
31
+ lineHeight: Math.round(fontSize * 0.875 * 1.25),
30
32
  color: colors.mutedForeground,
31
33
  textAlign: "center",
32
34
  },
@@ -11,17 +11,20 @@ export const useFieldVariantDefault = (): FieldStyles => {
11
11
  label: {
12
12
  fontFamily,
13
13
  fontSize: fontSize * 0.875,
14
+ lineHeight: Math.round(fontSize * 0.875 * 1.25),
14
15
  fontWeight: "600",
15
16
  color: colors.foreground,
16
17
  },
17
18
  description: {
18
19
  fontFamily,
19
20
  fontSize: fontSize * 0.875,
21
+ lineHeight: Math.round(fontSize * 0.875 * 1.25),
20
22
  color: colors.mutedForeground,
21
23
  },
22
24
  error: {
23
25
  fontFamily,
24
26
  fontSize: fontSize * 0.875,
27
+ lineHeight: Math.round(fontSize * 0.875 * 1.25),
25
28
  color: colors.danger,
26
29
  },
27
30
  }),
@@ -15,7 +15,6 @@ export const Icon: React.FC<PropsWithRequiredRender<IconProps>> = ({
15
15
  ...variantProps,
16
16
  ...props,
17
17
  style: [variantProps.style, props.style],
18
- absoluteStrokeWidth: props.absoluteStrokeWidth ?? true,
19
18
  };
20
19
 
21
20
  return <Component {...composedProps} />;
@@ -19,9 +19,11 @@ export function useInputVariantDefault(size: Size): InputStyles {
19
19
  paddingHorizontal: s.paddingHorizontal,
20
20
  fontFamily,
21
21
  fontSize: s.fontSize,
22
+ lineHeight: s.lineHeight,
22
23
  height: s.height,
23
24
  color: colors.foreground,
24
25
  outlineWidth: 0,
26
+ paddingVertical: 0,
25
27
  ...Platform.select({
26
28
  default: {},
27
29
  web: {
@@ -19,9 +19,11 @@ export function useInputVariantSecondary(size: Size): InputStyles {
19
19
  paddingHorizontal: s.paddingHorizontal,
20
20
  fontFamily,
21
21
  fontSize: s.fontSize,
22
+ lineHeight: s.lineHeight,
22
23
  height: s.height,
23
24
  color: colors.foreground,
24
25
  outlineWidth: 0,
26
+ paddingVertical: 0,
25
27
  ...Platform.select({
26
28
  default: {},
27
29
  web: {
@@ -6,6 +6,7 @@ export function useLinkVariantDefault(): TextStyle {
6
6
  ({ colors, fontFamily, letterSpacing, fontSize }): TextStyle => ({
7
7
  color: colors.primary,
8
8
  fontSize,
9
+ lineHeight: Math.round(fontSize * 1.25),
9
10
  fontFamily,
10
11
  textDecorationLine: "underline",
11
12
  letterSpacing,
@@ -32,6 +32,7 @@ export const useMenuVariantDefault = (): MenuStyles => {
32
32
  itemText: {
33
33
  fontFamily: fontFamily,
34
34
  fontSize: fontSize,
35
+ lineHeight: Math.round(fontSize * 1.25),
35
36
  color: colors.foreground,
36
37
  },
37
38
  itemIcon: {
@@ -43,6 +44,7 @@ export const useMenuVariantDefault = (): MenuStyles => {
43
44
  paddingHorizontal: 16,
44
45
  fontFamily: fontFamily,
45
46
  fontSize: fontSize * 0.75,
47
+ lineHeight: Math.round(fontSize * 0.75 * 1.25),
46
48
  fontWeight: "600",
47
49
  color: colors.mutedForeground,
48
50
  },
@@ -89,6 +91,7 @@ export const useMenuVariantDefault = (): MenuStyles => {
89
91
  },
90
92
  shortcut: {
91
93
  fontSize: fontSize * 0.75,
94
+ lineHeight: Math.round(fontSize * 0.75 * 1.25),
92
95
  fontFamily: fontFamily,
93
96
  color: colors.mutedForeground,
94
97
  },
@@ -41,6 +41,7 @@ export function usePhoneInputVariantDefault(size: Size): PhoneInputStyles {
41
41
  default: {
42
42
  fontFamily,
43
43
  fontSize: s.fontSize,
44
+ lineHeight: s.lineHeight,
44
45
  color: colors.foreground,
45
46
  },
46
47
  disabled: {
@@ -61,9 +62,11 @@ export function usePhoneInputVariantDefault(size: Size): PhoneInputStyles {
61
62
  paddingHorizontal: s.paddingHorizontal,
62
63
  fontFamily,
63
64
  fontSize: s.fontSize,
65
+ lineHeight: s.lineHeight,
64
66
  color: colors.foreground,
65
67
  height: "100%",
66
68
  outlineWidth: 0,
69
+ paddingVertical: 0,
67
70
  ...Platform.select({
68
71
  default: {},
69
72
  web: {
@@ -105,6 +108,7 @@ export function usePhoneInputVariantDefault(size: Size): PhoneInputStyles {
105
108
  default: {
106
109
  fontFamily,
107
110
  fontSize: s.fontSize,
111
+ lineHeight: s.lineHeight,
108
112
  color: colors.foreground,
109
113
  },
110
114
  },
@@ -117,9 +121,16 @@ export function usePhoneInputVariantDefault(size: Size): PhoneInputStyles {
117
121
  paddingHorizontal: s.paddingHorizontal * 0.75,
118
122
  fontFamily,
119
123
  fontSize: s.fontSize * 0.875,
124
+ lineHeight: Math.round(s.fontSize * 0.875 * 1.25),
120
125
  color: colors.foreground,
121
126
  marginBottom: 4,
122
127
  outlineWidth: 0,
128
+ ...Platform.select({
129
+ android: {
130
+ textAlignVertical: "center",
131
+ },
132
+ default: {},
133
+ }),
123
134
  },
124
135
  },
125
136
  };
@@ -6,6 +6,20 @@ export function PortalHost() {
6
6
  return <></>;
7
7
  }
8
8
 
9
+ /**
10
+ * Prevent scroll-lock libraries (e.g. react-remove-scroll used by Radix/Vaul
11
+ * modals) from blocking scroll events inside the portal. These libraries
12
+ * register document-level wheel/touchmove listeners that call
13
+ * preventDefault() on events originating outside their managed "shards".
14
+ * Stopping propagation at the portal container keeps those handlers from
15
+ * firing while still allowing native scroll within the portal content.
16
+ */
17
+ function preventScrollLock(container: HTMLElement) {
18
+ const stop = (e: Event) => e.stopPropagation();
19
+ container.addEventListener("wheel", stop);
20
+ container.addEventListener("touchmove", stop);
21
+ }
22
+
9
23
  export function Portal({ name, hostName = DEFAULT_PORTAL_HOST, children }: PortalProps) {
10
24
  const [container] = useState(() => {
11
25
  let container = document.getElementById(hostName);
@@ -15,6 +29,7 @@ export function Portal({ name, hostName = DEFAULT_PORTAL_HOST, children }: Porta
15
29
  container.id = hostName;
16
30
  container.style.pointerEvents = "auto";
17
31
  document.body.appendChild(container);
32
+ preventScrollLock(container);
18
33
  }
19
34
  return container;
20
35
  });
@@ -55,6 +55,7 @@ export const useRadioGroupVariantDefault = (): RadioGroupStyles => {
55
55
  default: {
56
56
  color: colors.foreground,
57
57
  fontSize,
58
+ lineHeight: Math.round(fontSize * 1.25),
58
59
  fontFamily,
59
60
  fontWeight: "500",
60
61
  },
@@ -66,6 +67,7 @@ export const useRadioGroupVariantDefault = (): RadioGroupStyles => {
66
67
  default: {
67
68
  color: colors.mutedForeground,
68
69
  fontSize: fontSize * 0.875,
70
+ lineHeight: Math.round(fontSize * 0.875 * 1.25),
69
71
  fontFamily,
70
72
  marginTop: 2,
71
73
  },
@@ -67,6 +67,7 @@ export const useRadioGroupVariantOutlined = (): RadioGroupStyles => {
67
67
  default: {
68
68
  color: colors.foreground,
69
69
  fontSize,
70
+ lineHeight: Math.round(fontSize * 1.25),
70
71
  fontFamily,
71
72
  fontWeight: "500",
72
73
  },
@@ -78,6 +79,7 @@ export const useRadioGroupVariantOutlined = (): RadioGroupStyles => {
78
79
  default: {
79
80
  color: colors.mutedForeground,
80
81
  fontSize: fontSize * 0.875,
82
+ lineHeight: Math.round(fontSize * 0.875 * 1.25),
81
83
  fontFamily,
82
84
  marginTop: 2,
83
85
  },
@@ -29,6 +29,7 @@ export function useSelectVariantDefault(size: Size): SelectStyles {
29
29
  default: {
30
30
  fontFamily,
31
31
  fontSize: s.fontSize,
32
+ lineHeight: s.lineHeight,
32
33
  color: colors.foreground,
33
34
  },
34
35
  disabled: {
@@ -39,6 +40,7 @@ export function useSelectVariantDefault(size: Size): SelectStyles {
39
40
  default: {
40
41
  fontFamily,
41
42
  fontSize: s.fontSize,
43
+ lineHeight: s.lineHeight,
42
44
  color: colors.mutedForeground,
43
45
  },
44
46
  disabled: {
@@ -69,6 +71,7 @@ export function useSelectVariantDefault(size: Size): SelectStyles {
69
71
  paddingHorizontal: s.paddingHorizontal,
70
72
  fontFamily,
71
73
  fontSize: s.fontSize,
74
+ lineHeight: s.lineHeight,
72
75
  color: colors.foreground,
73
76
  borderRadius: radius / 2,
74
77
  },
@@ -33,6 +33,7 @@ export function useSidebarVariantDefault(): SidebarStyles {
33
33
  groupLabel: {
34
34
  fontFamily,
35
35
  fontSize: fontSize * 0.75,
36
+ lineHeight: Math.round(fontSize * 0.75 * 1.25),
36
37
  fontWeight: "500",
37
38
  color: colors.mutedForeground,
38
39
  paddingHorizontal: spacing,
@@ -39,6 +39,7 @@ export const useTabsVariantDefault = (): TabsStyles => {
39
39
  default: {
40
40
  color: colors.mutedForeground,
41
41
  fontSize,
42
+ lineHeight: Math.round(fontSize * 1.25),
42
43
  fontFamily,
43
44
  fontWeight: "500",
44
45
  },
@@ -33,6 +33,7 @@ export const useTabsVariantLine = (): TabsStyles => {
33
33
  default: {
34
34
  color: colors.mutedForeground,
35
35
  fontSize,
36
+ lineHeight: Math.round(fontSize * 1.25),
36
37
  fontFamily,
37
38
  fontWeight: "500",
38
39
  },
@@ -24,6 +24,7 @@ export function useTextareaVariantDefault(): TextareaStyles {
24
24
  }),
25
25
  fontFamily,
26
26
  fontSize,
27
+ lineHeight: Math.round(fontSize * 1.25),
27
28
  minHeight: 120,
28
29
  textAlignVertical: "top",
29
30
  color: colors.foreground,
@@ -13,5 +13,5 @@ export function ToastIcon({ render: Component, ...props }: PropsWithRequiredRend
13
13
  style: [toast.styles?.icon?.style, props.style],
14
14
  };
15
15
 
16
- return <Component absoluteStrokeWidth {...composedProps} />;
16
+ return <Component {...composedProps} />;
17
17
  }
@@ -5,7 +5,7 @@ export const useToastVariantDanger = (): ToastStyles => {
5
5
  return useThemedStyles(
6
6
  ({ colors, radius, fontFamily, fontSize }): ToastStyles => ({
7
7
  root: {
8
- backgroundColor: colors.danger,
8
+ backgroundColor: colors.surface,
9
9
  borderWidth: 1,
10
10
  borderColor: colors.danger,
11
11
  borderRadius: radius,
@@ -20,23 +20,24 @@ export const useToastVariantDanger = (): ToastStyles => {
20
20
  gap: 4,
21
21
  },
22
22
  icon: {
23
- color: colors.foreground,
23
+ color: colors.danger,
24
24
  size: 16,
25
25
  style: {
26
26
  marginTop: 2,
27
27
  },
28
28
  },
29
29
  title: {
30
- color: colors.foreground,
30
+ color: colors.danger,
31
31
  fontSize: fontSize,
32
+ lineHeight: Math.round(fontSize * 1.25),
32
33
  fontWeight: "600",
33
34
  fontFamily,
34
35
  },
35
36
  description: {
36
- color: colors.foreground,
37
+ color: colors.mutedForeground,
37
38
  fontSize: fontSize * 0.875,
39
+ lineHeight: Math.round(fontSize * 0.875 * 1.25),
38
40
  fontFamily,
39
- opacity: 0.9,
40
41
  },
41
42
  }),
42
43
  );
@@ -29,12 +29,14 @@ export const useToastVariantDefault = (): ToastStyles => {
29
29
  title: {
30
30
  color: colors.foreground,
31
31
  fontSize: fontSize,
32
+ lineHeight: Math.round(fontSize * 1.25),
32
33
  fontWeight: "600",
33
34
  fontFamily,
34
35
  },
35
36
  description: {
36
37
  color: colors.mutedForeground,
37
38
  fontSize: fontSize * 0.875,
39
+ lineHeight: Math.round(fontSize * 0.875 * 1.25),
38
40
  fontFamily,
39
41
  },
40
42
  }),
@@ -5,7 +5,7 @@ export const useToastVariantSuccess = (): ToastStyles => {
5
5
  return useThemedStyles(
6
6
  ({ colors, radius, fontFamily, fontSize }): ToastStyles => ({
7
7
  root: {
8
- backgroundColor: colors.success,
8
+ backgroundColor: colors.surface,
9
9
  borderWidth: 1,
10
10
  borderColor: colors.success,
11
11
  borderRadius: radius,
@@ -20,23 +20,24 @@ export const useToastVariantSuccess = (): ToastStyles => {
20
20
  gap: 4,
21
21
  },
22
22
  icon: {
23
- color: colors.foreground,
23
+ color: colors.success,
24
24
  size: 16,
25
25
  style: {
26
26
  marginTop: 2,
27
27
  },
28
28
  },
29
29
  title: {
30
- color: colors.foreground,
30
+ color: colors.success,
31
31
  fontSize: fontSize,
32
+ lineHeight: Math.round(fontSize * 1.25),
32
33
  fontWeight: "600",
33
34
  fontFamily,
34
35
  },
35
36
  description: {
36
- color: colors.foreground,
37
+ color: colors.mutedForeground,
37
38
  fontSize: fontSize * 0.875,
39
+ lineHeight: Math.round(fontSize * 0.875 * 1.25),
38
40
  fontFamily,
39
- opacity: 0.9,
40
41
  },
41
42
  }),
42
43
  );
@@ -1,15 +1,18 @@
1
1
  import React from "react";
2
2
  import { Text as RnText, StyleSheet, type TextProps as RnTextProps } from "react-native";
3
+ import type { Size } from "../../utils/size-scale";
3
4
  import { TypographyVariants } from "./variants";
4
5
 
5
6
  export interface TypographyProps extends RnTextProps {
6
7
  variant?: keyof typeof TypographyVariants;
8
+ size?: Size;
7
9
  }
8
10
 
9
11
  export function Typography(props: TypographyProps) {
10
- const variantStyles = TypographyVariants[props.variant ?? "body-md"]();
12
+ const { variant = "body", size = "md", ...rest } = props;
13
+ const variantStyles = TypographyVariants[variant](size);
11
14
 
12
15
  const combinedStyles = StyleSheet.flatten([variantStyles, props.style]);
13
16
 
14
- return <RnText {...props} style={combinedStyles} />;
17
+ return <RnText {...rest} style={combinedStyles} />;
15
18
  }
@@ -0,0 +1,26 @@
1
+ import { type TextStyle } from "react-native";
2
+ import type { Size } from "../../../utils/size-scale";
3
+ import { useThemedStyles } from "../../../utils/use-themed-styles";
4
+
5
+ const bodyScale: Record<Size, number> = {
6
+ sm: 0.875,
7
+ md: 1,
8
+ lg: 1.25,
9
+ };
10
+
11
+ export function useTextVariantBody(size: Size): TextStyle {
12
+ return useThemedStyles(
13
+ ({ colors, fontFamily, letterSpacing, fontSize }): TextStyle => {
14
+ const scale = bodyScale[size];
15
+ const scaledFontSize = fontSize * scale;
16
+ const lineHeight = Math.round(scaledFontSize * 1.25);
17
+ return {
18
+ color: colors.foreground,
19
+ fontSize: scaledFontSize,
20
+ lineHeight,
21
+ fontFamily,
22
+ letterSpacing,
23
+ };
24
+ },
25
+ );
26
+ }
@@ -0,0 +1,27 @@
1
+ import { type TextStyle } from "react-native";
2
+ import type { Size } from "../../../utils/size-scale";
3
+ import { useThemedStyles } from "../../../utils/use-themed-styles";
4
+
5
+ const headingScale: Record<Size, number> = {
6
+ sm: 1,
7
+ md: 1.25,
8
+ lg: 1.5,
9
+ };
10
+
11
+ export function useTextVariantHeading(size: Size): TextStyle {
12
+ return useThemedStyles(
13
+ ({ colors, fontFamily, letterSpacing, fontSize }): TextStyle => {
14
+ const scale = headingScale[size];
15
+ const scaledFontSize = fontSize * scale;
16
+ const lineHeight = Math.round(scaledFontSize * 1.25);
17
+ return {
18
+ color: colors.foreground,
19
+ fontSize: scaledFontSize,
20
+ lineHeight,
21
+ fontFamily,
22
+ letterSpacing,
23
+ fontWeight: "600",
24
+ };
25
+ },
26
+ );
27
+ }
@@ -1,15 +1,7 @@
1
- import { useTextVariantBodyLg } from "./body-lg";
2
- import { useTextVariantBodyMd } from "./body-md";
3
- import { useTextVariantBodySm } from "./body-sm";
4
- import { useTextVariantHeadingLg } from "./heading-lg";
5
- import { useTextVariantHeadingMd } from "./heading-md";
6
- import { useTextVariantHeadingSm } from "./heading-sm";
1
+ import { useTextVariantBody } from "./body";
2
+ import { useTextVariantHeading } from "./heading";
7
3
 
8
4
  export const TypographyVariants = {
9
- ["body-sm"]: useTextVariantBodySm,
10
- ["body-md"]: useTextVariantBodyMd,
11
- ["body-lg"]: useTextVariantBodyLg,
12
- ["heading-sm"]: useTextVariantHeadingSm,
13
- ["heading-md"]: useTextVariantHeadingMd,
14
- ["heading-lg"]: useTextVariantHeadingLg,
5
+ body: useTextVariantBody,
6
+ heading: useTextVariantHeading,
15
7
  };
@@ -0,0 +1,42 @@
1
+ import { useEffect, useState } from "react";
2
+ import { Keyboard, Platform } from "react-native";
3
+
4
+ function getCurrentKeyboardHeight(): number {
5
+ if (Platform.OS === "web") return 0;
6
+ return Keyboard.metrics()?.height ?? 0;
7
+ }
8
+
9
+ /**
10
+ * Tracks the current software keyboard height on native platforms.
11
+ * Returns 0 when the keyboard is hidden or on web.
12
+ *
13
+ * Initializes with the current keyboard height so it works correctly
14
+ * even when the keyboard is already visible at mount time.
15
+ */
16
+ export function useKeyboardHeight(): number {
17
+ const [keyboardHeight, setKeyboardHeight] = useState(getCurrentKeyboardHeight);
18
+
19
+ useEffect(() => {
20
+ if (Platform.OS === "web") return;
21
+
22
+ const showEvent =
23
+ Platform.OS === "ios" ? "keyboardWillShow" : "keyboardDidShow";
24
+ const hideEvent =
25
+ Platform.OS === "ios" ? "keyboardWillHide" : "keyboardDidHide";
26
+
27
+ const showSubscription = Keyboard.addListener(showEvent, (e) => {
28
+ setKeyboardHeight(e.endCoordinates.height);
29
+ });
30
+
31
+ const hideSubscription = Keyboard.addListener(hideEvent, () => {
32
+ setKeyboardHeight(0);
33
+ });
34
+
35
+ return () => {
36
+ showSubscription.remove();
37
+ hideSubscription.remove();
38
+ };
39
+ }, []);
40
+
41
+ return keyboardHeight;
42
+ }
@@ -9,6 +9,7 @@ import {
9
9
  import { usePortalOffset } from "../components/portal";
10
10
  import { useSafeAreaInsets, type SafeAreaInsets } from "../safe-area";
11
11
  import { useIsReactNavigationModal } from "./use-is-react-navigation-modal";
12
+ import { useKeyboardHeight } from "./use-keyboard-height";
12
13
 
13
14
  type UseRelativePositionArgs = Omit<GetContentStyleArgs, "dimensions" | "insets">;
14
15
 
@@ -25,9 +26,20 @@ export function useRelativePosition({
25
26
  const dimensions = useWindowDimensions();
26
27
  const insets = useSafeAreaInsets();
27
28
  const portalOffset = usePortalOffset();
29
+ const keyboardHeight = useKeyboardHeight();
28
30
 
29
31
  const isReactNavigationModal = useIsReactNavigationModal();
30
32
 
33
+ // When the keyboard is visible, treat its top edge as the effective
34
+ // bottom boundary so menus/popovers don't render behind it.
35
+ const effectiveInsets: SafeAreaInsets = useMemo(
36
+ () => ({
37
+ ...insets,
38
+ bottom: Math.max(insets.bottom, keyboardHeight),
39
+ }),
40
+ [insets, keyboardHeight],
41
+ );
42
+
31
43
  return useMemo(() => {
32
44
  const hasLayout =
33
45
  triggerPosition.width > 0 &&
@@ -61,7 +73,7 @@ export function useRelativePosition({
61
73
  preferredSide,
62
74
  triggerPosition: adjustedTriggerPosition,
63
75
  alignOffset,
64
- insets,
76
+ insets: effectiveInsets,
65
77
  sideOffset,
66
78
  dimensions,
67
79
  };
@@ -76,7 +88,9 @@ export function useRelativePosition({
76
88
  // Temporary fix to calculate portal content relative position correctly when rendered in a React Navigation modal.
77
89
  top: Platform.select({
78
90
  default: sidePosition.top,
79
- ios: isReactNavigationModal ? sidePosition.top + insets.top : sidePosition.top,
91
+ ios: isReactNavigationModal
92
+ ? sidePosition.top + effectiveInsets.top
93
+ : sidePosition.top,
80
94
  }),
81
95
  };
82
96
 
@@ -85,7 +99,7 @@ export function useRelativePosition({
85
99
  align,
86
100
  preferredSide,
87
101
  alignOffset,
88
- insets,
102
+ effectiveInsets,
89
103
  triggerPosition,
90
104
  contentLayout,
91
105
  dimensions.width,