forked from tangled.org/core
Monorepo for Tangled

appview: add spinners to all buttons

how it works:

- hx-indicator adds the htmx-request class to the target of choice
- with tailwind, we can use `group-[.class]` to check if a parent
element has a certain class, and style things conditionally
- by applying `group-[.htmx-request]`, we can detect when a request is
in progress, and show/hide a lucide loader
- the loader is a static icon made to spin using the `animate-spin`
class

Changed files
+60 -31
appview
pages
templates
+1
appview/pages/templates/layouts/base.html
··· 7 7 name="viewport" 8 8 content="width=device-width, initial-scale=1.0" 9 9 /> 10 + <meta name="htmx-config" content='{"includeIndicatorStyles": false}'> 10 11 <script src="/static/htmx.min.js"></script> 11 12 <link rel="stylesheet" href="/static/tw.css?{{ cssContentHash }}" type="text/css" /> 12 13 <title>{{ block "title" . }}{{ end }} · tangled</title>
+13 -12
appview/pages/templates/repo/fragments/repoActions.html
··· 2 2 <div class="flex items-center gap-2 z-auto"> 3 3 <button 4 4 id="starBtn" 5 - class="btn disabled:opacity-50 disabled:cursor-not-allowed" 5 + class="btn disabled:opacity-50 disabled:cursor-not-allowed flex gap-2 items-center group" 6 6 {{ if .IsStarred }} 7 7 hx-delete="/star?subject={{ .RepoAt }}&countHint={{ .Stats.StarCount }}" 8 8 {{ else }} ··· 14 14 hx-swap="outerHTML" 15 15 hx-disabled-elt="#starBtn" 16 16 > 17 - <div class="flex gap-2 items-center"> 18 - {{ if .IsStarred }} 19 - {{ i "star" "w-4 h-4 fill-current" }} 20 - {{ else }} 21 - {{ i "star" "w-4 h-4" }} 22 - {{ end }} 23 - <span class="text-sm"> 24 - {{ .Stats.StarCount }} 25 - </span> 26 - </div> 17 + {{ if .IsStarred }} 18 + {{ i "star" "w-4 h-4 fill-current" }} 19 + {{ else }} 20 + {{ i "star" "w-4 h-4" }} 21 + {{ end }} 22 + <span class="text-sm"> 23 + {{ .Stats.StarCount }} 24 + </span> 25 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 27 26 </button> 28 27 {{ if .DisableFork }} 29 28 <button ··· 36 35 </button> 37 36 {{ else }} 38 37 <a 39 - class="btn text-sm no-underline hover:no-underline flex items-center gap-2" 38 + class="btn text-sm no-underline hover:no-underline flex items-center gap-2 group" 39 + hx-boost="true" 40 40 href="/{{ .FullName }}/fork" 41 41 > 42 42 {{ i "git-fork" "w-4 h-4" }} 43 43 fork 44 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 44 45 </a> 45 46 {{ end }} 46 47 </div>
+7 -2
appview/pages/templates/repo/new.html
··· 5 5 <p class="text-xl font-bold dark:text-white">Create a new repository</p> 6 6 </div> 7 7 <div class="p-6 bg-white dark:bg-gray-800 drop-shadow-sm rounded"> 8 - <form hx-post="/repo/new" class="space-y-12" hx-swap="none"> 8 + <form hx-post="/repo/new" class="space-y-12" hx-swap="none" hx-indicator="#spinner"> 9 9 <div class="space-y-2"> 10 10 <label for="name" class="-mb-1 dark:text-white">Repository name</label> 11 11 <input ··· 60 60 </fieldset> 61 61 62 62 <div class="space-y-2"> 63 - <button type="submit" class="btn">create repo</button> 63 + <button type="submit" class="btn flex gap-2 items-center"> 64 + create repo 65 + <span id="spinner" class="group"> 66 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 67 + </span> 68 + </button> 64 69 <div id="repo" class="error"></div> 65 70 </div> 66 71 </form>
+14 -9
appview/pages/templates/repo/pulls/fragments/pullActions.html
··· 17 17 hx-get="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/round/{{ $roundNumber }}/comment" 18 18 hx-target="#actions-{{$roundNumber}}" 19 19 hx-swap="outerHtml" 20 - class="btn p-2 flex items-center gap-2 no-underline hover:no-underline"> 20 + class="btn p-2 flex items-center gap-2 no-underline hover:no-underline group"> 21 21 {{ i "message-square-plus" "w-4 h-4" }} 22 22 <span>comment</span> 23 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 23 24 </button> 24 25 {{ if and $isPushAllowed $isOpen $isLastRound }} 25 26 {{ $disabled := "" }} ··· 30 31 hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/merge" 31 32 hx-swap="none" 32 33 hx-confirm="Are you sure you want to merge pull #{{ .Pull.PullId }} into the `{{ .Pull.TargetBranch }}` branch?" 33 - class="btn p-2 flex items-center gap-2" {{ $disabled }}> 34 + class="btn p-2 flex items-center gap-2 group" {{ $disabled }}> 34 35 {{ i "git-merge" "w-4 h-4" }} 35 - <span>merge</span> 36 + <span>merge</span> 37 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 36 38 </button> 37 39 {{ end }} 38 40 ··· 51 53 {{ end }} 52 54 53 55 hx-disabled-elt="#resubmitBtn" 54 - class="btn p-2 flex items-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed" {{ $disabled }} 56 + class="btn p-2 flex items-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed group" {{ $disabled }} 55 57 56 58 {{ if $disabled }} 57 59 title="Update this branch to resubmit this pull request" ··· 59 61 title="Resubmit this pull request" 60 62 {{ end }} 61 63 > 62 - {{ i "rotate-ccw" "w-4 h-4" }} 64 + {{ i "rotate-ccw" "w-4 h-4" }} 63 65 <span>resubmit</span> 66 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 64 67 </button> 65 68 {{ end }} 66 69 ··· 68 71 <button 69 72 hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/close" 70 73 hx-swap="none" 71 - class="btn p-2 flex items-center gap-2"> 72 - {{ i "ban" "w-4 h-4" }} 74 + class="btn p-2 flex items-center gap-2 group"> 75 + {{ i "ban" "w-4 h-4" }} 73 76 <span>close</span> 77 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 74 78 </button> 75 79 {{ end }} 76 80 ··· 78 82 <button 79 83 hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/reopen" 80 84 hx-swap="none" 81 - class="btn p-2 flex items-center gap-2"> 82 - {{ i "refresh-ccw-dot" "w-4 h-4" }} 85 + class="btn p-2 flex items-center gap-2 group"> 86 + {{ i "refresh-ccw-dot" "w-4 h-4" }} 83 87 <span>reopen</span> 88 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 84 89 </button> 85 90 {{ end }} 86 91 </div>
+8 -4
appview/pages/templates/repo/pulls/pull.html
··· 51 51 </span> 52 52 </div> 53 53 54 - <a class="btn flex items-center gap-2 no-underline hover:no-underline p-2" 54 + <a class="btn flex items-center gap-2 no-underline hover:no-underline p-2 group" 55 55 hx-boost="true" 56 56 href="/{{ $.RepoInfo.FullName }}/pulls/{{ $.Pull.PullId }}/round/{{.RoundNumber}}"> 57 - {{ i "file-diff" "w-4 h-4" }} <span class="hidden md:inline">diff</span> 57 + {{ i "file-diff" "w-4 h-4" }} 58 + <span class="hidden md:inline">diff</span> 59 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 58 60 </a> 59 61 {{ if not (eq .RoundNumber 0) }} 60 - <a class="btn flex items-center gap-2 no-underline hover:no-underline p-2" 62 + <a class="btn flex items-center gap-2 no-underline hover:no-underline p-2 group" 61 63 hx-boost="true" 62 64 href="/{{ $.RepoInfo.FullName }}/pulls/{{ $.Pull.PullId }}/round/{{.RoundNumber}}/interdiff"> 63 - {{ i "chevrons-left-right-ellipsis" "w-4 h-4 rotate-90" }} <span class="hidden md:inline">interdiff</span> 65 + {{ i "chevrons-left-right-ellipsis" "w-4 h-4 rotate-90" }} 66 + <span class="hidden md:inline">interdiff</span> 67 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 64 68 </a> 65 69 <span id="interdiff-error-{{.RoundNumber}}"></span> 66 70 {{ end }}
+5 -1
appview/pages/templates/user/fragments/editBio.html
··· 3 3 hx-post="/profile/bio" 4 4 class="flex flex-col gap-4 my-2 max-w-full" 5 5 hx-disabled-elt="#save-btn,#cancel-btn" 6 - hx-swap="none"> 6 + hx-swap="none" 7 + hx-indicator="#spinner"> 7 8 <div class="flex flex-col gap-1"> 8 9 {{ $description := "" }} 9 10 {{ if and .Profile .Profile.Description }} ··· 75 76 <div class="flex items-center gap-2 justify-between"> 76 77 <button id="save-btn" type="submit" class="btn p-1 w-full flex items-center gap-2 no-underline text-sm"> 77 78 {{ i "check" "size-4" }} save 79 + <span id="spinner" class="group"> 80 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 81 + </span> 78 82 </button> 79 83 <a href="/{{.LoggedInUser.Did}}" class="w-full no-underline hover:no-underline"> 80 84 <button id="cancel-btn" type="button" class="btn p-1 w-full flex items-center gap-2 no-underline text-sm">
+5 -1
appview/pages/templates/user/fragments/editPins.html
··· 3 3 <form 4 4 hx-post="/profile/pins" 5 5 hx-disabled-elt="#save-btn,#cancel-btn" 6 - hx-swap="none"> 6 + hx-swap="none" 7 + hx-indicator="#spinner"> 7 8 <div class="flex items-center justify-between mb-2"> 8 9 <p class="text-sm font-bold p-2 dark:text-white">SELECT PINNED REPOS</p> 9 10 <div class="flex items-center gap-2"> 10 11 <button id="save-btn" type="submit" class="btn px-2 flex items-center gap-2 no-underline text-sm"> 11 12 {{ i "check" "w-3 h-3" }} save 13 + <span id="spinner" class="group"> 14 + {{ i "loader-circle" "w-3 h-3 animate-spin hidden group-[.htmx-request]:inline" }} 15 + </span> 12 16 </button> 13 17 <a href="/{{.LoggedInUser.Did}}" class="w-full no-underline hover:no-underline"> 14 18 <button id="cancel-btn" type="button" class="btn px-2 w-full flex items-center gap-2 no-underline text-sm">
+2 -1
appview/pages/templates/user/fragments/profileCard.html
··· 68 68 {{ template "user/fragments/follow" . }} 69 69 {{ else }} 70 70 <button id="editBtn" 71 - class="btn mt-2 w-full flex items-center gap-2" 71 + class="btn mt-2 w-full flex items-center gap-2 group" 72 72 hx-target="#profile-bio" 73 73 hx-get="/profile/edit-bio" 74 74 hx-swap="innerHTML"> 75 75 {{ i "pencil" "w-4 h-4" }} 76 76 edit 77 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 77 78 </button> 78 79 {{ end }} 79 80 </div>
+5 -1
appview/pages/templates/user/profile.html
··· 235 235 </span> 236 236 </a> 237 237 {{ if and .LoggedInUser (eq .LoggedInUser.Did .Card.UserDid) }} 238 - <button hx-get="profile/edit-pins" hx-target="#all-repos" class="btn font-normal text-sm flex gap-2 items-center"> 238 + <button 239 + hx-get="profile/edit-pins" 240 + hx-target="#all-repos" 241 + class="btn font-normal text-sm flex gap-2 items-center group"> 239 242 {{ i "pencil" "w-3 h-3" }} 240 243 edit 244 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 241 245 </button> 242 246 {{ end }} 243 247 </div>