@bsky.app/sift 0.3.2 → 0.3.3

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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # @bsky.app/sift
2
2
 
3
+ ## 0.3.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [`345c167`](https://github.com/bluesky-social/toolbox/commit/345c1673c9cf8c83def2799326e15e2ec7a901e7) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Split outerStyle and innerStyle for sift to allow better customization"
8
+
3
9
  ## 0.3.2
4
10
 
5
11
  ### Patch Changes
package/build/Sift.d.ts CHANGED
@@ -3,7 +3,7 @@ import { type UseSiftReturn } from './useSift';
3
3
  export * from './useSift';
4
4
  export declare function Sift<Item extends {
5
5
  key: string;
6
- }>({ sift, data, render, style, onSelect, onDismiss, inverted, }: {
6
+ }>({ sift, data, render, outerStyle, innerStyle, onSelect, onDismiss, inverted, }: {
7
7
  sift: UseSiftReturn;
8
8
  data: Item[];
9
9
  render: (props: {
@@ -18,7 +18,14 @@ export declare function Sift<Item extends {
18
18
  };
19
19
  item: Item;
20
20
  }) => React.ReactElement;
21
- style?: StyleProp<ViewStyle>;
21
+ /**
22
+ * Applied to a View wrapping the FlatList.
23
+ */
24
+ outerStyle?: StyleProp<ViewStyle>;
25
+ /**
26
+ * Applied to the FlatList itself.
27
+ */
28
+ innerStyle?: StyleProp<ViewStyle>;
22
29
  onSelect?: (item: Item) => void;
23
30
  onDismiss?: () => void;
24
31
  inverted?: boolean;
@@ -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;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,KAAK,EAAE,MAAM,CAAA;QACb,OAAO,EAAE,OAAO,CAAA;QAChB,MAAM,EAAE,OAAO,CAAA;QACf,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,2CAqFA;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"}
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,UAAU,EACV,UAAU,EACV,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,KAAK,EAAE,MAAM,CAAA;QACb,OAAO,EAAE,OAAO,CAAA;QAChB,MAAM,EAAE,OAAO,CAAA;QACf,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;;OAEG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;IACjC;;OAEG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;IACjC,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,2CA2FA;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
@@ -4,7 +4,7 @@ import { View, FlatList, Pressable, } from 'react-native';
4
4
  import { useKeyboardHandling } from './useKeyboardHandling';
5
5
  export * from './useSift';
6
6
  const keyExtractor = (item) => item.key;
7
- export function Sift({ sift, data, render, style, onSelect, onDismiss, inverted, }) {
7
+ export function Sift({ sift, data, render, outerStyle, innerStyle, onSelect, onDismiss, inverted, }) {
8
8
  const [activeIndex, setActiveIndex] = useState(0);
9
9
  const activeIndexRef = useRef(activeIndex);
10
10
  activeIndexRef.current = activeIndex;
@@ -53,7 +53,12 @@ export function Sift({ sift, data, render, style, onSelect, onDismiss, inverted,
53
53
  onDismiss,
54
54
  });
55
55
  const hasStyles = sift.popoverStyles.top != null;
56
- return (_jsx(View, { collapsable: false, ref: sift.refs.setPopover, role: 'listbox', id: sift.id, style: [style, sift.popoverStyles, !hasStyles && { opacity: 0 }],
56
+ return (_jsx(View, { collapsable: false, ref: sift.refs.setPopover, role: 'listbox', id: sift.id, style: [
57
+ { width: '100%' },
58
+ outerStyle,
59
+ sift.popoverStyles,
60
+ !hasStyles && { opacity: 0 },
61
+ ],
57
62
  // @ts-ignore web only
58
63
  onMouseDown: e => {
59
64
  e.preventDefault();
@@ -68,7 +73,7 @@ export function Sift({ sift, data, render, style, onSelect, onDismiss, inverted,
68
73
  onPress: () => onSelectRef.current?.(item.item),
69
74
  },
70
75
  item: item.item,
71
- }), []), keyboardShouldPersistTaps: "handled" }) }));
76
+ }), []), keyboardShouldPersistTaps: "handled", style: innerStyle }) }));
72
77
  }
