@svadmin/lite 0.3.6 → 0.3.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.
- package/README.md +19 -13
- package/dist/components/LiteAlert.svelte +19 -0
- package/dist/components/LiteAlert.svelte.d.ts +11 -0
- package/dist/components/LiteArrayField.svelte +60 -0
- package/dist/components/LiteArrayField.svelte.d.ts +17 -0
- package/dist/components/LiteArrayItem.svelte +146 -0
- package/dist/components/LiteArrayItem.svelte.d.ts +13 -0
- package/dist/components/LiteAuditLog.svelte +104 -0
- package/dist/components/LiteAuditLog.svelte.d.ts +23 -0
- package/dist/components/LiteBreadcrumbs.svelte +39 -0
- package/dist/components/LiteBreadcrumbs.svelte.d.ts +16 -0
- package/dist/components/LiteChatDialog.svelte +101 -0
- package/dist/components/LiteChatDialog.svelte.d.ts +20 -0
- package/dist/components/LiteConfirmDialog.svelte +60 -0
- package/dist/components/LiteConfirmDialog.svelte.d.ts +22 -0
- package/dist/components/LiteEmptyState.svelte +39 -0
- package/dist/components/LiteEmptyState.svelte.d.ts +16 -0
- package/dist/components/LiteForm.svelte +165 -0
- package/dist/components/LiteForm.svelte.d.ts +26 -0
- package/dist/components/LiteLayout.svelte +147 -0
- package/dist/components/LiteLayout.svelte.d.ts +19 -0
- package/dist/components/LiteLogin.svelte +41 -0
- package/dist/components/LiteLogin.svelte.d.ts +8 -0
- package/dist/components/LitePagination.svelte +73 -0
- package/dist/components/LitePagination.svelte.d.ts +11 -0
- package/dist/components/LitePermissionMatrix.svelte +147 -0
- package/dist/components/LitePermissionMatrix.svelte.d.ts +32 -0
- package/dist/components/LiteSearch.svelte +41 -0
- package/dist/components/LiteSearch.svelte.d.ts +9 -0
- package/dist/components/LiteShow.svelte +61 -0
- package/dist/components/LiteShow.svelte.d.ts +14 -0
- package/dist/components/LiteShowField.svelte +62 -0
- package/dist/components/LiteShowField.svelte.d.ts +12 -0
- package/dist/components/LiteStatsCard.svelte +70 -0
- package/dist/components/LiteStatsCard.svelte.d.ts +24 -0
- package/dist/components/LiteTable.svelte +132 -0
- package/dist/components/LiteTable.svelte.d.ts +19 -0
- package/dist/components/LiteTabs.svelte +57 -0
- package/dist/components/LiteTabs.svelte.d.ts +16 -0
- package/dist/components/advanced/LiteAutoSaveIndicator.svelte +26 -0
- package/dist/components/advanced/LiteAutoSaveIndicator.svelte.d.ts +12 -0
- package/dist/components/advanced/LiteDraggableHeader.svelte +33 -0
- package/dist/components/advanced/LiteDraggableHeader.svelte.d.ts +15 -0
- package/dist/components/advanced/LiteDrawerForm.svelte +42 -0
- package/dist/components/advanced/LiteDrawerForm.svelte.d.ts +16 -0
- package/dist/components/advanced/LiteInlineEdit.svelte +32 -0
- package/dist/components/advanced/LiteInlineEdit.svelte.d.ts +15 -0
- package/dist/components/advanced/LiteModalForm.svelte +44 -0
- package/dist/components/advanced/LiteModalForm.svelte.d.ts +17 -0
- package/dist/components/advanced/LiteToast.svelte +34 -0
- package/dist/components/advanced/LiteToast.svelte.d.ts +14 -0
- package/dist/components/advanced/LiteUndoableNotification.svelte +25 -0
- package/dist/components/advanced/LiteUndoableNotification.svelte.d.ts +13 -0
- package/dist/components/advanced/LiteVirtualTable.svelte +44 -0
- package/dist/components/advanced/LiteVirtualTable.svelte.d.ts +20 -0
- package/dist/components/advanced/index.js +8 -0
- package/dist/components/buttons/LiteCloneButton.svelte +33 -0
- package/dist/components/buttons/LiteCloneButton.svelte.d.ts +11 -0
- package/dist/components/buttons/LiteCreateButton.svelte +31 -0
- package/dist/components/buttons/LiteCreateButton.svelte.d.ts +10 -0
- package/dist/components/buttons/LiteDeleteButton.svelte +57 -0
- package/dist/components/buttons/LiteDeleteButton.svelte.d.ts +12 -0
- package/dist/components/buttons/LiteEditButton.svelte +33 -0
- package/dist/components/buttons/LiteEditButton.svelte.d.ts +11 -0
- package/dist/components/buttons/LiteExportButton.svelte +31 -0
- package/dist/components/buttons/LiteExportButton.svelte.d.ts +10 -0
- package/dist/components/buttons/LiteImportButton.svelte +50 -0
- package/dist/components/buttons/LiteImportButton.svelte.d.ts +10 -0
- package/dist/components/buttons/LiteListButton.svelte +31 -0
- package/dist/components/buttons/LiteListButton.svelte.d.ts +10 -0
- package/dist/components/buttons/LiteRefreshButton.svelte +34 -0
- package/dist/components/buttons/LiteRefreshButton.svelte.d.ts +8 -0
- package/dist/components/buttons/LiteSaveButton.svelte +27 -0
- package/dist/components/buttons/LiteSaveButton.svelte.d.ts +8 -0
- package/dist/components/buttons/LiteShowButton.svelte +33 -0
- package/dist/components/buttons/LiteShowButton.svelte.d.ts +11 -0
- package/dist/components/buttons/index.js +10 -0
- package/dist/components/fields/LiteBooleanField.svelte +42 -0
- package/dist/components/fields/LiteBooleanField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteDateField.svelte +51 -0
- package/dist/components/fields/LiteDateField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteEmailField.svelte +41 -0
- package/dist/components/fields/LiteEmailField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteFileField.svelte +59 -0
- package/dist/components/fields/LiteFileField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteImageField.svelte +57 -0
- package/dist/components/fields/LiteImageField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteJsonField.svelte +43 -0
- package/dist/components/fields/LiteJsonField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteMarkdownField.svelte +33 -0
- package/dist/components/fields/LiteMarkdownField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteMultiSelectField.svelte +57 -0
- package/dist/components/fields/LiteMultiSelectField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteNumberField.svelte +35 -0
- package/dist/components/fields/LiteNumberField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteRelationField.svelte +67 -0
- package/dist/components/fields/LiteRelationField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteRichTextField.svelte +44 -0
- package/dist/components/fields/LiteRichTextField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteSelectField.svelte +47 -0
- package/dist/components/fields/LiteSelectField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteTagField.svelte +44 -0
- package/dist/components/fields/LiteTagField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteTextField.svelte +35 -0
- package/dist/components/fields/LiteTextField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteUrlField.svelte +52 -0
- package/dist/components/fields/LiteUrlField.svelte.d.ts +10 -0
- package/dist/components/fields/index.js +15 -0
- package/dist/components/layout/LiteAuthenticated.svelte +23 -0
- package/dist/components/layout/LiteAuthenticated.svelte.d.ts +10 -0
- package/dist/components/layout/LiteCanAccess.svelte +27 -0
- package/dist/components/layout/LiteCanAccess.svelte.d.ts +10 -0
- package/dist/components/layout/LiteCatchAllNavigate.svelte +20 -0
- package/dist/components/layout/LiteCatchAllNavigate.svelte.d.ts +7 -0
- package/dist/components/layout/LiteErrorBoundary.svelte +20 -0
- package/dist/components/layout/LiteErrorBoundary.svelte.d.ts +13 -0
- package/dist/components/layout/LiteErrorComponent.svelte +37 -0
- package/dist/components/layout/LiteErrorComponent.svelte.d.ts +9 -0
- package/dist/components/layout/LiteHeader.svelte +19 -0
- package/dist/components/layout/LiteHeader.svelte.d.ts +8 -0
- package/dist/components/layout/LiteNavigateToResource.svelte +25 -0
- package/dist/components/layout/LiteNavigateToResource.svelte.d.ts +7 -0
- package/dist/components/layout/LiteSidebar.svelte +93 -0
- package/dist/components/layout/LiteSidebar.svelte.d.ts +12 -0
- package/dist/components/layout/index.js +8 -0
- package/dist/components/pages/LiteCreatePage.svelte +39 -0
- package/dist/components/pages/LiteCreatePage.svelte.d.ts +10 -0
- package/dist/components/pages/LiteEditPage.svelte +54 -0
- package/dist/components/pages/LiteEditPage.svelte.d.ts +12 -0
- package/dist/components/pages/LiteForgotPasswordPage.svelte +60 -0
- package/dist/components/pages/LiteForgotPasswordPage.svelte.d.ts +11 -0
- package/dist/components/pages/LiteListPage.svelte +81 -0
- package/dist/components/pages/LiteListPage.svelte.d.ts +20 -0
- package/dist/components/pages/LiteProfilePage.svelte +61 -0
- package/dist/components/pages/LiteProfilePage.svelte.d.ts +14 -0
- package/dist/components/pages/LiteRegisterPage.svelte +63 -0
- package/dist/components/pages/LiteRegisterPage.svelte.d.ts +10 -0
- package/dist/components/pages/LiteShowPage.svelte +61 -0
- package/dist/components/pages/LiteShowPage.svelte.d.ts +11 -0
- package/dist/components/pages/LiteUpdatePasswordPage.svelte +51 -0
- package/dist/components/pages/LiteUpdatePasswordPage.svelte.d.ts +9 -0
- package/dist/components/pages/index.js +8 -0
- package/dist/components/widgets/LiteAnomalyBadge.svelte +40 -0
- package/dist/components/widgets/LiteAnomalyBadge.svelte.d.ts +15 -0
- package/dist/components/widgets/LiteBarChart.svelte +45 -0
- package/dist/components/widgets/LiteBarChart.svelte.d.ts +17 -0
- package/dist/components/widgets/LiteInsightCard.svelte +31 -0
- package/dist/components/widgets/LiteInsightCard.svelte.d.ts +13 -0
- package/dist/components/widgets/LiteLineChart.svelte +48 -0
- package/dist/components/widgets/LiteLineChart.svelte.d.ts +17 -0
- package/dist/components/widgets/LitePieChart.svelte +44 -0
- package/dist/components/widgets/LitePieChart.svelte.d.ts +17 -0
- package/dist/components/widgets/index.js +5 -0
- package/dist/enhance.js +112 -0
- package/dist/index.d.ts +27 -0
- package/{src/index.ts → dist/index.js} +3 -26
- package/dist/lite.css +817 -0
- package/dist/schema-generator.d.ts +29 -0
- package/dist/schema-generator.js +226 -0
- package/dist/security.d.ts +14 -0
- package/dist/security.js +59 -0
- package/dist/server-adapter.d.ts +111 -0
- package/dist/server-adapter.js +422 -0
- package/package.json +55 -18
- package/src/schema-generator.ts +0 -147
- package/src/server-adapter.ts +0 -307
- /package/{src/components/advanced/index.ts → dist/components/advanced/index.d.ts} +0 -0
- /package/{src/components/buttons/index.ts → dist/components/buttons/index.d.ts} +0 -0
- /package/{src/components/fields/index.ts → dist/components/fields/index.d.ts} +0 -0
- /package/{src/components/layout/index.ts → dist/components/layout/index.d.ts} +0 -0
- /package/{src/components/pages/index.ts → dist/components/pages/index.d.ts} +0 -0
- /package/{src/components/widgets/index.ts → dist/components/widgets/index.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
**Lightweight, SSR-compatible admin UI for [@svadmin](https://github.com/zuohuadong/svadmin).**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Core server-driven CRUD flows can run without hydration. An optional `enhance.js` asset adds progressive client-side conveniences.
|
|
6
|
+
|
|
7
|
+
The bundled CSS follows an IE11-oriented baseline, but Svelte 5, SvelteKit, Tailwind-based companion packages, and each consumer's transpilation target determine the final browser support. This package therefore does not make a blanket IE11 compatibility guarantee.
|
|
6
8
|
|
|
7
9
|
## Why?
|
|
8
10
|
|
|
9
|
-
The main `@svadmin/ui` package delivers a premium SPA experience using Svelte 5, Tailwind CSS v4, and TanStack.
|
|
10
|
-
However, some enterprise/government environments require IE11 compatibility.
|
|
11
|
+
The main `@svadmin/ui` package delivers a premium SPA experience using Svelte 5, Tailwind CSS v4, and TanStack. Those tools target modern browsers. Some enterprise/government environments instead prefer server-driven navigation, native forms, and a smaller client-side runtime.
|
|
11
12
|
|
|
12
13
|
`@svadmin/lite` provides a server-rendered fallback that **shares the same DataProvider, AuthProvider, and Resource definitions** — only the rendering layer is different.
|
|
13
14
|
|
|
@@ -23,7 +24,7 @@ However, some enterprise/government environments require IE11 compatibility.
|
|
|
23
24
|
| **Pagination** | Pure `<a>` page links |
|
|
24
25
|
| **Login/Logout** | Cookie-based auth via SvelteKit Form Actions |
|
|
25
26
|
| **Auth Guard** | Server hook redirects unauthenticated users |
|
|
26
|
-
| **UA Detection** |
|
|
27
|
+
| **UA Detection** | Optional legacy-browser detection hook redirects users to `/lite/` routes |
|
|
27
28
|
| **i18n** | Uses `@svadmin/core` `t()` translations |
|
|
28
29
|
| **Multi-level Menu** | Config-driven 2/3 level menus via `MenuItem[]` |
|
|
29
30
|
| **Print** | `@media print` optimized styles |
|
|
@@ -49,13 +50,16 @@ export const load = createListLoader(dataProvider, postsResource);
|
|
|
49
50
|
export const actions = createCrudActions(dataProvider, postsResource);
|
|
50
51
|
```
|
|
51
52
|
|
|
53
|
+
```typescript
|
|
54
|
+
// src/routes/lite/posts/+page.ts
|
|
55
|
+
export const csr = false;
|
|
56
|
+
```
|
|
57
|
+
|
|
52
58
|
```svelte
|
|
53
59
|
<!-- src/routes/lite/posts/+page.svelte -->
|
|
54
60
|
<script lang="ts">
|
|
55
|
-
export const csr = false; // ← Critical: disable client-side rendering
|
|
56
|
-
|
|
57
61
|
import { LiteLayout, LiteTable, LitePagination, LiteSearch, LiteAlert } from '@svadmin/lite';
|
|
58
|
-
import '@svadmin/lite/
|
|
62
|
+
import '@svadmin/lite/lite.css';
|
|
59
63
|
import { resources } from '$lib/admin';
|
|
60
64
|
|
|
61
65
|
let { data, form } = $props();
|
|
@@ -121,7 +125,7 @@ Pass a `menu` prop to `LiteLayout` to replace the auto-generated flat resource l
|
|
|
121
125
|
</LiteLayout>
|
|
122
126
|
```
|
|
123
127
|
|
|
124
|
-
### 3.
|
|
128
|
+
### 3. Optionally route legacy browsers to Lite pages
|
|
125
129
|
|
|
126
130
|
```typescript
|
|
127
131
|
// src/hooks.server.ts
|
|
@@ -130,7 +134,7 @@ import { createLegacyRedirectHook } from '@svadmin/lite';
|
|
|
130
134
|
export const handle = createLegacyRedirectHook('/lite');
|
|
131
135
|
```
|
|
132
136
|
|
|
133
|
-
### 4.
|
|
137
|
+
### 4. Optional legacy-browser metadata
|
|
134
138
|
|
|
135
139
|
```html
|
|
136
140
|
<!-- src/app.html -->
|
|
@@ -168,8 +172,8 @@ export const handle = createLegacyRedirectHook('/lite');
|
|
|
168
172
|
|
|
169
173
|
## CSS
|
|
170
174
|
|
|
171
|
-
Import `@svadmin/lite/
|
|
172
|
-
- IE11
|
|
175
|
+
Import `@svadmin/lite/lite.css` in your layout. It's fully self-contained:
|
|
176
|
+
- IE11-oriented CSS baseline (standard flexbox, no CSS variables)
|
|
173
177
|
- Custom-styled checkboxes, radios, and selects (no `appearance: none` needed)
|
|
174
178
|
- Indigo/Slate color system aligned with `@svadmin/ui`
|
|
175
179
|
- Modern focus rings (`box-shadow` based)
|
|
@@ -178,14 +182,16 @@ Import `@svadmin/lite/src/lite.css` in your layout. It's fully self-contained:
|
|
|
178
182
|
- Print-optimized styles
|
|
179
183
|
- ~500 lines, ~14KB unminified
|
|
180
184
|
|
|
185
|
+
This CSS baseline helps older browsers, but the generated Svelte/SvelteKit application and any Tailwind v4 UI used alongside Lite still require the browser targets configured by those tools (Tailwind v4 itself targets modern browsers).
|
|
186
|
+
|
|
181
187
|
## Optional: Progressive Enhancement
|
|
182
188
|
|
|
183
|
-
Copy
|
|
189
|
+
Copy the exported `@svadmin/lite/enhance.js` asset to your application's static folder. This ES5 script adds:
|
|
184
190
|
- Auto-close delete confirmation when clicking outside
|
|
185
191
|
- Auto-focus first form input
|
|
186
192
|
- Unsaved changes warning
|
|
187
193
|
|
|
188
|
-
|
|
194
|
+
The asset is optional for core server-rendered navigation and form submission; the conveniences listed above require it.
|
|
189
195
|
|
|
190
196
|
## License
|
|
191
197
|
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* LiteAlert — Success/error feedback banner for form actions.
|
|
4
|
+
* Renders from SvelteKit form action results.
|
|
5
|
+
*/
|
|
6
|
+
interface Props {
|
|
7
|
+
type: 'success' | 'error' | 'info';
|
|
8
|
+
message: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
let { type, message }: Props = $props();
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
{#if message}
|
|
15
|
+
<div class="lite-alert {type === 'success' ? 'lite-alert-success' : type === 'error' ? 'lite-alert-error' : ''}">
|
|
16
|
+
{#if type === 'success'}✓{:else if type === 'error'}✗{:else}ℹ{/if}
|
|
17
|
+
{message}
|
|
18
|
+
</div>
|
|
19
|
+
{/if}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LiteAlert — Success/error feedback banner for form actions.
|
|
3
|
+
* Renders from SvelteKit form action results.
|
|
4
|
+
*/
|
|
5
|
+
interface Props {
|
|
6
|
+
type: 'success' | 'error' | 'info';
|
|
7
|
+
message: string;
|
|
8
|
+
}
|
|
9
|
+
declare const LiteAlert: import("svelte").Component<Props, {}, "">;
|
|
10
|
+
type LiteAlert = ReturnType<typeof LiteAlert>;
|
|
11
|
+
export default LiteAlert;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* LiteArrayField — SSR-compatible array sub-form.
|
|
4
|
+
* One row and remove-on-save controls work without JavaScript; enhance.js
|
|
5
|
+
* progressively adds in-place add/remove controls.
|
|
6
|
+
*/
|
|
7
|
+
import type { FieldDefinition } from '@svadmin/core';
|
|
8
|
+
import LiteArrayItem from './LiteArrayItem.svelte';
|
|
9
|
+
|
|
10
|
+
interface Props {
|
|
11
|
+
field: FieldDefinition;
|
|
12
|
+
/** Current array values */
|
|
13
|
+
values?: Record<string, unknown>[];
|
|
14
|
+
/** Form field name prefix (for nested form encoding) */
|
|
15
|
+
namePrefix?: string;
|
|
16
|
+
mode?: 'create' | 'edit';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let {
|
|
20
|
+
field,
|
|
21
|
+
values = [],
|
|
22
|
+
namePrefix = field.key,
|
|
23
|
+
mode = 'create',
|
|
24
|
+
}: Props = $props();
|
|
25
|
+
|
|
26
|
+
const subFields = $derived(field.subFields || []);
|
|
27
|
+
const renderedValues = $derived(values.length > 0 ? values : [{}]);
|
|
28
|
+
const hasServerValues = $derived(values.length > 0);
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<fieldset
|
|
32
|
+
class="lite-array-field"
|
|
33
|
+
data-lite-array
|
|
34
|
+
data-lite-array-name={namePrefix}
|
|
35
|
+
data-next-index={renderedValues.length}
|
|
36
|
+
>
|
|
37
|
+
<legend>
|
|
38
|
+
{field.label}
|
|
39
|
+
{#if field.required}<span class="required">*</span>{/if}
|
|
40
|
+
</legend>
|
|
41
|
+
|
|
42
|
+
{#each renderedValues as item, i (i)}
|
|
43
|
+
<LiteArrayItem
|
|
44
|
+
{subFields}
|
|
45
|
+
{item}
|
|
46
|
+
{namePrefix}
|
|
47
|
+
index={i}
|
|
48
|
+
isDraft={!field.required && !hasServerValues}
|
|
49
|
+
{mode}
|
|
50
|
+
/>
|
|
51
|
+
{/each}
|
|
52
|
+
|
|
53
|
+
<button type="button" class="lite-btn" data-lite-array-add hidden>
|
|
54
|
+
+ Add Item
|
|
55
|
+
</button>
|
|
56
|
+
|
|
57
|
+
<template data-lite-array-template>
|
|
58
|
+
<LiteArrayItem {subFields} item={{}} {namePrefix} index="__INDEX__" isDraft={false} {mode} />
|
|
59
|
+
</template>
|
|
60
|
+
</fieldset>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LiteArrayField — SSR-compatible array sub-form.
|
|
3
|
+
* One row and remove-on-save controls work without JavaScript; enhance.js
|
|
4
|
+
* progressively adds in-place add/remove controls.
|
|
5
|
+
*/
|
|
6
|
+
import type { FieldDefinition } from '@svadmin/core';
|
|
7
|
+
interface Props {
|
|
8
|
+
field: FieldDefinition;
|
|
9
|
+
/** Current array values */
|
|
10
|
+
values?: Record<string, unknown>[];
|
|
11
|
+
/** Form field name prefix (for nested form encoding) */
|
|
12
|
+
namePrefix?: string;
|
|
13
|
+
mode?: 'create' | 'edit';
|
|
14
|
+
}
|
|
15
|
+
declare const LiteArrayField: import("svelte").Component<Props, {}, "">;
|
|
16
|
+
type LiteArrayField = ReturnType<typeof LiteArrayField>;
|
|
17
|
+
export default LiteArrayField;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { FieldDefinition } from '@svadmin/core';
|
|
3
|
+
import { fieldToInputType, fieldToPlaceholder } from '../schema-generator';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
subFields: FieldDefinition[];
|
|
7
|
+
item: Record<string, unknown>;
|
|
8
|
+
namePrefix: string;
|
|
9
|
+
index: number | string;
|
|
10
|
+
/** Empty optional-array placeholder that remains server-submittable without JS. */
|
|
11
|
+
isDraft?: boolean;
|
|
12
|
+
mode?: 'create' | 'edit';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
let { subFields, item, namePrefix, index, isDraft = false, mode = 'create' }: Props = $props();
|
|
16
|
+
|
|
17
|
+
function fieldName(key: string): string {
|
|
18
|
+
return `${namePrefix}[${index}][${key}]`;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function fieldId(key: string): string {
|
|
22
|
+
return `${namePrefix}_${index}_${key}`;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function displayValue(value: unknown): string {
|
|
26
|
+
if (value == null) return '';
|
|
27
|
+
if (typeof value === 'object') {
|
|
28
|
+
try {
|
|
29
|
+
return JSON.stringify(value);
|
|
30
|
+
} catch {
|
|
31
|
+
return '';
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return String(value);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function retainedUploadReferences(value: unknown): string[] {
|
|
38
|
+
if (typeof value === 'string') return value.trim() ? [value] : [];
|
|
39
|
+
if (Array.isArray(value)) return value.flatMap(retainedUploadReferences);
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
</script>
|
|
43
|
+
|
|
44
|
+
<div
|
|
45
|
+
class="lite-array-item"
|
|
46
|
+
data-lite-array-item
|
|
47
|
+
data-lite-array-draft={isDraft ? '' : undefined}
|
|
48
|
+
>
|
|
49
|
+
<input type="hidden" name={fieldName('_present')} value="1" />
|
|
50
|
+
<div class="lite-array-item-header">
|
|
51
|
+
<span class="lite-array-item-number">#{typeof index === 'number' ? index + 1 : ''}</span>
|
|
52
|
+
{#if !isDraft}
|
|
53
|
+
<button
|
|
54
|
+
type="submit"
|
|
55
|
+
name={fieldName('_delete')}
|
|
56
|
+
value="1"
|
|
57
|
+
formnovalidate
|
|
58
|
+
class="lite-btn lite-btn-sm lite-array-remove-nojs"
|
|
59
|
+
>
|
|
60
|
+
Remove item
|
|
61
|
+
</button>
|
|
62
|
+
{/if}
|
|
63
|
+
<button type="button" class="lite-btn lite-btn-sm lite-array-remove" data-lite-array-remove hidden>
|
|
64
|
+
Remove
|
|
65
|
+
</button>
|
|
66
|
+
</div>
|
|
67
|
+
|
|
68
|
+
{#each subFields as sub (sub.key)}
|
|
69
|
+
<div class="lite-array-subfield">
|
|
70
|
+
<label for={fieldId(sub.key)}>
|
|
71
|
+
{sub.label}
|
|
72
|
+
{#if sub.required}<span class="required">*</span>{/if}
|
|
73
|
+
</label>
|
|
74
|
+
{#if sub.type === 'textarea' || sub.type === 'richtext'}
|
|
75
|
+
<textarea
|
|
76
|
+
id={fieldId(sub.key)}
|
|
77
|
+
name={fieldName(sub.key)}
|
|
78
|
+
class="lite-input"
|
|
79
|
+
rows="3"
|
|
80
|
+
required={sub.required && !isDraft}
|
|
81
|
+
placeholder={fieldToPlaceholder(sub)}
|
|
82
|
+
>{displayValue(item[sub.key])}</textarea>
|
|
83
|
+
{:else if sub.type === 'boolean'}
|
|
84
|
+
<div class="lite-checkbox-group">
|
|
85
|
+
<input
|
|
86
|
+
id={fieldId(sub.key)}
|
|
87
|
+
name={fieldName(sub.key)}
|
|
88
|
+
type="checkbox"
|
|
89
|
+
value="1"
|
|
90
|
+
checked={Boolean(item[sub.key])}
|
|
91
|
+
/>
|
|
92
|
+
<label for={fieldId(sub.key)}>{sub.label}</label>
|
|
93
|
+
</div>
|
|
94
|
+
{:else if (sub.type === 'select' || sub.type === 'multiselect') && sub.options}
|
|
95
|
+
<select
|
|
96
|
+
id={fieldId(sub.key)}
|
|
97
|
+
name={fieldName(sub.key)}
|
|
98
|
+
class="lite-select"
|
|
99
|
+
required={sub.required && !isDraft}
|
|
100
|
+
multiple={sub.type === 'multiselect'}
|
|
101
|
+
>
|
|
102
|
+
{#if sub.type !== 'multiselect'}
|
|
103
|
+
<option value="">-- Select --</option>
|
|
104
|
+
{/if}
|
|
105
|
+
{#each sub.options as opt (opt.value)}
|
|
106
|
+
{@const selectedValue = item[sub.key]}
|
|
107
|
+
<option
|
|
108
|
+
value={String(opt.value)}
|
|
109
|
+
selected={sub.type === 'multiselect'
|
|
110
|
+
? Array.isArray(selectedValue) && selectedValue.map(String).includes(String(opt.value))
|
|
111
|
+
: String(selectedValue ?? '') === String(opt.value)}
|
|
112
|
+
>
|
|
113
|
+
{opt.label}
|
|
114
|
+
</option>
|
|
115
|
+
{/each}
|
|
116
|
+
</select>
|
|
117
|
+
{:else if sub.type === 'file' || sub.type === 'image' || sub.type === 'images'}
|
|
118
|
+
{#if mode === 'edit'}
|
|
119
|
+
{#each retainedUploadReferences(item[sub.key]) as reference, referenceIndex (`${reference}:${referenceIndex}`)}
|
|
120
|
+
<input type="hidden" name={fieldName(sub.key)} value={reference} />
|
|
121
|
+
{/each}
|
|
122
|
+
{/if}
|
|
123
|
+
<input
|
|
124
|
+
id={fieldId(sub.key)}
|
|
125
|
+
name={fieldName(sub.key)}
|
|
126
|
+
type="file"
|
|
127
|
+
class="lite-input"
|
|
128
|
+
required={sub.required
|
|
129
|
+
&& !isDraft
|
|
130
|
+
&& (mode === 'create' || retainedUploadReferences(item[sub.key]).length === 0)}
|
|
131
|
+
multiple={sub.type === 'images'}
|
|
132
|
+
/>
|
|
133
|
+
{:else}
|
|
134
|
+
<input
|
|
135
|
+
id={fieldId(sub.key)}
|
|
136
|
+
name={fieldName(sub.key)}
|
|
137
|
+
type={fieldToInputType(sub)}
|
|
138
|
+
value={displayValue(item[sub.key])}
|
|
139
|
+
class="lite-input"
|
|
140
|
+
required={sub.required && !isDraft}
|
|
141
|
+
placeholder={fieldToPlaceholder(sub)}
|
|
142
|
+
/>
|
|
143
|
+
{/if}
|
|
144
|
+
</div>
|
|
145
|
+
{/each}
|
|
146
|
+
</div>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { FieldDefinition } from '@svadmin/core';
|
|
2
|
+
interface Props {
|
|
3
|
+
subFields: FieldDefinition[];
|
|
4
|
+
item: Record<string, unknown>;
|
|
5
|
+
namePrefix: string;
|
|
6
|
+
index: number | string;
|
|
7
|
+
/** Empty optional-array placeholder that remains server-submittable without JS. */
|
|
8
|
+
isDraft?: boolean;
|
|
9
|
+
mode?: 'create' | 'edit';
|
|
10
|
+
}
|
|
11
|
+
declare const LiteArrayItem: import("svelte").Component<Props, {}, "">;
|
|
12
|
+
type LiteArrayItem = ReturnType<typeof LiteArrayItem>;
|
|
13
|
+
export default LiteArrayItem;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* LiteAuditLog — SSR-compatible audit log viewer.
|
|
4
|
+
* Pure HTML table with pagination links. No client-side JS required.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
interface AuditEntry {
|
|
8
|
+
id: string | number;
|
|
9
|
+
userName?: string;
|
|
10
|
+
action: string;
|
|
11
|
+
resource?: string;
|
|
12
|
+
createdAt: string;
|
|
13
|
+
ipAddress?: string;
|
|
14
|
+
details?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface Props {
|
|
18
|
+
logs: AuditEntry[];
|
|
19
|
+
total?: number;
|
|
20
|
+
page?: number;
|
|
21
|
+
pageSize?: number;
|
|
22
|
+
basePath?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let {
|
|
26
|
+
logs,
|
|
27
|
+
total = 0,
|
|
28
|
+
page = 1,
|
|
29
|
+
pageSize = 20,
|
|
30
|
+
basePath = '?',
|
|
31
|
+
}: Props = $props();
|
|
32
|
+
|
|
33
|
+
const totalPages = $derived(Math.ceil(total / pageSize) || 1);
|
|
34
|
+
|
|
35
|
+
function formatDate(d: string) {
|
|
36
|
+
return new Date(d).toLocaleString();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function actionClass(action: string): string {
|
|
40
|
+
const a = action.toLowerCase();
|
|
41
|
+
if (a.includes('delete') || a.includes('remove')) return 'lite-badge-danger';
|
|
42
|
+
if (a.includes('create') || a.includes('add')) return 'lite-badge-success';
|
|
43
|
+
if (a.includes('update') || a.includes('edit')) return 'lite-badge-warning';
|
|
44
|
+
return 'lite-badge-default';
|
|
45
|
+
}
|
|
46
|
+
</script>
|
|
47
|
+
|
|
48
|
+
<div class="lite-audit-log">
|
|
49
|
+
<h2 style="margin-bottom:16px;">Audit Logs</h2>
|
|
50
|
+
|
|
51
|
+
<table class="lite-table">
|
|
52
|
+
<thead>
|
|
53
|
+
<tr>
|
|
54
|
+
<th style="width:160px;">Time</th>
|
|
55
|
+
<th>User</th>
|
|
56
|
+
<th>Action</th>
|
|
57
|
+
<th>Resource</th>
|
|
58
|
+
<th style="width:120px;">IP Address</th>
|
|
59
|
+
</tr>
|
|
60
|
+
</thead>
|
|
61
|
+
<tbody>
|
|
62
|
+
{#each logs as log, _i (_i)}
|
|
63
|
+
<tr>
|
|
64
|
+
<td style="font-family:monospace;font-size:12px;color:#64748b;">{formatDate(log.createdAt)}</td>
|
|
65
|
+
<td>{log.userName ?? '—'}</td>
|
|
66
|
+
<td><span class="lite-badge {actionClass(log.action)}">{log.action}</span></td>
|
|
67
|
+
<td style="color:#64748b;">{log.resource ?? '—'}</td>
|
|
68
|
+
<td style="font-family:monospace;font-size:12px;color:#64748b;">{log.ipAddress ?? '—'}</td>
|
|
69
|
+
</tr>
|
|
70
|
+
{:else}
|
|
71
|
+
<tr>
|
|
72
|
+
<td colspan="5" style="text-align:center;padding:24px;color:#94a3b8;">No audit logs found.</td>
|
|
73
|
+
</tr>
|
|
74
|
+
{/each}
|
|
75
|
+
</tbody>
|
|
76
|
+
</table>
|
|
77
|
+
|
|
78
|
+
<!-- Pagination -->
|
|
79
|
+
{#if totalPages > 1}
|
|
80
|
+
<div class="lite-pagination" style="margin-top:12px;">
|
|
81
|
+
{#if page > 1}
|
|
82
|
+
<a href={`${basePath}page={page - 1}`} class="lite-btn lite-btn-sm">« Prev</a>
|
|
83
|
+
{/if}
|
|
84
|
+
<span style="padding:0 12px;font-size:14px;color:#64748b;">Page {page} / {totalPages} ({total} total)</span>
|
|
85
|
+
{#if page < totalPages}
|
|
86
|
+
<a href={`${basePath}page={page + 1}`} class="lite-btn lite-btn-sm">Next »</a>
|
|
87
|
+
{/if}
|
|
88
|
+
</div>
|
|
89
|
+
{/if}
|
|
90
|
+
</div>
|
|
91
|
+
|
|
92
|
+
<style>
|
|
93
|
+
.lite-badge {
|
|
94
|
+
display: inline-block;
|
|
95
|
+
padding: 2px 8px;
|
|
96
|
+
border-radius: 4px;
|
|
97
|
+
font-size: 12px;
|
|
98
|
+
font-weight: 600;
|
|
99
|
+
}
|
|
100
|
+
.lite-badge-danger { background: #fef2f2; color: #dc2626; border: 1px solid #fecaca; }
|
|
101
|
+
.lite-badge-success { background: #f0fdf4; color: #166534; border: 1px solid #bbf7d0; }
|
|
102
|
+
.lite-badge-warning { background: #fffbeb; color: #92400e; border: 1px solid #fde68a; }
|
|
103
|
+
.lite-badge-default { background: #f1f5f9; color: #475569; border: 1px solid #e2e8f0; }
|
|
104
|
+
</style>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LiteAuditLog — SSR-compatible audit log viewer.
|
|
3
|
+
* Pure HTML table with pagination links. No client-side JS required.
|
|
4
|
+
*/
|
|
5
|
+
interface AuditEntry {
|
|
6
|
+
id: string | number;
|
|
7
|
+
userName?: string;
|
|
8
|
+
action: string;
|
|
9
|
+
resource?: string;
|
|
10
|
+
createdAt: string;
|
|
11
|
+
ipAddress?: string;
|
|
12
|
+
details?: string;
|
|
13
|
+
}
|
|
14
|
+
interface Props {
|
|
15
|
+
logs: AuditEntry[];
|
|
16
|
+
total?: number;
|
|
17
|
+
page?: number;
|
|
18
|
+
pageSize?: number;
|
|
19
|
+
basePath?: string;
|
|
20
|
+
}
|
|
21
|
+
declare const LiteAuditLog: import("svelte").Component<Props, {}, "">;
|
|
22
|
+
type LiteAuditLog = ReturnType<typeof LiteAuditLog>;
|
|
23
|
+
export default LiteAuditLog;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* LiteBreadcrumbs — SSR-compatible breadcrumb navigation.
|
|
4
|
+
* Pure HTML <nav> with <a> links. No client-side JS required.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
interface BreadcrumbItem {
|
|
8
|
+
label: string;
|
|
9
|
+
href?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface Props {
|
|
13
|
+
items: BreadcrumbItem[];
|
|
14
|
+
/** Separator character between items */
|
|
15
|
+
separator?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let {
|
|
19
|
+
items,
|
|
20
|
+
separator = '/',
|
|
21
|
+
}: Props = $props();
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<nav class="lite-breadcrumbs" aria-label="Breadcrumb">
|
|
25
|
+
<ol>
|
|
26
|
+
{#each items as item, i (i)}
|
|
27
|
+
<li>
|
|
28
|
+
{#if item.href && i < items.length - 1}
|
|
29
|
+
<a href={item.href}>{item.label}</a>
|
|
30
|
+
{:else}
|
|
31
|
+
<span class="current">{item.label}</span>
|
|
32
|
+
{/if}
|
|
33
|
+
{#if i < items.length - 1}
|
|
34
|
+
<span class="lite-breadcrumb-sep" aria-hidden="true">{separator}</span>
|
|
35
|
+
{/if}
|
|
36
|
+
</li>
|
|
37
|
+
{/each}
|
|
38
|
+
</ol>
|
|
39
|
+
</nav>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LiteBreadcrumbs — SSR-compatible breadcrumb navigation.
|
|
3
|
+
* Pure HTML <nav> with <a> links. No client-side JS required.
|
|
4
|
+
*/
|
|
5
|
+
interface BreadcrumbItem {
|
|
6
|
+
label: string;
|
|
7
|
+
href?: string;
|
|
8
|
+
}
|
|
9
|
+
interface Props {
|
|
10
|
+
items: BreadcrumbItem[];
|
|
11
|
+
/** Separator character between items */
|
|
12
|
+
separator?: string;
|
|
13
|
+
}
|
|
14
|
+
declare const LiteBreadcrumbs: import("svelte").Component<Props, {}, "">;
|
|
15
|
+
type LiteBreadcrumbs = ReturnType<typeof LiteBreadcrumbs>;
|
|
16
|
+
export default LiteBreadcrumbs;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* LiteChatDialog — SSR-compatible AI Chat Dialog fallback.
|
|
4
|
+
* Relies on standard <form> POST without polling or WebSockets.
|
|
5
|
+
* No client-side JS required.
|
|
6
|
+
*/
|
|
7
|
+
import type { ChatMessage } from '@svadmin/core';
|
|
8
|
+
|
|
9
|
+
interface Props {
|
|
10
|
+
/** History of messages */
|
|
11
|
+
messages: ChatMessage[];
|
|
12
|
+
/** URL to handle the POST request for new messages */
|
|
13
|
+
actionRoute: string;
|
|
14
|
+
/** If true, shows a "Thinking..." indicator */
|
|
15
|
+
isLoading?: boolean;
|
|
16
|
+
title?: string;
|
|
17
|
+
placeholder?: string;
|
|
18
|
+
submitLabel?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
let {
|
|
22
|
+
messages = [],
|
|
23
|
+
actionRoute,
|
|
24
|
+
isLoading = false,
|
|
25
|
+
title = 'AI Assistant',
|
|
26
|
+
placeholder = 'Type your message...',
|
|
27
|
+
submitLabel = 'Send'
|
|
28
|
+
}: Props = $props();
|
|
29
|
+
|
|
30
|
+
function formatDate(ts: number) {
|
|
31
|
+
if (!ts) return '';
|
|
32
|
+
return new Date(ts).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Auto-scroll anchor logic: pure HTML way to scroll to bottom after page load
|
|
36
|
+
// User should include "#latest-msg" in the form action if possible
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<div class="lite-chat-dialog lite-card" style="display:flex;flex-direction:column;height:560px;padding:0;overflow:hidden;max-width:400px;margin:0 auto;">
|
|
40
|
+
<!-- Header -->
|
|
41
|
+
<div style="background:#0f172a;color:#fff;padding:14px 16px;font-weight:600;flex-shrink:0;display:flex;align-items:center;border-top-left-radius:8px;border-top-right-radius:8px;">
|
|
42
|
+
{title}
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
<!-- Message History -->
|
|
46
|
+
<div class="lite-chat-history" style="flex:1;overflow-y:auto;padding:16px;background:#f8fafc;">
|
|
47
|
+
{#if messages.length === 0}
|
|
48
|
+
<div style="text-align:center;color:#64748b;margin-top:60px;font-size:14px;">
|
|
49
|
+
How can I help you today?
|
|
50
|
+
</div>
|
|
51
|
+
{/if}
|
|
52
|
+
|
|
53
|
+
{#each messages as msg, i (i)}
|
|
54
|
+
{#if msg.role === 'user' || msg.role === 'assistant'}
|
|
55
|
+
<div
|
|
56
|
+
id={i === messages.length - 1 ? 'latest-msg' : ''}
|
|
57
|
+
style="margin-bottom:16px;display:flex;flex-direction:column;align-items:{msg.role === 'user' ? 'flex-end' : 'flex-start'};"
|
|
58
|
+
>
|
|
59
|
+
<div style="
|
|
60
|
+
max-width:85%;
|
|
61
|
+
padding:10px 14px;
|
|
62
|
+
border-radius:12px;
|
|
63
|
+
font-size:14px;
|
|
64
|
+
line-height:1.5;
|
|
65
|
+
{msg.role === 'user'
|
|
66
|
+
? 'background:#4f46e5;color:#fff;border-bottom-right-radius:2px;'
|
|
67
|
+
: 'background:#e2e8f0;color:#0f172a;border-bottom-left-radius:2px;'}"
|
|
68
|
+
>
|
|
69
|
+
<div style="white-space:pre-wrap;word-break:break-word;">{msg.content}</div>
|
|
70
|
+
</div>
|
|
71
|
+
<div style="font-size:11px;color:#94a3b8;margin-top:4px;">
|
|
72
|
+
{msg.role === 'user' ? 'You' : 'Assistant'} • {formatDate(msg.timestamp)}
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
{/if}
|
|
76
|
+
{/each}
|
|
77
|
+
|
|
78
|
+
{#if isLoading}
|
|
79
|
+
<div id="latest-msg" style="display:flex;flex-direction:column;align-items:flex-start;margin-bottom:16px;">
|
|
80
|
+
<div style="background:#e2e8f0;color:#64748b;padding:10px 14px;border-radius:12px;border-bottom-left-radius:2px;font-size:13px;font-style:italic;">
|
|
81
|
+
Thinking...
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
84
|
+
{/if}
|
|
85
|
+
</div>
|
|
86
|
+
|
|
87
|
+
<!-- Input Form -->
|
|
88
|
+
<form method="POST" action={actionRoute} style="display:flex;padding:12px;background:#fff;border-top:1px solid #e2e8f0;align-items:stretch;margin:0;flex-shrink:0;">
|
|
89
|
+
<textarea
|
|
90
|
+
name="message"
|
|
91
|
+
class="lite-input"
|
|
92
|
+
placeholder={placeholder}
|
|
93
|
+
required
|
|
94
|
+
rows="1"
|
|
95
|
+
style="min-height:40px;resize:none;margin-right:8px;"
|
|
96
|
+
></textarea>
|
|
97
|
+
<button type="submit" class="lite-btn lite-btn-primary" disabled={isLoading} style="display:flex;align-items:center;padding:0 16px;">
|
|
98
|
+
{submitLabel}
|
|
99
|
+
</button>
|
|
100
|
+
</form>
|
|
101
|
+
</div>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LiteChatDialog — SSR-compatible AI Chat Dialog fallback.
|
|
3
|
+
* Relies on standard <form> POST without polling or WebSockets.
|
|
4
|
+
* No client-side JS required.
|
|
5
|
+
*/
|
|
6
|
+
import type { ChatMessage } from '@svadmin/core';
|
|
7
|
+
interface Props {
|
|
8
|
+
/** History of messages */
|
|
9
|
+
messages: ChatMessage[];
|
|
10
|
+
/** URL to handle the POST request for new messages */
|
|
11
|
+
actionRoute: string;
|
|
12
|
+
/** If true, shows a "Thinking..." indicator */
|
|
13
|
+
isLoading?: boolean;
|
|
14
|
+
title?: string;
|
|
15
|
+
placeholder?: string;
|
|
16
|
+
submitLabel?: string;
|
|
17
|
+
}
|
|
18
|
+
declare const LiteChatDialog: import("svelte").Component<Props, {}, "">;
|
|
19
|
+
type LiteChatDialog = ReturnType<typeof LiteChatDialog>;
|
|
20
|
+
export default LiteChatDialog;
|