@foxui/social 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +20 -0
- package/dist/components/blog-entry/BlogEntry.svelte +80 -0
- package/dist/components/blog-entry/BlogEntry.svelte.d.ts +14 -0
- package/dist/components/blog-entry/index.d.ts +1 -0
- package/dist/components/blog-entry/index.js +1 -0
- package/dist/components/bluesky-login/BlueskyLogin.svelte +23 -0
- package/dist/components/bluesky-login/BlueskyLogin.svelte.d.ts +4 -0
- package/dist/components/bluesky-login/BlueskyLoginModal.svelte +141 -0
- package/dist/components/bluesky-login/BlueskyLoginModal.svelte.d.ts +9 -0
- package/dist/components/bluesky-login/index.d.ts +8 -0
- package/dist/components/bluesky-login/index.js +3 -0
- package/dist/components/bluesky-post/BlueskyPost.svelte +36 -0
- package/dist/components/bluesky-post/BlueskyPost.svelte.d.ts +10 -0
- package/dist/components/bluesky-post/index.d.ts +5 -0
- package/dist/components/bluesky-post/index.js +110 -0
- package/dist/components/chat/Chat.svelte +0 -0
- package/dist/components/chat/Chat.svelte.d.ts +26 -0
- package/dist/components/chat/ChatMessage.svelte +0 -0
- package/dist/components/chat/ChatMessage.svelte.d.ts +26 -0
- package/dist/components/chat/index.d.ts +1 -0
- package/dist/components/chat/index.js +1 -0
- package/dist/components/emoji-picker/EmojiPicker.svelte +91 -0
- package/dist/components/emoji-picker/EmojiPicker.svelte.d.ts +11 -0
- package/dist/components/emoji-picker/PopoverEmojiPicker.svelte +24 -0
- package/dist/components/emoji-picker/PopoverEmojiPicker.svelte.d.ts +11 -0
- package/dist/components/emoji-picker/emoji.d.ts +7 -0
- package/dist/components/emoji-picker/emoji.js +56 -0
- package/dist/components/emoji-picker/index.d.ts +2 -0
- package/dist/components/emoji-picker/index.js +2 -0
- package/dist/components/github-corner/GithubCorner.svelte +62 -0
- package/dist/components/github-corner/GithubCorner.svelte.d.ts +4 -0
- package/dist/components/github-corner/index.d.ts +1 -0
- package/dist/components/github-corner/index.js +1 -0
- package/dist/components/index.d.ts +12 -0
- package/dist/components/index.js +20 -0
- package/dist/components/nested-comments/Comment.svelte +151 -0
- package/dist/components/nested-comments/Comment.svelte.d.ts +9 -0
- package/dist/components/nested-comments/NestedComments.svelte +14 -0
- package/dist/components/nested-comments/NestedComments.svelte.d.ts +7 -0
- package/dist/components/nested-comments/index.d.ts +1 -0
- package/dist/components/nested-comments/index.js +1 -0
- package/dist/components/post/Post.svelte +294 -0
- package/dist/components/post/Post.svelte.d.ts +23 -0
- package/dist/components/post/PostAction.svelte +27 -0
- package/dist/components/post/PostAction.svelte.d.ts +9 -0
- package/dist/components/post/embeds/Embed.svelte +24 -0
- package/dist/components/post/embeds/Embed.svelte.d.ts +7 -0
- package/dist/components/post/embeds/External.svelte +39 -0
- package/dist/components/post/embeds/External.svelte.d.ts +7 -0
- package/dist/components/post/embeds/Images.svelte +38 -0
- package/dist/components/post/embeds/Images.svelte.d.ts +7 -0
- package/dist/components/post/embeds/Video.svelte +45 -0
- package/dist/components/post/embeds/Video.svelte.d.ts +7 -0
- package/dist/components/post/index.d.ts +63 -0
- package/dist/components/post/index.js +1 -0
- package/dist/components/social-icons/All.svelte +47 -0
- package/dist/components/social-icons/All.svelte.d.ts +12 -0
- package/dist/components/social-icons/Bluesky.svelte +37 -0
- package/dist/components/social-icons/Bluesky.svelte.d.ts +8 -0
- package/dist/components/social-icons/Discord.svelte +37 -0
- package/dist/components/social-icons/Discord.svelte.d.ts +8 -0
- package/dist/components/social-icons/Facebook.svelte +37 -0
- package/dist/components/social-icons/Facebook.svelte.d.ts +8 -0
- package/dist/components/social-icons/Github.svelte +38 -0
- package/dist/components/social-icons/Github.svelte.d.ts +8 -0
- package/dist/components/social-icons/Twitter.svelte +37 -0
- package/dist/components/social-icons/Twitter.svelte.d.ts +8 -0
- package/dist/components/social-icons/Youtube.svelte +36 -0
- package/dist/components/social-icons/Youtube.svelte.d.ts +8 -0
- package/dist/components/social-icons/index.d.ts +7 -0
- package/dist/components/social-icons/index.js +8 -0
- package/dist/components/star-rating/StarRating.svelte +104 -0
- package/dist/components/star-rating/StarRating.svelte.d.ts +13 -0
- package/dist/components/star-rating/index.d.ts +1 -0
- package/dist/components/star-rating/index.js +1 -0
- package/dist/components/swiper-cards/CardSwiper.svelte +235 -0
- package/dist/components/swiper-cards/CardSwiper.svelte.d.ts +18 -0
- package/dist/components/swiper-cards/index.d.ts +14 -0
- package/dist/components/swiper-cards/index.js +1 -0
- package/dist/components/user-profile/UserProfile.svelte +60 -0
- package/dist/components/user-profile/UserProfile.svelte.d.ts +13 -0
- package/dist/components/user-profile/index.d.ts +1 -0
- package/dist/components/user-profile/index.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/types.d.ts +1 -0
- package/package.json +79 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { WithElementRef, WithoutChildrenOrChild } from 'bits-ui';
|
|
3
|
+
import type { HTMLAnchorAttributes } from 'svelte/elements';
|
|
4
|
+
import { cn } from '@foxui/core';
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
class: className,
|
|
8
|
+
target = '_blank',
|
|
9
|
+
svgClasses,
|
|
10
|
+
...restProps
|
|
11
|
+
}: WithoutChildrenOrChild<WithElementRef<HTMLAnchorAttributes>> & {
|
|
12
|
+
svgClasses?: string;
|
|
13
|
+
} = $props();
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<a
|
|
17
|
+
{target}
|
|
18
|
+
class={cn(
|
|
19
|
+
'text-base-800 hover:text-accent-600 dark:text-base-300 dark:hover:text-accent-400 transition-colors',
|
|
20
|
+
className
|
|
21
|
+
)}
|
|
22
|
+
{...restProps}
|
|
23
|
+
>
|
|
24
|
+
<span class="sr-only">Bluesky</span>
|
|
25
|
+
|
|
26
|
+
<svg
|
|
27
|
+
role="img"
|
|
28
|
+
viewBox="0 0 24 24"
|
|
29
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
30
|
+
class={['size-6', svgClasses]}
|
|
31
|
+
aria-hidden="true"
|
|
32
|
+
fill="currentColor"
|
|
33
|
+
><path
|
|
34
|
+
d="M12 10.8c-1.087-2.114-4.046-6.053-6.798-7.995C2.566.944 1.561 1.266.902 1.565.139 1.908 0 3.08 0 3.768c0 .69.378 5.65.624 6.479.815 2.736 3.713 3.66 6.383 3.364.136-.02.275-.039.415-.056-.138.022-.276.04-.415.056-3.912.58-7.387 2.005-2.83 7.078 5.013 5.19 6.87-1.113 7.823-4.308.953 3.195 2.05 9.271 7.733 4.308 4.267-4.308 1.172-6.498-2.74-7.078a8.741 8.741 0 0 1-.415-.056c.14.017.279.036.415.056 2.67.297 5.568-.628 6.383-3.364.246-.828.624-5.79.624-6.478 0-.69-.139-1.861-.902-2.206-.659-.298-1.664-.62-4.3 1.24C16.046 4.748 13.087 8.687 12 10.8Z"
|
|
35
|
+
/></svg
|
|
36
|
+
>
|
|
37
|
+
</a>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { WithElementRef, WithoutChildrenOrChild } from 'bits-ui';
|
|
2
|
+
import type { HTMLAnchorAttributes } from 'svelte/elements';
|
|
3
|
+
type $$ComponentProps = WithoutChildrenOrChild<WithElementRef<HTMLAnchorAttributes>> & {
|
|
4
|
+
svgClasses?: string;
|
|
5
|
+
};
|
|
6
|
+
declare const Bluesky: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
7
|
+
type Bluesky = ReturnType<typeof Bluesky>;
|
|
8
|
+
export default Bluesky;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { WithElementRef, WithoutChildrenOrChild } from 'bits-ui';
|
|
3
|
+
import type { HTMLAnchorAttributes } from 'svelte/elements';
|
|
4
|
+
import { cn } from '@foxui/core';
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
class: className,
|
|
8
|
+
target = '_blank',
|
|
9
|
+
svgClasses,
|
|
10
|
+
...restProps
|
|
11
|
+
}: WithoutChildrenOrChild<WithElementRef<HTMLAnchorAttributes>> & {
|
|
12
|
+
svgClasses?: string;
|
|
13
|
+
} = $props();
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<a
|
|
17
|
+
{target}
|
|
18
|
+
class={cn(
|
|
19
|
+
'text-base-800 hover:text-accent-600 dark:text-base-300 dark:hover:text-accent-400 transition-colors',
|
|
20
|
+
className
|
|
21
|
+
)}
|
|
22
|
+
{...restProps}
|
|
23
|
+
>
|
|
24
|
+
<span class="sr-only">Discord</span>
|
|
25
|
+
|
|
26
|
+
<svg
|
|
27
|
+
role="img"
|
|
28
|
+
viewBox="0 0 24 24"
|
|
29
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
30
|
+
class={['size-6', svgClasses]}
|
|
31
|
+
fill="currentColor"
|
|
32
|
+
aria-hidden="true"
|
|
33
|
+
><path
|
|
34
|
+
d="M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z"
|
|
35
|
+
/></svg
|
|
36
|
+
>
|
|
37
|
+
</a>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { WithElementRef, WithoutChildrenOrChild } from 'bits-ui';
|
|
2
|
+
import type { HTMLAnchorAttributes } from 'svelte/elements';
|
|
3
|
+
type $$ComponentProps = WithoutChildrenOrChild<WithElementRef<HTMLAnchorAttributes>> & {
|
|
4
|
+
svgClasses?: string;
|
|
5
|
+
};
|
|
6
|
+
declare const Discord: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
7
|
+
type Discord = ReturnType<typeof Discord>;
|
|
8
|
+
export default Discord;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { WithElementRef, WithoutChildrenOrChild } from 'bits-ui';
|
|
3
|
+
import type { HTMLAnchorAttributes } from 'svelte/elements';
|
|
4
|
+
import { cn } from '@foxui/core';
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
class: className,
|
|
8
|
+
target = '_blank',
|
|
9
|
+
svgClasses,
|
|
10
|
+
...restProps
|
|
11
|
+
}: WithoutChildrenOrChild<WithElementRef<HTMLAnchorAttributes>> & {
|
|
12
|
+
svgClasses?: string;
|
|
13
|
+
} = $props();
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<a
|
|
17
|
+
{target}
|
|
18
|
+
class={cn(
|
|
19
|
+
'text-base-800 hover:text-accent-600 dark:text-base-300 dark:hover:text-accent-400 transition-colors',
|
|
20
|
+
className
|
|
21
|
+
)}
|
|
22
|
+
{...restProps}
|
|
23
|
+
>
|
|
24
|
+
<span class="sr-only">Facebook</span>
|
|
25
|
+
|
|
26
|
+
<svg
|
|
27
|
+
role="img"
|
|
28
|
+
viewBox="0 0 24 24"
|
|
29
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
30
|
+
class={['size-6', svgClasses]}
|
|
31
|
+
fill="currentColor"
|
|
32
|
+
aria-hidden="true"
|
|
33
|
+
><path
|
|
34
|
+
d="M9.101 23.691v-7.98H6.627v-3.667h2.474v-1.58c0-4.085 1.848-5.978 5.858-5.978.401 0 .955.042 1.468.103a8.68 8.68 0 0 1 1.141.195v3.325a8.623 8.623 0 0 0-.653-.036 26.805 26.805 0 0 0-.733-.009c-.707 0-1.259.096-1.675.309a1.686 1.686 0 0 0-.679.622c-.258.42-.374.995-.374 1.752v1.297h3.919l-.386 2.103-.287 1.564h-3.246v8.245C19.396 23.238 24 18.179 24 12.044c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.628 3.874 10.35 9.101 11.647Z"
|
|
35
|
+
/></svg
|
|
36
|
+
>
|
|
37
|
+
</a>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { WithElementRef, WithoutChildrenOrChild } from 'bits-ui';
|
|
2
|
+
import type { HTMLAnchorAttributes } from 'svelte/elements';
|
|
3
|
+
type $$ComponentProps = WithoutChildrenOrChild<WithElementRef<HTMLAnchorAttributes>> & {
|
|
4
|
+
svgClasses?: string;
|
|
5
|
+
};
|
|
6
|
+
declare const Facebook: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
7
|
+
type Facebook = ReturnType<typeof Facebook>;
|
|
8
|
+
export default Facebook;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { WithElementRef, WithoutChildrenOrChild } from 'bits-ui';
|
|
3
|
+
import type { HTMLAnchorAttributes } from 'svelte/elements';
|
|
4
|
+
import { cn } from '@foxui/core';
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
class: className,
|
|
8
|
+
target = '_blank',
|
|
9
|
+
svgClasses,
|
|
10
|
+
...restProps
|
|
11
|
+
}: WithoutChildrenOrChild<WithElementRef<HTMLAnchorAttributes>> & {
|
|
12
|
+
svgClasses?: string;
|
|
13
|
+
} = $props();
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<a
|
|
17
|
+
{target}
|
|
18
|
+
class={cn(
|
|
19
|
+
'text-base-800 hover:text-accent-600 dark:text-base-300 dark:hover:text-accent-400 rounded-2xl transition-colors',
|
|
20
|
+
'focus-visible:outline-base-900 dark:focus-visible:outline-base-100 focus-visible:outline-2 focus-visible:outline-offset-2',
|
|
21
|
+
className
|
|
22
|
+
)}
|
|
23
|
+
{...restProps}
|
|
24
|
+
>
|
|
25
|
+
<span class="sr-only">GitHub</span>
|
|
26
|
+
|
|
27
|
+
<svg
|
|
28
|
+
role="img"
|
|
29
|
+
viewBox="0 0 24 24"
|
|
30
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
31
|
+
fill="currentColor"
|
|
32
|
+
aria-hidden="true"
|
|
33
|
+
class={['size-5', svgClasses]}
|
|
34
|
+
><path
|
|
35
|
+
d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"
|
|
36
|
+
/></svg
|
|
37
|
+
>
|
|
38
|
+
</a>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { WithElementRef, WithoutChildrenOrChild } from 'bits-ui';
|
|
2
|
+
import type { HTMLAnchorAttributes } from 'svelte/elements';
|
|
3
|
+
type $$ComponentProps = WithoutChildrenOrChild<WithElementRef<HTMLAnchorAttributes>> & {
|
|
4
|
+
svgClasses?: string;
|
|
5
|
+
};
|
|
6
|
+
declare const Github: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
7
|
+
type Github = ReturnType<typeof Github>;
|
|
8
|
+
export default Github;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { WithElementRef, WithoutChildrenOrChild } from 'bits-ui';
|
|
3
|
+
import type { HTMLAnchorAttributes } from 'svelte/elements';
|
|
4
|
+
import { cn } from '@foxui/core';
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
class: className,
|
|
8
|
+
target = '_blank',
|
|
9
|
+
svgClasses,
|
|
10
|
+
...restProps
|
|
11
|
+
}: WithoutChildrenOrChild<WithElementRef<HTMLAnchorAttributes>> & {
|
|
12
|
+
svgClasses?: string;
|
|
13
|
+
} = $props();
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<a
|
|
17
|
+
{target}
|
|
18
|
+
class={cn(
|
|
19
|
+
'text-base-800 hover:text-accent-600 dark:text-base-300 dark:hover:text-accent-400 transition-colors',
|
|
20
|
+
className
|
|
21
|
+
)}
|
|
22
|
+
{...restProps}
|
|
23
|
+
>
|
|
24
|
+
<span class="sr-only">X</span>
|
|
25
|
+
|
|
26
|
+
<svg
|
|
27
|
+
role="img"
|
|
28
|
+
viewBox="0 0 24 24"
|
|
29
|
+
class={['size-6', svgClasses]}
|
|
30
|
+
fill="currentColor"
|
|
31
|
+
aria-hidden="true"
|
|
32
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
33
|
+
><title>X</title><path
|
|
34
|
+
d="M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z"
|
|
35
|
+
/></svg
|
|
36
|
+
>
|
|
37
|
+
</a>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { WithElementRef, WithoutChildrenOrChild } from 'bits-ui';
|
|
2
|
+
import type { HTMLAnchorAttributes } from 'svelte/elements';
|
|
3
|
+
type $$ComponentProps = WithoutChildrenOrChild<WithElementRef<HTMLAnchorAttributes>> & {
|
|
4
|
+
svgClasses?: string;
|
|
5
|
+
};
|
|
6
|
+
declare const Twitter: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
7
|
+
type Twitter = ReturnType<typeof Twitter>;
|
|
8
|
+
export default Twitter;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { WithElementRef, WithoutChildrenOrChild } from 'bits-ui';
|
|
3
|
+
import type { HTMLAnchorAttributes } from 'svelte/elements';
|
|
4
|
+
import { cn } from '@foxui/core';
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
class: className,
|
|
8
|
+
target = '_blank',
|
|
9
|
+
svgClasses,
|
|
10
|
+
...restProps
|
|
11
|
+
}: WithoutChildrenOrChild<WithElementRef<HTMLAnchorAttributes>> & {
|
|
12
|
+
svgClasses?: string;
|
|
13
|
+
} = $props();
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<a
|
|
17
|
+
{target}
|
|
18
|
+
class={cn(
|
|
19
|
+
'text-base-800 hover:text-accent-600 dark:text-base-300 dark:hover:text-accent-400 transition-colors',
|
|
20
|
+
className
|
|
21
|
+
)}
|
|
22
|
+
{...restProps}
|
|
23
|
+
>
|
|
24
|
+
<span class="sr-only">YouTube</span>
|
|
25
|
+
<svg
|
|
26
|
+
class={['size-7', svgClasses]}
|
|
27
|
+
fill="currentColor"
|
|
28
|
+
aria-hidden="true"
|
|
29
|
+
role="img"
|
|
30
|
+
viewBox="0 0 24 24"
|
|
31
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
32
|
+
><path
|
|
33
|
+
d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"
|
|
34
|
+
/></svg
|
|
35
|
+
>
|
|
36
|
+
</a>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { WithElementRef, WithoutChildrenOrChild } from 'bits-ui';
|
|
2
|
+
import type { HTMLAnchorAttributes } from 'svelte/elements';
|
|
3
|
+
type $$ComponentProps = WithoutChildrenOrChild<WithElementRef<HTMLAnchorAttributes>> & {
|
|
4
|
+
svgClasses?: string;
|
|
5
|
+
};
|
|
6
|
+
declare const Youtube: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
7
|
+
type Youtube = ReturnType<typeof Youtube>;
|
|
8
|
+
export default Youtube;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { default as SocialIcons } from './All.svelte';
|
|
2
|
+
export { default as Discord } from './Discord.svelte';
|
|
3
|
+
export { default as Github } from './Github.svelte';
|
|
4
|
+
export { default as Twitter } from './Twitter.svelte';
|
|
5
|
+
export { default as Youtube } from './Youtube.svelte';
|
|
6
|
+
export { default as Bluesky } from './Bluesky.svelte';
|
|
7
|
+
export { default as Facebook } from './Facebook.svelte';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// all icons from https://simpleicons.org/
|
|
2
|
+
export { default as SocialIcons } from './All.svelte';
|
|
3
|
+
export { default as Discord } from './Discord.svelte';
|
|
4
|
+
export { default as Github } from './Github.svelte';
|
|
5
|
+
export { default as Twitter } from './Twitter.svelte';
|
|
6
|
+
export { default as Youtube } from './Youtube.svelte';
|
|
7
|
+
export { default as Bluesky } from './Bluesky.svelte';
|
|
8
|
+
export { default as Facebook } from './Facebook.svelte';
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// todo convert to radio group
|
|
3
|
+
import { cn } from '@foxui/core';
|
|
4
|
+
import type { WithElementRef, WithoutChildrenOrChild } from 'bits-ui';
|
|
5
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
rating = $bindable(),
|
|
9
|
+
size = 'size-8',
|
|
10
|
+
changeable = true,
|
|
11
|
+
class: className,
|
|
12
|
+
ref = $bindable(null),
|
|
13
|
+
strokeWidth = 0.8,
|
|
14
|
+
buttonClasses,
|
|
15
|
+
svgClasses,
|
|
16
|
+
...restProps
|
|
17
|
+
}: WithElementRef<WithoutChildrenOrChild<HTMLAttributes<HTMLDivElement>>> & {
|
|
18
|
+
rating: number;
|
|
19
|
+
size?: string;
|
|
20
|
+
changeable?: boolean;
|
|
21
|
+
|
|
22
|
+
strokeWidth?: number;
|
|
23
|
+
|
|
24
|
+
buttonClasses?: string;
|
|
25
|
+
svgClasses?: string;
|
|
26
|
+
} = $props();
|
|
27
|
+
|
|
28
|
+
let hoverRating = $state(rating);
|
|
29
|
+
|
|
30
|
+
$effect(() => {
|
|
31
|
+
hoverRating = rating;
|
|
32
|
+
});
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<div class={cn('flex items-center', className)} {...restProps} bind:this={ref}>
|
|
36
|
+
{#if changeable}
|
|
37
|
+
{#each Array.from({ length: 5 }).map((_, i) => i + 1) as i}
|
|
38
|
+
<button
|
|
39
|
+
class={cn(
|
|
40
|
+
'group focus-visible:outline-base-900 dark:focus-visible:outline-base-100 cursor-pointer rounded-xl focus-visible:outline-2',
|
|
41
|
+
buttonClasses
|
|
42
|
+
)}
|
|
43
|
+
onclick={() => (rating = i)}
|
|
44
|
+
onfocus={() => (hoverRating = i)}
|
|
45
|
+
onblur={() => (hoverRating = rating)}
|
|
46
|
+
onmouseenter={() => (hoverRating = i)}
|
|
47
|
+
onmouseleave={() => (hoverRating = rating)}
|
|
48
|
+
>
|
|
49
|
+
<svg
|
|
50
|
+
class={cn(
|
|
51
|
+
size,
|
|
52
|
+
'shrink-0',
|
|
53
|
+
i > rating &&
|
|
54
|
+
i > hoverRating &&
|
|
55
|
+
'stroke-base-400 text-base-100 dark:stroke-base-700/70 dark:text-base-900',
|
|
56
|
+
i <= rating &&
|
|
57
|
+
i <= hoverRating &&
|
|
58
|
+
'stroke-accent-600 text-accent-400 dark:stroke-accent-500/80 dark:text-accent-500/40',
|
|
59
|
+
|
|
60
|
+
((i > rating && i <= hoverRating) || (i > hoverRating && i <= rating)) &&
|
|
61
|
+
'stroke-accent-600/50 text-accent-400/50 dark:stroke-accent-500/40 dark:text-accent-500/20',
|
|
62
|
+
svgClasses
|
|
63
|
+
)}
|
|
64
|
+
viewBox="0 0 24 24"
|
|
65
|
+
fill="currentColor"
|
|
66
|
+
aria-hidden="true"
|
|
67
|
+
stroke-width={strokeWidth}
|
|
68
|
+
data-slot="icon"
|
|
69
|
+
>
|
|
70
|
+
<path
|
|
71
|
+
fill-rule="evenodd"
|
|
72
|
+
d="M10.788 3.21c.448-1.077 1.976-1.077 2.424 0l2.082 5.006 5.404.434c1.164.093 1.636 1.545.749 2.305l-4.117 3.527 1.257 5.273c.271 1.136-.964 2.033-1.96 1.425L12 18.354 7.373 21.18c-.996.608-2.231-.29-1.96-1.425l1.257-5.273-4.117-3.527c-.887-.76-.415-2.212.749-2.305l5.404-.434 2.082-5.005Z"
|
|
73
|
+
clip-rule="evenodd"
|
|
74
|
+
/>
|
|
75
|
+
</svg>
|
|
76
|
+
|
|
77
|
+
<span class="sr-only">rate {i} stars</span>
|
|
78
|
+
</button>
|
|
79
|
+
{/each}
|
|
80
|
+
{:else}
|
|
81
|
+
{#each Array.from({ length: 5 }).map((_, i) => i + 1) as i}
|
|
82
|
+
<svg
|
|
83
|
+
class={cn(
|
|
84
|
+
size,
|
|
85
|
+
'stroke-base-400 text-base-100 dark:stroke-base-700 dark:text-base-800 shrink-0',
|
|
86
|
+
i <= rating &&
|
|
87
|
+
'stroke-accent-600 text-accent-400 dark:stroke-accent-500/80 dark:text-accent-500/50',
|
|
88
|
+
svgClasses
|
|
89
|
+
)}
|
|
90
|
+
viewBox="0 0 24 24"
|
|
91
|
+
fill="currentColor"
|
|
92
|
+
aria-hidden="true"
|
|
93
|
+
stroke-width={strokeWidth}
|
|
94
|
+
data-slot="icon"
|
|
95
|
+
>
|
|
96
|
+
<path
|
|
97
|
+
fill-rule="evenodd"
|
|
98
|
+
d="M10.788 3.21c.448-1.077 1.976-1.077 2.424 0l2.082 5.006 5.404.434c1.164.093 1.636 1.545.749 2.305l-4.117 3.527 1.257 5.273c.271 1.136-.964 2.033-1.96 1.425L12 18.354 7.373 21.18c-.996.608-2.231-.29-1.96-1.425l1.257-5.273-4.117-3.527c-.887-.76-.415-2.212.749-2.305l5.404-.434 2.082-5.005Z"
|
|
99
|
+
clip-rule="evenodd"
|
|
100
|
+
/>
|
|
101
|
+
</svg>
|
|
102
|
+
{/each}
|
|
103
|
+
{/if}
|
|
104
|
+
</div>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { WithElementRef, WithoutChildrenOrChild } from 'bits-ui';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
type $$ComponentProps = WithElementRef<WithoutChildrenOrChild<HTMLAttributes<HTMLDivElement>>> & {
|
|
4
|
+
rating: number;
|
|
5
|
+
size?: string;
|
|
6
|
+
changeable?: boolean;
|
|
7
|
+
strokeWidth?: number;
|
|
8
|
+
buttonClasses?: string;
|
|
9
|
+
svgClasses?: string;
|
|
10
|
+
};
|
|
11
|
+
declare const StarRating: import("svelte").Component<$$ComponentProps, {}, "ref" | "rating">;
|
|
12
|
+
type StarRating = ReturnType<typeof StarRating>;
|
|
13
|
+
export default StarRating;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as StarRating } from './StarRating.svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as StarRating } from './StarRating.svelte';
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// TODO: fix types
|
|
3
|
+
|
|
4
|
+
import { onMount, type Snippet } from 'svelte';
|
|
5
|
+
import { DragGesture, type FullGestureState } from '@use-gesture/vanilla';
|
|
6
|
+
import type { CardData, Direction, SwipeEventData } from '.';
|
|
7
|
+
import { Image } from '@foxui/core';
|
|
8
|
+
|
|
9
|
+
let {
|
|
10
|
+
card = DefaultCard,
|
|
11
|
+
cardData,
|
|
12
|
+
onswipe,
|
|
13
|
+
swipe = $bindable(),
|
|
14
|
+
|
|
15
|
+
minSwipeDistance = 0.5,
|
|
16
|
+
minSwipeVelocity = 0.5,
|
|
17
|
+
arrowKeys = true,
|
|
18
|
+
thresholdPassed = $bindable(0),
|
|
19
|
+
anchor = null,
|
|
20
|
+
rotate = true,
|
|
21
|
+
cardCount = 5
|
|
22
|
+
}: {
|
|
23
|
+
card?: Snippet<[CardData]>;
|
|
24
|
+
|
|
25
|
+
cardData: (index: number) => CardData;
|
|
26
|
+
onswipe?: (cardInfo: SwipeEventData) => void;
|
|
27
|
+
swipe?: (direction: Direction) => void;
|
|
28
|
+
|
|
29
|
+
minSwipeDistance?: number;
|
|
30
|
+
minSwipeVelocity?: number;
|
|
31
|
+
arrowKeys?: boolean;
|
|
32
|
+
thresholdPassed?: number;
|
|
33
|
+
anchor?: number | null;
|
|
34
|
+
rotate?: boolean;
|
|
35
|
+
cardCount?: number;
|
|
36
|
+
} = $props();
|
|
37
|
+
|
|
38
|
+
swipe = (direction: Direction = 'right') => {
|
|
39
|
+
if (thresholdPassed !== 0) return;
|
|
40
|
+
|
|
41
|
+
let dir = direction === 'left' ? -1 : 1;
|
|
42
|
+
|
|
43
|
+
if (!topCard) throw new Error('No top card found');
|
|
44
|
+
cardSwiped(topCard, [dir, 0.1], [dir, 1]);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
let container: HTMLElement;
|
|
48
|
+
|
|
49
|
+
let cardIndex = 0;
|
|
50
|
+
let topCard: HTMLElement | undefined = $state();
|
|
51
|
+
let topCardIndex = 0;
|
|
52
|
+
|
|
53
|
+
let currentZ = 100000;
|
|
54
|
+
|
|
55
|
+
let cards: HTMLElement[] = $state(new Array(cardCount));
|
|
56
|
+
let cardsData: CardData[] = $state([]);
|
|
57
|
+
|
|
58
|
+
onMount(() => {
|
|
59
|
+
for (let i = 0; i < cardCount; i++) {
|
|
60
|
+
cardsData.push(cardData(cardIndex++));
|
|
61
|
+
cards.push();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
let gestures: DragGesture[] = [];
|
|
65
|
+
|
|
66
|
+
cards.forEach((el) => {
|
|
67
|
+
if (!el) return;
|
|
68
|
+
|
|
69
|
+
el.style.zIndex = currentZ.toString();
|
|
70
|
+
currentZ--;
|
|
71
|
+
|
|
72
|
+
let gesture = new DragGesture(el, (state) => {
|
|
73
|
+
ondrag(el, state);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
gestures.push(gesture);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
topCardIndex = 0;
|
|
80
|
+
topCard = cards[topCardIndex];
|
|
81
|
+
|
|
82
|
+
container.classList.remove('hidden');
|
|
83
|
+
|
|
84
|
+
return () => {
|
|
85
|
+
gestures.forEach((gesture) => gesture.destroy());
|
|
86
|
+
};
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
const cardSwiped = (el: HTMLElement, velocity: [number, number], movement: [number, number]) => {
|
|
90
|
+
el.classList.add('transition-transform', 'duration-300');
|
|
91
|
+
let index = cards.indexOf(el);
|
|
92
|
+
|
|
93
|
+
let direction: Direction = movement[0] > 0 ? 'right' : 'left';
|
|
94
|
+
let data = cardsData[index];
|
|
95
|
+
|
|
96
|
+
onswipe?.({ direction, element: el, data, index: cardIndex - 2 });
|
|
97
|
+
|
|
98
|
+
thresholdPassed = movement[0] > 0 ? 1 : -1;
|
|
99
|
+
|
|
100
|
+
let moveOutWidth = document.body.clientWidth;
|
|
101
|
+
|
|
102
|
+
let endX = Math.max(Math.abs(velocity[0]) * moveOutWidth, moveOutWidth);
|
|
103
|
+
let toX = movement[0] > 0 ? endX : -endX;
|
|
104
|
+
let endY = Math.abs(velocity[1]) * moveOutWidth;
|
|
105
|
+
let toY = movement[1] > 0 ? endY : -endY;
|
|
106
|
+
|
|
107
|
+
let rotate = movement[0] * 0.03 * (movement[1] / 80);
|
|
108
|
+
|
|
109
|
+
el.style.transform = `translate(${toX}px, ${toY + movement[1]}px) rotate(${rotate}deg)`;
|
|
110
|
+
|
|
111
|
+
setTimeout(async () => {
|
|
112
|
+
thresholdPassed = 0;
|
|
113
|
+
|
|
114
|
+
cardsData[index] = cardData(cardIndex++);
|
|
115
|
+
|
|
116
|
+
// next card
|
|
117
|
+
topCardIndex = (topCardIndex + 1) % cardCount;
|
|
118
|
+
topCard = cards[topCardIndex];
|
|
119
|
+
|
|
120
|
+
currentZ--;
|
|
121
|
+
el.style.zIndex = currentZ.toString();
|
|
122
|
+
|
|
123
|
+
el.classList.remove('transition-transform', 'duration-300');
|
|
124
|
+
el.style.transform = '';
|
|
125
|
+
}, 350);
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const ondrag = (
|
|
129
|
+
el: HTMLElement,
|
|
130
|
+
state: Omit<FullGestureState<'drag'>, 'event'> & {
|
|
131
|
+
event: PointerEvent | MouseEvent | TouchEvent | KeyboardEvent;
|
|
132
|
+
}
|
|
133
|
+
) => {
|
|
134
|
+
let elWidth = el.offsetWidth;
|
|
135
|
+
|
|
136
|
+
if (state.active) {
|
|
137
|
+
let angle = state.movement[0] * 0.03 * (state.movement[1] / 80);
|
|
138
|
+
|
|
139
|
+
// fix movement on a curved path if anchor is set
|
|
140
|
+
if (anchor) {
|
|
141
|
+
let vec = [state.movement[0], state.movement[1] - anchor];
|
|
142
|
+
let len = Math.sqrt(vec[0] ** 2 + vec[1] ** 2);
|
|
143
|
+
vec = [(vec[0] / len) * anchor, (vec[1] / len) * anchor];
|
|
144
|
+
|
|
145
|
+
state.movement[0] = vec[0];
|
|
146
|
+
state.movement[1] = vec[1] + anchor;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
el.style.transform = `translate(${state.movement[0]}px, ${state.movement[1]}px)`;
|
|
150
|
+
|
|
151
|
+
if (rotate) {
|
|
152
|
+
el.style.transform += ` rotate(${angle}deg)`;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (Math.abs(state.movement[0]) / elWidth > minSwipeDistance) {
|
|
156
|
+
thresholdPassed = state.movement[0] > 0 ? 1 : -1;
|
|
157
|
+
} else {
|
|
158
|
+
thresholdPassed = 0;
|
|
159
|
+
}
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
// if dragging is finished
|
|
163
|
+
let keep =
|
|
164
|
+
Math.abs(state.movement[0]) / elWidth < minSwipeDistance &&
|
|
165
|
+
Math.abs(state.velocity[0]) < minSwipeVelocity;
|
|
166
|
+
|
|
167
|
+
if (keep) {
|
|
168
|
+
thresholdPassed = 0;
|
|
169
|
+
el.classList.add('transition-transform', 'duration-300');
|
|
170
|
+
el.style.transform = '';
|
|
171
|
+
setTimeout(() => {
|
|
172
|
+
el.classList.remove('transition-transform', 'duration-300');
|
|
173
|
+
}, 300);
|
|
174
|
+
} else {
|
|
175
|
+
cardSwiped(el, state.velocity, state.movement);
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
</script>
|
|
179
|
+
|
|
180
|
+
<svelte:body
|
|
181
|
+
onkeydown={(e) => {
|
|
182
|
+
if (!arrowKeys) return;
|
|
183
|
+
if (e.key === 'ArrowLeft') {
|
|
184
|
+
swipe('left');
|
|
185
|
+
} else if (e.key === 'ArrowRight') {
|
|
186
|
+
swipe('right');
|
|
187
|
+
}
|
|
188
|
+
}}
|
|
189
|
+
/>
|
|
190
|
+
|
|
191
|
+
{#snippet DefaultCard({ image, title, description }: CardData)}
|
|
192
|
+
<div
|
|
193
|
+
class="border-base-400 dark:border-base-600 bg-base-50 dark:bg-base-900 relative h-full w-full overflow-hidden rounded-2xl border"
|
|
194
|
+
>
|
|
195
|
+
{#key image}
|
|
196
|
+
{#if image}
|
|
197
|
+
<Image
|
|
198
|
+
containerClasses="absolute inset-0 h-full w-full rounded-2xl"
|
|
199
|
+
src={image}
|
|
200
|
+
alt={title ?? ''}
|
|
201
|
+
loading="eager"
|
|
202
|
+
class="h-full w-full object-cover"
|
|
203
|
+
/>
|
|
204
|
+
{/if}
|
|
205
|
+
{/key}
|
|
206
|
+
<div
|
|
207
|
+
class="from-base-50/80 dark:from-base-950/80 absolute inset-0 rounded-b-xl bg-gradient-to-t via-transparent"
|
|
208
|
+
></div>
|
|
209
|
+
<div class="absolute bottom-0 flex w-full justify-start px-3 py-16 sm:px-12">
|
|
210
|
+
<div class="flex flex-col">
|
|
211
|
+
<h3 class="text-base-900 dark:text-base-50 pb-2 text-3xl font-bold">{title}</h3>
|
|
212
|
+
<p class="text-base-800 dark:text-base-200 text-sm">{description}</p>
|
|
213
|
+
</div>
|
|
214
|
+
</div>
|
|
215
|
+
</div>
|
|
216
|
+
{/snippet}
|
|
217
|
+
|
|
218
|
+
<div class="isolate h-full w-full touch-none select-none">
|
|
219
|
+
<div class="relative z-0 hidden h-full w-full" bind:this={container}>
|
|
220
|
+
{#each cards as _, i}
|
|
221
|
+
<div
|
|
222
|
+
bind:this={cards[i]}
|
|
223
|
+
class="absolute h-full w-full cursor-grab touch-none overflow-hidden ease-in-out select-none"
|
|
224
|
+
>
|
|
225
|
+
{#if cardsData[i]}
|
|
226
|
+
{@render card({
|
|
227
|
+
image: cardsData[i].image,
|
|
228
|
+
title: cardsData[i].title,
|
|
229
|
+
description: cardsData[i].description
|
|
230
|
+
})}
|
|
231
|
+
{/if}
|
|
232
|
+
</div>
|
|
233
|
+
{/each}
|
|
234
|
+
</div>
|
|
235
|
+
</div>
|