Skip to content

Commit c95a788

Browse files
committed
feat(notification): adds notification content
1 parent c057316 commit c95a788

20 files changed

+1049
-95
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -255,9 +255,9 @@ See examples in the demo (code [here](https://github.com/dvcol/neo-svelte/tree/f
255255
- [x] fake typos
256256
- [x] random pauses
257257

258-
- [ ] Alerts
259-
- [ ] toast
260-
- [ ] rich notification
258+
- [x] Alerts
259+
- [x] toast
260+
- [x] rich notification
261261
- [ ] container
262262
- [x] transition
263263
- [ ] split/resizable

demo/components/DemoNotification.svelte

Lines changed: 66 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
<script lang="ts">
22
33
import type { NeoNotificationStackProps } from '~/floating/notification/neo-notification-stack.model';
4+
import type { NeoNotification } from '~/floating/notification/neo-notification.model';
45
56
import NeoButton from '~/buttons/NeoButton.svelte';
67
import NeoButtonGroup from '~/buttons/NeoButtonGroup.svelte';
78
import { NeoNotificationPlacements } from '~/floating/common/neo-placement.model.js';
89
import NeoNotificationStack from '~/floating/notification/NeoNotificationStack.svelte';
910
import NeoNumberStep from '~/inputs/NeoNumberStep.svelte';
1011
import NeoSelect from '~/inputs/NeoSelect.svelte';
11-
import { DefaultShadowElevation, MaxShadowElevation } from '~/utils/shadow.utils';
12+
import { MaxShadowElevation } from '~/utils/shadow.utils';
1213
1314
import { colorOptions } from '../utils/color.utils';
1415
import { positionOptions } from '../utils/placement.utils';
@@ -17,24 +18,31 @@
1718
1819
const container = $state<NeoNotificationStackProps>({
1920
placement: NeoNotificationPlacements.TopEnd,
20-
duration: 0,
21+
duration: 5000,
2122
expand: false,
22-
});
23-
24-
const options = $state({
25-
elevation: DefaultShadowElevation,
23+
draggable: true,
24+
swipeable: true,
25+
close: true,
26+
loading: false,
27+
elevation: 1,
2628
color: '',
29+
filled: false,
30+
tinted: false,
31+
rounded: false,
32+
borderless: false,
2733
});
28-
2934
let stack = $state<NeoNotificationStack>();
3035
31-
const pushNotification = () => {
36+
const pushNotification = (notif?: NeoNotification) => {
3237
if (!stack) return;
3338
(window as any).stack = (window as any).stack || [];
3439
(window as any).stack.push(stack.add({
35-
containerProps: { style: `height: ${5}rem; width: ${20}rem` },
36-
}),
37-
);
40+
title: `Item: ${new Date().toLocaleTimeString()}`,
41+
subtitle: 'Subtitle: this is a notification item',
42+
content: `This is a notification item created at ${new Date().toLocaleTimeString()}.
43+
You can customize it with various properties.`,
44+
...notif,
45+
}));
3846
};
3947
4048
</script>
@@ -46,7 +54,7 @@
4654
center
4755
bind:value={container.duration}
4856
min={0}
49-
max={10000}
57+
max={60000}
5058
defaultValue={0}
5159
step={1000}
5260
nullable={false}
@@ -69,14 +77,17 @@
6977
rounded
7078
glass
7179
/>
80+
</div>
81+
82+
<div class="row">
7283
<NeoNumberStep
7384
label="Elevation"
7485
placement="left"
7586
center
76-
bind:value={options.elevation}
87+
bind:value={container.elevation}
7788
min={0}
7889
max={MaxShadowElevation}
79-
defaultValue={DefaultShadowElevation}
90+
defaultValue={1}
8091
nullable={false}
8192
floating={false}
8293
groupProps={{ style: 'margin-left: 6rem' }}
@@ -89,9 +100,9 @@
89100
placeholder="Select color"
90101
placement="left"
91102
floating={false}
92-
color={options.color}
103+
color={container.color}
93104
size={10}
94-
bind:value={options.color}
105+
bind:value={container.color}
95106
containerProps={{ style: 'margin-left: 6rem' }}
96107
options={colorOptions}
97108
openOnFocus
@@ -103,6 +114,13 @@
103114
<div class="row">
104115
<NeoButtonGroup text rounded>
105116
<NeoButton toggle bind:checked={container.expand}>Expand</NeoButton>
117+
<NeoButton toggle bind:checked={container.draggable}>Draggable</NeoButton>
118+
<NeoButton toggle bind:checked={container.swipeable}>Swipeable</NeoButton>
119+
<NeoButton toggle bind:checked={container.close}>Close</NeoButton>
120+
<NeoButton toggle bind:checked={container.loading}>Loading</NeoButton>
121+
<NeoButton toggle bind:checked={container.tinted}>Tinted</NeoButton>
122+
<NeoButton toggle bind:checked={container.filled}>Filled</NeoButton>
123+
<NeoButton toggle bind:checked={container.rounded}>Rounded</NeoButton>
106124
<NeoButton onclick={stack?.clear}>Clear</NeoButton>
107125
</NeoButtonGroup>
108126
</div>
@@ -111,11 +129,39 @@
111129

