lars
lars
Explore posts from servers
SSolidJS
Created by lars on 2/4/2024 in #support
Better stacktraces when using SolidJS via a library?
No description
6 replies
SSolidJS
Created by lars on 1/7/2024 in #support
SolidJS UI library + Astro
Hey, would anyone happen to have experience using a UI library together with Astro? I can get it working if I just export some simple components, but if I then add an import to another SolidJS library (eg. @kobalte/core or @ark-ui/solid to help build my primitives), then I run into:
The requested module 'solid-js/web' does not provide an export named 'effect'
The requested module 'solid-js/web' does not provide an export named 'effect'
At first I was using tsup with tsup-preset-solid, but at this point I’ve tried almost everything I can think of: rollup, vite, esbuild, or just plain tsc. On the other hand, tried a bunch of different Astro configs, but no matter what I do I can’t get past this error. Are there any example projects with such a setup somewhere?
30 replies
CC#
Created by lars on 8/13/2023 in #help
❔ Output to console if run from console - otherwise do not create console window?
I've got an Windows app that doesn't have a UI. I'd like to not have a console window opened when it's launched fron File Explorer, but if the user launches the app from a terminal (eg. ./myapp.exe), then I'd want Console.WriteLine calls (for debugging) to go to that terminal window. Is there some way to achieve this? If I set the OutputType to Exe, then it spawns a console window when launched from File Explorer. However, when run from a terminal window, the behavior is correct - Console.WriteLine output goes to that existing terminal window. If I set the OutputType to WinExe, the behavior is correct when launched from File Explorer - no console window is spawned. However, when run from a terminal window, Console.WriteLine calls don't appear at all
13 replies
SSolidJS
Created by lars on 7/4/2023 in #support
Manually mounting SolidJS component within HTML component via `render`
I'm on an adventure of doing some truly weird shit. I'm parsing YAML and dynamically creating HTML and inserting SolidJS components based on the template properties below:
group/main:
template: |
<div class="main">
{{ widgets }}
</div>
widgets:
- type: 'clock'
template: |
<div class="clock">
{{ hours }}:{{ minutes }}
</div>
group/main:
template: |
<div class="main">
{{ widgets }}
</div>
widgets:
- type: 'clock'
template: |
<div class="clock">
{{ hours }}:{{ minutes }}
</div>
(The user is the one who writes the YAML and runs the app, so it doesn't matter if it's insecure and dangerous) How I'm getting this to work currently:
export function ClockWidget(props) {
const [date, setDate] = createSignal(new Date());

const minutes = createMemo(() => date().getMinutes());
const hours = createMemo(() => date().getHours());
const interval = setInterval(() => setDate(new Date()), 1000);

// Create an `HTMLElement` from `props.template`.
const element = getParsedTemplate();

createEffect(
on(
() => [hours(), minutes()],
// When the hours/minutes change, re-parse the template and mutate
// the original HTMLElement in-place to match the new template. Maybe there's
// some better way to do this?
() => diffAndMutate(element, getParsedTemplate()),
),
);

function getParsedTemplate() {
return parseTemplate(props.template, { // props.template is a string `<div class="clock">{{ hours }} ...`
bindings: {
strings: {
hours: hours(),
minutes: minutes(),
},
},
});
}

return element; // This does not return JSX; it returns a regular `HTMLElement`.
}

export function Group(props) {
// Create an `HTMLElement` from `props.template`.
return parseTemplate(props.template, {
bindings: {
components: {
// Hardcode clock widget to be the only widget for this example.
widgets: () => (
<ClockWidget template={props.widgets[0].template} />
),
},
},
});
}
export function ClockWidget(props) {
const [date, setDate] = createSignal(new Date());

const minutes = createMemo(() => date().getMinutes());
const hours = createMemo(() => date().getHours());
const interval = setInterval(() => setDate(new Date()), 1000);

// Create an `HTMLElement` from `props.template`.
const element = getParsedTemplate();

createEffect(
on(
() => [hours(), minutes()],
// When the hours/minutes change, re-parse the template and mutate
// the original HTMLElement in-place to match the new template. Maybe there's
// some better way to do this?
() => diffAndMutate(element, getParsedTemplate()),
),
);

function getParsedTemplate() {
return parseTemplate(props.template, { // props.template is a string `<div class="clock">{{ hours }} ...`
bindings: {
strings: {
hours: hours(),
minutes: minutes(),
},
},
});
}

return element; // This does not return JSX; it returns a regular `HTMLElement`.
}

