urpanels-ui-pack 0.0.4 → 0.0.10

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 (51) 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/InfoCard/InfoCard.svelte +61 -30
  7. package/dist/InputCheckboxModal/InputCheckboxModal.svelte +235 -0
  8. package/dist/InputCheckboxModal/InputCheckboxModal.svelte.d.ts +23 -0
  9. package/dist/InputCheckboxModal/index.d.ts +1 -0
  10. package/dist/InputCheckboxModal/index.js +1 -0
  11. package/dist/InputSelectModal/InputSelectModal.svelte +118 -0
  12. package/dist/InputSelectModal/InputSelectModal.svelte.d.ts +19 -0
  13. package/dist/InputSelectModal/index.d.ts +1 -0
  14. package/dist/InputSelectModal/index.js +1 -0
  15. package/dist/LoadingSpinner/LoadingSpinner.svelte +1 -1
  16. package/dist/Modal/Modal.svelte +74 -2
  17. package/dist/Modal/Modal.svelte.d.ts +9 -2
  18. package/dist/PageLayout/ActionButton.svelte +12 -4
  19. package/dist/PageLayout/PageContent.svelte +1 -1
  20. package/dist/PageLayout/PageHeader.svelte +75 -15
  21. package/dist/PageLayout/PageHeader.svelte.d.ts +10 -1
  22. package/dist/PageLayout/SearchBar.svelte +1 -1
  23. package/dist/PageLayout/ViewToggle.svelte +1 -1
  24. package/dist/Pagination/Pagination.svelte +1 -1
  25. package/dist/index.d.ts +1 -0
  26. package/dist/index.js +8 -0
  27. package/dist/inputs/InputNumber/InputNumber.svelte +140 -0
  28. package/dist/inputs/InputNumber/InputNumber.svelte.d.ts +27 -0
  29. package/dist/inputs/InputNumber/index.d.ts +2 -0
  30. package/dist/inputs/InputNumber/index.js +2 -0
  31. package/dist/inputs/InputSelect/InputSelect.svelte +73 -0
  32. package/dist/inputs/InputSelect/InputSelect.svelte.d.ts +18 -0
  33. package/dist/inputs/InputSelect/index.d.ts +2 -0
  34. package/dist/inputs/InputSelect/index.js +2 -0
  35. package/dist/inputs/InputText/InputText.svelte +126 -0
  36. package/dist/inputs/InputText/InputText.svelte.d.ts +49 -0
  37. package/dist/inputs/InputText/index.d.ts +2 -0
  38. package/dist/inputs/InputText/index.js +2 -0
  39. package/dist/inputs/TextArea/TextArea.svelte +113 -0
  40. package/dist/inputs/TextArea/TextArea.svelte.d.ts +21 -0
  41. package/dist/inputs/TextArea/index.d.ts +2 -0
  42. package/dist/inputs/TextArea/index.js +2 -0
  43. package/dist/inputs/index.d.ts +3 -0
  44. package/dist/inputs/index.js +4 -0
  45. package/dist/sections/PreviewSelector/PreviewSelector.svelte +164 -0
  46. package/dist/sections/PreviewSelector/PreviewSelector.svelte.d.ts +25 -0
  47. package/dist/sections/PreviewSelector/index.d.ts +2 -0
  48. package/dist/sections/PreviewSelector/index.js +1 -0
  49. package/dist/sections/index.d.ts +2 -0
  50. package/dist/sections/index.js +1 -0
  51. package/package.json +14 -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}
@@ -16,6 +16,7 @@
16
16
  badges = [],
17
17
  relatedItems,
18
18
  note,
19
+ footerActions,
19
20
  onView,
20
21
  onEdit,
21
22
  onDelete
@@ -23,6 +24,7 @@
23
24
 
24
25
  const isCompact = $derived(variant === 'compact');
25
26
  const hasActions = $derived(onView || onEdit || onDelete);
27
+ const hasBadgeLabels = $derived(badges?.some((b) => b?.label));
26
28
 
