@hero-design/rn-work-uikit 1.1.0-alpha.0 → 1.1.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/CHANGELOG.md +2 -3
- package/THEME_OVERRIDE.md +52 -0
- package/lib/index.js +134 -4
- package/locales/en_AU.js +10 -0
- package/locales/en_AU.mjs +8 -0
- package/locales/en_CA.js +10 -0
- package/locales/en_CA.mjs +8 -0
- package/locales/index.js +11 -0
- package/locales/index.mjs +9 -0
- package/locales/types.js +2 -0
- package/locales/types.mjs +1 -0
- package/package.json +5 -4
- package/rollup.config.mjs +18 -2
- package/src/__tests__/__snapshots__/index.spec.tsx.snap +1 -1
- package/src/__tests__/index.spec.tsx +15 -0
- package/src/__tests__/theme-export-override.spec.ts +90 -0
- package/src/index.ts +13 -1
- package/src/theme/ThemeProvider.ts +20 -0
- package/src/theme/ThemeSwitcher.tsx +76 -0
- package/src/theme/__tests__/ThemeProvider.spec.tsx +32 -0
- package/src/theme/__tests__/__snapshots__/index.spec.ts.snap +1844 -0
- package/src/theme/__tests__/index.spec.ts +7 -0
- package/src/theme/components/textInput.ts +59 -0
- package/src/theme/getTheme.ts +32 -0
- package/src/theme/index.ts +17 -0
- package/stats/1.1.0/rn-work-uikit-stats.html +4842 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @hero-design/rn-work-uikit
|
|
2
2
|
|
|
3
|
-
## 1.1.0
|
|
3
|
+
## 1.1.0
|
|
4
4
|
|
|
5
5
|
### Minor Changes
|
|
6
6
|
|
|
@@ -8,5 +8,4 @@
|
|
|
8
8
|
|
|
9
9
|
### Patch Changes
|
|
10
10
|
|
|
11
|
-
-
|
|
12
|
-
- @hero-design/rn@8.101.3-alpha.0
|
|
11
|
+
- [#3984](https://github.com/Thinkei/hero-design/pull/3984) [`eac6055689ef74e39c21a04dfd25ace4f1bbe613`](https://github.com/Thinkei/hero-design/commit/eac6055689ef74e39c21a04dfd25ace4f1bbe613) Thanks [@ttkien](https://github.com/ttkien)! - initialise theme for work
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Theme Override Mechanism
|
|
2
|
+
|
|
3
|
+
This package provides work-specific theme overrides that take precedence over the base `@hero-design/rn` theme while maintaining full API compatibility.
|
|
4
|
+
|
|
5
|
+
## How It Works
|
|
6
|
+
|
|
7
|
+
### Export Strategy
|
|
8
|
+
We use ES6 module export precedence where named exports override wildcard exports:
|
|
9
|
+
|
|
10
|
+
```typescript
|
|
11
|
+
// Re-export everything from base package
|
|
12
|
+
export * from '@hero-design/rn';
|
|
13
|
+
|
|
14
|
+
// Override specific theme exports (these take precedence)
|
|
15
|
+
export {
|
|
16
|
+
getTheme,
|
|
17
|
+
ThemeProvider,
|
|
18
|
+
useTheme,
|
|
19
|
+
theme,
|
|
20
|
+
// ... other theme-related exports
|
|
21
|
+
} from './theme';
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### What Gets Overridden
|
|
25
|
+
Only theme-related exports are customized for work-specific needs:
|
|
26
|
+
|
|
27
|
+
- **`getTheme()`** - Returns work theme with `textInput` component overrides
|
|
28
|
+
- **`ThemeProvider`** - Work-specific theme provider with enhanced typing
|
|
29
|
+
- **`useTheme()`** - Hook returning work theme with proper TypeScript types
|
|
30
|
+
- **`theme`** - Default work theme object
|
|
31
|
+
- **Theme types** - Enhanced TypeScript definitions
|
|
32
|
+
|
|
33
|
+
All other components (Button, TextInput, etc.) remain unchanged from the base package.
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
### Drop-in Replacement
|
|
38
|
+
Replace your imports without any code changes:
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
// Before
|
|
42
|
+
import { ThemeProvider, useTheme, Button } from '@hero-design/rn';
|
|
43
|
+
|
|
44
|
+
// After - same API, work theme applied automatically
|
|
45
|
+
import { ThemeProvider, useTheme, Button } from '@hero-design/rn-work-uikit';
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Guaranteed Behavior
|
|
49
|
+
- ✅ Work-specific theme overrides (currently `textInput` styling)
|
|
50
|
+
- ✅ All base components and functionality preserved
|
|
51
|
+
- ✅ Full TypeScript support with work theme types
|
|
52
|
+
- ✅ Backward compatibility with existing code
|
package/lib/index.js
CHANGED
|
@@ -1,12 +1,142 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var rn = require('@hero-design/rn');
|
|
4
|
+
var React = require('react');
|
|
4
5
|
|
|
6
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
5
7
|
|
|
8
|
+
var React__default = /*#__PURE__*/_interopDefaultCompat(React);
|
|
6
9
|
|
|
10
|
+
function _defineProperty(e, r, t) {
|
|
11
|
+
return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
12
|
+
value: t,
|
|
13
|
+
enumerable: !0,
|
|
14
|
+
configurable: !0,
|
|
15
|
+
writable: !0
|
|
16
|
+
}) : e[r] = t, e;
|
|
17
|
+
}
|
|
18
|
+
function ownKeys(e, r) {
|
|
19
|
+
var t = Object.keys(e);
|
|
20
|
+
if (Object.getOwnPropertySymbols) {
|
|
21
|
+
var o = Object.getOwnPropertySymbols(e);
|
|
22
|
+
r && (o = o.filter(function (r) {
|
|
23
|
+
return Object.getOwnPropertyDescriptor(e, r).enumerable;
|
|
24
|
+
})), t.push.apply(t, o);
|
|
25
|
+
}
|
|
26
|
+
return t;
|
|
27
|
+
}
|
|
28
|
+
function _objectSpread2(e) {
|
|
29
|
+
for (var r = 1; r < arguments.length; r++) {
|
|
30
|
+
var t = null != arguments[r] ? arguments[r] : {};
|
|
31
|
+
r % 2 ? ownKeys(Object(t), !0).forEach(function (r) {
|
|
32
|
+
_defineProperty(e, r, t[r]);
|
|
33
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
|
|
34
|
+
Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return e;
|
|
38
|
+
}
|
|
39
|
+
function _toPrimitive(t, r) {
|
|
40
|
+
if ("object" != typeof t || !t) return t;
|
|
41
|
+
var e = t[Symbol.toPrimitive];
|
|
42
|
+
if (void 0 !== e) {
|
|
43
|
+
var i = e.call(t, r || "default");
|
|
44
|
+
if ("object" != typeof i) return i;
|
|
45
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
46
|
+
}
|
|
47
|
+
return ("string" === r ? String : Number)(t);
|
|
48
|
+
}
|
|
49
|
+
function _toPropertyKey(t) {
|
|
50
|
+
var i = _toPrimitive(t, "string");
|
|
51
|
+
return "symbol" == typeof i ? i : i + "";
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
var getTextInputTheme = function getTextInputTheme(theme) {
|
|
55
|
+
var baseTextInputTheme = theme.__hd__.textInput;
|
|
56
|
+
// Override specific values here as needed
|
|
57
|
+
var colors = _objectSpread2({}, baseTextInputTheme.colors);
|
|
58
|
+
var space = _objectSpread2({}, baseTextInputTheme.space);
|
|
59
|
+
var fonts = _objectSpread2({}, baseTextInputTheme.fonts);
|
|
60
|
+
var fontSizes = _objectSpread2({}, baseTextInputTheme.fontSizes);
|
|
61
|
+
var borderWidths = _objectSpread2({}, baseTextInputTheme.borderWidths);
|
|
62
|
+
var radii = _objectSpread2({}, baseTextInputTheme.radii);
|
|
63
|
+
var sizes = _objectSpread2({}, baseTextInputTheme.sizes);
|
|
64
|
+
var lineHeights = _objectSpread2({}, baseTextInputTheme.lineHeights);
|
|
65
|
+
return {
|
|
66
|
+
colors: colors,
|
|
67
|
+
space: space,
|
|
68
|
+
fonts: fonts,
|
|
69
|
+
fontSizes: fontSizes,
|
|
70
|
+
borderWidths: borderWidths,
|
|
71
|
+
radii: radii,
|
|
72
|
+
sizes: sizes,
|
|
73
|
+
lineHeights: lineHeights
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
var getTheme = function getTheme(scale) {
|
|
78
|
+
var systemPalette = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : rn.swagSystemPalette;
|
|
79
|
+
var baseTheme = rn.getTheme(scale, systemPalette);
|
|
80
|
+
return _objectSpread2(_objectSpread2({}, baseTheme), {}, {
|
|
81
|
+
__hd__: _objectSpread2(_objectSpread2({}, baseTheme.__hd__), {}, {
|
|
82
|
+
textInput: getTextInputTheme(baseTheme)
|
|
83
|
+
})
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
var WorkThemeProvider = rn.ThemeProvider;
|
|
88
|
+
var useWorkTheme = rn.useTheme;
|
|
89
|
+
|
|
90
|
+
var WorkThemeSwitcher = function WorkThemeSwitcher(_ref) {
|
|
91
|
+
var _ref$name = _ref.name,
|
|
92
|
+
name = _ref$name === void 0 ? 'work' : _ref$name,
|
|
93
|
+
children = _ref.children;
|
|
94
|
+
var theme = React.useMemo(function () {
|
|
95
|
+
switch (name) {
|
|
96
|
+
case 'swag':
|
|
97
|
+
return getTheme(undefined, rn.swagSystemPalette);
|
|
98
|
+
case 'work':
|
|
99
|
+
return getTheme(undefined, rn.workSystemPalette);
|
|
100
|
+
case 'jobs':
|
|
101
|
+
return getTheme(undefined, rn.jobsSystemPalette);
|
|
102
|
+
case 'wallet':
|
|
103
|
+
return getTheme(undefined, rn.walletSystemPalette);
|
|
104
|
+
case 'eBens':
|
|
105
|
+
return getTheme(undefined, rn.eBensSystemPalette);
|
|
106
|
+
case 'swagDark':
|
|
107
|
+
return getTheme(undefined, rn.swagDarkSystemPalette);
|
|
108
|
+
case 'swagLight':
|
|
109
|
+
case 'ehWork':
|
|
110
|
+
return getTheme(undefined, rn.swagLightSystemPalette);
|
|
111
|
+
case 'ehWorkDark':
|
|
112
|
+
return getTheme(undefined, rn.ehWorkDarkSystemPalette);
|
|
113
|
+
case 'ehJobs':
|
|
114
|
+
return getTheme(undefined, rn.swagLightJobsSystemPalette);
|
|
115
|
+
}
|
|
116
|
+
}, [name]);
|
|
117
|
+
return /*#__PURE__*/React__default.default.createElement(WorkThemeProvider, {
|
|
118
|
+
theme: theme
|
|
119
|
+
}, children);
|
|
120
|
+
};
|
|
121
|
+
var withWorkTheme = function withWorkTheme(C, themeName) {
|
|
122
|
+
return function (props) {
|
|
123
|
+
return /*#__PURE__*/React__default.default.createElement(WorkThemeSwitcher, {
|
|
124
|
+
name: themeName
|
|
125
|
+
}, /*#__PURE__*/React__default.default.createElement(C, props));
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
var defaultTheme = getTheme();
|
|
130
|
+
|
|
131
|
+
exports.ThemeProvider = WorkThemeProvider;
|
|
132
|
+
exports.ThemeSwitcher = WorkThemeSwitcher;
|
|
133
|
+
exports.getTheme = getTheme;
|
|
134
|
+
exports.theme = defaultTheme;
|
|
135
|
+
exports.useTheme = useWorkTheme;
|
|
136
|
+
exports.withTheme = withWorkTheme;
|
|
7
137
|
Object.keys(rn).forEach(function (k) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
138
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
139
|
+
enumerable: true,
|
|
140
|
+
get: function () { return rn[k]; }
|
|
141
|
+
});
|
|
12
142
|
});
|
package/locales/en_AU.js
ADDED
package/locales/en_CA.js
ADDED
package/locales/index.js
ADDED
package/locales/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hero-design/rn-work-uikit",
|
|
3
|
-
"version": "1.1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "es/index.js",
|
|
@@ -16,10 +16,11 @@
|
|
|
16
16
|
"build:types": "tsc --noEmit false --emitDeclarationOnly --project tsconfig.prod.json",
|
|
17
17
|
"build": "yarn build:js && yarn build:types",
|
|
18
18
|
"build:watch": "yarn build:js -w & yarn build:types -w",
|
|
19
|
-
"publish:npm": "yarn publish --access public"
|
|
19
|
+
"publish:npm": "yarn publish --access public",
|
|
20
|
+
"set-dev-env": "npm pkg set react-native=src/index.ts"
|
|
20
21
|
},
|
|
21
22
|
"dependencies": {
|
|
22
|
-
"@hero-design/rn": "^8.101.
|
|
23
|
+
"@hero-design/rn": "^8.101.1"
|
|
23
24
|
},
|
|
24
25
|
"peerDependencies": {
|
|
25
26
|
"@hero-design/react-native-month-year-picker": "^8.43.1",
|
|
@@ -45,7 +46,6 @@
|
|
|
45
46
|
"@babel/preset-react": "^7.26.3",
|
|
46
47
|
"@babel/preset-typescript": "^7.27.0",
|
|
47
48
|
"@babel/runtime": "^7.25.0",
|
|
48
|
-
"@emotion/jest": "^11.11.0",
|
|
49
49
|
"@eslint/compat": "^1.1.1",
|
|
50
50
|
"@eslint/eslintrc": "^3.1.0",
|
|
51
51
|
"@eslint/js": "^9.8.0",
|
|
@@ -107,6 +107,7 @@
|
|
|
107
107
|
"react-test-renderer": "18.2.0",
|
|
108
108
|
"rollup": "^4.24.3",
|
|
109
109
|
"rollup-plugin-copy": "^3.5.0",
|
|
110
|
+
"rollup-plugin-delete": "^3.0.1",
|
|
110
111
|
"rollup-plugin-flow": "^1.1.1",
|
|
111
112
|
"rollup-plugin-visualizer": "^5.12.0",
|
|
112
113
|
"ts-jest": "^29.1.1",
|
package/rollup.config.mjs
CHANGED
|
@@ -7,12 +7,15 @@ import replace from '@rollup/plugin-replace';
|
|
|
7
7
|
import flow from 'rollup-plugin-flow';
|
|
8
8
|
import { visualizer } from 'rollup-plugin-visualizer';
|
|
9
9
|
import pkg from './package.json' assert { type: 'json' };
|
|
10
|
+
import copy from 'rollup-plugin-copy';
|
|
11
|
+
import del from 'rollup-plugin-delete';
|
|
10
12
|
|
|
11
13
|
const extensions = ['.js', '.jsx', '.ts', '.tsx'];
|
|
12
14
|
|
|
13
15
|
const generateBuildStats = process.env.GENERATE_BUILD_STATS === 'true';
|
|
14
16
|
const bundleTemplate = process.env.BUNDLE_TEMPLATE || 'treemap';
|
|
15
|
-
const fileName =
|
|
17
|
+
const fileName =
|
|
18
|
+
process.env.FILE_NAME || `stats/${pkg.version}/rn-work-uikit-stats.html`;
|
|
16
19
|
|
|
17
20
|
export default [
|
|
18
21
|
{
|
|
@@ -63,6 +66,19 @@ export default [
|
|
|
63
66
|
}),
|
|
64
67
|
]
|
|
65
68
|
: []),
|
|
69
|
+
del({ targets: ['locales', 'types'] }),
|
|
70
|
+
copy({
|
|
71
|
+
targets: [
|
|
72
|
+
{
|
|
73
|
+
src: 'node_modules/@hero-design/rn/locales',
|
|
74
|
+
dest: '.',
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
src: 'node_modules/@hero-design/rn/types',
|
|
78
|
+
dest: '.',
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
}),
|
|
66
82
|
],
|
|
67
83
|
},
|
|
68
|
-
];
|
|
84
|
+
];
|
|
@@ -16,3 +16,18 @@ describe('first test to ensure configure correctly', () => {
|
|
|
16
16
|
expect(toJSON()).toMatchSnapshot();
|
|
17
17
|
});
|
|
18
18
|
});
|
|
19
|
+
|
|
20
|
+
describe('Export Completeness', () => {
|
|
21
|
+
it('should include all exports from @hero-design/rn', () => {
|
|
22
|
+
// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
|
|
23
|
+
const baseRN = require('@hero-design/rn');
|
|
24
|
+
// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
|
|
25
|
+
const workUIKit = require('../index');
|
|
26
|
+
|
|
27
|
+
const baseExports = Object.keys(baseRN);
|
|
28
|
+
|
|
29
|
+
baseExports.forEach((exportName) => {
|
|
30
|
+
expect(workUIKit).toHaveProperty(exportName);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
});
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// Mock the entire theme module to avoid import resolution issues
|
|
2
|
+
jest.mock('../theme', () => {
|
|
3
|
+
const mockWorkTheme = {
|
|
4
|
+
colors: { text: 'work-color' },
|
|
5
|
+
fonts: { base: 'work-font' },
|
|
6
|
+
space: { base: 'work-space' },
|
|
7
|
+
__hd__: {
|
|
8
|
+
textInput: {
|
|
9
|
+
colors: {
|
|
10
|
+
text: '#WORK_THEME_COLOR',
|
|
11
|
+
background: '#WORK_BACKGROUND',
|
|
12
|
+
},
|
|
13
|
+
space: { containerPadding: 'WORK_PADDING' },
|
|
14
|
+
fonts: { text: 'WORK_FONT' },
|
|
15
|
+
},
|
|
16
|
+
button: { base: 'button' },
|
|
17
|
+
accordion: { base: 'accordion' },
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const mockGetTheme = jest.fn(() => mockWorkTheme);
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
__esModule: true,
|
|
25
|
+
default: mockWorkTheme,
|
|
26
|
+
getTheme: mockGetTheme,
|
|
27
|
+
Theme: {},
|
|
28
|
+
CustomTheme: {},
|
|
29
|
+
ThemeProvider: jest.fn(),
|
|
30
|
+
ThemeSwitcher: jest.fn(),
|
|
31
|
+
useTheme: jest.fn(),
|
|
32
|
+
withTheme: jest.fn(),
|
|
33
|
+
};
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Mock the base @hero-design/rn
|
|
37
|
+
jest.mock('@hero-design/rn', () => ({
|
|
38
|
+
getTheme: jest.fn(() => ({
|
|
39
|
+
colors: { text: 'base-color' },
|
|
40
|
+
__hd__: {
|
|
41
|
+
textInput: {
|
|
42
|
+
colors: { text: 'BASE_THEME_COLOR' },
|
|
43
|
+
space: { containerPadding: 'BASE_PADDING' },
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
})),
|
|
47
|
+
// Re-export everything else as is
|
|
48
|
+
Button: 'MockButton',
|
|
49
|
+
TextInput: 'MockTextInput',
|
|
50
|
+
ThemeProvider: 'MockBaseThemeProvider',
|
|
51
|
+
useTheme: jest.fn(),
|
|
52
|
+
}));
|
|
53
|
+
|
|
54
|
+
describe('Theme Export Override', () => {
|
|
55
|
+
beforeEach(() => {
|
|
56
|
+
// Clear module cache to ensure fresh imports
|
|
57
|
+
jest.resetModules();
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('should export work-specific theme with overridden textInput from index', () => {
|
|
61
|
+
// Re-import to get the mocked version
|
|
62
|
+
// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
|
|
63
|
+
const { theme: workTheme } = require('../index');
|
|
64
|
+
|
|
65
|
+
// Verify that the theme has the work-specific textInput overrides
|
|
66
|
+
expect(workTheme.__hd__.textInput.colors.text).toBe('#WORK_THEME_COLOR');
|
|
67
|
+
expect(workTheme.__hd__.textInput.colors.background).toBe(
|
|
68
|
+
'#WORK_BACKGROUND'
|
|
69
|
+
);
|
|
70
|
+
expect(workTheme.__hd__.textInput.space.containerPadding).toBe(
|
|
71
|
+
'WORK_PADDING'
|
|
72
|
+
);
|
|
73
|
+
expect(workTheme.__hd__.textInput.fonts.text).toBe('WORK_FONT');
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('should export work-specific getTheme function with overridden textInput', () => {
|
|
77
|
+
// Re-import to get the mocked version
|
|
78
|
+
// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
|
|
79
|
+
const { getTheme: workGetTheme } = require('../index');
|
|
80
|
+
|
|
81
|
+
const workTheme = workGetTheme();
|
|
82
|
+
|
|
83
|
+
// Verify that getTheme returns work-specific textInput theme
|
|
84
|
+
expect(workTheme.__hd__.textInput.colors.text).toBe('#WORK_THEME_COLOR');
|
|
85
|
+
expect(workTheme.__hd__.textInput.space.containerPadding).toBe(
|
|
86
|
+
'WORK_PADDING'
|
|
87
|
+
);
|
|
88
|
+
expect(workTheme.__hd__.textInput.fonts.text).toBe('WORK_FONT');
|
|
89
|
+
});
|
|
90
|
+
});
|
package/src/index.ts
CHANGED
|
@@ -1,2 +1,14 @@
|
|
|
1
|
-
// Re-export
|
|
1
|
+
// Re-export everything from @hero-design/rn except theme exports we want to override
|
|
2
2
|
export * from '@hero-design/rn';
|
|
3
|
+
|
|
4
|
+
// Override theme exports with work-specific versions
|
|
5
|
+
export {
|
|
6
|
+
getTheme,
|
|
7
|
+
type Theme,
|
|
8
|
+
ThemeProvider,
|
|
9
|
+
ThemeSwitcher,
|
|
10
|
+
useTheme,
|
|
11
|
+
withTheme,
|
|
12
|
+
} from './theme';
|
|
13
|
+
|
|
14
|
+
export { default as theme } from './theme';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ThemeProvider as BaseThemeProvider, useTheme } from '@hero-design/rn';
|
|
3
|
+
import type { Theme } from './getTheme';
|
|
4
|
+
|
|
5
|
+
export interface ThemeProviderProps {
|
|
6
|
+
theme: Partial<Theme> | ((outerTheme: Theme) => Theme);
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface ThemeProviderType {
|
|
11
|
+
(props: ThemeProviderProps): React.ReactElement;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const WorkThemeProvider = BaseThemeProvider as ThemeProviderType;
|
|
15
|
+
|
|
16
|
+
const useWorkTheme = useTheme as () => Theme;
|
|
17
|
+
|
|
18
|
+
export { WorkThemeProvider, useWorkTheme };
|
|
19
|
+
|
|
20
|
+
export default WorkThemeProvider;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import React, { PropsWithChildren, useMemo } from 'react';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
eBensSystemPalette,
|
|
5
|
+
ehWorkDarkSystemPalette,
|
|
6
|
+
jobsSystemPalette,
|
|
7
|
+
swagDarkSystemPalette,
|
|
8
|
+
swagLightJobsSystemPalette,
|
|
9
|
+
swagLightSystemPalette,
|
|
10
|
+
swagSystemPalette,
|
|
11
|
+
walletSystemPalette,
|
|
12
|
+
workSystemPalette,
|
|
13
|
+
} from '@hero-design/rn';
|
|
14
|
+
import getWorkTheme from './getTheme';
|
|
15
|
+
import { WorkThemeProvider } from './ThemeProvider';
|
|
16
|
+
|
|
17
|
+
type ThemeName =
|
|
18
|
+
| 'swag'
|
|
19
|
+
| 'swagDark'
|
|
20
|
+
| 'swagLight'
|
|
21
|
+
| 'work'
|
|
22
|
+
| 'jobs'
|
|
23
|
+
| 'wallet'
|
|
24
|
+
| 'eBens'
|
|
25
|
+
| 'ehWorkDark'
|
|
26
|
+
| 'ehWork'
|
|
27
|
+
| 'ehJobs';
|
|
28
|
+
|
|
29
|
+
const WorkThemeSwitcher = ({
|
|
30
|
+
name = 'work',
|
|
31
|
+
children,
|
|
32
|
+
}: {
|
|
33
|
+
name?: ThemeName;
|
|
34
|
+
children: React.ReactNode;
|
|
35
|
+
}) => {
|
|
36
|
+
const theme = useMemo(() => {
|
|
37
|
+
switch (name) {
|
|
38
|
+
case 'swag':
|
|
39
|
+
return getWorkTheme(undefined, swagSystemPalette);
|
|
40
|
+
case 'work':
|
|
41
|
+
return getWorkTheme(undefined, workSystemPalette);
|
|
42
|
+
case 'jobs':
|
|
43
|
+
return getWorkTheme(undefined, jobsSystemPalette);
|
|
44
|
+
case 'wallet':
|
|
45
|
+
return getWorkTheme(undefined, walletSystemPalette);
|
|
46
|
+
case 'eBens':
|
|
47
|
+
return getWorkTheme(undefined, eBensSystemPalette);
|
|
48
|
+
case 'swagDark':
|
|
49
|
+
return getWorkTheme(undefined, swagDarkSystemPalette);
|
|
50
|
+
case 'swagLight':
|
|
51
|
+
case 'ehWork':
|
|
52
|
+
return getWorkTheme(undefined, swagLightSystemPalette);
|
|
53
|
+
case 'ehWorkDark':
|
|
54
|
+
return getWorkTheme(undefined, ehWorkDarkSystemPalette);
|
|
55
|
+
case 'ehJobs':
|
|
56
|
+
return getWorkTheme(undefined, swagLightJobsSystemPalette);
|
|
57
|
+
}
|
|
58
|
+
}, [name]);
|
|
59
|
+
|
|
60
|
+
return <WorkThemeProvider theme={theme}>{children}</WorkThemeProvider>;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export const withWorkTheme =
|
|
64
|
+
<P extends Record<string, unknown>>(
|
|
65
|
+
C: React.ComponentType<P>,
|
|
66
|
+
themeName: ThemeName
|
|
67
|
+
) =>
|
|
68
|
+
(props: PropsWithChildren<P>) => {
|
|
69
|
+
return (
|
|
70
|
+
<WorkThemeSwitcher name={themeName}>
|
|
71
|
+
<C {...props} />
|
|
72
|
+
</WorkThemeSwitcher>
|
|
73
|
+
);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export default WorkThemeSwitcher;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render } from '@testing-library/react-native';
|
|
3
|
+
import { Text } from 'react-native';
|
|
4
|
+
import { WorkThemeProvider, useWorkTheme } from '../ThemeProvider';
|
|
5
|
+
import workTheme from '..';
|
|
6
|
+
|
|
7
|
+
const TestComponent = () => {
|
|
8
|
+
const theme = useWorkTheme();
|
|
9
|
+
return <Text testID="test-text">Theme loaded: {theme ? 'Yes' : 'No'}</Text>;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
describe('WorkThemeProvider', () => {
|
|
13
|
+
it('should provide theme to children', () => {
|
|
14
|
+
const { getByTestId } = render(
|
|
15
|
+
<WorkThemeProvider theme={workTheme}>
|
|
16
|
+
<TestComponent />
|
|
17
|
+
</WorkThemeProvider>
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
expect(getByTestId('test-text')).toBeTruthy();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('should allow useWorkTheme hook to access theme', () => {
|
|
24
|
+
const { getByText } = render(
|
|
25
|
+
<WorkThemeProvider theme={workTheme}>
|
|
26
|
+
<TestComponent />
|
|
27
|
+
</WorkThemeProvider>
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
expect(getByText('Theme loaded: Yes')).toBeTruthy();
|
|
31
|
+
});
|
|
32
|
+
});
|