export function Group(props) {
// Create an `HTMLElement` from `props.template`.
return parseTemplate(props.template, {
bindings: {
components: {
// Hardcode clock widget to be the only widget for this example.
widgets: () => (
<ClockWidget template={props.widgets[0].template} />
),
},
},
});
}
3 replies
SSolidJS
Created by lars on 6/28/2023 in #support
Losing reactivity in props passed to `children` callback
I've got a component Field that passes a memo to props.children. I'm running into an issue where the child component is not updating on changes to the memo
export function Field(props: { form: Form; children: JSXElement }) { // `Form` is a SolidJS store
const fieldState = createMemo(() => {
return {
value: store.value,
isDisabled: store.isDisabled,
isRequired: store.isRequired,
hasError: store.hasError,
};
});

createEffect(() => console.log('Changed', fieldState()); // Is logging successfully on changes

return props.children(fieldState());
}

// ---------------------------
<Field form={myForm}>
{(fieldState) => (
<>
<p>{JSON.stringify(fieldState)}</p> // !! Not updating on changes
<CustomInput {...fieldState} />
</>
)}
</Field>
export function Field(props: { form: Form; children: JSXElement }) { // `Form` is a SolidJS store
const fieldState = createMemo(() => {
return {
value: store.value,
isDisabled: store.isDisabled,
isRequired: store.isRequired,
hasError: store.hasError,
};
});

createEffect(() => console.log('Changed', fieldState()); // Is logging successfully on changes

return props.children(fieldState());
}

// ---------------------------
<Field form={myForm}>
{(fieldState) => (
<>
<p>{JSON.stringify(fieldState)}</p> // !! Not updating on changes
<CustomInput {...fieldState} />
</>
)}
</Field>
It works totally fine if I instead have several memos though:
export function Field(props: { form: Form; children: JSXElement }) {
const fieldState = {
value: createMemo(() => store.value),
isDisabled: createMemo(() => store.isDisabled),
...
};

return props.children(fieldState);
}

// ---------------------------
<Field form={myForm}>
{(fieldState) => (
<>
<p>{JSON.stringify(fieldState)}</p> // Updating correctly now
<CustomInput value={fieldState.value()} isDisabled={fieldState.isDisabled()} ... />
</>
)}
</Field>
export function Field(props: { form: Form; children: JSXElement }) {
const fieldState = {
value: createMemo(() => store.value),
isDisabled: createMemo(() => store.isDisabled),
...
};

return props.children(fieldState);
}

// ---------------------------
<Field form={myForm}>
{(fieldState) => (
<>
<p>{JSON.stringify(fieldState)}</p> // Updating correctly now
<CustomInput value={fieldState.value()} isDisabled={fieldState.isDisabled()} ... />
</>
)}
</Field>
a downside with the working example is having to pass in all props explicitly instead of just spreading em (ie. {...fieldState}) 😬 how come the reactivity is lost? is there a way to preserve reactivity + still being able to spread the props?
2 replies
SSolidJS
Created by lars on 5/10/2023 in #support
updating a tree of nodes in a SolidJS store
hey y'all. i'm trying to build a tree view where nodes have an isExpanded state i'm having a tough time trying to update the corresponding node. below is the approach i've tried but it doesn't trigger a component update for whatever reason. if there's a totally different way to do this, then i'm all ears
type Node = {
id: string;
isExpanded: boolean;
children: Node[];
}

export function useTreeState() {
const [treeState, setTreeState] = createStore<Node[]>([]);

function setNodeExpansion(id: string, isExpanded: boolean): void {
setTreeState(
produce(tree => {
// Traverse down to get the node to update.
const foundNode = getNodeDeep(styleTree, id);
foundNode.isExpanded = true; // <---- this doesn't actually update
return tree;
}),
);
}
}
type Node = {
id: string;
isExpanded: boolean;
children: Node[];
}

export function useTreeState() {
const [treeState, setTreeState] = createStore<Node[]>([]);

function setNodeExpansion(id: string, isExpanded: boolean): void {
setTreeState(
produce(tree => {
// Traverse down to get the node to update.
const foundNode = getNodeDeep(styleTree, id);
foundNode.isExpanded = true; // <---- this doesn't actually update
return tree;
}),
);
}
}
4 replies
SSolidJS
Created by lars on 5/1/2023 in #support
parent route with redirect (solid-router)?
is there a way to define a parent route that redirects to a child route? eg. say with the below route config, is there a way to set up a redirect from /home -> /home/browse?
<Route path="/home" component={Home}>
<Route path="/browse" component={Browse} />
<Route path="/projects" component={Projects} />
</Route>
<Route path="/home" component={Home}>
<Route path="/browse" component={Browse} />
<Route path="/projects" component={Projects} />
</Route>
4 replies
SSolidJS
Created by lars on 3/14/2023 in #support
Confusion around solid-query
coming from Angular, so I'm new to both solidJS and solid-query/react-query, when writing a useAuth hook, how would you go about fetching and storing the initial session?
export const useAuth = () => {
const [session, setSession] = createSignal<Session | null>(null);

/** Instance of auth client. */
const { auth } = createClient();

const initialSession = () => {
return createQuery({
queryKey: () => ['getSession'],
queryFn: () => auth.getSession().then(res => res.session),
});
};

setSession(initialSession()?.data ?? null); // <- this doesn't work as expected

return { session }
}
export const useAuth = () => {
const [session, setSession] = createSignal<Session | null>(null);

/** Instance of auth client. */
const { auth } = createClient();

const initialSession = () => {
return createQuery({
queryKey: () => ['getSession'],
queryFn: () => auth.getSession().then(res => res.session),
});
};

setSession(initialSession()?.data ?? null); // <- this doesn't work as expected

return { session }
}
3 replies
SSolidJS
Created by lars on 3/12/2023 in #support
Monorepo error with SolidStart `__vite_ssr_import_0__.template is not a function`
I've got a shared UI library (compiled into esm + cjs with vite) that is used with both a regular SolidJS app and a SolidStart app. It's working fine in the SolidJS app, but when importing the lib in the SolidStart app, I'm getting a pretty cryptic error:
__vite_ssr_import_0__.template is not a function
TypeError: __vite_ssr_import_0__.template is not a function
at /@fs/C:/Projects/Glazer/libs/ui-solid/dist/index.mjs:11:23
at async instantiateModule (file:///C:/Projects/Glazer/node_modules/.pnpm/[email protected]_@[email protected]/node_modules/vite/dist/node/chunks/dep-3007b26d.js:52400:9
__vite_ssr_import_0__.template is not a function
TypeError: __vite_ssr_import_0__.template is not a function
at /@fs/C:/Projects/Glazer/libs/ui-solid/dist/index.mjs:11:23
at async instantiateModule (file:///C:/Projects/Glazer/node_modules/.pnpm/[email protected]_@[email protected]/node_modules/vite/dist/node/chunks/dep-3007b26d.js:52400:9
7 replies