This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

web/components: add ColorBall component

the appview draws those little shiny dots for languages and labels from
one template. the web app had no such thing, so BlobHeader kept its own
copy of the gradient and LanguageBar drew a flat circle instead. now
there is one component for it, in three sizes, and both use it.

Signed-off-by: eti <eti@eti.tf>

+67 -10
+3 -6
web/src/lib/components/repo/BlobHeader.svelte
··· 7 7 import Button from "$lib/components/ui/Button.svelte"; 8 8 import ButtonGroup from "$lib/components/ui/ButtonGroup.svelte"; 9 9 import Checkbox from "$lib/components/ui/Checkbox.svelte"; 10 + import ColorBall from "$lib/components/ui/ColorBall.svelte"; 10 11 import { LANGUAGE_COLORS, LANGUAGE_COLOR_FALLBACK } from "./language-colors"; 11 12 import RefChip from "./RefChip.svelte"; 12 13 import RepoCrumbs from "./RepoCrumbs.svelte"; ··· 58 59 }; 59 60 </script> 60 61 61 - <div class="flex flex-wrap items-center justify-between gap-2 typography-paragraph-regular mb-2"> 62 + <div class="mb-2 flex flex-wrap items-center justify-between gap-2 typography-paragraph-regular"> 62 63 <div class="flex min-w-0 items-center gap-3"> 63 64 <RepoCrumbs {ownerHandle} {repoName} {ref} {path} /> 64 65 ··· 84 85 <div 85 86 class="flex w-fit items-center gap-2 rounded border border-border-default bg-background-canvas px-2 py-1 whitespace-nowrap" 86 87 > 87 - <div 88 - class="size-2 rounded-full" 89 - style:background="radial-gradient(circle at 35% 35%, color-mix(in srgb, {languageColor} 70%, 90 - white), {languageColor} 30%, color-mix(in srgb, {languageColor} 85%, black))" 91 - ></div> 88 + <ColorBall color={languageColor} /> 92 89 {language} 93 90 </div> 94 91 {/if}
+2 -4
web/src/lib/components/repo/LanguageBar.svelte
··· 1 1 <script lang="ts"> 2 + import ColorBall from "$lib/components/ui/ColorBall.svelte"; 2 3 import { LANGUAGE_COLORS, LANGUAGE_COLOR_FALLBACK } from "./language-colors"; 3 4 import type { LanguageSlice } from "./types"; 4 5 ··· 30 31 > 31 32 {#each languages as language (language.name)} 32 33 <div class="flex items-center gap-2 typography-paragraph-small"> 33 - <span 34 - class="inline-block size-2.5 shrink-0 rounded-full" 35 - style={`background-color: ${colorFor(language.name)}`} 36 - ></span> 34 + <ColorBall color={colorFor(language.name)} class="size-2.5" /> 37 35 <span> 38 36 {language.name} 39 37 <span class="text-foreground-subtle">{percent(language)}%</span>
+25
web/src/lib/components/ui/ColorBall.stories.svelte
··· 1 + <script module lang="ts"> 2 + import { defineMeta } from "@storybook/addon-svelte-csf"; 3 + import ColorBall from "./ColorBall.svelte"; 4 + 5 + const { Story } = defineMeta({ 6 + title: "UI/ColorBall", 7 + component: ColorBall, 8 + tags: ["autodocs"], 9 + argTypes: { 10 + size: { 11 + control: { type: "inline-radio" }, 12 + options: ["sm", "md", "lg"] 13 + } 14 + }, 15 + args: { 16 + color: "#3178c6", 17 + size: "sm" 18 + } 19 + }); 20 + </script> 21 + 22 + <Story name="Default" /> 23 + <Story name="Medium" args={{ size: "md" }} /> 24 + <Story name="Large" args={{ size: "lg" }} /> 25 + <Story name="Rust" args={{ color: "#dea584", size: "lg" }} />
+37
web/src/lib/components/ui/ColorBall.svelte
··· 1 + <script module lang="ts"> 2 + import { tv, type VariantProps } from "tailwind-variants"; 3 + 4 + export const colorBall = tv({ 5 + base: "shrink-0 rounded-full", 6 + variants: { 7 + size: { 8 + sm: "size-2", 9 + md: "size-4", 10 + lg: "size-8" 11 + } 12 + }, 13 + defaultVariants: { 14 + size: "sm" 15 + } 16 + }); 17 + 18 + export type ColorBallVariants = VariantProps<typeof colorBall>; 19 + </script> 20 + 21 + <script lang="ts"> 22 + interface Props { 23 + /** any CSS colour, e.g. a language colour or a label's hex */ 24 + color: string; 25 + size?: ColorBallVariants["size"]; 26 + class?: string; 27 + } 28 + 29 + let { color, size = "sm", class: className }: Props = $props(); 30 + 31 + const classes = $derived(colorBall({ size, class: className })); 32 + const sphere = $derived( 33 + `radial-gradient(circle at 35% 35%, color-mix(in srgb, ${color} 70%, white), ${color} 30%, color-mix(in srgb, ${color} 85%, black))` 34 + ); 35 + </script> 36 + 37 + <div class={classes} style:background={sphere}></div>