73
78
  /**
74
79
  * 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":"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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 index: number\n isFirst: boolean\n isLast: boolean\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 (item: {item: Item; index: number}) =>\n renderRef.current({\n index: item.index,\n isFirst: item.index === 0,\n isLast: item.index === data.length - 1,\n active: item.index === activeIndexRef.current,\n props: {\n role: 'option',\n 'aria-selected': item.index === activeIndexRef.current,\n onPress: () => onSelectRef.current?.(item.item),\n },\n item: item.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"]}
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 outerStyle,\n innerStyle,\n onSelect,\n onDismiss,\n inverted,\n}: {\n sift: UseSiftReturn\n data: Item[]\n render: (props: {\n index: number\n isFirst: boolean\n isLast: boolean\n active: boolean\n props: {\n role: string\n 'aria-selected': boolean\n onPress: () => void\n }\n item: Item\n }) => React.ReactElement\n /**\n * Applied to a View wrapping the FlatList.\n */\n outerStyle?: StyleProp<ViewStyle>\n /**\n * Applied to the FlatList itself.\n */\n innerStyle?: 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={[\n {width: '100%'},\n outerStyle,\n sift.popoverStyles,\n !hasStyles && {opacity: 0},\n ]}\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 (item: {item: Item; index: number}) =>\n renderRef.current({\n index: item.index,\n isFirst: item.index === 0,\n isLast: item.index === data.length - 1,\n active: item.index === activeIndexRef.current,\n props: {\n role: 'option',\n 'aria-selected': item.index === activeIndexRef.current,\n onPress: () => onSelectRef.current?.(item.item),\n },\n item: item.item,\n }),\n [],\n )}\n keyboardShouldPersistTaps=\"handled\"\n style={innerStyle}\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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bsky.app/sift",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "license": "MIT",
5
5
  "description": "A little React Native library for building autocompletes.",
6
6
  "repository": "https://github.com/bluesky-social/toolbox",
package/src/Sift.tsx CHANGED
@@ -19,7 +19,8 @@ export function Sift<Item extends {key: string}>({
19
19
  sift,
20
20
  data,
21
21
  render,
22
- style,
22
+ outerStyle,
23
+ innerStyle,
23
24
  onSelect,
24
25
  onDismiss,
25
26
  inverted,
@@ -38,7 +39,14 @@ export function Sift<Item extends {key: string}>({
38
39
  }
39
40
  item: Item
40
41
  }) => React.ReactElement
41
- style?: StyleProp<ViewStyle>
42
+ /**
43
+ * Applied to a View wrapping the FlatList.
44
+ */
45
+ outerStyle?: StyleProp<ViewStyle>
46
+ /**
47
+ * Applied to the FlatList itself.
48
+ */
49
+ innerStyle?: StyleProp<ViewStyle>
42
50
  onSelect?: (item: Item) => void
43
51
  onDismiss?: () => void
44
52
  inverted?: boolean
@@ -97,7 +105,12 @@ export function Sift<Item extends {key: string}>({
97
105
  ref={sift.refs.setPopover}
98
106
  role={'listbox' as any}
99
107
  id={sift.id}
100
- style={[style, sift.popoverStyles, !hasStyles && {opacity: 0}]}
108
+ style={[
109
+ {width: '100%'},
110
+ outerStyle,
111
+ sift.popoverStyles,
112
+ !hasStyles && {opacity: 0},
113
+ ]}
101
114
  // @ts-ignore web only
102
115
  onMouseDown={e => {
103
116
  e.preventDefault()
@@ -124,6 +137,7 @@ export function Sift<Item extends {key: string}>({
124
137
  [],
125
138
  )}
126
139
  keyboardShouldPersistTaps="handled"
140
+ style={innerStyle}
127
141
  />
128
142
  </View>
129
143
  )