@jobber/components-native 0.108.1 → 0.109.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 (88) hide show
  1. package/dist/docs/AtlantisThemeContext/AtlantisThemeContext.md +40 -0
  2. package/dist/docs/Icon/Icon.md +60 -53
  3. package/dist/docs/Select/Select.md +987 -0
  4. package/dist/docs/index.md +1 -0
  5. package/dist/package.json +3 -3
  6. package/dist/src/Select/Select.composable.test.js +38 -0
  7. package/dist/src/Select/Select.js +26 -0
  8. package/dist/src/Select/SelectComposableTypes.js +1 -0
  9. package/dist/src/Select/SelectRoot.js +85 -0
  10. package/dist/src/Select/SelectRoot.style.js +9 -0
  11. package/dist/src/Select/SelectRoot.test.js +157 -0
  12. package/dist/src/Select/components/SelectContent.js +51 -0
  13. package/dist/src/Select/components/SelectContent.test.js +51 -0
  14. package/dist/src/Select/components/SelectFieldContext.js +10 -0
  15. package/dist/src/Select/components/SelectItem.js +29 -0
  16. package/dist/src/Select/components/SelectItem.style.js +6 -0
  17. package/dist/src/Select/components/SelectItem.test.js +98 -0
  18. package/dist/src/Select/components/SelectLabel.js +29 -0
  19. package/dist/src/Select/components/SelectTrigger.js +40 -0
  20. package/dist/src/Select/components/SelectTrigger.style.js +26 -0
  21. package/dist/src/Select/index.js +2 -0
  22. package/dist/src/primitives/Portal/index.js +3 -1
  23. package/dist/src/primitives/Select/SelectPrimitive.js +4 -12
  24. package/dist/src/primitives/Select/SelectPrimitive.style.js +14 -9
  25. package/dist/src/primitives/Select/SelectPrimitive.test.js +2 -2
  26. package/dist/src/primitives/Select/index.js +1 -1
  27. package/dist/src/utils/meta/meta.json +11 -0
  28. package/dist/tsconfig.build.tsbuildinfo +1 -1
  29. package/dist/types/src/Select/Select.composable.test.d.ts +1 -0
  30. package/dist/types/src/Select/Select.d.ts +18 -0
  31. package/dist/types/src/Select/SelectComposableTypes.d.ts +50 -0
  32. package/dist/types/src/Select/SelectRoot.d.ts +12 -0
  33. package/dist/types/src/Select/SelectRoot.style.d.ts +8 -0
  34. package/dist/types/src/Select/SelectRoot.test.d.ts +1 -0
  35. package/dist/types/src/Select/components/SelectContent.d.ts +8 -0
  36. package/dist/types/src/Select/components/SelectContent.test.d.ts +1 -0
  37. package/dist/types/src/Select/components/SelectFieldContext.d.ts +27 -0
  38. package/dist/types/src/Select/components/SelectItem.d.ts +32 -0
  39. package/dist/types/src/Select/components/SelectItem.style.d.ts +5 -0
  40. package/dist/types/src/Select/components/SelectItem.test.d.ts +1 -0
  41. package/dist/types/src/Select/components/SelectLabel.d.ts +22 -0
  42. package/dist/types/src/Select/components/SelectTrigger.d.ts +20 -0
  43. package/dist/types/src/Select/components/SelectTrigger.style.d.ts +21 -0
  44. package/dist/types/src/Select/index.d.ts +2 -1
  45. package/dist/types/src/primitives/Select/SelectPrimitive.d.ts +3 -1
  46. package/dist/types/src/primitives/Select/SelectPrimitive.style.d.ts +6 -3
  47. package/dist/types/src/primitives/Select/index.d.ts +1 -1
  48. package/dist/types/src/primitives/Select/types.d.ts +1 -1
  49. package/package.json +3 -3
  50. package/src/Select/Select.composable.stories.tsx +93 -0
  51. package/src/Select/Select.composable.test.tsx +56 -0
  52. package/src/Select/Select.guide.md +197 -0
  53. package/src/Select/Select.tsx +31 -0
  54. package/src/Select/SelectComposableTypes.ts +57 -0
  55. package/src/Select/SelectRoot.style.ts +10 -0
  56. package/src/Select/SelectRoot.test.tsx +245 -0
  57. package/src/Select/SelectRoot.tsx +120 -0
  58. package/src/Select/components/SelectContent.test.tsx +67 -0
  59. package/src/Select/components/SelectContent.tsx +75 -0
  60. package/src/Select/components/SelectFieldContext.tsx +46 -0
  61. package/src/Select/components/SelectItem.style.ts +7 -0
  62. package/src/Select/components/SelectItem.test.tsx +166 -0
  63. package/src/Select/components/SelectItem.tsx +78 -0
  64. package/src/Select/components/SelectLabel.tsx +57 -0
  65. package/src/Select/components/SelectTrigger.style.ts +29 -0
  66. package/src/Select/components/SelectTrigger.tsx +98 -0
  67. package/src/Select/docs/SelectComposableBasic.tsx +18 -0
  68. package/src/Select/docs/SelectComposableControlledWithRef.tsx +28 -0
  69. package/src/Select/docs/SelectComposableCustomMarker.tsx +25 -0
  70. package/src/Select/docs/SelectComposableDescription.tsx +18 -0
  71. package/src/Select/docs/SelectComposableDisabled.tsx +18 -0
  72. package/src/Select/docs/SelectComposableDisabledOptions.tsx +20 -0
  73. package/src/Select/docs/SelectComposableGroupedOptions.tsx +29 -0
  74. package/src/Select/docs/SelectComposableItemPrefixSuffix.tsx +34 -0
  75. package/src/Select/docs/SelectComposableLabelAbove.tsx +18 -0
  76. package/src/Select/docs/SelectComposableLabelInside.tsx +18 -0
  77. package/src/Select/docs/SelectComposableProvinces.tsx +36 -0
  78. package/src/Select/docs/SelectComposableReadOnly.tsx +18 -0
  79. package/src/Select/docs/SelectComposableValidationFlow.tsx +27 -0
  80. package/src/Select/docs/index.ts +14 -0
  81. package/src/Select/index.ts +10 -1
  82. package/src/primitives/Portal/index.ts +3 -1
  83. package/src/primitives/Select/SelectPrimitive.style.ts +18 -11
  84. package/src/primitives/Select/SelectPrimitive.test.tsx +2 -2
  85. package/src/primitives/Select/SelectPrimitive.tsx +6 -18
  86. package/src/primitives/Select/index.ts +4 -1
  87. package/src/primitives/Select/types.ts +1 -1
  88. package/src/utils/meta/meta.json +11 -0
