@kanso-labs/react-native-kanso-ui 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 (253) hide show
  1. package/README.md +4 -3
  2. package/dist/autocomplete/index.js +15 -1
  3. package/dist/autocomplete/index.js.map +1 -1
  4. package/dist/badge/index.js +9 -70
  5. package/dist/badge/index.js.map +1 -1
  6. package/dist/button/group.d.ts +5 -0
  7. package/dist/button/group.js +115 -0
  8. package/dist/button/group.js.map +1 -0
  9. package/dist/button/index.d.ts +4 -1
  10. package/dist/button/index.js +45 -23
  11. package/dist/button/index.js.map +1 -1
  12. package/dist/button/palettes.d.ts +2 -0
  13. package/dist/button/slots.js +2 -1
  14. package/dist/button/slots.js.map +1 -1
  15. package/dist/calendar/index.js +351 -182
  16. package/dist/calendar/index.js.map +1 -1
  17. package/dist/calendar/styles.js +33 -2
  18. package/dist/calendar/styles.js.map +1 -1
  19. package/dist/carousel/arrangement.d.ts +5 -0
  20. package/dist/carousel/arrangement.js +123 -0
  21. package/dist/carousel/arrangement.js.map +1 -0
  22. package/dist/chequer/index.js +95 -0
  23. package/dist/chequer/index.js.map +1 -0
  24. package/dist/collection/index.d.ts +157 -0
  25. package/dist/collection/index.js +1331 -0
  26. package/dist/collection/index.js.map +1 -0
  27. package/dist/color-thumb/index.js +56 -0
  28. package/dist/color-thumb/index.js.map +1 -0
  29. package/dist/components/badge/index.d.ts +48 -0
  30. package/dist/components/badge/index.js +122 -0
  31. package/dist/components/badge/index.js.map +1 -0
  32. package/dist/{badge → components/badge}/styles.js +10 -6
  33. package/dist/components/badge/styles.js.map +1 -0
  34. package/dist/components/breadcrumbs/index.d.ts +66 -0
  35. package/dist/components/breadcrumbs/index.js +285 -0
  36. package/dist/components/breadcrumbs/index.js.map +1 -0
  37. package/dist/components/button/index.d.ts +4 -2
  38. package/dist/components/button/index.js +227 -188
  39. package/dist/components/button/index.js.map +1 -1
  40. package/dist/components/button-group/index.d.ts +87 -0
  41. package/dist/components/button-group/index.js +275 -0
  42. package/dist/components/button-group/index.js.map +1 -0
  43. package/dist/components/calendar/index.d.ts +11 -3
  44. package/dist/components/calendar/index.js +60 -45
  45. package/dist/components/calendar/index.js.map +1 -1
  46. package/dist/components/carousel/index.d.ts +72 -0
  47. package/dist/components/carousel/index.js +496 -0
  48. package/dist/components/carousel/index.js.map +1 -0
  49. package/dist/components/checkbox/index.d.ts +7 -1
  50. package/dist/components/checkbox/index.js +183 -138
  51. package/dist/components/checkbox/index.js.map +1 -1
  52. package/dist/components/checkbox-group/index.d.ts +92 -0
  53. package/dist/components/checkbox-group/index.js +306 -0
  54. package/dist/components/checkbox-group/index.js.map +1 -0
  55. package/dist/components/code/index.d.ts +25 -0
  56. package/dist/components/code/index.js +87 -0
  57. package/dist/components/code/index.js.map +1 -0
  58. package/dist/components/color-area/index.d.ts +85 -0
  59. package/dist/components/color-area/index.js +630 -0
  60. package/dist/components/color-area/index.js.map +1 -0
  61. package/dist/components/color-field/index.d.ts +144 -0
  62. package/dist/components/color-field/index.js +516 -0
  63. package/dist/components/color-field/index.js.map +1 -0
  64. package/dist/components/color-picker/index.d.ts +74 -0
  65. package/dist/components/color-picker/index.js +317 -0
  66. package/dist/components/color-picker/index.js.map +1 -0
  67. package/dist/components/color-slider/index.d.ts +82 -0
  68. package/dist/components/color-slider/index.js +456 -0
  69. package/dist/components/color-slider/index.js.map +1 -0
  70. package/dist/components/color-swatch/index.d.ts +46 -0
  71. package/dist/components/color-swatch/index.js +127 -0
  72. package/dist/components/color-swatch/index.js.map +1 -0
  73. package/dist/components/color-swatch-picker/index.d.ts +81 -0
  74. package/dist/components/color-swatch-picker/index.js +287 -0
  75. package/dist/components/color-swatch-picker/index.js.map +1 -0
  76. package/dist/components/color-wheel/index.d.ts +71 -0
  77. package/dist/components/color-wheel/index.js +407 -0
  78. package/dist/components/color-wheel/index.js.map +1 -0
  79. package/dist/components/combo-box/index.d.ts +193 -0
  80. package/dist/components/combo-box/index.js +616 -0
  81. package/dist/components/combo-box/index.js.map +1 -0
  82. package/dist/components/container/index.d.ts +47 -0
  83. package/dist/components/container/index.js +85 -0
  84. package/dist/components/container/index.js.map +1 -0
  85. package/dist/components/date-field/index.d.ts +120 -0
  86. package/dist/components/date-field/index.js +111 -0
  87. package/dist/components/date-field/index.js.map +1 -0
  88. package/dist/components/date-picker/index.d.ts +130 -0
  89. package/dist/components/date-picker/index.js +310 -0
  90. package/dist/components/date-picker/index.js.map +1 -0
  91. package/dist/components/date-range-picker/index.d.ts +139 -0
  92. package/dist/components/date-range-picker/index.js +421 -0
  93. package/dist/components/date-range-picker/index.js.map +1 -0
  94. package/dist/components/disclosure/index.d.ts +94 -0
  95. package/dist/components/disclosure/index.js +365 -0
  96. package/dist/components/disclosure/index.js.map +1 -0
  97. package/dist/components/disclosure-group/index.d.ts +61 -0
  98. package/dist/components/disclosure-group/index.js +100 -0
  99. package/dist/components/disclosure-group/index.js.map +1 -0
  100. package/dist/components/drop-zone/index.d.ts +113 -0
  101. package/dist/components/drop-zone/index.js +304 -0
  102. package/dist/components/drop-zone/index.js.map +1 -0
  103. package/dist/components/fab/index.d.ts +80 -0
  104. package/dist/components/fab/index.js +246 -0
  105. package/dist/components/fab/index.js.map +1 -0
  106. package/dist/components/fab-menu/index.d.ts +120 -0
  107. package/dist/components/fab-menu/index.js +640 -0
  108. package/dist/components/fab-menu/index.js.map +1 -0
  109. package/dist/components/feed/index.d.ts +57 -0
  110. package/dist/components/feed/index.js +167 -0
  111. package/dist/components/feed/index.js.map +1 -0
  112. package/dist/components/form/index.d.ts +3 -2
  113. package/dist/components/form/index.js.map +1 -1
  114. package/dist/components/icon-button/index.d.ts +4 -2
  115. package/dist/components/icon-button/index.js +204 -171
  116. package/dist/components/icon-button/index.js.map +1 -1
  117. package/dist/components/keycap/index.d.ts +27 -0
  118. package/dist/components/keycap/index.js +136 -0
  119. package/dist/components/keycap/index.js.map +1 -0
  120. package/dist/components/list/index.d.ts +15 -158
  121. package/dist/components/list/index.js +21 -1047
  122. package/dist/components/list/index.js.map +1 -1
  123. package/dist/components/list-box/index.d.ts +73 -0
  124. package/dist/components/list-box/index.js +82 -0
  125. package/dist/components/list-box/index.js.map +1 -0
  126. package/dist/components/loading-indicator/index.d.ts +32 -0
  127. package/dist/components/loading-indicator/index.js +174 -0
  128. package/dist/components/loading-indicator/index.js.map +1 -0
  129. package/dist/components/menu/index.js +1 -1
  130. package/dist/components/navigation-tree/index.d.ts +117 -0
  131. package/dist/components/navigation-tree/index.js +135 -0
  132. package/dist/components/navigation-tree/index.js.map +1 -0
  133. package/dist/components/number-field/index.js +132 -143
  134. package/dist/components/number-field/index.js.map +1 -1
  135. package/dist/components/range-calendar/index.d.ts +69 -0
  136. package/dist/components/range-calendar/index.js +144 -0
  137. package/dist/components/range-calendar/index.js.map +1 -0
  138. package/dist/components/search-view/index.d.ts +78 -0
  139. package/dist/components/search-view/index.js +570 -0
  140. package/dist/components/search-view/index.js.map +1 -0
  141. package/dist/components/select/index.d.ts +152 -0
  142. package/dist/components/select/index.js +419 -0
  143. package/dist/components/select/index.js.map +1 -0
  144. package/dist/components/separator/index.d.ts +3 -2
  145. package/dist/components/separator/index.js +29 -26
  146. package/dist/components/separator/index.js.map +1 -1
  147. package/dist/components/slider/index.d.ts +111 -0
  148. package/dist/components/slider/index.js +673 -0
  149. package/dist/components/slider/index.js.map +1 -0
  150. package/dist/components/split-button/index.d.ts +77 -0
  151. package/dist/components/split-button/index.js +354 -0
  152. package/dist/components/split-button/index.js.map +1 -0
  153. package/dist/components/supporting-pane/index.d.ts +44 -0
  154. package/dist/components/supporting-pane/index.js +109 -0
  155. package/dist/components/supporting-pane/index.js.map +1 -0
  156. package/dist/components/tabs/index.d.ts +196 -0
  157. package/dist/components/tabs/index.js +1137 -0
  158. package/dist/components/tabs/index.js.map +1 -0
  159. package/dist/components/text/index.d.ts +1 -1
  160. package/dist/components/text/index.js +49 -21
  161. package/dist/components/text/index.js.map +1 -1
  162. package/dist/components/text-area/index.d.ts +145 -0
  163. package/dist/components/text-area/index.js +231 -0
  164. package/dist/components/text-area/index.js.map +1 -0
  165. package/dist/components/time-field/index.d.ts +43 -0
  166. package/dist/components/time-field/index.js +107 -0
  167. package/dist/components/time-field/index.js.map +1 -0
  168. package/dist/components/time-picker/index.d.ts +65 -0
  169. package/dist/components/time-picker/index.js +1168 -0
  170. package/dist/components/time-picker/index.js.map +1 -0
  171. package/dist/components/toolbar/index.d.ts +53 -0
  172. package/dist/components/toolbar/index.js +185 -0
  173. package/dist/components/toolbar/index.js.map +1 -0
  174. package/dist/components/tooltip/index.d.ts +101 -0
  175. package/dist/components/tooltip/index.js +223 -0
  176. package/dist/components/tooltip/index.js.map +1 -0
  177. package/dist/components/tree/index.d.ts +112 -0
  178. package/dist/components/tree/index.js +157 -0
  179. package/dist/components/tree/index.js.map +1 -0
  180. package/dist/control/group.js +23 -0
  181. package/dist/control/group.js.map +1 -0
  182. package/dist/disclosure/chevron.js +75 -0
  183. package/dist/disclosure/chevron.js.map +1 -0
  184. package/dist/disclosure/index.js +7 -0
  185. package/dist/disclosure/index.js.map +1 -0
  186. package/dist/drop/index.d.ts +54 -0
  187. package/dist/drop/index.js +161 -0
  188. package/dist/drop/index.js.map +1 -0
  189. package/dist/fab/index.d.ts +19 -0
  190. package/dist/fab/index.js +147 -0
  191. package/dist/fab/index.js.map +1 -0
  192. package/dist/field/chevron.js +74 -0
  193. package/dist/field/chevron.js.map +1 -0
  194. package/dist/field/index.d.ts +2 -1
  195. package/dist/field/index.js +350 -153
  196. package/dist/field/index.js.map +1 -1
  197. package/dist/field/styles.js +27 -0
  198. package/dist/field/styles.js.map +1 -1
  199. package/dist/files/index.d.ts +18 -0
  200. package/dist/files/index.js +107 -0
  201. package/dist/files/index.js.map +1 -0
  202. package/dist/form/index.d.ts +6 -4
  203. package/dist/form/index.js +64 -85
  204. package/dist/form/index.js.map +1 -1
  205. package/dist/glyphs/index.js +92 -1
  206. package/dist/glyphs/index.js.map +1 -1
  207. package/dist/i18n/index.js +20 -1
  208. package/dist/i18n/index.js.map +1 -1
  209. package/dist/i18n/messages.js +1394 -34
  210. package/dist/i18n/messages.js.map +1 -1
  211. package/dist/index.d.ts +51 -6
  212. package/dist/index.js +47 -4
  213. package/dist/indicator/paths.js +23 -1
  214. package/dist/indicator/paths.js.map +1 -1
  215. package/dist/modal/index.js +96 -68
  216. package/dist/modal/index.js.map +1 -1
  217. package/dist/navigation/index.js +8 -5
  218. package/dist/navigation/index.js.map +1 -1
  219. package/dist/number/keyboard.js +16 -0
  220. package/dist/number/keyboard.js.map +1 -0
  221. package/dist/overlay/anchored.js +68 -38
  222. package/dist/overlay/anchored.js.map +1 -1
  223. package/dist/overlay/keyboard.js +57 -0
  224. package/dist/overlay/keyboard.js.map +1 -0
  225. package/dist/overlay/panel.js +173 -19
  226. package/dist/overlay/panel.js.map +1 -1
  227. package/dist/overlay/placement.js +16 -2
  228. package/dist/overlay/placement.js.map +1 -1
  229. package/dist/picker/index.js +322 -0
  230. package/dist/picker/index.js.map +1 -0
  231. package/dist/press/index.d.ts +2 -0
  232. package/dist/press/index.js +102 -100
  233. package/dist/press/index.js.map +1 -1
  234. package/dist/row/index.js +77 -69
  235. package/dist/row/index.js.map +1 -1
  236. package/dist/row/styles.js +13 -2
  237. package/dist/row/styles.js.map +1 -1
  238. package/dist/segments/field.js +277 -0
  239. package/dist/segments/field.js.map +1 -0
  240. package/dist/segments/index.js +574 -0
  241. package/dist/segments/index.js.map +1 -0
  242. package/dist/segments/styles.js +24 -0
  243. package/dist/segments/styles.js.map +1 -0
  244. package/dist/separator/index.js +7 -0
  245. package/dist/separator/index.js.map +1 -0
  246. package/dist/slider/index.js +145 -0
  247. package/dist/slider/index.js.map +1 -0
  248. package/dist/swatch/index.js +56 -0
  249. package/dist/swatch/index.js.map +1 -0
  250. package/dist/typography/size.js +14 -0
  251. package/dist/typography/size.js.map +1 -0
  252. package/package.json +11 -2
  253. package/dist/badge/styles.js.map +0 -1
