@svadmin/ui 0.73.0 → 0.74.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/README.md +53 -28
- package/dist/app.css +3733 -4119
- package/dist/app.theme.css +3733 -4119
- package/dist/component-registry.d.ts +14977 -0
- package/dist/component-registry.js +216 -0
- package/dist/components/AboutSettings.svelte +7 -1
- package/dist/components/AboutSettings.svelte.d.ts +4 -1
- package/dist/components/ActivityFeed.svelte +9 -3
- package/dist/components/ActivityFeed.svelte.d.ts +3 -0
- package/dist/components/AdminApp.svelte +19 -10
- package/dist/components/AdminApp.svelte.d.ts +6 -0
- package/dist/components/ApiSettings.svelte +41 -5
- package/dist/components/ApprovalCenter.svelte +283 -0
- package/dist/components/ApprovalCenter.svelte.d.ts +10 -0
- package/dist/components/AuditLogViewer.svelte +3 -1
- package/dist/components/AutoForm.svelte +33 -3
- package/dist/components/AutoForm.svelte.d.ts +1 -0
- package/dist/components/AutoTable.svelte +610 -47
- package/dist/components/AutoTable.svelte.d.ts +17 -1
- package/dist/components/BoundRecordDetailDrawer.svelte +9 -0
- package/dist/components/BoundRecordDetailDrawer.svelte.d.ts +2 -0
- package/dist/components/Breadcrumbs.svelte +11 -1
- package/dist/components/CancelTaskButton.svelte +12 -42
- package/dist/components/ColorPicker.svelte +73 -0
- package/dist/components/ColorPicker.svelte.d.ts +15 -0
- package/dist/components/ComboboxField.svelte +114 -27
- package/dist/components/ComboboxField.svelte.d.ts +1 -0
- package/dist/components/DashboardView.svelte +99 -0
- package/dist/components/DashboardView.svelte.d.ts +14 -0
- package/dist/components/DatePicker.svelte +10 -0
- package/dist/components/DatePicker.svelte.d.ts +6 -0
- package/dist/components/DateRangeInput.svelte +85 -5
- package/dist/components/DateRangeInput.svelte.d.ts +10 -0
- package/dist/components/DateRangePicker.svelte +10 -0
- package/dist/components/DateRangePicker.svelte.d.ts +6 -0
- package/dist/components/DateTimeInput.svelte +74 -5
- package/dist/components/DateTimeInput.svelte.d.ts +8 -0
- package/dist/components/DateTimePicker.svelte +10 -0
- package/dist/components/DateTimePicker.svelte.d.ts +6 -0
- package/dist/components/DevTools.svelte +34 -26
- package/dist/components/DevframePanel.svelte +123 -0
- package/dist/components/DevframePanel.svelte.d.ts +3 -0
- package/dist/components/ErrorSummary.svelte +52 -0
- package/dist/components/ErrorSummary.svelte.d.ts +14 -0
- package/dist/components/FieldRenderer.svelte +82 -81
- package/dist/components/FileUpload.svelte +214 -52
- package/dist/components/FileUpload.svelte.d.ts +11 -0
- package/dist/components/FilterBuilder.svelte +88 -66
- package/dist/components/FilterCollectionInput.svelte +80 -0
- package/dist/components/FilterCollectionInput.svelte.d.ts +10 -0
- package/dist/components/GanttChart.svelte +66 -14
- package/dist/components/GanttChart.svelte.d.ts +6 -0
- package/dist/components/Header.svelte +18 -2
- package/dist/components/ImportWizard.svelte +339 -17
- package/dist/components/ImportWizard.svelte.d.ts +11 -0
- package/dist/components/JsonSchemaForm.svelte +120 -52
- package/dist/components/JsonSchemaForm.svelte.d.ts +7 -1
- package/dist/components/KanbanBoard.svelte +195 -40
- package/dist/components/KanbanBoard.svelte.d.ts +9 -2
- package/dist/components/Layout.svelte +4 -2
- package/dist/components/LazyAutoForm.svelte +28 -0
- package/dist/components/LazyAutoForm.svelte.d.ts +8 -0
- package/dist/components/LazyAutoTable.svelte +28 -0
- package/dist/components/LazyAutoTable.svelte.d.ts +8 -0
- package/dist/components/LazySettingsPage.svelte +28 -0
- package/dist/components/LazySettingsPage.svelte.d.ts +8 -0
- package/dist/components/LazyShowPage.svelte +28 -0
- package/dist/components/LazyShowPage.svelte.d.ts +8 -0
- package/dist/components/ListPage.svelte +5 -1
- package/dist/components/ListPage.svelte.d.ts +3 -0
- package/dist/components/LoginPage.svelte +1 -1
- package/dist/components/MultiTabKeepAlive.svelte +11 -6
- package/dist/components/NotificationsSettings.svelte +69 -2
- package/dist/components/NotificationsSettings.svelte.d.ts +25 -1
- package/dist/components/PermissionMatrix.svelte +20 -1
- package/dist/components/PivotExportButton.svelte +157 -0
- package/dist/components/PivotExportButton.svelte.d.ts +16 -0
- package/dist/components/PivotTable.svelte +229 -74
- package/dist/components/PivotTable.svelte.d.ts +19 -2
- package/dist/components/RadioGroup.svelte +121 -0
- package/dist/components/RadioGroup.svelte.d.ts +43 -0
- package/dist/components/RangeSlider.svelte +127 -0
- package/dist/components/RangeSlider.svelte.d.ts +22 -0
- package/dist/components/Rate.svelte +121 -0
- package/dist/components/Rate.svelte.d.ts +16 -0
- package/dist/components/RecordDetailDrawer.svelte +4 -2
- package/dist/components/RecordDetailDrawer.svelte.d.ts +2 -0
- package/dist/components/RelationPicker.svelte +341 -0
- package/dist/components/RelationPicker.svelte.d.ts +26 -0
- package/dist/components/ResourceOperationsPage.svelte +18 -18
- package/dist/components/ResourceOperationsPage.svelte.d.ts +2 -2
- package/dist/components/RetryTaskButton.svelte +12 -42
- package/dist/components/SecuritySettings.svelte +29 -5
- package/dist/components/SegmentedControl.svelte +145 -0
- package/dist/components/SegmentedControl.svelte.d.ts +38 -0
- package/dist/components/SettingsPage.svelte +3 -1
- package/dist/components/SettingsPage.svelte.d.ts +1 -0
- package/dist/components/ShowPage.svelte +18 -3
- package/dist/components/ShowPage.svelte.d.ts +3 -0
- package/dist/components/Sidebar.svelte +2 -2
- package/dist/components/Slider.svelte +100 -0
- package/dist/components/Slider.svelte.d.ts +19 -0
- package/dist/components/SpreadsheetView.svelte +1213 -95
- package/dist/components/SpreadsheetView.svelte.d.ts +19 -0
- package/dist/components/TagsInput.svelte +178 -0
- package/dist/components/TagsInput.svelte.d.ts +17 -0
- package/dist/components/TimePicker.svelte +10 -0
- package/dist/components/TimePicker.svelte.d.ts +6 -0
- package/dist/components/TreeSelect.svelte +267 -53
- package/dist/components/TreeSelect.svelte.d.ts +3 -0
- package/dist/components/TreeTable.svelte +484 -82
- package/dist/components/TreeTable.svelte.d.ts +24 -1
- package/dist/components/TwoFactorAuthPage.svelte +85 -48
- package/dist/components/TwoFactorAuthPage.svelte.d.ts +12 -1
- package/dist/components/VirtualTable.svelte +116 -20
- package/dist/components/VirtualTable.svelte.d.ts +5 -0
- package/dist/components/account/CompanyProfilePage.svelte +74 -38
- package/dist/components/account/GetStartedPage.svelte +2 -1
- package/dist/components/account/ImportMembersPage.svelte +22 -167
- package/dist/components/account/ImportMembersPage.svelte.d.ts +4 -1
- package/dist/components/account/MemberDirectory.svelte +156 -0
- package/dist/components/account/MemberDirectory.svelte.d.ts +19 -0
- package/dist/components/account/MembersStarterPage.svelte +9 -55
- package/dist/components/account/MembersStarterPage.svelte.d.ts +5 -1
- package/dist/components/account/SecurityLogPage.svelte +4 -1
- package/dist/components/account/SettingsPlainPage.svelte +7 -38
- package/dist/components/account/SettingsPlainPage.svelte.d.ts +4 -1
- package/dist/components/account/SettingsSidebarPage.svelte +7 -20
- package/dist/components/account/TeamMembersPage.svelte +4 -20
- package/dist/components/account/TeamMembersPage.svelte.d.ts +5 -1
- package/dist/components/account/UserProfilePage.svelte +3 -25
- package/dist/components/account/UserProfilePage.svelte.d.ts +17 -2
- package/dist/components/buttons/ExportButton.svelte +56 -12
- package/dist/components/buttons/ExportButton.svelte.d.ts +11 -0
- package/dist/components/content/ContentPageHeader.svelte +1 -1
- package/dist/components/content/ContentPageShell.svelte +1 -1
- package/dist/components/content/MetricBlock.svelte +1 -1
- package/dist/components/content/PageToolbar.svelte +1 -1
- package/dist/components/content/ReferenceNotice.svelte +5 -0
- package/dist/components/content/ReferenceNotice.svelte.d.ts +18 -0
- package/dist/components/content/SectionHeader.svelte +1 -1
- package/dist/components/content/SettingsFieldRow.svelte +1 -1
- package/dist/components/content/SettingsGroup.svelte +1 -1
- package/dist/components/content/StatusBadge.svelte +1 -1
- package/dist/components/content/WorkspaceLayout.svelte +1 -1
- package/dist/components/export-reference.d.ts +2 -0
- package/dist/components/export-reference.js +9 -0
- package/dist/components/fieldComponentMap.js +2 -5
- package/dist/components/fields/DateField.svelte +12 -13
- package/dist/components/fields/date-display.d.ts +6 -0
- package/dist/components/fields/date-display.js +24 -0
- package/dist/components/network/TeamCrewTablePage.svelte +6 -1
- package/dist/components/network/UserCardsNFTPage.svelte +2 -0
- package/dist/components/profile/PublicProfilePage.svelte +2 -0
- package/dist/components/saved-list-views.d.ts +74 -1
- package/dist/components/saved-list-views.js +191 -3
- package/dist/components/table-contract.d.ts +12 -1
- package/dist/components/task-action.svelte.d.ts +13 -0
- package/dist/components/task-action.svelte.js +73 -0
- package/dist/components/ui/DesignSystemShowcase.svelte +164 -0
- package/dist/components/ui/DesignSystemShowcase.svelte.d.ts +3 -0
- package/dist/components/ui/badge/badge-variants.d.ts +3 -2
- package/dist/components/ui/badge/badge-variants.js +2 -3
- package/dist/components/ui/badge/badge.svelte +3 -0
- package/dist/components/ui/badge/badge.svelte.d.ts +1 -0
- package/dist/components/ui/button/button-variants.d.ts +5 -4
- package/dist/components/ui/button/button-variants.js +7 -5
- package/dist/components/ui/checkbox/checkbox.svelte +5 -1
- package/dist/components/ui/checkbox/checkbox.svelte.d.ts +5 -1
- package/dist/components/ui/input/input.svelte +7 -2
- package/dist/components/ui/input/input.svelte.d.ts +4 -1
- package/dist/components/ui/select/select.svelte +4 -1
- package/dist/components/ui/select/select.svelte.d.ts +2 -1
- package/dist/components/ui/textarea/textarea.svelte +2 -2
- package/dist/components.css +33 -2
- package/dist/date-input-policy.d.ts +4 -0
- package/dist/date-input-policy.js +35 -0
- package/dist/design-system-components.d.ts +100 -0
- package/dist/design-system-components.js +101 -0
- package/dist/design-system.js +1 -1
- package/dist/devtools-bridge.d.ts +80 -0
- package/dist/devtools-bridge.js +92 -0
- package/dist/index.d.ts +37 -2
- package/dist/index.js +23 -2
- package/dist/recipes.d.ts +960 -4
- package/dist/recipes.js +264 -4
- package/dist/tree-table-model.d.ts +24 -0
- package/dist/tree-table-model.js +111 -0
- package/package.json +22 -10
- package/dist/styled-system/css/conditions.js +0 -36
- package/dist/styled-system/css/css.d.ts +0 -22
- package/dist/styled-system/css/css.js +0 -45
- package/dist/styled-system/css/cva.d.ts +0 -6
- package/dist/styled-system/css/cva.js +0 -87
- package/dist/styled-system/css/cx.d.ts +0 -5
- package/dist/styled-system/css/cx.js +0 -15
- package/dist/styled-system/css/index.d.ts +0 -5
- package/dist/styled-system/css/index.js +0 -4
- package/dist/styled-system/css/sva.d.ts +0 -4
- package/dist/styled-system/css/sva.js +0 -46
- package/dist/styled-system/helpers.js +0 -316
- package/dist/styled-system/patterns/aspect-ratio.d.ts +0 -20
- package/dist/styled-system/patterns/aspect-ratio.js +0 -38
- package/dist/styled-system/patterns/bleed.d.ts +0 -21
- package/dist/styled-system/patterns/bleed.js +0 -24
- package/dist/styled-system/patterns/box.d.ts +0 -20
- package/dist/styled-system/patterns/box.js +0 -15
- package/dist/styled-system/patterns/center.d.ts +0 -20
- package/dist/styled-system/patterns/center.js +0 -21
- package/dist/styled-system/patterns/circle.d.ts +0 -20
- package/dist/styled-system/patterns/circle.js +0 -25
- package/dist/styled-system/patterns/container.d.ts +0 -20
- package/dist/styled-system/patterns/container.js +0 -21
- package/dist/styled-system/patterns/cq.d.ts +0 -21
- package/dist/styled-system/patterns/cq.js +0 -21
- package/dist/styled-system/patterns/divider.d.ts +0 -22
- package/dist/styled-system/patterns/divider.js +0 -25
- package/dist/styled-system/patterns/flex.d.ts +0 -26
- package/dist/styled-system/patterns/flex.js +0 -26
- package/dist/styled-system/patterns/float.d.ts +0 -23
- package/dist/styled-system/patterns/float.js +0 -52
- package/dist/styled-system/patterns/grid-item.d.ts +0 -25
- package/dist/styled-system/patterns/grid-item.js +0 -25
- package/dist/styled-system/patterns/grid.d.ts +0 -24
- package/dist/styled-system/patterns/grid.js +0 -27
- package/dist/styled-system/patterns/hstack.d.ts +0 -21
- package/dist/styled-system/patterns/hstack.js +0 -24
- package/dist/styled-system/patterns/index.d.ts +0 -21
- package/dist/styled-system/patterns/index.js +0 -20
- package/dist/styled-system/patterns/link-overlay.d.ts +0 -20
- package/dist/styled-system/patterns/link-overlay.js +0 -24
- package/dist/styled-system/patterns/spacer.d.ts +0 -20
- package/dist/styled-system/patterns/spacer.js +0 -25
- package/dist/styled-system/patterns/square.d.ts +0 -20
- package/dist/styled-system/patterns/square.js +0 -24
- package/dist/styled-system/patterns/stack.d.ts +0 -23
- package/dist/styled-system/patterns/stack.js +0 -24
- package/dist/styled-system/patterns/visually-hidden.d.ts +0 -20
- package/dist/styled-system/patterns/visually-hidden.js +0 -18
- package/dist/styled-system/patterns/vstack.d.ts +0 -21
- package/dist/styled-system/patterns/vstack.js +0 -24
- package/dist/styled-system/patterns/wrap.d.ts +0 -24
- package/dist/styled-system/patterns/wrap.js +0 -25
- package/dist/styled-system/recipes/content-header.d.ts +0 -31
- package/dist/styled-system/recipes/content-header.js +0 -65
- package/dist/styled-system/recipes/content-page.d.ts +0 -34
- package/dist/styled-system/recipes/content-page.js +0 -43
- package/dist/styled-system/recipes/create-recipe.js +0 -82
- package/dist/styled-system/recipes/index.d.ts +0 -17
- package/dist/styled-system/recipes/index.js +0 -16
- package/dist/styled-system/recipes/metric-block.d.ts +0 -34
- package/dist/styled-system/recipes/metric-block.js +0 -76
- package/dist/styled-system/recipes/product-list.d.ts +0 -31
- package/dist/styled-system/recipes/product-list.js +0 -73
- package/dist/styled-system/recipes/product-section.d.ts +0 -31
- package/dist/styled-system/recipes/product-section.js +0 -49
- package/dist/styled-system/recipes/product-settings-row.d.ts +0 -34
- package/dist/styled-system/recipes/product-settings-row.js +0 -58
- package/dist/styled-system/recipes/product-settings.d.ts +0 -31
- package/dist/styled-system/recipes/product-settings.js +0 -57
- package/dist/styled-system/recipes/product-status.d.ts +0 -34
- package/dist/styled-system/recipes/product-status.js +0 -45
- package/dist/styled-system/recipes/product-toolbar.d.ts +0 -31
- package/dist/styled-system/recipes/product-toolbar.js +0 -41
- package/dist/styled-system/recipes/product-workspace.d.ts +0 -34
- package/dist/styled-system/recipes/product-workspace.js +0 -58
- package/dist/styled-system/recipes/surface-metric.d.ts +0 -38
- package/dist/styled-system/recipes/surface-metric.js +0 -63
- package/dist/styled-system/recipes/surface-table.d.ts +0 -34
- package/dist/styled-system/recipes/surface-table.js +0 -62
- package/dist/styled-system/recipes/ui-badge.d.ts +0 -31
- package/dist/styled-system/recipes/ui-badge.js +0 -38
- package/dist/styled-system/recipes/ui-button.d.ts +0 -32
- package/dist/styled-system/recipes/ui-button.js +0 -43
- package/dist/styled-system/recipes/ui-input.d.ts +0 -31
- package/dist/styled-system/recipes/ui-input.js +0 -49
- package/dist/styled-system/recipes/ui-textarea.d.ts +0 -31
- package/dist/styled-system/recipes/ui-textarea.js +0 -24
- package/dist/styled-system/styles.css +0 -1257
- package/dist/styled-system/tokens/index.d.ts +0 -9
- package/dist/styled-system/tokens/index.js +0 -268
- package/dist/styled-system/tokens/tokens.d.ts +0 -36
- package/dist/styled-system/types/composition.d.ts +0 -227
- package/dist/styled-system/types/conditions.d.ts +0 -236
- package/dist/styled-system/types/csstype.d.ts +0 -22570
- package/dist/styled-system/types/index.d.ts +0 -6
- package/dist/styled-system/types/parts.d.ts +0 -8
- package/dist/styled-system/types/pattern.d.ts +0 -78
- package/dist/styled-system/types/prop-type.d.ts +0 -223
- package/dist/styled-system/types/recipe.d.ts +0 -181
- package/dist/styled-system/types/selectors.d.ts +0 -59
- package/dist/styled-system/types/static-css.d.ts +0 -56
- package/dist/styled-system/types/style-props.d.ts +0 -8088
- package/dist/styled-system/types/system-types.d.ts +0 -151
- package/dist/styles/recipes.css +0 -1262
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { cn } from '../utils.js';
|
|
3
|
+
import { useTranslation } from '@svadmin/core/i18n';
|
|
4
|
+
import { captureAdminContext, captureAuthSession, type RegisteredAccessControlProvider } from '@svadmin/core';
|
|
5
|
+
import { buildPivot, buildPivotCacheKey, buildPivotDrilldown, decodePivotResult, snapshotPivotQuery, formatPivotValue, type PivotCache, type PivotProvider, type PivotQuery, type PivotResult, type PivotDrilldown } from '@svadmin/core/pivot';
|
|
6
|
+
import type { Filter } from '@svadmin/core';
|
|
7
|
+
import { definedOptions } from '@svadmin/core/options';
|
|
8
|
+
import { snapshotPlainData } from '@svadmin/core/schema';
|
|
9
|
+
import { RotateCw } from '@lucide/svelte';
|
|
10
|
+
import { Button } from './ui/button/index.js';
|
|
3
11
|
|
|
4
|
-
export type AggregationFn = '
|
|
12
|
+
export type AggregationFn = import('@svadmin/core/pivot').PivotAggregation;
|
|
5
13
|
|
|
6
14
|
interface Props {
|
|
7
|
-
data
|
|
15
|
+
data?: Record<string, unknown>[];
|
|
8
16
|
rowField: string;
|
|
9
17
|
rowLabel?: string;
|
|
10
18
|
columnField: string;
|
|
@@ -13,7 +21,22 @@
|
|
|
13
21
|
valueLabel?: string;
|
|
14
22
|
aggregator?: AggregationFn;
|
|
15
23
|
formatValue?: (val: number) => string;
|
|
24
|
+
loading?: boolean;
|
|
25
|
+
error?: string | undefined;
|
|
26
|
+
onRetry?: () => void;
|
|
27
|
+
onDrillDown?: (input: PivotDrilldown) => void | Promise<void>;
|
|
28
|
+
ariaLabel?: string;
|
|
16
29
|
class?: string;
|
|
30
|
+
resource?: string;
|
|
31
|
+
provider?: PivotProvider | undefined;
|
|
32
|
+
cache?: PivotCache;
|
|
33
|
+
/** 由宿主提供的身份、租户和授权版本作用域键;服务端模式必须非空。 */
|
|
34
|
+
scopeKey?: string;
|
|
35
|
+
filters?: Filter[];
|
|
36
|
+
meta?: Record<string, unknown>;
|
|
37
|
+
enabled?: boolean;
|
|
38
|
+
accessCheck?: boolean;
|
|
39
|
+
aggregateData?: unknown;
|
|
17
40
|
}
|
|
18
41
|
|
|
19
42
|
let {
|
|
@@ -25,116 +48,248 @@
|
|
|
25
48
|
valueField,
|
|
26
49
|
valueLabel = valueField,
|
|
27
50
|
aggregator = 'sum',
|
|
28
|
-
formatValue
|
|
51
|
+
formatValue,
|
|
52
|
+
loading = false,
|
|
53
|
+
error,
|
|
54
|
+
onRetry,
|
|
55
|
+
onDrillDown,
|
|
56
|
+
ariaLabel,
|
|
29
57
|
class: className = '',
|
|
58
|
+
resource = '',
|
|
59
|
+
provider,
|
|
60
|
+
cache,
|
|
61
|
+
scopeKey,
|
|
62
|
+
filters,
|
|
63
|
+
meta,
|
|
64
|
+
enabled = true,
|
|
65
|
+
accessCheck = true,
|
|
66
|
+
aggregateData,
|
|
30
67
|
}: Props = $props();
|
|
31
68
|
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
69
|
+
const i18n = useTranslation();
|
|
70
|
+
const adminContext = captureAdminContext();
|
|
71
|
+
const authScope = $derived(captureAuthSession(adminContext.authProvider));
|
|
72
|
+
const tenantScope = $derived(adminContext.tenantCacheKey?.__svadminTenant);
|
|
73
|
+
const permissionProvider = $derived(accessCheck ? adminContext.accessControlProvider : null);
|
|
74
|
+
let remotePivot = $state<PivotResult | undefined>(undefined);
|
|
75
|
+
let remoteLoading = $state(false);
|
|
76
|
+
let remoteError = $state<PivotResult['error']>();
|
|
77
|
+
let remotePermissionDenied = $state(false);
|
|
78
|
+
let retryVersion = $state(0);
|
|
79
|
+
let requestEpoch = 0;
|
|
80
|
+
let requestOwner = $state.raw<{
|
|
81
|
+
provider: PivotProvider | undefined;
|
|
82
|
+
query: PivotQuery | undefined;
|
|
83
|
+
scope: string | undefined;
|
|
84
|
+
enabled: boolean;
|
|
85
|
+
retry: number;
|
|
86
|
+
permission: RegisteredAccessControlProvider | null;
|
|
87
|
+
cache: PivotCache | undefined;
|
|
88
|
+
cacheProviderKey: string | undefined;
|
|
89
|
+
authScope: ReturnType<typeof captureAuthSession>;
|
|
90
|
+
tenantScope: typeof tenantScope;
|
|
91
|
+
}>();
|
|
92
|
+
const remoteQuery = $derived(snapshotPivotQuery(definedOptions({
|
|
93
|
+
resource, rowField, columnField, valueField, aggregator, filters, meta,
|
|
94
|
+
})));
|
|
95
|
+
const ownerMatches = $derived(requestOwner?.provider === provider && requestOwner?.query === remoteQuery
|
|
96
|
+
&& requestOwner?.scope === scopeKey && requestOwner?.enabled === enabled && requestOwner?.retry === retryVersion
|
|
97
|
+
&& requestOwner?.permission === permissionProvider && requestOwner?.cache === cache
|
|
98
|
+
&& requestOwner?.cacheProviderKey === cache?.providerKey
|
|
99
|
+
&& requestOwner?.authScope === authScope && requestOwner?.tenantScope === tenantScope);
|
|
100
|
+
$effect(() => {
|
|
101
|
+
const activeProvider = provider;
|
|
102
|
+
const query = remoteQuery;
|
|
103
|
+
const scope = scopeKey;
|
|
104
|
+
const allowed = enabled;
|
|
105
|
+
const permission = permissionProvider;
|
|
106
|
+
const activeCache = cache;
|
|
107
|
+
const cacheProviderKey = activeCache?.providerKey;
|
|
108
|
+
const activeAuthScope = authScope;
|
|
109
|
+
const activeTenantScope = tenantScope;
|
|
110
|
+
const retry = retryVersion;
|
|
111
|
+
requestOwner = {
|
|
112
|
+
provider: activeProvider, query, scope, enabled: allowed, retry, permission,
|
|
113
|
+
cache: activeCache, cacheProviderKey, authScope: activeAuthScope, tenantScope: activeTenantScope,
|
|
114
|
+
};
|
|
115
|
+
remotePivot = undefined;
|
|
116
|
+
remoteLoading = false;
|
|
117
|
+
remoteError = undefined;
|
|
118
|
+
remotePermissionDenied = false;
|
|
119
|
+
if (!activeProvider) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
if (!allowed) return;
|
|
123
|
+
if (!activeAuthScope.available) {
|
|
124
|
+
remotePermissionDenied = true;
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (!query || typeof scope !== 'string' || !scope.trim()) {
|
|
128
|
+
remoteError = 'invalidData';
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const epoch = ++requestEpoch;
|
|
132
|
+
const current = () => epoch === requestEpoch && ownerMatches && activeAuthScope.isCurrent()
|
|
133
|
+
&& activeTenantScope === tenantScope;
|
|
134
|
+
const denied = {};
|
|
135
|
+
remoteLoading = true;
|
|
136
|
+
void Promise.resolve().then(async () => {
|
|
137
|
+
if (!current()) return undefined;
|
|
138
|
+
if (permission) {
|
|
139
|
+
const result = await permission.can(definedOptions({
|
|
140
|
+
resource: query.resource, action: 'show', meta: query.meta,
|
|
141
|
+
}));
|
|
142
|
+
if (!result.can) throw denied;
|
|
143
|
+
}
|
|
144
|
+
if (!current()) return undefined;
|
|
145
|
+
const request = snapshotPivotQuery(query);
|
|
146
|
+
if (!request) throw new Error('Invalid pivot query');
|
|
147
|
+
const baseCacheKey = activeCache ? buildPivotCacheKey(request, scope, cacheProviderKey) : undefined;
|
|
148
|
+
if (activeCache && !baseCacheKey) throw new Error('Invalid cache namespace');
|
|
149
|
+
const cacheKey = baseCacheKey
|
|
150
|
+
? JSON.stringify([baseCacheKey, activeAuthScope.cacheKey, activeTenantScope ?? null]) : undefined;
|
|
151
|
+
if (activeCache && cacheKey) {
|
|
152
|
+
try {
|
|
153
|
+
const cached = snapshotPlainData(await activeCache.get(cacheKey));
|
|
154
|
+
if (!current()) return undefined;
|
|
155
|
+
if (cached !== undefined && !decodePivotResult(cached).error) return cached;
|
|
156
|
+
} catch { /* 缓存不可用时仍允许读取当前数据源。 */ }
|
|
157
|
+
}
|
|
158
|
+
if (!current()) return undefined;
|
|
159
|
+
const value = await activeProvider.aggregate(request);
|
|
160
|
+
if (!current()) return undefined;
|
|
161
|
+
if (activeCache && cacheKey && !decodePivotResult(value).error) {
|
|
162
|
+
try { await activeCache.set(cacheKey, snapshotPlainData(value)); }
|
|
163
|
+
catch { /* 缓存写入失败不遮蔽有效聚合结果。 */ }
|
|
164
|
+
}
|
|
165
|
+
return value;
|
|
166
|
+
}).then(value => {
|
|
167
|
+
if (!current()) return;
|
|
168
|
+
const decoded = decodePivotResult(value);
|
|
169
|
+
if (decoded.error) {
|
|
170
|
+
remotePivot = undefined;
|
|
171
|
+
remoteError = decoded.error;
|
|
60
172
|
} else {
|
|
61
|
-
|
|
173
|
+
remotePivot = decoded;
|
|
62
174
|
}
|
|
63
|
-
|
|
64
|
-
|
|
175
|
+
remoteLoading = false;
|
|
176
|
+
}).catch(cause => {
|
|
177
|
+
if (!current()) return;
|
|
178
|
+
remotePivot = undefined;
|
|
179
|
+
remoteLoading = false;
|
|
180
|
+
remotePermissionDenied = cause === denied;
|
|
181
|
+
remoteError = cause === denied ? undefined : 'invalidData';
|
|
182
|
+
});
|
|
183
|
+
return () => { requestEpoch += 1; };
|
|
65
184
|
});
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
function
|
|
74
|
-
|
|
75
|
-
.filter((d) => String(d[rowField] ?? '—') === r)
|
|
76
|
-
.map((d) => Number(d[valueField]) || 0);
|
|
77
|
-
return computeAgg(vals);
|
|
185
|
+
const emptyPivot = buildPivot([], { rowField: 'row', columnField: 'column', valueField: 'value' });
|
|
186
|
+
const pivot: PivotResult = $derived(provider
|
|
187
|
+
? (enabled && ownerMatches ? remotePivot ?? emptyPivot : emptyPivot)
|
|
188
|
+
: aggregateData !== undefined ? decodePivotResult(aggregateData)
|
|
189
|
+
: buildPivot(loading || error ? [] : data, { rowField, columnField, valueField, aggregator }));
|
|
190
|
+
const effectiveLoading = $derived(provider ? enabled && (!ownerMatches || remoteLoading || loading) : loading);
|
|
191
|
+
const displayError = $derived(error || (provider && ownerMatches && enabled && remotePermissionDenied ? i18n.t('common.accessDenied') : '') || (provider && ownerMatches && enabled && remoteError ? i18n.t(`pivot.${remoteError}`) : '') || (pivot.error ? i18n.t(`pivot.${pivot.error}`) : ''));
|
|
192
|
+
function display(value: number | null | undefined): string {
|
|
193
|
+
return formatPivotValue(value, formatValue ?? (v => v.toLocaleString(i18n.locale, { maximumFractionDigits: 2 })));
|
|
78
194
|
}
|
|
195
|
+
const drillContext = $derived({
|
|
196
|
+
pivot, query: remoteQuery, scope: scopeKey, handler: onDrillDown,
|
|
197
|
+
ready: enabled && !effectiveLoading && !displayError && (!provider || ownerMatches),
|
|
198
|
+
});
|
|
199
|
+
let drillPending = $state.raw<object>();
|
|
200
|
+
let drillError = $state.raw<object>();
|
|
201
|
+
const canDrill = $derived(drillContext.ready && !!onDrillDown && !!remoteQuery
|
|
202
|
+
&& typeof scopeKey === 'string' && !!scopeKey.trim() && scopeKey.length <= 4000);
|
|
79
203
|
|
|
80
|
-
function
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
204
|
+
async function drillDown(context: typeof drillContext, rowKey: string, columnKey: string) {
|
|
205
|
+
if (context !== drillContext || !canDrill || drillPending === context || !context.handler) return;
|
|
206
|
+
const row = context.pivot.rows.find(item => item.key === rowKey);
|
|
207
|
+
const column = context.pivot.columns.find(item => item.key === columnKey);
|
|
208
|
+
if (!context.pivot.cells.get(rowKey)?.has(columnKey)) return;
|
|
209
|
+
const input = buildPivotDrilldown(context.query, context.scope, row, column);
|
|
210
|
+
if (!input) return;
|
|
211
|
+
drillPending = context;
|
|
212
|
+
drillError = undefined;
|
|
213
|
+
try {
|
|
214
|
+
await context.handler(input);
|
|
215
|
+
} catch {
|
|
216
|
+
if (context === drillContext) drillError = context;
|
|
217
|
+
} finally {
|
|
218
|
+
if (drillPending === context) drillPending = undefined;
|
|
219
|
+
}
|
|
85
220
|
}
|
|
86
|
-
|
|
87
|
-
const grandTotal = $derived(
|
|
88
|
-
computeAgg(data.map((d) => Number(d[valueField]) || 0))
|
|
89
|
-
);
|
|
90
221
|
</script>
|
|
91
222
|
|
|
92
|
-
<div class={cn('svadmin-u-a217b4eaa918 svadmin-u-ca6bcd4b6f3f svadmin-u-18049387f0af svadmin-u-cd0ad9a56558 svadmin-u-8e63407b5ceb svadmin-u-cef5b893cf23 svadmin-u-359090c2d529 svadmin-u-6ed543e2fbbb', className)}>
|
|
223
|
+
<div aria-busy={effectiveLoading} class={cn('svadmin-u-a217b4eaa918 svadmin-u-ca6bcd4b6f3f svadmin-u-18049387f0af svadmin-u-cd0ad9a56558 svadmin-u-8e63407b5ceb svadmin-u-cef5b893cf23 svadmin-u-359090c2d529 svadmin-u-6ed543e2fbbb', className)}>
|
|
93
224
|
<div class="svadmin-u-60fbb7713999 svadmin-u-3960ffc248d9 svadmin-u-8ef2268efbbc svadmin-u-77a2a20e90d4 svadmin-u-f4cc511ff0c1 svadmin-u-65fdbade2025 svadmin-u-05faf5c801ff">
|
|
94
225
|
<div class="svadmin-u-e83a7042bc91 svadmin-u-d4108abe6359">
|
|
95
|
-
|
|
226
|
+
{i18n.t('pivot.title')} <span class="svadmin-u-bfa603190748 svadmin-u-8ecebc9f80e6">({rowLabel} × {columnLabel})</span>
|
|
96
227
|
</div>
|
|
97
228
|
<div class="svadmin-u-bfa603190748">
|
|
98
|
-
|
|
229
|
+
<strong class="svadmin-u-20aaf08a7ed1">{i18n.t(`pivot.${aggregator}`)}</strong> ({valueLabel})
|
|
99
230
|
</div>
|
|
100
231
|
</div>
|
|
101
232
|
|
|
102
|
-
|
|
103
|
-
<
|
|
233
|
+
{#if effectiveLoading}
|
|
234
|
+
<div role="status">{i18n.t('common.loading')}</div>
|
|
235
|
+
{:else if displayError}
|
|
236
|
+
<div role="alert">{displayError}</div>
|
|
237
|
+
{#if (error && onRetry) || (provider && enabled && remoteError)}
|
|
238
|
+
<Button type="button" variant="ghost" size="sm" onclick={() => {
|
|
239
|
+
if (error) onRetry?.();
|
|
240
|
+
else retryVersion += 1;
|
|
241
|
+
}}><RotateCw aria-hidden="true" />{i18n.t('common.retry')}</Button>
|
|
242
|
+
{/if}
|
|
243
|
+
{:else if pivot.rows.length === 0}
|
|
244
|
+
<div role="status">{i18n.t('common.noData')}</div>
|
|
245
|
+
{:else}
|
|
246
|
+
{@const context = drillContext}
|
|
247
|
+
{#if drillError === context}<p role="alert">{i18n.t('pivot.drilldownFailed')}</p>{/if}
|
|
248
|
+
<div class="svadmin-u-1384f66f41d0 svadmin-u-5f22e64f2282 svadmin-u-ca6bcd4b6f3f svadmin-u-05faf5c801ff" style="overflow-x: auto;">
|
|
249
|
+
<table aria-label={ariaLabel ?? `${i18n.t('pivot.title')}: ${rowLabel} / ${columnLabel} / ${valueLabel}`} class="svadmin-u-6da6a3c3f741 svadmin-u-308fc069e46e svadmin-u-4583f90cd9bd">
|
|
104
250
|
<thead class="svadmin-u-b00f43c30c2b svadmin-u-e83a7042bc91 svadmin-u-bfa603190748 svadmin-u-65fdbade2025 svadmin-u-05faf5c801ff">
|
|
105
251
|
<tr>
|
|
106
|
-
<th class="svadmin-u-0e17f2bd9074 svadmin-u-e7ee55ac7ffe svadmin-u-2eba0d65d059 svadmin-u-706701550477">{rowLabel} \ {columnLabel}</th>
|
|
107
|
-
{#each
|
|
108
|
-
<th class="svadmin-u-0e17f2bd9074 svadmin-u-e7ee55ac7ffe svadmin-u-e83a7042bc91 svadmin-u-d4108abe6359">{col}</th>
|
|
252
|
+
<th scope="col" class="svadmin-u-0e17f2bd9074 svadmin-u-e7ee55ac7ffe svadmin-u-2eba0d65d059 svadmin-u-706701550477">{rowLabel} \ {columnLabel}</th>
|
|
253
|
+
{#each pivot.columns as col (col.key)}
|
|
254
|
+
<th scope="col" class="svadmin-u-0e17f2bd9074 svadmin-u-e7ee55ac7ffe svadmin-u-e83a7042bc91 svadmin-u-d4108abe6359">{col.label}</th>
|
|
109
255
|
{/each}
|
|
110
|
-
<th class="svadmin-u-0e17f2bd9074 svadmin-u-e7ee55ac7ffe svadmin-u-706701550477 svadmin-u-e83a7042bc91 svadmin-u-d4108abe6359">
|
|
256
|
+
<th scope="col" class="svadmin-u-0e17f2bd9074 svadmin-u-e7ee55ac7ffe svadmin-u-706701550477 svadmin-u-e83a7042bc91 svadmin-u-d4108abe6359">{i18n.t('pivot.total')}</th>
|
|
111
257
|
</tr>
|
|
112
258
|
</thead>
|
|
113
259
|
<tbody class="svadmin-u-fa6acbf81d74 svadmin-u-08b5607c7258 svadmin-u-0e65706bcccd">
|
|
114
|
-
{#each
|
|
260
|
+
{#each pivot.rows as row (row.key)}
|
|
115
261
|
<tr class="svadmin-u-c4b5eaba40e3 svadmin-u-ceb69a6b0e5f">
|
|
116
|
-
<
|
|
117
|
-
{#each
|
|
118
|
-
{@const val =
|
|
262
|
+
<th scope="row" class="svadmin-u-0e17f2bd9074 svadmin-u-03b4dd7f172b svadmin-u-2eba0d65d059 svadmin-u-2689f3958069 svadmin-u-d4108abe6359 svadmin-u-967d113a1451 svadmin-u-79bf1259388b">{row.label}</th>
|
|
263
|
+
{#each pivot.columns as col (col.key)}
|
|
264
|
+
{@const val = pivot.cells.get(row.key)?.get(col.key)}
|
|
119
265
|
<td class={cn('svadmin-u-0e17f2bd9074 svadmin-u-03b4dd7f172b', val === 0 ? 'svadmin-u-52183a1cca53' : 'svadmin-u-d4108abe6359')}>
|
|
120
|
-
{
|
|
266
|
+
{#if canDrill && pivot.cells.get(row.key)?.has(col.key)}
|
|
267
|
+
<button type="button" class="svadmin-u-0e65706bcccd" onclick={() => drillDown(context, row.key, col.key)}
|
|
268
|
+
disabled={drillPending === context} aria-busy={drillPending === context}
|
|
269
|
+
aria-label={`${i18n.t('pivot.drilldown')}: ${row.label} / ${col.label}`}>
|
|
270
|
+
{display(val)}
|
|
271
|
+
</button>
|
|
272
|
+
{:else}
|
|
273
|
+
{display(val)}
|
|
274
|
+
{/if}
|
|
121
275
|
</td>
|
|
122
276
|
{/each}
|
|
123
277
|
<td class="svadmin-u-0e17f2bd9074 svadmin-u-03b4dd7f172b svadmin-u-e83a7042bc91 svadmin-u-d4108abe6359 svadmin-u-967d113a1451">
|
|
124
|
-
{
|
|
278
|
+
{display(pivot.rowTotals.get(row.key))}
|
|
125
279
|
</td>
|
|
126
280
|
</tr>
|
|
127
281
|
{/each}
|
|
128
282
|
</tbody>
|
|
129
283
|
<tfoot class="svadmin-u-706701550477 svadmin-u-e83a7042bc91 svadmin-u-0e65706bcccd svadmin-u-bee68af349c9 svadmin-u-18049387f0af svadmin-u-d4108abe6359">
|
|
130
284
|
<tr>
|
|
131
|
-
<
|
|
132
|
-
{#each
|
|
133
|
-
<td class="svadmin-u-0e17f2bd9074 svadmin-u-e7ee55ac7ffe">{
|
|
285
|
+
<th scope="row" class="svadmin-u-0e17f2bd9074 svadmin-u-e7ee55ac7ffe svadmin-u-2eba0d65d059 svadmin-u-79bf1259388b">{i18n.t('pivot.grandTotal')}</th>
|
|
286
|
+
{#each pivot.columns as col (col.key)}
|
|
287
|
+
<td class="svadmin-u-0e17f2bd9074 svadmin-u-e7ee55ac7ffe">{display(pivot.columnTotals.get(col.key))}</td>
|
|
134
288
|
{/each}
|
|
135
|
-
<td class="svadmin-u-0e17f2bd9074 svadmin-u-e7ee55ac7ffe svadmin-u-20aaf08a7ed1">{
|
|
289
|
+
<td class="svadmin-u-0e17f2bd9074 svadmin-u-e7ee55ac7ffe svadmin-u-20aaf08a7ed1">{display(pivot.grandTotal)}</td>
|
|
136
290
|
</tr>
|
|
137
291
|
</tfoot>
|
|
138
292
|
</table>
|
|
139
293
|
</div>
|
|
294
|
+
{/if}
|
|
140
295
|
</div>
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
import { type PivotCache, type PivotProvider, type PivotDrilldown } from '@svadmin/core/pivot';
|
|
2
|
+
import type { Filter } from '@svadmin/core';
|
|
3
|
+
export type AggregationFn = import('@svadmin/core/pivot').PivotAggregation;
|
|
2
4
|
interface Props {
|
|
3
|
-
data
|
|
5
|
+
data?: Record<string, unknown>[];
|
|
4
6
|
rowField: string;
|
|
5
7
|
rowLabel?: string;
|
|
6
8
|
columnField: string;
|
|
@@ -9,7 +11,22 @@ interface Props {
|
|
|
9
11
|
valueLabel?: string;
|
|
10
12
|
aggregator?: AggregationFn;
|
|
11
13
|
formatValue?: (val: number) => string;
|
|
14
|
+
loading?: boolean;
|
|
15
|
+
error?: string | undefined;
|
|
16
|
+
onRetry?: () => void;
|
|
17
|
+
onDrillDown?: (input: PivotDrilldown) => void | Promise<void>;
|
|
18
|
+
ariaLabel?: string;
|
|
12
19
|
class?: string;
|
|
20
|
+
resource?: string;
|
|
21
|
+
provider?: PivotProvider | undefined;
|
|
22
|
+
cache?: PivotCache;
|
|
23
|
+
/** 由宿主提供的身份、租户和授权版本作用域键;服务端模式必须非空。 */
|
|
24
|
+
scopeKey?: string;
|
|
25
|
+
filters?: Filter[];
|
|
26
|
+
meta?: Record<string, unknown>;
|
|
27
|
+
enabled?: boolean;
|
|
28
|
+
accessCheck?: boolean;
|
|
29
|
+
aggregateData?: unknown;
|
|
13
30
|
}
|
|
14
31
|
declare const PivotTable: import("svelte").Component<Props, {}, "">;
|
|
15
32
|
type PivotTable = ReturnType<typeof PivotTable>;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
<script lang="ts" generics="T extends string">
|
|
2
|
+
import { cn } from '../utils.js';
|
|
3
|
+
|
|
4
|
+
export interface RadioGroupOption<T extends string = string> {
|
|
5
|
+
value: T;
|
|
6
|
+
label: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface Props<T extends string = string> {
|
|
12
|
+
options: readonly RadioGroupOption<T>[];
|
|
13
|
+
value?: T | null;
|
|
14
|
+
name?: string;
|
|
15
|
+
legend?: string;
|
|
16
|
+
ariaLabel?: string;
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
required?: boolean;
|
|
19
|
+
invalid?: boolean;
|
|
20
|
+
describedby?: string;
|
|
21
|
+
class?: string;
|
|
22
|
+
onchange?: (value: T) => void;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let {
|
|
26
|
+
options,
|
|
27
|
+
value = $bindable(null),
|
|
28
|
+
name,
|
|
29
|
+
legend,
|
|
30
|
+
ariaLabel,
|
|
31
|
+
disabled = false,
|
|
32
|
+
required = false,
|
|
33
|
+
invalid = false,
|
|
34
|
+
describedby,
|
|
35
|
+
class: className = '',
|
|
36
|
+
onchange,
|
|
37
|
+
}: Props<T> = $props();
|
|
38
|
+
|
|
39
|
+
function select(option: RadioGroupOption<T>): void {
|
|
40
|
+
if (disabled || option.disabled) return;
|
|
41
|
+
if (value !== option.value) {
|
|
42
|
+
value = option.value;
|
|
43
|
+
onchange?.(option.value);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
</script>
|
|
47
|
+
|
|
48
|
+
<fieldset
|
|
49
|
+
class={cn('svadmin-radio-group', className)}
|
|
50
|
+
disabled={disabled}
|
|
51
|
+
data-invalid={invalid ? 'true' : undefined}
|
|
52
|
+
aria-describedby={describedby}
|
|
53
|
+
aria-label={legend ? undefined : ariaLabel}
|
|
54
|
+
>
|
|
55
|
+
{#if legend}<legend>{legend}</legend>{/if}
|
|
56
|
+
<div class="svadmin-radio-group__options">
|
|
57
|
+
{#each options as option (option.value)}
|
|
58
|
+
{@const inputId = `${name ?? 'radio'}-${option.value}`}
|
|
59
|
+
<label class="svadmin-radio-group__option" class:svadmin-radio-group__option--disabled={disabled || option.disabled} for={inputId}>
|
|
60
|
+
<input
|
|
61
|
+
id={inputId}
|
|
62
|
+
type="radio"
|
|
63
|
+
{name}
|
|
64
|
+
value={option.value}
|
|
65
|
+
checked={value === option.value}
|
|
66
|
+
disabled={disabled || option.disabled}
|
|
67
|
+
required={required}
|
|
68
|
+
aria-describedby={describedby}
|
|
69
|
+
onchange={() => select(option)}
|
|
70
|
+
/>
|
|
71
|
+
<span class="svadmin-radio-group__copy">
|
|
72
|
+
<span>{option.label}</span>
|
|
73
|
+
{#if option.description}<small>{option.description}</small>{/if}
|
|
74
|
+
</span>
|
|
75
|
+
</label>
|
|
76
|
+
{/each}
|
|
77
|
+
</div>
|
|
78
|
+
</fieldset>
|
|
79
|
+
|
|
80
|
+
<style>
|
|
81
|
+
.svadmin-radio-group {
|
|
82
|
+
min-inline-size: 0;
|
|
83
|
+
border: 0;
|
|
84
|
+
padding: 0;
|
|
85
|
+
margin: 0;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.svadmin-radio-group legend {
|
|
89
|
+
padding: 0;
|
|
90
|
+
margin-block-end: 8px;
|
|
91
|
+
color: var(--foreground);
|
|
92
|
+
font-weight: 600;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.svadmin-radio-group__options {
|
|
96
|
+
display: grid;
|
|
97
|
+
gap: 8px;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.svadmin-radio-group__option {
|
|
101
|
+
display: flex;
|
|
102
|
+
align-items: flex-start;
|
|
103
|
+
gap: 8px;
|
|
104
|
+
min-block-size: 32px;
|
|
105
|
+
cursor: pointer;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.svadmin-radio-group__option--disabled {
|
|
109
|
+
cursor: not-allowed;
|
|
110
|
+
opacity: 0.5;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.svadmin-radio-group__copy {
|
|
114
|
+
display: grid;
|
|
115
|
+
gap: 2px;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.svadmin-radio-group__copy small {
|
|
119
|
+
color: var(--muted-foreground);
|
|
120
|
+
}
|
|
121
|
+
</style>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export interface RadioGroupOption<T extends string = string> {
|
|
2
|
+
value: T;
|
|
3
|
+
label: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
}
|
|
7
|
+
interface Props<T extends string = string> {
|
|
8
|
+
options: readonly RadioGroupOption<T>[];
|
|
9
|
+
value?: T | null;
|
|
10
|
+
name?: string;
|
|
11
|
+
legend?: string;
|
|
12
|
+
ariaLabel?: string;
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
required?: boolean;
|
|
15
|
+
invalid?: boolean;
|
|
16
|
+
describedby?: string;
|
|
17
|
+
class?: string;
|
|
18
|
+
onchange?: (value: T) => void;
|
|
19
|
+
}
|
|
20
|
+
declare function $$render<T extends string>(): {
|
|
21
|
+
props: Props<T>;
|
|
22
|
+
exports: {};
|
|
23
|
+
bindings: "value";
|
|
24
|
+
slots: {};
|
|
25
|
+
events: {};
|
|
26
|
+
};
|
|
27
|
+
declare class __sveltets_Render<T extends string> {
|
|
28
|
+
props(): ReturnType<typeof $$render<T>>['props'];
|
|
29
|
+
events(): ReturnType<typeof $$render<T>>['events'];
|
|
30
|
+
slots(): ReturnType<typeof $$render<T>>['slots'];
|
|
31
|
+
bindings(): "value";
|
|
32
|
+
exports(): {};
|
|
33
|
+
}
|
|
34
|
+
interface $$IsomorphicComponent {
|
|
35
|
+
new <T extends string>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
|
|
36
|
+
$$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
|
|
37
|
+
} & ReturnType<__sveltets_Render<T>['exports']>;
|
|
38
|
+
<T extends string>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
|
|
39
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
40
|
+
}
|
|
41
|
+
declare const RadioGroup: $$IsomorphicComponent;
|
|
42
|
+
type RadioGroup<T extends string> = InstanceType<typeof RadioGroup<T>>;
|
|
43
|
+
export default RadioGroup;
|