Skip to content

Commit 548335e

Browse files
committed
feat: timeline
1 parent f8ba8cc commit 548335e

File tree

13 files changed

+482
-3
lines changed

13 files changed

+482
-3
lines changed

.changeset/fuzzy-geckos-draw.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte-5-ui-lib': patch
3+
---
4+
5+
feat: timeline

src/lib/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export * from './skeleton';
2828
export * from './spinner';
2929
export * from './tab';
3030
export * from './table';
31+
export * from './timeline'
3132
export * from './toast';
3233
export * from './toolbar';
3334
export * from './utils';

src/lib/pagination/Pagination.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
{/if}
4444
{#each pages as { name, href, active }}
4545
<li>
46-
<PaginationItem {size} {active} {href} {...attributes}>
46+
<PaginationItem {size} {active} {href} >
4747
{name}
4848
</PaginationItem>
4949
</li>

src/lib/timeline/Activity.svelte

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<script lang="ts">
2+
import { type ActivityProps as Props, activity } from './index';
3+
4+
let { children, class: className, ...attributes }: Props = $props();
5+
const base = activity({ class: className });
6+
</script>
7+
8+
<ol class={base} {...attributes}>
9+
{@render children()}
10+
</ol>
11+
12+
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<script lang="ts">
2+
import { type ActivityItemProps as Props, activityitem } from './index';
3+
4+
let { activities, liClass, spanClass, imgClass, outerDivClass, innerDivClass, timeClass, titleClass, textClass, ...attributes }: Props = $props();
5+
6+
const { li, span, img, outerDiv, innerDiv, time, title, text } = $derived(activityitem());
7+
</script>
8+
9+
{#each activities as { name, date, src, alt, activity }}
10+
<li class={li({ class: liClass })} {...attributes}>
11+
<span class={span({ class: spanClass })}>
12+
<img class={img({ class: imgClass })} {src} {alt} />
13+
</span>
14+
<div class={outerDiv({ class: outerDivClass })}>
15+
<div class={innerDiv({ class: innerDivClass })}>
16+
<time class={time({ class: timeClass })}>{date}</time>
17+
<div class={title({ class: titleClass })}>
18+
{@html name}
19+
</div>
20+
</div>
21+
{#if activity}
22+
<div class={text({ class: textClass })}>
23+
{@html activity}
24+
</div>
25+
{/if}
26+
</div>
27+
</li>
28+
{/each}
29+

src/lib/timeline/Group.svelte

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<script lang="ts">
2+
import { type GroupProps as Props, group } from '.';
3+
4+
let { children, divClass, timeClass, date, olClass, ...attributes }: Props = $props();
5+
const { div, time, ol } = $derived(group());
6+
</script>
7+
8+
<div class={div({ class: divClass })}>
9+
<time class={time({ class: timeClass })}>{date}</time>
10+
<ol class={ol({ class: olClass })} {...attributes}>
11+
{@render children()}
12+
</ol>
13+
</div>

src/lib/timeline/GroupItem.svelte

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<script lang="ts">
2+
import { type GroupItemProps as Props, groupitem} from '.';
3+
4+
let { timelines, aClass, imgClass, divClass, titleClass, spanClass, ...attributes }: Props = $props();
5+
6+
const { a, img, div, title, span } = $derived(groupitem());
7+
</script>
8+
9+
{#each timelines as { name, src, alt, isPrivate, href, comment }}
10+
<li>
11+
<a {href} class={a({ class: aClass })}>
12+
<img class={img({ class: imgClass })} {src} {alt} />
13+
<div class={div({ class: divClass })}>
14+
<div class={title({ class: titleClass })}>
15+
{@html name}
16+
</div>
17+
{#if comment}
18+
<div class="text-sm font-normal">{comment}</div>
19+
{/if}
20+
21+
<span class={span({ class: spanClass })}>
22+
{#if isPrivate}
23+
<svg class="me-1 w-3 h-3" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
24+
<path fill-rule="evenodd" d="M3.707 2.293a1 1 0 00-1.414 1.414l14 14a1 1 0 001.414-1.414l-1.473-1.473A10.014 10.014 0 0019.542 10C18.268 5.943 14.478 3 10 3a9.958 9.958 0 00-4.512 1.074l-1.78-1.781zm4.261 4.26l1.514 1.515a2.003 2.003 0 012.45 2.45l1.514 1.514a4 4 0 00-5.478-5.478z" clip-rule="evenodd" />
25+
<path d="M12.454 16.697L9.75 13.992a4 4 0 01-3.742-3.741L2.335 6.578A9.98 9.98 0 00.458 10c1.274 4.057 5.065 7 9.542 7 .847 0 1.669-.105 2.454-.303z" />
26+
</svg>
27+
Private
28+
{:else}
29+
<svg class="me-1 w-3 h-3" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
30+
<path fill-rule="evenodd" d="M4.083 9h1.946c.089-1.546.383-2.97.837-4.118A6.004 6.004 0 004.083 9zM10 2a8 8 0 100 16 8 8 0 000-16zm0 2c-.076 0-.232.032-.465.262-.238.234-.497.623-.737 1.182-.389.907-.673 2.142-.766 3.556h3.936c-.093-1.414-.377-2.649-.766-3.556-.24-.56-.5-.948-.737-1.182C10.232 4.032 10.076 4 10 4zm3.971 5c-.089-1.546-.383-2.97-.837-4.118A6.004 6.004 0 0115.917 9h-1.946zm-2.003 2H8.032c.093 1.414.377 2.649.766 3.556.24.56.5.948.737 1.182.233.23.389.262.465.262.076 0 .232-.032.465-.262.238-.234.498-.623.737-1.182.389-.907.673-2.142.766-3.556zm1.166 4.118c.454-1.147.748-2.572.837-4.118h1.946a6.004 6.004 0 01-2.783 4.118zm-6.268 0C6.412 13.97 6.118 12.546 6.03 11H4.083a6.004 6.004 0 002.783 4.118z" clip-rule="evenodd" />
31+
</svg>
32+
Public
33+
{/if}
34+
</span>
35+
</div>
36+
</a>
37+
</li>
38+
{/each}

src/lib/timeline/Timeline.svelte

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<script lang="ts">
2+
import { setContext } from 'svelte';
3+
import { type TimelineProps as Props, timeline } from '.';
4+
5+
let { children, order = 'default', class: className, ...attributes }: Props = $props();
6+
7+
setContext('order', order);
8+
const olCls = $derived(timeline({ order, className }));
9+
</script>
10+
11+
<ol class={olCls} {...attributes}>
12+
{@render children()}
13+
</ol>
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<script lang="ts">
2+
import { getContext } from 'svelte';
3+
import { type TimelineItemProps as Props, timelineitem } from '.';
4+
5+
let { children, orientationSlot, title, date, svgClass, liClass, divClass, timeClass, h3Class, ...attributes }: Props = $props();
6+
let order: 'default' | 'vertical' | 'horizontal' | 'activity' | 'group' = getContext('order');
7+
8+
const { li, div, time, h3, svg } = $derived(timelineitem({ order }));
9+
</script>
10+
11+
<li class={li({ class: liClass})} {...attributes}>
12+
<div class={div({ class: divClass })}></div>
13+
{#if order !== 'default'}
14+
{#if orientationSlot && (order === 'vertical' || order === 'horizontal')}
15+
{@render orientationSlot()}
16+
{:else}
17+
<svg aria-hidden="true" class={svg({ class: svgClass })} fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
18+
<path fill-rule="evenodd" d="M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1zm0 5a1 1 0 000 2h8a1 1 0 100-2H6z" clip-rule="evenodd" />
19+
</svg>
20+
{/if}
21+
{:else if date}
22+
<time class={time({ class: timeClass })}>{date}</time>
23+
{/if}
24+
25+
{#if title}
26+
<h3 class={h3({ class: h3Class })}>
27+
{title}
28+
</h3>
29+
{/if}
30+
31+
{#if order !== 'default'}
32+
{#if date}
33+
<time class={time({ class: timeClass })}>{date}</time>
34+
{/if}
35+
{/if}
36+
37+
{@render children()}
38+
</li>

src/lib/timeline/index.ts

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import Activity from "./Activity.svelte";
2+
import ActivityItem from "./ActivityItem.svelte";
3+
import Group from "./Group.svelte";
4+
import GroupItem from "./GroupItem.svelte";
5+
import Timeline from "./Timeline.svelte";
6+
import TimelineItem from "./TimelineItem.svelte";
7+
import { activity, activityitem, group, groupitem, timeline, timelineitem } from './theme';
8+
import type { HTMLOlAttributes, HTMLLiAttributes } from 'svelte/elements';
9+
import type { Snippet } from 'svelte';
10+
11+
interface ActivityType {
12+
name: HTMLElement | string;
13+
date: Date | string;
14+
src: string;
15+
alt: string;
16+
activity?: HTMLElement | string;
17+
}
18+
19+
interface GroupTimelineType {
20+
name: string | HTMLElement;
21+
src: string;
22+
alt: string;
23+
href?: string;
24+
isPrivate?: boolean;
25+
comment?: string | HTMLElement;
26+
}
27+
28+
interface ActivityProps extends HTMLOlAttributes{
29+
children: Snippet;
30+
}
31+
32+
interface ActivityItemProps extends HTMLLiAttributes{
33+
activities: ActivityType[];
34+
liClass?: string;
35+
spanClass?: string;
36+
imgClass?: string;
37+
outerDivClass?: string;
38+
innerDivClass?: string;
39+
timeClass?: string;
40+
titleClass?: string;
41+
textClass?: string;
42+
}
43+
44+
interface GroupProps extends HTMLOlAttributes {
45+
children: Snippet;
46+
divClass?: string;
47+
timeClass?: string;
48+
date?: Date | string;
49+
olClass?: string;
50+
}
51+
52+
interface GroupItemProps extends HTMLLiAttributes{
53+
timelines: GroupTimelineType[];
54+
aClass?: string;
55+
imgClass?: string;
56+
divClass?: string;
57+
titleClass?: string;
58+
spanClass?: string;
59+
}
60+
61+
interface TimelineProps extends HTMLOlAttributes{
62+
children: Snippet;
63+
order?: 'default' | 'vertical' | 'horizontal' | 'activity' | 'group';
64+
}
65+
66+
interface TimelineItemProps extends HTMLLiAttributes{
67+
children: Snippet;
68+
orientationSlot?: Snippet;
69+
title: string;
70+
date: string;
71+
svgClass?: string;
72+
liClass?: string;
73+
divClass?: string;
74+
timeClass?: string;
75+
h3Class?: string;
76+
}
77+
78+
export {
79+
Activity,
80+
ActivityItem,
81+
Group,
82+
GroupItem,
83+
Timeline,
84+
TimelineItem,
85+
activity, activityitem, group, groupitem, timeline, timelineitem,
86+
type ActivityType, type ActivityProps, type ActivityItemProps, type GroupTimelineType, type GroupProps, type GroupItemProps, type TimelineProps, type TimelineItemProps
87+
}

0 commit comments

Comments
 (0)