110 karma · joined March 20, 2021
(1) helpers to generate base colors and palettes based on various color relationships, e.g. complementary, split-complementary, double-complementary, analogous, triadic
(2) auto-generating a complete set of palettes and their base colors (opinionated), based on a single color value input (the "primary brand color")
(3) opinionated default "role mapping function"
All the above provide various levels of "automation", from fully customized to single color value input, full automation.
Thanks for the feedback. Hope to get more of your valuable inputs.
I am gathering useful links like this, and will make them available in the README for further readings.
--- start excerpt ---
The main intention/purpose of the library is to provide a well-defined structure to guide the developer in crafting their color system. Especially when using TypeScript, this benefit is immediately felt.
Since this is the very first release of the lib, it only includes this core functionality. Based on feedback from users, I intend to build up the library to include more things that users would say are useful to them.
Based on your comment, it looks like one such enhancement could be to add functionality to generate additional base colors based on a single "seed" color (e.g. the main brand color), e.g. a triad of base colors (primary, secondary, tertiary) based on Triadic Palette from the primary's base.
This is where feedback like yours will help make this library more helpful to more developers.
--- end excerpt ---
To address your specific example, the pattern you pointed out is not really equivalent to c(a, b). The color mapping function "c" is applied internally when building the individual palettes, not to (a, b).
I will try to make my example in the README a little less contrived, as I can see where the confusion is coming from.
Also when in the future versions this library will bundle various color mapping functions (again, based on user feedback), the structure provided by the library will make more sense because the "c" part there would be any one of the pre-built functions that you can just pass to the `colorScheme()` helper.
Again I appreciate your insights.
The main intention/purpose of the library is to provide a well-defined structure to guide the developer in crafting their color system. Especially when using TypeScript, this benefit is immediately felt.
Since this is the very first release of the lib, it only includes this core functionality. Based on feedback from users, I intend to build up the library to include more things that users would say are useful to them.
Based on your comment, it looks like one such enhancement could be to add functionality to generate additional base colors based on a single "seed" color (e.g. the main brand color), e.g. a triad of base colors (primary, secondary, tertiary) based on Triadic Palette from the primary's base.
This is where feedback like yours will help make this library more helpful to more developers.
Admittedly a lot of pointers like this are missing in the README, because there's just a lot about Color Theory and generally the science behind color, than what my documentation has space for.
Can you recommend a link to a nice website where users can learn more about things like this? I would like to add that link to the README.
I appreciate your insights.
This area is where TypeScript would play nicely. The library implements types that fully utilize generics to define and impose restrictions for color keys, as well as ensuring type consistency across the color system. * This is the next item in my list to add to the documentation. *
So for example, you can easily implement a color system similar to Material Design 3 that only accepts these color keys: 0 | 10 | 20 | 30 ... 90 | 95 | 98 | 100. But as this is not every color system's approach, the library adopts the least restrictive default, so you can say it's less opinionated.
But for pure JS projects, custom color mapping can do the job if your design system prescribes discrete color keys for palette colors.
Although the library is not a color generator per se, it has one built-in palette generator (color mapping function), which is tonal/monochromatic--chosen as default because it's the most common palette type used by popular design systems like Material Design. You can use third-party libraries to aid writing any additional color mapping function you want to implement. (I can also include additional color mappings based on feedback.)
Ultimately, what simpler-color provides is a well-defined structure for your custom color system that works well with various color-generator libraries.
Using a proper color system for your UI ensures a cohesive, more polished look for your application. This library makes it super easy for you to create your very own color system.
Works both in browser and Node, and whichever UI framework/libraries you're using.
Hope you find this useful.
So to answer the question, yes SimpleR State works with SSR, but you need to take an extra step. You would need to somehow "scope" your global state inside the React component tree. The most common solution is using a Context to store your server-side entities, so that they are not "shared" among SSR requests.
SimpleR State proclaims itself as "unopinionated", so the preferred SSR solution is a decision that the developer has to make. It would be worth adding some options in the documentation, though. So thanks for bringing this up. I also received a few requests on such documentation in the previous Request For Comments during the beta run. A doc page on SSR is underway.
Thanks for your encouraging feedback.
But since I want to help as much as I can, my advice is, regardless of which library you choose, or which approach (atomic vs. monolithic/structured)... start with analyzing which parts of the state in your app really are supposed to be "shared" state. I have a feeling you may be trying to use "shared" state libraries to manage state that only the individual components would actually need. Do those dynamic components actually need to share data? The answer to that is the first important consideration, IMHO, before you can go forward.
Good luck.
Don't get me wrong. SimpleR State is a "complete" library despite the simple API. It supports things like selectors, async actions, and plug-ins. And soon, it will come with built-in plug-ins like persistence, Dev Tools, validation, etc.
Everyone has different priorities when choosing a library, so I suggest going through the design goals that I highlighted in the README file, or complete documentation here:
and see if it fits what you're specifically looking for in a library.
At the end of the day, all these libraries are just React code. In that sense they differ in terms of patterns/principles behind their implementation, but maybe more importantly, in the API/syntax (which is what immediately matters to the developer using it). This is what I can confidently say that SimpleR State delivers... one of the simplest APIs you can find.
But first thing you should identify, IMHO, is which of those states are _really_ "shared" states. Coz some of those state values are probably better kept local.
It's never my intention for this library to try and be the "best" out there. I simply want to create what I sought for, which is the closest to the simplest approach I can think of. And to share it to the public, in case someone out there is looking for the same thing I am, and maybe it could help that someone. That's what open source is for, after all.
But there is always an alternative, IMHO. If the project has a good code structure and follow equally good coding standards and review process, using simple un-opinionated/flexible libraries would not be a liability with "scale" (in terms of team/project size).
And there's one advantage of simpler approaches for growing teams: faster/easier onboarding. Let's face it, even good React/Redux developers can understand simpler code faster.
Just an alternative thought. But I completely get your point.
I tried scoping the entities using Context in some prior art which we use in production. Some colleagues kindly gave me some benchmark results and the version without Context (external/module-scope) was faster.
I'm not trying to debate against Context here. In fact, there's nothing that would stop anyone from using SimpleR State's entities with Context API.
1. It was inadvertently removed from the documentation, but these are equivalent:
const count = counter.use()
const count = useEntity(counter)
but the `counter.use()` was chosen in the documentation due to more feedback that requested this "simpler" format (i.e. no need to import `useEntity()`. But again, to your point I will restore the mention of `useEntity` in the documentation.2. As for the [state, setState] convention, think of useEntity more like useContext than useState. Then it gets simpler.
3. I would also argue that since this is "shared" state, the developer might (again, the library is not opinionated on this) choose to separate the logic of updating shared state. For this reason, I didn't see any reason to provide a setter through the hook, when you can access the setter from anywhere via something like counter.set(). Conforming to useState convention was not justified in this case, especially since useContext convention equally makes sense for shared state.
4. To suit whatever convention, you can always do something like this alongside the definition of the entity:
export const useCounter = counter.use
I want to point out that SimpleR State provides the flexible constructs to allow the developer to tailor it to their preferred convention.Thanks for your feedback.
Since data is not encapsulated inside React component tree, I found it to be multiple times faster than when using Context.
And one thing that's perhaps the most obvious... it's simpler because you don't have to use Providers at all.
https://simpler-state.js.org/recipe-transforms.html
Thanks for your reply.
Specifically, look at these "Recipes" pages: