urpanels-ui-pack 0.0.2
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/README.md +37 -0
- package/dist/Button/Button.svelte +76 -0
- package/dist/Button/Button.svelte.d.ts +13 -0
- package/dist/Button/index.d.ts +1 -0
- package/dist/Button/index.js +1 -0
- package/dist/InfoCard/InfoCard.svelte +227 -0
- package/dist/InfoCard/InfoCard.svelte.d.ts +4 -0
- package/dist/InfoCard/InfoCard.types.d.ts +56 -0
- package/dist/InfoCard/InfoCard.types.js +1 -0
- package/dist/InfoCard/index.d.ts +2 -0
- package/dist/InfoCard/index.js +1 -0
- package/dist/LoadingSpinner/LoadingSpinner.svelte +3 -0
- package/dist/LoadingSpinner/LoadingSpinner.svelte.d.ts +26 -0
- package/dist/LoadingSpinner/index.d.ts +1 -0
- package/dist/LoadingSpinner/index.js +1 -0
- package/dist/Modal/Modal.svelte +122 -0
- package/dist/Modal/Modal.svelte.d.ts +39 -0
- package/dist/Modal/index.d.ts +1 -0
- package/dist/Modal/index.js +1 -0
- package/dist/PageLayout/ActionButton.svelte +26 -0
- package/dist/PageLayout/ActionButton.svelte.d.ts +8 -0
- package/dist/PageLayout/PageContent.svelte +19 -0
- package/dist/PageLayout/PageContent.svelte.d.ts +8 -0
- package/dist/PageLayout/PageHeader.svelte +29 -0
- package/dist/PageLayout/PageHeader.svelte.d.ts +9 -0
- package/dist/PageLayout/SearchBar.svelte +25 -0
- package/dist/PageLayout/SearchBar.svelte.d.ts +8 -0
- package/dist/PageLayout/ViewToggle.svelte +53 -0
- package/dist/PageLayout/ViewToggle.svelte.d.ts +8 -0
- package/dist/PageLayout/index.d.ts +5 -0
- package/dist/PageLayout/index.js +5 -0
- package/dist/Pagination/Pagination.svelte +96 -0
- package/dist/Pagination/Pagination.svelte.d.ts +4 -0
- package/dist/Pagination/Pagination.types.d.ts +11 -0
- package/dist/Pagination/Pagination.types.js +1 -0
- package/dist/Pagination/index.d.ts +2 -0
- package/dist/Pagination/index.js +1 -0
- package/dist/RichTextEditor/RichTextEditor.svelte +575 -0
- package/dist/RichTextEditor/RichTextEditor.svelte.d.ts +10 -0
- package/dist/RichTextEditor/index.d.ts +1 -0
- package/dist/RichTextEditor/index.js +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +12 -0
- package/dist/sections/ArticlesGrid/ArticlesGrid.svelte +201 -0
- package/dist/sections/ArticlesGrid/ArticlesGrid.svelte.d.ts +31 -0
- package/dist/sections/ArticlesGrid/README.md +229 -0
- package/dist/sections/ArticlesGrid/index.d.ts +2 -0
- package/dist/sections/ArticlesGrid/index.js +1 -0
- package/dist/sections/FeaturedGalleryGrid/FeaturedGalleryGrid.svelte +118 -0
- package/dist/sections/FeaturedGalleryGrid/FeaturedGalleryGrid.svelte.d.ts +21 -0
- package/dist/sections/FeaturedGalleryGrid/README.md +270 -0
- package/dist/sections/FeaturedGalleryGrid/index.d.ts +2 -0
- package/dist/sections/FeaturedGalleryGrid/index.js +1 -0
- package/dist/sections/HeroCarousel/HeroCarousel.svelte +318 -0
- package/dist/sections/HeroCarousel/HeroCarousel.svelte.d.ts +23 -0
- package/dist/sections/HeroCarousel/index.d.ts +1 -0
- package/dist/sections/HeroCarousel/index.js +1 -0
- package/dist/sections/index.d.ts +5 -0
- package/dist/sections/index.js +3 -0
- package/dist/utils/translations.svelte.d.ts +37 -0
- package/dist/utils/translations.svelte.js +67 -0
- package/package.json +47 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import LoadingSpinner from '../LoadingSpinner/LoadingSpinner.svelte';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
children: Snippet;
|
|
7
|
+
isLoading?: boolean;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
let { children, isLoading = false }: Props = $props();
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<div class="px-4 sm:px-6 pb-6">
|
|
14
|
+
{#if isLoading}
|
|
15
|
+
<LoadingSpinner />
|
|
16
|
+
{:else}
|
|
17
|
+
{@render children()}
|
|
18
|
+
{/if}
|
|
19
|
+
</div>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
title: string;
|
|
6
|
+
actions?: Snippet;
|
|
7
|
+
search?: Snippet;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
let { title, actions, search }: Props = $props();
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<div class="sticky top-0 z-20 bg-white px-4 sm:px-6 py-3 mb-4">
|
|
14
|
+
<div class="flex items-center justify-between">
|
|
15
|
+
<h1 class="text-2xl font-bold">{title}</h1>
|
|
16
|
+
|
|
17
|
+
{#if actions}
|
|
18
|
+
<div class="flex items-center gap-4">
|
|
19
|
+
{@render actions()}
|
|
20
|
+
</div>
|
|
21
|
+
{/if}
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
{#if search}
|
|
25
|
+
<div class="mt-3">
|
|
26
|
+
{@render search()}
|
|
27
|
+
</div>
|
|
28
|
+
{/if}
|
|
29
|
+
</div>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
title: string;
|
|
4
|
+
actions?: Snippet;
|
|
5
|
+
search?: Snippet;
|
|
6
|
+
}
|
|
7
|
+
declare const PageHeader: import("svelte").Component<Props, {}, "">;
|
|
8
|
+
type PageHeader = ReturnType<typeof PageHeader>;
|
|
9
|
+
export default PageHeader;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
interface Props {
|
|
3
|
+
placeholder?: string;
|
|
4
|
+
value?: string;
|
|
5
|
+
oninput?: (e: Event) => void;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
let { placeholder = "Ara...", value = $bindable(""), oninput }: Props = $props();
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<label class="relative block">
|
|
12
|
+
<span class="sr-only">Ara</span>
|
|
13
|
+
<input
|
|
14
|
+
type="search"
|
|
15
|
+
{placeholder}
|
|
16
|
+
class="w-full rounded-full border border-gray-200 bg-gray-50 px-4 py-2 pr-10 text-sm placeholder-gray-400 focus:border-blue-400 focus:bg-white focus:ring-1 focus:ring-blue-200"
|
|
17
|
+
bind:value
|
|
18
|
+
{oninput}
|
|
19
|
+
/>
|
|
20
|
+
<div class="pointer-events-none absolute right-3 top-1/2 -translate-y-1/2 text-gray-400">
|
|
21
|
+
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
|
22
|
+
<path fill-rule="evenodd" d="M12.9 14.32a8 8 0 111.414-1.414l3.386 3.386a1 1 0 01-1.414 1.414l-3.386-3.386zM8 14a6 6 0 100-12 6 6 0 000 12z" clip-rule="evenodd" />
|
|
23
|
+
</svg>
|
|
24
|
+
</div>
|
|
25
|
+
</label>
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { t } from '../utils/translations.svelte';
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
mode?: 'card-table' | 'daily-weekly';
|
|
6
|
+
isSecondOption?: boolean;
|
|
7
|
+
onToggle?: (isSecondOption: boolean) => void;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
let { mode = 'card-table', isSecondOption = $bindable(false), onToggle }: Props = $props();
|
|
11
|
+
|
|
12
|
+
const labels = $derived({
|
|
13
|
+
'card-table': { first: t('common.cardView'), second: t('common.tableView') },
|
|
14
|
+
'daily-weekly': { first: t('common.dailyView'), second: t('common.weeklyView') }
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const icons = {
|
|
18
|
+
'card-table': {
|
|
19
|
+
first: 'M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z',
|
|
20
|
+
second: 'M4 6h16M4 10h16M4 14h16M4 18h16'
|
|
21
|
+
},
|
|
22
|
+
'daily-weekly': {
|
|
23
|
+
first: 'M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z',
|
|
24
|
+
second: 'M4 6h16M4 10h16M4 14h16M4 18h16'
|
|
25
|
+
}
|
|
26
|
+
} as const;
|
|
27
|
+
|
|
28
|
+
function handleToggle(value: boolean) {
|
|
29
|
+
isSecondOption = value;
|
|
30
|
+
onToggle?.(value);
|
|
31
|
+
}
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<div class="inline-flex items-center bg-gray-100 rounded-xl p-1.5">
|
|
35
|
+
<button
|
|
36
|
+
onclick={() => handleToggle(false)}
|
|
37
|
+
class="flex items-center gap-2 px-4 md:px-3 py-2.5 md:py-1.5 rounded-lg text-base md:text-sm font-medium transition-all {!isSecondOption ? 'bg-white text-blue-600 shadow-sm' : 'text-gray-600 hover:text-gray-900'}"
|
|
38
|
+
>
|
|
39
|
+
<svg class="w-6 h-6 md:w-4 md:h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
40
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d={icons[mode].first} />
|
|
41
|
+
</svg>
|
|
42
|
+
<span class="hidden md:inline">{labels[mode].first}</span>
|
|
43
|
+
</button>
|
|
44
|
+
<button
|
|
45
|
+
onclick={() => handleToggle(true)}
|
|
46
|
+
class="flex items-center gap-2 px-4 md:px-3 py-2.5 md:py-1.5 rounded-lg text-base md:text-sm font-medium transition-all {isSecondOption ? 'bg-white text-blue-600 shadow-sm' : 'text-gray-600 hover:text-gray-900'}"
|
|
47
|
+
>
|
|
48
|
+
<svg class="w-6 h-6 md:w-4 md:h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
49
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d={icons[mode].second} />
|
|
50
|
+
</svg>
|
|
51
|
+
<span class="hidden md:inline">{labels[mode].second}</span>
|
|
52
|
+
</button>
|
|
53
|
+
</div>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
mode?: 'card-table' | 'daily-weekly';
|
|
3
|
+
isSecondOption?: boolean;
|
|
4
|
+
onToggle?: (isSecondOption: boolean) => void;
|
|
5
|
+
}
|
|
6
|
+
declare const ViewToggle: import("svelte").Component<Props, {}, "isSecondOption">;
|
|
7
|
+
type ViewToggle = ReturnType<typeof ViewToggle>;
|
|
8
|
+
export default ViewToggle;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { default as PageHeader } from './PageHeader.svelte';
|
|
2
|
+
export { default as PageContent } from './PageContent.svelte';
|
|
3
|
+
export { default as SearchBar } from './SearchBar.svelte';
|
|
4
|
+
export { default as ViewToggle } from './ViewToggle.svelte';
|
|
5
|
+
export { default as ActionButton } from './ActionButton.svelte';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { default as PageHeader } from './PageHeader.svelte';
|
|
2
|
+
export { default as PageContent } from './PageContent.svelte';
|
|
3
|
+
export { default as SearchBar } from './SearchBar.svelte';
|
|
4
|
+
export { default as ViewToggle } from './ViewToggle.svelte';
|
|
5
|
+
export { default as ActionButton } from './ActionButton.svelte';
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { PaginationProps } from './Pagination.types';
|
|
3
|
+
import { t } from '../utils/translations.svelte';
|
|
4
|
+
|
|
5
|
+
let {
|
|
6
|
+
currentPage,
|
|
7
|
+
totalPages,
|
|
8
|
+
pageSize,
|
|
9
|
+
totalItems,
|
|
10
|
+
itemName = '',
|
|
11
|
+
searchTerm = '',
|
|
12
|
+
onPageChange,
|
|
13
|
+
showInfo = true,
|
|
14
|
+
showPageNumbers = true
|
|
15
|
+
}: PaginationProps = $props();
|
|
16
|
+
|
|
17
|
+
const startItem = $derived((currentPage - 1) * pageSize + 1);
|
|
18
|
+
const endItem = $derived(Math.min(currentPage * pageSize, totalItems));
|
|
19
|
+
|
|
20
|
+
function handlePageChange(page: number) {
|
|
21
|
+
if (page >= 1 && page <= totalPages) {
|
|
22
|
+
onPageChange(page);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function shouldShowPageNumber(pageNum: number): boolean {
|
|
27
|
+
return (
|
|
28
|
+
totalPages <= 7 ||
|
|
29
|
+
pageNum === 1 ||
|
|
30
|
+
pageNum === totalPages ||
|
|
31
|
+
(pageNum >= currentPage - 1 && pageNum <= currentPage + 1)
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function shouldShowEllipsis(pageNum: number): boolean {
|
|
36
|
+
return pageNum === currentPage - 2 || pageNum === currentPage + 2;
|
|
37
|
+
}
|
|
38
|
+
</script>
|
|
39
|
+
|
|
40
|
+
{#if totalPages > 1}
|
|
41
|
+
<div class="mt-6 flex flex-col sm:flex-row items-center justify-between gap-4 border-t pt-4">
|
|
42
|
+
{#if showInfo}
|
|
43
|
+
<div class="text-sm text-gray-600">
|
|
44
|
+
{t('table.showing')}: <span class="font-semibold">{startItem}</span> -
|
|
45
|
+
<span class="font-semibold">{endItem}</span> /
|
|
46
|
+
<span class="font-semibold">{totalItems}</span> {itemName}
|
|
47
|
+
{#if searchTerm && searchTerm.trim()}
|
|
48
|
+
<span class="text-blue-600 ml-2">({t('common.search')}: "{searchTerm}")</span>
|
|
49
|
+
{/if}
|
|
50
|
+
</div>
|
|
51
|
+
{/if}
|
|
52
|
+
|
|
53
|
+
<div class="flex items-center gap-2">
|
|
54
|
+
<button
|
|
55
|
+
onclick={() => handlePageChange(currentPage - 1)}
|
|
56
|
+
disabled={currentPage === 1}
|
|
57
|
+
class="px-3 py-1 rounded border {currentPage === 1
|
|
58
|
+
? 'bg-gray-100 text-gray-400 cursor-not-allowed border-gray-200'
|
|
59
|
+
: 'bg-white text-blue-600 border-blue-300 hover:bg-blue-50 cursor-pointer'}"
|
|
60
|
+
>
|
|
61
|
+
‹ {t('common.previous')}
|
|
62
|
+
</button>
|
|
63
|
+
|
|
64
|
+
{#if showPageNumbers}
|
|
65
|
+
{#each Array.from({ length: totalPages }, (_, i) => i + 1) as pageNum}
|
|
66
|
+
{#if shouldShowPageNumber(pageNum)}
|
|
67
|
+
<button
|
|
68
|
+
onclick={() => handlePageChange(pageNum)}
|
|
69
|
+
class="px-3 py-1 rounded border {currentPage === pageNum
|
|
70
|
+
? 'bg-blue-600 text-white border-blue-600 font-semibold'
|
|
71
|
+
: 'bg-white text-blue-600 border-blue-300 hover:bg-blue-50 cursor-pointer'}"
|
|
72
|
+
>
|
|
73
|
+
{pageNum}
|
|
74
|
+
</button>
|
|
75
|
+
{:else if shouldShowEllipsis(pageNum)}
|
|
76
|
+
<span class="text-gray-500">...</span>
|
|
77
|
+
{/if}
|
|
78
|
+
{/each}
|
|
79
|
+
{:else}
|
|
80
|
+
<span class="px-3 py-1 text-sm text-gray-700">
|
|
81
|
+
{t('common.page')} {currentPage} / {totalPages}
|
|
82
|
+
</span>
|
|
83
|
+
{/if}
|
|
84
|
+
|
|
85
|
+
<button
|
|
86
|
+
onclick={() => handlePageChange(currentPage + 1)}
|
|
87
|
+
disabled={currentPage >= totalPages}
|
|
88
|
+
class="px-3 py-1 rounded border {currentPage >= totalPages
|
|
89
|
+
? 'bg-gray-100 text-gray-400 cursor-not-allowed border-gray-200'
|
|
90
|
+
: 'bg-white text-blue-600 border-blue-300 hover:bg-blue-50 cursor-pointer'}"
|
|
91
|
+
>
|
|
92
|
+
{t('common.next')} ›
|
|
93
|
+
</button>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
{/if}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface PaginationProps {
|
|
2
|
+
currentPage: number;
|
|
3
|
+
totalPages: number;
|
|
4
|
+
pageSize: number;
|
|
5
|
+
totalItems: number;
|
|
6
|
+
onPageChange: (page: number) => void;
|
|
7
|
+
itemName?: string;
|
|
8
|
+
searchTerm?: string;
|
|
9
|
+
showInfo?: boolean;
|
|
10
|
+
showPageNumbers?: boolean;
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Pagination } from './Pagination.svelte';
|