Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Astro component shims #590

Open
adamburmister opened this issue Mar 9, 2025 · 0 comments
Open

Astro component shims #590

adamburmister opened this issue Mar 9, 2025 · 0 comments

Comments

@adamburmister
Copy link

Summary

Preline suffers from Bootstrap-copy-paste syndrome. An Astro component system would help DRY.

Detailed Description

I really want to use Preline as my SaaS component lib on an Astro SSR site.

  • I like doing things SSR
  • I cannot use ShadCN/UI due to React contexts on SSR

While the style of copy-pasting component HTML works, it ends up in unmaintainable code.

  • If i need to update a Preline component I need to find-replace across the entire codebase, which becomes increasingly difficult as the code wavers with customisations
  • Because of the verbosity, it becomes hard to read HTML and understand component structures

It would really be useful to have a series of Astro shims for the components to make it more readable...

<AvatarGroup>
  <Avatar src={avatar1} name="Maria" alt="Maria" />
  <Avatar src={avatar2} name="John" alt="John" />
  <Avatar src={avatar3} name="Sara" alt="Sara" />
  <Avatar src={avatar4} name="Mike" alt="Mike" />
</AvatarGroup>

With an example implementation:

---
import { cn } from "@/lib/utils";
import { type VariantProps, cva } from "class-variance-authority";

const avatarGroup = cva(["flex"], {
  variants: {
    spacing: {
      tight: "-space-x-4",
      normal: "-space-x-2",
      loose: "-space-x-1",
    },
    limit: {
      true: "has-[*:nth-child(n+6)]:has-[*:last-child]:hidden",
    },
  },
  defaultVariants: {
    spacing: "normal",
    limit: false,
  },
});

export type AvatarGroupVariantProps = VariantProps<typeof avatarGroup>;

export type Props = AvatarGroupVariantProps & {
  class?: string;
  max?: number;
  showCount?: boolean;
  totalCount?: number;
};

const {
  spacing,
  limit,
  class: className,
  max = 5,
  showCount = true,
  totalCount,
  ...rest
} = Astro.props;
---

<div class={cn(avatarGroup({ spacing, limit }), className)} {...rest}>
  <slot />

  {
    showCount && totalCount && totalCount > max && (
      <span class="inline-flex items-center justify-center size-11 rounded-full bg-gray-100 border-2 border-gray-200 dark:bg-neutral-600 dark:border-neutral-700">
        <span class="font-medium text-gray-500 dark:text-neutral-400">
          +{totalCount - max}
        </span>
      </span>
    )
  }
</div>

Use Cases

All Astro sites would benefit from being more able to easily adopt Preline

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant