@kanso-labs/react-native-kanso-ui 0.9.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 (196) 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/button/group.d.ts +5 -0
  5. package/dist/button/group.js +115 -0
  6. package/dist/button/group.js.map +1 -0
  7. package/dist/button/index.d.ts +4 -1
  8. package/dist/button/index.js +44 -22
  9. package/dist/button/index.js.map +1 -1
  10. package/dist/button/slots.js +2 -1
  11. package/dist/button/slots.js.map +1 -1
  12. package/dist/calendar/index.js +351 -182
  13. package/dist/calendar/index.js.map +1 -1
  14. package/dist/calendar/styles.js +33 -2
  15. package/dist/calendar/styles.js.map +1 -1
  16. package/dist/carousel/arrangement.d.ts +5 -0
  17. package/dist/carousel/arrangement.js +123 -0
  18. package/dist/carousel/arrangement.js.map +1 -0
  19. package/dist/chequer/index.js +95 -0
  20. package/dist/chequer/index.js.map +1 -0
  21. package/dist/collection/index.d.ts +157 -0
  22. package/dist/collection/index.js +1331 -0
  23. package/dist/collection/index.js.map +1 -0
  24. package/dist/color-thumb/index.js +56 -0
  25. package/dist/color-thumb/index.js.map +1 -0
  26. package/dist/components/button/index.d.ts +4 -2
  27. package/dist/components/button/index.js +227 -188
  28. package/dist/components/button/index.js.map +1 -1
  29. package/dist/components/button-group/index.d.ts +87 -0
  30. package/dist/components/button-group/index.js +275 -0
  31. package/dist/components/button-group/index.js.map +1 -0
  32. package/dist/components/calendar/index.d.ts +11 -3
  33. package/dist/components/calendar/index.js +60 -45
  34. package/dist/components/calendar/index.js.map +1 -1
  35. package/dist/components/carousel/index.d.ts +72 -0
  36. package/dist/components/carousel/index.js +496 -0
  37. package/dist/components/carousel/index.js.map +1 -0
  38. package/dist/components/checkbox-group/index.d.ts +3 -4
  39. package/dist/components/checkbox-group/index.js +1 -1
  40. package/dist/components/checkbox-group/index.js.map +1 -1
  41. package/dist/components/color-area/index.d.ts +85 -0
  42. package/dist/components/color-area/index.js +630 -0
  43. package/dist/components/color-area/index.js.map +1 -0
  44. package/dist/components/color-field/index.d.ts +144 -0
  45. package/dist/components/color-field/index.js +516 -0
  46. package/dist/components/color-field/index.js.map +1 -0
  47. package/dist/components/color-picker/index.d.ts +74 -0
  48. package/dist/components/color-picker/index.js +317 -0
  49. package/dist/components/color-picker/index.js.map +1 -0
  50. package/dist/components/color-slider/index.d.ts +82 -0
  51. package/dist/components/color-slider/index.js +456 -0
  52. package/dist/components/color-slider/index.js.map +1 -0
  53. package/dist/components/color-swatch/index.d.ts +46 -0
  54. package/dist/components/color-swatch/index.js +127 -0
  55. package/dist/components/color-swatch/index.js.map +1 -0
  56. package/dist/components/color-swatch-picker/index.d.ts +81 -0
  57. package/dist/components/color-swatch-picker/index.js +287 -0
  58. package/dist/components/color-swatch-picker/index.js.map +1 -0
  59. package/dist/components/color-wheel/index.d.ts +71 -0
  60. package/dist/components/color-wheel/index.js +407 -0
  61. package/dist/components/color-wheel/index.js.map +1 -0
  62. package/dist/components/combo-box/index.d.ts +193 -0
  63. package/dist/components/combo-box/index.js +616 -0
  64. package/dist/components/combo-box/index.js.map +1 -0
  65. package/dist/components/date-field/index.d.ts +120 -0
  66. package/dist/components/date-field/index.js +111 -0
  67. package/dist/components/date-field/index.js.map +1 -0
  68. package/dist/components/date-picker/index.d.ts +130 -0
  69. package/dist/components/date-picker/index.js +310 -0
  70. package/dist/components/date-picker/index.js.map +1 -0
  71. package/dist/components/date-range-picker/index.d.ts +139 -0
  72. package/dist/components/date-range-picker/index.js +421 -0
  73. package/dist/components/date-range-picker/index.js.map +1 -0
  74. package/dist/components/disclosure/index.d.ts +94 -0
  75. package/dist/components/disclosure/index.js +365 -0
  76. package/dist/components/disclosure/index.js.map +1 -0
  77. package/dist/components/disclosure-group/index.d.ts +61 -0
  78. package/dist/components/disclosure-group/index.js +100 -0
  79. package/dist/components/disclosure-group/index.js.map +1 -0
  80. package/dist/components/drop-zone/index.d.ts +113 -0
  81. package/dist/components/drop-zone/index.js +304 -0
  82. package/dist/components/drop-zone/index.js.map +1 -0
  83. package/dist/components/fab/index.d.ts +1 -1
  84. package/dist/components/fab/index.js +91 -76
  85. package/dist/components/fab/index.js.map +1 -1
  86. package/dist/components/form/index.d.ts +3 -2
  87. package/dist/components/form/index.js.map +1 -1
  88. package/dist/components/icon-button/index.d.ts +4 -2
  89. package/dist/components/icon-button/index.js +204 -171
  90. package/dist/components/icon-button/index.js.map +1 -1
  91. package/dist/components/list/index.d.ts +15 -158
  92. package/dist/components/list/index.js +21 -1047
  93. package/dist/components/list/index.js.map +1 -1
  94. package/dist/components/list-box/index.d.ts +73 -0
  95. package/dist/components/list-box/index.js +82 -0
  96. package/dist/components/list-box/index.js.map +1 -0
  97. package/dist/components/loading-indicator/index.d.ts +32 -0
  98. package/dist/components/loading-indicator/index.js +174 -0
  99. package/dist/components/loading-indicator/index.js.map +1 -0
  100. package/dist/components/navigation-tree/index.d.ts +117 -0
  101. package/dist/components/navigation-tree/index.js +135 -0
  102. package/dist/components/navigation-tree/index.js.map +1 -0
  103. package/dist/components/number-field/index.js +132 -143
  104. package/dist/components/number-field/index.js.map +1 -1
  105. package/dist/components/range-calendar/index.d.ts +69 -0
  106. package/dist/components/range-calendar/index.js +144 -0
  107. package/dist/components/range-calendar/index.js.map +1 -0
  108. package/dist/components/search-view/index.d.ts +78 -0
  109. package/dist/components/search-view/index.js +570 -0
  110. package/dist/components/search-view/index.js.map +1 -0
  111. package/dist/components/select/index.d.ts +152 -0
  112. package/dist/components/select/index.js +419 -0
  113. package/dist/components/select/index.js.map +1 -0
  114. package/dist/components/slider/index.d.ts +111 -0
  115. package/dist/components/slider/index.js +673 -0
  116. package/dist/components/slider/index.js.map +1 -0
  117. package/dist/components/split-button/index.d.ts +77 -0
  118. package/dist/components/split-button/index.js +354 -0
  119. package/dist/components/split-button/index.js.map +1 -0
  120. package/dist/components/tabs/index.d.ts +196 -0
  121. package/dist/components/tabs/index.js +1137 -0
  122. package/dist/components/tabs/index.js.map +1 -0
  123. package/dist/components/time-field/index.d.ts +43 -0
  124. package/dist/components/time-field/index.js +107 -0
  125. package/dist/components/time-field/index.js.map +1 -0
  126. package/dist/components/time-picker/index.d.ts +65 -0
  127. package/dist/components/time-picker/index.js +1168 -0
  128. package/dist/components/time-picker/index.js.map +1 -0
  129. package/dist/components/tooltip/index.d.ts +101 -0
  130. package/dist/components/tooltip/index.js +223 -0
  131. package/dist/components/tooltip/index.js.map +1 -0
  132. package/dist/components/tree/index.d.ts +112 -0
  133. package/dist/components/tree/index.js +157 -0
  134. package/dist/components/tree/index.js.map +1 -0
  135. package/dist/disclosure/chevron.js +75 -0
  136. package/dist/disclosure/chevron.js.map +1 -0
  137. package/dist/disclosure/index.js +7 -0
  138. package/dist/disclosure/index.js.map +1 -0
  139. package/dist/drop/index.d.ts +54 -0
  140. package/dist/drop/index.js +161 -0
  141. package/dist/drop/index.js.map +1 -0
  142. package/dist/field/chevron.js +74 -0
  143. package/dist/field/chevron.js.map +1 -0
  144. package/dist/field/index.d.ts +2 -1
  145. package/dist/field/index.js +310 -154
  146. package/dist/field/index.js.map +1 -1
  147. package/dist/field/styles.js +9 -0
  148. package/dist/field/styles.js.map +1 -1
  149. package/dist/files/index.d.ts +18 -0
  150. package/dist/files/index.js +107 -0
  151. package/dist/files/index.js.map +1 -0
  152. package/dist/form/index.d.ts +5 -2
  153. package/dist/form/index.js +64 -85
  154. package/dist/form/index.js.map +1 -1
  155. package/dist/glyphs/index.js +92 -1
  156. package/dist/glyphs/index.js.map +1 -1
  157. package/dist/i18n/index.js +20 -1
  158. package/dist/i18n/index.js.map +1 -1
  159. package/dist/i18n/messages.js +1394 -34
  160. package/dist/i18n/messages.js.map +1 -1
  161. package/dist/index.d.ts +35 -3
  162. package/dist/index.js +34 -3
  163. package/dist/indicator/paths.js +23 -1
  164. package/dist/indicator/paths.js.map +1 -1
  165. package/dist/modal/index.js +92 -77
  166. package/dist/modal/index.js.map +1 -1
  167. package/dist/number/keyboard.js +16 -0
  168. package/dist/number/keyboard.js.map +1 -0
  169. package/dist/overlay/anchored.js +68 -38
  170. package/dist/overlay/anchored.js.map +1 -1
  171. package/dist/overlay/keyboard.js +57 -0
  172. package/dist/overlay/keyboard.js.map +1 -0
  173. package/dist/overlay/panel.js +173 -19
  174. package/dist/overlay/panel.js.map +1 -1
  175. package/dist/overlay/placement.js +13 -1
  176. package/dist/overlay/placement.js.map +1 -1
  177. package/dist/picker/index.js +322 -0
  178. package/dist/picker/index.js.map +1 -0
  179. package/dist/press/index.d.ts +2 -0
  180. package/dist/press/index.js +102 -100
  181. package/dist/press/index.js.map +1 -1
  182. package/dist/row/index.js +77 -69
  183. package/dist/row/index.js.map +1 -1
  184. package/dist/row/styles.js +13 -2
  185. package/dist/row/styles.js.map +1 -1
  186. package/dist/segments/field.js +277 -0
  187. package/dist/segments/field.js.map +1 -0
  188. package/dist/segments/index.js +574 -0
  189. package/dist/segments/index.js.map +1 -0
  190. package/dist/segments/styles.js +24 -0
  191. package/dist/segments/styles.js.map +1 -0
  192. package/dist/slider/index.js +145 -0
  193. package/dist/slider/index.js.map +1 -0
  194. package/dist/swatch/index.js +56 -0
  195. package/dist/swatch/index.js.map +1 -0
  196. package/package.json +11 -2
