ghostdevv / svelte-turnstile

A lightweight Svelte component for Cloudflare Turnstile
https://svelte-turnstile.pages.dev/
MIT License
163 stars 10 forks source link

Add `class` to the `div` element #9

Closed FluffyDiscord closed 2 months ago

FluffyDiscord commented 1 year ago

Please add option to add CSS classes to the div element

image

ghostdevv commented 1 year ago

Hey, what issues are you running into that would need you to style that div?

FluffyDiscord commented 1 year ago

The package is understandably using div that Turnstile can mount to. The annoyance comes using flex with gaps or grid in CSS and having invisible Turnstile implementation. Since it's invisible, I have to manually wrap it whole in display: none element and manage the state myself (show/hide) so it doesn't always break my form design.

This is just a nitpick, but it's one less wrapping element, because I could change the class prop of your component instead of my wrapping element

ghostdevv commented 1 year ago

My only concern with adding a class prop is that it's not something that svelte supports - i.e. you couldn't pass scoped classes

Perhaps there is a better solution, like an invisible option on the component - could you share an example of your show/hide logic?

blujedis commented 4 months ago

Is there a reason why a simple export can't be used here? I ran into the same need as @FluffyDiscord. While not the end of the world this seems like a quick convenience fix.

Example of what that might look like:

<script lang="ts">
  export let classes = '';
</script>

{#if loaded && mounted}
    {#key $$props}
        <div use:turnstile class={classes} />
    {/key}
{/if}

You can also take it a step further and update the $$Props type in your component then the user could simply pass class as they normally would for an element.

types.ts

import type { SvelteHTMLElements } from 'svelte/elements';
export type HTMLTag = keyof SvelteHTMLElements;
export type ElementProps<K extends HTMLTag> = SvelteHTMLElements[K];

Component.svelte

$$Props = { theme: TurnstileTheme; size: TurstileSize; ...} & ElementProps<'div'>;
export let {
   theme,
   size,
} = {
  theme: 'auto',
  size: 'normal',
  ...
} as $$Props;

By exporting your props in this manner you'll be able to pass class in directly:

UserComponent.svelte

<Turnstile siteKey="SITE_KEY" class="flex justify-center" />
ghostdevv commented 2 months ago

Since it's been requested a few times now I've gone ahead and added this in v0.7.0 - I'm not a massive fan but I can definitely understand the value! Hopefully in the future I can refactor this component to be an action instead and give devs full control of the place it's mounted into.

cc: @FluffyDiscord @blujedis

blujedis commented 2 months ago

@ghostdevv think this is the right call gracias.