Skip to content

Commit ad46ebf

Browse files
committed
feat(button-groups): wip groups
1 parent 6a33674 commit ad46ebf

File tree

14 files changed

+335
-61
lines changed

14 files changed

+335
-61
lines changed

README.md

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,24 @@
22
Neomorphic ui library for svelte 5
33

44
## TODO
5-
- buttons
6-
- toggle
7-
- skeleton
8-
- border loading
9-
- tags
10-
- badge
11-
- avatar
12-
- badge
135
- button groups
14-
- card
15-
- border loading
16-
- skeleton
17-
- images
18-
- videos
19-
- carousel
206
- navbar
7+
- card
8+
- border loading
9+
- skeleton
10+
- images
11+
- videos
12+
- carousel
13+
- avatar
14+
- badge
15+
- tags
16+
- badge
2117
- switch
2218
- loading
2319
- border loading
2420
- skeleton
2521
- radio
2622
- checkbox
27-
- tooltip
28-
- popconfirm
29-
- popselect
3023
- Inputs
3124
- validation
3225
- loading
@@ -46,12 +39,15 @@ Neomorphic ui library for svelte 5
4639
- time/date
4740
- floating label
4841

49-
5042
- Progress/Loading
5143
- bar
5244
- circle
5345
- border
5446
- background
47+
- tooltip
48+
- popconfirm
49+
- popselect
50+
5551
- Alerts
5652
- notification
5753
- simple message

demo/App.svelte

Lines changed: 48 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,40 @@
22
import '~/styles/reset.scss';
33
import '~/styles/theme.scss';
44
5-
import DemoButtons from './components/DemoButtons.svelte';
5+
import { wait } from '@dvcol/common-utils/common/promise';
6+
7+
import { RouterView } from '@dvcol/svelte-simple-router/components';
8+
import { fade } from 'svelte/transition';
9+
10+
import { router } from './router/router.js';
11+
12+
import { Route } from './router/routes';
13+
14+
import type { TransitionProps } from '@dvcol/svelte-simple-router/models';
615
716
import NeoButton from '~/buttons/NeoButton.svelte';
17+
import NeoButtonGroup from '~/buttons/NeoButtonGroup.svelte';
818
import IconMoon from '~/icons/IconMoon.svelte';
919
import IconSun from '~/icons/IconSun.svelte';
1020
11-
let transitionIn = $state(false);
12-
let transitionOut = $state(false);
13-
const onTransition = () => {
14-
transitionOut = true;
15-
setTimeout(() => {
16-
transitionOut = false;
17-
transitionIn = true;
18-
19-
setTimeout(() => {
20-
transitionIn = false;
21-
}, 750);
22-
}, 750);
21+
const transition: TransitionProps = {
22+
in: fade,
23+
out: fade,
24+
params: { in: { delay: 200, duration: 200 }, out: { duration: 200 } },
25+
skipFirst: true,
26+
};
27+
28+
const active = $derived(router.route?.name);
29+
let transitioning = $state(false);
30+
31+
const onChange = async () => {
32+
transitioning = true;
33+
await wait(150);
34+
};
35+
36+
const onLoaded = async () => {
37+
await wait(350);
38+
transitioning = false;
2339
};
2440
2541
let dark = $state(window.matchMedia('(prefers-color-scheme: dark)').matches);
@@ -31,11 +47,19 @@
3147
document.documentElement.setAttribute('theme', 'light');
3248
}
3349
});
50+
51+
const routes = [Route.Buttons, Route.ButtonGroups];
3452
</script>
3553