@@ -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,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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chevron.js","names":["ColorValue","useEffect","I18nManager","Animated","Easing","useAnimatedStyle","useReducedMotion","useSharedValue","withTiming","ChevronEndGlyph","useTheme","ExpandChevron","t0","$","_c","color","isExpanded","motion","reduceMotion","turn","isRTL","angle","t1","t2","set","duration","durationShort3","easing","bezier","easingStandard","turned","transform","rotate","get","t3","t4","_c"],"sources":["../../src/disclosure/chevron.tsx"],"sourcesContent":["import type { ColorValue } from 'react-native'\n\nimport { useEffect } from 'react'\nimport { I18nManager } from 'react-native'\nimport Animated, {\n Easing,\n useAnimatedStyle,\n useReducedMotion,\n useSharedValue,\n withTiming,\n} from 'react-native-reanimated'\n\nimport { ChevronEndGlyph } from '../glyphs'\nimport { useTheme } from '../theme/scope'\n\n/**\n * The chevron of something that opens in place, a Disclosure's header or a\n * Tree's row, pointing at what it opens and turned a quarter to point down\n * once it is open, on short3 and the standard curve, and at once under\n * reduced motion. The glyph mirrors itself under right-to-left, so the turn\n * goes the other way there to point it down too. It takes its size from the\n * slot it sits in, and its colour too unless given one.\n */\nfunction ExpandChevron({\n color,\n isExpanded,\n}: {\n readonly color?: ColorValue\n readonly isExpanded: boolean\n}) {\n const { motion } = useTheme()\n const reduceMotion = useReducedMotion()\n const turn = isExpanded ? (I18nManager.isRTL ? -90 : 90) : 0\n const angle = useSharedValue(turn)\n\n useEffect(() => {\n angle.set(\n reduceMotion\n ? turn\n : withTiming(turn, {\n duration: motion.durationShort3,\n easing: Easing.bezier(...motion.easingStandard),\n }),\n )\n }, [angle, motion, reduceMotion, turn])\n\n const turned = useAnimatedStyle(() => {\n 'worklet'\n return { transform: [{ rotate: `${angle.get()}deg` }] }\n })\n\n return (\n <Animated.View style={turned}>\n <ChevronEndGlyph color={color} />\n </Animated.View>\n )\n}\n\nexport { ExpandChevron }\n"],"mappings":";;;;;;;;;;;;;;;;AAuBA,SAAAW,cAAAC,IAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAuB,MAAA,EAAAC,OAAAC,eAAAJ;CAOrB,MAAA,EAAAK,WAAmBP,SAAS;CAC5B,MAAAQ,eAAqBZ,iBAAiB;CACtC,MAAAa,OAAaH,aAAcd,YAAWkB,QAAX,MAAA,KAAd;CACb,MAAAC,QAAcd,eAAeY,IAAI;CAAC,IAAAG;CAAA,IAAAC;CAAA,IAAAV,EAAA,OAAAQ,SAAAR,EAAA,OAAAI,UAAAJ,EAAA,OAAAK,gBAAAL,EAAA,OAAAM,MAAA;EAExBG,WAAA;GACRD,MAAKG,IACHN,eAAAC,OAEIX,WAAWW,MAAM;IAAAM,UACLR,OAAMS;IAAeC,QACvBvB,OAAMwB,OAAO,GAAIX,OAAMY,cAAe;GAChD,CAAC,CACP;EAAC;EACAN,KAAA;GAACF;GAAOJ;GAAQC;GAAcC;EAAI;EAACN,EAAA,KAAAQ;EAAAR,EAAA,KAAAI;EAAAJ,EAAA,KAAAK;EAAAL,EAAA,KAAAM;EAAAN,EAAA,KAAAS;EAAAT,EAAA,KAAAU;CAAA,OAAA;EAAAD,KAAAT,EAAA;EAAAU,KAAAV,EAAA;CAAA;CATtCZ,UAAUqB,IASPC,EAAmC;CAEtC,MAAAO,SAAezB,uBAAiB;EAAA;EAAA,OAEvB,EAAA0B,WAAa,CAAC,EAAAC,QAAU,GAAGX,MAAKY,IAAK,EAAC,KAAM,CAAC,EAAE;CAAC,CACxD;CAAC,IAAAC;CAAA,IAAArB,EAAA,OAAAE,OAAA;EAIEmB,KAAA,oBAAC,iBAAD,EAAwBnB,MAAK,CAAA;EAAIF,EAAA,KAAAE;EAAAF,EAAA,KAAAqB;CAAA,OAAAA,KAAArB,EAAA;CAAA,IAAAsB;CAAA,IAAAtB,EAAA,OAAAqB,MAAArB,EAAA,OAAAiB,QAAA;EADnCK,KAAA,oBAAA,SAAA,MAAA;GAAsBL,OAAAA;GACpBI,UAAAA;EACF,CAAA;EAAgBrB,EAAA,KAAAqB;EAAArB,EAAA,KAAAiB;EAAAjB,EAAA,MAAAsB;CAAA,OAAAA,KAAAtB,EAAA;CAAA,OAFhBsB;AAEgB"}
@@ -0,0 +1,7 @@
1
+ import { createContext } from "react";
2
+ //#region src/disclosure/index.ts
3
+ const DisclosureGroupStateContext = createContext(null);
4
+ //#endregion
5
+ export { DisclosureGroupStateContext };
6
+
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["DisclosureGroupState","createContext","DisclosureGroupStateContext"],"sources":["../../src/disclosure/index.ts"],"sourcesContent":["import type { DisclosureGroupState } from 'react-stately/useDisclosureGroupState'\n\nimport { createContext } from 'react'\n\n// The open keys of the DisclosureGroup around a Disclosure, as React Aria's\n// group state context is on web. A Disclosure inside one reads whether it is\n// open from the group's keys, under its `id`, and toggles that key when its\n// header is pressed. Null is no group, and a Disclosure then keeps its own\n// state.\nconst DisclosureGroupStateContext = createContext<DisclosureGroupState | null>(\n null,\n)\n\nexport { DisclosureGroupStateContext }\n"],"mappings":";;AASA,MAAME,8BAA8BD,cAClC,IACF"}
@@ -0,0 +1,54 @@
1
+ import { PickedFile } from "../files/index.js";
2
+ //#region src/drop/index.d.ts
3
+ /** The kinds of thing a drag carries, asked about one MIME type at a time. */
4
+ type DragTypes = {
5
+ readonly has: (type: string) => boolean;
6
+ };
7
+ /** Where something being dragged came over the target, from its top start corner. */
8
+ type DropEnterEvent = {
9
+ readonly type: 'dropenter';
10
+ readonly x: number;
11
+ readonly y: number;
12
+ };
13
+ /** What landed on the target, where, and what the drop does with it. */
14
+ type DropEvent = {
15
+ readonly dropOperation: Exclude<DropOperation, 'cancel'>;
16
+ readonly items: readonly DropItem[];
17
+ readonly type: 'drop';
18
+ readonly x: number;
19
+ readonly y: number;
20
+ };
21
+ /** Where something being dragged left the target. */
22
+ type DropExitEvent = {
23
+ readonly type: 'dropexit';
24
+ readonly x: number;
25
+ readonly y: number;
26
+ };
27
+ type DropItem = FileDropItem | TextDropItem;
28
+ /** What a drop does with what it carries, as web's drag and drop names it. */
29
+ type DropOperation = 'cancel' | 'copy' | 'link' | 'move';
30
+ /**
31
+ * A file dropped or picked: the file itself, and its contents as text, read
32
+ * when asked for.
33
+ */
34
+ type FileDropItem = PickedFile & {
35
+ readonly getText: () => Promise<string>;
36
+ readonly kind: 'file';
37
+ };
38
+ /**
39
+ * Text dropped from another page or app, in each of the MIME types it was
40
+ * dragged as, such as `text/plain` and `text/uri-list`. Only React Native
41
+ * Web takes one.
42
+ */
43
+ type TextDropItem = {
44
+ readonly getText: (type: string) => Promise<string>;
45
+ readonly kind: 'text';
46
+ readonly types: ReadonlySet<string>;
47
+ };
48
+ /** Whether an item is a file, for picking the files out of a drop. */
49
+ declare function isFileDropItem(item: DropItem): item is FileDropItem;
50
+ /** Whether an item is dropped text, for picking it out of a drop. */
51
+ declare function isTextDropItem(item: DropItem): item is TextDropItem;
52
+ //#endregion
53
+ export { type DragTypes, type DropEnterEvent, type DropEvent, type DropExitEvent, type DropItem, type DropOperation, type FileDropItem, type TextDropItem, isFileDropItem, isTextDropItem };
54
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,161 @@
1
+ //#region src/drop/index.ts
2
+ const EVERY = [
3
+ "copy",
4
+ "link",
5
+ "move"
6
+ ];
7
+ const ALLOWED = {
8
+ all: EVERY,
9
+ copy: ["copy"],
10
+ copyLink: ["copy", "link"],
11
+ copyMove: ["copy", "move"],
12
+ link: ["link"],
13
+ linkMove: ["link", "move"],
14
+ move: ["move"],
15
+ none: [],
16
+ uninitialized: EVERY
17
+ };
18
+ const FILES = "Files";
19
+ function dragTypesOf(transfer) {
20
+ const files = Array.from(transfer.items, (item) => item.kind === "file" ? item.type : void 0).filter((type) => type !== void 0);
21
+ return typesOf([...transfer.types.filter((type) => type !== FILES), ...files]);
22
+ }
23
+ function droppedItemsOf(transfer) {
24
+ const files = Array.from(transfer.files, (file) => ({
25
+ getText: async () => file.text(),
26
+ kind: "file",
27
+ name: file.name,
28
+ size: file.size,
29
+ type: file.type,
30
+ uri: URL.createObjectURL(file)
31
+ }));
32
+ const texts = new Map(transfer.types.filter((type) => type !== FILES).map((type) => [type, transfer.getData(type)]));
33
+ if (texts.size === 0) return files;
34
+ const text = {
35
+ getText: async (type) => Promise.resolve(texts.get(type) ?? ""),
36
+ kind: "text",
37
+ types: new Set(texts.keys())
38
+ };
39
+ return [...files, text];
40
+ }
41
+ /** A picked file as a file drop item, whose text is read from its URI. */
42
+ function fileItemOf(file) {
43
+ return {
44
+ ...file,
45
+ getText: async () => {
46
+ return (await fetch(file.uri)).text();
47
+ },
48
+ kind: "file"
49
+ };
50
+ }
51
+ /**
52
+ * Whether drops can be watched on a node: under React Native Web, where a
53
+ * View's node is its DOM element.
54
+ */
55
+ function isDropTarget(node) {
56
+ return typeof node === "object" && node !== null && "addEventListener" in node && "removeEventListener" in node;
57
+ }
58
+ /** Whether an item is a file, for picking the files out of a drop. */
59
+ function isFileDropItem(item) {
60
+ return item.kind === "file";
61
+ }
62
+ /** Whether an item is dropped text, for picking it out of a drop. */
63
+ function isTextDropItem(item) {
64
+ return item.kind === "text";
65
+ }
66
+ /**
67
+ * The operation a drop of these types would do: the call site's answer, else
68
+ * the first the drag allows, else none at all.
69
+ */
70
+ function operationOf(handlers, types, allowed) {
71
+ const first = allowed.at(0);
72
+ if (first === void 0) return "cancel";
73
+ return handlers.getDropOperation?.(types, allowed) ?? first;
74
+ }
75
+ /** The kinds of thing a set of items carries, for `getDropOperation`. */
76
+ function typesOf(types) {
77
+ const set = new Set(types);
78
+ return { has: (type) => set.has(type) };
79
+ }
80
+ /**
81
+ * Takes HTML5 drag and drop on a React Native Web element, as web's React
82
+ * Aria does on a DropZone: `onDropEnter` once something the target will take
83
+ * comes over it, `onDropExit` once it leaves or lands, and `onDrop` with what
84
+ * landed. `handlers` is read at each event, so it can follow the props. A
85
+ * drag crossing the target's own children stays over it, counted in and out
86
+ * as the browser reports each. While `isDisabled` returns true nothing is
87
+ * taken, and the browser shows that nothing will be. It hands back what
88
+ * stops it.
89
+ */
90
+ function watchDrops(target, handlers, isDisabled, setOver) {
91
+ let depth = 0;
92
+ let over = false;
93
+ const point = (event) => {
94
+ const box = target.getBoundingClientRect?.() ?? {
95
+ left: 0,
96
+ top: 0
97
+ };
98
+ return {
99
+ x: event.clientX - box.left,
100
+ y: event.clientY - box.top
101
+ };
102
+ };
103
+ const operation = (event) => event.dataTransfer === null || isDisabled() ? "cancel" : operationOf(handlers(), dragTypesOf(event.dataTransfer), ALLOWED[event.dataTransfer.effectAllowed] ?? EVERY);
104
+ const leave = (event) => {
105
+ if (over) {
106
+ over = false;
107
+ setOver(false);
108
+ handlers().onDropExit?.({
109
+ type: "dropexit",
110
+ ...point(event)
111
+ });
112
+ }
113
+ };
114
+ const onDragEnter = (event) => {
115
+ depth += 1;
116
+ if (depth === 1 && operation(event) !== "cancel") {
117
+ event.preventDefault();
118
+ over = true;
119
+ setOver(true);
120
+ handlers().onDropEnter?.({
121
+ type: "dropenter",
122
+ ...point(event)
123
+ });
124
+ }
125
+ };
126
+ const onDragOver = (event) => {
127
+ const chosen = operation(event);
128
+ if (event.dataTransfer !== null) event.dataTransfer.dropEffect = chosen === "cancel" ? "none" : chosen;
129
+ if (chosen !== "cancel") event.preventDefault();
130
+ };
131
+ const onDragLeave = (event) => {
132
+ depth = Math.max(0, depth - 1);
133
+ if (depth === 0) leave(event);
134
+ };
135
+ const onDrop = (event) => {
136
+ const chosen = operation(event);
137
+ depth = 0;
138
+ event.preventDefault();
139
+ if (chosen !== "cancel" && event.dataTransfer !== null) handlers().onDrop?.({
140
+ dropOperation: chosen,
141
+ items: droppedItemsOf(event.dataTransfer),
142
+ type: "drop",
143
+ ...point(event)
144
+ });
145
+ leave(event);
146
+ };
147
+ target.addEventListener("dragenter", onDragEnter);
148
+ target.addEventListener("dragover", onDragOver);
149
+ target.addEventListener("dragleave", onDragLeave);
150
+ target.addEventListener("drop", onDrop);
151
+ return () => {
152
+ target.removeEventListener("dragenter", onDragEnter);
153
+ target.removeEventListener("dragover", onDragOver);
154
+ target.removeEventListener("dragleave", onDragLeave);
155
+ target.removeEventListener("drop", onDrop);
156
+ };
157
+ }
158
+ //#endregion
159
+ export { fileItemOf, isDropTarget, isFileDropItem, isTextDropItem, operationOf, typesOf, watchDrops };
160
+
161
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["PickedFile","DomDataTransfer","dropEffect","effectAllowed","files","ArrayLike","DomFile","getData","format","items","kind","type","types","DomDragEvent","clientX","clientY","dataTransfer","preventDefault","DomDropTarget","addEventListener","listener","event","getBoundingClientRect","left","top","removeEventListener","Blob","name","text","Promise","DragTypes","has","DropEnterEvent","x","y","DropEvent","dropOperation","Exclude","DropOperation","DropItem","DropExitEvent","DropHandlers","getDropOperation","allowedOperations","onDrop","onDropEnter","onDropExit","FileDropItem","TextDropItem","getText","ReadonlySet","EVERY","ALLOWED","Readonly","Partial","Record","all","copy","copyLink","copyMove","link","linkMove","move","none","uninitialized","FILES","dragTypesOf","transfer","Array","from","item","undefined","filter","typesOf","droppedItemsOf","file","size","uri","URL","createObjectURL","texts","Map","map","resolve","get","Set","keys","fileItemOf","response","fetch","isDropTarget","node","isFileDropItem","isTextDropItem","operationOf","handlers","allowed","first","at","Iterable","set","watchDrops","target","isDisabled","setOver","isOver","depth","over","point","box","operation","leave","onDragEnter","onDragOver","chosen","onDragLeave","Math","max"],"sources":["../../src/drop/index.ts"],"sourcesContent":["import type { PickedFile } from '../files'\n\n// What a drop is, in web's React Aria's words, and how a DropZone takes one\n// under React Native Web, where the browser hands the page HTML5 drag and\n// drop. iOS and Android hand React Native no drag from another app, so there\n// the drop is a pick from the chooser, which DropZone turns into the same\n// event.\n\n// The slices of the DOM a drop reaches. The library is built without the DOM's\n// types, since Hermes has no DOM, so they are written out here, as far as\n// they are read.\ntype DomDataTransfer = {\n dropEffect: string\n readonly effectAllowed: string\n readonly files: ArrayLike<DomFile>\n readonly getData: (format: string) => string\n readonly items: ArrayLike<{ readonly kind: string; readonly type: string }>\n readonly types: readonly string[]\n}\n\ntype DomDragEvent = {\n readonly clientX: number\n readonly clientY: number\n readonly dataTransfer: DomDataTransfer | null\n readonly preventDefault: () => void\n}\n\ntype DomDropTarget = {\n readonly addEventListener: (\n type: string,\n listener: (event: DomDragEvent) => void,\n ) => void\n readonly getBoundingClientRect?: () => {\n readonly left: number\n readonly top: number\n }\n readonly removeEventListener: (\n type: string,\n listener: (event: DomDragEvent) => void,\n ) => void\n}\n\ntype DomFile = Blob & {\n readonly name: string\n readonly text: () => Promise<string>\n}\n\n/** The kinds of thing a drag carries, asked about one MIME type at a time. */\ntype DragTypes = {\n readonly has: (type: string) => boolean\n}\n\n/** Where something being dragged came over the target, from its top start corner. */\ntype DropEnterEvent = {\n readonly type: 'dropenter'\n readonly x: number\n readonly y: number\n}\n\n/** What landed on the target, where, and what the drop does with it. */\ntype DropEvent = {\n readonly dropOperation: Exclude<DropOperation, 'cancel'>\n readonly items: readonly DropItem[]\n readonly type: 'drop'\n readonly x: number\n readonly y: number\n}\n\n/** Where something being dragged left the target. */\ntype DropExitEvent = {\n readonly type: 'dropexit'\n readonly x: number\n readonly y: number\n}\n\n/** What the target does with each moment of a drag, all optional. */\ntype DropHandlers = {\n readonly getDropOperation?:\n | ((\n types: DragTypes,\n allowedOperations: readonly DropOperation[],\n ) => DropOperation)\n | undefined\n readonly onDrop?: ((event: DropEvent) => void) | undefined\n readonly onDropEnter?: ((event: DropEnterEvent) => void) | undefined\n readonly onDropExit?: ((event: DropExitEvent) => void) | undefined\n}\n\ntype DropItem = FileDropItem | TextDropItem\n\n/** What a drop does with what it carries, as web's drag and drop names it. */\ntype DropOperation = 'cancel' | 'copy' | 'link' | 'move'\n\n/**\n * A file dropped or picked: the file itself, and its contents as text, read\n * when asked for.\n */\ntype FileDropItem = PickedFile & {\n readonly getText: () => Promise<string>\n readonly kind: 'file'\n}\n\n/**\n * Text dropped from another page or app, in each of the MIME types it was\n * dragged as, such as `text/plain` and `text/uri-list`. Only React Native\n * Web takes one.\n */\ntype TextDropItem = {\n readonly getText: (type: string) => Promise<string>\n readonly kind: 'text'\n readonly types: ReadonlySet<string>\n}\n\n// Every operation, copy first: a file dragged in from the desktop is copied,\n// never moved.\nconst EVERY: readonly DropOperation[] = ['copy', 'link', 'move']\n\n// The operations each `effectAllowed` the dragging page set leaves open.\nconst ALLOWED: Readonly<Partial<Record<string, readonly DropOperation[]>>> = {\n all: EVERY,\n copy: ['copy'],\n copyLink: ['copy', 'link'],\n copyMove: ['copy', 'move'],\n link: ['link'],\n linkMove: ['link', 'move'],\n move: ['move'],\n none: [],\n uninitialized: EVERY,\n}\n\n// What a drag says of its files before it lands, and what a dragged string is\n// listed as. The browser lists files as `Files` alone, so their own types are\n// read off the items.\nconst FILES = 'Files'\n\n// What a drag over the target carries, read off its data transfer while it\n// is still over the target, where the browser shows only the types.\nfunction dragTypesOf(transfer: DomDataTransfer): DragTypes {\n const files = Array.from(transfer.items, (item) =>\n item.kind === 'file' ? item.type : undefined,\n ).filter((type) => type !== undefined)\n\n return typesOf([...transfer.types.filter((type) => type !== FILES), ...files])\n}\n\n// What a drop carries, read while the drop event runs, since the browser\n// guards the data transfer once it has: each file, and every string type\n// together as one text item.\nfunction droppedItemsOf(transfer: DomDataTransfer): DropItem[] {\n const files = Array.from(transfer.files, (file): FileDropItem => ({\n getText: async () => file.text(),\n kind: 'file',\n name: file.name,\n size: file.size,\n type: file.type,\n uri: URL.createObjectURL(file),\n }))\n const texts = new Map(\n transfer.types\n .filter((type) => type !== FILES)\n .map((type) => [type, transfer.getData(type)]),\n )\n\n if (texts.size === 0) {\n return files\n }\n\n const text: TextDropItem = {\n getText: async (type) => Promise.resolve(texts.get(type) ?? ''),\n kind: 'text',\n types: new Set(texts.keys()),\n }\n\n return [...files, text]\n}\n\n/** A picked file as a file drop item, whose text is read from its URI. */\nfunction fileItemOf(file: PickedFile): FileDropItem {\n return {\n ...file,\n getText: async () => {\n const response = await fetch(file.uri)\n return response.text()\n },\n kind: 'file',\n }\n}\n\n/**\n * Whether drops can be watched on a node: under React Native Web, where a\n * View's node is its DOM element.\n */\nfunction isDropTarget(node: unknown): node is DomDropTarget {\n return (\n typeof node === 'object' &&\n node !== null &&\n 'addEventListener' in node &&\n 'removeEventListener' in node\n )\n}\n\n/** Whether an item is a file, for picking the files out of a drop. */\nfunction isFileDropItem(item: DropItem): item is FileDropItem {\n return item.kind === 'file'\n}\n\n/** Whether an item is dropped text, for picking it out of a drop. */\nfunction isTextDropItem(item: DropItem): item is TextDropItem {\n return item.kind === 'text'\n}\n\n/**\n * The operation a drop of these types would do: the call site's answer, else\n * the first the drag allows, else none at all.\n */\nfunction operationOf(\n handlers: DropHandlers,\n types: DragTypes,\n allowed: readonly DropOperation[],\n): DropOperation {\n const first = allowed.at(0)\n\n if (first === undefined) {\n return 'cancel'\n }\n return handlers.getDropOperation?.(types, allowed) ?? first\n}\n\n/** The kinds of thing a set of items carries, for `getDropOperation`. */\nfunction typesOf(types: Iterable<string>): DragTypes {\n const set = new Set(types)\n return { has: (type) => set.has(type) }\n}\n\n/**\n * Takes HTML5 drag and drop on a React Native Web element, as web's React\n * Aria does on a DropZone: `onDropEnter` once something the target will take\n * comes over it, `onDropExit` once it leaves or lands, and `onDrop` with what\n * landed. `handlers` is read at each event, so it can follow the props. A\n * drag crossing the target's own children stays over it, counted in and out\n * as the browser reports each. While `isDisabled` returns true nothing is\n * taken, and the browser shows that nothing will be. It hands back what\n * stops it.\n */\nfunction watchDrops(\n target: DomDropTarget,\n handlers: () => DropHandlers,\n isDisabled: () => boolean,\n setOver: (isOver: boolean) => void,\n) {\n let depth = 0\n let over = false\n\n const point = (event: DomDragEvent) => {\n const box = target.getBoundingClientRect?.() ?? { left: 0, top: 0 }\n return { x: event.clientX - box.left, y: event.clientY - box.top }\n }\n const operation = (event: DomDragEvent) =>\n event.dataTransfer === null || isDisabled()\n ? 'cancel'\n : operationOf(\n handlers(),\n dragTypesOf(event.dataTransfer),\n ALLOWED[event.dataTransfer.effectAllowed] ?? EVERY,\n )\n const leave = (event: DomDragEvent) => {\n if (over) {\n over = false\n setOver(false)\n handlers().onDropExit?.({ type: 'dropexit', ...point(event) })\n }\n }\n\n const onDragEnter = (event: DomDragEvent) => {\n depth += 1\n\n if (depth === 1 && operation(event) !== 'cancel') {\n event.preventDefault()\n over = true\n setOver(true)\n handlers().onDropEnter?.({ type: 'dropenter', ...point(event) })\n }\n }\n const onDragOver = (event: DomDragEvent) => {\n const chosen = operation(event)\n\n if (event.dataTransfer !== null) {\n event.dataTransfer.dropEffect = chosen === 'cancel' ? 'none' : chosen\n }\n if (chosen !== 'cancel') {\n event.preventDefault()\n }\n }\n const onDragLeave = (event: DomDragEvent) => {\n depth = Math.max(0, depth - 1)\n\n if (depth === 0) {\n leave(event)\n }\n }\n const onDrop = (event: DomDragEvent) => {\n const chosen = operation(event)\n\n depth = 0\n event.preventDefault()\n\n if (chosen !== 'cancel' && event.dataTransfer !== null) {\n handlers().onDrop?.({\n dropOperation: chosen,\n items: droppedItemsOf(event.dataTransfer),\n type: 'drop',\n ...point(event),\n })\n }\n leave(event)\n }\n\n target.addEventListener('dragenter', onDragEnter)\n target.addEventListener('dragover', onDragOver)\n target.addEventListener('dragleave', onDragLeave)\n target.addEventListener('drop', onDrop)\n\n return () => {\n target.removeEventListener('dragenter', onDragEnter)\n target.removeEventListener('dragover', onDragOver)\n target.removeEventListener('dragleave', onDragLeave)\n target.removeEventListener('drop', onDrop)\n }\n}\n\nexport {\n fileItemOf,\n isDropTarget,\n isFileDropItem,\n isTextDropItem,\n operationOf,\n typesOf,\n watchDrops,\n}\nexport type {\n DragTypes,\n DropEnterEvent,\n DropEvent,\n DropExitEvent,\n DropHandlers,\n DropItem,\n DropOperation,\n FileDropItem,\n TextDropItem,\n}\n"],"mappings":"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"}