@happyvertical/smrt-svelte 0.53.0 → 0.53.2
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/package.json +15 -15
- package/dist/__tests__/app-state.test.js +0 -156
- package/dist/__tests__/data-surface-bridge.test.js +0 -351
- package/dist/__tests__/provider-mode-harness.svelte +0 -14
- package/dist/__tests__/provider-mode-harness.svelte.d.ts +0 -11
- package/dist/__tests__/provider-mode-harness.svelte.d.ts.map +0 -1
- package/dist/__tests__/provider-mode-probe.svelte +0 -13
- package/dist/__tests__/provider-mode-probe.svelte.d.ts +0 -8
- package/dist/__tests__/provider-mode-probe.svelte.d.ts.map +0 -1
- package/dist/__tests__/provider-webmcp-harness.svelte +0 -14
- package/dist/__tests__/provider-webmcp-harness.svelte.d.ts +0 -8
- package/dist/__tests__/provider-webmcp-harness.svelte.d.ts.map +0 -1
- package/dist/__tests__/success-never-text.test.js +0 -100
- package/dist/__tests__/warm-clients.test.js +0 -186
- package/dist/browser-ai/adapters/llm/bitgpu-inference-backend.test.js +0 -464
- package/dist/browser-ai/adapters/llm/webllm-inference-backend.test.js +0 -646
- package/dist/browser-ai/adapters/stt/browser-speech.test.js +0 -113
- package/dist/browser-ai/adapters/stt/dictation-source.test.js +0 -52
- package/dist/browser-ai/svelte/components/__tests__/ModelStatusControl.test.js +0 -172
- package/dist/components/board/__tests__/Board.test.js +0 -498
- package/dist/components/board/__tests__/BoardSsrHarness.svelte +0 -30
- package/dist/components/board/__tests__/BoardSsrHarness.svelte.d.ts +0 -19
- package/dist/components/board/__tests__/BoardSsrHarness.svelte.d.ts.map +0 -1
- package/dist/components/forms/__tests__/AddressInput.behavior.test.js +0 -216
- package/dist/components/forms/__tests__/CheckboxInput.test.js +0 -92
- package/dist/components/forms/__tests__/DateRangeInput.behavior.test.js +0 -135
- package/dist/components/forms/__tests__/DateTimeInput.behavior.test.js +0 -113
- package/dist/components/forms/__tests__/FileUpload.error-alert.test.js +0 -37
- package/dist/components/forms/__tests__/FileUpload.native-form.test.js +0 -249
- package/dist/components/forms/__tests__/FileUpload.test.js +0 -90
- package/dist/components/forms/__tests__/FileUploadReset.fixture.svelte +0 -24
- package/dist/components/forms/__tests__/FileUploadReset.fixture.svelte.d.ts +0 -10
- package/dist/components/forms/__tests__/FileUploadReset.fixture.svelte.d.ts.map +0 -1
- package/dist/components/forms/__tests__/Form.behavior.test.js +0 -137
- package/dist/components/forms/__tests__/Form.extraction.test.js +0 -68
- package/dist/components/forms/__tests__/Form.stt-error.test.js +0 -57
- package/dist/components/forms/__tests__/Form.test.js +0 -86
- package/dist/components/forms/__tests__/Form.ui-controls.test.js +0 -119
- package/dist/components/forms/__tests__/Form.webmcp.test.js +0 -2336
- package/dist/components/forms/__tests__/FormMicButton.test.js +0 -92
- package/dist/components/forms/__tests__/FormScope.test.js +0 -39
- package/dist/components/forms/__tests__/MeasurementInput.behavior.test.js +0 -129
- package/dist/components/forms/__tests__/MoneyInput.behavior.test.js +0 -124
- package/dist/components/forms/__tests__/NumberInput.behavior.test.js +0 -151
- package/dist/components/forms/__tests__/PhoneInput.behavior.test.js +0 -96
- package/dist/components/forms/__tests__/SearchInput.test.js +0 -79
- package/dist/components/forms/__tests__/SelectInput.behavior.test.js +0 -132
- package/dist/components/forms/__tests__/TextInput.behavior.test.js +0 -131
- package/dist/components/forms/__tests__/TextareaInput.behavior.test.js +0 -96
- package/dist/components/forms/__tests__/async-invalid-field.fixture.svelte +0 -30
- package/dist/components/forms/__tests__/async-invalid-field.fixture.svelte.d.ts +0 -7
- package/dist/components/forms/__tests__/async-invalid-field.fixture.svelte.d.ts.map +0 -1
- package/dist/components/forms/__tests__/async-validation-form.fixture.svelte +0 -19
- package/dist/components/forms/__tests__/async-validation-form.fixture.svelte.d.ts +0 -9
- package/dist/components/forms/__tests__/async-validation-form.fixture.svelte.d.ts.map +0 -1
- package/dist/components/forms/__tests__/async-validation-snapshot-form.fixture.svelte +0 -21
- package/dist/components/forms/__tests__/async-validation-snapshot-form.fixture.svelte.d.ts +0 -8
- package/dist/components/forms/__tests__/async-validation-snapshot-form.fixture.svelte.d.ts.map +0 -1
- package/dist/components/forms/__tests__/composite-inputs-a11y.test.js +0 -69
- package/dist/components/forms/__tests__/compound-registration-wrapper.fixture.svelte +0 -27
- package/dist/components/forms/__tests__/compound-registration-wrapper.fixture.svelte.d.ts +0 -9
- package/dist/components/forms/__tests__/compound-registration-wrapper.fixture.svelte.d.ts.map +0 -1
- package/dist/components/forms/__tests__/custom-registration-field.fixture.svelte +0 -48
- package/dist/components/forms/__tests__/custom-registration-field.fixture.svelte.d.ts +0 -10
- package/dist/components/forms/__tests__/custom-registration-field.fixture.svelte.d.ts.map +0 -1
- package/dist/components/forms/__tests__/form-extraction-values.fixture.svelte +0 -26
- package/dist/components/forms/__tests__/form-extraction-values.fixture.svelte.d.ts +0 -13
- package/dist/components/forms/__tests__/form-extraction-values.fixture.svelte.d.ts.map +0 -1
- package/dist/components/forms/__tests__/form-registration-lifecycle.fixture.svelte +0 -52
- package/dist/components/forms/__tests__/form-registration-lifecycle.fixture.svelte.d.ts +0 -16
- package/dist/components/forms/__tests__/form-registration-lifecycle.fixture.svelte.d.ts.map +0 -1
- package/dist/components/forms/__tests__/form-scope.fixture.svelte +0 -30
- package/dist/components/forms/__tests__/form-scope.fixture.svelte.d.ts +0 -10
- package/dist/components/forms/__tests__/form-scope.fixture.svelte.d.ts.map +0 -1
- package/dist/components/forms/__tests__/form-with-fields.fixture.svelte +0 -158
- package/dist/components/forms/__tests__/form-with-fields.fixture.svelte.d.ts +0 -51
- package/dist/components/forms/__tests__/form-with-fields.fixture.svelte.d.ts.map +0 -1
- package/dist/components/forms/__tests__/form-with-policy-field.fixture.svelte +0 -24
- package/dist/components/forms/__tests__/form-with-policy-field.fixture.svelte.d.ts +0 -11
- package/dist/components/forms/__tests__/form-with-policy-field.fixture.svelte.d.ts.map +0 -1
- package/dist/components/forms/__tests__/form-with-structured-fields.fixture.svelte +0 -105
- package/dist/components/forms/__tests__/form-with-structured-fields.fixture.svelte.d.ts +0 -42
- package/dist/components/forms/__tests__/form-with-structured-fields.fixture.svelte.d.ts.map +0 -1
- package/dist/components/forms/__tests__/form-with-ui-controls.fixture.svelte +0 -84
- package/dist/components/forms/__tests__/form-with-ui-controls.fixture.svelte.d.ts +0 -14
- package/dist/components/forms/__tests__/form-with-ui-controls.fixture.svelte.d.ts.map +0 -1
- package/dist/components/forms/__tests__/legacy-form-context.fixture.svelte +0 -44
- package/dist/components/forms/__tests__/legacy-form-context.fixture.svelte.d.ts +0 -9
- package/dist/components/forms/__tests__/legacy-form-context.fixture.svelte.d.ts.map +0 -1
- package/dist/components/forms/__tests__/mic-keyboard-a11y.test.js +0 -74
- package/dist/components/forms/__tests__/policy-field.fixture.svelte +0 -35
- package/dist/components/forms/__tests__/policy-field.fixture.svelte.d.ts +0 -8
- package/dist/components/forms/__tests__/policy-field.fixture.svelte.d.ts.map +0 -1
- package/dist/components/forms/__tests__/rich-inputs-a11y.test.js +0 -87
- package/dist/components/settings/__tests__/SettingsCatalog.test.js +0 -69
- package/dist/components/settings/__tests__/catalog.test.js +0 -46
- package/dist/components/workspace/__tests__/AdminShell.responsive.test.js +0 -597
- package/dist/components/workspace/__tests__/AdminShell.test.js +0 -572
- package/dist/components/workspace/__tests__/RoleShell.test.js +0 -772
- package/dist/components/workspace/__tests__/TenantNav.test.js +0 -208
- package/dist/components/workspace/__tests__/WorkspaceAccountMenu.test.js +0 -79
- package/dist/components/workspace/__tests__/WorkspaceShell.test.js +0 -630
- package/dist/components/workspace/__tests__/admin-shell-header-overflow.test.js +0 -25
- package/dist/components/workspace/__tests__/admin-shell-hotkeys.test.js +0 -34
- package/dist/components/workspace/__tests__/admin-shell-mobile.test.js +0 -217
- package/dist/components/workspace/__tests__/admin-shell-mutation-effect-harness.svelte +0 -52
- package/dist/components/workspace/__tests__/admin-shell-mutation-effect-harness.svelte.d.ts +0 -23
- package/dist/components/workspace/__tests__/admin-shell-mutation-effect-harness.svelte.d.ts.map +0 -1
- package/dist/components/workspace/__tests__/admin-shell-page-contracts.test.js +0 -30
- package/dist/components/workspace/__tests__/admin-shell-responsive-state.test.js +0 -184
- package/dist/components/workspace/__tests__/admin-shell-settings.test.js +0 -25
- package/dist/components/workspace/__tests__/admin-shell-state.test.js +0 -286
- package/dist/components/workspace/__tests__/admin-shell-theme-hooks.test.js +0 -36
- package/dist/components/workspace/__tests__/breadcrumbs-helpers.test.js +0 -141
- package/dist/components/workspace/__tests__/context-forwarding-harness.svelte +0 -45
- package/dist/components/workspace/__tests__/context-forwarding-harness.svelte.d.ts +0 -21
- package/dist/components/workspace/__tests__/context-forwarding-harness.svelte.d.ts.map +0 -1
- package/dist/components/workspace/__tests__/define-tools-dock.test.js +0 -1188
- package/dist/components/workspace/__tests__/harness.svelte +0 -25
- package/dist/components/workspace/__tests__/harness.svelte.d.ts +0 -14
- package/dist/components/workspace/__tests__/harness.svelte.d.ts.map +0 -1
- package/dist/components/workspace/__tests__/index.test.js +0 -28
- package/dist/components/workspace/__tests__/legacy-index.test.js +0 -9
- package/dist/components/workspace/__tests__/manifest-nav-helpers.test.js +0 -24
- package/dist/components/workspace/__tests__/manifest-nav.test.js +0 -599
- package/dist/components/workspace/__tests__/nav-helpers.test.js +0 -95
- package/dist/components/workspace/__tests__/render-harness.svelte +0 -66
- package/dist/components/workspace/__tests__/render-harness.svelte.d.ts +0 -32
- package/dist/components/workspace/__tests__/render-harness.svelte.d.ts.map +0 -1
- package/dist/components/workspace/__tests__/render-tools-dock.test.js +0 -260
- package/dist/components/workspace/__tests__/role-shell-bind-harness.svelte +0 -58
- package/dist/components/workspace/__tests__/role-shell-bind-harness.svelte.d.ts +0 -16
- package/dist/components/workspace/__tests__/role-shell-bind-harness.svelte.d.ts.map +0 -1
- package/dist/components/workspace/__tests__/role-shell-switch-harness.svelte +0 -41
- package/dist/components/workspace/__tests__/role-shell-switch-harness.svelte.d.ts +0 -13
- package/dist/components/workspace/__tests__/role-shell-switch-harness.svelte.d.ts.map +0 -1
- package/dist/components/workspace/__tests__/shell-chrome-components.test.js +0 -108
- package/dist/components/workspace/__tests__/system-feed.test.js +0 -327
- package/dist/components/workspace/__tests__/test-icon.svelte +0 -17
- package/dist/components/workspace/__tests__/test-icon.svelte.d.ts +0 -19
- package/dist/components/workspace/__tests__/test-icon.svelte.d.ts.map +0 -1
- package/dist/components/workspace/__tests__/typed-tool-fixture/TypedTool.svelte +0 -38
- package/dist/components/workspace/__tests__/typed-tool-fixture/TypedTool.svelte.d.ts +0 -22
- package/dist/components/workspace/__tests__/typed-tool-fixture/TypedTool.svelte.d.ts.map +0 -1
- package/dist/components/workspace/__tests__/typed-tool-fixture/register-typed-tool.d.ts +0 -66
- package/dist/components/workspace/__tests__/typed-tool-fixture/register-typed-tool.d.ts.map +0 -1
- package/dist/components/workspace/__tests__/typed-tool-fixture/register-typed-tool.js +0 -115
- package/dist/components/workspace/__tests__/typed-tool-fixture/typed-tool-types.d.ts +0 -15
- package/dist/components/workspace/__tests__/typed-tool-fixture/typed-tool-types.d.ts.map +0 -1
- package/dist/components/workspace/__tests__/typed-tool-fixture/typed-tool-types.js +0 -7
- package/dist/components/workspace/__tests__/typed-tool-fixture.test.js +0 -115
- package/dist/components/workspace/__tests__/use-harness-orphan.svelte +0 -9
- package/dist/components/workspace/__tests__/use-harness-orphan.svelte.d.ts +0 -19
- package/dist/components/workspace/__tests__/use-harness-orphan.svelte.d.ts.map +0 -1
- package/dist/components/workspace/__tests__/use-harness.svelte +0 -23
- package/dist/components/workspace/__tests__/use-harness.svelte.d.ts +0 -8
- package/dist/components/workspace/__tests__/use-harness.svelte.d.ts.map +0 -1
- package/dist/components/workspace/__tests__/use-tools-dock.test.js +0 -33
- package/dist/components/workspace/__tests__/workspace-shell-bind-harness.svelte +0 -43
- package/dist/components/workspace/__tests__/workspace-shell-bind-harness.svelte.d.ts +0 -11
- package/dist/components/workspace/__tests__/workspace-shell-bind-harness.svelte.d.ts.map +0 -1
- package/dist/components/workspace/server/__tests__/compose-availability.test.js +0 -383
- package/dist/components/workspace/server/__tests__/typed-context-fixture.d.ts +0 -78
- package/dist/components/workspace/server/__tests__/typed-context-fixture.d.ts.map +0 -1
- package/dist/components/workspace/server/__tests__/typed-context-fixture.js +0 -104
- package/dist/hooks/__tests__/stt-consumer.fixture.svelte +0 -25
- package/dist/hooks/__tests__/stt-consumer.fixture.svelte.d.ts +0 -15
- package/dist/hooks/__tests__/stt-consumer.fixture.svelte.d.ts.map +0 -1
- package/dist/hooks/__tests__/stt-ownership-harness.svelte +0 -42
- package/dist/hooks/__tests__/stt-ownership-harness.svelte.d.ts +0 -20
- package/dist/hooks/__tests__/stt-ownership-harness.svelte.d.ts.map +0 -1
- package/dist/hooks/__tests__/useSTT-ownership.test.js +0 -102
- package/dist/i18n/__tests__/server.spec.js +0 -57
- package/dist/internal/logger.test.js +0 -54
- package/dist/provider-mode.test.js +0 -86
- package/dist/provider-webmcp.test.js +0 -244
- package/dist/state/__tests__/app-state-ai-lifecycle.test.js +0 -240
- package/dist/state/__tests__/warm-clients.test.js +0 -40
- package/dist/web/__tests__/activity-feed-harness.svelte +0 -32
- package/dist/web/__tests__/activity-feed-harness.svelte.d.ts +0 -18
- package/dist/web/__tests__/activity-feed-harness.svelte.d.ts.map +0 -1
- package/dist/web/__tests__/activity-feed.integration.svelte.test.js +0 -190
- package/dist/web/__tests__/activity-feed.svelte.test.js +0 -235
- package/dist/web/__tests__/assistant-dock.integration.svelte.test.js +0 -204
- package/dist/web/__tests__/data-surface-conformance.integration.svelte.test.js +0 -1392
- package/dist/web/__tests__/harness.svelte +0 -25
- package/dist/web/__tests__/harness.svelte.d.ts +0 -15
- package/dist/web/__tests__/harness.svelte.d.ts.map +0 -1
- package/dist/web/__tests__/list-data-surface.fixture.svelte +0 -59
- package/dist/web/__tests__/list-data-surface.fixture.svelte.d.ts +0 -14
- package/dist/web/__tests__/list-data-surface.fixture.svelte.d.ts.map +0 -1
- package/dist/web/__tests__/list-data-surface.svelte.test.js +0 -106
- package/dist/web/__tests__/list-data-surface.test.js +0 -651
- package/dist/web/__tests__/list-sort-surface.fixture.svelte +0 -41
- package/dist/web/__tests__/list-sort-surface.fixture.svelte.d.ts +0 -15
- package/dist/web/__tests__/list-sort-surface.fixture.svelte.d.ts.map +0 -1
- package/dist/web/__tests__/list-sort-surface.svelte.test.js +0 -59
- package/dist/web/__tests__/live-collection.svelte.test.js +0 -185
- package/dist/web/__tests__/provider-ui-registry.fixture.svelte +0 -43
- package/dist/web/__tests__/provider-ui-registry.fixture.svelte.d.ts +0 -13
- package/dist/web/__tests__/provider-ui-registry.fixture.svelte.d.ts.map +0 -1
- package/dist/web/__tests__/provider-ui-registry.test.js +0 -235
- package/dist/web/__tests__/remote-query-harness.svelte +0 -27
- package/dist/web/__tests__/remote-query-harness.svelte.d.ts +0 -11
- package/dist/web/__tests__/remote-query-harness.svelte.d.ts.map +0 -1
- package/dist/web/__tests__/remote-query.svelte.test.js +0 -101
- package/dist/web/__tests__/surfaces.child.fixture.svelte +0 -69
- package/dist/web/__tests__/surfaces.child.fixture.svelte.d.ts +0 -16
- package/dist/web/__tests__/surfaces.child.fixture.svelte.d.ts.map +0 -1
- package/dist/web/__tests__/surfaces.fixture.svelte +0 -26
- package/dist/web/__tests__/surfaces.fixture.svelte.d.ts +0 -18
- package/dist/web/__tests__/surfaces.fixture.svelte.d.ts.map +0 -1
- package/dist/web/__tests__/surfaces.svelte.test.js +0 -140
- package/dist/web/__tests__/update-available-harness.svelte +0 -46
- package/dist/web/__tests__/update-available-harness.svelte.d.ts +0 -22
- package/dist/web/__tests__/update-available-harness.svelte.d.ts.map +0 -1
- package/dist/web/__tests__/update-available.svelte.test.js +0 -137
- package/dist/web/__tests__/view-intent-provider.fixture.svelte +0 -28
- package/dist/web/__tests__/view-intent-provider.fixture.svelte.d.ts +0 -13
- package/dist/web/__tests__/view-intent-provider.fixture.svelte.d.ts.map +0 -1
- package/dist/web/__tests__/view-intent.fixture.svelte +0 -33
- package/dist/web/__tests__/view-intent.fixture.svelte.d.ts +0 -15
- package/dist/web/__tests__/view-intent.fixture.svelte.d.ts.map +0 -1
- package/dist/web/__tests__/view-intent.intents.d.ts +0 -14
- package/dist/web/__tests__/view-intent.intents.d.ts.map +0 -1
- package/dist/web/__tests__/view-intent.intents.js +0 -38
- package/dist/web/__tests__/view-intent.svelte.test.js +0 -244
- package/dist/web/__tests__/webmcp-composed.child.fixture.svelte +0 -73
- package/dist/web/__tests__/webmcp-composed.child.fixture.svelte.d.ts +0 -8
- package/dist/web/__tests__/webmcp-composed.child.fixture.svelte.d.ts.map +0 -1
- package/dist/web/__tests__/webmcp-composed.fixture.svelte +0 -52
- package/dist/web/__tests__/webmcp-composed.fixture.svelte.d.ts +0 -12
- package/dist/web/__tests__/webmcp-composed.fixture.svelte.d.ts.map +0 -1
- package/dist/web/__tests__/webmcp-composed.integration.svelte.test.js +0 -251
- package/dist/web/__tests__/webmcp-effects-reactivity.child.fixture.svelte +0 -16
- package/dist/web/__tests__/webmcp-effects-reactivity.child.fixture.svelte.d.ts +0 -19
- package/dist/web/__tests__/webmcp-effects-reactivity.child.fixture.svelte.d.ts.map +0 -1
- package/dist/web/__tests__/webmcp-effects-reactivity.fixture.svelte +0 -11
- package/dist/web/__tests__/webmcp-effects-reactivity.fixture.svelte.d.ts +0 -8
- package/dist/web/__tests__/webmcp-effects-reactivity.fixture.svelte.d.ts.map +0 -1
- package/dist/web/__tests__/webmcp-harness-reactive-samename.svelte +0 -20
- package/dist/web/__tests__/webmcp-harness-reactive-samename.svelte.d.ts +0 -7
- package/dist/web/__tests__/webmcp-harness-reactive-samename.svelte.d.ts.map +0 -1
- package/dist/web/__tests__/webmcp-harness-unannotated.svelte +0 -14
- package/dist/web/__tests__/webmcp-harness-unannotated.svelte.d.ts +0 -19
- package/dist/web/__tests__/webmcp-harness-unannotated.svelte.d.ts.map +0 -1
- package/dist/web/__tests__/webmcp-harness.svelte +0 -18
- package/dist/web/__tests__/webmcp-harness.svelte.d.ts +0 -7
- package/dist/web/__tests__/webmcp-harness.svelte.d.ts.map +0 -1
- package/dist/web/__tests__/webmcp-ssr.fixture.svelte +0 -13
- package/dist/web/__tests__/webmcp-ssr.fixture.svelte.d.ts +0 -19
- package/dist/web/__tests__/webmcp-ssr.fixture.svelte.d.ts.map +0 -1
- package/dist/web/__tests__/webmcp-ui.test.js +0 -723
- package/dist/web/__tests__/webmcp.test.js +0 -234
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure phone-chrome decisions behind AdminShell: hide-on-scroll, keyboard
|
|
3
|
-
* heuristic, viewport classes, the phone top-bar model, and bottom-bar mode.
|
|
4
|
-
*/
|
|
5
|
-
import { describe, expect, it } from 'vitest';
|
|
6
|
-
import { bottomBarMode, findShellNavTrail, keyboardLikelyOpen, normalizeShellPath, phoneTopBarFor, ScrollChrome, shellPageTrailFor, viewportFor, } from '../admin-shell/mobile-shell.js';
|
|
7
|
-
describe('ScrollChrome (hide on scroll)', () => {
|
|
8
|
-
function run(chrome, ys, extra = {}) {
|
|
9
|
-
return ys.map((y) => chrome.update({ y, ...extra }));
|
|
10
|
-
}
|
|
11
|
-
it('stays shown near the top of the page', () => {
|
|
12
|
-
expect(run(new ScrollChrome(), [0, 20, 40, 56])).toEqual([
|
|
13
|
-
false,
|
|
14
|
-
false,
|
|
15
|
-
false,
|
|
16
|
-
false,
|
|
17
|
-
]);
|
|
18
|
-
});
|
|
19
|
-
it('hides after scrolling down and comes back on the first scroll up', () => {
|
|
20
|
-
const chrome = new ScrollChrome();
|
|
21
|
-
expect(run(chrome, [0, 100, 120, 300])).toEqual([false, true, true, true]);
|
|
22
|
-
expect(chrome.update({ y: 295 })).toBe(false);
|
|
23
|
-
expect(run(chrome, [300, 306, 310])).toEqual([false, false, true]);
|
|
24
|
-
});
|
|
25
|
-
it('ignores jitter below the thresholds', () => {
|
|
26
|
-
const chrome = new ScrollChrome();
|
|
27
|
-
run(chrome, [0, 200, 400]);
|
|
28
|
-
expect(chrome.update({ y: 398 })).toBe(true);
|
|
29
|
-
});
|
|
30
|
-
it('always shows at the top and while pinned', () => {
|
|
31
|
-
const chrome = new ScrollChrome();
|
|
32
|
-
run(chrome, [0, 200, 400]);
|
|
33
|
-
expect(chrome.update({ y: 10 })).toBe(false);
|
|
34
|
-
run(chrome, [200, 400]);
|
|
35
|
-
expect(chrome.update({ y: 600, pinned: true })).toBe(false);
|
|
36
|
-
expect(chrome.update({ y: 800, pinned: true })).toBe(false);
|
|
37
|
-
});
|
|
38
|
-
it('does not treat iOS overscroll bounce as a scroll up', () => {
|
|
39
|
-
const chrome = new ScrollChrome();
|
|
40
|
-
run(chrome, [0, 300, 500], { maxY: 500 });
|
|
41
|
-
expect(chrome.update({ y: 540, maxY: 500 })).toBe(true);
|
|
42
|
-
expect(chrome.update({ y: 500, maxY: 500 })).toBe(true);
|
|
43
|
-
});
|
|
44
|
-
it('honours custom tuning and reset', () => {
|
|
45
|
-
const chrome = new ScrollChrome({ revealWithin: 0, hideAfter: 50 });
|
|
46
|
-
expect(run(chrome, [10, 40])).toEqual([false, false]);
|
|
47
|
-
expect(chrome.update({ y: 70 })).toBe(true);
|
|
48
|
-
chrome.reset();
|
|
49
|
-
expect(chrome.hidden).toBe(false);
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
describe('viewportFor', () => {
|
|
53
|
-
it('classifies phone, tablet and desktop', () => {
|
|
54
|
-
expect(viewportFor({ phone: true, desktop: false })).toBe('phone');
|
|
55
|
-
expect(viewportFor({ phone: false, desktop: false })).toBe('tablet');
|
|
56
|
-
expect(viewportFor({ phone: false, desktop: true })).toBe('desktop');
|
|
57
|
-
});
|
|
58
|
-
});
|
|
59
|
-
describe('keyboardLikelyOpen', () => {
|
|
60
|
-
it('is open when the visual viewport is much shorter', () => {
|
|
61
|
-
expect(keyboardLikelyOpen({ layoutHeight: 844, visualHeight: 500 })).toBe(true);
|
|
62
|
-
expect(keyboardLikelyOpen({ layoutHeight: 844, visualHeight: 780 })).toBe(false);
|
|
63
|
-
});
|
|
64
|
-
it('does not mistake pinch zoom for a keyboard', () => {
|
|
65
|
-
expect(keyboardLikelyOpen({ layoutHeight: 844, visualHeight: 422, scale: 2 })).toBe(false);
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
describe('nav paths', () => {
|
|
69
|
-
const nav = [
|
|
70
|
-
{ href: '/', label: 'Home' },
|
|
71
|
-
{
|
|
72
|
-
href: '/settings',
|
|
73
|
-
label: 'Settings',
|
|
74
|
-
children: [{ href: '/settings/health', label: 'Health' }],
|
|
75
|
-
},
|
|
76
|
-
];
|
|
77
|
-
it('normalizes trailing slashes', () => {
|
|
78
|
-
expect(normalizeShellPath('/a/b//')).toBe('/a/b');
|
|
79
|
-
expect(normalizeShellPath('/')).toBe('/');
|
|
80
|
-
});
|
|
81
|
-
it('finds the trail to the deepest matching item without the root swallowing everything', () => {
|
|
82
|
-
expect(findShellNavTrail(nav, '/settings/health/x').map((item) => item.label)).toEqual(['Settings', 'Health']);
|
|
83
|
-
expect(findShellNavTrail(nav, '/other')).toEqual([]);
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
describe('phoneTopBarFor', () => {
|
|
87
|
-
const navItems = [
|
|
88
|
-
{ href: '/sites/alpha/articles', label: 'Articles' },
|
|
89
|
-
{
|
|
90
|
-
href: '/sites/alpha/settings',
|
|
91
|
-
label: 'Settings',
|
|
92
|
-
children: [{ href: '/sites/alpha/settings/health', label: 'Health' }],
|
|
93
|
-
},
|
|
94
|
-
];
|
|
95
|
-
const base = { homeHref: '/sites/alpha', homeTitle: 'Alpha Times', navItems };
|
|
96
|
-
it('shows the workspace name on section homes', () => {
|
|
97
|
-
expect(phoneTopBarFor({ ...base, path: '/sites/alpha' })).toEqual({
|
|
98
|
-
kind: 'home',
|
|
99
|
-
title: 'Alpha Times',
|
|
100
|
-
});
|
|
101
|
-
expect(phoneTopBarFor({ ...base, path: '/sites/alpha/articles/' }).kind).toBe('home');
|
|
102
|
-
});
|
|
103
|
-
it('gives a nested nav page a back arrow to its parent nav item', () => {
|
|
104
|
-
expect(phoneTopBarFor({ ...base, path: '/sites/alpha/settings/health' })).toEqual({
|
|
105
|
-
kind: 'detail',
|
|
106
|
-
title: 'Health',
|
|
107
|
-
backHref: '/sites/alpha/settings',
|
|
108
|
-
backLabel: 'Settings',
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
it('goes back to the last page-given parent', () => {
|
|
112
|
-
expect(phoneTopBarFor({
|
|
113
|
-
...base,
|
|
114
|
-
path: '/sites/alpha/articles/a1/video/create',
|
|
115
|
-
pageTitle: 'Create video',
|
|
116
|
-
parents: [
|
|
117
|
-
{ label: 'Fair opens Friday', href: '/sites/alpha/articles/a1' },
|
|
118
|
-
{ label: 'Videos', href: '/sites/alpha/articles/a1/videos' },
|
|
119
|
-
],
|
|
120
|
-
})).toEqual({
|
|
121
|
-
kind: 'detail',
|
|
122
|
-
title: 'Create video',
|
|
123
|
-
backHref: '/sites/alpha/articles/a1/videos',
|
|
124
|
-
backLabel: 'Videos',
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
it('shows back to the parent list and the page title on detail pages', () => {
|
|
128
|
-
expect(phoneTopBarFor({
|
|
129
|
-
...base,
|
|
130
|
-
path: '/sites/alpha/articles/a1/images',
|
|
131
|
-
pageTitle: 'Fair opens Friday',
|
|
132
|
-
})).toEqual({
|
|
133
|
-
kind: 'detail',
|
|
134
|
-
title: 'Fair opens Friday',
|
|
135
|
-
backHref: '/sites/alpha/articles',
|
|
136
|
-
backLabel: 'Articles',
|
|
137
|
-
});
|
|
138
|
-
});
|
|
139
|
-
it('falls back to the parent name, then to home', () => {
|
|
140
|
-
expect(phoneTopBarFor({ ...base, path: '/sites/alpha/articles/a1' })).toMatchObject({ title: 'Articles', backHref: '/sites/alpha/articles' });
|
|
141
|
-
expect(phoneTopBarFor({ ...base, path: '/sites/alpha/other/thing' })).toMatchObject({ kind: 'detail', backHref: '/sites/alpha' });
|
|
142
|
-
});
|
|
143
|
-
it('uses a page-provided parent and back label', () => {
|
|
144
|
-
expect(phoneTopBarFor({
|
|
145
|
-
...base,
|
|
146
|
-
path: '/sites/alpha/articles/a1/video/create',
|
|
147
|
-
pageTitle: 'Create video',
|
|
148
|
-
backHref: '/sites/alpha/articles/a1/videos',
|
|
149
|
-
backLabel: 'Videos',
|
|
150
|
-
})).toEqual({
|
|
151
|
-
kind: 'detail',
|
|
152
|
-
title: 'Create video',
|
|
153
|
-
backHref: '/sites/alpha/articles/a1/videos',
|
|
154
|
-
backLabel: 'Videos',
|
|
155
|
-
});
|
|
156
|
-
});
|
|
157
|
-
});
|
|
158
|
-
describe('shellPageTrailFor', () => {
|
|
159
|
-
const navItems = [
|
|
160
|
-
{ href: '/sites/alpha/articles', label: 'Content' },
|
|
161
|
-
{
|
|
162
|
-
href: '/sites/alpha/settings',
|
|
163
|
-
label: 'Settings',
|
|
164
|
-
children: [{ href: '/sites/alpha/health', label: 'Health' }],
|
|
165
|
-
},
|
|
166
|
-
];
|
|
167
|
-
const base = { homeHref: '/sites/alpha', homeTitle: 'Alpha Times', navItems };
|
|
168
|
-
const labels = (path, parents) => shellPageTrailFor({ ...base, path, parents }).crumbs.map((c) => c.label);
|
|
169
|
-
it('has no crumbs on section homes', () => {
|
|
170
|
-
expect(shellPageTrailFor({ ...base, path: '/sites/alpha' })).toMatchObject({
|
|
171
|
-
sectionHome: true,
|
|
172
|
-
crumbs: [],
|
|
173
|
-
});
|
|
174
|
-
expect(shellPageTrailFor({ ...base, path: '/sites/alpha/articles/' })).toMatchObject({
|
|
175
|
-
sectionHome: true,
|
|
176
|
-
crumbs: [],
|
|
177
|
-
current: { label: 'Content' },
|
|
178
|
-
});
|
|
179
|
-
});
|
|
180
|
-
it('shows an ancestor once when the page also names it as a parent', () => {
|
|
181
|
-
expect(labels('/sites/alpha/articles/create', [
|
|
182
|
-
{ label: 'Content', href: '/sites/alpha/articles/' },
|
|
183
|
-
])).toEqual(['Alpha Times', 'Content']);
|
|
184
|
-
});
|
|
185
|
-
it('lists ancestors only, never the current page', () => {
|
|
186
|
-
expect(labels('/sites/alpha/articles/a1')).toEqual([
|
|
187
|
-
'Alpha Times',
|
|
188
|
-
'Content',
|
|
189
|
-
]);
|
|
190
|
-
// A nested nav page: its parent item is an ancestor even when the URL
|
|
191
|
-
// is not below it.
|
|
192
|
-
expect(labels('/sites/alpha/health')).toEqual(['Alpha Times', 'Settings']);
|
|
193
|
-
expect(labels('/sites/alpha/health/job-1')).toEqual([
|
|
194
|
-
'Alpha Times',
|
|
195
|
-
'Settings',
|
|
196
|
-
'Health',
|
|
197
|
-
]);
|
|
198
|
-
expect(labels('/sites/alpha/other')).toEqual(['Alpha Times']);
|
|
199
|
-
});
|
|
200
|
-
it('appends page-given parents after the nav trail', () => {
|
|
201
|
-
expect(labels('/sites/alpha/articles/a1/videos', [
|
|
202
|
-
{ label: 'Fair opens Friday', href: '/sites/alpha/articles/a1' },
|
|
203
|
-
])).toEqual(['Alpha Times', 'Content', 'Fair opens Friday']);
|
|
204
|
-
// A parent on a section home makes it a child page.
|
|
205
|
-
expect(labels('/sites/alpha/articles', [
|
|
206
|
-
{ label: 'Somewhere', href: '/sites/alpha/somewhere' },
|
|
207
|
-
])).toEqual(['Alpha Times', 'Somewhere']);
|
|
208
|
-
});
|
|
209
|
-
});
|
|
210
|
-
describe('bottomBarMode', () => {
|
|
211
|
-
it('swaps the nav bar for a form bar and hides both with the keyboard', () => {
|
|
212
|
-
expect(bottomBarMode({ formActions: false, keyboardOpen: false })).toBe('nav');
|
|
213
|
-
expect(bottomBarMode({ formActions: true, keyboardOpen: false })).toBe('form');
|
|
214
|
-
expect(bottomBarMode({ formActions: true, keyboardOpen: true })).toBe('none');
|
|
215
|
-
expect(bottomBarMode({ formActions: false, keyboardOpen: true })).toBe('none');
|
|
216
|
-
});
|
|
217
|
-
});
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
/**
|
|
3
|
-
* Runs a caller-supplied ShellState mutation inside a consumer $effect. Tests
|
|
4
|
-
* use this to prove ShellState's internal reads do not become dependencies of
|
|
5
|
-
* the consumer effect.
|
|
6
|
-
*/
|
|
7
|
-
import type { ShellState } from '../admin-shell/state.svelte.js';
|
|
8
|
-
import type { ShellActivity } from '../admin-shell/types.js';
|
|
9
|
-
|
|
10
|
-
type EffectCleanup = () => void;
|
|
11
|
-
|
|
12
|
-
interface MutationInputs {
|
|
13
|
-
activity: ShellActivity;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
interface Props {
|
|
17
|
-
shell: ShellState;
|
|
18
|
-
run: (shell: ShellState, inputs: MutationInputs) => EffectCleanup | undefined;
|
|
19
|
-
onReady: (controls: {
|
|
20
|
-
getRuns: () => number;
|
|
21
|
-
setActivityProgress: (progress: number) => void;
|
|
22
|
-
}) => void;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const props: Props = $props();
|
|
26
|
-
const activity = $state<ShellActivity>({
|
|
27
|
-
id: 'reactive-sync',
|
|
28
|
-
label: 'Reactive sync',
|
|
29
|
-
kind: 'sync',
|
|
30
|
-
scope: 'system',
|
|
31
|
-
status: 'running',
|
|
32
|
-
progress: 0,
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
// Plain let on purpose: making this $state would add tracking noise to the
|
|
36
|
-
// effect-leak signal this harness exists to measure.
|
|
37
|
-
let runs = 0;
|
|
38
|
-
|
|
39
|
-
$effect(() => {
|
|
40
|
-
runs += 1;
|
|
41
|
-
return props.run(props.shell, { activity });
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
// This harness intentionally snapshots the callback during setup.
|
|
45
|
-
// svelte-ignore state_referenced_locally
|
|
46
|
-
props.onReady({
|
|
47
|
-
getRuns: () => runs,
|
|
48
|
-
setActivityProgress: (progress: number) => {
|
|
49
|
-
activity.progress = progress;
|
|
50
|
-
},
|
|
51
|
-
});
|
|
52
|
-
</script>
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Runs a caller-supplied ShellState mutation inside a consumer $effect. Tests
|
|
3
|
-
* use this to prove ShellState's internal reads do not become dependencies of
|
|
4
|
-
* the consumer effect.
|
|
5
|
-
*/
|
|
6
|
-
import type { ShellState } from '../admin-shell/state.svelte.js';
|
|
7
|
-
import type { ShellActivity } from '../admin-shell/types.js';
|
|
8
|
-
type EffectCleanup = () => void;
|
|
9
|
-
interface MutationInputs {
|
|
10
|
-
activity: ShellActivity;
|
|
11
|
-
}
|
|
12
|
-
interface Props {
|
|
13
|
-
shell: ShellState;
|
|
14
|
-
run: (shell: ShellState, inputs: MutationInputs) => EffectCleanup | undefined;
|
|
15
|
-
onReady: (controls: {
|
|
16
|
-
getRuns: () => number;
|
|
17
|
-
setActivityProgress: (progress: number) => void;
|
|
18
|
-
}) => void;
|
|
19
|
-
}
|
|
20
|
-
declare const AdminShellMutationEffectHarness: import("svelte").Component<Props, {}, "">;
|
|
21
|
-
type AdminShellMutationEffectHarness = ReturnType<typeof AdminShellMutationEffectHarness>;
|
|
22
|
-
export default AdminShellMutationEffectHarness;
|
|
23
|
-
//# sourceMappingURL=admin-shell-mutation-effect-harness.svelte.d.ts.map
|
package/dist/components/workspace/__tests__/admin-shell-mutation-effect-harness.svelte.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"admin-shell-mutation-effect-harness.svelte.d.ts","sourceRoot":"","sources":["../../../../src/components/workspace/__tests__/admin-shell-mutation-effect-harness.svelte.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAG7D,KAAK,aAAa,GAAG,MAAM,IAAI,CAAC;AAEhC,UAAU,cAAc;IACtB,QAAQ,EAAE,aAAa,CAAC;CACzB;AAED,UAAU,KAAK;IACb,KAAK,EAAE,UAAU,CAAC;IAClB,GAAG,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,cAAc,KAAK,aAAa,GAAG,SAAS,CAAC;IAC9E,OAAO,EAAE,CAAC,QAAQ,EAAE;QAClB,OAAO,EAAE,MAAM,MAAM,CAAC;QACtB,mBAAmB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;KACjD,KAAK,IAAI,CAAC;CACZ;AAwCD,QAAA,MAAM,+BAA+B,2CAAwC,CAAC;AAC9E,KAAK,+BAA+B,GAAG,UAAU,CAAC,OAAO,+BAA+B,CAAC,CAAC;AAC1F,eAAe,+BAA+B,CAAC"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AdminShell's page-header contracts on phones. jsdom doesn't apply the
|
|
3
|
-
* component's scoped styles, so these read the rules themselves: the phone
|
|
4
|
-
* top bar replaces the page's crumbs and title, and tabs inside a page header
|
|
5
|
-
* keep sticking under the bar.
|
|
6
|
-
*/
|
|
7
|
-
import { describe, expect, it } from 'vitest';
|
|
8
|
-
import source from '../admin-shell/AdminShell.svelte?raw';
|
|
9
|
-
const css = source.slice(source.indexOf('<style>'));
|
|
10
|
-
function rule(selector) {
|
|
11
|
-
const start = css.indexOf(selector);
|
|
12
|
-
expect(start, `missing rule for ${selector}`).toBeGreaterThan(-1);
|
|
13
|
-
return css.slice(start, css.indexOf('}', start));
|
|
14
|
-
}
|
|
15
|
-
describe('AdminShell page-header contracts', () => {
|
|
16
|
-
it('hides the breadcrumb row on phones', () => {
|
|
17
|
-
expect(rule(".smrt-admin-shell[data-viewport='phone'] :global([data-shell-breadcrumbs])")).toContain('display: none');
|
|
18
|
-
});
|
|
19
|
-
it('visually hides the page title while the phone top bar shows it', () => {
|
|
20
|
-
const titleRule = rule('.smrt-admin-shell[data-phone-top] :global([data-shell-page-title])');
|
|
21
|
-
// Visually hidden, not display:none: screen readers and the document
|
|
22
|
-
// outline keep the heading.
|
|
23
|
-
expect(titleRule).toContain('position: absolute');
|
|
24
|
-
expect(titleRule).toContain('clip-path: inset(50%)');
|
|
25
|
-
expect(titleRule).not.toContain('display: none');
|
|
26
|
-
});
|
|
27
|
-
it("lets a page header's tabs stick under the top bar", () => {
|
|
28
|
-
expect(rule('.smrt-admin-shell[data-phone-top]\n :global([data-page-header-extra]:has([data-shell-tabs]))')).toContain('display: contents');
|
|
29
|
-
});
|
|
30
|
-
});
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ShellState's viewport defaults, resizable-edge sizes, and per-edge
|
|
3
|
-
* persistence opt-outs.
|
|
4
|
-
*/
|
|
5
|
-
import { describe, expect, it, vi } from 'vitest';
|
|
6
|
-
import { panelPersists, pruneShellSettingsDelta, resolvePanelResize, resolveShellConfig, stripUnpersistedSettings, } from '../admin-shell/settings.js';
|
|
7
|
-
import { createShellState } from '../admin-shell/state.svelte.js';
|
|
8
|
-
function adapter(initial = null) {
|
|
9
|
-
const writes = [];
|
|
10
|
-
return {
|
|
11
|
-
writes,
|
|
12
|
-
read: vi.fn(() => initial),
|
|
13
|
-
write: vi.fn((delta) => {
|
|
14
|
-
writes.push(JSON.parse(JSON.stringify(delta)));
|
|
15
|
-
}),
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
const navDefaults = {
|
|
19
|
-
phone: 'collapsed',
|
|
20
|
-
tablet: 'collapsed',
|
|
21
|
-
desktop: 'expanded',
|
|
22
|
-
};
|
|
23
|
-
describe('viewport defaults', () => {
|
|
24
|
-
it('uses the default for the initial viewport', () => {
|
|
25
|
-
const phone = createShellState({
|
|
26
|
-
viewport: 'phone',
|
|
27
|
-
config: { left: { viewportDefaults: navDefaults } },
|
|
28
|
-
});
|
|
29
|
-
expect(phone.panels.left).toBe('collapsed');
|
|
30
|
-
const desktop = createShellState({
|
|
31
|
-
viewport: 'desktop',
|
|
32
|
-
config: { left: { viewportDefaults: navDefaults } },
|
|
33
|
-
});
|
|
34
|
-
expect(desktop.panels.left).toBe('expanded');
|
|
35
|
-
});
|
|
36
|
-
it('applies the new default only when the viewport class changes', () => {
|
|
37
|
-
const shell = createShellState({
|
|
38
|
-
viewport: 'desktop',
|
|
39
|
-
config: { left: { viewportDefaults: navDefaults } },
|
|
40
|
-
});
|
|
41
|
-
shell.collapsePanel('left');
|
|
42
|
-
shell.setViewport('desktop');
|
|
43
|
-
expect(shell.panels.left).toBe('collapsed');
|
|
44
|
-
shell.setViewport('tablet');
|
|
45
|
-
expect(shell.viewport).toBe('tablet');
|
|
46
|
-
expect(shell.panels.left).toBe('collapsed');
|
|
47
|
-
shell.expandPanel('left');
|
|
48
|
-
shell.setViewport('desktop');
|
|
49
|
-
expect(shell.panels.left).toBe('expanded');
|
|
50
|
-
// A later settings merge does not resurrect the old class's toggle.
|
|
51
|
-
shell.applySettings({ activeFocusToolId: 'x' });
|
|
52
|
-
expect(shell.panels.left).toBe('expanded');
|
|
53
|
-
});
|
|
54
|
-
it('never persists the state of an edge that follows the viewport', async () => {
|
|
55
|
-
const store = adapter({ panels: { left: 'expanded', right: 'expanded' } });
|
|
56
|
-
const shell = createShellState({
|
|
57
|
-
viewport: 'phone',
|
|
58
|
-
config: { left: { viewportDefaults: navDefaults } },
|
|
59
|
-
settingsAdapter: store,
|
|
60
|
-
});
|
|
61
|
-
await shell.hydrate();
|
|
62
|
-
expect(shell.panels.left).toBe('collapsed');
|
|
63
|
-
expect(shell.panels.right).toBe('expanded');
|
|
64
|
-
shell.expandPanel('left');
|
|
65
|
-
expect(store.writes.at(-1)?.panels).toEqual({ right: 'expanded' });
|
|
66
|
-
});
|
|
67
|
-
it('leaves edges without viewport defaults alone (backward compatible)', () => {
|
|
68
|
-
const shell = createShellState({ viewport: 'desktop' });
|
|
69
|
-
shell.expandPanel('left');
|
|
70
|
-
shell.setViewport('phone');
|
|
71
|
-
expect(shell.panels.left).toBe('expanded');
|
|
72
|
-
expect(shell.snapshot().viewport).toBe('phone');
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
describe('phone presentation', () => {
|
|
76
|
-
it('hides a phone-hidden edge only on phones, and Escape skips it there', () => {
|
|
77
|
-
const shell = createShellState({
|
|
78
|
-
viewport: 'phone',
|
|
79
|
-
config: { right: { phone: 'hidden', initial: 'expanded' } },
|
|
80
|
-
});
|
|
81
|
-
expect(shell.phonePresentation('right')).toBe('hidden');
|
|
82
|
-
expect(shell.phonePresentation('left')).toBe('drawer');
|
|
83
|
-
expect(shell.isEdgeShown('right')).toBe(false);
|
|
84
|
-
expect(shell.closeTopmostExpanded()).toBe(false);
|
|
85
|
-
expect(shell.panels.right).toBe('expanded');
|
|
86
|
-
shell.setViewport('desktop');
|
|
87
|
-
expect(shell.isEdgeShown('right')).toBe(true);
|
|
88
|
-
expect(shell.closeTopmostExpanded()).toBe(true);
|
|
89
|
-
expect(shell.panels.right).toBe('collapsed');
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
describe('resizable edges', () => {
|
|
93
|
-
it('resolves limits for side edges only', () => {
|
|
94
|
-
const config = resolveShellConfig({
|
|
95
|
-
right: { resizable: { min: 300, max: 600 } },
|
|
96
|
-
left: { resizable: true },
|
|
97
|
-
top: { resizable: true },
|
|
98
|
-
});
|
|
99
|
-
expect(resolvePanelResize('right', config.panels.right)).toEqual({
|
|
100
|
-
min: 300,
|
|
101
|
-
max: 600,
|
|
102
|
-
step: 16,
|
|
103
|
-
});
|
|
104
|
-
expect(resolvePanelResize('left', config.panels.left)).toEqual({
|
|
105
|
-
min: 240,
|
|
106
|
-
max: 720,
|
|
107
|
-
step: 16,
|
|
108
|
-
});
|
|
109
|
-
expect(resolvePanelResize('top', config.panels.top)).toBeNull();
|
|
110
|
-
expect(resolvePanelResize('bottom', config.panels.bottom)).toBeNull();
|
|
111
|
-
});
|
|
112
|
-
it('clamps, persists, and resets sizes', () => {
|
|
113
|
-
const store = adapter();
|
|
114
|
-
const shell = createShellState({
|
|
115
|
-
config: { right: { resizable: { min: 300, max: 600 } } },
|
|
116
|
-
settingsAdapter: store,
|
|
117
|
-
});
|
|
118
|
-
expect(shell.panelSize('right')).toBeNull();
|
|
119
|
-
shell.setPanelSize('right', 900);
|
|
120
|
-
expect(shell.panelSize('right')).toBe(600);
|
|
121
|
-
expect(store.writes.at(-1)?.sizes).toEqual({ right: 600 });
|
|
122
|
-
shell.setPanelSize('right', 120.4, { persist: false });
|
|
123
|
-
expect(shell.panelSize('right')).toBe(300);
|
|
124
|
-
expect(store.write).toHaveBeenCalledTimes(1);
|
|
125
|
-
shell.setPanelSize('right', null);
|
|
126
|
-
expect(shell.panelSize('right')).toBeNull();
|
|
127
|
-
expect(pruneShellSettingsDelta(shell.settings).sizes).toBeUndefined();
|
|
128
|
-
});
|
|
129
|
-
it('ignores sizes for edges that are not resizable', () => {
|
|
130
|
-
const shell = createShellState({ settings: { sizes: { left: 500 } } });
|
|
131
|
-
expect(shell.panelSize('left')).toBeNull();
|
|
132
|
-
shell.setPanelSize('left', 400);
|
|
133
|
-
expect(shell.settings.sizes).toEqual({ left: 500 });
|
|
134
|
-
expect(shell.panelSize('left')).toBeNull();
|
|
135
|
-
});
|
|
136
|
-
it('keeps a size in memory but not in storage when size persistence is off', () => {
|
|
137
|
-
const store = adapter({ sizes: { right: 480 } });
|
|
138
|
-
const shell = createShellState({
|
|
139
|
-
config: { right: { resizable: true, persist: { size: false } } },
|
|
140
|
-
settingsAdapter: store,
|
|
141
|
-
});
|
|
142
|
-
void shell.hydrate();
|
|
143
|
-
expect(shell.panelSize('right')).toBeNull();
|
|
144
|
-
shell.setPanelSize('right', 500);
|
|
145
|
-
expect(shell.panelSize('right')).toBe(500);
|
|
146
|
-
expect(store.writes.at(-1)?.sizes).toBeUndefined();
|
|
147
|
-
});
|
|
148
|
-
});
|
|
149
|
-
describe('persistence opt-out', () => {
|
|
150
|
-
it('reports what an edge persists', () => {
|
|
151
|
-
const config = resolveShellConfig({
|
|
152
|
-
left: { persist: false },
|
|
153
|
-
right: { persist: { state: false } },
|
|
154
|
-
bottom: { viewportDefaults: { phone: 'collapsed' } },
|
|
155
|
-
});
|
|
156
|
-
expect(panelPersists(config.panels.left, 'state')).toBe(false);
|
|
157
|
-
expect(panelPersists(config.panels.left, 'size')).toBe(false);
|
|
158
|
-
expect(panelPersists(config.panels.right, 'state')).toBe(false);
|
|
159
|
-
expect(panelPersists(config.panels.right, 'size')).toBe(true);
|
|
160
|
-
expect(panelPersists(config.panels.bottom, 'state')).toBe(false);
|
|
161
|
-
expect(panelPersists(config.panels.top, 'state')).toBe(true);
|
|
162
|
-
});
|
|
163
|
-
it('strips unpersisted panels and sizes on write and on read', async () => {
|
|
164
|
-
const config = resolveShellConfig({ left: { persist: false } });
|
|
165
|
-
expect(stripUnpersistedSettings({
|
|
166
|
-
panels: { left: 'expanded', right: 'collapsed' },
|
|
167
|
-
sizes: { left: 300 },
|
|
168
|
-
}, config)).toEqual({ panels: { right: 'collapsed' } });
|
|
169
|
-
const store = adapter({
|
|
170
|
-
panels: { left: 'expanded' },
|
|
171
|
-
hotkeysEnabled: false,
|
|
172
|
-
});
|
|
173
|
-
const shell = createShellState({
|
|
174
|
-
config: { left: { persist: false, initial: 'collapsed' } },
|
|
175
|
-
settingsAdapter: store,
|
|
176
|
-
});
|
|
177
|
-
await shell.hydrate();
|
|
178
|
-
expect(shell.panels.left).toBe('collapsed');
|
|
179
|
-
expect(shell.settings.hotkeysEnabled).toBe(false);
|
|
180
|
-
shell.expandPanel('left');
|
|
181
|
-
expect(shell.panels.left).toBe('expanded');
|
|
182
|
-
expect(store.writes.at(-1)?.panels).toBeUndefined();
|
|
183
|
-
});
|
|
184
|
-
});
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { mergeShellSettingsDelta, resolveHotkey, resolveInitialPanelState, resolveShellConfig, } from '../admin-shell/settings.js';
|
|
3
|
-
describe('AdminShell settings', () => {
|
|
4
|
-
it('treats false app config as a hidden edge', () => {
|
|
5
|
-
const config = resolveShellConfig({ right: false });
|
|
6
|
-
expect(config.panels.right.initial).toBe('hidden');
|
|
7
|
-
expect(resolveInitialPanelState('right', config.panels.right)).toBe('hidden');
|
|
8
|
-
expect(resolveHotkey('right', config.panels.right)).toBeNull();
|
|
9
|
-
});
|
|
10
|
-
it('resolves user panel deltas over app defaults', () => {
|
|
11
|
-
const config = resolveShellConfig({
|
|
12
|
-
left: { initial: 'collapsed' },
|
|
13
|
-
});
|
|
14
|
-
expect(resolveInitialPanelState('left', config.panels.left, {
|
|
15
|
-
panels: { left: 'expanded' },
|
|
16
|
-
})).toBe('expanded');
|
|
17
|
-
});
|
|
18
|
-
it('merges sparse deltas without replacing unrelated keys', () => {
|
|
19
|
-
expect(mergeShellSettingsDelta({ hotkeysEnabled: true, panels: { left: 'expanded' } }, { keymap: { top: { code: 'KeyQ' } } })).toEqual({
|
|
20
|
-
hotkeysEnabled: true,
|
|
21
|
-
panels: { left: 'expanded' },
|
|
22
|
-
keymap: { top: { code: 'KeyQ' } },
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
|
-
});
|