@selvajs/ui 3.0.0 → 4.0.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/dist/components/compute/AppLayout.svelte +11 -1
- package/dist/components/compute/AppLayout.svelte.d.ts +5 -1
- package/dist/components/compute/ComputeApp.svelte +30 -1
- package/dist/components/compute/ComputeApp.svelte.d.ts +18 -1
- package/dist/components/compute/ParameterPresetManager.svelte +132 -72
- package/dist/components/compute/ParameterPresetManager.svelte.d.ts +8 -1
- package/dist/components/layout/AppShell.svelte +32 -12
- package/dist/components/layout/AppShell.svelte.d.ts +8 -0
- package/dist/components/layout/PageFooter.svelte +16 -2
- package/dist/components/layout/PageFooter.svelte.d.ts +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/types/presetLabels.d.ts +40 -0
- package/dist/types/presetLabels.js +33 -0
- package/package.json +4 -4
- package/src/lib/components/compute/AppLayout.svelte +11 -1
- package/src/lib/components/compute/ComputeApp.svelte +30 -1
- package/src/lib/components/compute/ParameterPresetManager.svelte +132 -72
- package/src/lib/components/layout/AppShell.svelte +32 -12
- package/src/lib/components/layout/PageFooter.svelte +16 -2
- package/src/lib/index.ts +1 -0
- package/src/lib/types/presetLabels.ts +86 -0
|
@@ -16,6 +16,12 @@
|
|
|
16
16
|
rightContent?: Snippet;
|
|
17
17
|
subnav?: Snippet;
|
|
18
18
|
headerClass?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Bring-your-own header. When provided, this renders inside the sticky
|
|
21
|
+
* header bar instead of the built-in PageHeader. The bar keeps the
|
|
22
|
+
* standard `--header-h` height so the fixed-mode layout math is unaffected.
|
|
23
|
+
*/
|
|
24
|
+
header?: Snippet;
|
|
19
25
|
|
|
20
26
|
// Body layout
|
|
21
27
|
// 'fixed' — full viewport, header + body + footer; body owns its own scroll. For app-like pages (builder, preview, library/[guid]).
|
|
@@ -29,6 +35,8 @@
|
|
|
29
35
|
showFooter?: boolean;
|
|
30
36
|
errors?: string[];
|
|
31
37
|
warnings?: string[];
|
|
38
|
+
/** Fully overrides the footer copyright line. `{name}` and `{year}` are substituted. */
|
|
39
|
+
footerText?: string;
|
|
32
40
|
footerChildren?: Snippet;
|
|
33
41
|
|
|
34
42
|
// Body content
|
|
@@ -49,11 +57,13 @@
|
|
|
49
57
|
rightContent,
|
|
50
58
|
subnav,
|
|
51
59
|
headerClass = '',
|
|
60
|
+
header,
|
|
52
61
|
mode: _mode = 'scroll',
|
|
53
62
|
sidenav,
|
|
54
63
|
showFooter = false,
|
|
55
64
|
errors = [],
|
|
56
65
|
warnings = [],
|
|
66
|
+
footerText,
|
|
57
67
|
footerChildren,
|
|
58
68
|
class: className = '',
|
|
59
69
|
bodyClass = '',
|
|
@@ -83,17 +93,27 @@
|
|
|
83
93
|
|
|
84
94
|
<div class={rootClass}>
|
|
85
95
|
{#if showHeader}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
96
|
+
{#if header}
|
|
97
|
+
<header
|
|
98
|
+
class={`top-0 backdrop-blur-sm sticky z-40 border-b border-border bg-background/90 ${headerClass}`}
|
|
99
|
+
>
|
|
100
|
+
<div class="flex h-(--header-h) items-center px-(--page-px)">
|
|
101
|
+
{@render header()}
|
|
102
|
+
</div>
|
|
103
|
+
</header>
|
|
104
|
+
{:else}
|
|
105
|
+
<PageHeader
|
|
106
|
+
{homeUrl}
|
|
107
|
+
{title}
|
|
108
|
+
{logo}
|
|
109
|
+
{brandName}
|
|
110
|
+
{showModeToggle}
|
|
111
|
+
{navItems}
|
|
112
|
+
{rightContent}
|
|
113
|
+
{subnav}
|
|
114
|
+
class={headerClass}
|
|
115
|
+
/>
|
|
116
|
+
{/if}
|
|
97
117
|
{/if}
|
|
98
118
|
|
|
99
119
|
<div class={bodyShellClass} style={bodyShellStyle}>
|
|
@@ -109,7 +129,7 @@
|
|
|
109
129
|
|
|
110
130
|
{#if showFooter}
|
|
111
131
|
<div class="bottom-0 sticky z-10 shrink-0">
|
|
112
|
-
<PageFooter {errors} {warnings} copyrightName={_copyright}>
|
|
132
|
+
<PageFooter {errors} {warnings} copyrightName={_copyright} {footerText}>
|
|
113
133
|
{#if footerChildren}
|
|
114
134
|
{@render footerChildren()}
|
|
115
135
|
{/if}
|
|
@@ -11,10 +11,18 @@
|
|
|
11
11
|
errors?: string[];
|
|
12
12
|
warnings?: string[];
|
|
13
13
|
copyrightName?: string;
|
|
14
|
+
/** Fully overrides the copyright line. `{name}` and `{year}` are substituted. */
|
|
15
|
+
footerText?: string;
|
|
14
16
|
children?: Snippet;
|
|
15
17
|
}
|
|
16
18
|
|
|
17
|
-
let {
|
|
19
|
+
let {
|
|
20
|
+
errors = [],
|
|
21
|
+
warnings = [],
|
|
22
|
+
copyrightName = 'Selva',
|
|
23
|
+
footerText,
|
|
24
|
+
children
|
|
25
|
+
}: Props = $props();
|
|
18
26
|
|
|
19
27
|
let footerStore = (() => {
|
|
20
28
|
try {
|
|
@@ -64,6 +72,12 @@
|
|
|
64
72
|
|
|
65
73
|
const groupedErrors = $derived(groupMessages(errors));
|
|
66
74
|
const groupedWarnings = $derived(groupMessages(warnings));
|
|
75
|
+
|
|
76
|
+
const copyrightLine = $derived(
|
|
77
|
+
footerText
|
|
78
|
+
? footerText.replace('{name}', copyrightName).replace('{year}', String(_currentYear))
|
|
79
|
+
: `by ${copyrightName} © ${_currentYear}`
|
|
80
|
+
);
|
|
67
81
|
</script>
|
|
68
82
|
|
|
69
83
|
<footer
|
|
@@ -218,6 +232,6 @@
|
|
|
218
232
|
<FooterItemRenderer {item} />
|
|
219
233
|
{/each}
|
|
220
234
|
|
|
221
|
-
<p>
|
|
235
|
+
<p>{copyrightLine}</p>
|
|
222
236
|
</div>
|
|
223
237
|
</footer>
|
package/src/lib/index.ts
CHANGED
|
@@ -33,3 +33,4 @@ export { randomId } from './utils/randomId';
|
|
|
33
33
|
// UI-specific runtime types (not from schema)
|
|
34
34
|
export type { ActionButton } from './types/actionButton';
|
|
35
35
|
export type { SolveFn } from './types/solveFn';
|
|
36
|
+
export { DEFAULT_PRESET_LABELS, type PresetLabels } from './types/presetLabels';
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Overridable UI strings for the parameter-preset manager (Save/Load flow) and
|
|
3
|
+
* footer copyright text. All optional — unset keys fall back to the English
|
|
4
|
+
* defaults in `DEFAULT_PRESET_LABELS`. Pass a partial object to localize.
|
|
5
|
+
*/
|
|
6
|
+
export interface PresetLabels {
|
|
7
|
+
// Toolbar buttons
|
|
8
|
+
saveButton: string;
|
|
9
|
+
loadButton: string;
|
|
10
|
+
|
|
11
|
+
// Save dialog
|
|
12
|
+
saveDialogTitle: string;
|
|
13
|
+
saveDialogDescription: string;
|
|
14
|
+
saveNameLabel: string;
|
|
15
|
+
saveNamePlaceholder: string;
|
|
16
|
+
saveDescriptionLabel: string;
|
|
17
|
+
saveDescriptionPlaceholder: string;
|
|
18
|
+
saveAuthorLabel: string;
|
|
19
|
+
saveAuthorPlaceholder: string;
|
|
20
|
+
saveTagsLabel: string;
|
|
21
|
+
saveTagsPlaceholder: string;
|
|
22
|
+
saveNameRequired: string;
|
|
23
|
+
|
|
24
|
+
// Load dialog
|
|
25
|
+
loadDialogTitle: string;
|
|
26
|
+
loadDialogDescription: string;
|
|
27
|
+
loadFromFileButton: string;
|
|
28
|
+
loadEmptyList: string;
|
|
29
|
+
loadImportError: string;
|
|
30
|
+
|
|
31
|
+
// Validation dialog
|
|
32
|
+
validationTitle: string;
|
|
33
|
+
validationValidatingPrefix: string;
|
|
34
|
+
validationNoIssuesTitle: string;
|
|
35
|
+
validationNoIssuesBody: string;
|
|
36
|
+
validationWarningsTitle: string;
|
|
37
|
+
/** `{count}` is replaced with the number of warnings. */
|
|
38
|
+
validationWarningsBody: string;
|
|
39
|
+
validationErrorsTitle: string;
|
|
40
|
+
validationErrorsBody: string;
|
|
41
|
+
validationIssuesHeading: string;
|
|
42
|
+
validationExpected: string;
|
|
43
|
+
validationActual: string;
|
|
44
|
+
|
|
45
|
+
// Shared buttons
|
|
46
|
+
cancelButton: string;
|
|
47
|
+
loadAnywayButton: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export const DEFAULT_PRESET_LABELS: PresetLabels = {
|
|
51
|
+
saveButton: 'Save State',
|
|
52
|
+
loadButton: 'Load State',
|
|
53
|
+
|
|
54
|
+
saveDialogTitle: 'Save Parameter State',
|
|
55
|
+
saveDialogDescription: 'Save the current parameter values as a .sps file',
|
|
56
|
+
saveNameLabel: 'State Name *',
|
|
57
|
+
saveNamePlaceholder: 'e.g., Design Option A',
|
|
58
|
+
saveDescriptionLabel: 'Description',
|
|
59
|
+
saveDescriptionPlaceholder: 'Optional description of this state',
|
|
60
|
+
saveAuthorLabel: 'Author',
|
|
61
|
+
saveAuthorPlaceholder: 'Your name or email',
|
|
62
|
+
saveTagsLabel: 'Tags',
|
|
63
|
+
saveTagsPlaceholder: 'facade, option-a, client-approved (comma-separated)',
|
|
64
|
+
saveNameRequired: 'Please enter a name for this state',
|
|
65
|
+
|
|
66
|
+
loadDialogTitle: 'Load Parameter State',
|
|
67
|
+
loadDialogDescription: 'Select a .sps state file from your drive to load',
|
|
68
|
+
loadFromFileButton: 'Select .sps File',
|
|
69
|
+
loadEmptyList: 'No saved states found',
|
|
70
|
+
loadImportError: 'Failed to import state: ',
|
|
71
|
+
|
|
72
|
+
validationTitle: 'State Validation Report',
|
|
73
|
+
validationValidatingPrefix: 'Validating state: ',
|
|
74
|
+
validationNoIssuesTitle: 'No Issues Found',
|
|
75
|
+
validationNoIssuesBody: 'This state can be loaded safely.',
|
|
76
|
+
validationWarningsTitle: 'Warnings Detected',
|
|
77
|
+
validationWarningsBody: '{count} warning(s) found, but state can still be loaded.',
|
|
78
|
+
validationErrorsTitle: 'Critical Errors',
|
|
79
|
+
validationErrorsBody: 'Cannot load this state due to critical incompatibilities.',
|
|
80
|
+
validationIssuesHeading: 'Issues:',
|
|
81
|
+
validationExpected: 'Expected:',
|
|
82
|
+
validationActual: 'Actual:',
|
|
83
|
+
|
|
84
|
+
cancelButton: 'Cancel',
|
|
85
|
+
loadAnywayButton: 'Load Anyway'
|
|
86
|
+
};
|