@happyvertical/smrt-fields 0.40.60 → 0.40.61
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/AGENTS.md +58 -12
- package/README.md +90 -2
- package/dist/__smrt-register__.d.ts +2 -0
- package/dist/__smrt-register__.d.ts.map +1 -0
- package/dist/cache.d.ts +18 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/collections/FieldPolicyCollection.d.ts +95 -0
- package/dist/collections/FieldPolicyCollection.d.ts.map +1 -0
- package/dist/field-definitions.d.ts +77 -0
- package/dist/field-definitions.d.ts.map +1 -0
- package/dist/field-policy-resolver.d.ts +46 -0
- package/dist/field-policy-resolver.d.ts.map +1 -0
- package/dist/index.d.ts +9 -532
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +752 -55
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +45 -3
- package/dist/models/FieldPolicy.d.ts +163 -0
- package/dist/models/FieldPolicy.d.ts.map +1 -0
- package/dist/permissions.d.ts +9 -0
- package/dist/permissions.d.ts.map +1 -0
- package/dist/playground.d.ts +2 -0
- package/dist/playground.d.ts.map +1 -0
- package/dist/playground.js +39 -0
- package/dist/playground.js.map +1 -0
- package/dist/settings-catalog.d.ts +73 -0
- package/dist/settings-catalog.d.ts.map +1 -0
- package/dist/smrt-knowledge.json +50 -7
- package/dist/svelte/__tests__/FieldPolicyControlPanel.test.js +223 -0
- package/dist/svelte/__tests__/FieldPolicyGear.test.js +503 -0
- package/dist/svelte/__tests__/FormHelp.test.js +138 -0
- package/dist/svelte/__tests__/ModeUX.test.js +109 -0
- package/dist/svelte/__tests__/ObjectForm.test.js +556 -0
- package/dist/svelte/__tests__/ObjectFormGeneratedApi.integration.test.js +436 -0
- package/dist/svelte/__tests__/PolicyField.test.js +373 -0
- package/dist/svelte/__tests__/fixtures/AdvancedFieldsFixture.svelte +30 -0
- package/dist/svelte/__tests__/fixtures/AdvancedFieldsFixture.svelte.d.ts +9 -0
- package/dist/svelte/__tests__/fixtures/AdvancedFieldsFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/DomPrefillFixture.svelte +33 -0
- package/dist/svelte/__tests__/fixtures/DomPrefillFixture.svelte.d.ts +10 -0
- package/dist/svelte/__tests__/fixtures/DomPrefillFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/FormHelpFixture.svelte +19 -0
- package/dist/svelte/__tests__/fixtures/FormHelpFixture.svelte.d.ts +10 -0
- package/dist/svelte/__tests__/fixtures/FormHelpFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/GeneratedApiGearFixture.svelte +18 -0
- package/dist/svelte/__tests__/fixtures/GeneratedApiGearFixture.svelte.d.ts +11 -0
- package/dist/svelte/__tests__/fixtures/GeneratedApiGearFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/GracefulDegradeFixture.svelte +11 -0
- package/dist/svelte/__tests__/fixtures/GracefulDegradeFixture.svelte.d.ts +19 -0
- package/dist/svelte/__tests__/fixtures/GracefulDegradeFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/ModeSwitchFixture.svelte +18 -0
- package/dist/svelte/__tests__/fixtures/ModeSwitchFixture.svelte.d.ts +8 -0
- package/dist/svelte/__tests__/fixtures/ModeSwitchFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/NoIdFixture.svelte +24 -0
- package/dist/svelte/__tests__/fixtures/NoIdFixture.svelte.d.ts +13 -0
- package/dist/svelte/__tests__/fixtures/NoIdFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormActionsFixture.svelte +20 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormActionsFixture.svelte.d.ts +11 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormActionsFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormFixture.svelte +17 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormFixture.svelte.d.ts +10 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormRegistryFixture.svelte +25 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormRegistryFixture.svelte.d.ts +10 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormRegistryFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormSnippetFixture.svelte +34 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormSnippetFixture.svelte.d.ts +10 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormSnippetFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormSourceFixture.svelte +29 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormSourceFixture.svelte.d.ts +11 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormSourceFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormSourceSnippetFixture.svelte +33 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormSourceSnippetFixture.svelte.d.ts +9 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormSourceSnippetFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/PolicyDataTableFixture.svelte +40 -0
- package/dist/svelte/__tests__/fixtures/PolicyDataTableFixture.svelte.d.ts +8 -0
- package/dist/svelte/__tests__/fixtures/PolicyDataTableFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/PrefillFixture.svelte +26 -0
- package/dist/svelte/__tests__/fixtures/PrefillFixture.svelte.d.ts +13 -0
- package/dist/svelte/__tests__/fixtures/PrefillFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/ProviderFieldFixture.svelte +39 -0
- package/dist/svelte/__tests__/fixtures/ProviderFieldFixture.svelte.d.ts +17 -0
- package/dist/svelte/__tests__/fixtures/ProviderFieldFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/RegistryInput.svelte +15 -0
- package/dist/svelte/__tests__/fixtures/RegistryInput.svelte.d.ts +5 -0
- package/dist/svelte/__tests__/fixtures/RegistryInput.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/RevealPrefillFixture.svelte +29 -0
- package/dist/svelte/__tests__/fixtures/RevealPrefillFixture.svelte.d.ts +14 -0
- package/dist/svelte/__tests__/fixtures/RevealPrefillFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/SettingsCatalogStub.svelte +24 -0
- package/dist/svelte/__tests__/fixtures/SettingsCatalogStub.svelte.d.ts +14 -0
- package/dist/svelte/__tests__/fixtures/SettingsCatalogStub.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/SnippetFixture.svelte +28 -0
- package/dist/svelte/__tests__/fixtures/SnippetFixture.svelte.d.ts +13 -0
- package/dist/svelte/__tests__/fixtures/SnippetFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/ToggleModeButton.svelte +14 -0
- package/dist/svelte/__tests__/fixtures/ToggleModeButton.svelte.d.ts +19 -0
- package/dist/svelte/__tests__/fixtures/ToggleModeButton.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/TooltipFixture.svelte +25 -0
- package/dist/svelte/__tests__/fixtures/TooltipFixture.svelte.d.ts +14 -0
- package/dist/svelte/__tests__/fixtures/TooltipFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/settings-catalog.test.js +161 -0
- package/dist/svelte/components/AdvancedFields.svelte +49 -0
- package/dist/svelte/components/AdvancedFields.svelte.d.ts +17 -0
- package/dist/svelte/components/AdvancedFields.svelte.d.ts.map +1 -0
- package/dist/svelte/components/FieldInput.svelte +159 -0
- package/dist/svelte/components/FieldInput.svelte.d.ts +5 -0
- package/dist/svelte/components/FieldInput.svelte.d.ts.map +1 -0
- package/dist/svelte/components/FieldPolicyControlPanel.svelte +261 -0
- package/dist/svelte/components/FieldPolicyControlPanel.svelte.d.ts +26 -0
- package/dist/svelte/components/FieldPolicyControlPanel.svelte.d.ts.map +1 -0
- package/dist/svelte/components/FieldPolicyEditor.svelte +417 -0
- package/dist/svelte/components/FieldPolicyEditor.svelte.d.ts +18 -0
- package/dist/svelte/components/FieldPolicyEditor.svelte.d.ts.map +1 -0
- package/dist/svelte/components/FieldPolicyGearButton.svelte +17 -0
- package/dist/svelte/components/FieldPolicyGearButton.svelte.d.ts +8 -0
- package/dist/svelte/components/FieldPolicyGearButton.svelte.d.ts.map +1 -0
- package/dist/svelte/components/FieldPolicyGearProvider.svelte +135 -0
- package/dist/svelte/components/FieldPolicyGearProvider.svelte.d.ts +17 -0
- package/dist/svelte/components/FieldPolicyGearProvider.svelte.d.ts.map +1 -0
- package/dist/svelte/components/FieldPolicyProvider.svelte +89 -0
- package/dist/svelte/components/FieldPolicyProvider.svelte.d.ts +35 -0
- package/dist/svelte/components/FieldPolicyProvider.svelte.d.ts.map +1 -0
- package/dist/svelte/components/FormHelp.svelte +157 -0
- package/dist/svelte/components/FormHelp.svelte.d.ts +15 -0
- package/dist/svelte/components/FormHelp.svelte.d.ts.map +1 -0
- package/dist/svelte/components/ModeSwitch.svelte +47 -0
- package/dist/svelte/components/ModeSwitch.svelte.d.ts +10 -0
- package/dist/svelte/components/ModeSwitch.svelte.d.ts.map +1 -0
- package/dist/svelte/components/ObjectForm.svelte +351 -0
- package/dist/svelte/components/ObjectForm.svelte.d.ts +40 -0
- package/dist/svelte/components/ObjectForm.svelte.d.ts.map +1 -0
- package/dist/svelte/components/ObjectFormSourceProvider.svelte +18 -0
- package/dist/svelte/components/ObjectFormSourceProvider.svelte.d.ts +11 -0
- package/dist/svelte/components/ObjectFormSourceProvider.svelte.d.ts.map +1 -0
- package/dist/svelte/components/PolicyField.svelte +338 -0
- package/dist/svelte/components/PolicyField.svelte.d.ts +80 -0
- package/dist/svelte/components/PolicyField.svelte.d.ts.map +1 -0
- package/dist/svelte/context.svelte.d.ts +54 -0
- package/dist/svelte/context.svelte.d.ts.map +1 -0
- package/dist/svelte/context.svelte.js +55 -0
- package/dist/svelte/data-table.d.ts +17 -0
- package/dist/svelte/data-table.d.ts.map +1 -0
- package/dist/svelte/data-table.js +19 -0
- package/dist/svelte/field-policy-editor.d.ts +81 -0
- package/dist/svelte/field-policy-editor.d.ts.map +1 -0
- package/dist/svelte/field-policy-editor.js +120 -0
- package/dist/svelte/gear-context.svelte.d.ts +14 -0
- package/dist/svelte/gear-context.svelte.d.ts.map +1 -0
- package/dist/svelte/gear-context.svelte.js +15 -0
- package/dist/svelte/index.d.ts +58 -0
- package/dist/svelte/index.d.ts.map +1 -0
- package/dist/svelte/index.js +38 -0
- package/dist/svelte/input-registry.d.ts +21 -0
- package/dist/svelte/input-registry.d.ts.map +1 -0
- package/dist/svelte/input-registry.js +26 -0
- package/dist/svelte/object-form-source-context.svelte.d.ts +4 -0
- package/dist/svelte/object-form-source-context.svelte.d.ts.map +1 -0
- package/dist/svelte/object-form-source-context.svelte.js +8 -0
- package/dist/svelte/object-form-source.svelte.d.ts +18 -0
- package/dist/svelte/object-form-source.svelte.d.ts.map +1 -0
- package/dist/svelte/object-form-source.svelte.js +99 -0
- package/dist/svelte/object-form.d.ts +6 -0
- package/dist/svelte/object-form.d.ts.map +1 -0
- package/dist/svelte/object-form.js +38 -0
- package/dist/svelte/playground/FieldPolicyFormPreview.svelte +212 -0
- package/dist/svelte/playground/FieldPolicyFormPreview.svelte.d.ts +4 -0
- package/dist/svelte/playground/FieldPolicyFormPreview.svelte.d.ts.map +1 -0
- package/dist/svelte/playground/ObjectFormPreview.svelte +129 -0
- package/dist/svelte/playground/ObjectFormPreview.svelte.d.ts +4 -0
- package/dist/svelte/playground/ObjectFormPreview.svelte.d.ts.map +1 -0
- package/dist/svelte/playground.d.ts +20 -0
- package/dist/svelte/playground.d.ts.map +1 -0
- package/dist/svelte/playground.js +38 -0
- package/dist/svelte/settings-catalog.d.ts +54 -0
- package/dist/svelte/settings-catalog.d.ts.map +1 -0
- package/dist/svelte/settings-catalog.js +116 -0
- package/dist/svelte/types.d.ts +101 -0
- package/dist/svelte/types.d.ts.map +1 -0
- package/dist/svelte/types.js +4 -0
- package/dist/types.d.ts +276 -203
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js.map +1 -1
- package/package.json +33 -8
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
/**
|
|
3
|
+
* Component tests for FieldPolicyProvider + PolicyField (#2048).
|
|
4
|
+
*
|
|
5
|
+
* Covers the acceptance criteria:
|
|
6
|
+
* - PolicyField adoption with no layout change; unwrapped fields keep working
|
|
7
|
+
* - Basic mode hides advanced-tier fields; disclosure reveals them
|
|
8
|
+
* - Required-with-default fields prefill; loaded-record edits never overwritten
|
|
9
|
+
* - Help hint renders from resolved help (manifest description → org override)
|
|
10
|
+
* - Graceful degradation outside a Provider
|
|
11
|
+
* - Snippet escape hatch
|
|
12
|
+
* - a11y (axe-clean)
|
|
13
|
+
*/
|
|
14
|
+
import { expectNoA11yViolations, render, screen, userEvent, } from '@happyvertical/smrt-vitest/svelte';
|
|
15
|
+
import { tick } from 'svelte';
|
|
16
|
+
import { describe, expect, it } from 'vitest';
|
|
17
|
+
import FieldPolicyProvider from '../components/FieldPolicyProvider.svelte';
|
|
18
|
+
import PolicyField from '../components/PolicyField.svelte';
|
|
19
|
+
import DomPrefillFixture from './fixtures/DomPrefillFixture.svelte';
|
|
20
|
+
import GracefulDegradeFixture from './fixtures/GracefulDegradeFixture.svelte';
|
|
21
|
+
import NoIdFixture from './fixtures/NoIdFixture.svelte';
|
|
22
|
+
import PrefillFixture from './fixtures/PrefillFixture.svelte';
|
|
23
|
+
import ProviderFieldFixture from './fixtures/ProviderFieldFixture.svelte';
|
|
24
|
+
import RevealPrefillFixture from './fixtures/RevealPrefillFixture.svelte';
|
|
25
|
+
import SnippetFixture from './fixtures/SnippetFixture.svelte';
|
|
26
|
+
import TooltipFixture from './fixtures/TooltipFixture.svelte';
|
|
27
|
+
function makePolicy(overrides = {}) {
|
|
28
|
+
return {
|
|
29
|
+
objectRef: '@test:Widget',
|
|
30
|
+
fields: {
|
|
31
|
+
name: {
|
|
32
|
+
fieldName: 'name',
|
|
33
|
+
hasDefault: false,
|
|
34
|
+
defaultValue: undefined,
|
|
35
|
+
visibility: 'basic',
|
|
36
|
+
help: 'The widget name',
|
|
37
|
+
label: 'Name',
|
|
38
|
+
order: 1,
|
|
39
|
+
group: null,
|
|
40
|
+
locked: false,
|
|
41
|
+
required: true,
|
|
42
|
+
},
|
|
43
|
+
sku: {
|
|
44
|
+
fieldName: 'sku',
|
|
45
|
+
hasDefault: true,
|
|
46
|
+
defaultValue: 'WIDG-001',
|
|
47
|
+
visibility: 'basic',
|
|
48
|
+
help: null,
|
|
49
|
+
label: 'SKU',
|
|
50
|
+
order: 2,
|
|
51
|
+
group: null,
|
|
52
|
+
locked: false,
|
|
53
|
+
required: false,
|
|
54
|
+
},
|
|
55
|
+
wholesalePrice: {
|
|
56
|
+
fieldName: 'wholesalePrice',
|
|
57
|
+
hasDefault: true,
|
|
58
|
+
defaultValue: 0,
|
|
59
|
+
visibility: 'advanced',
|
|
60
|
+
help: 'Price for wholesale customers',
|
|
61
|
+
label: 'Wholesale Price',
|
|
62
|
+
order: 3,
|
|
63
|
+
group: 'pricing',
|
|
64
|
+
locked: false,
|
|
65
|
+
required: false,
|
|
66
|
+
},
|
|
67
|
+
internalNotes: {
|
|
68
|
+
fieldName: 'internalNotes',
|
|
69
|
+
hasDefault: false,
|
|
70
|
+
defaultValue: undefined,
|
|
71
|
+
visibility: 'hidden',
|
|
72
|
+
help: 'Internal only',
|
|
73
|
+
label: 'Internal Notes',
|
|
74
|
+
order: 4,
|
|
75
|
+
group: null,
|
|
76
|
+
locked: false,
|
|
77
|
+
required: false,
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
...overrides,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
describe('FieldPolicyProvider + PolicyField', () => {
|
|
84
|
+
it('renders basic fields in basic mode', () => {
|
|
85
|
+
const policy = makePolicy();
|
|
86
|
+
render(ProviderFieldFixture, {
|
|
87
|
+
props: { policy, mode: 'basic' },
|
|
88
|
+
});
|
|
89
|
+
expect(screen.getByRole('textbox', { name: /Name/ })).toBeInTheDocument();
|
|
90
|
+
expect(screen.getByRole('textbox', { name: /SKU/ })).toBeInTheDocument();
|
|
91
|
+
});
|
|
92
|
+
it('hides advanced fields in basic mode', () => {
|
|
93
|
+
const policy = makePolicy();
|
|
94
|
+
render(ProviderFieldFixture, {
|
|
95
|
+
props: { policy, mode: 'basic' },
|
|
96
|
+
});
|
|
97
|
+
// wholesalePrice is type=number → role is spinbutton, not textbox
|
|
98
|
+
expect(screen.queryByRole('spinbutton', { name: /Wholesale Price/ })).not.toBeInTheDocument();
|
|
99
|
+
});
|
|
100
|
+
it('reveals advanced fields in advanced mode', async () => {
|
|
101
|
+
const policy = makePolicy();
|
|
102
|
+
render(ProviderFieldFixture, {
|
|
103
|
+
props: { policy, mode: 'advanced' },
|
|
104
|
+
});
|
|
105
|
+
// Wait for the provider's mode-sync $effect to flush (the untrack() seed
|
|
106
|
+
// reflects the requested mode on first paint, but $effect reactivity in
|
|
107
|
+
// jsdom needs a tick for the DOM to settle).
|
|
108
|
+
await tick();
|
|
109
|
+
// wholesalePrice is type=number → role is spinbutton, not textbox
|
|
110
|
+
expect(screen.getByRole('spinbutton', { name: /Wholesale Price/ })).toBeInTheDocument();
|
|
111
|
+
});
|
|
112
|
+
it('never renders hidden-tier fields', () => {
|
|
113
|
+
const policy = makePolicy();
|
|
114
|
+
render(ProviderFieldFixture, {
|
|
115
|
+
props: { policy, mode: 'advanced' },
|
|
116
|
+
});
|
|
117
|
+
expect(screen.queryByText('Internal Notes')).not.toBeInTheDocument();
|
|
118
|
+
});
|
|
119
|
+
it('renders help hint from resolved help text', () => {
|
|
120
|
+
const policy = makePolicy();
|
|
121
|
+
render(ProviderFieldFixture, {
|
|
122
|
+
props: { policy, mode: 'basic' },
|
|
123
|
+
});
|
|
124
|
+
expect(screen.getByText('The widget name')).toBeInTheDocument();
|
|
125
|
+
});
|
|
126
|
+
it('renders required marker for required fields', () => {
|
|
127
|
+
const policy = makePolicy();
|
|
128
|
+
render(ProviderFieldFixture, {
|
|
129
|
+
props: { policy, mode: 'basic' },
|
|
130
|
+
});
|
|
131
|
+
const nameField = screen.getByText('Name').closest('.policy-field');
|
|
132
|
+
expect(nameField?.querySelector('.policy-field__required')).not.toBeNull();
|
|
133
|
+
});
|
|
134
|
+
it('does not render required marker for optional fields', () => {
|
|
135
|
+
const policy = makePolicy();
|
|
136
|
+
render(ProviderFieldFixture, {
|
|
137
|
+
props: { policy, mode: 'basic' },
|
|
138
|
+
});
|
|
139
|
+
const skuField = screen.getByText('SKU').closest('.policy-field');
|
|
140
|
+
expect(skuField?.querySelector('.policy-field__required')).toBeNull();
|
|
141
|
+
});
|
|
142
|
+
it('exposes default value via snippet props for prefill signal', () => {
|
|
143
|
+
const policy = makePolicy();
|
|
144
|
+
render(PrefillFixture, {
|
|
145
|
+
props: { policy, mode: 'basic' },
|
|
146
|
+
});
|
|
147
|
+
// The fixture renders the default value text from snippet props
|
|
148
|
+
expect(screen.getByText('Default: WIDG-001')).toBeInTheDocument();
|
|
149
|
+
});
|
|
150
|
+
it('degrades gracefully outside a Provider (renders children verbatim)', () => {
|
|
151
|
+
render(GracefulDegradeFixture);
|
|
152
|
+
// Should render the input even without a provider
|
|
153
|
+
expect(screen.getByRole('textbox')).toBeInTheDocument();
|
|
154
|
+
});
|
|
155
|
+
it('snippet escape hatch receives resolved policy data', () => {
|
|
156
|
+
const policy = makePolicy();
|
|
157
|
+
render(SnippetFixture, {
|
|
158
|
+
props: { policy, mode: 'basic' },
|
|
159
|
+
});
|
|
160
|
+
expect(screen.getByTestId('field-label')).toHaveTextContent('Name');
|
|
161
|
+
expect(screen.getByTestId('field-help')).toHaveTextContent('The widget name');
|
|
162
|
+
expect(screen.getByTestId('field-required')).toHaveTextContent('true');
|
|
163
|
+
});
|
|
164
|
+
it('helpDensity tooltip attaches help to the label title and hides the hint', () => {
|
|
165
|
+
const policy = makePolicy();
|
|
166
|
+
render(TooltipFixture, {
|
|
167
|
+
props: { policy, helpDensity: 'tooltip' },
|
|
168
|
+
});
|
|
169
|
+
// Help moves to the label's title attribute
|
|
170
|
+
const label = screen.getByText('Name').closest('label');
|
|
171
|
+
expect(label).not.toBeNull();
|
|
172
|
+
expect(label?.getAttribute('title')).toBe('The widget name');
|
|
173
|
+
// The help text is no longer rendered as visible text content
|
|
174
|
+
expect(screen.queryByText('The widget name')).not.toBeInTheDocument();
|
|
175
|
+
// No visible hint element (query the component's stable class rather than
|
|
176
|
+
// a role — `<p>` has no ARIA role, so a role query is unreliable).
|
|
177
|
+
expect(document.querySelectorAll('.policy-field__hint').length).toBe(0);
|
|
178
|
+
});
|
|
179
|
+
it('links the help hint to the input via aria-describedby', async () => {
|
|
180
|
+
const policy = makePolicy();
|
|
181
|
+
render(ProviderFieldFixture, {
|
|
182
|
+
props: { policy, mode: 'basic' },
|
|
183
|
+
});
|
|
184
|
+
await tick();
|
|
185
|
+
// `name` has resolved help rendered as the hint paragraph #name-help —
|
|
186
|
+
// the input must reference it for screen readers.
|
|
187
|
+
const input = screen.getByRole('textbox', { name: /Name/ });
|
|
188
|
+
expect(input.getAttribute('aria-describedby')).toBe('name-help');
|
|
189
|
+
expect(document.getElementById('name-help')).not.toBeNull();
|
|
190
|
+
// `sku` has no resolved help → no hint id, no dangling aria reference.
|
|
191
|
+
const skuInput = screen.getByRole('textbox', { name: /SKU/ });
|
|
192
|
+
expect(skuInput.hasAttribute('aria-describedby')).toBe(false);
|
|
193
|
+
});
|
|
194
|
+
it('associates the label with the wrapped control via for/id', async () => {
|
|
195
|
+
const policy = makePolicy();
|
|
196
|
+
render(ProviderFieldFixture, {
|
|
197
|
+
props: { policy, mode: 'basic' },
|
|
198
|
+
});
|
|
199
|
+
await tick();
|
|
200
|
+
// The fixture inputs carry id={name} — the label's `for` must match it so
|
|
201
|
+
// the accessible name comes from the rendered label.
|
|
202
|
+
const label = screen.getByText('Name').closest('label');
|
|
203
|
+
expect(label?.getAttribute('for')).toBe('name');
|
|
204
|
+
expect(document.getElementById('name')).not.toBeNull();
|
|
205
|
+
const skuLabel = screen.getByText('SKU').closest('label');
|
|
206
|
+
expect(skuLabel?.getAttribute('for')).toBe('sku');
|
|
207
|
+
});
|
|
208
|
+
it('assigns an id to a wrapped control that has none (for never dangles)', async () => {
|
|
209
|
+
const policy = makePolicy();
|
|
210
|
+
render(NoIdFixture, { props: { policy, mode: 'basic' } });
|
|
211
|
+
await tick();
|
|
212
|
+
const label = screen.getByText('Name').closest('label');
|
|
213
|
+
const forTarget = label?.getAttribute('for');
|
|
214
|
+
expect(forTarget).toBe('name');
|
|
215
|
+
// The wrapper must have given the id-less control an id the label hits.
|
|
216
|
+
expect(document.getElementById(forTarget)).not.toBeNull();
|
|
217
|
+
});
|
|
218
|
+
it('helpDensity tooltip falls back to a visible hint when there is no label', () => {
|
|
219
|
+
// Policy with no resolved label → label === null → help must still render
|
|
220
|
+
const policy = makePolicy({
|
|
221
|
+
fields: {
|
|
222
|
+
name: {
|
|
223
|
+
fieldName: 'name',
|
|
224
|
+
hasDefault: false,
|
|
225
|
+
defaultValue: undefined,
|
|
226
|
+
visibility: 'basic',
|
|
227
|
+
help: 'Orphan help text',
|
|
228
|
+
label: null,
|
|
229
|
+
order: 1,
|
|
230
|
+
group: null,
|
|
231
|
+
locked: false,
|
|
232
|
+
required: false,
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
});
|
|
236
|
+
render(TooltipFixture, {
|
|
237
|
+
props: { policy, helpDensity: 'tooltip' },
|
|
238
|
+
});
|
|
239
|
+
expect(screen.getByText('Orphan help text')).toBeInTheDocument();
|
|
240
|
+
});
|
|
241
|
+
it('mode toggle reveals advanced fields', async () => {
|
|
242
|
+
const policy = makePolicy();
|
|
243
|
+
render(ProviderFieldFixture, {
|
|
244
|
+
props: { policy, mode: 'basic' },
|
|
245
|
+
});
|
|
246
|
+
// Advanced field not visible initially
|
|
247
|
+
expect(screen.queryByRole('spinbutton', { name: /Wholesale/ })).not.toBeInTheDocument();
|
|
248
|
+
// Toggle mode (the fixture's button calls modeStore.toggle() via context)
|
|
249
|
+
await userEvent.click(screen.getByRole('button', { name: 'Toggle Mode' }));
|
|
250
|
+
expect(screen.getByRole('spinbutton', { name: /Wholesale Price/ })).toBeInTheDocument();
|
|
251
|
+
});
|
|
252
|
+
it('is axe-clean', async () => {
|
|
253
|
+
const policy = makePolicy();
|
|
254
|
+
const { container } = render(ProviderFieldFixture, {
|
|
255
|
+
props: { policy, mode: 'basic' },
|
|
256
|
+
});
|
|
257
|
+
await expectNoA11yViolations(container);
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
describe('PolicyField default prefill (new records only)', () => {
|
|
261
|
+
it('prefills an empty input with the resolved default for a new record', async () => {
|
|
262
|
+
const policy = makePolicy();
|
|
263
|
+
render(DomPrefillFixture, {
|
|
264
|
+
props: { policy, isNewRecord: true, skuValue: '' },
|
|
265
|
+
});
|
|
266
|
+
await tick();
|
|
267
|
+
// The sku field has a resolved default of 'WIDG-001'; the empty input
|
|
268
|
+
// should be prefilled with it.
|
|
269
|
+
const input = screen.getByRole('textbox', {
|
|
270
|
+
name: /SKU/,
|
|
271
|
+
});
|
|
272
|
+
expect(input.value).toBe('WIDG-001');
|
|
273
|
+
// The bound state should pick up the prefilled value too
|
|
274
|
+
expect(screen.getByTestId('sku-state')).toHaveTextContent('WIDG-001');
|
|
275
|
+
});
|
|
276
|
+
it('does NOT clobber a loaded record with an existing value', async () => {
|
|
277
|
+
const policy = makePolicy();
|
|
278
|
+
render(DomPrefillFixture, {
|
|
279
|
+
props: { policy, isNewRecord: true, skuValue: 'EXISTING-999' },
|
|
280
|
+
});
|
|
281
|
+
await tick();
|
|
282
|
+
// The input already has a value (loaded record); the default must NOT
|
|
283
|
+
// overwrite it.
|
|
284
|
+
const input = screen.getByRole('textbox', {
|
|
285
|
+
name: /SKU/,
|
|
286
|
+
});
|
|
287
|
+
expect(input.value).toBe('EXISTING-999');
|
|
288
|
+
expect(screen.getByTestId('sku-state')).toHaveTextContent('EXISTING-999');
|
|
289
|
+
});
|
|
290
|
+
it('does NOT prefill when isNewRecord is false', async () => {
|
|
291
|
+
const policy = makePolicy();
|
|
292
|
+
render(DomPrefillFixture, {
|
|
293
|
+
props: { policy, isNewRecord: false, skuValue: '' },
|
|
294
|
+
});
|
|
295
|
+
await tick();
|
|
296
|
+
// isNewRecord=false → no prefill even though the field is empty and has a
|
|
297
|
+
// resolved default.
|
|
298
|
+
const input = screen.getByRole('textbox', {
|
|
299
|
+
name: /SKU/,
|
|
300
|
+
});
|
|
301
|
+
expect(input.value).toBe('');
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
describe('PolicyField prefill on reveal (advanced-tier fields)', () => {
|
|
305
|
+
it('prefills an advanced field when the mode switch reveals it', async () => {
|
|
306
|
+
const policy = makePolicy();
|
|
307
|
+
render(RevealPrefillFixture, {
|
|
308
|
+
props: { policy, isNewRecord: true },
|
|
309
|
+
});
|
|
310
|
+
await tick();
|
|
311
|
+
// Hidden in basic mode: no input to prefill yet.
|
|
312
|
+
expect(screen.queryByRole('spinbutton', { name: /Wholesale Price/ })).not.toBeInTheDocument();
|
|
313
|
+
// Reveal the advanced tier.
|
|
314
|
+
await userEvent.click(screen.getByRole('button', { name: 'Toggle Mode' }));
|
|
315
|
+
await tick();
|
|
316
|
+
// wholesalePrice resolves default 0 — a legitimate integer default that
|
|
317
|
+
// must survive the undefined/null guards.
|
|
318
|
+
const input = screen.getByRole('spinbutton', {
|
|
319
|
+
name: /Wholesale Price/,
|
|
320
|
+
});
|
|
321
|
+
expect(input.value).toBe('0');
|
|
322
|
+
// The bound state picked up the prefilled value via the dispatched event.
|
|
323
|
+
expect(screen.getByTestId('wholesale-state')).toHaveTextContent('0');
|
|
324
|
+
});
|
|
325
|
+
it('does NOT prefill a revealed advanced field when isNewRecord is false', async () => {
|
|
326
|
+
const policy = makePolicy();
|
|
327
|
+
render(RevealPrefillFixture, {
|
|
328
|
+
props: { policy, isNewRecord: false },
|
|
329
|
+
});
|
|
330
|
+
await tick();
|
|
331
|
+
await userEvent.click(screen.getByRole('button', { name: 'Toggle Mode' }));
|
|
332
|
+
await tick();
|
|
333
|
+
const input = screen.getByRole('spinbutton', {
|
|
334
|
+
name: /Wholesale Price/,
|
|
335
|
+
});
|
|
336
|
+
expect(input.value).toBe('');
|
|
337
|
+
});
|
|
338
|
+
it('prefills only once — a deliberately cleared input is never re-filled', async () => {
|
|
339
|
+
const policy = makePolicy();
|
|
340
|
+
render(RevealPrefillFixture, {
|
|
341
|
+
props: { policy, isNewRecord: true },
|
|
342
|
+
});
|
|
343
|
+
await tick();
|
|
344
|
+
// Reveal → prefill runs once.
|
|
345
|
+
await userEvent.click(screen.getByRole('button', { name: 'Toggle Mode' }));
|
|
346
|
+
await tick();
|
|
347
|
+
const input = screen.getByRole('spinbutton', {
|
|
348
|
+
name: /Wholesale Price/,
|
|
349
|
+
});
|
|
350
|
+
expect(input.value).toBe('0');
|
|
351
|
+
// The user deliberately clears the field.
|
|
352
|
+
await userEvent.clear(input);
|
|
353
|
+
await tick();
|
|
354
|
+
// Hide and reveal again: the one-shot guard must prevent a re-prefill.
|
|
355
|
+
await userEvent.click(screen.getByRole('button', { name: 'Toggle Mode' }));
|
|
356
|
+
await userEvent.click(screen.getByRole('button', { name: 'Toggle Mode' }));
|
|
357
|
+
await tick();
|
|
358
|
+
const revealed = screen.getByRole('spinbutton', {
|
|
359
|
+
name: /Wholesale Price/,
|
|
360
|
+
});
|
|
361
|
+
expect(revealed.value).toBe('');
|
|
362
|
+
});
|
|
363
|
+
});
|
|
364
|
+
describe('PolicyField standalone', () => {
|
|
365
|
+
it('renders without a provider (no crash)', () => {
|
|
366
|
+
render(PolicyField, {
|
|
367
|
+
props: { name: 'test' },
|
|
368
|
+
target: document.body,
|
|
369
|
+
});
|
|
370
|
+
// No label wrapping since no context, just children area
|
|
371
|
+
// Should not throw
|
|
372
|
+
});
|
|
373
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { ResolvedObjectFieldPolicy } from '../../../types.js';
|
|
3
|
+
import AdvancedFields from '../../components/AdvancedFields.svelte';
|
|
4
|
+
import FieldPolicyProvider from '../../components/FieldPolicyProvider.svelte';
|
|
5
|
+
import PolicyField from '../../components/PolicyField.svelte';
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
policy,
|
|
9
|
+
mode = 'advanced',
|
|
10
|
+
}: {
|
|
11
|
+
policy: ResolvedObjectFieldPolicy;
|
|
12
|
+
mode?: 'basic' | 'advanced';
|
|
13
|
+
} = $props();
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<FieldPolicyProvider {policy} {mode}>
|
|
17
|
+
<PolicyField name="name">
|
|
18
|
+
<input id="name" name="name" type="text" />
|
|
19
|
+
</PolicyField>
|
|
20
|
+
<AdvancedFields>
|
|
21
|
+
<PolicyField name="secretKey">
|
|
22
|
+
<input id="secretKey" name="secretKey" type="text" />
|
|
23
|
+
</PolicyField>
|
|
24
|
+
{#if policy.fields.another}
|
|
25
|
+
<PolicyField name="another">
|
|
26
|
+
<input id="another" name="another" type="text" />
|
|
27
|
+
</PolicyField>
|
|
28
|
+
{/if}
|
|
29
|
+
</AdvancedFields>
|
|
30
|
+
</FieldPolicyProvider>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ResolvedObjectFieldPolicy } from '../../../types.js';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
policy: ResolvedObjectFieldPolicy;
|
|
4
|
+
mode?: 'basic' | 'advanced';
|
|
5
|
+
};
|
|
6
|
+
declare const AdvancedFieldsFixture: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
7
|
+
type AdvancedFieldsFixture = ReturnType<typeof AdvancedFieldsFixture>;
|
|
8
|
+
export default AdvancedFieldsFixture;
|
|
9
|
+
//# sourceMappingURL=AdvancedFieldsFixture.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AdvancedFieldsFixture.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/__tests__/fixtures/AdvancedFieldsFixture.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAKlE,KAAK,gBAAgB,GAAI;IACxB,MAAM,EAAE,yBAAyB,CAAC;IAClC,IAAI,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;CAC7B,CAAC;AA+BF,QAAA,MAAM,qBAAqB,sDAAwC,CAAC;AACpE,KAAK,qBAAqB,GAAG,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACtE,eAAe,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Test fixture: PolicyField with bind:value inputs to verify prefill.
|
|
4
|
+
* - New record with default → input prefilled from resolved default
|
|
5
|
+
* - Loaded record with existing value → input NOT clobbered by default
|
|
6
|
+
*/
|
|
7
|
+
import { untrack } from 'svelte';
|
|
8
|
+
import type { ResolvedObjectFieldPolicy } from '../../../types.js';
|
|
9
|
+
import FieldPolicyProvider from '../../components/FieldPolicyProvider.svelte';
|
|
10
|
+
import PolicyField from '../../components/PolicyField.svelte';
|
|
11
|
+
|
|
12
|
+
let {
|
|
13
|
+
policy,
|
|
14
|
+
isNewRecord = true,
|
|
15
|
+
skuValue = '',
|
|
16
|
+
}: {
|
|
17
|
+
policy: ResolvedObjectFieldPolicy;
|
|
18
|
+
isNewRecord?: boolean;
|
|
19
|
+
skuValue?: string;
|
|
20
|
+
} = $props();
|
|
21
|
+
|
|
22
|
+
// Seed the bound value once from the prop (untrack makes the one-shot capture
|
|
23
|
+
// explicit, mirroring ThemeProvider's SSR-seeding pattern — a loaded record's
|
|
24
|
+
// existing value must never be re-synced from the prop).
|
|
25
|
+
let sku = $state(untrack(() => skuValue));
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<FieldPolicyProvider {policy} mode="basic">
|
|
29
|
+
<PolicyField name="sku" {isNewRecord}>
|
|
30
|
+
<input id="sku" name="sku" type="text" bind:value={sku} />
|
|
31
|
+
</PolicyField>
|
|
32
|
+
<div data-testid="sku-state">{sku}</div>
|
|
33
|
+
</FieldPolicyProvider>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ResolvedObjectFieldPolicy } from '../../../types.js';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
policy: ResolvedObjectFieldPolicy;
|
|
4
|
+
isNewRecord?: boolean;
|
|
5
|
+
skuValue?: string;
|
|
6
|
+
};
|
|
7
|
+
declare const DomPrefillFixture: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
8
|
+
type DomPrefillFixture = ReturnType<typeof DomPrefillFixture>;
|
|
9
|
+
export default DomPrefillFixture;
|
|
10
|
+
//# sourceMappingURL=DomPrefillFixture.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DomPrefillFixture.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/__tests__/fixtures/DomPrefillFixture.svelte.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAIlE,KAAK,gBAAgB,GAAI;IACxB,MAAM,EAAE,yBAAyB,CAAC;IAClC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AA6BF,QAAA,MAAM,iBAAiB,sDAAwC,CAAC;AAChE,KAAK,iBAAiB,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC9D,eAAe,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { ResolvedObjectFieldPolicy } from '../../../types.js';
|
|
3
|
+
import FieldPolicyProvider from '../../components/FieldPolicyProvider.svelte';
|
|
4
|
+
import FormHelp from '../../components/FormHelp.svelte';
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
policy,
|
|
8
|
+
objectDescription,
|
|
9
|
+
mode = 'basic',
|
|
10
|
+
}: {
|
|
11
|
+
policy: ResolvedObjectFieldPolicy;
|
|
12
|
+
objectDescription?: string;
|
|
13
|
+
mode?: 'basic' | 'advanced';
|
|
14
|
+
} = $props();
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<FieldPolicyProvider {policy} {mode}>
|
|
18
|
+
<FormHelp {objectDescription} />
|
|
19
|
+
</FieldPolicyProvider>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ResolvedObjectFieldPolicy } from '../../../types.js';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
policy: ResolvedObjectFieldPolicy;
|
|
4
|
+
objectDescription?: string;
|
|
5
|
+
mode?: 'basic' | 'advanced';
|
|
6
|
+
};
|
|
7
|
+
declare const FormHelpFixture: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
8
|
+
type FormHelpFixture = ReturnType<typeof FormHelpFixture>;
|
|
9
|
+
export default FormHelpFixture;
|
|
10
|
+
//# sourceMappingURL=FormHelpFixture.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormHelpFixture.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/__tests__/fixtures/FormHelpFixture.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAIlE,KAAK,gBAAgB,GAAI;IACxB,MAAM,EAAE,yBAAyB,CAAC;IAClC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,IAAI,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;CAC7B,CAAC;AAmBF,QAAA,MAAM,eAAe,sDAAwC,CAAC;AAC9D,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1D,eAAe,eAAe,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import FieldPolicyGearButton from '../../components/FieldPolicyGearButton.svelte';
|
|
3
|
+
import FieldPolicyGearProvider from '../../components/FieldPolicyGearProvider.svelte';
|
|
4
|
+
import type { FieldPolicyEditorAdapter } from '../../field-policy-editor.js';
|
|
5
|
+
import type { ObjectFormFieldDefinition } from '../../types.js';
|
|
6
|
+
|
|
7
|
+
interface Props {
|
|
8
|
+
objectRef: string;
|
|
9
|
+
fields: Record<string, ObjectFormFieldDefinition>;
|
|
10
|
+
adapter: FieldPolicyEditorAdapter;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
let { objectRef, fields, adapter }: Props = $props();
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<FieldPolicyGearProvider {objectRef} {fields} {adapter}>
|
|
17
|
+
<FieldPolicyGearButton />
|
|
18
|
+
</FieldPolicyGearProvider>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { FieldPolicyEditorAdapter } from '../../field-policy-editor.js';
|
|
2
|
+
import type { ObjectFormFieldDefinition } from '../../types.js';
|
|
3
|
+
interface Props {
|
|
4
|
+
objectRef: string;
|
|
5
|
+
fields: Record<string, ObjectFormFieldDefinition>;
|
|
6
|
+
adapter: FieldPolicyEditorAdapter;
|
|
7
|
+
}
|
|
8
|
+
declare const GeneratedApiGearFixture: import("svelte").Component<Props, {}, "">;
|
|
9
|
+
type GeneratedApiGearFixture = ReturnType<typeof GeneratedApiGearFixture>;
|
|
10
|
+
export default GeneratedApiGearFixture;
|
|
11
|
+
//# sourceMappingURL=GeneratedApiGearFixture.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GeneratedApiGearFixture.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/__tests__/fixtures/GeneratedApiGearFixture.svelte.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAC7E,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAGhE,UAAU,KAAK;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC;IAClD,OAAO,EAAE,wBAAwB,CAAC;CACnC;AAiBD,QAAA,MAAM,uBAAuB,2CAAwC,CAAC;AACtE,KAAK,uBAAuB,GAAG,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAC1E,eAAe,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Test fixture: PolicyField rendered WITHOUT a FieldPolicyProvider.
|
|
4
|
+
* Verifies graceful degradation — children render verbatim.
|
|
5
|
+
*/
|
|
6
|
+
import PolicyField from '../../components/PolicyField.svelte';
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<PolicyField name="standalone">
|
|
10
|
+
<input type="text" />
|
|
11
|
+
</PolicyField>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
2
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
|
+
$$bindings?: Bindings;
|
|
4
|
+
} & Exports;
|
|
5
|
+
(internal: unknown, props: {
|
|
6
|
+
$$events?: Events;
|
|
7
|
+
$$slots?: Slots;
|
|
8
|
+
}): Exports & {
|
|
9
|
+
$set?: any;
|
|
10
|
+
$on?: any;
|
|
11
|
+
};
|
|
12
|
+
z_$$bindings?: Bindings;
|
|
13
|
+
}
|
|
14
|
+
declare const GracefulDegradeFixture: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
15
|
+
[evt: string]: CustomEvent<any>;
|
|
16
|
+
}, {}, {}, string>;
|
|
17
|
+
type GracefulDegradeFixture = InstanceType<typeof GracefulDegradeFixture>;
|
|
18
|
+
export default GracefulDegradeFixture;
|
|
19
|
+
//# sourceMappingURL=GracefulDegradeFixture.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GracefulDegradeFixture.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/__tests__/fixtures/GracefulDegradeFixture.svelte.ts"],"names":[],"mappings":"AAoBA,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IACtG,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,sBAAsB;;kBAA+E,CAAC;AAC1F,KAAK,sBAAsB,GAAG,YAAY,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAC5E,eAAe,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { ResolvedObjectFieldPolicy } from '../../../types.js';
|
|
3
|
+
import FieldPolicyProvider from '../../components/FieldPolicyProvider.svelte';
|
|
4
|
+
import ModeSwitch from '../../components/ModeSwitch.svelte';
|
|
5
|
+
import PolicyField from '../../components/PolicyField.svelte';
|
|
6
|
+
|
|
7
|
+
let { policy }: { policy: ResolvedObjectFieldPolicy } = $props();
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<FieldPolicyProvider {policy} mode="basic">
|
|
11
|
+
<ModeSwitch />
|
|
12
|
+
<PolicyField name="name">
|
|
13
|
+
<input id="name" name="name" type="text" />
|
|
14
|
+
</PolicyField>
|
|
15
|
+
<PolicyField name="secretKey">
|
|
16
|
+
<input id="secretKey" name="secretKey" type="text" />
|
|
17
|
+
</PolicyField>
|
|
18
|
+
</FieldPolicyProvider>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ResolvedObjectFieldPolicy } from '../../../types.js';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
policy: ResolvedObjectFieldPolicy;
|
|
4
|
+
};
|
|
5
|
+
declare const ModeSwitchFixture: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
6
|
+
type ModeSwitchFixture = ReturnType<typeof ModeSwitchFixture>;
|
|
7
|
+
export default ModeSwitchFixture;
|
|
8
|
+
//# sourceMappingURL=ModeSwitchFixture.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModeSwitchFixture.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/__tests__/fixtures/ModeSwitchFixture.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAKlE,KAAK,gBAAgB,GAAI;IAAE,MAAM,EAAE,yBAAyB,CAAA;CAAE,CAAC;AAsBhE,QAAA,MAAM,iBAAiB,sDAAwC,CAAC;AAChE,KAAK,iBAAiB,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC9D,eAAe,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* Test fixture: PolicyField wrapping a control with NO id attribute — the
|
|
4
|
+
* wrapper must assign one so the label's `for` never dangles.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { ResolvedObjectFieldPolicy } from '../../../types.js';
|
|
8
|
+
import FieldPolicyProvider from '../../components/FieldPolicyProvider.svelte';
|
|
9
|
+
import PolicyField from '../../components/PolicyField.svelte';
|
|
10
|
+
|
|
11
|
+
let {
|
|
12
|
+
policy,
|
|
13
|
+
mode = 'basic',
|
|
14
|
+
}: {
|
|
15
|
+
policy: ResolvedObjectFieldPolicy;
|
|
16
|
+
mode?: 'basic' | 'advanced';
|
|
17
|
+
} = $props();
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<FieldPolicyProvider {policy} {mode}>
|
|
21
|
+
<PolicyField name="name">
|
|
22
|
+
<input type="text" />
|
|
23
|
+
</PolicyField>
|
|
24
|
+
</FieldPolicyProvider>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test fixture: PolicyField wrapping a control with NO id attribute — the
|
|
3
|
+
* wrapper must assign one so the label's `for` never dangles.
|
|
4
|
+
*/
|
|
5
|
+
import type { ResolvedObjectFieldPolicy } from '../../../types.js';
|
|
6
|
+
type $$ComponentProps = {
|
|
7
|
+
policy: ResolvedObjectFieldPolicy;
|
|
8
|
+
mode?: 'basic' | 'advanced';
|
|
9
|
+
};
|
|
10
|
+
declare const NoIdFixture: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
11
|
+
type NoIdFixture = ReturnType<typeof NoIdFixture>;
|
|
12
|
+
export default NoIdFixture;
|
|
13
|
+
//# sourceMappingURL=NoIdFixture.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NoIdFixture.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/__tests__/fixtures/NoIdFixture.svelte.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAIlE,KAAK,gBAAgB,GAAI;IACxB,MAAM,EAAE,yBAAyB,CAAC;IAClC,IAAI,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;CAC7B,CAAC;AAsBF,QAAA,MAAM,WAAW,sDAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
|