urpanels-ui-pack 0.0.4 → 0.0.11

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.
Files changed (101) hide show
  1. package/dist/BasePageService/BasePageService.d.ts +121 -0
  2. package/dist/BasePageService/BasePageService.js +191 -0
  3. package/dist/BasePageService/index.d.ts +2 -0
  4. package/dist/BasePageService/index.js +1 -0
  5. package/dist/Button/Button.svelte +1 -0
  6. package/dist/DataTableLite/DataTableLite.svelte +56 -0
  7. package/dist/DataTableLite/DataTableLite.svelte.d.ts +15 -0
  8. package/dist/DataTableLite/index.d.ts +1 -0
  9. package/dist/DataTableLite/index.js +1 -0
  10. package/dist/FilterBar/FilterBar.svelte +124 -0
  11. package/dist/FilterBar/FilterBar.svelte.d.ts +14 -0
  12. package/dist/FilterBar/index.d.ts +2 -0
  13. package/dist/FilterBar/index.js +1 -0
  14. package/dist/FilterBar/types.d.ts +35 -0
  15. package/dist/FilterBar/types.js +1 -0
  16. package/dist/ImageEditorModal/ImageEditorModal.svelte +330 -0
  17. package/dist/ImageEditorModal/ImageEditorModal.svelte.d.ts +23 -0
  18. package/dist/ImageEditorModal/index.d.ts +1 -0
  19. package/dist/ImageEditorModal/index.js +1 -0
  20. package/dist/InfoCard/InfoCard.svelte +61 -30
  21. package/dist/InputCheckboxModal/InputCheckboxModal.svelte +235 -0
  22. package/dist/InputCheckboxModal/InputCheckboxModal.svelte.d.ts +23 -0
  23. package/dist/InputCheckboxModal/index.d.ts +1 -0
  24. package/dist/InputCheckboxModal/index.js +1 -0
  25. package/dist/InputMultiSelectModal/InputMultiSelectModal.svelte +285 -0
  26. package/dist/InputMultiSelectModal/InputMultiSelectModal.svelte.d.ts +25 -0
  27. package/dist/InputMultiSelectModal/index.d.ts +1 -0
  28. package/dist/InputMultiSelectModal/index.js +1 -0
  29. package/dist/InputQuantityModal/InputQuantityModal.svelte +431 -0
  30. package/dist/InputQuantityModal/InputQuantityModal.svelte.d.ts +29 -0
  31. package/dist/InputQuantityModal/index.d.ts +1 -0
  32. package/dist/InputQuantityModal/index.js +1 -0
  33. package/dist/InputSelectModal/InputSelectModal.svelte +118 -0
  34. package/dist/InputSelectModal/InputSelectModal.svelte.d.ts +19 -0
  35. package/dist/InputSelectModal/index.d.ts +1 -0
  36. package/dist/InputSelectModal/index.js +1 -0
  37. package/dist/InputSelectModalV2/InputSelectModalV2.svelte +340 -0
  38. package/dist/InputSelectModalV2/InputSelectModalV2.svelte.d.ts +48 -0
  39. package/dist/InputSelectModalV2/index.d.ts +1 -0
  40. package/dist/InputSelectModalV2/index.js +1 -0
  41. package/dist/KpiStatsGrid/KpiStatsGrid.svelte +50 -0
  42. package/dist/KpiStatsGrid/KpiStatsGrid.svelte.d.ts +14 -0
  43. package/dist/KpiStatsGrid/index.d.ts +1 -0
  44. package/dist/KpiStatsGrid/index.js +1 -0
  45. package/dist/LoadingSpinner/LoadingSpinner.svelte +1 -1
  46. package/dist/Modal/Modal.svelte +108 -19
  47. package/dist/Modal/Modal.svelte.d.ts +11 -2
  48. package/dist/PageLayout/ActionButton.svelte +12 -4
  49. package/dist/PageLayout/PageContent.svelte +1 -1
  50. package/dist/PageLayout/PageHeader.svelte +89 -14
  51. package/dist/PageLayout/PageHeader.svelte.d.ts +10 -1
  52. package/dist/PageLayout/SearchBar.svelte +1 -1
  53. package/dist/PageLayout/ViewToggle.svelte +1 -1
  54. package/dist/Pagination/Pagination.svelte +1 -1
  55. package/dist/RecentActivityList/RecentActivityList.svelte +64 -0
  56. package/dist/RecentActivityList/RecentActivityList.svelte.d.ts +18 -0
  57. package/dist/RecentActivityList/index.d.ts +1 -0
  58. package/dist/RecentActivityList/index.js +1 -0
  59. package/dist/RichTextEditor/RichTextEditor.svelte +181 -1
  60. package/dist/RichTextEditor/RichTextEditor.svelte.d.ts +3 -0
  61. package/dist/RichTextRenderer/RichTextRenderer.svelte +169 -0
  62. package/dist/RichTextRenderer/RichTextRenderer.svelte.d.ts +11 -0
  63. package/dist/RichTextRenderer/index.d.ts +1 -0
  64. package/dist/RichTextRenderer/index.js +1 -0
  65. package/dist/StatusPill/StatusPill.svelte +26 -0
  66. package/dist/StatusPill/StatusPill.svelte.d.ts +10 -0
  67. package/dist/StatusPill/index.d.ts +1 -0
  68. package/dist/StatusPill/index.js +1 -0
  69. package/dist/TimelineList/TimelineList.svelte +207 -0
  70. package/dist/TimelineList/TimelineList.svelte.d.ts +4 -0
  71. package/dist/TimelineList/TimelineList.types.d.ts +70 -0
  72. package/dist/TimelineList/TimelineList.types.js +1 -0
  73. package/dist/TimelineList/index.d.ts +2 -0
  74. package/dist/TimelineList/index.js +1 -0
  75. package/dist/index.d.ts +19 -0
  76. package/dist/index.js +19 -0
  77. package/dist/inputs/InputNumber/InputNumber.svelte +140 -0
  78. package/dist/inputs/InputNumber/InputNumber.svelte.d.ts +27 -0
  79. package/dist/inputs/InputNumber/index.d.ts +2 -0
  80. package/dist/inputs/InputNumber/index.js +2 -0
  81. package/dist/inputs/InputSelect/InputSelect.svelte +73 -0
  82. package/dist/inputs/InputSelect/InputSelect.svelte.d.ts +18 -0
  83. package/dist/inputs/InputSelect/index.d.ts +2 -0
  84. package/dist/inputs/InputSelect/index.js +2 -0
  85. package/dist/inputs/InputText/InputText.svelte +126 -0
  86. package/dist/inputs/InputText/InputText.svelte.d.ts +49 -0
  87. package/dist/inputs/InputText/index.d.ts +2 -0
  88. package/dist/inputs/InputText/index.js +2 -0
  89. package/dist/inputs/TextArea/TextArea.svelte +113 -0
  90. package/dist/inputs/TextArea/TextArea.svelte.d.ts +21 -0
  91. package/dist/inputs/TextArea/index.d.ts +2 -0
  92. package/dist/inputs/TextArea/index.js +2 -0
  93. package/dist/inputs/index.d.ts +3 -0
  94. package/dist/inputs/index.js +4 -0
  95. package/dist/sections/PreviewSelector/PreviewSelector.svelte +164 -0
  96. package/dist/sections/PreviewSelector/PreviewSelector.svelte.d.ts +25 -0
  97. package/dist/sections/PreviewSelector/index.d.ts +2 -0
  98. package/dist/sections/PreviewSelector/index.js +1 -0
  99. package/dist/sections/index.d.ts +2 -5
  100. package/dist/sections/index.js +6 -3
  101. package/package.json +17 -1
