Files
radicle-explorer/src/components/EditableTitle.svelte
T
Rūdolfs Ošiņš 010cac0377 Redesign app with new UI kit
Redesign the entire app with a new UI kit. Typography, colors, icons,
avatars, and border radii have all been updated for a more polished,
consistent appearance that matches our other products like
radicle-explorer.

- Replace blockies-based avatars with a new DID-based avatar system
- Move Settings and Create Issue into fullscreen modals
- Change the default theme to follow the system theme
- Remove window decorations on macOS for a cleaner, more native feel
- Update the app icon
- Fix popovers and tooltips

Navigation:

- Rewrite app navigation and layouts
- Add a sidebar that gives you access to all your repos
- Change the startup screen to open directly to the notification inbox
- Add a getting started guide shown to new users on first launch

Settings:

- Add a setting to disable the notification badge
- Add a code font setting

Bug fixes:

- Fix reactions and edits incorrectly targeting the root comment
  instead of the intended reply
- Restrict issue/patch state, labels and assignees to delegates only
2026-03-20 17:48:38 -06:00

108 lines
2.5 KiB
Svelte

<script lang="ts">
import Button from "@app/components/Button.svelte";
import Icon from "@app/components/Icon.svelte";
import InlineTitle from "@app/components/InlineTitle.svelte";
import TextInput from "@app/components/TextInput.svelte";
interface Props {
allowedToEdit: true | undefined;
cobId: string;
title: string;
updateTitle: (newTitle: string) => Promise<void>;
}
const { allowedToEdit, cobId, title, updateTitle }: Props = $props();
let editingTitle = $state(false);
let newTitle = $state("");
$effect(() => {
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
cobId;
editingTitle = false;
newTitle = title;
});
async function save() {
if (newTitle.trim().length <= 0) {
return;
}
if (title === newTitle) {
editingTitle = false;
return;
}
await updateTitle(newTitle);
}
</script>
<style>
.title {
font: var(--txt-heading-m);
-webkit-user-select: text;
user-select: text;
display: flex;
align-items: center;
word-break: break-word;
min-height: 2rem;
width: 100%;
}
.edit-title-icon {
display: none;
}
.title-wrapper:hover .edit-title-icon {
display: flex;
}
</style>
<div class="title">
{#if editingTitle}
<TextInput
valid={newTitle.trim().length > 0}
bind:value={newTitle}
autofocus
onSubmit={save}
onDismiss={() => {
newTitle = title;
editingTitle = false;
}} />
<div class="global-flex" style:margin-left="0.5rem">
<Button
variant="naked"
disabled={!(newTitle.trim().length > 0)}
onclick={save}>
<Icon name="checkmark" />
</Button>
<Button
variant="naked"
onclick={() => {
newTitle = title;
editingTitle = false;
}}>
<Icon name="close" />
</Button>
</div>
{:else}
<div class="global-flex" style:gap="0">
<!-- svelte-ignore a11y_click_events_have_key_events -->
<div
class="title-wrapper global-flex"
role="button"
style:cursor={allowedToEdit ? "pointer" : "default"}
onclick={() => {
if (allowedToEdit) {
editingTitle = true;
}
}}
tabindex="0">
<InlineTitle content={title} fontSize="medium" />
{#if allowedToEdit}
<div class="edit-title-icon"><Icon name="edit" /></div>
{/if}
</div>
</div>
{/if}
</div>