@jobber/components-native 0.102.2 → 0.103.1-JOB-fix-me-b57d779.1

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.
@@ -1,16 +1,56 @@
1
1
  # Activity Indicator
2
2
 
3
- ActivityIndicator is used to indicate the loading of content where the actual
4
- amount of loading time or progress is unknown.
3
+ `ActivityIndicator` is used to communicate an **indeterminate** activity the
4
+ user cannot directly control or measure — loading, fetching, or waiting on an
5
+ external system.
5
6
 
6
- ## Related components
7
+ Use `ActivityIndicator` when the loading time or fraction of progress is
8
+ unknown. If you know the fraction of progress (for example, "3 of 4 files
9
+ uploaded"), use `ProgressBar` instead. A `ProgressIndicator` counterpart that
10
+ will subsume `ProgressBar` under the new naming is forthcoming.
7
11
 
8
- To indicate loading content in web applications, refer to
9
- [Spinner](/components/Spinner).
12
+ ## Design & usage guidelines
10
13
 
11
- ActivityIndicator uses the core component
12
- [ActivityIndicator](https://reactnative.dev/docs/activityIndicator) from
13
- `react-native`.
14
+ The default `ActivityIndicator` size is `base` (32px) and can be used in most
15
+ cases. The `small` size (16px) should be used on individual elements of an
16
+ interface (e.g. inside a `Button` or `Card`) or when sitting next to short
17
+ inline text.
18
+
19
+ Layout is the consumer's responsibility — `ActivityIndicator` does not expose
20
+ an `inline` prop. Place it inside your own flex / inline-block container, or
21
+ pass a `className` / `style`, to control surrounding layout.
22
+
23
+ ## Accessibility
24
+
25
+ `ActivityIndicator` announces itself politely to assistive technology:
26
+
27
+ * `role="status"` marks the element as a polite live region, appropriate for
28
+ a non-urgent loading state.
29
+ * `aria-label` defaults to the literal English string `"Loading"`. Pass a
30
+ custom `ariaLabel` to localize or to describe the specific activity
31
+ (e.g. `ariaLabel="Uploading file"`).
32
+
33
+ The indicator does not participate in the keyboard tab order.
34
+
35
+ ### Reduced motion
36
+
37
+ When the user's operating system reports
38
+ [`prefers-reduced-motion: reduce`](https://developer.mozilla.org/docs/Web/CSS/@media/prefers-reduced-motion),
39
+ the indicator hides its rocking and rotating layers, repaints a single
40
+ static ring in the icon foreground colour, and gently pulses its opacity so
41
+ the indicator still reads as "busy" without rotational motion.
42
+
43
+ ## Relationship to Spinner
44
+
45
+ The legacy [Spinner](/components/Spinner) component remains available and
46
+ unchanged. New code should prefer `ActivityIndicator`. A follow-up change is
47
+ expected to deprecate `Spinner` in favour of `ActivityIndicator`.
48
+
49
+ ## Mobile
50
+
51
+ On mobile (`@jobber/components-native`), `ActivityIndicator` uses the
52
+ [ActivityIndicator](https://reactnative.dev/docs/activityIndicator) core
53
+ component from React Native.
14
54
 
15
55
  ## Mockup
16
56
 
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jobber/components-native",
3
- "version": "0.102.2",
3
+ "version": "0.103.1-JOB-fix-me-b57d779.1+b57d779a",
4
4
  "license": "MIT",
5
5
  "description": "React Native implementation of Atlantis",
6
6
  "repository": {
@@ -15,6 +15,19 @@
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
+ "./meta.json": "./dist/src/utils/meta/meta.json",
28
+ "./dist/src/utils/meta/meta.json": "./dist/src/utils/meta/meta.json",
29
+ "./package.json": "./package.json"
30
+ },
18
31
  "files": [
19
32
  "dist",
20
33
  "dist/docs/**/*",
@@ -58,7 +71,7 @@
58
71
  "devDependencies": {
59
72
  "@babel/runtime": "^7.29.2",
60
73
  "@gorhom/bottom-sheet": "^5.2.8",
61
- "@jobber/design": "0.101.0",
74
+ "@jobber/design": "0.101.1",
62
75
  "@jobber/hooks": "2.20.1",
63
76
  "@react-native-community/datetimepicker": "^8.4.5",
64
77
  "@react-native/babel-preset": "^0.82.1",
@@ -109,5 +122,5 @@
109
122
  "react-native-screens": ">=4.18.0",
110
123
  "react-native-svg": ">=12.0.0"
111
124
  },
112
- "gitHead": "2829a8684a94528cf087b63fa471c531c95d01c8"
125
+ "gitHead": "b57d779ace9b72a8aaa258ee26ee1ebd3cdc4cbf"
113
126
  }
@@ -1,13 +1,16 @@
1
1
  import React from "react";
2
2
  import Svg, { Path } from "react-native-svg";
3
3
  import { getIcon } from "@jobber/design";
4
+ import { useAtlantisTheme } from "../AtlantisThemeContext";
4
5
  export function Icon({ name, color, size = "base", customColor, testID, }) {
6
+ const { tokens } = useAtlantisTheme();
5
7
  const { svgStyle, paths, viewBox } = getIcon({
6
8
  name,
7
9
  color,
8
10
  size,
9
11
  platform: "mobile",
10
12
  format: "js",
13
+ tokens,
11
14
  });
12
15
  const icon = paths.map((path) => {
13
16
  return React.createElement(Path, { key: path, d: path, fill: customColor || svgStyle.fill });
@@ -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
  it("renders home icon", () => {
5
8
  const tree = render(React.createElement(Icon, { name: "home" })).toJSON();
6
9
  expect(tree).toMatchSnapshot();
@@ -38,3 +41,37 @@ it("applies name prop as testID when testID prop is not provided", () => {
38
41
  const { getByTestId } = render(React.createElement(Icon, { name: "home" }));
39
42
  expect(getByTestId("home")).toBeDefined();
40
43
  });
44
+ describe("theme-aware fill", () => {
45
+ function getPathFills(svg) {
46
+ return svg.UNSAFE_root.findAllByType(Path).map(p => p.props.fill);
47
+ }
48
+ it("resolves the icon color to the dark-theme token under a dark theme", () => {
49
+ const expected = darkTokens["color-icon"];
50
+ const svg = render(React.createElement(AtlantisThemeContextProvider, { dangerouslyOverrideTheme: "dark" },
51
+ React.createElement(Icon, { name: "home", color: "icon" })));
52
+ expect(getPathFills(svg)[0]).toBe(expected);
53
+ expect(getPathFills(svg)[0]).not.toBe("hsl(198, 35%, 21%)");
54
+ });
55
+ it("resolves an icon's semantic default fill via live tokens when no color prop is given", () => {
56
+ // Regression check: semantic fills (e.g. quote -> color-quote) must
57
+ // resolve through their own token, not fall back to color-icon.
58
+ const expectedQuote = darkTokens["color-quote"];
59
+ const fallbackIcon = darkTokens["color-icon"];
60
+ const svg = render(React.createElement(AtlantisThemeContextProvider, { dangerouslyOverrideTheme: "dark" },
61
+ React.createElement(Icon, { name: "quote" })));
62
+ expect(getPathFills(svg)[0]).toBe(expectedQuote);
63
+ expect(getPathFills(svg)[0]).not.toBe(fallbackIcon);
64
+ });
65
+ it("defaults to the color-icon token when no color prop and no semantic default exist", () => {
66
+ const expected = darkTokens["color-icon"];
67
+ const svg = render(React.createElement(AtlantisThemeContextProvider, { dangerouslyOverrideTheme: "dark" },
68
+ React.createElement(Icon, { name: "home" })));
69
+ expect(getPathFills(svg)[0]).toBe(expected);
70
+ expect(getPathFills(svg)[0]).not.toBe("hsl(198, 35%, 21%)");
71
+ });
72
+ it("customColor still wins over theme tokens", () => {
73
+ const svg = render(React.createElement(AtlantisThemeContextProvider, { dangerouslyOverrideTheme: "dark" },
74
+ React.createElement(Icon, { name: "home", color: "icon", customColor: "#f33323" })));
75
+ expect(getPathFills(svg)[0]).toBe("#f33323");
76
+ });
77
+ });
@@ -0,0 +1 @@
1
+ export {};