@@ -0,0 +1,25 @@
1
+ import React from "react";
2
+ import { Icon, Select } from "@jobber/components-native";
3
+ import { PROVINCES } from "./SelectComposableProvinces";
4
+
5
+ /** Override the default checkmark via the `indicator` slot prop. */
6
+ export function SelectComposableCustomMarker() {
7
+ return (
8
+ <Select.Root defaultValue={PROVINCES[0]}>
9
+ <Select.Label>Province</Select.Label>
10
+ <Select.Trigger>
11
+ <Select.Value placeholder="Select a province" />
12
+ </Select.Trigger>
13
+ <Select.Content>
14
+ {PROVINCES.map(province => (
15
+ <Select.Item
16
+ key={province.value}
17
+ value={province.value}
18
+ label={province.label}
19
+ indicator={<Icon name="starFill" />}
20
+ />
21
+ ))}
22
+ </Select.Content>
23
+ </Select.Root>
24
+ );
25
+ }
@@ -0,0 +1,18 @@
1
+ import React from "react";
2
+ import { Select } from "@jobber/components-native";
3
+ import { ProvinceItems } from "./SelectComposableProvinces";
4
+
5
+ /** Supporting `description` rendered below the field. */
6
+ export function SelectComposableDescription() {
7
+ return (
8
+ <Select.Root description="Where the work takes place.">
9
+ <Select.Label>Province</Select.Label>
10
+ <Select.Trigger>
11
+ <Select.Value placeholder="Select a province" />
12
+ </Select.Trigger>
13
+ <Select.Content>
14
+ <ProvinceItems />
15
+ </Select.Content>
16
+ </Select.Root>
17
+ );
18
+ }
@@ -0,0 +1,18 @@
1
+ import React from "react";
2
+ import { Select } from "@jobber/components-native";
3
+ import { PROVINCES, ProvinceItems } from "./SelectComposableProvinces";
4
+
5
+ /** Disabled field. */
6
+ export function SelectComposableDisabled() {
7
+ return (
8
+ <Select.Root disabled defaultValue={PROVINCES[6]}>
9
+ <Select.Label>Province</Select.Label>
10
+ <Select.Trigger>
11
+ <Select.Value placeholder="Select a province" />
12
+ </Select.Trigger>
13
+ <Select.Content>
14
+ <ProvinceItems />
15
+ </Select.Content>
16
+ </Select.Root>
17
+ );
18
+ }
@@ -0,0 +1,20 @@
1
+ import React from "react";
2
+ import { Select } from "@jobber/components-native";
3
+
4
+ /** Individual options can be disabled. */
5
+ export function SelectComposableDisabledOptions() {
6
+ return (
7
+ <Select.Root>
8
+ <Select.Label>Province</Select.Label>
9
+ <Select.Trigger>
10
+ <Select.Value placeholder="Select a province" />
11
+ </Select.Trigger>
12
+ <Select.Content>
13
+ <Select.Item value="on" label="Ontario" />
14
+ <Select.Item value="qc" label="Quebec" disabled />
15
+ <Select.Item value="bc" label="British Columbia" />
16
+ <Select.Item value="ab" label="Alberta" disabled />
17
+ </Select.Content>
18
+ </Select.Root>
19
+ );
20
+ }
@@ -0,0 +1,29 @@
1
+ import React from "react";
2
+ import { Select } from "@jobber/components-native";
3
+
4
+ /** Grouped options with group labels and a separator between groups. */
5
+ export function SelectComposableGroupedOptions() {
6
+ return (
7
+ <Select.Root>
8
+ <Select.Label>City</Select.Label>
9
+ <Select.Trigger>
10
+ <Select.Value placeholder="Select a city" />
11
+ </Select.Trigger>
12
+ <Select.Content>
13
+ <Select.Group>
14
+ <Select.GroupLabel>West</Select.GroupLabel>
15
+ <Select.Item value="van" label="Vancouver" />
16
+ <Select.Item value="cgy" label="Calgary" />
17
+ <Select.Item value="edm" label="Edmonton" />
18
+ </Select.Group>
19
+ <Select.Separator />
20
+ <Select.Group>
21
+ <Select.GroupLabel>East</Select.GroupLabel>
22
+ <Select.Item value="tor" label="Toronto" />
23
+ <Select.Item value="mtl" label="Montreal" />
24
+ <Select.Item value="hal" label="Halifax" />
25
+ </Select.Group>
26
+ </Select.Content>
27
+ </Select.Root>
28
+ );
29
+ }
@@ -0,0 +1,34 @@
1
+ import React from "react";
2
+ import { Icon, Select, Text } from "@jobber/components-native";
3
+ import { PROVINCES } from "./SelectComposableProvinces";
4
+
5
+ /** `Select.ItemPrefix` / `Select.ItemSuffix` slots passed into `Select.Item`. */
6
+ export function SelectComposableItemPrefixSuffix() {
7
+ return (
8
+ <Select.Root defaultValue={PROVINCES[0]}>
9
+ <Select.Label>Province</Select.Label>
10
+ <Select.Trigger>
11
+ <Select.Value placeholder="Select a province" />
12
+ </Select.Trigger>
13
+ <Select.Content>
14
+ {PROVINCES.map(province => (
15
+ <Select.Item
16
+ key={province.value}
17
+ value={province.value}
18
+ label={province.label}
19
+ prefix={
20
+ <Select.ItemPrefix>
21
+ <Icon name="home" />
22
+ </Select.ItemPrefix>
23
+ }
24
+ suffix={
25
+ <Select.ItemSuffix>
26
+ <Text variation="subdued">{province.value.toUpperCase()}</Text>
27
+ </Select.ItemSuffix>
28
+ }
29
+ />
30
+ ))}
31
+ </Select.Content>
32
+ </Select.Root>
33
+ );
34
+ }
@@ -0,0 +1,18 @@
1
+ import React from "react";
2
+ import { Select } from "@jobber/components-native";
3
+ import { ProvinceItems } from "./SelectComposableProvinces";
4
+
5
+ /** `labelPlacement="above"` renders the same `Select.Label` above the trigger. */
6
+ export function SelectComposableLabelAbove() {
7
+ return (
8
+ <Select.Root labelPlacement="above">
9
+ <Select.Label>Province</Select.Label>
10
+ <Select.Trigger>
11
+ <Select.Value placeholder="Select a province" />
12
+ </Select.Trigger>
13
+ <Select.Content>
14
+ <ProvinceItems />
15
+ </Select.Content>
16
+ </Select.Root>
17
+ );
18
+ }
@@ -0,0 +1,18 @@
1
+ import React from "react";
2
+ import { Select } from "@jobber/components-native";
3
+ import { ProvinceItems } from "./SelectComposableProvinces";
4
+
5
+ /** `labelPlacement="inside"` renders the label as a small label inside the trigger. */
6
+ export function SelectComposableLabelInside() {
7
+ return (
8
+ <Select.Root labelPlacement="inside">
9
+ <Select.Label>Province</Select.Label>
10
+ <Select.Trigger>
11
+ <Select.Value placeholder="Select a province" />
12
+ </Select.Trigger>
13
+ <Select.Content>
14
+ <ProvinceItems />
15
+ </Select.Content>
16
+ </Select.Root>
17
+ );
18
+ }
@@ -0,0 +1,36 @@
1
+ import React from "react";
2
+ import { Select } from "@jobber/components-native";
3
+
4
+ /** Shared option shape + data for the composable `Select` docs examples. */
5
+ export interface ProvinceOption {
6
+ value: string;
7
+ label: string;
8
+ }
9
+
10
+ export const PROVINCES: ProvinceOption[] = [
11
+ { value: "ab", label: "Alberta" },
12
+ { value: "bc", label: "British Columbia" },
13
+ { value: "mb", label: "Manitoba" },
14
+ { value: "nb", label: "New Brunswick" },
15
+ { value: "nl", label: "Newfoundland and Labrador" },
16
+ { value: "ns", label: "Nova Scotia" },
17
+ { value: "on", label: "Ontario" },
18
+ { value: "pe", label: "Prince Edward Island" },
19
+ { value: "qc", label: "Quebec" },
20
+ { value: "sk", label: "Saskatchewan" },
21
+ ];
22
+
23
+ /** The province options rendered as `Select.Item`s. */
24
+ export function ProvinceItems() {
25
+ return (
26
+ <>
27
+ {PROVINCES.map(province => (
28
+ <Select.Item
29
+ key={province.value}
30
+ value={province.value}
31
+ label={province.label}
32
+ />
33
+ ))}
34
+ </>
35
+ );
36
+ }
@@ -0,0 +1,18 @@
1
+ import React from "react";
2
+ import { Select } from "@jobber/components-native";
3
+ import { PROVINCES, ProvinceItems } from "./SelectComposableProvinces";
4
+
5
+ /** Read-only: non-interactive, value rendered as text with no chevron. */
6
+ export function SelectComposableReadOnly() {
7
+ return (
8
+ <Select.Root readOnly defaultValue={PROVINCES[6]}>
9
+ <Select.Label>Province</Select.Label>
10
+ <Select.Trigger>
11
+ <Select.Value placeholder="Select a province" />
12
+ </Select.Trigger>
13
+ <Select.Content>
14
+ <ProvinceItems />
15
+ </Select.Content>
16
+ </Select.Root>
17
+ );
18
+ }
@@ -0,0 +1,27 @@
1
+ import React, { useState } from "react";
2
+ import { Select } from "@jobber/components-native";
3
+ import {
4
+ ProvinceItems,
5
+ type ProvinceOption,
6
+ } from "./SelectComposableProvinces";
7
+
8
+ /** Validation: the `error` message and critical styling clear once selected. */
9
+ export function SelectComposableValidationFlow() {
10
+ const [value, setValue] = useState<ProvinceOption | undefined>();
11
+
12
+ return (
13
+ <Select.Root
14
+ value={value}
15
+ onValueChange={option => setValue(option as ProvinceOption | undefined)}
16
+ error={value ? undefined : "Please select a province."}
17
+ >
18
+ <Select.Label>Province</Select.Label>
19
+ <Select.Trigger>
20
+ <Select.Value placeholder="Select a province" />
21
+ </Select.Trigger>
22
+ <Select.Content>
23
+ <ProvinceItems />
24
+ </Select.Content>
25
+ </Select.Root>
26
+ );
27
+ }
@@ -1,2 +1,16 @@
1
1
  export { SelectBasic } from "./SelectBasic";
