jahilldev / component-elements

Create a custom element from any component with these tiny functions (2KB GZipped, ~1KB Brotli). Preact and React currently supported
MIT License
89 stars 7 forks source link

Slot casing #16

Closed allanpope closed 2 years ago

allanpope commented 2 years ago

Hey,

If I add an attribute to my web component eg: foo-bar="123", it will be available in the components props as fooBar.

If I pass through a slot eg: <p slot="hello-world">Hello</p>, it will be available in the components props as hello-world. Is it possible to get slot attributes coming through in camelcase?

jahilldev commented 2 years ago

Hi @allanpope!

Thanks for reaching out.

If I understand correctly, you're proposing we normalise the slot keys from a casing (snake, kebab, pascal, etc), into camelCase?

I can't see any immediate issues with this, other than making sure the logic that does this can handle the potential variations in casing I mention above. We probably can't assume someone will use one or another.

When I get a minute I'll take a look into doing this, otherwise, feel free to have a go, all contributions welcome 👍

The alternative to this (which wouldnt involve additional code / bytes), of course, is to just use camelCase keys for the slot attributes:

slot="mySlot"

That way the prop key will be in the relevant casing.

Either way, let me know your thoughts.

Thanks

allanpope commented 2 years ago

Thanks, yeah thats right. It seems to already be normalised for the the attributes but not the slots. If I get time I'll try to take a look at implementing it also.

In my case all web component attributes are defined in kebab case, eg: <p slot="loading-indicator">Loading...</p> and I can't easily tell consumers to switch to camelcase.

In my preact component i'd like to destructure the prop to but I cant, as it's kebab case. Instead I do props['loading-indicator'].

jahilldev commented 2 years ago

@allanpope While we look into doing this, you could destructure using computed properties. Not the cleanest solution, I know:

const INDICATOR = 'loading-indicator'; // In a config somewhere?

/*[...]*/

const { [INDICATOR]: loadingIndicator } = props;

I'm going to have a bash at this sometime this week, will let you know how I get on.

I'll provide support for the major casing types, as others might have different requirements, e.g Pascal, snake_case, and kebab-case. I'll also update the README accordingly so this is clear to others.

jahilldev commented 2 years ago

Hi @allanpope,

Apologies for the delay, I've just opened a PR that does the above, handling common casing conventions including "Sentence Case" (just for fun): https://github.com/jahilldev/component-elements/pull/17

Let me know what you think.

I'll merge and deploy soon.

Thanks 👍

allanpope commented 2 years ago

@jahilldev awesome 🎉, appreciate it

jahilldev commented 2 years ago

@allanpope I've just merged and published preactement@v1.8.0 and reactement@1.1.0.

Let me know how you get on, feedback either way!

Thanks 👍

EDIT: I'd strongly suggest you jump to preactement v1.8.2 or reactement v1.1.2, depending on whichever library you're using. I've just published a bug fix for children props and SSR.

jahilldev commented 2 years ago

@allanpope I'm going to close this issue for now, let me know if you have any other problems with this and we can revisit.

Thanks again for contributing! 👍

allanpope commented 2 years ago

Worked great, cheers