Skip to content

Commit aac6256

Browse files
committed
fix: tab buttons type=button, render both tabs with CSS hidden to fix hydration
1 parent 22f9df2 commit aac6256

1 file changed

Lines changed: 30 additions & 35 deletions

File tree

src/routes/bot/profile/+page.svelte

Lines changed: 30 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -128,56 +128,50 @@
128128
<p class="hint">Customize syndicated posts per network. Bluesky fields fall back to ActivityPub values if left empty.</p>
129129

130130
<div class="template-tabs">
131-
<button class:active={previewTab === 'ap'} onclick={() => previewTab = 'ap'}>
131+
<button type="button" class:active={previewTab === 'ap'} onclick={() => previewTab = 'ap'}>
132132
<span class="tab-icon">🐘</span> ActivityPub
133133
</button>
134-
<button class:active={previewTab === 'bsky'} onclick={() => previewTab = 'bsky'}>
134+
<button type="button" class:active={previewTab === 'bsky'} onclick={() => previewTab = 'bsky'}>
135135
<span class="tab-icon">🦋</span> Bluesky
136136
</button>
137137
</div>
138138

139-
{#if previewTab === 'ap'}
140-
<div class="template-fields">
141-
<div class="field">
142-
<label for="postPrefix">Prefix</label>
143-
<input type="text" id="postPrefix" name="postPrefix" bind:value={apPrefixInput} placeholder="e.g. 📝 Edit detected:" />
144-
</div>
145-
<div class="field">
146-
<label for="postSuffix">Suffix</label>
147-
<input type="text" id="postSuffix" name="postSuffix" bind:value={apSuffixInput} placeholder="e.g. #newsdiff #transparency" />
148-
</div>
149-
<div class="budget" class:budget-warn={apBudget < 50} class:budget-over={apBudget < 0}>
150-
{apPreview.length}/500 chars
151-
</div>
139+
<div class="template-fields" class:hidden={previewTab !== 'ap'}>
140+
<div class="field">
141+
<label for="postPrefix">Prefix</label>
142+
<input type="text" id="postPrefix" name="postPrefix" bind:value={apPrefixInput} placeholder="e.g. 📝 Edit detected:" />
152143
</div>
153-
{:else}
154-
<div class="template-fields">
155-
<div class="field">
156-
<label for="bskyPostPrefix">Prefix</label>
157-
<input type="text" id="bskyPostPrefix" name="bskyPostPrefix" bind:value={bskyPrefixInput} placeholder={apPrefixInput || 'Same as ActivityPub'} />
158-
</div>
159-
<div class="field">
160-
<label for="bskyPostSuffix">Suffix</label>
161-
<input type="text" id="bskyPostSuffix" name="bskyPostSuffix" bind:value={bskySuffixInput} placeholder={apSuffixInput || 'Same as ActivityPub'} />
162-
</div>
163-
<div class="budget" class:budget-warn={bskyBudget < 30} class:budget-over={bskyBudget < 0}>
164-
{bskyPreview.length}/300 chars
165-
{#if bskyBudget < 0} — title will be truncated{/if}
166-
</div>
144+
<div class="field">
145+
<label for="postSuffix">Suffix</label>
146+
<input type="text" id="postSuffix" name="postSuffix" bind:value={apSuffixInput} placeholder="e.g. #newsdiff #transparency" />
167147
</div>
168-
{/if}
148+
<div class="budget" class:budget-warn={apBudget < 50} class:budget-over={apBudget < 0}>
149+
{apPreview.length}/500 chars
150+
</div>
151+
</div>
152+
<div class="template-fields" class:hidden={previewTab !== 'bsky'}>
153+
<div class="field">
154+
<label for="bskyPostPrefix">Prefix</label>
155+
<input type="text" id="bskyPostPrefix" name="bskyPostPrefix" bind:value={bskyPrefixInput} placeholder={apPrefixInput || 'Same as ActivityPub'} />
156+
</div>
157+
<div class="field">
158+
<label for="bskyPostSuffix">Suffix</label>
159+
<input type="text" id="bskyPostSuffix" name="bskyPostSuffix" bind:value={bskySuffixInput} placeholder={apSuffixInput || 'Same as ActivityPub'} />
160+
</div>
161+
<div class="budget" class:budget-warn={bskyBudget < 30} class:budget-over={bskyBudget < 0}>
162+
{bskyPreview.length}/300 chars
163+
{#if bskyBudget < 0} — title will be truncated{/if}
164+
</div>
165+
</div>
169166

170167
{#if preview}
171168
<div class="preview-card" class:preview-mastodon={previewTab === 'ap'} class:preview-bluesky={previewTab === 'bsky'}>
172169
<div class="preview-header">
173170
<span class="preview-icon">{previewTab === 'ap' ? '🐘' : '🦋'}</span>
174171
<span class="preview-label">{previewTab === 'ap' ? 'ActivityPub' : 'Bluesky'} preview</span>
175172
</div>
176-
{#if previewTab === 'ap'}
177-
<div class="preview-body">{apPreview}</div>
178-
{:else}
179-
<div class="preview-body" class:preview-truncated={bskyPreview.length > 300}>{bskyPreview.slice(0, 300)}{#if bskyPreview.length > 300}...{/if}</div>
180-
{/if}
173+
<div class="preview-body" class:hidden={previewTab !== 'ap'}>{apPreview}</div>
174+
<div class="preview-body" class:hidden={previewTab !== 'bsky'} class:preview-truncated={bskyPreview.length > 300}>{bskyPreview.slice(0, 300)}{#if bskyPreview.length > 300}...{/if}</div>
181175
</div>
182176
{/if}
183177
</section>
@@ -255,6 +249,7 @@
255249
.template-tabs button.active { color: var(--color-text); border-bottom-color: var(--color-primary); font-weight: 600; }
256250
.template-tabs button:hover { color: var(--color-text); }
257251
.template-fields { margin-bottom: 0.75rem; }
252+
.hidden { display: none; }
258253
259254
.preview-card { border: 1px solid var(--color-border); border-radius: 0.5rem; overflow: hidden; background: white; margin-top: 1rem; }
260255
.preview-header { display: flex; align-items: center; gap: 0.4rem; padding: 0.5rem 0.75rem; background: #f8f8f8; border-bottom: 1px solid var(--color-border); font-size: 0.8rem; font-weight: 600; color: var(--color-muted); }

0 commit comments

Comments
 (0)