2
2
  export { SelectInitialValue } from "./SelectInitialValue";
3
+
4
+ // Composable Select docs examples
5
+ export { SelectComposableBasic } from "./SelectComposableBasic";
6
+ export { SelectComposableLabelAbove } from "./SelectComposableLabelAbove";
7
+ export { SelectComposableLabelInside } from "./SelectComposableLabelInside";
8
+ export { SelectComposableDescription } from "./SelectComposableDescription";
9
+ export { SelectComposableValidationFlow } from "./SelectComposableValidationFlow";
10
+ export { SelectComposableGroupedOptions } from "./SelectComposableGroupedOptions";
11
+ export { SelectComposableItemPrefixSuffix } from "./SelectComposableItemPrefixSuffix";
12
+ export { SelectComposableCustomMarker } from "./SelectComposableCustomMarker";
13
+ export { SelectComposableDisabledOptions } from "./SelectComposableDisabledOptions";
14
+ export { SelectComposableControlledWithRef } from "./SelectComposableControlledWithRef";
15
+ export { SelectComposableReadOnly } from "./SelectComposableReadOnly";
16
+ export { SelectComposableDisabled } from "./SelectComposableDisabled";
@@ -1,3 +1,12 @@
1
- export type { SelectOption, SelectProps } from "./Select";
1
+ // The composable `Select.*` parts are attached as statics on the `Select`
2
+ // function declaration in `Select.tsx` (docgen-visible), not assembled here.
2
3
  export { Select, Option } from "./Select";
