How to deconstruct properites on import based on theme? - javascript

I have a colors.ts file:
export const black = '#0C0C0C';
export const blue = '#22618E';
and when ever I want to import a specific color I import it like:
import {black} from 'Shared';
In my Shared folder I have an index.ts that exports the colors:
export * from './colors';
Now I want to be able to export and Import the same way when using a theme.
Example
colors.ts:
const DefaultTheme = {
black: '#0C0C0C',
blue: '#22618E',
}
const SpecialTheme= {
black: 'red',
blue: 'yellow',
}
export const ColorsBytheme = () => {
const context = myContext();
return context.Default? DefaultTheme :SpecialTheme;
}
Problem:
I can not deconstruct/import the properties directly, this gives me undefined:
import {black} from 'Shared';
How can I accomplish this?
EDIT:
I have also tried by using a self invoking function when exporting:
const ColorsBytheme = () => {
return DefaultTheme;
};
export default ColorsBytheme();
When I import
import { black } from 'Shared';
It is still undefined

Based on your code example, you are currently exporting ColorsBytheme as a function that generates/returns the theme object...therefore, your import/deconstruction would need to look something along the lines of:
import { ColorsBytheme } from "Shared"
const { black } = ColorsBytheme();
Another option if you wish to have a single line would be to use require instead of import:
const { black } = require("Shared").ColorsBytheme()
Variables that are imported are just that, static variables. Functions are not evaluated when they are imported, therefore, in order for the values to be dynamic, the function needs to be executed.

Related

Export without destructuring

import { utils } from 'shared'
const {
pick,
get,
isEmpty,
sortBy,
orderObjectsArray,
isString
} = utils.lodashAlternative
export { pick, get, isEmpty, sortBy, orderObjectsArray, isString }
Above you can see exports , imagine I don't want to desctructure all of those functions , how can I do it ? I've tried to make export utils.lodashAlternative , but it will not work , also :
const {...data} = utils.lodashAlternative
export {...data}
Also will not work, it there any way to export it without discructuring ?
A simple way to export everything under utils.lodashAlternative is creating an alias and exporting that one instead.
There's no need to create an object and spread lodashAlternative inside.
You can't declare and export afterwards (unless you use as)!
Way 1: using default
import { utils } from 'shared'
const lodashAlternative = utils.lodashAlternative;
export default lodashAlternative;
Way 2: exporting directly
import { utils } from 'shared'
export const lodashAlternative = utils.lodashAlternative;
Way 3: export each one separately, to be able to import them separately
import {utils} from "shared";
const { foo, bar } = utils.lodashAlternative;
export { foo, bar };
import then:
// WITH WAY 1
import lodashAlternative from "lodash-alternative";
// WITH WAY 2
import {lodashAlternative} from "lodash-alternative";
// WITH WAY 3
import {foo, bar} from "lodash-alternative";
Blitz here

React: How to combine each multiple styles marked in Material-UI

I have two styles.
One thing is included in specific components, another thing is included in global components.
for example, let's suppose that we have the following tree.
index.tsx
-App.tsx
-globalConstants.ts
in globalConstants.ts
import { Theme, makeStyles, createStyles } from '#material-ui/core/styles';
export const sharedStyles = makeStyles((theme: Theme) =>
createStyles({
.
.
.
}),
);
in App.tsx
import React from 'react';
import { Theme, makeStyles, createStyles } from '#material-ui/core/styles';
import { sharedStyles } from '../constants/globalConstants'
const useStyles = makeStyles((theme: Theme) =>
createStyles({
.
.
.
}),
);
My problem is I can't combine useStyles and sharedStyles into one classes variable.
Of course, I can use this like following
export default function NavBar() {
const classes = useStyles();
const sharedClasses = sharedStyles();
}
But I'd like to combine classes and sharedClasses into one constants such as
const classes = {useStyles()+sharedStyles())
Is there some good way how to combine that?
Well, it seems to lead us to an open-based answer, still, I'd like to provide some approach that I have found.
Refer to material-ui official document: styles_advanced
You can use third-party libs like clsx.
import clsx from 'clsx';
import { makeStyles } from '#material-ui/core/styles';
const useStylesBase = makeStyles({
root: {
color: 'blue', // 🔵
},
});
const useStyles = makeStyles({
root: {
color: 'red', // 🔴
},
});
export default function MyComponent() {
// Order doesn't matter
const classes = useStyles();
const classesBase = useStylesBase();
// Order doesn't matter
const className = clsx(classes.root, classesBase.root)
// color: red 🔴 wins.
return <div className={className} />;
}
I'm sure there are many similar libs so choose the one you feel good about.
And you can implement it by yourself, refer to the sample in this issue
function combineStyles(...styles) {
return function CombineStyles(theme) {
const outStyles = styles.map((arg) => {
// Apply the "theme" object for style functions.
if (typeof arg === 'function') {
return arg(theme);
}
// Objects need no change.
return arg;
});
return outStyles.reduce((acc, val) => Object.assign(acc, val));
};
}
export default combineStyles;
Hope this answer would find you well.

Can not import functions corretly in reactJS App?

