@tamagui/select 1.0.1-beta.151 → 1.0.1-beta.154
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/dist/cjs/BubbleSelect.js +24 -19
- package/dist/cjs/BubbleSelect.js.map +1 -1
- package/dist/cjs/Select.js +342 -301
- package/dist/cjs/Select.js.map +2 -2
- package/dist/cjs/SelectContent.js +18 -15
- package/dist/cjs/SelectContent.js.map +1 -1
- package/dist/cjs/SelectContent.native.js.map +1 -1
- package/dist/cjs/SelectImpl.js +9 -4
- package/dist/cjs/SelectImpl.js.map +2 -2
- package/dist/cjs/SelectScrollButton.js +109 -95
- package/dist/cjs/SelectScrollButton.js.map +2 -2
- package/dist/cjs/SelectViewport.js +49 -35
- package/dist/cjs/SelectViewport.js.map +2 -2
- package/dist/cjs/SelectViewport.native.js +5 -7
- package/dist/cjs/SelectViewport.native.js.map +1 -1
- package/dist/cjs/context.js.map +1 -1
- package/dist/esm/BubbleSelect.js +20 -18
- package/dist/esm/BubbleSelect.js.map +1 -1
- package/dist/esm/Select.js +338 -300
- package/dist/esm/Select.js.map +2 -2
- package/dist/esm/SelectContent.js +18 -12
- package/dist/esm/SelectContent.js.map +1 -1
- package/dist/esm/SelectContent.native.js.map +1 -1
- package/dist/esm/SelectImpl.js +5 -3
- package/dist/esm/SelectImpl.js.map +2 -2
- package/dist/esm/SelectScrollButton.js +105 -94
- package/dist/esm/SelectScrollButton.js.map +2 -2
- package/dist/esm/SelectViewport.js +45 -34
- package/dist/esm/SelectViewport.js.map +1 -1
- package/dist/esm/SelectViewport.native.js +5 -4
- package/dist/esm/SelectViewport.native.js.map +1 -1
- package/dist/esm/context.js.map +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/jsx/BubbleSelect.js +20 -18
- package/dist/jsx/BubbleSelect.js.map +1 -1
- package/dist/jsx/Select.js +217 -196
- package/dist/jsx/Select.js.map +2 -2
- package/dist/jsx/SelectContent.js.map +1 -1
- package/dist/jsx/SelectContent.native.js.map +1 -1
- package/dist/jsx/SelectImpl.js.map +2 -2
- package/dist/jsx/SelectScrollButton.js +79 -69
- package/dist/jsx/SelectScrollButton.js.map +1 -1
- package/dist/jsx/SelectViewport.js +25 -23
- package/dist/jsx/SelectViewport.js.map +1 -1
- package/dist/jsx/SelectViewport.native.js.map +1 -1
- package/dist/jsx/context.js.map +1 -1
- package/dist/jsx/index.js.map +1 -1
- package/package.json +12 -12
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/SelectViewport.tsx"],
|
|
4
4
|
"sourcesContent": ["import { FloatingFocusManager } from '@floating-ui/react-dom-interactions'\nimport { TamaguiElement, isWeb } from '@tamagui/core'\nimport { styled } from '@tamagui/core'\nimport { PortalItem } from '@tamagui/portal'\nimport { ThemeableStack } from '@tamagui/stacks'\nimport * as React from 'react'\n\nimport { VIEWPORT_NAME } from './constants'\nimport { useSelectContext } from './context'\nimport { useSelectBreakpointActive } from './Select'\nimport { ScopedProps, SelectViewportProps } from './types'\n\n/* -------------------------------------------------------------------------------------------------\n * SelectViewport\n * -----------------------------------------------------------------------------------------------*/\n\nexport const SelectViewportFrame = styled(ThemeableStack, {\n name: VIEWPORT_NAME,\n backgroundColor: '$background',\n elevate: true,\n bordered: true,\n overflow: 'scroll',\n userSelect: 'none',\n\n variants: {\n size: {\n '...size': (val, { tokens }) => {\n return {\n borderRadius: tokens.radius[val] ?? val,\n }\n },\n },\n },\n\n defaultVariants: {\n size: '$2',\n },\n})\n\nexport const SelectViewport = React.forwardRef<TamaguiElement, SelectViewportProps>(\n (props: ScopedProps<SelectViewportProps>, forwardedRef) => {\n const { __scopeSelect, children, ...viewportProps } = props\n const context = useSelectContext(VIEWPORT_NAME, __scopeSelect)\n const breakpointActive = useSelectBreakpointActive(context.sheetBreakpoint)\n\n if (breakpointActive || !isWeb) {\n return <PortalItem hostName={`${context.scopeKey}SheetContents`}>{children}</PortalItem>\n }\n\n if (!context.floatingContext) {\n return null\n }\n\n if (!context.open) {\n return children\n }\n\n const {\n style: { scrollbarWidth, listStyleType, ...restStyle },\n ...floatingProps\n } = context.interactions!.getFloatingProps()\n\n return (\n <>\n <style\n dangerouslySetInnerHTML={{\n __html: selectViewportCSS,\n }}\n />\n <FloatingFocusManager context={context.floatingContext} preventTabbing>\n <SelectViewportFrame\n size={context.size}\n // @ts-ignore\n role=\"presentation\"\n {...viewportProps}\n ref={forwardedRef}\n {...floatingProps}\n {...restStyle}\n >\n {children}\n </SelectViewportFrame>\n </FloatingFocusManager>\n </>\n )\n }\n)\n\nSelectViewport.displayName = VIEWPORT_NAME\n\nconst selectViewportCSS = `\n.is_SelectViewport {\n scrollbar-width: none;\n -webkit-overflow-scrolling: touch;\n overscroll-behavior: contain;\n}\n\n.is_SelectViewport::-webkit-scrollbar{\n display:none\n}\n`\n"],
|
|
5
|
-
"mappings": "
|
|
5
|
+
"mappings": "AA8Ca,SAiBP,UAjBO,KAiBP,YAjBO;AA9Cb,SAAS,4BAA4B;AACrC,SAAyB,aAAa;AACtC,SAAS,cAAc;AACvB,SAAS,kBAAkB;AAC3B,SAAS,sBAAsB;AAC/B,YAAY,WAAW;AAEvB,SAAS,qBAAqB;AAC9B,SAAS,wBAAwB;AACjC,SAAS,iCAAiC;AAOnC,MAAM,sBAAsB,OAAO,gBAAgB;AAAA,EACxD,MAAM;AAAA,EACN,iBAAiB;AAAA,EACjB,SAAS;AAAA,EACT,UAAU;AAAA,EACV,UAAU;AAAA,EACV,YAAY;AAAA,EAEZ,UAAU;AAAA,IACR,MAAM;AAAA,MACJ,WAAW,CAAC,KAAK,EAAE,OAAO,MAAM;AAC9B,eAAO;AAAA,UACL,cAAc,OAAO,OAAO,QAAQ;AAAA,QACtC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,iBAAiB;AAAA,IACf,MAAM;AAAA,EACR;AACF,CAAC;AAEM,MAAM,iBAAiB,MAAM;AAAA,EAClC,CAAC,OAAyC,iBAAiB;AACzD,UAAM,EAAE,eAAe,aAAa,cAAc,IAAI;AACtD,UAAM,UAAU,iBAAiB,eAAe,aAAa;AAC7D,UAAM,mBAAmB,0BAA0B,QAAQ,eAAe;AAE1E,QAAI,oBAAoB,CAAC,OAAO;AAC9B,aAAO,oBAAC;AAAA,QAAW,UAAU,GAAG,QAAQ;AAAA,QAA0B;AAAA,OAAS;AAAA,IAC7E;AAEA,QAAI,CAAC,QAAQ,iBAAiB;AAC5B,aAAO;AAAA,IACT;AAEA,QAAI,CAAC,QAAQ,MAAM;AACjB,aAAO;AAAA,IACT;AAEA,UAAM;AAAA,MACJ,OAAO,EAAE,gBAAgB,kBAAkB,UAAU;AAAA,SAClD;AAAA,IACL,IAAI,QAAQ,aAAc,iBAAiB;AAE3C,WACE;AAAA,MACE;AAAA,4BAAC;AAAA,UACC,yBAAyB;AAAA,YACvB,QAAQ;AAAA,UACV;AAAA,SACF;AAAA,QACA,oBAAC;AAAA,UAAqB,SAAS,QAAQ;AAAA,UAAiB,gBAAc;AAAA,UACpE,8BAAC;AAAA,YACC,MAAM,QAAQ;AAAA,YAEd,MAAK;AAAA,YACJ,GAAG;AAAA,YACJ,KAAK;AAAA,YACJ,GAAG;AAAA,YACH,GAAG;AAAA,YAEH;AAAA,WACH;AAAA,SACF;AAAA;AAAA,KACF;AAAA,EAEJ;AACF;AAEA,eAAe,cAAc;AAE7B,MAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
1
2
|
import { PortalItem } from "@tamagui/portal";
|
|
2
|
-
import * as React from "react";
|
|
3
3
|
import { VIEWPORT_NAME } from "./constants";
|
|
4
4
|
import { useSelectContext } from "./context";
|
|
5
5
|
const SelectViewport = (props) => {
|
|
6
6
|
const { __scopeSelect, children } = props;
|
|
7
7
|
const context = useSelectContext(VIEWPORT_NAME, __scopeSelect);
|
|
8
|
-
return /* @__PURE__ */
|
|
9
|
-
hostName: `${context.scopeKey}SheetContents
|
|
10
|
-
|
|
8
|
+
return /* @__PURE__ */ jsx(PortalItem, {
|
|
9
|
+
hostName: `${context.scopeKey}SheetContents`,
|
|
10
|
+
children
|
|
11
|
+
});
|
|
11
12
|
};
|
|
12
13
|
SelectViewport.displayName = VIEWPORT_NAME;
|
|
13
14
|
export {
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/SelectViewport.native.tsx"],
|
|
4
4
|
"sourcesContent": ["import { PortalItem } from '@tamagui/portal'\nimport * as React from 'react'\n\nimport { VIEWPORT_NAME } from './constants'\nimport { useSelectContext } from './context'\nimport { ScopedProps, SelectViewportProps } from './types'\n\nexport const SelectViewport = (props: ScopedProps<SelectViewportProps>) => {\n const { __scopeSelect, children } = props\n const context = useSelectContext(VIEWPORT_NAME, __scopeSelect)\n return <PortalItem hostName={`${context.scopeKey}SheetContents`}>{children}</PortalItem>\n}\n\nSelectViewport.displayName = VIEWPORT_NAME\n"],
|
|
5
|
-
"mappings": "
|
|
5
|
+
"mappings": "AAUS;AAVT,SAAS,kBAAkB;AAG3B,SAAS,qBAAqB;AAC9B,SAAS,wBAAwB;AAG1B,MAAM,iBAAiB,CAAC,UAA4C;AACzE,QAAM,EAAE,eAAe,SAAS,IAAI;AACpC,QAAM,UAAU,iBAAiB,eAAe,aAAa;AAC7D,SAAO,oBAAC;AAAA,IAAW,UAAU,GAAG,QAAQ;AAAA,IAA0B;AAAA,GAAS;AAC7E;AAEA,eAAe,cAAc;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/esm/context.js.map
CHANGED
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/context.tsx"],
|
|
4
4
|
"sourcesContent": ["import { createContextScope } from '@tamagui/create-context'\n\nimport { SELECT_NAME } from './constants'\nimport { SelectContextValue } from './types'\n\nexport const [createSelectContext, createSelectScope] = createContextScope(SELECT_NAME)\n\nexport const [SelectProvider, useSelectContext] =\n createSelectContext<SelectContextValue>(SELECT_NAME)\n"],
|
|
5
|
-
"mappings": "AAAA;
|
|
5
|
+
"mappings": "AAAA,SAAS,0BAA0B;AAEnC,SAAS,mBAAmB;AAGrB,MAAM,CAAC,qBAAqB,iBAAiB,IAAI,mBAAmB,WAAW;AAE/E,MAAM,CAAC,gBAAgB,gBAAgB,IAC5C,oBAAwC,WAAW;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/esm/index.js.map
CHANGED
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/index.tsx"],
|
|
4
4
|
"sourcesContent": ["export * from './Select'\nexport type {\n SelectContentProps,\n SelectProps,\n SelectScrollButtonProps,\n SelectViewportProps,\n} from './types'\nexport * from './context'\n"],
|
|
5
|
-
"mappings": "AAAA;
|
|
5
|
+
"mappings": "AAAA,cAAc;AAOd,cAAc;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/jsx/BubbleSelect.js
CHANGED
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
import { usePrevious } from "@radix-ui/react-use-previous";
|
|
2
2
|
import { useComposedRefs } from "@tamagui/compose-refs";
|
|
3
3
|
import * as React from "react";
|
|
4
|
-
const BubbleSelect = React.forwardRef(
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
4
|
+
const BubbleSelect = React.forwardRef(
|
|
5
|
+
(props, forwardedRef) => {
|
|
6
|
+
const { value, ...selectProps } = props;
|
|
7
|
+
const ref = React.useRef(null);
|
|
8
|
+
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
9
|
+
const prevValue = usePrevious(value);
|
|
10
|
+
React.useEffect(() => {
|
|
11
|
+
const select = ref.current;
|
|
12
|
+
const selectProto = window.HTMLSelectElement.prototype;
|
|
13
|
+
const descriptor = Object.getOwnPropertyDescriptor(selectProto, "value");
|
|
14
|
+
const setValue = descriptor.set;
|
|
15
|
+
if (prevValue !== value && setValue) {
|
|
16
|
+
const event = new Event("change", { bubbles: true });
|
|
17
|
+
setValue.call(select, value);
|
|
18
|
+
select.dispatchEvent(event);
|
|
19
|
+
}
|
|
20
|
+
}, [prevValue, value]);
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
);
|
|
22
24
|
//# sourceMappingURL=BubbleSelect.js.map
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/BubbleSelect.tsx"],
|
|
4
4
|
"sourcesContent": ["import { usePrevious } from '@radix-ui/react-use-previous'\nimport { useComposedRefs } from '@tamagui/compose-refs'\nimport * as React from 'react'\n\n/* -----------------------------------------------------------------------------------------------*/\nconst BubbleSelect = React.forwardRef<HTMLSelectElement, React.ComponentPropsWithoutRef<'select'>>(\n (props, forwardedRef) => {\n const { value, ...selectProps } = props\n const ref = React.useRef<HTMLSelectElement>(null)\n const composedRefs = useComposedRefs(forwardedRef, ref)\n const prevValue = usePrevious(value)\n\n // Bubble value change to parents (e.g form change event)\n React.useEffect(() => {\n const select = ref.current!\n const selectProto = window.HTMLSelectElement.prototype\n const descriptor = Object.getOwnPropertyDescriptor(selectProto, 'value') as PropertyDescriptor\n const setValue = descriptor.set\n if (prevValue !== value && setValue) {\n const event = new Event('change', { bubbles: true })\n setValue.call(select, value)\n select.dispatchEvent(event)\n }\n }, [prevValue, value])\n\n /**\n * We purposefully use a `select` here to support form autofill as much\n * as possible.\n *\n * We purposefully do not add the `value` attribute here to allow the value\n * to be set programatically and bubble to any parent form `onChange` event.\n * Adding the `value` will cause React to consider the programatic\n * dispatch a duplicate and it will get swallowed.\n *\n * We use `VisuallyHidden` rather than `display: \"none\"` because Safari autofill\n * won't work otherwise.\n */\n // TODO\n return null\n // return (\n // <VisuallyHidden asChild>\n // <select {...selectProps} ref={composedRefs} defaultValue={value} />\n // </VisuallyHidden>\n // )\n }\n)\n"],
|
|
5
|
-
"mappings": "AAAA;
|
|
5
|
+
"mappings": "AAAA,SAAS,mBAAmB;AAC5B,SAAS,uBAAuB;AAChC,YAAY,WAAW;AAGvB,MAAM,eAAe,MAAM;AAAA,EACzB,CAAC,OAAO,iBAAiB;AACvB,UAAM,EAAE,UAAU,YAAY,IAAI;AAClC,UAAM,MAAM,MAAM,OAA0B,IAAI;AAChD,UAAM,eAAe,gBAAgB,cAAc,GAAG;AACtD,UAAM,YAAY,YAAY,KAAK;AAGnC,UAAM,UAAU,MAAM;AACpB,YAAM,SAAS,IAAI;AACnB,YAAM,cAAc,OAAO,kBAAkB;AAC7C,YAAM,aAAa,OAAO,yBAAyB,aAAa,OAAO;AACvE,YAAM,WAAW,WAAW;AAC5B,UAAI,cAAc,SAAS,UAAU;AACnC,cAAM,QAAQ,IAAI,MAAM,UAAU,EAAE,SAAS,KAAK,CAAC;AACnD,iBAAS,KAAK,QAAQ,KAAK;AAC3B,eAAO,cAAc,KAAK;AAAA,MAC5B;AAAA,IACF,GAAG,CAAC,WAAW,KAAK,CAAC;AAerB,WAAO;AAAA,EAMT;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/jsx/Select.js
CHANGED
|
@@ -18,38 +18,44 @@ import { SelectInlineImpl } from "./SelectImpl";
|
|
|
18
18
|
import { SelectScrollDownButton, SelectScrollUpButton } from "./SelectScrollButton";
|
|
19
19
|
import { SelectViewport } from "./SelectViewport";
|
|
20
20
|
const TRIGGER_NAME = "SelectTrigger";
|
|
21
|
-
const SelectTrigger = React.forwardRef(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
21
|
+
const SelectTrigger = React.forwardRef(
|
|
22
|
+
(props, forwardedRef) => {
|
|
23
|
+
const {
|
|
24
|
+
__scopeSelect,
|
|
25
|
+
disabled = false,
|
|
26
|
+
"aria-labelledby": ariaLabelledby,
|
|
27
|
+
...triggerProps
|
|
28
|
+
} = props;
|
|
29
|
+
const context = useSelectContext(TRIGGER_NAME, __scopeSelect);
|
|
30
|
+
const labelledBy = ariaLabelledby;
|
|
31
|
+
return <ListItem componentName={TRIGGER_NAME} backgrounded radiused hoverTheme pressTheme focusTheme focusable borderWidth={1} size={context.size} aria-expanded={context.open} aria-autocomplete="none" aria-labelledby={labelledBy} dir={context.dir} disabled={disabled} data-disabled={disabled ? "" : void 0} {...triggerProps} ref={forwardedRef} {...process.env.TAMAGUI_TARGET === "web" && context.interactions ? context.interactions.getReferenceProps() : {
|
|
32
|
+
onPress() {
|
|
33
|
+
context.setOpen(!context.open);
|
|
34
|
+
}
|
|
35
|
+
}} />;
|
|
36
|
+
}
|
|
37
|
+
);
|
|
36
38
|
SelectTrigger.displayName = TRIGGER_NAME;
|
|
37
39
|
const VALUE_NAME = "SelectValue";
|
|
38
40
|
const SelectValueFrame = styled(Paragraph, {
|
|
39
41
|
name: VALUE_NAME,
|
|
40
42
|
selectable: false
|
|
41
43
|
});
|
|
42
|
-
const SelectValue = SelectValueFrame.extractable(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
44
|
+
const SelectValue = SelectValueFrame.extractable(
|
|
45
|
+
React.forwardRef(
|
|
46
|
+
({ __scopeSelect, children: childrenProp, placeholder }, forwardedRef) => {
|
|
47
|
+
const context = useSelectContext(VALUE_NAME, __scopeSelect);
|
|
48
|
+
const { onValueNodeHasChildrenChange } = context;
|
|
49
|
+
const hasChildren = childrenProp !== void 0;
|
|
50
|
+
const composedRefs = useComposedRefs(forwardedRef, context.onValueNodeChange);
|
|
51
|
+
useIsomorphicLayoutEffect(() => {
|
|
52
|
+
onValueNodeHasChildrenChange(hasChildren);
|
|
53
|
+
}, [onValueNodeHasChildrenChange, hasChildren]);
|
|
54
|
+
const children = childrenProp ?? context.selectedItem;
|
|
55
|
+
return <SelectValueFrame size={context.size} ref={composedRefs} pointerEvents="none">{context.value === void 0 && placeholder !== void 0 ? placeholder : children}</SelectValueFrame>;
|
|
56
|
+
}
|
|
57
|
+
)
|
|
58
|
+
);
|
|
53
59
|
SelectValue.displayName = VALUE_NAME;
|
|
54
60
|
const SelectIcon = styled(XStack, {
|
|
55
61
|
name: "SelectIcon",
|
|
@@ -58,121 +64,127 @@ const SelectIcon = styled(XStack, {
|
|
|
58
64
|
});
|
|
59
65
|
const ITEM_NAME = "SelectItem";
|
|
60
66
|
const [SelectItemContextProvider, useSelectItemContext] = createSelectContext(ITEM_NAME);
|
|
61
|
-
const SelectItem = React.forwardRef(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (
|
|
92
|
-
listRef
|
|
67
|
+
const SelectItem = React.forwardRef(
|
|
68
|
+
(props, forwardedRef) => {
|
|
69
|
+
const {
|
|
70
|
+
__scopeSelect,
|
|
71
|
+
value,
|
|
72
|
+
disabled = false,
|
|
73
|
+
textValue: textValueProp,
|
|
74
|
+
index,
|
|
75
|
+
...itemProps
|
|
76
|
+
} = props;
|
|
77
|
+
const context = useSelectContext(ITEM_NAME, __scopeSelect);
|
|
78
|
+
const isSelected = context.value === value;
|
|
79
|
+
const textId = useId();
|
|
80
|
+
const {
|
|
81
|
+
selectedIndex,
|
|
82
|
+
setSelectedIndex,
|
|
83
|
+
listRef,
|
|
84
|
+
open,
|
|
85
|
+
setOpen,
|
|
86
|
+
onChange,
|
|
87
|
+
setActiveIndex,
|
|
88
|
+
allowMouseUpRef,
|
|
89
|
+
allowSelectRef,
|
|
90
|
+
setValueAtIndex,
|
|
91
|
+
selectTimeoutRef,
|
|
92
|
+
dataRef
|
|
93
|
+
} = context;
|
|
94
|
+
const composedRefs = useComposedRefs(forwardedRef, (node) => {
|
|
95
|
+
if (!isWeb)
|
|
96
|
+
return;
|
|
97
|
+
if (node instanceof HTMLElement) {
|
|
98
|
+
if (listRef) {
|
|
99
|
+
listRef.current[index] = node;
|
|
100
|
+
}
|
|
93
101
|
}
|
|
102
|
+
});
|
|
103
|
+
React.useEffect(() => {
|
|
104
|
+
setValueAtIndex(index, value);
|
|
105
|
+
}, [index, setValueAtIndex, value]);
|
|
106
|
+
function handleSelect() {
|
|
107
|
+
setSelectedIndex(index);
|
|
108
|
+
onChange(value);
|
|
109
|
+
setOpen(false);
|
|
94
110
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
setValueAtIndex(index, value);
|
|
98
|
-
}, [index, setValueAtIndex, value]);
|
|
99
|
-
function handleSelect() {
|
|
100
|
-
setSelectedIndex(index);
|
|
101
|
-
onChange(value);
|
|
102
|
-
setOpen(false);
|
|
103
|
-
}
|
|
104
|
-
const selectItemProps = context.interactions ? context.interactions.getItemProps({
|
|
105
|
-
onTouchStart() {
|
|
106
|
-
allowSelectRef.current = true;
|
|
107
|
-
allowMouseUpRef.current = false;
|
|
108
|
-
},
|
|
109
|
-
onKeyDown(event) {
|
|
110
|
-
if (event.key === "Enter" || event.key === " " && !dataRef?.current.typing) {
|
|
111
|
-
event.preventDefault();
|
|
112
|
-
handleSelect();
|
|
113
|
-
} else {
|
|
111
|
+
const selectItemProps = context.interactions ? context.interactions.getItemProps({
|
|
112
|
+
onTouchStart() {
|
|
114
113
|
allowSelectRef.current = true;
|
|
114
|
+
allowMouseUpRef.current = false;
|
|
115
|
+
},
|
|
116
|
+
onKeyDown(event) {
|
|
117
|
+
if (event.key === "Enter" || event.key === " " && !dataRef?.current.typing) {
|
|
118
|
+
event.preventDefault();
|
|
119
|
+
handleSelect();
|
|
120
|
+
} else {
|
|
121
|
+
allowSelectRef.current = true;
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
onClick() {
|
|
125
|
+
if (allowSelectRef.current) {
|
|
126
|
+
setSelectedIndex(index);
|
|
127
|
+
setOpen(false);
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
onMouseUp() {
|
|
131
|
+
if (!allowMouseUpRef.current) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (allowSelectRef.current) {
|
|
135
|
+
handleSelect();
|
|
136
|
+
}
|
|
137
|
+
clearTimeout(selectTimeoutRef.current);
|
|
138
|
+
selectTimeoutRef.current = setTimeout(() => {
|
|
139
|
+
allowSelectRef.current = true;
|
|
140
|
+
});
|
|
115
141
|
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
},
|
|
123
|
-
onMouseUp() {
|
|
124
|
-
if (!allowMouseUpRef.current) {
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
if (allowSelectRef.current) {
|
|
128
|
-
handleSelect();
|
|
129
|
-
}
|
|
130
|
-
clearTimeout(selectTimeoutRef.current);
|
|
131
|
-
selectTimeoutRef.current = setTimeout(() => {
|
|
132
|
-
allowSelectRef.current = true;
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
}) : {
|
|
136
|
-
onPress: handleSelect
|
|
137
|
-
};
|
|
138
|
-
return <SelectItemContextProvider scope={__scopeSelect} value={value} textId={textId || ""} isSelected={isSelected}><ListItem backgrounded pressTheme focusTheme componentName={ITEM_NAME} ref={composedRefs} aria-labelledby={textId} aria-selected={isSelected} data-state={isSelected ? "active" : "inactive"} aria-disabled={disabled || void 0} data-disabled={disabled ? "" : void 0} tabIndex={disabled ? void 0 : -1} size={context.size} {...itemProps} {...selectItemProps} /></SelectItemContextProvider>;
|
|
139
|
-
});
|
|
142
|
+
}) : {
|
|
143
|
+
onPress: handleSelect
|
|
144
|
+
};
|
|
145
|
+
return <SelectItemContextProvider scope={__scopeSelect} value={value} textId={textId || ""} isSelected={isSelected}><ListItem backgrounded pressTheme focusTheme componentName={ITEM_NAME} ref={composedRefs} aria-labelledby={textId} aria-selected={isSelected} data-state={isSelected ? "active" : "inactive"} aria-disabled={disabled || void 0} data-disabled={disabled ? "" : void 0} tabIndex={disabled ? void 0 : -1} size={context.size} {...itemProps} {...selectItemProps} /></SelectItemContextProvider>;
|
|
146
|
+
}
|
|
147
|
+
);
|
|
140
148
|
SelectItem.displayName = ITEM_NAME;
|
|
141
149
|
const ITEM_TEXT_NAME = "SelectItemText";
|
|
142
150
|
const SelectItemTextFrame = styled(Paragraph, {
|
|
143
151
|
name: ITEM_TEXT_NAME,
|
|
144
152
|
selectable: false
|
|
145
153
|
});
|
|
146
|
-
const SelectItemText = React.forwardRef(
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
154
|
+
const SelectItemText = React.forwardRef(
|
|
155
|
+
(props, forwardedRef) => {
|
|
156
|
+
const { __scopeSelect, className, ...itemTextProps } = props;
|
|
157
|
+
const context = useSelectContext(ITEM_TEXT_NAME, __scopeSelect);
|
|
158
|
+
const itemContext = useSelectItemContext(ITEM_TEXT_NAME, __scopeSelect);
|
|
159
|
+
const ref = React.useRef(null);
|
|
160
|
+
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
161
|
+
const isSelected = itemContext.isSelected && context.valueNode && !context.valueNodeHasChildren;
|
|
162
|
+
const contents = <SelectItemTextFrame className={className} size={context.size} id={itemContext.textId} {...itemTextProps} ref={composedRefs} />;
|
|
163
|
+
if (!isWeb) {
|
|
164
|
+
React.useEffect(() => {
|
|
165
|
+
if (isSelected) {
|
|
166
|
+
context.setSelectedItem(contents);
|
|
167
|
+
}
|
|
168
|
+
}, [isSelected]);
|
|
169
|
+
}
|
|
170
|
+
return <>
|
|
171
|
+
{contents}
|
|
172
|
+
{isWeb && isSelected ? ReactDOM.createPortal(itemTextProps.children, context.valueNode) : null}
|
|
173
|
+
</>;
|
|
160
174
|
}
|
|
161
|
-
|
|
162
|
-
{contents}
|
|
163
|
-
{isWeb && isSelected ? ReactDOM.createPortal(itemTextProps.children, context.valueNode) : null}
|
|
164
|
-
</>;
|
|
165
|
-
});
|
|
175
|
+
);
|
|
166
176
|
SelectItemText.displayName = ITEM_TEXT_NAME;
|
|
167
177
|
const ITEM_INDICATOR_NAME = "SelectItemIndicator";
|
|
168
178
|
const SelectItemIndicatorFrame = styled(XStack, {
|
|
169
179
|
name: ITEM_TEXT_NAME
|
|
170
180
|
});
|
|
171
|
-
const SelectItemIndicator = React.forwardRef(
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}
|
|
181
|
+
const SelectItemIndicator = React.forwardRef(
|
|
182
|
+
(props, forwardedRef) => {
|
|
183
|
+
const { __scopeSelect, ...itemIndicatorProps } = props;
|
|
184
|
+
const itemContext = useSelectItemContext(ITEM_INDICATOR_NAME, __scopeSelect);
|
|
185
|
+
return itemContext.isSelected ? <SelectItemIndicatorFrame aria-hidden {...itemIndicatorProps} ref={forwardedRef} /> : null;
|
|
186
|
+
}
|
|
187
|
+
);
|
|
176
188
|
SelectItemIndicator.displayName = ITEM_INDICATOR_NAME;
|
|
177
189
|
const GROUP_NAME = "SelectGroup";
|
|
178
190
|
const [SelectGroupContextProvider, useSelectGroupContext] = createSelectContext(GROUP_NAME);
|
|
@@ -180,19 +192,23 @@ const SelectGroupFrame = styled(YStack, {
|
|
|
180
192
|
name: GROUP_NAME,
|
|
181
193
|
width: "100%"
|
|
182
194
|
});
|
|
183
|
-
const SelectGroup = React.forwardRef(
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
}
|
|
195
|
+
const SelectGroup = React.forwardRef(
|
|
196
|
+
(props, forwardedRef) => {
|
|
197
|
+
const { __scopeSelect, ...groupProps } = props;
|
|
198
|
+
const groupId = useId();
|
|
199
|
+
return <SelectGroupContextProvider scope={__scopeSelect} id={groupId || ""}><SelectGroupFrame role="group" aria-labelledby={groupId} {...groupProps} ref={forwardedRef} /></SelectGroupContextProvider>;
|
|
200
|
+
}
|
|
201
|
+
);
|
|
188
202
|
SelectGroup.displayName = GROUP_NAME;
|
|
189
203
|
const LABEL_NAME = "SelectLabel";
|
|
190
|
-
const SelectLabel = React.forwardRef(
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
}
|
|
204
|
+
const SelectLabel = React.forwardRef(
|
|
205
|
+
(props, forwardedRef) => {
|
|
206
|
+
const { __scopeSelect, ...labelProps } = props;
|
|
207
|
+
const context = useSelectContext(LABEL_NAME, __scopeSelect);
|
|
208
|
+
const groupContext = useSelectGroupContext(LABEL_NAME, __scopeSelect);
|
|
209
|
+
return <ListItem componentName={LABEL_NAME} fontWeight="800" id={groupContext.id} size={context.size} {...labelProps} ref={forwardedRef} />;
|
|
210
|
+
}
|
|
211
|
+
);
|
|
196
212
|
SelectLabel.displayName = LABEL_NAME;
|
|
197
213
|
const SelectSeparator = styled(Separator, {
|
|
198
214
|
name: "SelectSeparator"
|
|
@@ -225,66 +241,71 @@ SelectSheetContents.displayName = SHEET_CONTENTS_NAME;
|
|
|
225
241
|
const SelectSheetImpl = (props) => {
|
|
226
242
|
return <>{props.children}</>;
|
|
227
243
|
};
|
|
228
|
-
const Select = withStaticProperties(
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
}, {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
244
|
+
const Select = withStaticProperties(
|
|
245
|
+
(props) => {
|
|
246
|
+
const {
|
|
247
|
+
__scopeSelect,
|
|
248
|
+
children,
|
|
249
|
+
open: openProp,
|
|
250
|
+
defaultOpen,
|
|
251
|
+
onOpenChange,
|
|
252
|
+
value: valueProp,
|
|
253
|
+
defaultValue,
|
|
254
|
+
onValueChange,
|
|
255
|
+
size: sizeProp = "$4",
|
|
256
|
+
sheetBreakpoint = false,
|
|
257
|
+
dir
|
|
258
|
+
} = props;
|
|
259
|
+
const isSheet = useSelectBreakpointActive(sheetBreakpoint);
|
|
260
|
+
const SelectImpl = isSheet ? SelectSheetImpl : SelectInlineImpl;
|
|
261
|
+
const forceUpdate = React.useReducer(() => ({}), {})[1];
|
|
262
|
+
const [selectedItem, setSelectedItem] = React.useState(null);
|
|
263
|
+
const [open, setOpen] = useControllableState({
|
|
264
|
+
prop: openProp,
|
|
265
|
+
defaultProp: defaultOpen || false,
|
|
266
|
+
onChange: onOpenChange,
|
|
267
|
+
strategy: "most-recent-wins"
|
|
268
|
+
});
|
|
269
|
+
const [value, setValue] = useControllableState({
|
|
270
|
+
prop: valueProp,
|
|
271
|
+
defaultProp: defaultValue || "",
|
|
272
|
+
onChange: onValueChange,
|
|
273
|
+
strategy: "most-recent-wins"
|
|
274
|
+
});
|
|
275
|
+
const [activeIndex, setActiveIndex] = React.useState(null);
|
|
276
|
+
const selectedIndexRef = React.useRef(null);
|
|
277
|
+
const activeIndexRef = React.useRef(null);
|
|
278
|
+
const listContentRef = React.useRef([]);
|
|
279
|
+
const [selectedIndex, setSelectedIndex] = React.useState(
|
|
280
|
+
Math.max(0, listContentRef.current.indexOf(value))
|
|
281
|
+
);
|
|
282
|
+
const [valueNode, setValueNode] = React.useState(null);
|
|
283
|
+
const [valueNodeHasChildren, setValueNodeHasChildren] = React.useState(false);
|
|
284
|
+
useIsomorphicLayoutEffect(() => {
|
|
285
|
+
selectedIndexRef.current = selectedIndex;
|
|
286
|
+
activeIndexRef.current = activeIndex;
|
|
287
|
+
});
|
|
288
|
+
return <SelectProvider dir={dir} blockSelection={false} size={sizeProp} fallback={false} selectedItem={selectedItem} setSelectedItem={setSelectedItem} forceUpdate={forceUpdate} valueNode={valueNode} onValueNodeChange={setValueNode} onValueNodeHasChildrenChange={setValueNodeHasChildren} valueNodeHasChildren={valueNodeHasChildren} scopeKey={__scopeSelect ? Object.keys(__scopeSelect)[0] : ""} sheetBreakpoint={sheetBreakpoint} scope={__scopeSelect} setValueAtIndex={(index, value2) => {
|
|
289
|
+
listContentRef.current[index] = value2;
|
|
290
|
+
}} activeIndex={activeIndex} onChange={setValue} selectedIndex={selectedIndex} setActiveIndex={setActiveIndex} setOpen={setOpen} setSelectedIndex={setSelectedIndex} value={value} open={open}><SelectSheetController onChangeOpen={setOpen} __scopeSelect={__scopeSelect}><SelectImpl activeIndexRef={activeIndexRef} listContentRef={listContentRef} selectedIndexRef={selectedIndexRef} {...props} open={open} value={value}>{children}</SelectImpl></SelectSheetController></SelectProvider>;
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
Content: SelectContent,
|
|
294
|
+
Group: SelectGroup,
|
|
295
|
+
Icon: SelectIcon,
|
|
296
|
+
Item: SelectItem,
|
|
297
|
+
ItemIndicator: SelectItemIndicator,
|
|
298
|
+
ItemText: SelectItemText,
|
|
299
|
+
Label: SelectLabel,
|
|
300
|
+
ScrollDownButton: SelectScrollDownButton,
|
|
301
|
+
ScrollUpButton: SelectScrollUpButton,
|
|
302
|
+
Trigger: SelectTrigger,
|
|
303
|
+
Value: SelectValue,
|
|
304
|
+
Viewport: SelectViewport,
|
|
305
|
+
SheetContents: SelectSheetContents,
|
|
306
|
+
Sheet
|
|
307
|
+
}
|
|
308
|
+
);
|
|
288
309
|
Select.displayName = SELECT_NAME;
|
|
289
310
|
export {
|
|
290
311
|
Select,
|