112130
<section>
113131
<div class="row">
114-
<div class="column">
115-
<span class="label">Notification</span>
132+
<span class="label">Basic</span>
116133

117-
<NeoButton elevation="0" onclick={pushNotification}>Default</NeoButton>
118-
</div>
134+
<NeoButton elevation="0" onclick={() => pushNotification()}>Default</NeoButton>
135+
<NeoButton elevation="0" onclick={() => pushNotification({ type: 'info' })}>Info</NeoButton>
136+
<NeoButton elevation="0" onclick={() => pushNotification({ type: 'warning' })}>Warning</NeoButton>
137+
<NeoButton elevation="0" onclick={() => pushNotification({ type: 'error' })}>Error</NeoButton>
138+
<NeoButton elevation="0" onclick={() => pushNotification({ type: 'success' })}>Success</NeoButton>
139+
</div>
140+
141+
<div class="row">
142+
<span class="label">Advanced</span>
143+
144+
<NeoButton elevation="0" onclick={() => pushNotification({ title: undefined, subtitle: undefined })}>Compact</NeoButton>
145+
<NeoButton
146+
elevation="0"
147+
onclick={() => pushNotification({ actionProps: {
148+
label: 'Action',
149+
onclick: () => {
150+
return 'dismissed';
151+
},
152+
} })}
153+
>
154+
Action
155+
</NeoButton>
156+
<NeoButton
157+
elevation="0"
158+
onclick={() => pushNotification({
159+
progress: true,
160+
pauseOnHover: false,
161+
})}
162+
>
163+
Progress
164+
</NeoButton>
119165
</div>
120166
</section>
121167

@@ -133,10 +179,6 @@
133179
word-break: break-all;
134180
}
135181
136-
.column {
137-
@include flex.column($center: true, $gap: var(--neo-gap-lg), $flex: 0 1 auto);
138-
}
139-
140182
.row {
141183
@include flex.row($center: true, $gap: var(--neo-gap-xl), $flex: 0 1 auto);
142184

src/lib/buttons/NeoCloseButton.svelte

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
<script lang="ts">
2-
import type { NeoIconButtonProps } from '~/buttons/neo-icon-button.model.js';
2+
import type { NeoCloseButtonProps } from '~/buttons/neo-close-button.model.js';
33
44
import NeoButton from '~/buttons/NeoButton.svelte';
55
import NeoIconClose from '~/icons/NeoIconClose.svelte';
6+
import { getColorVariable } from '~/utils/index.js';
67
78
let {
89
// Button props
@@ -11,28 +12,52 @@
1112
hovered = $bindable(false),
1213
focused = $bindable(false),
1314
15+
// States
16+
hoverColor,
17+
size,
18+
1419
// Other Props
1520
iconProps,
1621
...rest
17-
}: NeoIconButtonProps = $props();
22+
}: NeoCloseButtonProps = $props();
1823
24+
const iconSize = $derived.by(() => {
25+
switch (size) {
26+
case 'sm':
27+
return 0.6875;
28+
case 'lg':
29+
return 1;
30+
default:
31+
return 0.875;
32+
}
33+
});
1934
</script>
2035

2136
{#snippet icon()}
22-
<NeoIconClose size="0.875rem" {...iconProps} />
37+
<NeoIconClose size="{iconSize}rem" {...iconProps} />
2338
{/snippet}
2439

25-
<div class="neo-close-button">
40+
<div
41+
data-size={size}
42+
class="neo-close-button"
43+
style:--neo-close-color={getColorVariable(hoverColor)}
44+
>
2645
<NeoButton bind:ref bind:checked bind:hovered bind:focused {icon} {...rest} />
2746
</div>
2847

2948
<style lang="scss">
3049
.neo-close-button {
3150
display: contents;
3251
33-
--neo-btn-text-color-hover: var(--neo-close-color-hover, rgb(255 0 0 / 75%));
52+
--neo-btn-text-color-hover: oklch(from var(--neo-close-color) l c h / 75%);
3453
--neo-btn-text-color-active: var(--neo-close-color, rgb(255 0 0));
3554
55+
&[data-size='sm'] {
56+
--neo-btn-padding-empty: var(--neo-btn-close-padding, var(--neo-gap-3xs, 0.3125rem));
57+
--neo-btn-padding: var(--neo-btn-close-padding, var(--neo-gap-3xs, 0.3125rem));
58+
--neo-btn-margin: var(--neo-btn-close-margin, var(--neo-gap-xxs, 0.5rem));
59+
}
60+
3661
> :global(.neo-button) {
3762
:global(.neo-icon) {
3863
transition: rotate 0.3s ease-out;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import type { NeoIconButtonProps } from '~/buttons/neo-icon-button.model.js';
2+
import type { Color } from '~/utils/colors.utils.js';
3+
4+
export const NeoCloseButtonSize = {
5+
Small: 'sm',
6+
Medium: 'md',
7+
Large: 'lg',
8+
} as const;
9+
10+
export type NeoCloseButtonSizes = (typeof NeoCloseButtonSize)[keyof typeof NeoCloseButtonSize];
11+
12+
export interface NeoCloseButtonProps extends NeoIconButtonProps {
13+
hoverColor?: Color | CSSStyleDeclaration['color'];
14+
size?: NeoCloseButtonSizes;
15+
}

0 commit comments

Comments
 (0)