@@ -0,0 +1,121 @@
1
+ import { PageService, type PageOts } from "@urga-panel/ur-panels-core/dist/services/abstract/pageServices/PageServices";
2
+ /**
3
+ * View mode types for list display
4
+ */
5
+ export type ViewMode = 'card' | 'table';
6
+ /**
7
+ * Local settings interface - extend this for custom settings
8
+ */
9
+ export interface BaseLocalSettings {
10
+ viewMode?: ViewMode;
11
+ pageSize?: number;
12
+ [key: string]: any;
13
+ }
14
+ /**
15
+ * Base Page Service with common loading state management and local settings
16
+ * All page services should extend this instead of PageService directly
17
+ *
18
+ * IMPORTANT: Child classes MUST implement isLoading with $state()
19
+ * Example: public isLoading: boolean = $state(true);
20
+ *
21
+ * For viewMode reactivity, child class should implement:
22
+ * public viewMode: ViewMode = $state(this.getLocalSetting('viewMode') || 'card');
23
+ */
24
+ export declare abstract class BasePageService extends PageService {
25
+ /**
26
+ * Loading state - MUST be implemented in child class with $state()
27
+ * Example: public isLoading: boolean = $state(true);
28
+ */
29
+ abstract isLoading: boolean;
30
+ /**
31
+ * Unique key for localStorage - override in child class
32
+ * Default uses class name, but should be overridden for uniqueness
33
+ */
34
+ protected get localStorageKey(): string;
35
+ /**
36
+ * Default settings - override in child class to set defaults
37
+ */
38
+ protected get defaultSettings(): BaseLocalSettings;
39
+ constructor(ots: PageOts);
40
+ /**
41
+ * Wraps an async function with loading state management
42
+ * Automatically sets isLoading to true before execution and false after
43
+ *
44
+ * @param fn - Async function to execute
45
+ * @returns Promise with the result of the function
46
+ *
47
+ * @example
48
+ * await service.withLoading(async () => {
49
+ * await loadData();
50
+ * });
51
+ */
52
+ withLoading<T>(fn: () => Promise<T>): Promise<T>;
53
+ /**
54
+ * Sets loading state manually
55
+ * Use this when you need more granular control
56
+ *
57
+ * @param loading - Loading state
58
+ */
59
+ protected setLoading(loading: boolean): void;
60
+ /**
61
+ * Gets all local settings from localStorage
62
+ * @returns Current settings merged with defaults
63
+ */
64
+ getLocalSettings<T extends BaseLocalSettings = BaseLocalSettings>(): T;
65
+ /**
66
+ * Gets a specific setting value
67
+ * @param key - Setting key
68
+ * @returns Setting value or default
69
+ *
70
+ * @example
71
+ * const viewMode = this.getLocalSetting('viewMode'); // 'card' | 'table'
72
+ */
73
+ getLocalSetting<K extends keyof BaseLocalSettings>(key: K): BaseLocalSettings[K];
74
+ /**
75
+ * Saves a specific setting to localStorage
76
+ * @param key - Setting key
77
+ * @param value - Setting value
78
+ *
79
+ * @example
80
+ * this.saveLocalSetting('viewMode', 'table');
81
+ */
82
+ saveLocalSetting<K extends keyof BaseLocalSettings>(key: K, value: BaseLocalSettings[K]): void;
83
+ /**
84
+ * Saves multiple settings at once
85
+ * @param settings - Partial settings object
86
+ *
87
+ * @example
88
+ * this.saveLocalSettings({ viewMode: 'table', pageSize: 50 });
89
+ */
90
+ saveLocalSettings(settings: Partial<BaseLocalSettings>): void;
91
+ /**
92
+ * Clears all local settings for this page
93
+ */
94
+ clearLocalSettings(): void;
95
+ /**
96
+ * Gets the current view mode from local settings
97
+ * @returns 'card' or 'table'
98
+ */
99
+ getViewMode(): ViewMode;
100
+ /**
101
+ * Saves view mode preference
102
+ * NOTE: Child class should also update its $state viewMode property
103
+ * @param mode - 'card' or 'table'
104
+ */
105
+ saveViewMode(mode: ViewMode): void;
106
+ /**
107
+ * Toggles between card and table view
108
+ * @returns The new view mode
109
+ */
110
+ toggleViewMode(): ViewMode;
111
+ /**
112
+ * Gets the saved page size
113
+ * @returns Page size number
114
+ */
115
+ getPageSize(): number;
116
+ /**
117
+ * Saves page size preference
118
+ * @param size - Number of items per page
119
+ */
120
+ savePageSize(size: number): void;
121
+ }
@@ -0,0 +1,191 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { PageService } from "@urga-panel/ur-panels-core/dist/services/abstract/pageServices/PageServices";
3
+ /**
4
+ * Base Page Service with common loading state management and local settings
5
+ * All page services should extend this instead of PageService directly
6
+ *
7
+ * IMPORTANT: Child classes MUST implement isLoading with $state()
8
+ * Example: public isLoading: boolean = $state(true);
9
+ *
10
+ * For viewMode reactivity, child class should implement:
11
+ * public viewMode: ViewMode = $state(this.getLocalSetting('viewMode') || 'card');
12
+ */
13
+ export class BasePageService extends PageService {
14
+ /**
15
+ * Unique key for localStorage - override in child class
16
+ * Default uses class name, but should be overridden for uniqueness
17
+ */
18
+ get localStorageKey() {
19
+ return `urpanels_page_${this.constructor.name}`;
20
+ }
21
+ /**
22
+ * Default settings - override in child class to set defaults
23
+ */
24
+ get defaultSettings() {
25
+ return {
26
+ viewMode: 'card',
27
+ pageSize: 20
28
+ };
29
+ }
30
+ constructor(ots) {
31
+ super(ots);
32
+ }
33
+ // ==================== Loading State Management ====================
34
+ /**
35
+ * Wraps an async function with loading state management
36
+ * Automatically sets isLoading to true before execution and false after
37
+ *
38
+ * @param fn - Async function to execute
39
+ * @returns Promise with the result of the function
40
+ *
41
+ * @example
42
+ * await service.withLoading(async () => {
43
+ * await loadData();
44
+ * });
45
+ */
46
+ async withLoading(fn) {
47
+ this.isLoading = true;
48
+ try {
49
+ return await fn();
50
+ }
51
+ finally {
52
+ this.isLoading = false;
53
+ }
54
+ }
55
+ /**
56
+ * Sets loading state manually
57
+ * Use this when you need more granular control
58
+ *
59
+ * @param loading - Loading state
60
+ */
61
+ setLoading(loading) {
62
+ this.isLoading = loading;
63
+ }
64
+ // ==================== Local Settings Management ====================
65
+ /**
66
+ * Gets all local settings from localStorage
67
+ * @returns Current settings merged with defaults
68
+ */
69
+ getLocalSettings() {
70
+ if (typeof window === 'undefined') {
71
+ return this.defaultSettings;
72
+ }
73
+ try {
74
+ const stored = localStorage.getItem(this.localStorageKey);
75
+ if (stored) {
76
+ const parsed = JSON.parse(stored);
77
+ return { ...this.defaultSettings, ...parsed };
78
+ }
79
+ }
80
+ catch (e) {
81
+ console.warn('Failed to parse local settings:', e);
82
+ }
83
+ return this.defaultSettings;
84
+ }
85
+ /**
86
+ * Gets a specific setting value
87
+ * @param key - Setting key
88
+ * @returns Setting value or default
89
+ *
90
+ * @example
91
+ * const viewMode = this.getLocalSetting('viewMode'); // 'card' | 'table'
92
+ */
93
+ getLocalSetting(key) {
94
+ var _a;
95
+ const settings = this.getLocalSettings();
96
+ return (_a = settings[key]) !== null && _a !== void 0 ? _a : this.defaultSettings[key];
97
+ }
98
+ /**
99
+ * Saves a specific setting to localStorage
100
+ * @param key - Setting key
101
+ * @param value - Setting value
102
+ *
103
+ * @example
104
+ * this.saveLocalSetting('viewMode', 'table');
105
+ */
106
+ saveLocalSetting(key, value) {
107
+ if (typeof window === 'undefined')
108
+ return;
109
+ try {
110
+ const current = this.getLocalSettings();
111
+ current[key] = value;
112
+ localStorage.setItem(this.localStorageKey, JSON.stringify(current));
113
+ }
114
+ catch (e) {
115
+ console.warn('Failed to save local setting:', e);
116
+ }
117
+ }
118
+ /**
119
+ * Saves multiple settings at once
120
+ * @param settings - Partial settings object
121
+ *
122
+ * @example
123
+ * this.saveLocalSettings({ viewMode: 'table', pageSize: 50 });
124
+ */
125
+ saveLocalSettings(settings) {
126
+ if (typeof window === 'undefined')
127
+ return;
128
+ try {
129
+ const current = this.getLocalSettings();
130
+ const updated = { ...current, ...settings };
131
+ localStorage.setItem(this.localStorageKey, JSON.stringify(updated));
132
+ }
133
+ catch (e) {
134
+ console.warn('Failed to save local settings:', e);
135
+ }
136
+ }
137
+ /**
138
+ * Clears all local settings for this page
139
+ */
140
+ clearLocalSettings() {
141
+ if (typeof window === 'undefined')
142
+ return;
143
+ try {
144
+ localStorage.removeItem(this.localStorageKey);
145
+ }
146
+ catch (e) {
147
+ console.warn('Failed to clear local settings:', e);
148
+ }
149
+ }
150
+ // ==================== View Mode Helpers ====================
151
+ /**
152
+ * Gets the current view mode from local settings
153
+ * @returns 'card' or 'table'
154
+ */
155
+ getViewMode() {
156
+ return this.getLocalSetting('viewMode') || 'card';
157
+ }
158
+ /**
159
+ * Saves view mode preference
160
+ * NOTE: Child class should also update its $state viewMode property
161
+ * @param mode - 'card' or 'table'
162
+ */
163
+ saveViewMode(mode) {
164
+ this.saveLocalSetting('viewMode', mode);
165
+ }
166
+ /**
167
+ * Toggles between card and table view
168
+ * @returns The new view mode
169
+ */
170
+ toggleViewMode() {
171
+ const current = this.getViewMode();
172
+ const newMode = current === 'card' ? 'table' : 'card';
173
+ this.saveViewMode(newMode);
174
+ return newMode;
175
+ }
176
+ // ==================== Page Size Helpers ====================
177
+ /**
178
+ * Gets the saved page size
179
+ * @returns Page size number
180
+ */
181
+ getPageSize() {
182
+ return this.getLocalSetting('pageSize') || 20;
183
+ }
184
+ /**
185
+ * Saves page size preference
186
+ * @param size - Number of items per page
187
+ */
188
+ savePageSize(size) {
189
+ this.saveLocalSetting('pageSize', size);
190
+ }
191
+ }
@@ -0,0 +1,2 @@
1
+ export { BasePageService } from './BasePageService.js';
2
+ export type { ViewMode, BaseLocalSettings } from './BasePageService.js';
@@ -0,0 +1 @@
1
+ export { BasePageService } from './BasePageService.js';
@@ -42,6 +42,7 @@
42
42
  disabled={isDisabled}
