diff --git a/README.md b/README.md index 9827f2d..5b14274 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,8 @@ See examples in the demo (code [here](https://github.com/dvcol/neo-svelte/tree/f ## TODO - [ ] @media any-pointer:coarse any-hover:none - [x] Buttons + - [x] toggle + - [x] groups - [x] Tabs - [x] Card - [x] Inputs @@ -78,6 +80,7 @@ See examples in the demo (code [here](https://github.com/dvcol/neo-svelte/tree/f - [x] custom before-after - [x] steps - [ ] vertical + - [ ] rating (stars) - [x] select - [x] native - [ ] custom @@ -87,6 +90,19 @@ See examples in the demo (code [here](https://github.com/dvcol/neo-svelte/tree/f - [ ] nested menus - [ ] list + - [ ] snippets + - [ ] children + - [ ] header + - [ ] footer + - [ ] select + - [ ] multiple + - [ ] disabled + - [ ] readonly + - [ ] header (pills or item count) + - [ ] separator + - [ ] label (sections + - [ ] keyboard navigation + - [ ] scroll shadow - [ ] virtualized - [ ] infinite scroll - [ ] drag & drop @@ -98,6 +114,27 @@ See examples in the demo (code [here](https://github.com/dvcol/neo-svelte/tree/f - [ ] select - [ ] tree +- [ ] Chat + - [ ] infinite scroll + - [ ] virtual scroll + - [ ] async + - [ ] stream + - [ ] generative text animation + - [ ] scroll to bottom + - [ ] typing indicator + - [ ] read indicator + - [ ] reactions + - [ ] threads + - [ ] @ / # tags + - [ ] mentions + - [ ] attachments + - [ ] gifs/images + - [ ] videos + - [ ] audio + - [ ] custom cards (contact, etc.) + - [ ] custom bubbles + - [ ] custom input + - [ ] Modal/dialog - [ ] drawer/panel - [ ] collapsible diff --git a/demo/App.svelte b/demo/App.svelte index acd5448..8a9b6f4 100644 --- a/demo/App.svelte +++ b/demo/App.svelte @@ -24,7 +24,15 @@ in: fade, out: fade, params: { in: { delay: 200, duration: 200 }, out: { duration: 200 } }, - props: { container: { style: 'display: flex; justify-content: center; align-items: center;' } }, + props: { + container: { + style: { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + }, + }, + }, skipFirst: true, }; diff --git a/demo/components/DemoLists.svelte b/demo/components/DemoLists.svelte new file mode 100644 index 0000000..672405e --- /dev/null +++ b/demo/components/DemoLists.svelte @@ -0,0 +1,121 @@ + + +
+ + Empty + Loading + Skeleton + +
+ +
+
+ List + + + +
+
+ Custom loader + + {#snippet loader()} +
+ +
+ {/snippet} +
+
+
+ Custom Empty + + {#snippet empty()} +
+ Custom empty snippet +
+ {/snippet} +
+
+ + + + + + + + + + + + + + + + +
+ + diff --git a/demo/router/routes.ts b/demo/router/routes.ts index f419708..e53149e 100644 --- a/demo/router/routes.ts +++ b/demo/router/routes.ts @@ -11,6 +11,7 @@ export const Route = { Skeleton: 'skeleton' as const, Inputs: 'inputs' as const, Tooltips: 'tooltips' as const, + Lists: 'lists' as const, } as const; export type Routes = (typeof Route)[keyof typeof Route]; @@ -25,6 +26,7 @@ export const Path: Record = { Skeleton: '/skeleton' as const, Inputs: '/inputs' as const, Tooltips: '/tooltips' as const, + Lists: '/lists' as const, Any: '*' as const, } as const; @@ -79,6 +81,11 @@ export const options: RouterOptions = { path: Path.Tooltips, component: () => import('../components/DemoTooltips.svelte'), }, + { + name: Route.Lists, + path: Path.Lists, + component: () => import('../components/DemoLists.svelte'), + }, { name: Route.Any, path: Path.Any, diff --git a/package.json b/package.json index 0fb2585..0c1df5e 100644 --- a/package.json +++ b/package.json @@ -110,17 +110,17 @@ "svelte": ">=5" }, "dependencies": { - "@dvcol/common-utils": "^1.20.0", + "@dvcol/common-utils": "^1.21.2", "@dvcol/svelte-utils": "^1.6.1", "@skeletonlabs/floating-ui-svelte": "^0.3.9", - "svelte": "^5.19.0" + "svelte": "^5.19.3" }, "devDependencies": { "@commitlint/cli": "^19.4.1", "@commitlint/config-conventional": "^19.4.1", "@dvcol/eslint-plugin-presets": "^1.3.11", "@dvcol/stylelint-plugin-presets": "^2.1.2", - "@dvcol/svelte-simple-router": "^1.10.0", + "@dvcol/svelte-simple-router": "^1.10.1", "@sveltejs/adapter-auto": "^4.0.0", "@sveltejs/kit": "^2.16.0", "@sveltejs/package": "^2.3.7", @@ -162,7 +162,7 @@ "sass": "^1.83.4", "standard-version": "^9.5.0", "stylelint": "^16.9.0", - "svelte-check": "^4.1.1", + "svelte-check": "^4.1.4", "svelte-preprocess": "^6.0.3", "typescript": "^5.5.4", "vite": "^6.0.7", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c8b5b08..97b8f80 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,17 +9,17 @@ importers: .: dependencies: '@dvcol/common-utils': - specifier: ^1.20.0 - version: 1.20.0 + specifier: ^1.21.2 + version: 1.21.2 '@dvcol/svelte-utils': specifier: ^1.6.1 - version: 1.6.1(@types/node@22.5.4)(sass@1.83.4)(sugarss@2.0.0)(svelte@5.19.0) + version: 1.6.1(@types/node@22.5.4)(sass@1.83.4)(sugarss@2.0.0)(svelte@5.19.3) '@skeletonlabs/floating-ui-svelte': specifier: ^0.3.9 - version: 0.3.9(svelte@5.19.0) + version: 0.3.9(svelte@5.19.3) svelte: - specifier: ^5.19.0 - version: 5.19.0 + specifier: ^5.19.3 + version: 5.19.3 devDependencies: '@commitlint/cli': specifier: ^19.4.1 @@ -29,31 +29,31 @@ importers: version: 19.4.1 '@dvcol/eslint-plugin-presets': specifier: ^1.3.11 - version: 1.3.11(suyu6q4fzdqh3aytlan25ljjfa) + version: 1.3.11(z7cxgnttms2gl7huq66ofhf6ue) '@dvcol/stylelint-plugin-presets': specifier: ^2.1.2 version: 2.1.2(postcss-html@0.36.0)(postcss-scss@4.0.9(postcss@8.5.1))(postcss@8.5.1)(prettier@3.3.3)(stylelint@16.9.0(typescript@5.5.4)) '@dvcol/svelte-simple-router': - specifier: ^1.10.0 - version: 1.10.0(@types/node@22.5.4)(sass@1.83.4)(sugarss@2.0.0)(svelte@5.19.0) + specifier: ^1.10.1 + version: 1.10.1(@types/node@22.5.4)(sass@1.83.4)(sugarss@2.0.0)(svelte@5.19.3) '@sveltejs/adapter-auto': specifier: ^4.0.0 - version: 4.0.0(@sveltejs/kit@2.16.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.0)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)))(svelte@5.19.0)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0))) + version: 4.0.0(@sveltejs/kit@2.16.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.3)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)))(svelte@5.19.3)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0))) '@sveltejs/kit': specifier: ^2.16.0 - version: 2.16.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.0)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)))(svelte@5.19.0)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)) + version: 2.16.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.3)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)))(svelte@5.19.3)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)) '@sveltejs/package': specifier: ^2.3.7 - version: 2.3.7(svelte@5.19.0)(typescript@5.5.4) + version: 2.3.7(svelte@5.19.3)(typescript@5.5.4) '@sveltejs/vite-plugin-svelte': specifier: ^5.0.3 - version: 5.0.3(svelte@5.19.0)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)) + version: 5.0.3(svelte@5.19.3)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)) '@testing-library/jest-dom': specifier: ^6.6.3 version: 6.6.3 '@testing-library/svelte': specifier: ^5.2.6 - version: 5.2.6(svelte@5.19.0)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0))(vitest@3.0.2(@types/node@22.5.4)(jiti@1.21.0)(jsdom@25.0.1)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)) + version: 5.2.6(svelte@5.19.3)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0))(vitest@3.0.2(@types/node@22.5.4)(jiti@1.21.0)(jsdom@25.0.1)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)) '@testing-library/user-event': specifier: ^14.5.2 version: 14.5.2(@testing-library/dom@10.4.0) @@ -104,7 +104,7 @@ importers: version: 5.2.1(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.3) eslint-plugin-svelte: specifier: ^2.46.1 - version: 2.46.1(eslint@8.57.0)(svelte@5.19.0) + version: 2.46.1(eslint@8.57.0)(svelte@5.19.3) eslint-plugin-vitest: specifier: ^0.4.1 version: 0.4.1(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4)(vitest@3.0.2(@types/node@22.5.4)(jiti@1.21.0)(jsdom@25.0.1)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)) @@ -146,7 +146,7 @@ importers: version: 3.3.3 prettier-plugin-svelte: specifier: ^3.3.2 - version: 3.3.2(prettier@3.3.3)(svelte@5.19.0) + version: 3.3.2(prettier@3.3.3)(svelte@5.19.3) publint: specifier: ^0.2.0 version: 0.2.10 @@ -160,11 +160,11 @@ importers: specifier: ^16.9.0 version: 16.9.0(typescript@5.5.4) svelte-check: - specifier: ^4.1.1 - version: 4.1.1(svelte@5.19.0)(typescript@5.5.4) + specifier: ^4.1.4 + version: 4.1.4(svelte@5.19.3)(typescript@5.5.4) svelte-preprocess: specifier: ^6.0.3 - version: 6.0.3(@babel/core@7.25.2)(postcss-load-config@3.1.4(postcss@8.5.1))(postcss@8.5.1)(sass@1.83.4)(sugarss@2.0.0)(svelte@5.19.0)(typescript@5.5.4) + version: 6.0.3(@babel/core@7.25.2)(postcss-load-config@3.1.4(postcss@8.5.1))(postcss@8.5.1)(sass@1.83.4)(sugarss@2.0.0)(svelte@5.19.3)(typescript@5.5.4) typescript: specifier: ^5.5.4 version: 5.5.4 @@ -361,8 +361,8 @@ packages: '@dual-bundle/import-meta-resolve@4.1.0': resolution: {integrity: sha512-+nxncfwHM5SgAtrVzgpzJOI1ol0PkumhVo469KCf9lUi21IGcY90G98VuHm9VRrUypmAzawAHO9bs6hqeADaVg==} - '@dvcol/common-utils@1.20.0': - resolution: {integrity: sha512-v4I7X10BJiFQPhvNeheWoSF0i2q3LAU2JRRq+icXFFC81yuJ+4BgrzxQxDcOZ6ixNqDEg1QjjGIuDI7MbsVtUw==} + '@dvcol/common-utils@1.21.2': + resolution: {integrity: sha512-QkuHQXWc1s3UvjKBVh1r80uIPh//D6JFYO3EDTv6ocIeGlDgdv0qPAbDSfUh9QbRIv1W/hENeOPOpKwXG7wYww==} engines: {node: '>=20', pnpm: '>= 8'} '@dvcol/eslint-plugin-presets@1.3.11': @@ -461,8 +461,8 @@ packages: postcss-scss: optional: true - '@dvcol/svelte-simple-router@1.10.0': - resolution: {integrity: sha512-mjYLZo9SOxon+n23d6aQOO3hESZ30fAk8/AQeKSRcdA+T6iylYfR4LAQxYu/P7Ut44ovkaTdvHi90zPGT44l/g==} + '@dvcol/svelte-simple-router@1.10.1': + resolution: {integrity: sha512-RKLP/IdceOxvj/g3F9KEhplg3Cydm3IBeXgHmx3e7nH5vP49ksXJWntCwUE+qg0Ur0ytIgFEyLfnciMeTaeQ9g==} engines: {node: '>=20', pnpm: '>= 8'} peerDependencies: svelte: '>=5' @@ -2361,9 +2361,6 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true - esm-env@1.2.1: - resolution: {integrity: sha512-U9JedYYjCnadUlXk7e1Kr+aENQhtUaoaV9+gZm1T8LC/YBAPJx3NSPIAurFOC0U5vrdSevnUJS2/wUVxGwPhng==} - esm-env@1.2.2: resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==} @@ -4613,8 +4610,8 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - svelte-check@4.1.1: - resolution: {integrity: sha512-NfaX+6Qtc8W/CyVGS/F7/XdiSSyXz+WGYA9ZWV3z8tso14V2vzjfXviKaTFEzB7g8TqfgO2FOzP6XT4ApSTUTw==} + svelte-check@4.1.4: + resolution: {integrity: sha512-v0j7yLbT29MezzaQJPEDwksybTE2Ups9rUxEXy92T06TiA0cbqcO8wAOwNUVkFW6B0hsYHA+oAX3BS8b/2oHtw==} engines: {node: '>= 18.0.0'} hasBin: true peerDependencies: @@ -4673,8 +4670,8 @@ packages: svelte: ^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0 typescript: ^4.9.4 || ^5.0.0 - svelte@5.19.0: - resolution: {integrity: sha512-qvd2GvvYnJxS/MteQKFSMyq8cQrAAut28QZ39ySv9k3ggmhw4Au4Rfcsqva74i0xMys//OhbhVCNfXPrDzL/Bg==} + svelte@5.19.3: + resolution: {integrity: sha512-rb/bkYG9jq67OCWikMvaPnfOobyGn0JizVDwHpdeBtLiNXPMcoA9GTFC3BhptP7xGNquUU8J5GiS7PlGlfDAFA==} engines: {node: '>=18'} svg-tags@1.0.0: @@ -5531,11 +5528,11 @@ snapshots: '@dual-bundle/import-meta-resolve@4.1.0': {} - '@dvcol/common-utils@1.20.0': + '@dvcol/common-utils@1.21.2': dependencies: pretty-bytes: 6.1.1 - '@dvcol/eslint-plugin-presets@1.3.11(suyu6q4fzdqh3aytlan25ljjfa)': + '@dvcol/eslint-plugin-presets@1.3.11(z7cxgnttms2gl7huq66ofhf6ue)': dependencies: chalk: 4.1.2 dash-ast: 2.0.1 @@ -5558,9 +5555,9 @@ snapshots: '@typescript-eslint/parser': 7.18.0(eslint@8.57.0)(typescript@5.5.4) eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0) eslint-plugin-prettier: 5.2.1(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.3) - eslint-plugin-svelte: 2.46.1(eslint@8.57.0)(svelte@5.19.0) + eslint-plugin-svelte: 2.46.1(eslint@8.57.0)(svelte@5.19.3) eslint-plugin-vitest: 0.4.1(@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4)(vitest@3.0.2(@types/node@22.5.4)(jiti@1.21.0)(jsdom@25.0.1)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)) - svelte: 5.19.0 + svelte: 5.19.3 '@dvcol/stylelint-plugin-presets@2.1.2(postcss-html@0.36.0)(postcss-scss@4.0.9(postcss@8.5.1))(postcss@8.5.1)(prettier@3.3.3)(stylelint@16.9.0(typescript@5.5.4))': dependencies: @@ -5586,11 +5583,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@dvcol/svelte-simple-router@1.10.0(@types/node@22.5.4)(sass@1.83.4)(sugarss@2.0.0)(svelte@5.19.0)': + '@dvcol/svelte-simple-router@1.10.1(@types/node@22.5.4)(sass@1.83.4)(sugarss@2.0.0)(svelte@5.19.3)': dependencies: - '@dvcol/common-utils': 1.20.0 - '@dvcol/svelte-utils': 1.6.1(@types/node@22.5.4)(sass@1.83.4)(sugarss@2.0.0)(svelte@5.19.0) - svelte: 5.19.0 + '@dvcol/common-utils': 1.21.2 + '@dvcol/svelte-utils': 1.6.1(@types/node@22.5.4)(sass@1.83.4)(sugarss@2.0.0)(svelte@5.19.3) + svelte: 5.19.3 transitivePeerDependencies: - '@types/node' - less @@ -5601,10 +5598,10 @@ snapshots: - sugarss - terser - '@dvcol/svelte-utils@1.6.1(@types/node@22.5.4)(sass@1.83.4)(sugarss@2.0.0)(svelte@5.19.0)': + '@dvcol/svelte-utils@1.6.1(@types/node@22.5.4)(sass@1.83.4)(sugarss@2.0.0)(svelte@5.19.3)': dependencies: - '@dvcol/common-utils': 1.20.0 - svelte: 5.19.0 + '@dvcol/common-utils': 1.21.2 + svelte: 5.19.3 vite: 5.4.10(@types/node@22.5.4)(sass@1.83.4)(sugarss@2.0.0) transitivePeerDependencies: - '@types/node' @@ -6028,20 +6025,20 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.30.1': optional: true - '@skeletonlabs/floating-ui-svelte@0.3.9(svelte@5.19.0)': + '@skeletonlabs/floating-ui-svelte@0.3.9(svelte@5.19.3)': dependencies: '@floating-ui/dom': 1.6.13 '@floating-ui/utils': 0.2.9 - svelte: 5.19.0 + svelte: 5.19.3 - '@sveltejs/adapter-auto@4.0.0(@sveltejs/kit@2.16.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.0)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)))(svelte@5.19.0)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)))': + '@sveltejs/adapter-auto@4.0.0(@sveltejs/kit@2.16.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.3)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)))(svelte@5.19.3)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)))': dependencies: - '@sveltejs/kit': 2.16.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.0)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)))(svelte@5.19.0)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)) + '@sveltejs/kit': 2.16.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.3)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)))(svelte@5.19.3)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)) import-meta-resolve: 4.1.0 - '@sveltejs/kit@2.16.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.0)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)))(svelte@5.19.0)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0))': + '@sveltejs/kit@2.16.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.3)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)))(svelte@5.19.3)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0))': dependencies: - '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.19.0)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)) + '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.19.3)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)) '@types/cookie': 0.6.0 cookie: 0.6.0 devalue: 5.1.1 @@ -6053,37 +6050,37 @@ snapshots: sade: 1.8.1 set-cookie-parser: 2.7.0 sirv: 3.0.0 - svelte: 5.19.0 + svelte: 5.19.3 vite: 6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0) - '@sveltejs/package@2.3.7(svelte@5.19.0)(typescript@5.5.4)': + '@sveltejs/package@2.3.7(svelte@5.19.3)(typescript@5.5.4)': dependencies: chokidar: 4.0.1 kleur: 4.1.5 sade: 1.8.1 semver: 7.6.2 - svelte: 5.19.0 - svelte2tsx: 0.7.18(svelte@5.19.0)(typescript@5.5.4) + svelte: 5.19.3 + svelte2tsx: 0.7.18(svelte@5.19.3)(typescript@5.5.4) transitivePeerDependencies: - typescript - '@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.0)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)))(svelte@5.19.0)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0))': + '@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.3)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)))(svelte@5.19.3)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0))': dependencies: - '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.19.0)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)) + '@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.19.3)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)) debug: 4.4.0 - svelte: 5.19.0 + svelte: 5.19.3 vite: 6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.0)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0))': + '@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.3)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.0)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)))(svelte@5.19.0)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)) + '@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.3)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)))(svelte@5.19.3)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)) debug: 4.4.0 deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.17 - svelte: 5.19.0 + svelte: 5.19.3 vite: 6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0) vitefu: 1.0.5(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0)) transitivePeerDependencies: @@ -6110,10 +6107,10 @@ snapshots: lodash: 4.17.21 redent: 3.0.0 - '@testing-library/svelte@5.2.6(svelte@5.19.0)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0))(vitest@3.0.2(@types/node@22.5.4)(jiti@1.21.0)(jsdom@25.0.1)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0))': + '@testing-library/svelte@5.2.6(svelte@5.19.3)(vite@6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0))(vitest@3.0.2(@types/node@22.5.4)(jiti@1.21.0)(jsdom@25.0.1)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0))': dependencies: '@testing-library/dom': 10.4.0 - svelte: 5.19.0 + svelte: 5.19.3 optionalDependencies: vite: 6.0.7(@types/node@22.5.4)(jiti@1.21.0)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0) vitest: 3.0.2(@types/node@22.5.4)(jiti@1.21.0)(jsdom@25.0.1)(sass@1.83.4)(sugarss@2.0.0)(yaml@2.5.0) @@ -7398,7 +7395,7 @@ snapshots: optionalDependencies: eslint-config-prettier: 9.1.0(eslint@8.57.0) - eslint-plugin-svelte@2.46.1(eslint@8.57.0)(svelte@5.19.0): + eslint-plugin-svelte@2.46.1(eslint@8.57.0)(svelte@5.19.3): dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) '@jridgewell/sourcemap-codec': 1.5.0 @@ -7411,9 +7408,9 @@ snapshots: postcss-safe-parser: 6.0.0(postcss@8.5.1) postcss-selector-parser: 6.1.2 semver: 7.6.2 - svelte-eslint-parser: 0.43.0(svelte@5.19.0) + svelte-eslint-parser: 0.43.0(svelte@5.19.3) optionalDependencies: - svelte: 5.19.0 + svelte: 5.19.3 transitivePeerDependencies: - ts-node @@ -7489,8 +7486,6 @@ snapshots: transitivePeerDependencies: - supports-color - esm-env@1.2.1: {} - esm-env@1.2.2: {} espree@9.6.1: @@ -9165,10 +9160,10 @@ snapshots: dependencies: fast-diff: 1.3.0 - prettier-plugin-svelte@3.3.2(prettier@3.3.3)(svelte@5.19.0): + prettier-plugin-svelte@3.3.2(prettier@3.3.3)(svelte@5.19.3): dependencies: prettier: 3.3.3 - svelte: 5.19.0 + svelte: 5.19.3 prettier@3.3.3: {} @@ -9949,19 +9944,19 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - svelte-check@4.1.1(svelte@5.19.0)(typescript@5.5.4): + svelte-check@4.1.4(svelte@5.19.3)(typescript@5.5.4): dependencies: '@jridgewell/trace-mapping': 0.3.25 chokidar: 4.0.1 fdir: 6.3.0 - picocolors: 1.0.1 + picocolors: 1.1.1 sade: 1.8.1 - svelte: 5.19.0 + svelte: 5.19.3 typescript: 5.5.4 transitivePeerDependencies: - picomatch - svelte-eslint-parser@0.43.0(svelte@5.19.0): + svelte-eslint-parser@0.43.0(svelte@5.19.3): dependencies: eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 @@ -9969,11 +9964,11 @@ snapshots: postcss: 8.5.1 postcss-scss: 4.0.9(postcss@8.5.1) optionalDependencies: - svelte: 5.19.0 + svelte: 5.19.3 - svelte-preprocess@6.0.3(@babel/core@7.25.2)(postcss-load-config@3.1.4(postcss@8.5.1))(postcss@8.5.1)(sass@1.83.4)(sugarss@2.0.0)(svelte@5.19.0)(typescript@5.5.4): + svelte-preprocess@6.0.3(@babel/core@7.25.2)(postcss-load-config@3.1.4(postcss@8.5.1))(postcss@8.5.1)(sass@1.83.4)(sugarss@2.0.0)(svelte@5.19.3)(typescript@5.5.4): dependencies: - svelte: 5.19.0 + svelte: 5.19.3 optionalDependencies: '@babel/core': 7.25.2 postcss: 8.5.1 @@ -9982,14 +9977,14 @@ snapshots: sugarss: 2.0.0 typescript: 5.5.4 - svelte2tsx@0.7.18(svelte@5.19.0)(typescript@5.5.4): + svelte2tsx@0.7.18(svelte@5.19.3)(typescript@5.5.4): dependencies: dedent-js: 1.0.1 pascal-case: 3.1.2 - svelte: 5.19.0 + svelte: 5.19.3 typescript: 5.5.4 - svelte@5.19.0: + svelte@5.19.3: dependencies: '@ampproject/remapping': 2.3.0 '@jridgewell/sourcemap-codec': 1.5.0 @@ -9999,11 +9994,11 @@ snapshots: aria-query: 5.3.2 axobject-query: 4.1.0 clsx: 2.1.1 - esm-env: 1.2.1 + esm-env: 1.2.2 esrap: 1.4.3 is-reference: 3.0.3 locate-character: 3.0.0 - magic-string: 0.30.12 + magic-string: 0.30.17 zimmerframe: 1.1.2 svg-tags@1.0.0: {} diff --git a/src/lib/icons/IconList.svelte b/src/lib/icons/IconList.svelte new file mode 100644 index 0000000..a910a32 --- /dev/null +++ b/src/lib/icons/IconList.svelte @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/lib/list/NeoList.svelte b/src/lib/list/NeoList.svelte new file mode 100644 index 0000000..1e072be --- /dev/null +++ b/src/lib/list/NeoList.svelte @@ -0,0 +1,171 @@ + + +{#snippet loader()} + + {#if loading} +
  • + {#if customLoader} + {@render customLoader(context)} + {:else} + + {/if} +
  • + {/if} +{/snippet} + +{#snippet list()} + + {#each items as item, index (item.id ?? index)} + {#if item.render} + {@render item.render()} + {:else if customItem} + {@render customItem(item, index, context)} + {:else} + + {item.label ?? item.value} + + {/if} + {/each} +{/snippet} + +{@render children?.(context)} + + + {#if !empty} +
      + {@render list()} + {@render loader()} +
    + {:else if customEmpty} + {@render customEmpty(context)} + {:else} +
      + +
      + +
      No items
      +
      +
      +
    + {/if} +
    + + diff --git a/src/lib/list/neo-list.model.ts b/src/lib/list/neo-list.model.ts new file mode 100644 index 0000000..b6471d4 --- /dev/null +++ b/src/lib/list/neo-list.model.ts @@ -0,0 +1,46 @@ +import type { Snippet } from 'svelte'; +import type { Color } from '~/utils/colors.utils.js'; +import type { HTMLNeoBaseElement, HTMLRefProps } from '~/utils/html-element.utils.js'; + +export type NeoListItem = { + value: Value; + tag?: Tag; + id?: string | number; + label?: string; + color?: Color; + render?: Snippet; +} & HTMLNeoBaseElement; + +export type NeoListContext = { + // States + /** + * List items to display. + */ + items?: NeoListItem[]; + + /** + * If the list is currently loading additional items. + */ + loading?: boolean | number; + /** + * If the list should display a loading skeleton. + */ + skeleton?: boolean; +}; + +export type NeoListProps = { + // Snippets + item?: Snippet<[NeoListItem, number, NeoListContext]>; + empty?: Snippet<[NeoListContext]>; + loader?: Snippet<[NeoListContext]>; + children?: Snippet<[NeoListContext]>; + + // States + /** + * The HTML tag to use for the list. + * @default 'ul' + */ + tag?: Tag | keyof HTMLElementTagNameMap; +} & HTMLRefProps & + HTMLNeoBaseElement & + NeoListContext; diff --git a/src/lib/skeletons/NeoSkeletonContainer.svelte b/src/lib/skeletons/NeoSkeletonContainer.svelte index 0ce0211..0e6e7ef 100644 --- a/src/lib/skeletons/NeoSkeletonContainer.svelte +++ b/src/lib/skeletons/NeoSkeletonContainer.svelte @@ -43,8 +43,8 @@ const updateSize = () => { const rect = ref?.getBoundingClientRect(); - if (rect?.width) skeletonWidth = `${rect.width}px`; - if (rect?.height) skeletonHeight = `${rect.height}px`; + if (!width && rect?.width) skeletonWidth = `${rect.width}px`; + if (!height && rect?.height) skeletonHeight = `${rect.height}px`; }; $effect(() => { @@ -87,7 +87,7 @@ .neo-skeleton-container { display: flex; width: var(--neo-skeleton-content-width); - height: var(--neo-skeleton-content-height); + min-height: var(--neo-skeleton-content-height); } .neo-skeleton-content-container { diff --git a/src/lib/skeletons/NeoSkeletonText.svelte b/src/lib/skeletons/NeoSkeletonText.svelte index 20ad209..a4f2d0e 100644 --- a/src/lib/skeletons/NeoSkeletonText.svelte +++ b/src/lib/skeletons/NeoSkeletonText.svelte @@ -172,6 +172,7 @@ &.neo-title { width: 70%; height: var(--neo-skeleton-text-title-font-size, var(--neo-font-size-xl, 1.5rem)); + margin: 0; } } diff --git a/src/lib/styles/common/colors.scss b/src/lib/styles/common/colors.scss index cbb4942..3941a60 100644 --- a/src/lib/styles/common/colors.scss +++ b/src/lib/styles/common/colors.scss @@ -10,17 +10,23 @@ --neo-grey-dark: oklch(from var(--neo-grey) calc(l + 0.2) c h); --neo-blue: oklch(50% 0.302 264.206deg); --neo-blue-dark: oklch(from var(--neo-blue) calc(l + 0.4) c h); + --neo-purple-light: oklch(from var(--neo-purple) calc(l + 0.25) c h); + --neo-purple: oklch(50% 0.302 304.206deg); --neo-red-light: oklch(from var(--neo-red) calc(l + 0.25) c h); --neo-red: oklch(50% 0.302 26.206deg); + --neo-orange-light: oklch(from var(--neo-orange) calc(l + 0.15) c h); + --neo-orange: oklch(72% 0.177 65deg); --neo-green-light: oklch(from var(--neo-green) calc(l + 0.25) c h); --neo-green: oklch(52% 0.177 142.495deg); /** primary colors */ --neo-color-primary: var(--neo-blue); --neo-color-primary-50: oklch(from var(--neo-color-primary) l c h / 50%); + --neo-color-secondary: var(--neo-purple); --neo-color-error: var(--neo-red); --neo-color-error-50: oklch(from var(--neo-color-error) l c h / 50%); --neo-color-error-75: oklch(from var(--neo-color-error) l c h / 75%); + --neo-color-warning: var(--neo-orange); --neo-color-success: var(--neo-green); --neo-color-success-50: oklch(from var(--neo-color-success) l c h / 50%); @@ -89,11 +95,13 @@ /** dark primary colors */ --neo-dark-color-primary: var(--neo-blue-dark); --neo-dark-color-primary-50: oklch(from var(--neo-dark-color-primary) l c h / 50%); + --neo-dark-color-secondary: var(--neo-purple-light); --neo-dark-color-error: var(--neo-red-light); --neo-dark-color-error-50: oklch(from var(--neo-dark-color-error) l c h / 50%); --neo-dark-color-error-75: oklch(from var(--neo-dark-color-error) l c h / 75%); --neo-dark-color-success: var(--neo-green-light); --neo-dark-color-success-50: oklch(from var(--neo-dark-color-success) l c h / 50%); + --neo-dark-color-warning: var(--neo-orange-light); /********************* ** dark mode colors ** @@ -164,11 +172,13 @@ *********************/ --neo-color-primary: var(--neo-dark-color-primary); --neo-color-primary-50: var(--neo-dark-color-primary-50); + --neo-color-secondary: var(--neo-dark-color-secondary); --neo-color-error: var(--neo-dark-color-error); --neo-color-error-50: var(--neo-dark-color-error-50); --neo-color-error-75: var(--neo-dark-color-error-75); --neo-color-success: var(--neo-dark-color-success); --neo-color-success-50: var(--neo-dark-color-success-50); + --neo-color-warning: var(--neo-dark-color-warning); /********************* ** semantic colors ** diff --git a/src/lib/utils/colors.utils.ts b/src/lib/utils/colors.utils.ts new file mode 100644 index 0000000..7b88550 --- /dev/null +++ b/src/lib/utils/colors.utils.ts @@ -0,0 +1,22 @@ +export const Colors = { + Primary: 'primary', + Secondary: 'secondary', + Success: 'success', + Warning: 'warning', + Error: 'error', +} as const; + +export type Color = (typeof Colors)[keyof typeof Colors]; + +export const ColorVariables = { + [Colors.Primary]: '--neo-color-primary', + [Colors.Secondary]: '--neo-color-secondary', + [Colors.Success]: '--neo-color-success', + [Colors.Warning]: '--neo-color-warning', + [Colors.Error]: '--neo-color-error', +} as const; + +export const getColorVariable = (color?: Color): string | undefined => { + if (!color) return; + return `var(${ColorVariables[color]})`; +};