@jobber/components-native 0.108.2 → 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.
- package/dist/docs/Select/Select.md +987 -0
- package/dist/docs/index.md +1 -0
- package/dist/package.json +2 -2
- package/dist/src/Select/Select.composable.test.js +38 -0
- package/dist/src/Select/Select.js +26 -0
- package/dist/src/Select/SelectComposableTypes.js +1 -0
- package/dist/src/Select/SelectRoot.js +85 -0
- package/dist/src/Select/SelectRoot.style.js +9 -0
- package/dist/src/Select/SelectRoot.test.js +157 -0
- package/dist/src/Select/components/SelectContent.js +51 -0
- package/dist/src/Select/components/SelectContent.test.js +51 -0
- package/dist/src/Select/components/SelectFieldContext.js +10 -0
- package/dist/src/Select/components/SelectItem.js +29 -0
- package/dist/src/Select/components/SelectItem.style.js +6 -0
- package/dist/src/Select/components/SelectItem.test.js +98 -0
- package/dist/src/Select/components/SelectLabel.js +29 -0
- package/dist/src/Select/components/SelectTrigger.js +40 -0
- package/dist/src/Select/components/SelectTrigger.style.js +26 -0
- package/dist/src/Select/index.js +2 -0
- package/dist/src/primitives/Portal/index.js +3 -1
- package/dist/src/primitives/Select/SelectPrimitive.js +4 -12
- package/dist/src/primitives/Select/SelectPrimitive.style.js +14 -9
- package/dist/src/primitives/Select/SelectPrimitive.test.js +2 -2
- package/dist/src/primitives/Select/index.js +1 -1
- package/dist/src/utils/meta/meta.json +11 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/types/src/Select/Select.composable.test.d.ts +1 -0
- package/dist/types/src/Select/Select.d.ts +18 -0
- package/dist/types/src/Select/SelectComposableTypes.d.ts +50 -0
- package/dist/types/src/Select/SelectRoot.d.ts +12 -0
- package/dist/types/src/Select/SelectRoot.style.d.ts +8 -0
- package/dist/types/src/Select/SelectRoot.test.d.ts +1 -0
- package/dist/types/src/Select/components/SelectContent.d.ts +8 -0
- package/dist/types/src/Select/components/SelectContent.test.d.ts +1 -0
- package/dist/types/src/Select/components/SelectFieldContext.d.ts +27 -0
- package/dist/types/src/Select/components/SelectItem.d.ts +32 -0
- package/dist/types/src/Select/components/SelectItem.style.d.ts +5 -0
- package/dist/types/src/Select/components/SelectItem.test.d.ts +1 -0
- package/dist/types/src/Select/components/SelectLabel.d.ts +22 -0
- package/dist/types/src/Select/components/SelectTrigger.d.ts +20 -0
- package/dist/types/src/Select/components/SelectTrigger.style.d.ts +21 -0
- package/dist/types/src/Select/index.d.ts +2 -1
- package/dist/types/src/primitives/Select/SelectPrimitive.d.ts +3 -1
- package/dist/types/src/primitives/Select/SelectPrimitive.style.d.ts +6 -3
- package/dist/types/src/primitives/Select/index.d.ts +1 -1
- package/dist/types/src/primitives/Select/types.d.ts +1 -1
- package/package.json +2 -2
- package/src/Select/Select.composable.stories.tsx +93 -0
- package/src/Select/Select.composable.test.tsx +56 -0
- package/src/Select/Select.guide.md +197 -0
- package/src/Select/Select.tsx +31 -0
- package/src/Select/SelectComposableTypes.ts +57 -0
- package/src/Select/SelectRoot.style.ts +10 -0
- package/src/Select/SelectRoot.test.tsx +245 -0
- package/src/Select/SelectRoot.tsx +120 -0
- package/src/Select/components/SelectContent.test.tsx +67 -0
- package/src/Select/components/SelectContent.tsx +75 -0
- package/src/Select/components/SelectFieldContext.tsx +46 -0
- package/src/Select/components/SelectItem.style.ts +7 -0
- package/src/Select/components/SelectItem.test.tsx +166 -0
- package/src/Select/components/SelectItem.tsx +78 -0
- package/src/Select/components/SelectLabel.tsx +57 -0
- package/src/Select/components/SelectTrigger.style.ts +29 -0
- package/src/Select/components/SelectTrigger.tsx +98 -0
- package/src/Select/docs/SelectComposableBasic.tsx +18 -0
- package/src/Select/docs/SelectComposableControlledWithRef.tsx +28 -0
- package/src/Select/docs/SelectComposableCustomMarker.tsx +25 -0
- package/src/Select/docs/SelectComposableDescription.tsx +18 -0
- package/src/Select/docs/SelectComposableDisabled.tsx +18 -0
- package/src/Select/docs/SelectComposableDisabledOptions.tsx +20 -0
- package/src/Select/docs/SelectComposableGroupedOptions.tsx +29 -0
- package/src/Select/docs/SelectComposableItemPrefixSuffix.tsx +34 -0
- package/src/Select/docs/SelectComposableLabelAbove.tsx +18 -0
- package/src/Select/docs/SelectComposableLabelInside.tsx +18 -0
- package/src/Select/docs/SelectComposableProvinces.tsx +36 -0
- package/src/Select/docs/SelectComposableReadOnly.tsx +18 -0
- package/src/Select/docs/SelectComposableValidationFlow.tsx +27 -0
- package/src/Select/docs/index.ts +14 -0
- package/src/Select/index.ts +10 -1
- package/src/primitives/Portal/index.ts +3 -1
- package/src/primitives/Select/SelectPrimitive.style.ts +18 -11
- package/src/primitives/Select/SelectPrimitive.test.tsx +2 -2
- package/src/primitives/Select/SelectPrimitive.tsx +6 -18
- package/src/primitives/Select/index.ts +4 -1
- package/src/primitives/Select/types.ts +1 -1
- 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
|
+
}
|
package/src/Select/docs/index.ts
CHANGED
|
@@ -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";
|
package/src/Select/index.ts
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
48
|
-
|
|
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("
|
|
73
|
+
it("uses a provided testID verbatim", () => {
|
|
74
74
|
renderSelect({ testID: "city" });
|
|
75
|
-
expect(screen.getByTestId("
|
|
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={
|
|
57
|
+
testID={testID}
|
|
58
58
|
disabled={isDisabled}
|
|
59
59
|
accessibilityValue={accessibilityValue}
|
|
60
|
-
|
|
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();
|
|
@@ -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
|
-
/**
|
|
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. */
|
package/src/utils/meta/meta.json
CHANGED
|
@@ -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",
|