3
4
  export { SelectPressable } from "./components/SelectPressable";
5
+
6
+ // Legacy props-driven API types.
7
+ export type { SelectOption, SelectProps } from "./Select";
8
+
9
+ // Composable chrome type. The underlying `SelectPrimitive` part prop types are
10
+ // exported from the primitives barrel (`@jobber/components-native/primitives`),
11
+ // not re-exported here.
12
+ export type { SelectRootProps } from "./SelectComposableTypes";
@@ -1,5 +1,7 @@
1
1
  // The portal host that backs every portal-based primitive (e.g. the Select
2
2
  // dropdown). Apps mount one <AtlantisPortalHost/> at their root; it shares this
3
3
  // package's bundled @rn-primitives/portal instance with the primitives' Portal,
4
- // so registered overlays render in the host.
4
+ // so registered overlays render in the host. On iOS, `Select.Content` lifts the
5
+ // dropdown above native-stack modals with `FullWindowOverlay` (react-native-
6
+ // screens), so this single root host is sufficient on both platforms.
5
7
  export { PortalHost as AtlantisPortalHost } from "@rn-primitives/portal";
@@ -7,10 +7,6 @@ const baseLineHeight = staticTokens["typography--lineHeight-base"];
7
7
  export const useStyles = buildThemedStyles(tokens => {
8
8
  const typographyStyles = getTypographyStyles(tokens);
9
9
 
10
- // The dark theme merges a web CSS-string `shadow-base` over the native object
11
- // shadow, leaving stray indexed keys on the value. Pick only the React Native
12
- // shadow properties so those keys never reach the style (spreading them
13
- // breaks style application through the dropdown's portal on react-native-web).
14
10
  const shadowBase = tokens["shadow-base"];
15
11
  const contentShadow = {
16
12
  shadowColor: shadowBase.shadowColor,
@@ -26,7 +22,8 @@ export const useStyles = buildThemedStyles(tokens => {
26
22
  alignItems: "center",
27
23
  gap: tokens["space-small"],
28
24
  minHeight: tokens["space-largest"] + tokens["space-small"],
29
- paddingHorizontal: tokens["space-slim"],
25
+ paddingLeft: tokens["space-base"],
26
+ paddingRight: tokens["space-small"],
30
27
  backgroundColor: tokens["color-surface"],
31
28
  borderWidth: tokens["border-base"],
32
29
  borderColor: tokens["color-border--interactive"],
@@ -36,19 +33,29 @@ export const useStyles = buildThemedStyles(tokens => {
36
33
  triggerOpen: {
37
34
  borderWidth: tokens["border-thick"],
38
35
  borderColor: tokens["color-interactive--subtle"],
39
- // Keep the content from shifting when the border thickens.
40
- paddingHorizontal:
41
- tokens["space-slim"] - (tokens["border-thick"] - tokens["border-base"]),
36
+ // On open the border grows from `border-base` to `border-thick`, which
37
+ // would push the content inward by that width delta on each side.
38
+ // Subtract the delta from the horizontal padding so the total inset
39
+ // (border + padding) — and thus the label/value/chevron position — stays
40
+ // constant.
41
+ paddingLeft:
42
+ tokens["space-base"] - (tokens["border-thick"] - tokens["border-base"]),
43
+ paddingRight:
44
+ tokens["space-small"] -
45
+ (tokens["border-thick"] - tokens["border-base"]),
42
46
  },
43
47
 
44
48
  triggerPressed: {
45
49
  borderWidth: tokens["border-thick"],
46
50
  borderColor: tokens["color-border--interactive"],
47
- paddingHorizontal:
48
- tokens["space-slim"] - (tokens["border-thick"] - tokens["border-base"]),
51
+ // Same border-thickness compensation as `triggerOpen` above.
52
+ paddingLeft:
53
+ tokens["space-base"] - (tokens["border-thick"] - tokens["border-base"]),
54
+ paddingRight:
55
+ tokens["space-small"] -
56
+ (tokens["border-thick"] - tokens["border-base"]),
49
57
  },
50
58
 
51
- // Critical sets only the colour; width follows the open/pressed state.
52
59
  triggerInvalid: {
53
60
  borderColor: tokens["color-critical"],
54
61
  },
@@ -70,9 +70,9 @@ describe("SelectPrimitive.Trigger", () => {
70
70
  expect(screen.getByTestId("ATL-Select-Trigger")).toBeDefined();
71
71
  });
72
72
 
73
- it("namespaces a provided testID", () => {
73
+ it("uses a provided testID verbatim", () => {
74
74
  renderSelect({ testID: "city" });
75
- expect(screen.getByTestId("ATL-city-Select-Trigger")).toBeDefined();
75
+ expect(screen.getByTestId("city")).toBeDefined();
76
76
  expect(screen.queryByTestId("ATL-Select-Trigger")).toBeNull();
77
77
  });
78
78
 
@@ -20,6 +20,9 @@ import type {
20
20
  } from "./types";
21
21
  import { tokens as staticTokens } from "../../utils/design";
22
22
 
23
+ /** Default trigger testID. Consumer-supplied `testID`s are used verbatim. */
24
+ export const SELECT_TRIGGER_DEFAULT_TEST_ID = "ATL-Select-Trigger";
25
+
23
26
  function SelectPrimitiveRoot({ ...props }: SelectPrimitiveRootProps) {
24
27
  return <Primitive.Root {...props} />;
25
28
  }
@@ -32,16 +35,13 @@ function SelectPrimitiveRoot({ ...props }: SelectPrimitiveRootProps) {
32
35
  function SelectPrimitiveTrigger({
33
36
  children,
34
37
  style,
35
- testID,
38
+ testID = SELECT_TRIGGER_DEFAULT_TEST_ID,
36
39
  invalid,
37
- onPressIn,
38
- onPressOut,
39
40
  ref,
40
41
  ...props
41
42
  }: SelectPrimitiveTriggerProps) {
42
43
  const styles = useStyles();
43
44
  const { open, value, disabled: rootDisabled } = Primitive.useRootContext();
44
- const [pressed, setPressed] = React.useState(false);
45
45
 
46
46
  // `disabled` is Root-level; the primitive's Trigger won't read it from
47
47
  // context, so resolve it here and pass it down to block interaction.
@@ -54,18 +54,10 @@ function SelectPrimitiveTrigger({
54
54
  return (
55
55
  <Primitive.Trigger
56
56
  ref={ref}
57
- testID={computeTriggerTestID(testID)}
57
+ testID={testID}
58
58
  disabled={isDisabled}
59
59
  accessibilityValue={accessibilityValue}
60
- onPressIn={event => {
61
- setPressed(true);
62
- onPressIn?.(event);
63
- }}
64
- onPressOut={event => {
65
- setPressed(false);
66
- onPressOut?.(event);
67
- }}
68
- style={[
60
+ style={({ pressed }) => [
69
61
  styles.trigger,
70
62
  pressed && !open && styles.triggerPressed,
71
63
  open && styles.triggerOpen,
@@ -80,10 +72,6 @@ function SelectPrimitiveTrigger({
80
72
  );
81
73
  }
82
74
 
83
- function computeTriggerTestID(testID?: string): string {
84
- return testID ? `ATL-${testID}-Select-Trigger` : "ATL-Select-Trigger";
85
- }
86
-
87
75
  function SelectPrimitiveValue({ style, ...props }: SelectPrimitiveValueProps) {
88
76
  const styles = useStyles();
89
77
  const { value, disabled } = Primitive.useRootContext();
@@ -1,4 +1,7 @@
1
- export { SelectPrimitive } from "./SelectPrimitive";
1
+ export {
2
+ SelectPrimitive,
3
+ SELECT_TRIGGER_DEFAULT_TEST_ID,
4
+ } from "./SelectPrimitive";
2
5
  export type {
3
6
  SelectPrimitiveContentProps,
4
7
  SelectPrimitiveGroupProps,
@@ -33,7 +33,7 @@ export type SelectPrimitiveRootProps = RootProps;
33
33
  export interface SelectPrimitiveTriggerProps
34
34
  extends Omit<TriggerProps, "style" | "children" | "disabled" | "asChild">,
35
35
  React.RefAttributes<TriggerRef> {
36
- /** Renders as `ATL-<testID>-Select-Trigger`, or `ATL-Select-Trigger` when omitted. */
36
+ /** Used verbatim to locate the trigger in end-to-end tests. Defaults to `ATL-Select-Trigger`. */
37
37
  readonly testID?: string;
38
38
 
39
39
  /** Critical (error) border styling. Style-only — no field/validation logic. */
@@ -60,6 +60,17 @@
60
60
  "Option",
61
61
  "ProgressBar",
62
62
  "Select",
63
+ "Select.Content",
64
+ "Select.Group",
65
+ "Select.GroupLabel",
66
+ "Select.Item",
67
+ "Select.ItemPrefix",
68
+ "Select.ItemSuffix",
69
+ "Select.Label",
70
+ "Select.Root",
71
+ "Select.Separator",
72
+ "Select.Trigger",
73
+ "Select.Value",
63
74
  "SelectPressable",
64
75
  "StatusLabel",
65
76
  "Switch",