Comments (2)
Ship it. I think it’s the right call.
from jsxstyle.
Sorry for the delay! I’ve been thinking about this one for a while. I’m into the concept but I have some thoughts/concerns:
😓
- I’m not wild about the
cloneElement
usage. - This makes static analysis quite difficult if the
Styled
component contains dynamic children. Could warn about it injsxtyle-webpack-plugin
though, so not super concerning. - If a component doesn’t do anything with a
className
prop it will remain unstyled. This is a problem with the currentcomponent
prop as well, so also not super concerning.
😍
- Being able to style multiple children with the same styles is pretty cool.
- Component props and style props get to both be top-level (at long last!).
Styling inputs does suck, and it’s something I’ve been exploring a bit for jsxstyle 3. Up until now, jsxstyle has basically just swapped style props and component props.
Instead of writing code like this:
<input
type="text"
value="Hello"
style={{
display: 'block',
color: 'purple',
}}
/>
you write code like this:
<Block
component="input"
props={{
type: 'text',
value: 'Hello',
}}
color="purple"
/>
If you think of the styles as an object and component props as an object, the style object is usually going to contain more stuff, so moving it to the top level feels like the right thing to do. Swapping styles and component props isn’t necessarily better than what it’s replacing though—it’s just an API with a different set of priorities. Components that require a lot of props all of a sudden become a real chore to configure.
Separating component props from style props
Here’s an assumption I’m making: we want component props and style props at the same level.
<Block
component="input"
type="text"
value="Hello"
color="purple"
/>
If we had an allowlist of all component props, we’d be able to keep both component props and style props at the top level. With some runtime hacks we can actually get a list of all possible style props and then use that to separate component props from style props. The problem is that it’s not consistent, which means the types would potentially be lying to you and runtime implementations would differ slightly across each browser.
We could ask users for that list of props but this just seems like a different version of the same suckage:
<Block
component="input"
componentProps={['type', 'value']}
type="text"
value="Hello"
color="purple"
/>
The solution (?)
What if we kept an array of common component props? Here’s a rough example:
import React from 'react';
const commonProps = [
'id',
'name',
'placeholder',
'type',
'value',
] as const; // `as const` is necessary to make `CommonProp` nice and specific
// our common props as a union of strings
type CommonProp = (typeof commonProps)[number];
// a union of all HTML element names
type IntrinsicElement = keyof JSX.IntrinsicElements;
interface JsxstyleProps<T> extends React.CSSProperties {
component?: T;
}
// this is where the magic happens
type ComponentProps<T extends IntrinsicElement> = Pick<
JSX.IntrinsicElements[T],
Extract<keyof JSX.IntrinsicElements[T], CommonProp>
>;
const Example = <C extends IntrinsicElement = 'div'>(
props: JsxstyleProps<C> & ComponentProps<C>
): JSX.Element | null => {
// TODO: implementation :D
return null;
};
If you want to mess around with this a bit, here’s a TypeScript playground with a functioning example.
This array of common props wouldn’t be perfect, so we could allow users to provide a componentProps
array to add to the internal array of common props. The hope would be that we’d be able to remove the need for a componentProps
prop for the majority of users.
We could also auto-allow all aria/a11y-related props. I think we might do something like this already? 🤔
I like the simplicity, and we already do something like this for pseudoelement and pseudoclass prefixes.
Let me know what you think!
from jsxstyle.
Related Issues (20)
- export JsxstyleProps from jsxstyle.d.ts HOT 1
- Break with typescript's generic component HOT 4
- React 15 and `componentWillMount` HOT 3
- Break with using thread-loader on production HOT 2
- Replace most of the AST traversal in `extractStyles` with the TypeScript type checker HOT 2
- TS2503: Cannot find namespace 'JSX'. HOT 2
- RFC: Default `alignItems` to `center` for `Row` component
- React Native (react-native-web) HOT 3
- Question about useMatchMedia HOT 2
- RFC: Adjacent sibling selector API
- Clean up the server rendering API HOT 1
- Color helpers HOT 1
- Ideas for a jsxstyle 3.0 HOT 2
- React native web support HOT 3
- jsxstyle doesn’t have flow types HOT 1
- CSS custom properties and jsxstyle
- New top-level component prop: disabled HOT 1
- Proposal: combine jsxstyle and webpack plugin HOT 1
- Compatibility with [email protected] HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from jsxstyle.