
3D Extruded Buildings & Urban Footprints
Real-world 3D building extrusions with dynamic sunlight shadows, terrain DEM elevations, and pitch/bearing camera controls.
spinneruiLightweight loading indicator — circular spinner with three sizes and tone variants. Use inside buttons (replacing the icon when an action is in flight) or as a centered page loader.
Also available for React ->$pnpm dlx shadcn-vue@latest add https://uipkge.dev/r/vue/spinner.json$npx shadcn-vue@latest add https://uipkge.dev/r/vue/spinner.json$yarn dlx shadcn-vue@latest add https://uipkge.dev/r/vue/spinner.json$bunx shadcn-vue@latest add https://uipkge.dev/r/vue/spinner.jsonnpx shadcn-vue@latest add @uipkge/spinnerInstalls to:app/components/ui/spinner/| Name | Type / Values | Default | Required |
|---|---|---|---|
class | HTMLAttributes['class'] | — | optional |
size | 'default''sm''lg''icon' | — | optional |
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { Loader2 } from 'lucide-vue-next'
import { cn } from '@/lib/utils'
import { spinnerVariants } from './spinner.variants'
// Inlined union: SFC compiler can't extract runtime props from
// `SpinnerVariants['size']`.
const props = defineProps<{
class?: HTMLAttributes['class']
size?: 'default' | 'sm' | 'lg' | 'icon'
}>()
</script>
<template>
<Loader2
data-uipkge
data-slot="spinner"
:class="cn(spinnerVariants({ size: size ?? 'default' }), props.class)"
aria-label="Loading"
role="status"
/>
</template>
import type { VariantProps } from 'class-variance-authority'
import { cva } from 'class-variance-authority'
/**
* Variant definitions live in their own file (rather than the package
* `index.ts`) so consuming Vue SFCs can import without creating a circular
* dependency through the index. See card.variants.ts for the canonical
* example + the SSR symptom that motivated the split.
*/
// motion-safe: honor prefers-reduced-motion (static glyph when reduced).
export const spinnerVariants = cva('motion-safe:animate-spin text-muted-foreground', {
variants: {
size: {
default: 'size-6',
sm: 'size-4',
lg: 'size-8',
icon: 'size-4',
},
},
defaultVariants: {
size: 'default',
},
})
export type SpinnerVariants = VariantProps<typeof spinnerVariants>
export { default as Spinner } from './Spinner.vue'
// Re-export variant API from the sibling file (kept separate to avoid the
// Component.vue <-> index.ts circular import that broke dev SSR for Card).
export { spinnerVariants, type SpinnerVariants } from './spinner.variants'
Raw manifest:https://uipkge.dev/r/vue/spinner.json