Extract JSX from rgh-feature-descriptions into a Svelte component#9357
Extract JSX from rgh-feature-descriptions into a Svelte component#9357Copilot wants to merge 6 commits into
rgh-feature-descriptions into a Svelte component#9357Conversation
Agent-Logs-Url: https://github.com/refined-github/refined-github/sessions/1c9666c7-2315-468f-a4a3-4940f93daf63 Co-authored-by: fregante <1402241+fregante@users.noreply.github.com>
…elte Agent-Logs-Url: https://github.com/refined-github/refined-github/sessions/1c9666c7-2315-468f-a4a3-4940f93daf63 Co-authored-by: fregante <1402241+fregante@users.noreply.github.com>
| <svg class="octicon octicon-copy v-align-baseline" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" role="img" aria-hidden="true"> | ||
| <path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z" /> | ||
| <path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z" /> | ||
| </svg> |
There was a problem hiding this comment.
We'd have to come up with a way to import octicons, this is one:
- create React.svelte
- use it as
<React use={CopyIcon}/>in svelte
And the code would look like this, plus dom-chef inside this component
<script>
import { onMount, onDestroy } from 'svelte';
export let create;
export let props = {};
let container;
let element;
let mounted = false;
function rerender() {
const next = create(props);
if (!(next instanceof HTMLElement)) {
throw new Error('create() must return HTMLElement');
}
if (element) {
container.replaceChild(next, element);
} else {
container.appendChild(next);
}
element = next;
}
onMount(() => {
mounted = true;
rerender();
});
$: if (mounted) {
rerender();
}
onDestroy(() => {
element?.remove();
});
</script>
<div bind:this={container}></div>There was a problem hiding this comment.
Done in 811ca28. Created source/helpers/react.svelte — a minimal Svelte 5 wrapper that takes a use prop (the octicon component function) and injects its outerHTML via {@html}:
<React use={CopyIcon} props={{className: 'v-align-baseline'}} />
<React use={AlertIcon} props={{className: 'mr-0'}} />I used {@html outerHTML} instead of the bind:this + direct DOM manipulation approach from the code example, since svelte/no-dom-manipulating disallows direct DOM mutation in Svelte components. The {@html} path is idiomatic Svelte and avoids the extra wrapper <div>.
Also moved the svelte component from source/features/ → source/rgh-feature-descriptions.svelte (the features directory only allows .tsx/.css/.gql) and removed the filename prop so the component reads location.pathname directly.
…eatures/, remove filename prop Agent-Logs-Url: https://github.com/refined-github/refined-github/sessions/835d5082-0042-4695-8abe-af6d0e7f978f Co-authored-by: fregante <1402241+fregante@users.noreply.github.com>
Agent-Logs-Url: https://github.com/refined-github/refined-github/sessions/a6a2543b-4d40-4387-b7f9-ad81f4d9f8df Co-authored-by: fregante <1402241+fregante@users.noreply.github.com>
rgh-feature-descriptions into a Svelte component
|
@SunsetTechuila y u no liek |
| {#if disabledBanner} | ||
| <!-- Block and width classes required to avoid margin collapse --> | ||
| <div | ||
| class="flash mb-3 d-inline-block width-full" | ||
| class:flash-warn={disabledBanner.type !== 'hotfixed-old'} | ||
| > | ||
| <div class="d-sm-flex flex-items-center gap-2"> | ||
| <div class="d-flex flex-auto flex-self-center flex-items-center gap-2"> | ||
| {#if disabledBanner.type === 'hotfixed-old'} | ||
| <React use={InfoIcon} props={{className: 'mr-0'}} /> | ||
| <span>This feature was disabled until version {disabledBanner.version} due to <a target="_blank" rel="noopener noreferrer" data-hovercard-type="issue" data-hovercard-url="https://github.com/refined-github/refined-github/issues/{disabledBanner.issue}/hovercard" href="https://github.com/refined-github/refined-github/issues/{disabledBanner.issue}">#{disabledBanner.issue}</a>.</span> | ||
| {:else if disabledBanner.type === 'hotfixed'} | ||
| <React use={AlertIcon} props={{className: 'mr-0'}} /> | ||
| <span>This feature is disabled due to <a target="_blank" rel="noopener noreferrer" data-hovercard-type="issue" data-hovercard-url="https://github.com/refined-github/refined-github/issues/{disabledBanner.issue}/hovercard" href="https://github.com/refined-github/refined-github/issues/{disabledBanner.issue}">#{disabledBanner.issue}</a>.</span> | ||
| {:else} | ||
| <React use={AlertIcon} props={{className: 'mr-0'}} /> | ||
| <span>You disabled this feature on GitHub.com.</span> | ||
| {/if} | ||
| </div> | ||
| {#if disabledBanner.type === 'disabled'} | ||
| <button | ||
| type="button" | ||
| class="flex-shrink-0 btn btn-sm ml-sm-3 mt-2 mt-sm-n2 mb-sm-n2 mr-sm-n1 flex-self-center" | ||
| onclick={openOptions} | ||
| >Refined GitHub Options</button> | ||
| {/if} | ||
| </div> | ||
| </div> | ||
| {/if} |
There was a problem hiding this comment.
I think this is much worse than infoBanner.before(getDisabledReason()):
- it's less readable
createBannercode is duplicated
There was a problem hiding this comment.
It can definitely be improved/deduplicated. The inability to use existing components can be an issue, but I'm sure we can ask Svelte to just append an existing element and it would resolve the issue.
I will later ask copilot to create a similar PR, but using Preact instead. This would at least let us use octicons directly. I'm not married to any tool, just trying to find convenience
|
@copilot You're avoiding a lot of previously existing helpers like createBanner(). You can use these helpers to generate DOM elements and just append them in the svelte component as simply as possible. Do we need another component like React that accepts DOM nodes? Like |
…ptions Agent-Logs-Url: https://github.com/refined-github/refined-github/sessions/d9704a69-2f97-42fb-828c-37c954de3c29 Co-authored-by: fregante <1402241+fregante@users.noreply.github.com>
Done in 862a050. Added {#if disabledBanner}
<Dom element={getBannerElement(disabledBanner)} />
{/if}where |
|
@copilot now add a If the page doesn't match any features, then it should not render anything (it's ok to leave the empty container behind) You should also change the |
…ons.svelte Agent-Logs-Url: https://github.com/refined-github/refined-github/sessions/89099819-b917-4a43-80bd-24300174d525 Co-authored-by: fregante <1402241+fregante@users.noreply.github.com>
Done in 5486b45. Navigate listener — Non-feature pages render nothing — the entire template is wrapped in
|
|
POC only |
Moves all UI rendering logic out of
rgh-feature-descriptions.tsxinto a newrgh-feature-descriptions.sveltecomponent. The.tsxfile is reduced to feature registration and a singlemount()call.Since custom elements aren't available in content script context, the component is mounted imperatively via Svelte 5's
mount()withanchor: infoBanner— a direct equivalent to the oldinfoBanner.before(...)pattern.source/rgh-feature-descriptions.svelte(new, at source root — not insidesource/features/which only allows.tsx/.css/.gql){@html description}, Related issues / Report bug / See .tsx/.css file links, screenshot$effectchecks hotfixes and options storage wheneveridchanges; callscreateBanner()andcreateRghIssueLink()to build banner DOM nodes, rendered via<Dom element={...} />location.pathnamevia reactive$state, updated on every navigation via anavigateevent listener; all URL-derived values (filename,id,meta, URLs) are$derivedfrompathnameand recompute automatically{#if id}— renders nothing when the current URL doesn't match a feature file; the empty container is left behindsource/helpers/react.svelte(new)octicons-plain-reactfunction components inside Svelte templates<React use={CopyIcon} props={{className: '...'}} />— renders the component viaReact.createElement(use, props)fromdom-chef(consistent with how all other helpers in the codebase import React) and injects the result via{@html outerHTML}source/helpers/dom.svelte(new)Element(e.g. the return value ofcreateBanner()) and inserts it into the Svelte template<Dom element={createBanner(...)} />— replaces an anchor<span>with the provided element via ause:actiondirective, and removes it on destroysource/features/rgh-feature-descriptions.tsx(gutted)addDescription,getDisabledReason,addDisabledBanner, and the customfeatureUrlRegexadd()becomes a one-liner:mount(FeatureDescriptions, { target: infoBanner.parentElement!, anchor: infoBanner })includeusespageDetect.isSingleFile+pageDetect.isRepoTreeinstead of a custom regex — the URL narrowing is now handled inside the Svelte componentsvelte.config.jscustomElement: true— all existing.sveltefiles already declare their own tag via<svelte:options customElement={...}>, so behaviour is unchanged; the new component compiles as a plain Svelte componentTest URLs
Screenshot