I am having problem with import, I have a file like this :
import { TYPE_CONTRAT_UPDATE, CONFORMITE_UPDATE } from "./actionsTypes";
import { createAction } from "../../../../../../redux/Utilities";
const updateTypeContrat = (idContrat, data, success, error) =>
createAction(TYPE_CONTRAT_UPDATE.PUT_CALL, { idContrat, data, success,
error });
const updateConformiteContrat = (idContrat, data, success, error) =>
createAction(CONFORMITE_UPDATE.PUT_CALL, { idContrat, data, success,
error });
export default { updateTypeContrat, updateConformiteContrat};
I am trying to import as you can see variables in capital from my file actionsTypes, here is the file :
import { createPutTypes } from "../../../../../../redux/Utilities";
const TYPE_CONTRAT_UPDATE = createPutTypes("TYPE_CONTRAT_UPDATE");
const CONFORMITE_UPDATE = createPutTypes("CONFORMITE_UPDATE");
export default { CONFORMITE_UPDATE, TYPE_CONTRAT_UPDATE }
But I get an error :
Line 1: TYPE_CONTRAT_UPDATE not found in './actionsTypes' import/named
Line 1: CONFORMITE_UPDATE not found in './actionsTypes' import/named
Any help would be much appreciated.
You need to use named export instead of the default.
import { createPutTypes } from "../../../../../../redux/Utilities";
export const TYPE_CONTRAT_UPDATE = createPutTypes("TYPE_CONTRAT_UPDATE");
export const CONFORMITE_UPDATE = createPutTypes("CONFORMITE_UPDATE");
Those imports, as said from the error, should be named exports.
DEFAULT export
A default export (export default [...] is what will be imported when using import X from 'fileX'. There can be only one. No matter what you assign the import to in this case (here, you assign it to X), it will work
// fileX.js
export default Example;
You can do either
import X from 'fileX'; // works, X contains Example
import Example from 'fileX'; // same
...
NAMED exports
A named export (export const TYPE_CONTRACT = [...]) can be used as much as you want, however, the name of the import matters:
// fileX.js
export const Example = [...]
means that the import should be :
import { Example } from 'fileX'; // works properly, Example contains the export of fileX
import { X } from 'fileX'; // won't work, no way to know which export you're referring to
import Example from 'fileX'; // won't work either, this is not a default export.

Exporting constants from array

I have a long set of exported constants in a file. Here's an excerpt:
...
export const COUNTER_INCREMENT_REQUESTED = 'COUNTER_INCREMENT_REQUESTED';
export const COUNTER_INCREMENT_REQUESTED_ASYNC = 'COUNTER_INCREMENT_REQUESTED_ASYNC';
export const COUNTER_DECREMENT_REQUESTED = 'COUNTER_DECREMENT_REQUESTED';
export const COUNTER_DECREMENT_REQUESTED_ASYNC = 'COUNTER_DECREMENT_REQUESTED_ASYNC';
...
Is there a way to create an array and loop through it, exporting each value?
const events = [
...
'COUNTER_INCREMENT_REQUESTED',
'COUNTER_INCREMENT_REQUESTED_ASYNC',
'COUNTER_DECREMENT_REQUESTED',
'COUNTER_DECREMENT_REQUESTED_ASYNC',
...
]
for(event of events) {
export ...
}
No this is not possible.
One of the notable feature of ES module system is that the module structure can be statically analysed. This basically prevents programatically exporting things as you wish to do, as then it would break the static analysability.
I did manage a variation on this by putting the constants in it's own file/module, then importing them into the module and looping over them there.
constants.js
export const COUNTER_INCREMENT_REQUESTED = 'COUNTER_INCREMENT_REQUESTED';
export const COUNTER_INCREMENT_REQUESTED_ASYNC = 'COUNTER_INCREMENT_REQUESTED_ASYNC';
export const COUNTER_DECREMENT_REQUESTED = 'COUNTER_DECREMENT_REQUESTED';
export const COUNTER_DECREMENT_REQUESTED_ASYNC = 'COUNTER_DECREMENT_REQUESTED_ASYNC';
index.js
import * as actions from './constants';
...
let eventEmitters = {};
for(const action in actions ) {
...
}
export default eventEmitters;

Export component with and without hoc in one export

Is there any way to export component(s) with or without hoc in one export? I know I can do it like this:
export const TranslatedList = translate('components')(List);
export const PureList = List;
but is there any other way to do something like below:
export {
TranslatedList: translate('components')(List),
PureList: List,
};
and in index.js something like:
import { TranslatedList } from './List';
export default TranslatedList;
maybe stupid question but this will be really helpful to me
Maybe use node.js native exports like this:
module.exports = {
TranslatedList: translate('components')(List),
PureList: List,
};
And require it
const {TranslatedList, PureList} = require('list.js');
A little late to the party. I did not find a "great" solution to this issue, but this is an "ok" one, in my opinion.
const TranslatedDropzone = translate()(Dropzone)
const TranslatedDropzoneControls = translate()(DropzoneControls)
const TranslatedDropzonePreview = translate()(DropzonePreview)
const TranslatedFilePreview = translate()(FilePreview)
export {
TranslatedDropzone as Dropzone,
TranslatedDropzoneControls as DropzoneControls,
TranslatedDropzonePreview as DropzonePreview,
TranslatedFilePreview as FilePreview
}
export default TranslatedDropzone
In ES6 you simply cannot do this:
export {
TranslatedList: translate('components')(List),
PureList: List,
};
Instead you can try doing this:
const toExport = {
TranslatedList: translate('components')(List),
PureList: List,
};
export toExport;
To import, simply do this:
import { TranslatedList, PureList } from './list.js';

Categories