Open dehypnosis opened 4 years ago
But the whole process of styles injection is complicate and veiled, I think.
As for a final user, how does it affect your product? The idea is let users do nothing, making the plugin doing the required job. As a user in most cases I don't want to focus on the details. I'm glad to discuss if you have any ideas to simplify, but saving this concept is required.
Also my project is mono-repo which raises no such file path.. error with @ui-kitten/metro-config. (I had to make a tricky workaround to resolve it with @ui-kitten/metro-config)
Could you please explain in a bit more details or (what is even better) create a demo project?
I hope a tool to generate styles JSON (or js module) with command line might be good
Do you have ideas of what it should be like to cover the problems you faced? If it is a command-line function, what it should be like?
A1/A2. It does not affect to the final product surely but it intervened development process.
Firstly, I couldn't make variant styles for each platforms. So I had to dig into and figured out whole generation process and de-hoisted each @eva-design/{theme}
modules for each platforms.
It took me a lot of time.
At this point, I thought rather transparent even complicated API could be better for my case. Because setting up UI framework is very important and only required for the phase of initial project setup, so I could gladly elaborate it with much times.
Secondly, Automated metro-config
module didn't find right directory of @eva-design/{theme}
for my project which looks like below.
node_modules
@eva-design/
pkg/
common/
src/
app.tsx
mobile/
ios/
android/
web/
...
Sorry for not providing demo project but simply RELATIVE_PATHS
and resolution logic cannot fit for every structure.
const RELATIVE_PATHS = {
evaPackage: (evaPackage: string): string => {
return `node_modules/${evaPackage}`;
},
evaMapping: (evaPackage: string): string => {
return `node_modules/${evaPackage}/mapping.json`;
},
evaIndex: (evaPackage: string): string => {
return `node_modules/${evaPackage}/index.js`;
},
cache: (evaPackage: string): string => {
return `node_modules/${evaPackage}/${CACHE_FILE_NAME}`;
},
};
So I had to modify metro-config
module code a little to correct the wrong path for my project.
A3. After struggling with above problems. I just removed metro-config
module and manually compiled each styles for each platforms with @eva-design/processor
module. Then simply put them to context provider component directly.
So here IMHO, what about to generate styles directly to project tree with metro-config
rather creating styles into node_modules
directory and modifying @eva-design/{theme}
module main code? (forget about the CLI here)
For example... as like below.
const MetroConfig = require('@ui-kitten/metro-config');
const evaConfig = [
{
evaPackagePath: path.resolve('@eva-design/eva'),
customMappingPath: path.resolve('./custom-mapping.web.json'),
outputStylesPath: path.resolve('./styles.web.json'),
},
{
evaPackagePath: path.resolve('@eva-design/eva'),
customMappingPath: path.resolve('./custom-mapping.native.json'),
outputStylesPath: path.resolve('./styles.native.json'),
},
];
module.exports = MetroConfig.create(evaConfig, {
// Whatever was previously specified
});
import { checksum, styles } from "./styles";
// ...
function App() {
return (
<EvaThemeProvider styles={styles} theme={theme}>
{/* ... */}
</EvaThemeProvider>
);
}
Thank you for reading.
@dehypnosis Well, I thinking a bit about the possible solutions for platform-dependent mappings, and here is the best option I realized: Instead of using several mapping files, you can just use a variant groups feature. For instance, in mapping:
// ...
"MyComponent": {
// ...
"mapping": {},
"variantGroups": {
"platform": {
"ios": {
"fontSize": 24
},
"android": {
"fontSize": 24
},
"web": {
"fontSize": 32
},
},
},
}
Then, in js:
<MyComponent platform={Platform.OS} />
I guess it covers every use-case and allows you having only one mapping.json
. Also, it wouldn't break watchers. What do you think?
but simply RELATIVE_PATHS and resolution logic cannot fit for every structure.
That's true. I guess it should be rewritten with using of node process arguments.
Wow you are such a genious, that structure looks really good. I have no different idea.
Bytheway what about module.exports.styles = (generated module)
logic? Going as original one with correct path resolution?
Seeing your new mapping structure, It seems that variant components (providers? right?) can have variant plaforms' mappings. So is there an idea for generating multiple compilations to inject into each components for each proper platforms automatically or rather manually?
2020년 4월 20일 (월) 오후 9:57, Artur Yorsh notifications@github.com님이 작성:
@dehypnosis https://github.com/dehypnosis Well, I thinking a bit about the possible solutions for platform-dependent mappings, and here is the best option I realized: Instead of using several mapping files, you can just use a variant groups feature. For instance, in mapping:
// ..."MyComponent": { // ... "mapping": {}, "variantGroups": { "platform": { "ios": { "fontSize": 24 }, "android": { "fontSize": 24 }, "web": { "fontSize": 32 }, }, }, }
Then, in js:
I guess it covers every use-case and allows you having only one mapping.json. Also, it wouldn't break watchers. What do you think?
but simply RELATIVE_PATHS and resolution logic cannot fit for every structure.
That's true. I guess it should be rewritten with using of node process arguments.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/akveo/react-native-ui-kitten/issues/1019#issuecomment-616534954, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAY4ZLJWFQBAYYD6JVAKWHDRNRBCDANCNFSM4MHO747Q .
Seeing your new mapping structure
It's not new. This is something that already works. For instance, in terms of Eva status
and size
properties of button are variant groups. Also, you can combine multiple variant groups to achieve the result.
Mapping is extendable. For now, the only thing you may stuck when adding custom variant groups (like platform
) to existing components is that you'll have TS issues if you use it. Anyways, it will not break your own components if you describe them.
Okay I got it. what a flexible code base!
2020년 4월 21일 (화) 오전 1:37, Artur Yorsh notifications@github.com님이 작성:
Seeing your new mapping structure
It's not new. This is something that is already works. For instance, status and size properties of button are variant groups. Also, you can combine multiple variant groups to achieve the result.
Mapping is extendable. For now, the only thing you may stuck when adding custom variant groups (like platform) to existing components is that you'll have TS issues if you use it. Anyways, it will not break your own components if you describe them.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/akveo/react-native-ui-kitten/issues/1019#issuecomment-616670468, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAY4ZLNRGNV3JLPEVRBGAP3RNR24TANCNFSM4MHO747Q .
@dehypnosis I would suggest looking through existing implementation to realize how it works. There is no meaningful documentation on working with mapping to be honest.
So <ApplicationProvider platform={..} ... />
is avilable with strict
mapping with variant groups now?
2020년 4월 21일 (화) 오전 1:44, Artur Yorsh notifications@github.com님이 작성:
@dehypnosis https://github.com/dehypnosis I would suggest looking through existing implementation to realize how it works. There is no meaningful documentation on working with mapping to be honest.
mapping.json https://github.com/eva-design/eva/blob/master/packages/eva/mapping.json
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/akveo/react-native-ui-kitten/issues/1019#issuecomment-616674966, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAY4ZLK5OIYHISSSO4K4QYDRNR3X3ANCNFSM4MHO747Q .
@dehypnosis ApplicationProvider has no variant groups, this is about the components.
Okay then for examlple how can i set whole font family for web plaform only? Sorry for bothering you with too much questions. If cannot, It comes back to the start of the issue for me..
2020년 4월 21일 (화) 오전 1:59, Artur Yorsh notifications@github.com님이 작성:
@dehypnosis https://github.com/dehypnosis ApplicationProvider has no variant groups, this is about the components.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/akveo/react-native-ui-kitten/issues/1019#issuecomment-616683797, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAY4ZLLZ4XF2DBAOXSJIBT3RNR5OJANCNFSM4MHO747Q .
Well, let's dive deeper into the mapping engine together. 🚀
So what the docs say: you may use text-font-family
to set the font globally for all components.
Now lets go deeper and remember that the text in React Native should also be wrapped in a Text component, meaning we're able to customize it.
Knowing all of that, let's see how the Text mapping is structured. And realize we can create a platform
variant group to make it platform dependent like it was described above.
The final optimization I see here would be creating own component which renders UI Kitten Text component, but a little optimized with defaultProps
to include platform: Platform.OS
which will finally make the text configured for the platform it runs with no extra props.
Easy 😄 🤷♂️
I got the idea, so you mean it?
<ApplicationProvider {...eva}>
<MyTextWrapperWithPlatformProps platform={Platform.OS}>
// ...
</MyTextWrapper>
</ApplicationProvider>
with "MyTextWrapperWithPlatformProps" mapping for custom text-font-family.
Then will the mapping be inherited by the descendants? If then, all my needs will satisfy. Anyway thanks a lot for your awesome work and about the answers. I will try your solution later when the path resolution issue fixed.
@dehypnosis what // ...
in text children supposed to be?
Then will the mapping be inherited by the descendants?
Not by children. That's why I suggest creating defaultProps
Having the same issue with a NX monorepo setup, curious to know how this evolves....
@dehypnosis
you wrote:
- Also my project is mono-repo which raises
no such file path..
error with@ui-kitten/metro-config
. (I had to make a tricky workaround to resolve it with@ui-kitten/metro-config
)
Also my project is mono-repo which raises no such file path.. error with @ui-kitten/metro-config. (I had to make a tricky workaround to resolve it with @ui-kitten/metro-config)
What was that workaround? I am having the exact same issue, and i cant find anything on how to resolve this...
thanks in advance!
I ran into similar issues. This was my workaround for the hard-coded RELATIVE_PATHS
inside BootstrapService (detect root and call process.chdir
before calling BootstrapService.run
):
// cli.js
const path = require('path');
const findWorkspaceRoot = require('find-yarn-workspace-root');
const BootstrapService = require('@ui-kitten/metro-config/services/bootstrap.service').default;
function findRootFolder() {
const packageFolder = path.dirname(__dirname);
const index = packageFolder.toLowerCase().indexOf('node_modules');
const isRunningInsideNodeModules = index > -1;
if (isRunningInsideNodeModules) {
return packageFolder.substring(0, index);
}
// running inside local monorepo:
return findWorkspaceRoot(packageFolder);
}
const rootFolder = findRootFolder();
process.chdir(rootFolder);
BootstrapService.run({ evaPackage: '@eva-design/eva', customMappingFile: '....' });
node cli
🚀 Feature Proposal
Currently(v5), theme style JSON can be pre-generated with
@ui-kitten/metro-config
module. Which watches a given custom mapping file and creates a JSON file, then injects the created JSON file undernode_modules/@eva-design/...
directory. And the@eva-design/eva or material
modules' entry source code is rewrited to exportsexports.style = (style object from generated JSON)
. And finally<ApplicationProvider styles={evaModule.styles} (...)>
be not going to create styles in runtime.It works well and seems to make launching somewhat faster (I have not exactly measured yet).
no such file path..
error with@ui-kitten/metro-config
. (I had to make a tricky workaround to resolve it with@ui-kitten/metro-config
)While struggling with above problems, I thought rather another way of style pre-generation would be great. So now I generate styles modules by programmatically call the
schemaProcessor.createStyles
and store it into project files, then requires modules for each platforms and provide asstyles
prop ofApplicationProvider
.Yes it won't watch the custom mapping dynamically but it can support multiple styles and seems to easy to understand the theming flow.
I hope a tool to generate styles JSON (or js module) with command line might be good rather current veiled process. What do you think about such problems?
Example
Generate styles as js module to reduce JSON parsing time before build for native and web platforms each.
Provide styles in runtime