Skip to content

2.0.0-rc.6 | render is blocking on a latest signal read. #3289

Description

@mizulu

Describe the bug

after the reproduction finishes the initial load. clicking the reload button
triggers a signal update, that signal used in multiple places in the application to refresh
its dependents.

the signal is always read via a wrapper function that read it via latest()
so this signal should never get entangled.

the assumption that any owner reading that refresh signal, can re execute(unless it is held by another entanglement)
but that signal read itself should not cause entanglement. between its readers.

and we can see that works for the 3 top panels, each reload will reset the tab and show its fallback until it is resolved
the tabs independently resolve

however the TabPanel values are only updated on the initial click, and if we click it again while the top panels are still resolving, we will only see them going back to fallback, but the values of the Tab do not get updated even though
they have only 20ms resolve time. any effect on the refresh signal will not trigger until
everything settles

Your Example Website or App

https://s.olid.uk/id/pEAxMQSvTAqDiwR6cEoeWw (2.0.0-rc.6)

playground @ 2.0.0-beta.15

Steps to Reproduce the Bug or Issue

  1. wait for initial load of all panels
  2. click reload once , then again , then again, you will see top 3 panels reset to fallback
    but the TabPanel holding the values from the first reload click
  3. once we stop clicking reload and we let all panels resolve the TabPanel will update its new data() values

Expected behavior

it is not clear why TabPanel will hold the render, we can also isolate TabPanel to only depend on the refresh signal
dashboardReloadSignal() without any other dependencies, and the render will still block.
for example by generating random data without async in the TabPanel.tsx code.

this might be miss understanding, but it is hard to trace that easily.

additionally tried the same reproduction with older version like 2.0.0-rc.15
and the Tab data updates with every reload click.

Screenshots or Videos

##2.0.0-rc.6
Image


2.0.0-beta.15

Image

Platform

  • OS: [e.g. macOS, Windows, Linux]
  • Browser: [e.g. Chrome, Safari, Firefox]
  • Version: [e.g. 91.1]

Additional context

playground source files (json)

