fix(app): code splitting for web load perf gains
This commit is contained in:
@@ -175,12 +175,13 @@ export function List<T>(props: ListProps<T> & { ref?: (ref: ListRef) => void })
|
||||
fallback={
|
||||
<div data-slot="list-empty-state">
|
||||
<div data-slot="list-message">
|
||||
{props.emptyMessage ?? "No results"} for <span data-slot="list-filter">"{filter()}"</span>
|
||||
{props.emptyMessage ?? (grouped.loading ? "Loading" : "No results")} for{" "}
|
||||
<span data-slot="list-filter">"{filter()}"</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<For each={grouped()}>
|
||||
<For each={grouped.latest}>
|
||||
{(group) => (
|
||||
<div data-slot="list-group">
|
||||
<Show when={group.category}>
|
||||
|
||||
@@ -15,6 +15,7 @@ export function Markdown(
|
||||
async (markdown) => {
|
||||
return marked.parse(markdown)
|
||||
},
|
||||
{ initialValue: "" },
|
||||
)
|
||||
return (
|
||||
<div
|
||||
@@ -23,7 +24,7 @@ export function Markdown(
|
||||
...(local.classList ?? {}),
|
||||
[local.class ?? ""]: !!local.class,
|
||||
}}
|
||||
innerHTML={html()}
|
||||
innerHTML={html.latest}
|
||||
{...others}
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import {
|
||||
createContext,
|
||||
createRoot,
|
||||
createSignal,
|
||||
getOwner,
|
||||
Owner,
|
||||
ParentProps,
|
||||
type Owner,
|
||||
type ParentProps,
|
||||
runWithOwner,
|
||||
Show,
|
||||
useContext,
|
||||
type JSX,
|
||||
} from "solid-js"
|
||||
@@ -13,58 +13,66 @@ import { Dialog as Kobalte } from "@kobalte/core/dialog"
|
||||
|
||||
type DialogElement = () => JSX.Element
|
||||
|
||||
type Active = {
|
||||
id: string
|
||||
node: JSX.Element
|
||||
dispose: () => void
|
||||
owner: Owner
|
||||
onClose?: () => void
|
||||
}
|
||||
|
||||
const Context = createContext<ReturnType<typeof init>>()
|
||||
|
||||
function init() {
|
||||
const [active, setActive] = createSignal<
|
||||
| {
|
||||
id: string
|
||||
element: DialogElement
|
||||
onClose?: () => void
|
||||
owner: Owner
|
||||
}
|
||||
| undefined
|
||||
>()
|
||||
const [active, setActive] = createSignal<Active | undefined>()
|
||||
|
||||
const result = {
|
||||
const close = () => {
|
||||
const current = active()
|
||||
if (!current) return
|
||||
current.onClose?.()
|
||||
current.dispose()
|
||||
setActive(undefined)
|
||||
}
|
||||
|
||||
const show = (element: DialogElement, owner: Owner, onClose?: () => void) => {
|
||||
close()
|
||||
|
||||
const id = Math.random().toString(36).slice(2)
|
||||
let dispose: (() => void) | undefined
|
||||
|
||||
const node = runWithOwner(owner, () =>
|
||||
createRoot((d) => {
|
||||
dispose = d
|
||||
return (
|
||||
<Kobalte
|
||||
modal
|
||||
open={true}
|
||||
onOpenChange={(open) => {
|
||||
if (open) return
|
||||
close()
|
||||
}}
|
||||
>
|
||||
<Kobalte.Portal>
|
||||
<Kobalte.Overlay data-component="dialog-overlay" />
|
||||
{element()}
|
||||
</Kobalte.Portal>
|
||||
</Kobalte>
|
||||
)
|
||||
}),
|
||||
)
|
||||
|
||||
if (!dispose) return
|
||||
|
||||
setActive({ id, node, dispose, owner, onClose })
|
||||
}
|
||||
|
||||
return {
|
||||
get active() {
|
||||
return active()
|
||||
},
|
||||
close() {
|
||||
active()?.onClose?.()
|
||||
setActive(undefined)
|
||||
},
|
||||
show(element: DialogElement, owner: Owner, onClose?: () => void) {
|
||||
active()?.onClose?.()
|
||||
const id = Math.random().toString(36).slice(2)
|
||||
setActive({
|
||||
id,
|
||||
element: () =>
|
||||
runWithOwner(owner, () => (
|
||||
<Show when={active()?.id === id}>
|
||||
<Kobalte
|
||||
modal
|
||||
open={true}
|
||||
onOpenChange={(open) => {
|
||||
if (!open) {
|
||||
result.close()
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Kobalte.Portal>
|
||||
<Kobalte.Overlay data-component="dialog-overlay" />
|
||||
{element()}
|
||||
</Kobalte.Portal>
|
||||
</Kobalte>
|
||||
</Show>
|
||||
)),
|
||||
onClose,
|
||||
owner,
|
||||
})
|
||||
},
|
||||
close,
|
||||
show,
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
export function DialogProvider(props: ParentProps) {
|
||||
@@ -72,7 +80,7 @@ export function DialogProvider(props: ParentProps) {
|
||||
return (
|
||||
<Context.Provider value={ctx}>
|
||||
{props.children}
|
||||
<div data-component="dialog-stack">{ctx.active?.element?.()}</div>
|
||||
<div data-component="dialog-stack">{ctx.active?.node}</div>
|
||||
</Context.Provider>
|
||||
)
|
||||
}
|
||||
@@ -80,18 +88,21 @@ export function DialogProvider(props: ParentProps) {
|
||||
export function useDialog() {
|
||||
const ctx = useContext(Context)
|
||||
const owner = getOwner()
|
||||
|
||||
if (!owner) {
|
||||
throw new Error("useDialog must be used within a DialogProvider")
|
||||
}
|
||||
if (!ctx) {
|
||||
throw new Error("useDialog must be used within a DialogProvider")
|
||||
}
|
||||
|
||||
return {
|
||||
get active() {
|
||||
return ctx.active
|
||||
},
|
||||
show(element: DialogElement, onClose?: () => void) {
|
||||
ctx.show(element, owner, onClose)
|
||||
const base = ctx.active?.owner ?? owner
|
||||
ctx.show(element, base, onClose)
|
||||
},
|
||||
close() {
|
||||
ctx.close()
|
||||
|
||||
@@ -18,6 +18,9 @@ export interface FilteredListProps<T> {
|
||||
export function useFilteredList<T>(props: FilteredListProps<T>) {
|
||||
const [store, setStore] = createStore<{ filter: string }>({ filter: "" })
|
||||
|
||||
type Group = { category: string; items: [T, ...T[]] }
|
||||
const empty: Group[] = []
|
||||
|
||||
const [grouped, { refetch }] = createResource(
|
||||
() => ({
|
||||
filter: store.filter,
|
||||
@@ -42,11 +45,12 @@ export function useFilteredList<T>(props: FilteredListProps<T>) {
|
||||
)
|
||||
return result
|
||||
},
|
||||
{ initialValue: empty },
|
||||
)
|
||||
|
||||
const flat = createMemo(() => {
|
||||
return pipe(
|
||||
grouped() || [],
|
||||
grouped.latest || [],
|
||||
flatMap((x) => x.items),
|
||||
)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user