@bsky.app/sift 0.2.4 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/build/Sift.d.ts.map +1 -1
- package/build/Sift.js +34 -22
- package/build/Sift.js.map +1 -1
- package/package.json +1 -1
- package/src/Sift.tsx +47 -31
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @bsky.app/sift
|
|
2
2
|
|
|
3
|
+
## 0.2.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`4765658`](https://github.com/bluesky-social/toolbox/commit/4765658af7c35212d3fab55c306c60479162bbd2) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Minor optimizations
|
|
8
|
+
|
|
9
|
+
## 0.2.5
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [`585e3f0`](https://github.com/bluesky-social/toolbox/commit/585e3f0fd73f986ab4f49d29551f182d296eeaad) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - onMouseDown and keyboardShouldPersistTaps for better outside click and selection handling
|
|
14
|
+
|
|
3
15
|
## 0.2.4
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/build/Sift.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Sift.d.ts","sourceRoot":"","sources":["../src/Sift.tsx"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,cAAc,EAEpB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAC,KAAK,aAAa,EAAC,MAAM,WAAW,CAAA;AAG5C,cAAc,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"Sift.d.ts","sourceRoot":"","sources":["../src/Sift.tsx"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,cAAc,EAEpB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAC,KAAK,aAAa,EAAC,MAAM,WAAW,CAAA;AAG5C,cAAc,WAAW,CAAA;AAIzB,wBAAgB,IAAI,CAAC,IAAI,SAAS;IAAC,GAAG,EAAE,MAAM,CAAA;CAAC,EAAE,EAC/C,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,KAAK,EACL,QAAQ,EACR,SAAS,EACT,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,aAAa,CAAA;IACnB,IAAI,EAAE,IAAI,EAAE,CAAA;IACZ,MAAM,EAAE,CAAC,KAAK,EAAE;QACd,MAAM,EAAE,OAAO,CAAA;QACf,KAAK,EAAE;YACL,IAAI,EAAE,MAAM,CAAA;YACZ,eAAe,EAAE,OAAO,CAAA;YACxB,OAAO,EAAE,MAAM,IAAI,CAAA;SACpB,CAAA;QACD,IAAI,EAAE,IAAI,CAAA;KACX,KAAK,KAAK,CAAC,YAAY,CAAA;IACxB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;IAC5B,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAA;IAC/B,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,2CAkFA;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,EACvB,QAAQ,EACR,IAAI,EACJ,KAAK,EACL,GAAG,KAAK,EACT,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EACF,SAAS,CAAC,SAAS,CAAC,GACpB,CAAC,CAAC,KAAK,EAAE;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAC,KAAK,SAAS,CAAC,SAAS,CAAC,CAAC,GACvE,SAAS,CAAA;CACd,2CASA"}
|
package/build/Sift.js
CHANGED
|
@@ -1,38 +1,46 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useEffect, useRef, useState } from 'react';
|
|
2
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
3
3
|
import { View, FlatList, Pressable, } from 'react-native';
|
|
4
4
|
import { useKeyboardHandling } from './useKeyboardHandling';
|
|
5
5
|
export * from './useSift';
|
|
6
|
+
const keyExtractor = (item) => item.key;
|
|
6
7
|
export function Sift({ sift, data, render, style, onSelect, onDismiss, inverted, }) {
|
|
7
8
|
const [activeIndex, setActiveIndex] = useState(0);
|
|
8
9
|
const activeIndexRef = useRef(activeIndex);
|
|
9
10
|
activeIndexRef.current = activeIndex;
|
|
11
|
+
const dataLenRef = useRef(data.length);
|
|
12
|
+
dataLenRef.current = data.length;
|
|
10
13
|
const updateRef = useRef(sift.updatePosition);
|
|
11
14
|
updateRef.current = sift.updatePosition;
|
|
15
|
+
const renderRef = useRef(render);
|
|
16
|
+
renderRef.current = render;
|
|
17
|
+
const onSelectRef = useRef(onSelect);
|
|
18
|
+
onSelectRef.current = onSelect;
|
|
12
19
|
useEffect(() => {
|
|
13
|
-
|
|
20
|
+
if (activeIndexRef.current !== 0)
|
|
21
|
+
setActiveIndex(0);
|
|
14
22
|
updateRef.current();
|
|
15
23
|
}, [data.length]);
|
|
16
|
-
const next = () => {
|
|
17
|
-
if (
|
|
24
|
+
const next = useCallback(() => {
|
|
25
|
+
if (dataLenRef.current === 0)
|
|
18
26
|
return;
|
|
19
|
-
setActiveIndex(i => (i + 1) %
|
|
20
|
-
};
|
|
21
|
-
const prev = () => {
|
|
22
|
-
if (
|
|
27
|
+
setActiveIndex(i => (i + 1) % dataLenRef.current);
|
|
28
|
+
}, []);
|
|
29
|
+
const prev = useCallback(() => {
|
|
30
|
+
if (dataLenRef.current === 0)
|
|
23
31
|
return;
|
|
24
|
-
setActiveIndex(i => (i - 1 +
|
|
25
|
-
};
|
|
26
|
-
const first = () => {
|
|
27
|
-
if (
|
|
32
|
+
setActiveIndex(i => (i - 1 + dataLenRef.current) % dataLenRef.current);
|
|
33
|
+
}, []);
|
|
34
|
+
const first = useCallback(() => {
|
|
35
|
+
if (dataLenRef.current === 0)
|
|
28
36
|
return;
|
|
29
37
|
setActiveIndex(0);
|
|
30
|
-
};
|
|
31
|
-
const last = () => {
|
|
32
|
-
if (
|
|
38
|
+
}, []);
|
|
39
|
+
const last = useCallback(() => {
|
|
40
|
+
if (dataLenRef.current === 0)
|
|
33
41
|
return;
|
|
34
|
-
setActiveIndex(
|
|
35
|
-
};
|
|
42
|
+
setActiveIndex(dataLenRef.current - 1);
|
|
43
|
+
}, []);
|
|
36
44
|
useKeyboardHandling({
|
|
37
45
|
sift,
|
|
38
46
|
onArrowDown: inverted ? prev : next,
|
|
@@ -45,15 +53,19 @@ export function Sift({ sift, data, render, style, onSelect, onDismiss, inverted,
|
|
|
45
53
|
onDismiss,
|
|
46
54
|
});
|
|
47
55
|
const hasStyles = sift.popoverStyles.top != null;
|
|
48
|
-
return (_jsx(View, { collapsable: false, ref: sift.refs.setPopover, role:
|
|
49
|
-
|
|
56
|
+
return (_jsx(View, { collapsable: false, ref: sift.refs.setPopover, role: 'listbox', id: sift.id, style: [style, sift.popoverStyles, !hasStyles && { opacity: 0 }],
|
|
57
|
+
// @ts-ignore web only
|
|
58
|
+
onMouseDown: e => {
|
|
59
|
+
e.preventDefault();
|
|
60
|
+
}, children: _jsx(FlatList, { data: data, inverted: inverted, keyExtractor: keyExtractor, extraData: activeIndex, renderItem: useCallback((items) => renderRef.current({
|
|
61
|
+
active: items.index === activeIndexRef.current,
|
|
50
62
|
props: {
|
|
51
63
|
role: 'option',
|
|
52
|
-
'aria-selected': items.index ===
|
|
53
|
-
onPress: () =>
|
|
64
|
+
'aria-selected': items.index === activeIndexRef.current,
|
|
65
|
+
onPress: () => onSelectRef.current?.(items.item),
|
|
54
66
|
},
|
|
55
67
|
item: items.item,
|
|
56
|
-
}) }) }));
|
|
68
|
+
}), []), keyboardShouldPersistTaps: "handled" }) }));
|
|
57
69
|
}
|
|
58
70
|
/**
|
|
59
71
|
* A Pressable wrapper for items rendered in Sift. It applies the necessary
|
package/build/Sift.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Sift.js","sourceRoot":"","sources":["../src/Sift.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"Sift.js","sourceRoot":"","sources":["../src/Sift.tsx"],"names":[],"mappings":"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","sourcesContent":["import {useCallback, useEffect, useRef, useState} from 'react'\nimport {\n View,\n FlatList,\n Pressable,\n type StyleProp,\n type ViewStyle,\n type PressableProps,\n type Role,\n} from 'react-native'\nimport {type UseSiftReturn} from './useSift'\nimport {useKeyboardHandling} from './useKeyboardHandling'\n\nexport * from './useSift'\n\nconst keyExtractor = (item: {key: string}) => item.key\n\nexport function Sift<Item extends {key: string}>({\n sift,\n data,\n render,\n style,\n onSelect,\n onDismiss,\n inverted,\n}: {\n sift: UseSiftReturn\n data: Item[]\n render: (props: {\n active: boolean\n props: {\n role: string\n 'aria-selected': boolean\n onPress: () => void\n }\n item: Item\n }) => React.ReactElement\n style?: StyleProp<ViewStyle>\n onSelect?: (item: Item) => void\n onDismiss?: () => void\n inverted?: boolean\n}) {\n const [activeIndex, setActiveIndex] = useState(0)\n const activeIndexRef = useRef(activeIndex)\n activeIndexRef.current = activeIndex\n const dataLenRef = useRef(data.length)\n dataLenRef.current = data.length\n const updateRef = useRef(sift.updatePosition)\n updateRef.current = sift.updatePosition\n const renderRef = useRef(render)\n renderRef.current = render\n const onSelectRef = useRef(onSelect)\n onSelectRef.current = onSelect\n\n useEffect(() => {\n if (activeIndexRef.current !== 0) setActiveIndex(0)\n updateRef.current()\n }, [data.length])\n\n const next = useCallback(() => {\n if (dataLenRef.current === 0) return\n setActiveIndex(i => (i + 1) % dataLenRef.current)\n }, [])\n const prev = useCallback(() => {\n if (dataLenRef.current === 0) return\n setActiveIndex(i => (i - 1 + dataLenRef.current) % dataLenRef.current)\n }, [])\n const first = useCallback(() => {\n if (dataLenRef.current === 0) return\n setActiveIndex(0)\n }, [])\n const last = useCallback(() => {\n if (dataLenRef.current === 0) return\n setActiveIndex(dataLenRef.current - 1)\n }, [])\n\n useKeyboardHandling({\n sift,\n onArrowDown: inverted ? prev : next,\n onArrowUp: inverted ? next : prev,\n onHome: inverted ? last : first,\n onEnd: inverted ? first : last,\n onSelect: () => {\n onSelect?.(data[activeIndexRef.current])\n },\n onDismiss,\n })\n\n const hasStyles = sift.popoverStyles.top != null\n\n return (\n <View\n collapsable={false}\n ref={sift.refs.setPopover}\n role={'listbox' as any}\n id={sift.id}\n style={[style, sift.popoverStyles, !hasStyles && {opacity: 0}]}\n // @ts-ignore web only\n onMouseDown={e => {\n e.preventDefault()\n }}>\n <FlatList\n data={data}\n inverted={inverted}\n keyExtractor={keyExtractor}\n extraData={activeIndex}\n renderItem={useCallback(\n (items: {item: Item; index: number}) =>\n renderRef.current({\n active: items.index === activeIndexRef.current,\n props: {\n role: 'option',\n 'aria-selected': items.index === activeIndexRef.current,\n onPress: () => onSelectRef.current?.(items.item),\n },\n item: items.item,\n }),\n [],\n )}\n keyboardShouldPersistTaps=\"handled\"\n />\n </View>\n )\n}\n\n/**\n * A Pressable wrapper for items rendered in Sift. It applies the necessary\n * accessibility props for each item.\n */\nexport function SiftItem({\n children,\n role,\n style,\n ...props\n}: Omit<PressableProps, 'role' | 'style'> & {\n role?: string\n style?:\n | StyleProp<ViewStyle>\n | ((state: {pressed: boolean; hovered: boolean}) => StyleProp<ViewStyle>)\n | undefined\n}) {\n return (\n <Pressable\n role={role as Role}\n style={style as PressableProps['style']}\n {...props}>\n {children}\n </Pressable>\n )\n}\n"]}
|
package/package.json
CHANGED
package/src/Sift.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {useEffect, useRef, useState} from 'react'
|
|
1
|
+
import {useCallback, useEffect, useRef, useState} from 'react'
|
|
2
2
|
import {
|
|
3
3
|
View,
|
|
4
4
|
FlatList,
|
|
@@ -13,6 +13,8 @@ import {useKeyboardHandling} from './useKeyboardHandling'
|
|
|
13
13
|
|
|
14
14
|
export * from './useSift'
|
|
15
15
|
|
|
16
|
+
const keyExtractor = (item: {key: string}) => item.key
|
|
17
|
+
|
|
16
18
|
export function Sift<Item extends {key: string}>({
|
|
17
19
|
sift,
|
|
18
20
|
data,
|
|
@@ -41,30 +43,36 @@ export function Sift<Item extends {key: string}>({
|
|
|
41
43
|
const [activeIndex, setActiveIndex] = useState(0)
|
|
42
44
|
const activeIndexRef = useRef(activeIndex)
|
|
43
45
|
activeIndexRef.current = activeIndex
|
|
46
|
+
const dataLenRef = useRef(data.length)
|
|
47
|
+
dataLenRef.current = data.length
|
|
44
48
|
const updateRef = useRef(sift.updatePosition)
|
|
45
49
|
updateRef.current = sift.updatePosition
|
|
50
|
+
const renderRef = useRef(render)
|
|
51
|
+
renderRef.current = render
|
|
52
|
+
const onSelectRef = useRef(onSelect)
|
|
53
|
+
onSelectRef.current = onSelect
|
|
46
54
|
|
|
47
55
|
useEffect(() => {
|
|
48
|
-
setActiveIndex(0)
|
|
56
|
+
if (activeIndexRef.current !== 0) setActiveIndex(0)
|
|
49
57
|
updateRef.current()
|
|
50
58
|
}, [data.length])
|
|
51
59
|
|
|
52
|
-
const next = () => {
|
|
53
|
-
if (
|
|
54
|
-
setActiveIndex(i => (i + 1) %
|
|
55
|
-
}
|
|
56
|
-
const prev = () => {
|
|
57
|
-
if (
|
|
58
|
-
setActiveIndex(i => (i - 1 +
|
|
59
|
-
}
|
|
60
|
-
const first = () => {
|
|
61
|
-
if (
|
|
60
|
+
const next = useCallback(() => {
|
|
61
|
+
if (dataLenRef.current === 0) return
|
|
62
|
+
setActiveIndex(i => (i + 1) % dataLenRef.current)
|
|
63
|
+
}, [])
|
|
64
|
+
const prev = useCallback(() => {
|
|
65
|
+
if (dataLenRef.current === 0) return
|
|
66
|
+
setActiveIndex(i => (i - 1 + dataLenRef.current) % dataLenRef.current)
|
|
67
|
+
}, [])
|
|
68
|
+
const first = useCallback(() => {
|
|
69
|
+
if (dataLenRef.current === 0) return
|
|
62
70
|
setActiveIndex(0)
|
|
63
|
-
}
|
|
64
|
-
const last = () => {
|
|
65
|
-
if (
|
|
66
|
-
setActiveIndex(
|
|
67
|
-
}
|
|
71
|
+
}, [])
|
|
72
|
+
const last = useCallback(() => {
|
|
73
|
+
if (dataLenRef.current === 0) return
|
|
74
|
+
setActiveIndex(dataLenRef.current - 1)
|
|
75
|
+
}, [])
|
|
68
76
|
|
|
69
77
|
useKeyboardHandling({
|
|
70
78
|
sift,
|
|
@@ -84,24 +92,32 @@ export function Sift<Item extends {key: string}>({
|
|
|
84
92
|
<View
|
|
85
93
|
collapsable={false}
|
|
86
94
|
ref={sift.refs.setPopover}
|
|
87
|
-
role={
|
|
95
|
+
role={'listbox' as any}
|
|
88
96
|
id={sift.id}
|
|
89
|
-
style={[style, sift.popoverStyles, !hasStyles && {opacity: 0}]}
|
|
97
|
+
style={[style, sift.popoverStyles, !hasStyles && {opacity: 0}]}
|
|
98
|
+
// @ts-ignore web only
|
|
99
|
+
onMouseDown={e => {
|
|
100
|
+
e.preventDefault()
|
|
101
|
+
}}>
|
|
90
102
|
<FlatList
|
|
91
103
|
data={data}
|
|
92
104
|
inverted={inverted}
|
|
93
|
-
keyExtractor={
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
+
keyExtractor={keyExtractor}
|
|
106
|
+
extraData={activeIndex}
|
|
107
|
+
renderItem={useCallback(
|
|
108
|
+
(items: {item: Item; index: number}) =>
|
|
109
|
+
renderRef.current({
|
|
110
|
+
active: items.index === activeIndexRef.current,
|
|
111
|
+
props: {
|
|
112
|
+
role: 'option',
|
|
113
|
+
'aria-selected': items.index === activeIndexRef.current,
|
|
114
|
+
onPress: () => onSelectRef.current?.(items.item),
|
|
115
|
+
},
|
|
116
|
+
item: items.item,
|
|
117
|
+
}),
|
|
118
|
+
[],
|
|
119
|
+
)}
|
|
120
|
+
keyboardShouldPersistTaps="handled"
|
|
105
121
|
/>
|
|
106
122
|
</View>
|
|
107
123
|
)
|