@@ -0,0 +1,223 @@
1
+ import { useTheme } from "../../theme/scope.js";
2
+ import { composeStyles, themedStyles } from "../../theme/styles.js";
3
+ import { useTypeRole } from "../../typography/roles.js";
4
+ import { ButtonTooltipContext } from "../../button/slots.js";
5
+ import { PANEL_ORIGINS, usePanelMotion } from "../../overlay/panel.js";
6
+ import { Overlay } from "../../overlay/host.js";
7
+ import { useAnchoredPlacement } from "../../overlay/anchored.js";
8
+ import { c } from "react/compiler-runtime";
9
+ import { StyleSheet, Text } from "react-native";
10
+ import Animated from "react-native-reanimated";
11
+ import { useRef, useState } from "react";
12
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
13
+ import { useTooltipTriggerState } from "react-stately/useTooltipTriggerState";
14
+ //#region src/components/tooltip/index.tsx
15
+ const DEFAULT_DELAY = 1500;
16
+ const DEFAULT_CLOSE_DELAY = 500;
17
+ const MAX_WIDTH = 320;
18
+ const stylesOf = themedStyles(({ colors, radii, spacing }) => StyleSheet.create({
19
+ label: { color: colors.inverseOnSurface },
20
+ surface: {
21
+ backgroundColor: colors.inverseSurface,
22
+ borderRadius: radii.xs,
23
+ maxWidth: MAX_WIDTH,
24
+ paddingHorizontal: spacing.sm,
25
+ paddingVertical: spacing.xs,
26
+ pointerEvents: "none"
27
+ }
28
+ }));
29
+ /**
30
+ * A label for the button it wraps, the tooltips spec page's plain tooltip,
31
+ * shown while a press is held on the button or a pointer rests on it.
32
+ *
33
+ * ```tsx
34
+ * <Tooltip label="Search">
35
+ * <IconButton aria-label="Search">
36
+ * <SearchGlyph />
37
+ * </IconButton>
38
+ * </Tooltip>
39
+ * ```
40
+ *
41
+ * Pass `isOpen` with `onOpenChange` to hold the open state, or `defaultOpen`
42
+ * to let it keep its own, and `delay` and `closeDelay` for how long it waits
43
+ * before it opens and closes. What it says has to repeat what the button
44
+ * already means, since a screen reader hears it as the button's hint and
45
+ * touch only shows it to someone who holds a press: anything with a button
46
+ * in it, or worth reading twice, is a `Popover`.
47
+ *
48
+ * `style`, `ref` and `testID` land on the tooltip itself.
49
+ */
50
+ function Tooltip(t0) {
51
+ const $ = c(30);
52
+ const { align: t1, alignOffset, children, closeDelay: t2, defaultOpen, delay: t3, isDisabled: t4, isOpen, label, onOpenChange, ref, shouldCloseOnPress: t5, side: t6, sideOffset, style, testID, trigger } = t0;
53
+ const align = t1 === void 0 ? "center" : t1;
54
+ const closeDelay = t2 === void 0 ? DEFAULT_CLOSE_DELAY : t2;
55
+ const delay = t3 === void 0 ? DEFAULT_DELAY : t3;
56
+ const isDisabled = t4 === void 0 ? false : t4;
57
+ const shouldCloseOnPress = t5 === void 0 ? true : t5;
58
+ const side = t6 === void 0 ? "top" : t6;
59
+ let t7;
60
+ if ($[0] !== closeDelay || $[1] !== defaultOpen || $[2] !== delay || $[3] !== isOpen || $[4] !== onOpenChange) {
61
+ t7 = {
62
+ closeDelay,
63
+ defaultOpen,
64
+ delay,
65
+ isOpen,
66
+ onOpenChange
67
+ };
68
+ $[0] = closeDelay;
69
+ $[1] = defaultOpen;
70
+ $[2] = delay;
71
+ $[3] = isOpen;
72
+ $[4] = onOpenChange;
73
+ $[5] = t7;
74
+ } else t7 = $[5];
75
+ const state = useTooltipTriggerState(t7);
76
+ const anchor = useRef(null);
77
+ const hovered = useRef(false);
78
+ const [present, setPresent] = useState(state.isOpen);
79
+ const pointer = trigger !== "focus";
80
+ let t8;
81
+ if ($[6] !== delay || $[7] !== isDisabled || $[8] !== label || $[9] !== pointer || $[10] !== shouldCloseOnPress || $[11] !== state) {
82
+ t8 = isDisabled ? null : {
83
+ delayLongPress: delay,
84
+ hint: label,
85
+ onHoverIn: pointer ? () => {
86
+ hovered.current = true;
87
+ state.open(false);
88
+ } : void 0,
89
+ onHoverOut: pointer ? () => {
90
+ hovered.current = false;
91
+ state.close(false);
92
+ } : void 0,
93
+ onLongPress: () => {
94
+ state.open(true);
95
+ },
96
+ onPressIn: shouldCloseOnPress ? () => {
97
+ state.close(true);
98
+ } : void 0,
99
+ onPressOut: () => {
100
+ if (!hovered.current) state.close(false);
101
+ },
102
+ ref: anchor
103
+ };
104
+ $[6] = delay;
105
+ $[7] = isDisabled;
106
+ $[8] = label;
107
+ $[9] = pointer;
108
+ $[10] = shouldCloseOnPress;
109
+ $[11] = state;
110
+ $[12] = t8;
111
+ } else t8 = $[12];
112
+ const described = t8;
113
+ if (state.isOpen && !present) setPresent(true);
114
+ let t9;
115
+ if ($[13] !== children || $[14] !== described) {
116
+ t9 = /* @__PURE__ */ jsx(ButtonTooltipContext, {
117
+ value: described,
118
+ children
119
+ });
120
+ $[13] = children;
121
+ $[14] = described;
122
+ $[15] = t9;
123
+ } else t9 = $[15];
124
+ let t10;
125
+ if ($[16] !== align || $[17] !== alignOffset || $[18] !== label || $[19] !== present || $[20] !== ref || $[21] !== side || $[22] !== sideOffset || $[23] !== state.isOpen || $[24] !== style || $[25] !== testID) {
126
+ t10 = present ? /* @__PURE__ */ jsx(Overlay, { children: /* @__PURE__ */ jsx(TooltipSurface, {
127
+ align,
128
+ alignOffset,
129
+ anchor,
130
+ isOpen: state.isOpen,
131
+ label,
132
+ ref,
133
+ setPresent,
134
+ side,
135
+ sideOffset,
136
+ style,
137
+ testID
138
+ }) }) : null;
139
+ $[16] = align;
140
+ $[17] = alignOffset;
141
+ $[18] = label;
142
+ $[19] = present;
143
+ $[20] = ref;
144
+ $[21] = side;
145
+ $[22] = sideOffset;
146
+ $[23] = state.isOpen;
147
+ $[24] = style;
148
+ $[25] = testID;
149
+ $[26] = t10;
150
+ } else t10 = $[26];
151
+ let t11;
152
+ if ($[27] !== t10 || $[28] !== t9) {
153
+ t11 = /* @__PURE__ */ jsxs(Fragment$1, { children: [t9, t10] });
154
+ $[27] = t10;
155
+ $[28] = t9;
156
+ $[29] = t11;
157
+ } else t11 = $[29];
158
+ return t11;
159
+ }
160
+ function TooltipSurface(t0) {
161
+ const $ = c(17);
162
+ const { align, alignOffset, anchor, isOpen, label, ref, setPresent, side, sideOffset, style, testID } = t0;
163
+ const styles = stylesOf(useTheme());
164
+ const role = useTypeRole("bodySmall");
165
+ let t1;
166
+ if ($[0] !== align || $[1] !== alignOffset || $[2] !== anchor || $[3] !== side || $[4] !== sideOffset) {
167
+ t1 = {
168
+ align,
169
+ alignOffset,
170
+ anchor,
171
+ side,
172
+ sideOffset
173
+ };
174
+ $[0] = align;
175
+ $[1] = alignOffset;
176
+ $[2] = anchor;
177
+ $[3] = side;
178
+ $[4] = sideOffset;
179
+ $[5] = t1;
180
+ } else t1 = $[5];
181
+ const placement = useAnchoredPlacement(t1);
182
+ const motion = usePanelMotion(isOpen, placement.placed, setPresent);
183
+ const t2 = Animated;
184
+ const t3 = true;
185
+ const t4 = placement.onLayout;
186
+ const t5 = composeStyles(styles.surface, placement.style, { transformOrigin: PANEL_ORIGINS[placement.side] }, motion, style);
187
+ const T0 = Text;
188
+ const t6 = composeStyles(role, styles.label);
189
+ let t7;
190
+ if ($[6] !== T0 || $[7] !== label || $[8] !== t6) {
191
+ t7 = /* @__PURE__ */ jsx(T0, {
192
+ style: t6,
193
+ children: label
194
+ });
195
+ $[6] = T0;
196
+ $[7] = label;
197
+ $[8] = t6;
198
+ $[9] = t7;
199
+ } else t7 = $[9];
200
+ let t8;
201
+ if ($[10] !== placement.onLayout || $[11] !== ref || $[12] !== t2.View || $[13] !== t5 || $[14] !== t7 || $[15] !== testID) {
202
+ t8 = /* @__PURE__ */ jsx(t2.View, {
203
+ "aria-hidden": t3,
204
+ onLayout: t4,
205
+ ref,
206
+ style: t5,
207
+ testID,
208
+ children: t7
209
+ });
210
+ $[10] = placement.onLayout;
211
+ $[11] = ref;
212
+ $[12] = t2.View;
213
+ $[13] = t5;
214
+ $[14] = t7;
215
+ $[15] = testID;
216
+ $[16] = t8;
217
+ } else t8 = $[16];
218
+ return t8;
219
+ }
220
+ //#endregion
221
+ export { Tooltip };
222
+
223
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["ReactNode","Ref","RefObject","HostInstance","StyleProp","TextStyle","ViewStyle","AnimatedStyle","useMemo","useRef","useState","Text","NativeText","StyleSheet","Animated","useTooltipTriggerState","ButtonTooltip","OverlayAlign","OverlaySide","ResolvedTheme","ButtonTooltipContext","Overlay","useAnchoredPlacement","PANEL_ORIGINS","usePanelMotion","useTheme","composeStyles","themedStyles","useTypeRole","DEFAULT_DELAY","DEFAULT_CLOSE_DELAY","MAX_WIDTH","stylesOf","colors","radii","spacing","create","label","color","inverseOnSurface","surface","backgroundColor","inverseSurface","borderRadius","xs","maxWidth","paddingHorizontal","sm","paddingVertical","pointerEvents","SurfaceProps","Pick","TooltipProps","anchor","isOpen","setPresent","present","testID","TooltipAlign","align","alignOffset","children","closeDelay","defaultOpen","delay","isDisabled","onOpenChange","ref","shouldCloseOnPress","side","TooltipSide","sideOffset","style","trigger","Tooltip","t0","$","_c","t1","t2","t3","t4","t5","t6","undefined","t7","state","hovered","pointer","t8","delayLongPress","hint","onHoverIn","current","open","onHoverOut","close","onLongPress","onPressIn","onPressOut","described","t9","t10","t11","TooltipSurface","styles","role","placement","motion","placed","onLayout","transformOrigin","T0","View","_c","NativeText"],"sources":["../../../src/components/tooltip/index.tsx"],"sourcesContent":["import type { ReactNode, Ref, RefObject } from 'react'\nimport type {\n HostInstance,\n StyleProp,\n TextStyle,\n ViewStyle,\n} from 'react-native'\nimport type { AnimatedStyle } from 'react-native-reanimated'\n\nimport { useMemo, useRef, useState } from 'react'\nimport { Text as NativeText, StyleSheet } from 'react-native'\nimport Animated from 'react-native-reanimated'\nimport { useTooltipTriggerState } from 'react-stately/useTooltipTriggerState'\n\nimport type { ButtonTooltip } from '../../button/slots'\nimport type { OverlayAlign, OverlaySide } from '../../overlay'\nimport type { ResolvedTheme } from '../../theme/scope'\n\nimport { ButtonTooltipContext } from '../../button/slots'\nimport { Overlay, useAnchoredPlacement } from '../../overlay'\nimport { PANEL_ORIGINS, usePanelMotion } from '../../overlay/panel'\nimport { useTheme } from '../../theme/scope'\nimport { composeStyles, themedStyles } from '../../theme/styles'\nimport { useTypeRole } from '../../typography/roles'\n\n// kanso-ui's Tooltip, the tooltips page's plain tooltip: a container on\n// inverse surface with 8dp of padding at the ends and 4dp above and below,\n// holding a line of supporting text in body small on inverse on surface, so\n// one line is the page's 24dp. The page names a shape token without giving\n// its value, so it takes the extra-small corner, as web's does, and it lies\n// flat: the plain tooltip's tokens give no elevation. A long label wraps at\n// 320dp rather than running the width of the window.\n//\n// **It is placed by src/overlay's anchored placement**, in the overlay host\n// above the screen: on `side`, `top` unless told otherwise, lined up by\n// `align`, flipped to the opposite side at the edge of the window and kept\n// inside the safe area. It grows and fades in and out from the edge facing\n// the trigger as every anchored panel does, through src/overlay's panel\n// motion. It takes no press and draws no layer under it, so the screen stays\n// usable while it shows.\n//\n// **Touch has no hover, so a press held on the trigger for `delay` opens it**,\n// as Android's own tooltips open on a long press, and the press then ends\n// without pressing the trigger. A pointer resting on the trigger for `delay`\n// opens it as well, an iPad's or an Android mouse's. It closes `closeDelay`\n// after the pointer leaves, or after a held press ends while no pointer is on\n// the trigger, and at once on a press of the trigger unless\n// `shouldCloseOnPress` is off. `trigger=\"focus\"` leaves the pointer out, so\n// only the held press opens it. The state is React Stately's, the one web's\n// React Aria keeps, so once one tooltip has shown, the next a pointer rests on\n// opens at once, and only one shows at a time.\n//\n// **A screen reader never reaches the surface.** The label is the trigger's\n// accessibility hint instead, read after its name, which is what web's\n// `aria-describedby` gives a reader, and why the label is text.\n//\n// **The trigger is a Button, an IconButton or a FAB placed directly inside\n// it**, which takes the tooltip through src/button's slots.ts, as a\n// popover's trigger takes the popover. A tooltip and a popover or menu can\n// wrap the same button in either order.\n\n// How long a pointer rests on the trigger, or a press is held on it, before\n// the tooltip opens, and how long it stays once the pointer or the press has\n// gone, React Aria's own defaults, which web's takes.\nconst DEFAULT_DELAY = 1500\nconst DEFAULT_CLOSE_DELAY = 500\n\n// The widest it draws, web's cap.\nconst MAX_WIDTH = 320\n\nconst stylesOf = themedStyles(({ colors, radii, spacing }: ResolvedTheme) =>\n StyleSheet.create({\n label: {\n color: colors.inverseOnSurface,\n },\n surface: {\n backgroundColor: colors.inverseSurface,\n borderRadius: radii.xs,\n maxWidth: MAX_WIDTH,\n paddingHorizontal: spacing.sm,\n paddingVertical: spacing.xs,\n pointerEvents: 'none',\n },\n }),\n)\n\ntype SurfaceProps = Pick<\n TooltipProps,\n 'align' | 'alignOffset' | 'label' | 'ref' | 'side' | 'sideOffset' | 'style'\n> & {\n readonly anchor: RefObject<HostInstance | null>\n readonly isOpen: boolean\n readonly setPresent: (present: boolean) => void\n readonly testID: string | undefined\n}\n\n/** Where the tooltip sits along the side it opens on. */\ntype TooltipAlign = OverlayAlign\n\ntype TooltipProps = {\n /**\n * Where the tooltip sits along the side it opens on. On `top` and\n * `bottom`, `start` and `end` follow a right-to-left layout.\n * @default 'center'\n */\n readonly align?: TooltipAlign\n /** Moves the tooltip along that side, in dp: right or down when positive. */\n readonly alignOffset?: number\n /**\n * The button the tooltip describes, and nothing else: a `Button`,\n * `IconButton` or `Fab`, or a `Popover` or `Menu` whose trigger is one.\n */\n readonly children?: ReactNode\n /**\n * How long the tooltip stays once the pointer has left the trigger, or a\n * held press has ended, in milliseconds.\n * @default 500\n */\n readonly closeDelay?: number\n /** Whether the tooltip starts open, when it keeps its own state. */\n readonly defaultOpen?: boolean\n /**\n * How long a pointer rests on the trigger, or a press is held on it,\n * before the tooltip opens, in milliseconds.\n * @default 1500\n */\n readonly delay?: number\n /**\n * Keeps the tooltip from opening, and its label off the trigger's hint.\n * @default false\n */\n readonly isDisabled?: boolean\n /** Whether the tooltip is open, when the call site holds the state. */\n readonly isOpen?: boolean\n /**\n * What the tooltip says. Text, since it is also the trigger's\n * accessibility hint, which a screen reader reads after its name.\n */\n readonly label: string\n /** Called with the new state as the tooltip opens or closes. */\n readonly onOpenChange?: (isOpen: boolean) => void\n readonly ref?: Ref<HostInstance>\n /**\n * Whether a press of the trigger closes the tooltip.\n * @default true\n */\n readonly shouldCloseOnPress?: boolean\n /**\n * Which side of the trigger the tooltip opens on. It flips to the opposite\n * side when there is no room.\n * @default 'top'\n */\n readonly side?: TooltipSide\n /**\n * The gap between the trigger and the tooltip, in dp.\n * @default spacing.sm\n */\n readonly sideOffset?: number\n readonly style?: StyleProp<ViewStyle>\n readonly testID?: string\n /**\n * `focus` leaves a pointer resting on the trigger out, so only a press\n * held on it opens the tooltip.\n */\n readonly trigger?: 'focus'\n}\n\n/** Which side of the trigger the tooltip opens on. */\ntype TooltipSide = OverlaySide\n\n/**\n * A label for the button it wraps, the tooltips spec page's plain tooltip,\n * shown while a press is held on the button or a pointer rests on it.\n *\n * ```tsx\n * <Tooltip label=\"Search\">\n * <IconButton aria-label=\"Search\">\n * <SearchGlyph />\n * </IconButton>\n * </Tooltip>\n * ```\n *\n * Pass `isOpen` with `onOpenChange` to hold the open state, or `defaultOpen`\n * to let it keep its own, and `delay` and `closeDelay` for how long it waits\n * before it opens and closes. What it says has to repeat what the button\n * already means, since a screen reader hears it as the button's hint and\n * touch only shows it to someone who holds a press: anything with a button\n * in it, or worth reading twice, is a `Popover`.\n *\n * `style`, `ref` and `testID` land on the tooltip itself.\n */\nfunction Tooltip({\n align = 'center',\n alignOffset,\n children,\n closeDelay = DEFAULT_CLOSE_DELAY,\n defaultOpen,\n delay = DEFAULT_DELAY,\n isDisabled = false,\n isOpen,\n label,\n onOpenChange,\n ref,\n shouldCloseOnPress = true,\n side = 'top',\n sideOffset,\n style,\n testID,\n trigger,\n}: TooltipProps) {\n const state = useTooltipTriggerState({\n closeDelay,\n defaultOpen,\n delay,\n isOpen,\n onOpenChange,\n })\n const anchor = useRef<HostInstance>(null)\n const hovered = useRef(false)\n const [present, setPresent] = useState(state.isOpen)\n const pointer = trigger !== 'focus'\n // What the trigger takes on: the pointer resting on it and leaving it, the\n // held press that opens the tooltip, and a press that closes it, at once as\n // it starts and after `closeDelay` as a held one ends, unless a pointer\n // still rests on the trigger, which keeps it until the pointer leaves.\n const described = useMemo<ButtonTooltip | null>(\n () =>\n isDisabled\n ? null\n : {\n delayLongPress: delay,\n hint: label,\n onHoverIn: pointer\n ? () => {\n hovered.current = true\n state.open(false)\n }\n : undefined,\n onHoverOut: pointer\n ? () => {\n hovered.current = false\n state.close(false)\n }\n : undefined,\n onLongPress: () => {\n state.open(true)\n },\n onPressIn: shouldCloseOnPress\n ? () => {\n state.close(true)\n }\n : undefined,\n onPressOut: () => {\n if (!hovered.current) {\n state.close(false)\n }\n },\n ref: anchor,\n },\n [delay, isDisabled, label, pointer, shouldCloseOnPress, state],\n )\n\n // Mounted the moment it opens, and kept until its exit has run.\n if (state.isOpen && !present) {\n setPresent(true)\n }\n\n return (\n <>\n <ButtonTooltipContext value={described}>{children}</ButtonTooltipContext>\n {present ? (\n <Overlay>\n <TooltipSurface\n align={align}\n alignOffset={alignOffset}\n anchor={anchor}\n isOpen={state.isOpen}\n label={label}\n ref={ref}\n setPresent={setPresent}\n side={side}\n sideOffset={sideOffset}\n style={style}\n testID={testID}\n />\n </Overlay>\n ) : null}\n </>\n )\n}\n\n// The tooltip itself, drawn in the overlay host and placed beside the\n// trigger once it has reported its size.\nfunction TooltipSurface({\n align,\n alignOffset,\n anchor,\n isOpen,\n label,\n ref,\n setPresent,\n side,\n sideOffset,\n style,\n testID,\n}: SurfaceProps) {\n const styles = stylesOf(useTheme())\n const role = useTypeRole('bodySmall')\n const placement = useAnchoredPlacement({\n align,\n alignOffset,\n anchor,\n side,\n sideOffset,\n })\n const motion = usePanelMotion(isOpen, placement.placed, setPresent)\n\n return (\n <Animated.View\n aria-hidden\n onLayout={placement.onLayout}\n ref={ref}\n style={composeStyles<AnimatedStyle<ViewStyle>>(\n styles.surface,\n placement.style,\n { transformOrigin: PANEL_ORIGINS[placement.side] },\n motion,\n style,\n )}\n testID={testID}\n >\n <NativeText style={composeStyles<TextStyle>(role, styles.label)}>\n {label}\n </NativeText>\n </Animated.View>\n )\n}\n\nexport { Tooltip }\nexport type { TooltipAlign, TooltipProps, TooltipSide }\n"],"mappings":"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"}
@@ -0,0 +1,112 @@
1
+ import { CollectionLoadMoreProps, CollectionProps, CollectionRowProps, CollectionSectionProps, loaderNode, sectionNode } from "../../collection/index.js";
2
+ import { ReactNode } from "react";
3
+ import { Key } from "react-stately";
4
+ //#region src/components/tree/index.d.ts
5
+ type TreeItemProps = Omit<CollectionRowProps, 'children' | 'overline' | 'textValue'> & TreeItemText & {
6
+ /** The rows nested under this one, as further `Tree.Item` parts. */
7
+ readonly children?: ReactNode;
8
+ };
9
+ type TreeItemText = {
10
+ /** The row's headline, as something other than a plain string. */
11
+ readonly headline?: ReactNode;
12
+ /** The row's text, which a headline that is not a string cannot give. */
13
+ readonly textValue: string;
14
+ } | {
15
+ /** The row's headline, the one thing it is mostly about. */
16
+ readonly headline: string;
17
+ /** The row's text. Defaults to the headline. */
18
+ readonly textValue?: string;
19
+ };
20
+ type TreeLoadMoreProps = CollectionLoadMoreProps;
21
+ type TreeProps<T extends object = object> = CollectionProps<T> & {
22
+ /** The keys of the rows open at first, when the tree keeps its own. */
23
+ readonly defaultExpandedKeys?: Iterable<Key>;
24
+ /**
25
+ * The keys of the open rows, for a call site holding them itself with
26
+ * `onExpandedChange`.
27
+ */
28
+ readonly expandedKeys?: Iterable<Key>;
29
+ /** Called with the keys of the open rows whenever a row opens or closes. */
30
+ readonly onExpandedChange?: (keys: Set<Key>) => void;
31
+ };
32
+ type TreeSectionProps = CollectionSectionProps;
33
+ /**
34
+ * A list whose rows nest. Which rows are open is React Stately's, as web's
35
+ * is React Aria's: pass `expandedKeys` with `onExpandedChange` to control
36
+ * it, or `defaultExpandedKeys` to let it keep its own. Selection is React
37
+ * Stately's too: set `selectionMode` to `single` or `multiple`, and a tree
38
+ * that selects draws a checkbox on every row.
39
+ *
40
+ * ```tsx
41
+ * <Tree aria-label="Label">
42
+ * <Tree.Item headline="First item" id="first">
43
+ * <Tree.Item headline="Second item" id="second" />
44
+ * </Tree.Item>
45
+ * </Tree>
46
+ * ```
47
+ *
48
+ * Each row is the row every list here draws, indented by its depth, with a
49
+ * chevron on the rows that have rows under them. Composed from parts,
50
+ * `Tree.Item`, `Tree.Section` and `Tree.LoadMore`, which the tree draws from
51
+ * their props, so none of them renders anything on its own. Name the tree
52
+ * with `aria-label`. It scrolls by itself, so it wants a height to fill: a
53
+ * short tree on a page that scrolls takes `scrollEnabled={false}` and is
54
+ * laid out at its full length. It is drawn on surface, and `style` and `ref`
55
+ * land on the `FlatList`.
56
+ */
57
+ declare function Tree<T extends object = object>({ children, defaultExpandedKeys, defaultSelectedKeys, disabledKeys, disallowEmptySelection, expandedKeys, items, onExpandedChange, onSelectionChange, selectedKeys, selectionMode, ...props }: TreeProps<T>): import("react").JSX.Element;
58
+ declare namespace Tree {
59
+ var Item: typeof TreeItem;
60
+ var LoadMore: typeof TreeLoadMore;
61
+ var Section: typeof TreeSection;
62
+ }
63
+ /**
64
+ * One row, and the rows under it. Its slots are ListItem's: `leading`, the
65
+ * `headline`, `supporting` under it, and `trailing`. Give every row an `id`,
66
+ * which is the key selection and opening are reported by.
67
+ *
68
+ * Rows nested as `children` are what make it open: a row with none draws no
69
+ * chevron. The tree draws it from its entry in the collection, so it renders
70
+ * nothing on its own. `style`, `ref` and `testID` land on the row.
71
+ */
72
+ declare function TreeItem(_props: TreeItemProps): null;
73
+ declare namespace TreeItem {
74
+ var getCollectionNode: typeof treeItemNode;
75
+ }
76
+ /**
77
+ * The row shown while more rows are being fetched. `onLoadMore` is called
78
+ * as the reader nears the end of the tree, and the ring is drawn only while
79
+ * `isLoading`, in a live region, so a screen reader hears it arrive. It goes
80
+ * last, after the rows it loads more of.
81
+ */
82
+ declare function TreeLoadMore(_props: TreeLoadMoreProps): null;
83
+ declare namespace TreeLoadMore {
84
+ var getCollectionNode: typeof loaderNode;
85
+ }
86
+ /**
87
+ * A group of rows under a heading, which stays at the top of the tree while
88
+ * the group's rows scroll under it.
89
+ */
90
+ declare function TreeSection(_props: TreeSectionProps): null;
91
+ declare namespace TreeSection {
92
+ var getCollectionNode: typeof sectionNode;
93
+ }
94
+ declare function treeItemNode(props: TreeItemProps): Generator<{
95
+ 'aria-label': string | undefined;
96
+ childNodes(): Generator<{
97
+ element: ReactNode;
98
+ }, void, unknown>;
99
+ hasChildNodes: boolean;
100
+ key: Key | undefined;
101
+ props: {
102
+ readonly 'aria-label'?: string;
103
+ readonly children?: ReactNode;
104
+ readonly id?: Key;
105
+ };
106
+ rendered: ReactNode;
107
+ textValue: string;
108
+ type: string;
109
+ }, void, unknown>;
110
+ //#endregion
111
+ export { Tree, TreeItem, type TreeItemProps, TreeLoadMore, type TreeLoadMoreProps, type TreeProps, TreeSection, type TreeSectionProps };
112
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,157 @@
1
+ import { CollectionView, loaderNode, nestedRowNode, sectionNode } from "../../collection/index.js";
2
+ import { c } from "react/compiler-runtime";
3
+ import { jsx } from "react/jsx-runtime";
4
+ import { useTreeState } from "react-stately/useTreeState";
5
+ //#region src/components/tree/index.tsx
6
+ /**
7
+ * A list whose rows nest. Which rows are open is React Stately's, as web's
8
+ * is React Aria's: pass `expandedKeys` with `onExpandedChange` to control
9
+ * it, or `defaultExpandedKeys` to let it keep its own. Selection is React
10
+ * Stately's too: set `selectionMode` to `single` or `multiple`, and a tree
11
+ * that selects draws a checkbox on every row.
12
+ *
13
+ * ```tsx
14
+ * <Tree aria-label="Label">
15
+ * <Tree.Item headline="First item" id="first">
16
+ * <Tree.Item headline="Second item" id="second" />
17
+ * </Tree.Item>
18
+ * </Tree>
19
+ * ```
20
+ *
21
+ * Each row is the row every list here draws, indented by its depth, with a
22
+ * chevron on the rows that have rows under them. Composed from parts,
23
+ * `Tree.Item`, `Tree.Section` and `Tree.LoadMore`, which the tree draws from
24
+ * their props, so none of them renders anything on its own. Name the tree
25
+ * with `aria-label`. It scrolls by itself, so it wants a height to fill: a
26
+ * short tree on a page that scrolls takes `scrollEnabled={false}` and is
27
+ * laid out at its full length. It is drawn on surface, and `style` and `ref`
28
+ * land on the `FlatList`.
29
+ */
30
+ function Tree(t0) {
31
+ const $ = c(28);
32
+ let children;
33
+ let defaultExpandedKeys;
34
+ let defaultSelectedKeys;
35
+ let disabledKeys;
36
+ let disallowEmptySelection;
37
+ let expandedKeys;
38
+ let items;
39
+ let onExpandedChange;
40
+ let onSelectionChange;
41
+ let props;
42
+ let selectedKeys;
43
+ let t1;
44
+ if ($[0] !== t0) {
45
+ ({children, defaultExpandedKeys, defaultSelectedKeys, disabledKeys, disallowEmptySelection, expandedKeys, items, onExpandedChange, onSelectionChange, selectedKeys, selectionMode: t1, ...props} = t0);
46
+ $[0] = t0;
47
+ $[1] = children;
48
+ $[2] = defaultExpandedKeys;
49
+ $[3] = defaultSelectedKeys;
50
+ $[4] = disabledKeys;
51
+ $[5] = disallowEmptySelection;
52
+ $[6] = expandedKeys;
53
+ $[7] = items;
54
+ $[8] = onExpandedChange;
55
+ $[9] = onSelectionChange;
56
+ $[10] = props;
57
+ $[11] = selectedKeys;
58
+ $[12] = t1;
59
+ } else {
60
+ children = $[1];
61
+ defaultExpandedKeys = $[2];
62
+ defaultSelectedKeys = $[3];
63
+ disabledKeys = $[4];
64
+ disallowEmptySelection = $[5];
65
+ expandedKeys = $[6];
66
+ items = $[7];
67
+ onExpandedChange = $[8];
68
+ onSelectionChange = $[9];
69
+ props = $[10];
70
+ selectedKeys = $[11];
71
+ t1 = $[12];
72
+ }
73
+ const selectionMode = t1 === void 0 ? "none" : t1;
74
+ const t2 = children;
75
+ let t3;
76
+ if ($[13] !== defaultExpandedKeys || $[14] !== defaultSelectedKeys || $[15] !== disabledKeys || $[16] !== disallowEmptySelection || $[17] !== expandedKeys || $[18] !== items || $[19] !== onExpandedChange || $[20] !== onSelectionChange || $[21] !== selectedKeys || $[22] !== selectionMode || $[23] !== t2) {
77
+ t3 = {
78
+ children: t2,
79
+ defaultExpandedKeys,
80
+ defaultSelectedKeys,
81
+ disabledKeys,
82
+ disallowEmptySelection,
83
+ expandedKeys,
84
+ items,
85
+ onExpandedChange,
86
+ onSelectionChange,
87
+ selectedKeys,
88
+ selectionMode
89
+ };
90
+ $[13] = defaultExpandedKeys;
91
+ $[14] = defaultSelectedKeys;
92
+ $[15] = disabledKeys;
93
+ $[16] = disallowEmptySelection;
94
+ $[17] = expandedKeys;
95
+ $[18] = items;
96
+ $[19] = onExpandedChange;
97
+ $[20] = onSelectionChange;
98
+ $[21] = selectedKeys;
99
+ $[22] = selectionMode;
100
+ $[23] = t2;
101
+ $[24] = t3;
102
+ } else t3 = $[24];
103
+ const state = useTreeState(t3);
104
+ let t4;
105
+ if ($[25] !== props || $[26] !== state) {
106
+ t4 = /* @__PURE__ */ jsx(CollectionView, {
107
+ ...props,
108
+ kind: "list",
109
+ state
110
+ });
111
+ $[25] = props;
112
+ $[26] = state;
113
+ $[27] = t4;
114
+ } else t4 = $[27];
115
+ return t4;
116
+ }
117
+ /**
118
+ * One row, and the rows under it. Its slots are ListItem's: `leading`, the
119
+ * `headline`, `supporting` under it, and `trailing`. Give every row an `id`,
120
+ * which is the key selection and opening are reported by.
121
+ *
122
+ * Rows nested as `children` are what make it open: a row with none draws no
123
+ * chevron. The tree draws it from its entry in the collection, so it renders
124
+ * nothing on its own. `style`, `ref` and `testID` land on the row.
125
+ */
126
+ function TreeItem(_props) {
127
+ return null;
128
+ }
129
+ TreeItem.getCollectionNode = treeItemNode;
130
+ /**
131
+ * The row shown while more rows are being fetched. `onLoadMore` is called
132
+ * as the reader nears the end of the tree, and the ring is drawn only while
133
+ * `isLoading`, in a live region, so a screen reader hears it arrive. It goes
134
+ * last, after the rows it loads more of.
135
+ */
136
+ function TreeLoadMore(_props) {
137
+ return null;
138
+ }
139
+ TreeLoadMore.getCollectionNode = loaderNode;
140
+ /**
141
+ * A group of rows under a heading, which stays at the top of the tree while
142
+ * the group's rows scroll under it.
143
+ */
144
+ function TreeSection(_props) {
145
+ return null;
146
+ }
147
+ TreeSection.getCollectionNode = sectionNode;
148
+ function treeItemNode(props) {
149
+ return nestedRowNode(props, props.headline, props.textValue ?? (typeof props.headline === "string" ? props.headline : ""));
150
+ }
151
+ Tree.Item = TreeItem;
152
+ Tree.LoadMore = TreeLoadMore;
153
+ Tree.Section = TreeSection;
154
+ //#endregion
155
+ export { Tree, TreeItem, TreeLoadMore, TreeSection };
156
+
157
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["ReactNode","Key","TreeProps","StatelyTreeProps","useTreeState","CollectionLoadMoreProps","CollectionProps","CollectionRowProps","CollectionSectionProps","CollectionView","loaderNode","nestedRowNode","sectionNode","TreeItemProps","Omit","TreeItemText","children","headline","textValue","TreeLoadMoreProps","T","defaultExpandedKeys","Iterable","expandedKeys","onExpandedChange","keys","Set","TreeSectionProps","Tree","t0","$","_c","defaultSelectedKeys","disabledKeys","disallowEmptySelection","items","onSelectionChange","props","selectedKeys","t1","selectionMode","undefined","t2","t3","state","t4","TreeItem","_props","getCollectionNode","treeItemNode","TreeLoadMore","TreeSection","Item","LoadMore","Section","_c"],"sources":["../../../src/components/tree/index.tsx"],"sourcesContent":["import type { ReactNode } from 'react'\nimport type { Key } from 'react-stately'\nimport type { TreeProps as StatelyTreeProps } from 'react-stately/useTreeState'\n\nimport { useTreeState } from 'react-stately/useTreeState'\n\nimport type {\n CollectionLoadMoreProps,\n CollectionProps,\n CollectionRowProps,\n CollectionSectionProps,\n} from '../../collection'\n\nimport {\n CollectionView,\n loaderNode,\n nestedRowNode,\n sectionNode,\n} from '../../collection'\n\n// kanso-ui's Tree: a list whose rows nest. Each row is the row every list\n// here draws, src/row's, drawn by src/collection as a List draws it, so its\n// 56dp floor, body-large headline, body-medium supporting line, state layers,\n// selection colours and checkbox are that module's, and a tree beside a list\n// cannot drift from it.\n//\n// The lists page gives no nesting, so the two things a tree adds are web's\n// own, and src/collection draws both: a level is set in by 24dp, the width\n// of the menus page's chevron, which makes a level of nesting exactly as wide\n// as the caret that opens it; and a row with rows under it starts with that\n// chevron, which turns a quarter as it opens and mirrors under right-to-left,\n// while a row with none starts with the chevron's space, so its headline\n// lines up with a sibling's that opens.\n//\n// Three things differ from web's, each because a screen reader or a touch on\n// a phone works differently from a keyboard in a browser, and each the same\n// as List's.\n//\n// **A row is one element to a screen reader.** Web's row is a tree grid row\n// whose chevron and checkbox are buttons a keyboard reaches on their own.\n// VoiceOver and TalkBack read a pressable row as one element and reach\n// nothing inside it, so a row reports whether it is open and whether it is\n// selected, and opening, closing and selecting it are accessibility actions,\n// named from src/i18n as React Aria names web's chevron. Arrow keys, which\n// open and close a row on web, have nothing to reach on a phone and are\n// dropped.\n//\n// **A press does what React Aria's touch press does.** The chevron opens and\n// closes its row. A press on the row runs its action while nothing is\n// selected and selects once something is, a long press selects, and in a\n// tree that neither selects nor acts a press opens or closes the row, as\n// React Aria's does.\n//\n// **The tree is one `FlatList`.** The rows of an open row follow it in the\n// same column, and a section is its header and then its rows, so a large\n// tree draws only the rows in view, and a section's header stays at the top\n// while its rows scroll under it.\n\ntype TreeItemProps = Omit<\n CollectionRowProps,\n 'children' | 'overline' | 'textValue'\n> &\n TreeItemText & {\n /** The rows nested under this one, as further `Tree.Item` parts. */\n readonly children?: ReactNode\n }\n\n// What the row is worth as text, which the collection keeps beside the row\n// as web's does: a string headline is taken as the value, and anything else\n// has to say what it is worth, so the compiler asks for it where web's types\n// do.\ntype TreeItemText =\n | {\n /** The row's headline, as something other than a plain string. */\n readonly headline?: ReactNode\n /** The row's text, which a headline that is not a string cannot give. */\n readonly textValue: string\n }\n | {\n /** The row's headline, the one thing it is mostly about. */\n readonly headline: string\n /** The row's text. Defaults to the headline. */\n readonly textValue?: string\n }\n\ntype TreeLoadMoreProps = CollectionLoadMoreProps\n\ntype TreeProps<T extends object = object> = CollectionProps<T> & {\n /** The keys of the rows open at first, when the tree keeps its own. */\n readonly defaultExpandedKeys?: Iterable<Key>\n /**\n * The keys of the open rows, for a call site holding them itself with\n * `onExpandedChange`.\n */\n readonly expandedKeys?: Iterable<Key>\n /** Called with the keys of the open rows whenever a row opens or closes. */\n readonly onExpandedChange?: (keys: Set<Key>) => void\n}\n\ntype TreeSectionProps = CollectionSectionProps\n\n/**\n * A list whose rows nest. Which rows are open is React Stately's, as web's\n * is React Aria's: pass `expandedKeys` with `onExpandedChange` to control\n * it, or `defaultExpandedKeys` to let it keep its own. Selection is React\n * Stately's too: set `selectionMode` to `single` or `multiple`, and a tree\n * that selects draws a checkbox on every row.\n *\n * ```tsx\n * <Tree aria-label=\"Label\">\n * <Tree.Item headline=\"First item\" id=\"first\">\n * <Tree.Item headline=\"Second item\" id=\"second\" />\n * </Tree.Item>\n * </Tree>\n * ```\n *\n * Each row is the row every list here draws, indented by its depth, with a\n * chevron on the rows that have rows under them. Composed from parts,\n * `Tree.Item`, `Tree.Section` and `Tree.LoadMore`, which the tree draws from\n * their props, so none of them renders anything on its own. Name the tree\n * with `aria-label`. It scrolls by itself, so it wants a height to fill: a\n * short tree on a page that scrolls takes `scrollEnabled={false}` and is\n * laid out at its full length. It is drawn on surface, and `style` and `ref`\n * land on the `FlatList`.\n */\nfunction Tree<T extends object = object>({\n children,\n defaultExpandedKeys,\n defaultSelectedKeys,\n disabledKeys,\n disallowEmptySelection,\n expandedKeys,\n items,\n onExpandedChange,\n onSelectionChange,\n selectedKeys,\n selectionMode = 'none',\n ...props\n}: TreeProps<T>) {\n const state = useTreeState<T>({\n // Each part builds its own entry in the collection; see `treeItemNode`\n // and the two src/collection gives. The collection skips what is not an\n // element, as a ReactNode may be, and asks any element for its entry.\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- see above\n children: children as StatelyTreeProps<T>['children'],\n defaultExpandedKeys,\n defaultSelectedKeys,\n disabledKeys,\n disallowEmptySelection,\n expandedKeys,\n items,\n onExpandedChange,\n onSelectionChange,\n selectedKeys,\n selectionMode,\n })\n\n return <CollectionView<T> {...props} kind=\"list\" state={state} />\n}\n\n/**\n * One row, and the rows under it. Its slots are ListItem's: `leading`, the\n * `headline`, `supporting` under it, and `trailing`. Give every row an `id`,\n * which is the key selection and opening are reported by.\n *\n * Rows nested as `children` are what make it open: a row with none draws no\n * chevron. The tree draws it from its entry in the collection, so it renders\n * nothing on its own. `style`, `ref` and `testID` land on the row.\n */\nfunction TreeItem(_props: TreeItemProps): null {\n return null\n}\n\nTreeItem.getCollectionNode = treeItemNode\n\n/**\n * The row shown while more rows are being fetched. `onLoadMore` is called\n * as the reader nears the end of the tree, and the ring is drawn only while\n * `isLoading`, in a live region, so a screen reader hears it arrive. It goes\n * last, after the rows it loads more of.\n */\nfunction TreeLoadMore(_props: TreeLoadMoreProps): null {\n return null\n}\n\nTreeLoadMore.getCollectionNode = loaderNode\n\n/**\n * A group of rows under a heading, which stays at the top of the tree while\n * the group's rows scroll under it.\n */\nfunction TreeSection(_props: TreeSectionProps): null {\n return null\n}\n\nTreeSection.getCollectionNode = sectionNode\n\n// The entry the collection holds for an `Item` part, whose first line is its\n// headline.\nfunction treeItemNode(props: TreeItemProps) {\n return nestedRowNode(\n props,\n props.headline,\n props.textValue ??\n (typeof props.headline === 'string' ? props.headline : ''),\n )\n}\n\nTree.Item = TreeItem\nTree.LoadMore = TreeLoadMore\nTree.Section = TreeSection\n\nexport { Tree, TreeItem, TreeLoadMore, TreeSection }\nexport type { TreeItemProps, TreeLoadMoreProps, TreeProps, TreeSectionProps }\n"],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { createContext } from "react";
2
+ //#region src/control/group.ts
3
+ const CheckboxGroupContext = createContext(null);
4
+ /** An empty list of a group's checkboxes, made once per group. */
5
+ function createMembers() {
6
+ const controls = /* @__PURE__ */ new Map();
7
+ return {
8
+ add: (id, control) => {
9
+ controls.set(id, control);
10
+ },
11
+ get current() {
12
+ for (const control of controls.values()) if (control.current !== null) return control.current;
13
+ return null;
14
+ },
15
+ remove: (id) => {
16
+ controls.delete(id);
17
+ }
18
+ };
19
+ }
20
+ //#endregion
21
+ export { CheckboxGroupContext, createMembers };
22
+
23
+ //# sourceMappingURL=group.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"group.js","names":["RefObject","createContext","Focusable","CheckboxGroupContextValue","isDisabled","isInvalid","isReadOnly","isSelected","value","members","CheckboxGroupMembers","set","add","id","control","remove","CheckboxGroupContext","createMembers","controls","Map","current","values","delete"],"sources":["../../src/control/group.ts"],"sourcesContent":["import type { RefObject } from 'react'\n\nimport { createContext } from 'react'\n\nimport type { Focusable } from '../form'\n\n// What a CheckboxGroup tells the checkboxes inside it, as React Aria's group\n// state does on web: which entries are selected, how to change one, and the\n// states that reach every box from the group. Beside src/control's row\n// rather than in the group's own module, so Checkbox reads it without\n// importing the group.\n\ntype CheckboxGroupContextValue = {\n readonly isDisabled: boolean\n readonly isInvalid: boolean\n readonly isReadOnly: boolean\n readonly isSelected: (value: string) => boolean\n readonly members: CheckboxGroupMembers\n /** Selects or clears one entry, as a press on its checkbox does. */\n readonly set: (value: string, isSelected: boolean) => void\n}\n\n/**\n * A group's checkboxes, in the order they mounted, which is the order they\n * are drawn in. As a ref it holds the first of them that has a control, which\n * is what the form around the group focuses when the group holds a native\n * submission back.\n */\ntype CheckboxGroupMembers = RefObject<Focusable | null> & {\n /** Adds a checkbox's control, keeping its place if it is already there. */\n readonly add: (id: string, control: RefObject<Focusable | null>) => void\n readonly remove: (id: string) => void\n}\n\nconst CheckboxGroupContext = createContext<CheckboxGroupContextValue | null>(\n null,\n)\n\n/** An empty list of a group's checkboxes, made once per group. */\nfunction createMembers(): CheckboxGroupMembers {\n const controls = new Map<string, RefObject<Focusable | null>>()\n\n return {\n add: (id, control) => {\n controls.set(id, control)\n },\n get current() {\n for (const control of controls.values()) {\n if (control.current !== null) {\n return control.current\n }\n }\n return null\n },\n remove: (id) => {\n controls.delete(id)\n },\n }\n}\n\nexport { CheckboxGroupContext, createMembers }\nexport type { CheckboxGroupContextValue, CheckboxGroupMembers }\n"],"mappings":";;AAkCA,MAAMgB,uBAAuBf,cAC3B,IACF;;AAGA,SAASgB,gBAAsC;CAC7C,MAAMC,2BAAW,IAAIC,IAAyC;CAE9D,OAAO;EACLP,MAAMC,IAAIC,YAAY;GACpBI,SAASP,IAAIE,IAAIC,OAAO;EAC1B;EACA,IAAIM,UAAU;GACZ,KAAK,MAAMN,WAAWI,SAASG,OAAO,GACpC,IAAIP,QAAQM,YAAY,MACtB,OAAON,QAAQM;GAGnB,OAAO;EACT;EACAL,SAASF,OAAO;GACdK,SAASI,OAAOT,EAAE;EACpB;CACF;AACF"}
@@ -0,0 +1,75 @@
1
+ import { useTheme } from "../theme/scope.js";
2
+ import { ChevronEndGlyph } from "../glyphs/index.js";
3
+ import { c } from "react/compiler-runtime";
4
+ import { I18nManager } from "react-native";
5
+ import Animated, { Easing, useAnimatedStyle, useReducedMotion, useSharedValue, withTiming } from "react-native-reanimated";
6
+ import { useEffect } from "react";
7
+ import { jsx } from "react/jsx-runtime";
8
+ //#region src/disclosure/chevron.tsx
9
+ /**
10
+ * The chevron of something that opens in place, a Disclosure's header or a
11
+ * Tree's row, pointing at what it opens and turned a quarter to point down
12
+ * once it is open, on short3 and the standard curve, and at once under
13
+ * reduced motion. The glyph mirrors itself under right-to-left, so the turn
14
+ * goes the other way there to point it down too. It takes its size from the
15
+ * slot it sits in, and its colour too unless given one.
16
+ */
17
+ function ExpandChevron(t0) {
18
+ const $ = c(11);
19
+ const { color, isExpanded } = t0;
20
+ const { motion } = useTheme();
21
+ const reduceMotion = useReducedMotion();
22
+ const turn = isExpanded ? I18nManager.isRTL ? -90 : 90 : 0;
23
+ const angle = useSharedValue(turn);
24
+ let t1;
25
+ let t2;
26
+ if ($[0] !== angle || $[1] !== motion || $[2] !== reduceMotion || $[3] !== turn) {
27
+ t1 = () => {
28
+ angle.set(reduceMotion ? turn : withTiming(turn, {
29
+ duration: motion.durationShort3,
30
+ easing: Easing.bezier(...motion.easingStandard)
31
+ }));
32
+ };
33
+ t2 = [
34
+ angle,
35
+ motion,
36
+ reduceMotion,
37
+ turn
38
+ ];
39
+ $[0] = angle;
40
+ $[1] = motion;
41
+ $[2] = reduceMotion;
42
+ $[3] = turn;
43
+ $[4] = t1;
44
+ $[5] = t2;
45
+ } else {
46
+ t1 = $[4];
47
+ t2 = $[5];
48
+ }
49
+ useEffect(t1, t2);
50
+ const turned = useAnimatedStyle(() => {
51
+ "worklet";
52
+ return { transform: [{ rotate: `${angle.get()}deg` }] };
53
+ });
54
+ let t3;
55
+ if ($[6] !== color) {
56
+ t3 = /* @__PURE__ */ jsx(ChevronEndGlyph, { color });
57
+ $[6] = color;
58
+ $[7] = t3;
59
+ } else t3 = $[7];
60
+ let t4;
61
+ if ($[8] !== t3 || $[9] !== turned) {
62
+ t4 = /* @__PURE__ */ jsx(Animated.View, {
63
+ style: turned,
64
+ children: t3
65
+ });
66
+ $[8] = t3;
67
+ $[9] = turned;
68
+ $[10] = t4;
69
+ } else t4 = $[10];
70
+ return t4;
71
+ }
72
+ //#endregion
73
+ export { ExpandChevron };
74
+
75
+ //# sourceMappingURL=chevron.js.map