@jobber/components-native 0.102.2 → 0.103.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.
@@ -0,0 +1,4 @@
1
+ /**
2
+ * This file exports styled components-native primitives.
3
+ */
4
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jobber/components-native",
3
- "version": "0.102.2",
3
+ "version": "0.103.0",
4
4
  "license": "MIT",
5
5
  "description": "React Native implementation of Atlantis",
6
6
  "repository": {
@@ -15,6 +15,17 @@
15
15
  "main": "dist/src/index.js",
16
16
  "module": "dist/src/index.js",
17
17
  "types": "dist/types/src/index.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/types/src/index.d.ts",
21
+ "default": "./dist/src/index.js"
22
+ },
23
+ "./primitives": {
24
+ "types": "./dist/types/src/primitives/index.d.ts",
25
+ "default": "./dist/src/primitives/index.js"
26
+ },
27
+ "./package.json": "./package.json"
28
+ },
18
29
  "files": [
19
30
  "dist",
20
31
  "dist/docs/**/*",
@@ -58,7 +69,7 @@
58
69
  "devDependencies": {
59
70
  "@babel/runtime": "^7.29.2",
60
71
  "@gorhom/bottom-sheet": "^5.2.8",
61
- "@jobber/design": "0.101.0",
72
+ "@jobber/design": "0.101.1",
62
73
  "@jobber/hooks": "2.20.1",
63
74
  "@react-native-community/datetimepicker": "^8.4.5",
64
75
  "@react-native/babel-preset": "^0.82.1",
@@ -109,5 +120,5 @@
109
120
  "react-native-screens": ">=4.18.0",
110
121
  "react-native-svg": ">=12.0.0"
111
122
  },
112
- "gitHead": "2829a8684a94528cf087b63fa471c531c95d01c8"
123
+ "gitHead": "7b859533f0b0482ad30654fb0fde5d41c2d918ba"
113
124
  }
@@ -1,6 +1,9 @@
1
1
  import React from "react";
2
2
  import { render } from "@testing-library/react-native";
3
+ import { Path } from "react-native-svg";
4
+ import { darkTokens } from "@jobber/design";
3
5
  import { Icon } from ".";
6
+ import { AtlantisThemeContextProvider } from "../AtlantisThemeContext";
4
7
 
5
8
  it("renders home icon", () => {
6
9
  const tree = render(<Icon name="home" />).toJSON();
@@ -47,3 +50,58 @@ it("applies name prop as testID when testID prop is not provided", () => {
47
50
  const { getByTestId } = render(<Icon name="home" />);
48
51
  expect(getByTestId("home")).toBeDefined();
49
52
  });
53
+
54
+ describe("theme-aware fill", () => {
55
+ function getPathFills(svg: ReturnType<typeof render>) {
56
+ return svg.UNSAFE_root.findAllByType(Path).map(p => p.props.fill as string);
57
+ }
58
+
59
+ it("resolves the icon color to the dark-theme token under a dark theme", () => {
60
+ const expected = (darkTokens as Record<string, string>)["color-icon"];
61
+ const svg = render(
62
+ <AtlantisThemeContextProvider dangerouslyOverrideTheme="dark">
63
+ <Icon name="home" color="icon" />
64
+ </AtlantisThemeContextProvider>,
65
+ );
66
+
67
+ expect(getPathFills(svg)[0]).toBe(expected);
68
+ expect(getPathFills(svg)[0]).not.toBe("hsl(198, 35%, 21%)");
69
+ });
70
+
71
+ it("resolves an icon's semantic default fill via live tokens when no color prop is given", () => {
72
+ // Regression check: semantic fills (e.g. quote -> color-quote) must
73
+ // resolve through their own token, not fall back to color-icon.
74
+ const expectedQuote = (darkTokens as Record<string, string>)["color-quote"];
75
+ const fallbackIcon = (darkTokens as Record<string, string>)["color-icon"];
76
+ const svg = render(
77
+ <AtlantisThemeContextProvider dangerouslyOverrideTheme="dark">
78
+ <Icon name="quote" />
79
+ </AtlantisThemeContextProvider>,
80
+ );
81
+
82
+ expect(getPathFills(svg)[0]).toBe(expectedQuote);
83
+ expect(getPathFills(svg)[0]).not.toBe(fallbackIcon);
84
+ });
85
+
86
+ it("defaults to the color-icon token when no color prop and no semantic default exist", () => {
87
+ const expected = (darkTokens as Record<string, string>)["color-icon"];
88
+ const svg = render(
89
+ <AtlantisThemeContextProvider dangerouslyOverrideTheme="dark">
90
+ <Icon name="home" />
91
+ </AtlantisThemeContextProvider>,
92
+ );
93
+
94
+ expect(getPathFills(svg)[0]).toBe(expected);
95
+ expect(getPathFills(svg)[0]).not.toBe("hsl(198, 35%, 21%)");
96
+ });
97
+
98
+ it("customColor still wins over theme tokens", () => {
99
+ const svg = render(
100
+ <AtlantisThemeContextProvider dangerouslyOverrideTheme="dark">
101
+ <Icon name="home" color="icon" customColor="#f33323" />
102
+ </AtlantisThemeContextProvider>,
103
+ );
104
+
105
+ expect(getPathFills(svg)[0]).toBe("#f33323");
106
+ });
107
+ });
package/src/Icon/Icon.tsx CHANGED
@@ -2,6 +2,7 @@ import React from "react";
2
2
  import Svg, { Path } from "react-native-svg";
3
3
  import type { IconColorNames, IconNames, IconSizes } from "@jobber/design";
4
4
  import { getIcon } from "@jobber/design";
5
+ import { useAtlantisTheme } from "../AtlantisThemeContext";
5
6
 
6
7
  export interface IconProps {
7
8
  /** The icon to show. */
@@ -38,12 +39,14 @@ export function Icon({
38
39
  customColor,
39
40
  testID,
40
41
  }: IconProps) {
42
+ const { tokens } = useAtlantisTheme();
41
43
  const { svgStyle, paths, viewBox } = getIcon({
42
44
  name,
43
45
  color,
44
46
  size,
45
47
  platform: "mobile",
46
48
  format: "js",
49
+ tokens,
47
50
  });
48
51
 
49
52
  const icon = paths.map((path: string) => {
@@ -0,0 +1,4 @@
1
+ /**
2
+ * This file exports styled components-native primitives.
3
+ */
4
+ export {};