3654
<div class="container">
3755
<div class="row">
38-
<NeoButton onclick={onTransition}>transition</NeoButton>
56+
<NeoButtonGroup>
57+
{#each routes as route}
58+
<NeoButton checked={active === route} onclick={() => router.push({ name: route })}>
59+
{route}
60+
</NeoButton>
61+
{/each}
62+
</NeoButtonGroup>
3963
<NeoButton toggle bind:checked={dark}>
4064
{#snippet icon()}
4165
{#if dark}
@@ -48,9 +72,9 @@
4872
</NeoButton>
4973
</div>
5074

51-
<div class="row" class:transition-in={transitionIn} class:transition-out={transitionOut}>
52-
<DemoButtons />
53-
</div>
75+
<main class="row view" class:transition={transitioning}>
76+
<RouterView {router} {transition} {onChange} {onLoaded} />
77+
</main>
5478
</div>
5579

5680
<style lang="scss">
@@ -61,26 +85,19 @@
6185
@include flex.row($center: true, $gap: var(--gap-xl));
6286
}
6387
88+
.view {
89+
min-height: 70vh;
90+
}
91+
6492
.container {
6593
@include flex.column($gap: var(--gap-xl));
6694
6795
padding: 1rem;
6896
69-
:global(.transition-out *),
70-
:global(.transition-out *::before),
71-
:global(.transition-out *::after) {
97+
:global(.transition *),
98+
:global(.transition *::before),
99+
:global(.transition *::after) {
72100
box-shadow: var(--box-shadow-flat) !important;
73-
transition:
74-
all 0.5s ease,
75-
box-shadow 0.5s ease-in-out;
76-
}
77-
78-
:global(.transition-in *),
79-
:global(.transition-in *::before),
80-
:global(.transition-in *::after) {
81-
transition:
82-
all 0.5s ease,
83-
box-shadow 0.5s ease-in-out;
84101
}
85102
86103
:global(.rotate) {
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
<script lang="ts">
2+
import SphereBackdrop from '../utils/SphereBackdrop.svelte';
3+
4+
import NeoButton from '~/buttons/NeoButton.svelte';
5+
import NeoButtonGroup from '~/buttons/NeoButtonGroup.svelte';
6+
import IconAccount from '~/icons/IconAccount.svelte';
7+
8+
const onClick = (...args: any) => {
9+
console.info(...args);
10+
};
11+
12+
let loading = $state(false);
13+
const onLoading = (e: MouseEvent, checked?: boolean, duration = 5000) => {
14+
loading = !loading;
15+
setTimeout(() => {
16+
loading = !loading;
17+
}, duration);
18+
onClick(e);
19+
};
20+
21+
let skeleton = $state(false);
22+
const onSkeleton = (e: MouseEvent, checked?: boolean, duration = 5000) => {
23+
skeleton = !skeleton;
24+
setTimeout(() => {
25+
skeleton = !skeleton;
26+
}, duration);
27+
onClick(e);
28+
};
29+
</script>
30+
31+
{#snippet icon()}
32+
<IconAccount />
33+
{/snippet}
34+
35+
<div class="row">
36+
<div class="column">
37+
<span class="label">Default</span>
38+
<NeoButtonGroup>
39+
<NeoButton onclick={onClick}>Button</NeoButton>
40+
<NeoButton toggle onclick={onClick}>Toggle</NeoButton>
41+
<NeoButton disabled onclick={onClick}>Disabled</NeoButton>
42+
<NeoButton {loading} onclick={onLoading}>Loading</NeoButton>
43+
<NeoButton {loading} onclick={onLoading} {icon} />
44+
<NeoButton onclick={onClick} {icon}>Icon</NeoButton>
45+
<NeoButton reverse onclick={onClick} {icon}>Reversed</NeoButton>
46+
<NeoButton {loading} pulse onclick={onLoading}>Pulse</NeoButton>
47+
<NeoButton coalesce onclick={onClick}>Coalesce</NeoButton>
48+
<NeoButton {skeleton} onclick={onSkeleton}>Skeleton</NeoButton>
49+
</NeoButtonGroup>
50+
</div>
51+
52+
<div class="column">
53+
<span class="label">Flat</span>
54+
<NeoButtonGroup>
55+
<NeoButton flat onclick={onClick}>Button</NeoButton>
56+
<NeoButton flat toggle onclick={onClick}>Toggle</NeoButton>
57+
<NeoButton flat disabled onclick={onClick}>Disabled</NeoButton>
58+
<NeoButton flat {loading} onclick={onLoading}>Loading</NeoButton>
59+
<NeoButton flat {loading} onclick={onLoading} {icon} />
60+
<NeoButton flat onclick={onClick} {icon}>Icon</NeoButton>
61+
<NeoButton flat reverse onclick={onClick} {icon}>Reversed</NeoButton>
62+
<NeoButton flat {loading} pulse onclick={onLoading}>Pulse</NeoButton>
63+
<NeoButton flat coalesce onclick={onClick}>Coalesce</NeoButton>
64+
<NeoButton flat {skeleton} onclick={onSkeleton}>Skeleton</NeoButton>
65+
</NeoButtonGroup>
66+
</div>
67+
68+
<div class="column">
69+
<span class="label">Text</span>
70+
<NeoButtonGroup>
71+
<NeoButton text onclick={onClick}>Button</NeoButton>
72+
<NeoButton text toggle onclick={onClick}>Toggle</NeoButton>
73+
<NeoButton text disabled onclick={onClick}>Disabled</NeoButton>
74+
<NeoButton text {loading} onclick={onLoading}>Loading</NeoButton>
75+
<NeoButton text {loading} onclick={onLoading} {icon} />
76+
<NeoButton text onclick={onClick} {icon}>Icon</NeoButton>
77+
<NeoButton text reverse onclick={onClick} {icon}>Reversed</NeoButton>
78+
<NeoButton text {loading} pulse onclick={onLoading}>Pulse</NeoButton>
79+
<NeoButton text coalesce onclick={onClick}>Coalesce</NeoButton>
80+
<NeoButton text {skeleton} onclick={onSkeleton}>Skeleton</NeoButton>
81+
</NeoButtonGroup>
82+
</div>
83+
84+
<div class="column">
85+
<span class="label">Glass</span>
86+
<SphereBackdrop>
87+
<NeoButtonGroup>
88+
<NeoButton glass onclick={onClick}>Button</NeoButton>
89+
<NeoButton glass toggle onclick={onClick}>Toggle</NeoButton>
90+
<NeoButton glass disabled onclick={onClick}>Disabled</NeoButton>
91+
<NeoButton glass {loading} onclick={onLoading}>Loading</NeoButton>
92+
<NeoButton glass {loading} onclick={onLoading} {icon} />
93+
<NeoButton glass onclick={onClick} {icon}>Icon</NeoButton>
94+
<NeoButton glass reverse onclick={onClick} {icon}>Reversed</NeoButton>
95+
<NeoButton glass {loading} pulse onclick={onLoading}>Pulse</NeoButton>
96+
<NeoButton glass coalesce onclick={onClick}>Coalesce</NeoButton>
97+
<NeoButton glass {skeleton} onclick={onSkeleton}>Skeleton</NeoButton>
98+
</NeoButtonGroup>
99+
</SphereBackdrop>
100+
</div>
101+
</div>
102+
103+
<style lang="scss">
104+
@use 'src/lib/styles/common/flex' as flex;
105+
106+
.column {
107+
@include flex.column($center: true, $gap: var(--gap-lg));
108+
}
109+
110+
.row {
111+
@include flex.row($gap: var(--gap-xl));
112+
}
113+
114+
@media (width > 1550px) {
115+
.column {
116+
@include flex.row($gap: var(--gap-xxl));
117+
}
118+
119+
.row {
120+
@include flex.column($center: true, $gap: var(--gap-xl));
121+
}
122+
123+
.label {
124+
min-width: 4.5rem;
125+
}
126+
}
127+
</style>

demo/components/DemoButtons.svelte

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,20 +127,20 @@
127127
@use 'src/lib/styles/common/flex' as flex;
128128
129129
.column {
130-
@include flex.column($center: true, $gap: var(--gap-md));
130+
@include flex.column($center: true, $gap: var(--gap-lg));
131131
}
132132
133133
.row {
134-
@include flex.row;
134+
@include flex.row($gap: var(--gap-xl));
135135
}
136136
137137
@media (width > 1550px) {
138138
.column {
139-
@include flex.row($gap: var(--gap-xl));
139+
@include flex.row($gap: var(--gap-xxl));
140140
}
141141
142142
.row {
143-
@include flex.column($center: true, $gap: var(--gap-lg));
143+
@include flex.column($center: true, $gap: var(--gap-xl));
144144
}
145145
146146
.label {

demo/router/router.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { Router } from '@dvcol/svelte-simple-router';
2+
3+
import { options } from './routes.js';
4+
5+
export const router = new Router(options);

demo/router/routes.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import type { RouterOptions } from '@dvcol/svelte-simple-router/models';
2+
3+
export const Route = {
4+
Any: 'any' as const,
5+
Buttons: 'buttons' as const,
6+
ButtonGroups: 'button-groups' as const,
7+
} as const;
8+
9+
export type Routes = (typeof Route)[keyof typeof Route];
10+
11+
export const options: RouterOptions<Routes> = {
12+
hash: true,
13+
routes: [
14+
{
15+
name: Route.Buttons,
16+
path: '/buttons',
17+
component: () => import('../components/DemoButtons.svelte'),
18+
},
19+
{
20+
name: Route.ButtonGroups,
21+
path: '/buttons/groups',
22+
component: () => import('../components/DemoButtonGroups.svelte'),
23+
},
24+
{
25+
name: Route.Any,
26+
path: '*',
27+
redirect: {
28+
name: Route.Buttons,
29+
},
30+
},
31+
] as const,
32+
};

demo/utils/SphereBackdrop.svelte

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
let ref = $state<HTMLElement | null>(null);
77
const width = $derived(ref?.clientWidth ? `${ref?.clientWidth}px` : '200%');
88
const height = $derived(ref?.clientHeight ? `${ref?.clientHeight}px` : '100%');
9-
10-
$inspect(height);
119
</script>
1210

1311
<div bind:this={ref} class="sphere">

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
"@commitlint/config-conventional": "^19.4.1",
8989
"@dvcol/eslint-plugin-presets": "^1.3.11",
9090
"@dvcol/stylelint-plugin-presets": "^2.1.2",
91+
"@dvcol/svelte-simple-router": "^1.7.0",
9192
"@sveltejs/adapter-auto": "^3.2.5",
9293
"@sveltejs/kit": "^2.7.4",
9394
"@sveltejs/package": "^2.3.7",

0 commit comments

Comments
 (0)