43
43
  onclick={onclick}
44
44
  class={className}
45
+ data-component-name="Button"
45
46
  {...rest}
46
47
  >
47
48
  {#if loading}
@@ -0,0 +1,56 @@
1
+ <script lang="ts">
2
+ export type TableColumn = {
3
+ key: string;
4
+ label: string;
5
+ align?: 'left' | 'center' | 'right';
6
+ width?: string;
7
+ };
8
+
9
+ interface Props {
10
+ columns: TableColumn[];
11
+ rows: Record<string, any>[];
12
+ rowKey?: string;
13
+ emptyText?: string;
14
+ }
15
+
16
+ let { columns = [], rows = [], rowKey = 'id', emptyText = '-' }: Props = $props();
17
+
18
+ const alignClass = (align?: string) => {
19
+ if (align === 'center') return 'text-center';
20
+ if (align === 'right') return 'text-right';
21
+ return 'text-left';
22
+ };
23
+ </script>
24
+
25
+ <div class="overflow-x-auto" data-component-name="DataTableLite">
26
+ <table class="min-w-full border-collapse">
27
+ <thead>
28
+ <tr>
29
+ {#each columns as col}
30
+ <th class="px-3 py-2.5 text-xs font-semibold text-gray-700 bg-gray-50 border-b border-gray-200 {alignClass(col.align)}" style:width={col.width || undefined}>
31
+ {col.label}
32
+ </th>
33
+ {/each}
34
+ </tr>
35
+ </thead>
36
+ <tbody>
37
+ {#if rows.length === 0}
38
+ <tr>
39
+ <td colspan={columns.length} class="px-3 py-6 text-center text-sm text-gray-400">
40
+ {emptyText}
41
+ </td>
42
+ </tr>
43
+ {:else}
44
+ {#each rows as row (row[rowKey] || Math.random())}
45
+ <tr class="hover:bg-gray-50">
46
+ {#each columns as col}
47
+ <td class="px-3 py-2.5 text-sm text-gray-800 border-b border-gray-100 {alignClass(col.align)}">
48
+ {row[col.key] ?? '-'}
49
+ </td>
50
+ {/each}
51
+ </tr>
52
+ {/each}
53
+ {/if}
54
+ </tbody>
55
+ </table>
56
+ </div>
@@ -0,0 +1,15 @@
1
+ export type TableColumn = {
2
+ key: string;
3
+ label: string;
4
+ align?: 'left' | 'center' | 'right';
5
+ width?: string;
6
+ };
7
+ interface Props {
8
+ columns: TableColumn[];
9
+ rows: Record<string, any>[];
10
+ rowKey?: string;
11
+ emptyText?: string;
12
+ }
13
+ declare const DataTableLite: import("svelte").Component<Props, {}, "">;
14
+ type DataTableLite = ReturnType<typeof DataTableLite>;
15
+ export default DataTableLite;
@@ -0,0 +1 @@
1
+ export { default as DataTableLite } from './DataTableLite.svelte';
@@ -0,0 +1 @@
1
+ export { default as DataTableLite } from './DataTableLite.svelte';
@@ -0,0 +1,124 @@
1
+ <script lang="ts">
2
+ import type { FilterGroup, ActiveFilters } from './types';
3
+ import { t } from '../utils/translations.svelte';
4
+
5
+ interface Props {
6
+ /** Array of filter group definitions */
7
+ groups: FilterGroup[];
8
+ /** Current active filter values (bindable) */
9
+ activeFilters?: ActiveFilters;
10
+ /** Called when any filter changes */
11
+ onFilterChange?: (filters: ActiveFilters) => void;
12
+ /** Compact mode - smaller chips */
13
+ compact?: boolean;
14
+ }
15
+
16
+ let {
17
+ groups,
18
+ activeFilters = $bindable({}),
19
+ onFilterChange,
20
+ compact = false
21
+ }: Props = $props();
22
+
23
+ function isActive(groupKey: string, optionValue: string): boolean {
24
+ const current = activeFilters[groupKey];
25
+ if (current === null || current === undefined) return false;
26
+ if (Array.isArray(current)) return current.includes(optionValue);
27
+ return current === optionValue;
28
+ }
29
+
30
+ function isAllActive(groupKey: string): boolean {
31
+ const current = activeFilters[groupKey];
32
+ return current === null || current === undefined;
33
+ }
34
+
35
+ function handleSelect(group: FilterGroup, optionValue: string) {
36
+ if (group.type === 'single') {
37
+ // Single select: toggle between this option and "all"
38
+ if (activeFilters[group.key] === optionValue) {
39
+ activeFilters[group.key] = null;
40
+ } else {
41
+ activeFilters[group.key] = optionValue;
42
+ }
43
+ } else {
44
+ // Multi select: toggle option in array
45
+ const current = activeFilters[group.key];
46
+ let arr: string[] = Array.isArray(current) ? [...current] : [];
47
+
48
+ if (arr.includes(optionValue)) {
49
+ arr = arr.filter(v => v !== optionValue);
50
+ } else {
51
+ arr.push(optionValue);
52
+ }
53
+
54
+ activeFilters[group.key] = arr.length > 0 ? arr : null;
55
+ }
56
+
57
+ onFilterChange?.(activeFilters);
58
+ }
59
+
60
+ function handleSelectAll(groupKey: string) {
61
+ activeFilters[groupKey] = null;
62
+ onFilterChange?.(activeFilters);
63
+ }
64
+ </script>
65
+
66
+ <div class="flex flex-wrap gap-3" data-component-name="FilterBar">
67
+ {#each groups as group}
68
+ <div class="flex items-center gap-1.5">
69
+ {#if group.label}
70
+ <span class="text-xs font-medium text-gray-500 mr-1 hidden sm:inline">{group.label}:</span>
71
+ {/if}
72
+
73
+ <div class="flex flex-wrap items-center bg-gray-100 rounded-xl p-1 {compact ? 'gap-0.5' : 'gap-1'}">
74
+ <!-- "All" option -->
75
+ {#if group.allLabel !== null}
76
+ <button
77
+ onclick={() => handleSelectAll(group.key)}
78
+ class="
79
+ {compact ? 'px-2.5 py-1.5 text-xs' : 'px-3 py-1.5 text-sm'}
80
+ rounded-lg font-medium transition-all cursor-pointer
81
+ {isAllActive(group.key)
82
+ ? 'bg-white text-blue-600 shadow-sm'
83
+ : 'text-gray-600 hover:text-gray-900'}
84
+ "
85
+ >
86
+ {group.allLabel || t('common.all') || 'Tümü'}
87
+ </button>
88
+ {/if}
89
+
90
+ <!-- Filter options -->
91
+ {#each group.options as option}
92
+ <button
93
+ onclick={() => handleSelect(group, option.value)}
94
+ class="
95
+ flex items-start gap-1.5 text-left
96
+ {compact ? 'px-2.5 py-1.5 text-xs' : 'px-3 py-1.5 text-sm'}
97
+ max-w-[10rem] sm:max-w-[14rem]
98
+ rounded-lg font-medium transition-all cursor-pointer
99
+ {isActive(group.key, option.value)
100
+ ? 'bg-white text-blue-600 shadow-sm'
101
+ : 'text-gray-600 hover:text-gray-900'}
102
+ "
103
+ >
104
+ {#if option.icon}
105
+ <span class="text-sm">{option.icon}</span>
106
+ {/if}
107
+ <span class="whitespace-normal break-words leading-tight">{option.label}</span>
108
+ {#if option.count !== undefined}
109
+ <span class="
110
+ {compact ? 'text-[10px] px-1' : 'text-xs px-1.5'}
111
+ py-0.5 rounded-full
112
+ {isActive(group.key, option.value)
113
+ ? 'bg-blue-100 text-blue-700'
114
+ : 'bg-gray-200 text-gray-600'}
115
+ ">
116
+ {option.count}
117
+ </span>
118
+ {/if}
119
+ </button>
120
+ {/each}
121
+ </div>
122
+ </div>
123
+ {/each}
124
+ </div>
@@ -0,0 +1,14 @@
1
+ import type { FilterGroup, ActiveFilters } from './types';
2
+ interface Props {
3
+ /** Array of filter group definitions */
4
+ groups: FilterGroup[];
5
+ /** Current active filter values (bindable) */
6
+ activeFilters?: ActiveFilters;
7
+ /** Called when any filter changes */
8
+ onFilterChange?: (filters: ActiveFilters) => void;
9
+ /** Compact mode - smaller chips */
10
+ compact?: boolean;
11
+ }
12
+ declare const FilterBar: import("svelte").Component<Props, {}, "activeFilters">;
13
+ type FilterBar = ReturnType<typeof FilterBar>;
14
+ export default FilterBar;
@@ -0,0 +1,2 @@
1
+ export { default as FilterBar } from './FilterBar.svelte';
2
+ export type { FilterGroup, FilterOption, ActiveFilters } from './types';
@@ -0,0 +1 @@
1
+ export { default as FilterBar } from './FilterBar.svelte';
@@ -0,0 +1,35 @@
1
+ /**
2
+ * A single filter option within a filter group
3
+ */
4
+ export interface FilterOption {
5
+ /** Unique value for this option */
6
+ value: string;
7
+ /** Display label */
8
+ label: string;
9
+ /** Optional icon (emoji or SVG path) */
10
+ icon?: string;
11
+ /** Optional count badge */
12
+ count?: number;
13
+ }
14
+ /**
15
+ * A group of related filter options
16
+ * Each group represents a filter dimension (e.g., type, category, status)
17
+ */
18
+ export interface FilterGroup {
19
+ /** Unique key for this filter group (used in activeFilters map) */
20
+ key: string;
21
+ /** Display label for the group */
22
+ label?: string;
23
+ /** Available options */
24
+ options: FilterOption[];
25
+ /** Selection mode: single = radio-like, multi = checkbox-like */
26
+ type: 'single' | 'multi';
27
+ /** Custom label for the "all" option. Set to null to hide "all" option (only for multi) */
28
+ allLabel?: string | null;
29
+ }
30
+ /**
31
+ * Map of active filter values
32
+ * key = FilterGroup.key
33
+ * value = null (all), string (single selection), string[] (multi selection)
34
+ */
35
+ export type ActiveFilters = Record<string, string | string[] | null>;
@@ -0,0 +1 @@
1
+ export {};