27
29
  function truncateText(text: string, maxLength: number): string {
28
30
  if (!text) return '';
@@ -44,6 +46,8 @@
44
46
 
45
47
  <div
46
48
  class="bg-white rounded-lg shadow {isCompact ? 'p-3' : 'p-4'} flex flex-col gap-2 {hover ? 'hover:shadow-md transition-shadow' : ''} {className} relative"
49
+ data-component-name="InfoCard"
50
+ data-card-id={id}
47
51
  >
48
52
  {#if linkedStatus?.isLinked}
49
53
  <div class="absolute -top-1 -right-1 bg-indigo-500 text-white rounded-full w-5 h-5 flex items-center justify-center shadow-sm ring-2 ring-white" title="Kullanıcı hesabına bağlı">
@@ -124,7 +128,7 @@
124
128
  {#each fields as field}
125
129
  {#if field.condition !== false}
126
130
  <div class="{field.span === 2 ? 'col-span-2' : ''} truncate">
127
- <span class="font-semibold text-gray-700">{field.label}:</span>
131
+ <span class="font-semibold text-gray-700 whitespace-pre-line">{field.label}:</span>
128
132
  {#if field.icon}<span class="mx-1">{field.icon}</span>{/if}
129
133
  <span class="text-gray-900">{field.value || '-'}</span>
130
134
  </div>
@@ -134,38 +138,59 @@
134
138
  {/if}
135
139
 
136
140
  {#if badges && badges.length > 0}
137
- {#each badges as badgeGroup}
138
- {#if badgeGroup.items && badgeGroup.items.length > 0}
139
- {#snippet badgeSection()}
140
- {@const displayItems = badgeGroup.maxDisplay ? badgeGroup.items.slice(0, badgeGroup.maxDisplay) : badgeGroup.items}
141
- {@const remaining = badgeGroup.maxDisplay && badgeGroup.items.length > badgeGroup.maxDisplay ? badgeGroup.items.length - badgeGroup.maxDisplay : 0}
142
-
143
- <div class="mt-1">
144
- {#if badgeGroup.label}
145
- <div class="{isCompact ? 'text-[10px]' : 'text-xs'} font-semibold text-gray-600 mb-1">
146
- {#if badgeGroup.icon}<span class="mr-1">{badgeGroup.icon}</span>{/if}
147
- {badgeGroup.label}
148
- </div>
141
+ {#if !hasBadgeLabels}
142
+ <div class="mt-1 flex flex-wrap gap-1">
143
+ {#each badges as badgeGroup}
144
+ {#if badgeGroup.items && badgeGroup.items.length > 0}
145
+ {@const displayItems = badgeGroup.maxDisplay ? badgeGroup.items.slice(0, badgeGroup.maxDisplay) : badgeGroup.items}
146
+ {@const remaining = badgeGroup.maxDisplay && badgeGroup.items.length > badgeGroup.maxDisplay ? badgeGroup.items.length - badgeGroup.maxDisplay : 0}
147
+ {#each displayItems as item}
148
+ <span class="{isCompact ? 'text-[10px] px-1.5 py-0.5' : 'text-xs px-2 py-1'} rounded border {getBadgeColorClasses(badgeGroup.color)}">
149
+ {item}
150
+ </span>
151
+ {/each}
152
+ {#if remaining > 0}
153
+ <span class="{isCompact ? 'text-[10px] px-1.5 py-0.5' : 'text-xs px-2 py-1'} rounded border {getBadgeColorClasses(badgeGroup.color)}">
154
+ +{remaining}
155
+ </span>
149
156
  {/if}
150
- <div class="flex flex-wrap gap-1">
151
- {#each displayItems as item}
152
- <span class="{isCompact ? 'text-[10px] px-1.5 py-0.5' : 'text-xs px-2 py-1'} rounded border {getBadgeColorClasses(badgeGroup.color)}">
153
- {item}
154
- </span>
155
- {/each}
156
-
157
- {#if remaining > 0}
158
- <span class="{isCompact ? 'text-[10px] px-1.5 py-0.5' : 'text-xs px-2 py-1'} rounded border {getBadgeColorClasses(badgeGroup.color)}">
159
- +{remaining}
160
- </span>
157
+ {/if}
158
+ {/each}
159
+ </div>
160
+ {:else}
161
+ {#each badges as badgeGroup}
162
+ {#if badgeGroup.items && badgeGroup.items.length > 0}
163
+ {#snippet badgeSection()}
164
+ {@const displayItems = badgeGroup.maxDisplay ? badgeGroup.items.slice(0, badgeGroup.maxDisplay) : badgeGroup.items}
165
+ {@const remaining = badgeGroup.maxDisplay && badgeGroup.items.length > badgeGroup.maxDisplay ? badgeGroup.items.length - badgeGroup.maxDisplay : 0}
166
+
167
+ <div class="mt-1">
168
+ {#if badgeGroup.label}
169
+ <div class="{isCompact ? 'text-[10px]' : 'text-xs'} font-semibold text-gray-600 mb-1">
170
+ {#if badgeGroup.icon}<span class="mr-1">{badgeGroup.icon}</span>{/if}
171
+ {badgeGroup.label}
172
+ </div>
161
173
  {/if}
174
+ <div class="flex flex-wrap gap-1">
175
+ {#each displayItems as item}
176
+ <span class="{isCompact ? 'text-[10px] px-1.5 py-0.5' : 'text-xs px-2 py-1'} rounded border {getBadgeColorClasses(badgeGroup.color)}">
177
+ {item}
178
+ </span>
179
+ {/each}
180
+
181
+ {#if remaining > 0}
182
+ <span class="{isCompact ? 'text-[10px] px-1.5 py-0.5' : 'text-xs px-2 py-1'} rounded border {getBadgeColorClasses(badgeGroup.color)}">
183
+ +{remaining}
184
+ </span>
185
+ {/if}
186
+ </div>
162
187
  </div>
163
- </div>
164
- {/snippet}
165
-
166
- {@render badgeSection()}
167
- {/if}
168
- {/each}
188
+ {/snippet}
189
+
190
+ {@render badgeSection()}
191
+ {/if}
192
+ {/each}
193
+ {/if}
169
194
  {/if}
170
195
 
171
196
  {#if relatedItems && relatedItems.items && relatedItems.items.length > 0}
@@ -203,6 +228,12 @@
203
228
  {note.maxLength ? truncateText(note.text, note.maxLength) : note.text}
204
229
  </div>
205
230
  {/if}
231
+
232
+ {#if footerActions}
233
+ <div class="mt-2 flex flex-wrap gap-2">
234
+ {@render footerActions()}
235
+ </div>
236
+ {/if}
206
237
 
207
238
  {#if actionLayout === 'buttons' && hasActions}
208
239
  <div class="mt-3 flex justify-end gap-2 pt-2 border-t border-gray-100">