{
  "files": {
    "vite.config.ts": "import { defineConfig } from 'vite';\nimport solid from 'vite-plugin-solid';\n\nexport default defineConfig({\n  plugins: [solid()],\n});\n",
    "tsconfig.json": "{\n  \"compilerOptions\": {\n    \"target\": \"ESNext\",\n    \"useDefineForClassFields\": true,\n    \"module\": \"ESNext\",\n    \"lib\": [\"ESNext\", \"DOM\", \"DOM.Iterable\"],\n    \"types\": [\"vite/client\"],\n    \"skipLibCheck\": true,\n    \"moduleResolution\": \"bundler\",\n    \"allowImportingTsExtensions\": true,\n    \"isolatedModules\": true,\n    \"moduleDetection\": \"force\",\n    \"noEmit\": true,\n    \"jsx\": \"preserve\",\n    \"jsxImportSource\": \"@solidjs/web\",\n    \"strict\": true,\n    \"strictNullChecks\": true,\n    \"noUnusedLocals\": false,\n    \"noUnusedParameters\": false,\n    \"noFallthroughCasesInSwitch\": true,\n    \"noUncheckedSideEffectImports\": true\n  }\n}\n",
    "src/Utils/solidUtils.ts": "import { merge, onSettled, createEffect } from \"solid-js\";\r\n\r\nexport function withDefaults<T extends object>(props: T,\r\n                                               defaults: Partial<T>): T\r\n{\r\n    const obj = {} as Record<PropertyKey, unknown>;\r\n\r\n    for (const key of Object.keys(defaults) as (keyof T)[]) \r\n    {\r\n        Object.defineProperty(obj, \r\n                              key, \r\n                              {\r\n                                    get: () => \r\n                                    {\r\n                                        const value = props[key];\r\n                                        return value === undefined ? defaults[key] : value;\r\n                                    },\r\n                                    enumerable: true,\r\n                              });\r\n    }\r\n\r\n    return merge(props, obj) as never;\r\n}\r\n\r\n\r\ntype EventMap<T extends keyof HTMLElementEventMap> = (e: HTMLElementEventMap[T]) => any;\r\n\r\n\r\nexport function onCapture<T extends keyof HTMLElementEventMap>(type: T, listener: EventMap<T>)\r\n{\r\n\r\n    let element: HTMLElement | undefined;\r\n\r\n    onSettled(() =>\r\n    {\r\n\r\n        element?.addEventListener(type, listener, { capture: true });\r\n\r\n        return () =>\r\n        {\r\n            element?.removeEventListener(type, listener, { capture: true });\r\n        }\r\n    })\r\n\r\n    return (e: HTMLElement) =>\r\n    {\r\n        element = e;\r\n    }\r\n}",
    "src/Stores/dashboardStore.ts": "import { createStore, createSignal, latest, createEffect } from \"solid-js\";\r\n\r\nexport type Department =\r\n{\r\n    id: number;\r\n    name: string;\r\n}\r\n\r\nexport const availableDepartments: Department[] = \r\n[\r\n    {id: 1, name: \"Sales\"},\r\n    {id: 2, name: \"Production\"},\r\n    {id: 3, name: \"R&D\"}\r\n]\r\n\r\ntype DashboardStore =\r\n{\r\n    department: Department;\r\n    date: Date;\r\n    periodLength: PeriodLength;\r\n}\r\n\r\n\r\nexport type PeriodLength =\r\n{\r\n    id: number;\r\n    name: string;\r\n}\r\n\r\nexport const availablePeriods: PeriodLength[] =\r\n[\r\n    {id: 1, name: \"1 Day\"},\r\n    {id: 2, name: \"2 Days\"},\r\n    {id: 3, name: \"3 Days\"},\r\n    {id: 4, name: \"4 Days\"}\r\n]\r\n\r\nconst [dashboardStore, setDashboardStore] = createStore<DashboardStore>(\r\n    {\r\n        department: availableDepartments.find(t => t.id == 1)!,\r\n        date: new Date(2026,1,1,0,0,0,0),\r\n        periodLength: availablePeriods.find(t => t.id == 1)!\r\n    }\r\n);\r\n\r\n\r\n\r\nconst [dashboardReloadSignal_, setDashboardReloadSignal] = createSignal<object>(0);\r\n\r\n\r\nfunction dashboardReloadSignal(from= \"\"){\r\n  console.log(\"read\", from )\r\nreturn latest(dashboardReloadSignal_) // FIX for double reload, prevent this signal from being entangled by the different panels that uses it. \r\n}\r\n\r\n\r\ncreateEffect(()=>{\r\n  \r\n  return dashboardReloadSignal(\"effect\")\r\n}, (v)=>\r\nconsole.log(\"val\", v))\r\nexport {\r\n    dashboardReloadSignal\r\n};\r\n\r\nexport const reloadDashboard = () =>\r\n{\r\n  console.log(\"updating reload signal\")\r\n    setDashboardReloadSignal(v=>v+1);\r\n}\r\n\r\nexport const useDashboardStore  = (): [typeof dashboardStore, typeof setDashboardStore] =>\r\n{\r\n    return [dashboardStore, setDashboardStore];\r\n}\r\n",
    "src/Pages/Dashboard/Dashboard.tsx": "import \"./Dashboard.css\";\r\nimport { Component, onSettled } from 'solid-js';\r\nimport { useDashboardStore } from \"../../Stores/dashboardStore\";\r\nimport { withDefaults } from \"../../Utils/solidUtils\";\r\nimport { TopBar } from \"./Components/TopBar/TopBar\";\r\nimport { DataPanel } from \"./Components/DataPanel/DataPanel\";\r\nimport { TabPanel } from \"./Components/TabPanel/TabPanel\";\r\nimport { MiddlePanel } from './Components/MiddlePanel/MiddlePanel';\r\n\r\n\r\ntype DashboardProps =\r\n{\r\n    fakeId?: number;\r\n}\r\n\r\nexport const Dashboard: Component<DashboardProps> = (rawProps) =>\r\n{\r\n    const props = withDefaults(rawProps, { fakeId: 1});\r\n\r\n    const [dashboardStore, setDashboardStore] = useDashboardStore();\r\n\r\n    let myRef: HTMLDivElement | undefined;\r\n\r\n    onSettled(() =>\r\n    {\r\n       console.log(\"myRef\", myRef);\r\n    });\r\n\r\n    return (\r\n      <div class={\r\n        [\r\n          \"Dashboard\"\r\n        ]}>\r\n        <div class={[\"inner\"]}>\r\n          <div class={[\"top\", \"panel\"]}>\r\n            <TopBar />\r\n          </div>\r\n          <div class={[\"data-panel\", \"panel\"]}>\r\n            <DataPanel />\r\n          </div>\r\n          <div class={[\"middle-panel\", \"panel\"]}>\r\n            <MiddlePanel/>\r\n          </div>\r\n          <div class={[\"bottom-panel\", \"panel\"]}>\r\n            <div class=\"tabs\">\r\n              <TabPanel/>\r\n            </div>\r\n            <div class=\"misc-data\">\r\n            </div>\r\n          </div>\r\n        </div>\r\n      </div>\r\n    )\r\n}",
    "src/Pages/Dashboard/Dashboard.css": "*\r\n{\r\n   box-sizing: border-box;\r\n}\r\n\r\nhtml, body\r\n{\r\n   height:100%;\r\n   width:100%;\r\n   margin:0;\r\n   padding:0;\r\n}\r\n\r\n#root\r\n{\r\n   display:flex;\r\n   width:100%;\r\n   height:100%;\r\n}\r\n\r\n.Dashboard\r\n{\r\n   display:flex;\r\n   flex:1 1 0px;\r\n   padding:6px;\r\n\r\n   & > .inner\r\n   {\r\n      display:flex;\r\n      flex-direction: column;\r\n      flex:1 1 0px;\r\n\r\n      & > .panel\r\n      {\r\n         border:1px solid black;\r\n      }\r\n\r\n      & > .top\r\n      {\r\n         display:flex;\r\n         height:46px;\r\n      }\r\n\r\n      & > .data-panel\r\n      {\r\n         display:flex;\r\n         flex: 1 1 0;\r\n         min-height:160px;\r\n      }\r\n\r\n      & > .middle-panel\r\n      {\r\n         display:flex;\r\n         height: 60px;\r\n      }\r\n      \r\n      & > .bottom-panel\r\n      {\r\n         display:flex;\r\n         flex:0 1 360px;\r\n         min-height:360px;\r\n      }\r\n   }\r\n}",
    "src/Pages/Dashboard/Components/TopBar/TopBar.tsx": "import \"./TopBar.css\";\r\nimport { Component, createMemo, onSettled } from 'solid-js';\r\nimport { withDefaults } from \"../../../../Utils/solidUtils\";\r\nimport {useDashboardStore} from \"../../../../Stores/dashboardStore\";\r\nimport { TopBarAPI } from \"./Services/TopBarAPI\";\r\n\r\ntype TopBarProps =\r\n{\r\n    fakeId?: number;\r\n}\r\n\r\nexport const TopBar: Component<TopBarProps> = (rawProps) =>\r\n{\r\n    const props = withDefaults(rawProps, { fakeId: 1});\r\n\r\n    const [dashboardStore, setDashboardStore] = useDashboardStore();\r\n\r\n    const data = createMemo(async () =>\r\n    {\r\n        const result = await TopBarAPI.simulateFetchData(dashboardStore.date, dashboardStore.department, 400);\r\n\r\n        return result;\r\n    });\r\n\r\n    onSettled(() =>\r\n    {\r\n       \r\n    });\r\n\r\n    return (\r\n        <div class={\r\n          [\r\n            \"TopBar\"\r\n          ]}>\r\n            <div class=\"department-label\">\r\n              <span>Department: </span> \r\n              <span>{data().name}</span>\r\n              <span style={{\"margin-left\": \"10px\", \"font-size\": \"12px\"}}>(Some quick (sub 100ms) fetched server data so no point in showing a blocker)</span>\r\n            </div>\r\n          </div>\r\n    )\r\n}",
    "src/Pages/Dashboard/Components/TopBar/TopBar.css": ".TopBar\r\n{\r\n   display:flex;\r\n   align-items: center;\r\n   flex:1 1 0;\r\n   padding:0 6px;\r\n\r\n   & > .department-label\r\n   {\r\n\r\n   }\r\n}",
    "src/Pages/Dashboard/Components/TopBar/Services/TopBarAPI.ts": "import { type Department, availableDepartments } from \"../../../../../Stores/dashboardStore\";\r\n\r\nexport class TopBarAPI\r\n{\r\n    public static async simulateFetchData(period: Date, department: Department, delayMs: number = 500)\r\n    {\r\n        return await new Promise<Department>((resolve) =>\r\n        {\r\n            setTimeout(() => resolve({...availableDepartments.find(t => t.id == department.id)!}), delayMs);\r\n        });\r\n    }\r\n}\r\n",
    "src/Pages/Dashboard/Components/TabPanel/TabPanel.tsx": "import \"./TabPanel.css\";\r\nimport { Component, onSettled, createMemo, For, latest, createEffect } from 'solid-js';\r\nimport { withDefaults } from \"../../../../Utils/solidUtils\";\r\nimport { useDashboardStore, dashboardReloadSignal } from '../../../../Stores/dashboardStore';\r\nimport { TabPanelAPI } from \"./Services/TabPanelAPI\";\r\n\r\ntype TabPanelProps =\r\n  {\r\n    fakeId?: number;\r\n  }\r\n\r\nexport const TabPanel: Component<TabPanelProps> = (rawProps) => {\r\n  const props = withDefaults(rawProps, { fakeId: 1 });\r\n\r\n\r\n\r\n\r\n  const data = (() => {\r\n    dashboardReloadSignal(\"tab\");\r\n    return { items: [Math.random(), Math.random()] }\r\n  });\r\n\r\n\r\n  return (\r\n    <div class={\r\n      [\r\n        \"TabPanel\"\r\n      ]}>\r\n      <span style={{ \"margin-left\": \"10px\", \"font-size\": \"12px\" }}>(Some quick (sub 100ms) fetched server data so no point in showing a blocker)</span>\r\n\r\n      {/** when the reload signal triggers, the data is read but the render here is still blocked  */}\r\n      <For each={data().items}>\r\n        {\r\n          (data) => (<div>{data}</div>)\r\n        }\r\n      </For>\r\n\r\n\r\n    </div>\r\n  )\r\n}",
    "src/Pages/Dashboard/Components/TabPanel/TabPanel.css": ".TabPanel\r\n{\r\n  \r\n}",
    "src/Pages/Dashboard/Components/TabPanel/Services/TabPanelAPI.ts": "export type SomeData =\r\n{\r\n    items: number[]\r\n}\r\n\r\nexport class TabPanelAPI\r\n{\r\n    public static async simulateFetchData(period: Date, department: Department, delayMs: number = 500)\r\n    {\r\n        return await new Promise<SomeData>((resolve) =>\r\n        {\r\n            setTimeout(() => resolve({\r\n                                        items: \r\n                                        [\r\n                                          randomNumber(20),\r\n                                          randomNumber(20),\r\n                                          randomNumber(20),\r\n                                          randomNumber(20),\r\n                                          randomNumber(20),\r\n                                          randomNumber(20)\r\n                                        ]\r\n                                      }), delayMs);\r\n        });\r\n    }\r\n}\r\n\r\n\r\nconst randomNumber= (maxSize: number) =>\r\n{\r\n    return Math.floor(Math.random() * maxSize);\r\n}",
    "src/Pages/Dashboard/Components/MiddlePanel/MiddlePanel.tsx": "import \"./MiddlePanel.css\";\r\nimport { Component, onSettled } from 'solid-js';\r\nimport { withDefaults } from \"../../../../Utils/solidUtils\";\r\nimport { useDashboardStore, reloadDashboard, availablePeriods, availableDepartments, Department } from \"../../../../Stores/dashboardStore\";\r\nimport { Select } from '../../../../Components/UI/Select/Select';\r\nimport { PeriodLength } from \"../../../../Stores/dashboardStore\";\r\n\r\ntype MiddlePanelProps =\r\n{\r\n    fakeId?: number;\r\n}\r\n\r\nexport const MiddlePanel: Component<MiddlePanelProps> = (rawProps) =>\r\n{\r\n    const props = withDefaults(rawProps, { fakeId: 1});\r\n\r\n    const [dashboardStore, setDashboardStore] = useDashboardStore();\r\n\r\n    onSettled(() =>\r\n    {\r\n       \r\n    });\r\n\r\n    const handleReloadClick = () =>\r\n    {\r\n        reloadDashboard();\r\n    }\r\n\r\n    const handlePeriodLengthChange = (periodLength: PeriodLength, index: number) =>\r\n    {\r\n        \r\n        setDashboardStore(state => \r\n        {\r\n\r\n          state.periodLength = periodLength;\r\n\r\n          const newDate = new Date(state.date);\r\n\r\n          newDate.setDate(state.date.getDate() + 1);\r\n          state.date = newDate;\r\n\r\n        })\r\n    }\r\n\r\n    const handleDepartmentChange = (department: Department) =>\r\n    {\r\n        setDashboardStore(state =>\r\n          {\r\n              state.department = department;\r\n          });\r\n    }\r\n\r\n    return (\r\n      <div class={\r\n        [\r\n          \"MiddlePanel\"\r\n        ]}>\r\n          <div class=\"right\">\r\n             <button onClick={() => handleReloadClick()}>Reload</button>\r\n             <div>\r\n               <span>{\"recalculates dashboardStore.date\"}</span>\r\n               <Select items={availablePeriods} labelKey=\"name\" onChange={handlePeriodLengthChange}></Select>\r\n             </div>\r\n             <div>\r\n             <span>{\"dashboardStore.department\"}</span>\r\n               <Select items={availableDepartments} labelKey=\"name\" onChange={handleDepartmentChange}></Select>\r\n             </div>\r\n          </div>\r\n        </div>\r\n    )\r\n}",
    "src/Pages/Dashboard/Components/MiddlePanel/MiddlePanel.css": ".MiddlePanel\r\n{\r\n  display:flex;\r\n  align-items: center;\r\n  flex: 1 1 0;\r\n  margin-left:auto;\r\n  padding:0 6px;\r\n\r\n  & > .right\r\n  {\r\n     display:flex;\r\n     gap: 10px;\r\n  }\r\n}",
    "src/Pages/Dashboard/Components/DataPanel/DataPanel.tsx": "import \"./DataPanel.css\";\r\nimport { Component, onSettled, Loading } from 'solid-js';\r\nimport { withDefaults } from \"../../../../Utils/solidUtils\";\r\nimport { useDashboardStore } from '../../../../Stores/dashboardStore';\r\nimport { Graph } from \"./Components/Graph/Graph\";\r\nimport { Blocker } from \"../../../../Components/UI/Blocker/Blocker\";\r\n\r\ntype DataPanelProps =\r\n{\r\n    fakeId?: number;\r\n}\r\n\r\nexport const DataPanel: Component<DataPanelProps> = (rawProps) =>\r\n{\r\n    const props = withDefaults(rawProps, { fakeId: 1});\r\n\r\n    const [dashboardStore, setDashboardStore] = useDashboardStore();\r\n\r\n    onSettled(() =>\r\n    {\r\n      \r\n    });\r\n    \r\n    return (\r\n        <Loading fallback={<Blocker></Blocker>}>\r\n          <div class={\r\n          [\r\n            \"DataPanel\"\r\n          ]}>\r\n            <Graph delay={250 + (Math.random() * 2500)}/>\r\n            <Graph delay={1000 + (Math.random() * 2500)}/>\r\n            <Graph delay={4000 + (Math.random() * 5000)}/>\r\n          </div>\r\n        </Loading>\r\n    )\r\n}",
    "src/Pages/Dashboard/Components/DataPanel/DataPanel.css": ".DataPanel\r\n{\r\n   display:flex;\r\n   flex-direction: row;\r\n   flex:1 1 0px;\r\n\r\n   & > .Graph\r\n   {\r\n      flex:1 1 0px;\r\n      \r\n      &:not(:first-child)\r\n      {\r\n         border-left:1px solid silver;\r\n      }\r\n   }\r\n}",
    "src/Pages/Dashboard/Components/DataPanel/Components/Graph/Services/GraphAPI.ts": "import { Department } from \"Stores/dashboardStore\";\r\n\r\nexport type SomeData =\r\n{\r\n    items: number[]\r\n}\r\n\r\nexport class GraphAPI\r\n{\r\n    public static async simulateFetchData(period: Date, department: Department, delayMs: number = 500)\r\n    {\r\n        return await new Promise<SomeData>((resolve) =>\r\n        {\r\n            setTimeout(() => resolve({items: [1,2,3,4,5,6]}), delayMs);\r\n        });\r\n    }\r\n}\r\n",
    "src/Pages/Dashboard/Components/DataPanel/Components/Graph/Graph.tsx": "import \"./Graph.css\";\r\nimport { Component, onSettled, createMemo, Show, isPending, For } from 'solid-js';\r\nimport { withDefaults } from \"../../../../../../Utils/solidUtils\";\r\nimport { dashboardReloadSignal, useDashboardStore } from \"../../../../../../Stores/dashboardStore\";\r\nimport { Blocker } from \"../../../../../../Components/UI/Blocker/Blocker\";\r\nimport { GraphAPI } from \"./Services/GraphAPI\";\r\n\r\ntype GraphProps =\r\n{\r\n    delay: number;\r\n}\r\n\r\nexport const Graph: Component<GraphProps> = (rawProps) =>\r\n{\r\n    const props = withDefaults(rawProps, {});\r\n\r\n    const [dashboardStore, setDashboardStore] = useDashboardStore();\r\n\r\n    const data = createMemo(async () =>\r\n    {\r\n\r\n        dashboardReloadSignal(\"graph\");\r\n\r\n        const result = await GraphAPI.simulateFetchData(dashboardStore.date, dashboardStore.department, props.delay);\r\n\r\n        return result;\r\n    });\r\n\r\n    onSettled(() =>\r\n    {\r\n       \r\n    });\r\n\r\n    return (\r\n      <div class={\r\n        [\r\n          \"Graph\",\r\n          \"data-component\"\r\n        ]}>\r\n          <Show when={!isPending(() => data())} fallback={<Blocker />}>\r\n            <For each={data().items}>\r\n              {\r\n                (item) => (<div>{item}----</div>)\r\n              }\r\n            </For>\r\n          </Show>\r\n        </div>\r\n    )\r\n}",
    "src/Pages/Dashboard/Components/DataPanel/Components/Graph/Graph.css": ".Graph\r\n{\r\n    display:flex;\r\n    flex:1 1 0px;\r\n    padding:12px;\r\n}",
    "src/Components/UI/Select/Select.tsx": "import \"./Select.css\";\r\nimport { Component, For } from 'solid-js';\r\nimport { withDefaults } from \"../../../Utils/solidUtils\";\r\nimport { JSX } from \"@solidjs/web\";\r\n\r\ntype SelectProps<TItem extends Record<TKey, string | number>, TKey extends PropertyKey> =\r\n{\r\n    items: readonly TItem[];\r\n    defaultValue?: TItem;\r\n    onChange: (item: TItem, index: number) => void;\r\n    labelKey: TKey;\r\n};\r\n\r\nexport const Select = <TItem extends Record<TKey, string | number>, TKey extends PropertyKey>(props: SelectProps<TItem, TKey>) =>\r\n{\r\n    return (\r\n        <div class=\"Select\">\r\n            <select onChange={(e) => props.onChange(props.items[e.currentTarget.selectedIndex], e.currentTarget.selectedIndex)}>\r\n                <For each={props.items}>\r\n                    {(item) => <option>{item[props.labelKey]}</option>}\r\n                </For>\r\n            </select>\r\n        </div>\r\n    );\r\n};",
    "src/Components/UI/Select/Select.css": ".Select\r\n{\r\n  \r\n}",
    "src/Components/UI/Blocker/Blocker.tsx": "import \"./Blocker.css\";\r\nimport { Component } from 'solid-js';\r\nimport { withDefaults } from \"../../../Utils/solidUtils\";\r\n\r\ntype BlockerProps =\r\n{\r\n    \r\n}\r\n\r\nexport const Blocker: Component<BlockerProps> = (rawProps) =>\r\n{\r\n    const props = withDefaults(rawProps, {});\r\n\r\n    return (\r\n      <div class={\r\n        [\r\n          \"Blocker\"\r\n        ]}>\r\n          <LogoSvg></LogoSvg>\r\n        </div>\r\n    )\r\n}\r\n\r\nconst LogoSvg = () =>\r\n{\r\n  return (\r\n    <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 166 155.3\"><defs><linearGradient id=\"a\" gradientUnits=\"userSpaceOnUse\" x1=\"27.5\" y1=\"3\" x2=\"152\" y2=\"63.5\"><stop offset=\".1\" stop-color=\"#76b3e1\"/><stop offset=\".3\" stop-color=\"#dcf2fd\"/><stop offset=\"1\" stop-color=\"#76b3e1\"/></linearGradient><linearGradient id=\"b\" gradientUnits=\"userSpaceOnUse\" x1=\"95.8\" y1=\"32.6\" x2=\"74\" y2=\"105.2\"><stop offset=\"0\" stop-color=\"#76b3e1\"/><stop offset=\".5\" stop-color=\"#4377bb\"/><stop offset=\"1\" stop-color=\"#1f3b77\"/></linearGradient><linearGradient id=\"c\" gradientUnits=\"userSpaceOnUse\" x1=\"18.4\" y1=\"64.2\" x2=\"144.3\" y2=\"149.8\"><stop offset=\"0\" stop-color=\"#315aa9\"/><stop offset=\".5\" stop-color=\"#518ac8\"/><stop offset=\"1\" stop-color=\"#315aa9\"/></linearGradient><linearGradient id=\"d\" gradientUnits=\"userSpaceOnUse\" x1=\"75.2\" y1=\"74.5\" x2=\"24.4\" y2=\"260.8\"><stop offset=\"0\" stop-color=\"#4377bb\"/><stop offset=\".5\" stop-color=\"#1a336b\"/><stop offset=\"1\" stop-color=\"#1a336b\"/></linearGradient></defs><path d=\"M163 35S110-4 69 5l-3 1c-6 2-11 5-14 9l-2 3-15 26 26 5c11 7 25 10 38 7l46 9 18-30z\" fill=\"#76b3e1\"/><path d=\"M163 35S110-4 69 5l-3 1c-6 2-11 5-14 9l-2 3-15 26 26 5c11 7 25 10 38 7l46 9 18-30z\" opacity=\".3\" fill=\"url(#a)\"/><path d=\"M52 35l-4 1c-17 5-22 21-13 35 10 13 31 20 48 15l62-21S92 26 52 35z\" fill=\"#518ac8\"/><path d=\"M52 35l-4 1c-17 5-22 21-13 35 10 13 31 20 48 15l62-21S92 26 52 35z\" opacity=\".3\" fill=\"url(#b)\"/><path d=\"M134 80a45 45 0 00-48-15L24 85 4 120l112 19 20-36c4-7 3-15-2-23z\" fill=\"url(#c)\"/><path d=\"M114 115a45 45 0 00-48-15L4 120s53 40 94 30l3-1c17-5 23-21 13-34z\" fill=\"url(#d)\"/></svg>\r\n  )\r\n}",
    "src/Components/UI/Blocker/Blocker.css": "@keyframes BLOCKER_ANIMATION\r\n{\r\n    0%\r\n    {\r\n        opacity:1.0;\r\n    }\r\n    100%\r\n    {\r\n        opacity:0.4;\r\n    }\r\n}\r\n\r\n.Blocker\r\n{\r\n   display:flex;\r\n   flex:1 1 0px;\r\n   align-items: center;\r\n   justify-content: center;\r\n\r\n   & > svg\r\n   {\r\n      width:100px;\r\n      height:100px;\r\n      animation: BLOCKER_ANIMATION 0.7s alternate linear infinite;\r\n   }\r\n}",
    "package.json": "{\n  \"name\": \"vite-template-solid\",\n  \"version\": \"1.0.0\",\n  \"private\": true,\n  \"scripts\": {\n    \"dev\": \"vite\",\n    \"build\": \"vite build\",\n    \"preview\": \"vite preview\"\n  },\n  \"dependencies\": {\n    \"solid-js\": \"2.0.0-rc.6\",\n    \"@solidjs/web\": \"2.0.0-rc.6\",\n    \"typescript\": \"7.0.2\"\n  },\n  \"devDependencies\": {\n    \"vite\": \"6.0.0\",\n    \"vite-plugin-solid\": \"3.0.0-next.27\"\n  }\n}\n",
    "main.tsx": "import { render } from '@solidjs/web';\nimport { Dashboard } from './src/Pages/Dashboard/Dashboard';\n\nexport default function App() {\n  return <Dashboard></Dashboard>;\n}\n\nif (typeof document !== 'undefined') {\n  render(() => <App />, document.getElementById('root')!);\n}\n",
    "index.html": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>Solid App</title>\n  </head>\n  <body style=\"font-size:16px;font-family:Arial\">\n    <div id=\"root\"></div>\n    <script type=\"module\" src=\"/main.tsx\"></script>\n  </body>\n</html>\n",
    "import-map.json": "{\n  \"imports\": {\n    \"stores\": \"https://esm.sh/stores\",\n    \"vite-plugin-solid\": \"https://esm.sh/vite-plugin-solid\",\n    \"vite\": \"https://esm.sh/vite\",\n    \"solid-js\": \"https://esm.sh/solid-js@2.0.0-rc.6?dev&external=solid-js,@solidjs/signals\",\n    \"@solidjs/signals\": \"https://esm.sh/@solidjs/signals@2.0.0-rc.6?dev\",\n    \"solid-js/web\": \"https://esm.sh/@solidjs/web@2.0.0-rc.6?dev&external=solid-js,@solidjs/signals\",\n    \"solid-js/store\": \"https://esm.sh/solid-js@2.0.0-rc.6?dev&external=solid-js,@solidjs/signals\",\n    \"@solidjs/web\": \"https://esm.sh/@solidjs/web@2.0.0-rc.6?dev&external=solid-js,@solidjs/signals\"\n  }\n}"
  }
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions