@prenta/admin 0.93.0 → 0.94.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/CHANGELOG.md +111 -0
- package/dist/__tests__/lib/version-diff.test.d.ts +2 -0
- package/dist/__tests__/lib/version-diff.test.d.ts.map +1 -0
- package/dist/__tests__/lib/version-diff.test.js +230 -0
- package/dist/__tests__/lib/version-diff.test.js.map +1 -0
- package/dist/__tests__/lib/version-history.test.d.ts +2 -0
- package/dist/__tests__/lib/version-history.test.d.ts.map +1 -0
- package/dist/__tests__/lib/version-history.test.js +125 -0
- package/dist/__tests__/lib/version-history.test.js.map +1 -0
- package/dist/__tests__/styles/responsive-layer.test.d.ts +2 -0
- package/dist/__tests__/styles/responsive-layer.test.d.ts.map +1 -0
- package/dist/__tests__/styles/responsive-layer.test.js +127 -0
- package/dist/__tests__/styles/responsive-layer.test.js.map +1 -0
- package/dist/__tests__/views/canvas-review-mode.render.test.d.ts +2 -0
- package/dist/__tests__/views/canvas-review-mode.render.test.d.ts.map +1 -0
- package/dist/__tests__/views/canvas-review-mode.render.test.js +70 -0
- package/dist/__tests__/views/canvas-review-mode.render.test.js.map +1 -0
- package/dist/__tests__/views/editor-top-bar.render.test.js +29 -0
- package/dist/__tests__/views/editor-top-bar.render.test.js.map +1 -1
- package/dist/__tests__/views/version-history-panel.render.test.d.ts +2 -0
- package/dist/__tests__/views/version-history-panel.render.test.d.ts.map +1 -0
- package/dist/__tests__/views/version-history-panel.render.test.js +153 -0
- package/dist/__tests__/views/version-history-panel.render.test.js.map +1 -0
- package/dist/components/EditorRail.js +3 -3
- package/dist/components/EditorRail.js.map +1 -1
- package/dist/components/page-tab/DirectiveSwitch.d.ts.map +1 -1
- package/dist/components/page-tab/DirectiveSwitch.js +5 -1
- package/dist/components/page-tab/DirectiveSwitch.js.map +1 -1
- package/dist/layout/primitives/AdminShell.d.ts.map +1 -1
- package/dist/layout/primitives/AdminShell.js +2 -2
- package/dist/layout/primitives/AdminShell.js.map +1 -1
- package/dist/lib/version-diff.d.ts +50 -0
- package/dist/lib/version-diff.d.ts.map +1 -0
- package/dist/lib/version-diff.js +294 -0
- package/dist/lib/version-diff.js.map +1 -0
- package/dist/lib/version-history.d.ts +73 -0
- package/dist/lib/version-history.d.ts.map +1 -0
- package/dist/lib/version-history.js +126 -0
- package/dist/lib/version-history.js.map +1 -0
- package/dist/prenta-admin.css +1 -1
- package/dist/views/page-editor/EditorCanvas.d.ts +14 -1
- package/dist/views/page-editor/EditorCanvas.d.ts.map +1 -1
- package/dist/views/page-editor/EditorCanvas.js +3 -3
- package/dist/views/page-editor/EditorCanvas.js.map +1 -1
- package/dist/views/page-editor/EditorTopBar.d.ts +8 -2
- package/dist/views/page-editor/EditorTopBar.d.ts.map +1 -1
- package/dist/views/page-editor/EditorTopBar.js +8 -6
- package/dist/views/page-editor/EditorTopBar.js.map +1 -1
- package/dist/views/page-editor/PageSectionEditor.d.ts.map +1 -1
- package/dist/views/page-editor/PageSectionEditor.js +115 -32
- package/dist/views/page-editor/PageSectionEditor.js.map +1 -1
- package/dist/views/page-editor/ReviewBar.d.ts +21 -0
- package/dist/views/page-editor/ReviewBar.d.ts.map +1 -0
- package/dist/views/page-editor/ReviewBar.js +22 -0
- package/dist/views/page-editor/ReviewBar.js.map +1 -0
- package/dist/views/page-editor/SectionInspector.d.ts.map +1 -1
- package/dist/views/page-editor/SectionInspector.js +1 -1
- package/dist/views/page-editor/SectionInspector.js.map +1 -1
- package/dist/views/page-editor/SectionsPanel.js +1 -1
- package/dist/views/page-editor/SectionsPanel.js.map +1 -1
- package/dist/views/page-editor/VersionHistoryPanel.d.ts +29 -0
- package/dist/views/page-editor/VersionHistoryPanel.d.ts.map +1 -0
- package/dist/views/page-editor/VersionHistoryPanel.js +81 -0
- package/dist/views/page-editor/VersionHistoryPanel.js.map +1 -0
- package/dist/views/page-editor/sections/SectionRenderer.d.ts +13 -1
- package/dist/views/page-editor/sections/SectionRenderer.d.ts.map +1 -1
- package/dist/views/page-editor/sections/SectionRenderer.js +23 -8
- package/dist/views/page-editor/sections/SectionRenderer.js.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/lib/version-diff.test.ts +278 -0
- package/src/__tests__/lib/version-history.test.ts +166 -0
- package/src/__tests__/styles/responsive-layer.test.ts +152 -0
- package/src/__tests__/views/canvas-review-mode.render.test.tsx +94 -0
- package/src/__tests__/views/editor-top-bar.render.test.tsx +42 -0
- package/src/__tests__/views/version-history-panel.render.test.tsx +195 -0
- package/src/components/EditorRail.tsx +5 -5
- package/src/components/page-tab/DirectiveSwitch.tsx +4 -1
- package/src/layout/primitives/AdminShell.tsx +13 -1
- package/src/lib/version-diff.ts +376 -0
- package/src/lib/version-history.ts +192 -0
- package/src/styles/responsive.css +281 -0
- package/src/styles/theme.css +8 -0
- package/src/views/page-editor/EditorCanvas.tsx +34 -7
- package/src/views/page-editor/EditorTopBar.tsx +20 -8
- package/src/views/page-editor/PageSectionEditor.tsx +162 -43
- package/src/views/page-editor/ReviewBar.tsx +76 -0
- package/src/views/page-editor/SectionInspector.tsx +2 -1
- package/src/views/page-editor/SectionsPanel.tsx +2 -2
- package/src/views/page-editor/VersionHistoryPanel.tsx +302 -0
- package/src/views/page-editor/sections/SectionRenderer.tsx +53 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,116 @@
|
|
|
1
1
|
# @actuate-media/cms-admin
|
|
2
2
|
|
|
3
|
+
## 0.94.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 385dd10: Responsive + accessibility layer
|
|
8
|
+
|
|
9
|
+
Ports `design-system/cms-responsive.css` from the page-builder design bundle,
|
|
10
|
+
which the prototype now links and which post-dates the handoff copy in
|
|
11
|
+
`design_handoff_page_builder/` (followup 7: the bundle in hand had one `:focus`
|
|
12
|
+
rule, no `:focus-visible`, no reduced-motion, no contrast preference). None of
|
|
13
|
+
it existed in the admin.
|
|
14
|
+
|
|
15
|
+
The prototype's selectors (`.ni`, `.sec-panel`, `.icbtn`) do not exist here —
|
|
16
|
+
this admin is Tailwind over the same tokens — so the **rules** are ported and
|
|
17
|
+
re-expressed against the real structure, in one stylesheet scoped throughout to
|
|
18
|
+
`.prenta-admin`. The admin renders inside consumer applications; an unscoped
|
|
19
|
+
`@media print` or `:focus-visible` rule would restyle the host's own pages, and
|
|
20
|
+
a test asserts every selector in the file carries the scope.
|
|
21
|
+
- **Visible focus everywhere**, as a floor. Base-layer, so any component with
|
|
22
|
+
its own `focus-visible:ring` still wins and this only fills the gaps.
|
|
23
|
+
- **A skip link** — the first focusable thing in the admin, so a keyboard user's
|
|
24
|
+
first Tab offers a jump past ~20 sidebar items.
|
|
25
|
+
- **`prefers-reduced-motion`** honoured as a media query, not only through the
|
|
26
|
+
Appearance setting and the `motion-safe:` utilities that were written with it.
|
|
27
|
+
- **`prefers-contrast: more`** raises the three tertiary tokens, in both themes,
|
|
28
|
+
and a test asserts it raises rather than lowers — the shipped `--muted` is
|
|
29
|
+
already an AA correction over the handoff's value, and a "more contrast"
|
|
30
|
+
preference that moved it the other way would be worse than ignoring it.
|
|
31
|
+
- **44px touch targets under a coarse pointer**, opt-in per control rather than
|
|
32
|
+
a blanket `button` rule. The admin is full of dense tables where growing every
|
|
33
|
+
button reflows the layout around it; the design bundle carries a curated list
|
|
34
|
+
for the same reason. The switch is the carve-out both hit: its thumb is
|
|
35
|
+
positioned against the track, so the **hit area** grows and the control paints
|
|
36
|
+
at its designed 34×19.
|
|
37
|
+
- **The editor stacks below 900px** — rail above canvas, both full width, drag
|
|
38
|
+
handle gone. The width override needs `!important`: the rail's width is an
|
|
39
|
+
inline style because it is drag-resizable and persisted.
|
|
40
|
+
- **Print** drops the chrome and lets the canvas print at natural size instead
|
|
41
|
+
of as a clipped, transformed thumbnail.
|
|
42
|
+
|
|
43
|
+
Two rules deliberately did not come across. The prototype turns the sidebar into
|
|
44
|
+
a fixed bottom bar under 768px, where `AdminShell` already has a working
|
|
45
|
+
slide-in overlay driven by `matchMedia` — replacing a working navigation pattern
|
|
46
|
+
was not part of finishing the page builder. And the blanket `min-height` list is
|
|
47
|
+
the per-control class described above.
|
|
48
|
+
|
|
49
|
+
Every way this breaks is invisible: a stylesheet that stops being imported, a
|
|
50
|
+
class hook renamed in a component, or a token override placed before the token
|
|
51
|
+
it overrides all render perfectly and simply lack the behaviour. Unit tests pin
|
|
52
|
+
the import order and assert every hook is applied by some component; e2e tests
|
|
53
|
+
measure the result in a browser, because "the CSS says 44px" and "the button is
|
|
54
|
+
44px" are different claims. The second caught a real gap — the history button's
|
|
55
|
+
conditional className had been missed by the edit that added the class to its
|
|
56
|
+
four neighbours.
|
|
57
|
+
|
|
58
|
+
- 385dd10: Version history: a mode, not a popup
|
|
59
|
+
|
|
60
|
+
The page editor's history was a right-hand dialog with a flat list and a
|
|
61
|
+
Restore button. The handoff's stage 6 asks for something different in kind:
|
|
62
|
+
history is about comparing **renders**, so selecting a version puts it on the
|
|
63
|
+
canvas and marks what changed. A modal covers the thing it exists to let you
|
|
64
|
+
look at; a drawer resizes it. This overlays the rail instead, so the canvas
|
|
65
|
+
does not move a pixel and the only thing that differs between two versions is
|
|
66
|
+
the page itself. An e2e test measures exactly that.
|
|
67
|
+
|
|
68
|
+
**The diff is computed, not stored.** Field-level, from the full snapshots the
|
|
69
|
+
versions API already returns, and the same result drives three surfaces: the
|
|
70
|
+
per-field list in the panel, the dashed outlines on the canvas, and the review
|
|
71
|
+
bar's count. One computation, so they cannot disagree. Field names come from
|
|
72
|
+
the section registry — the same definitions the inspector renders from — so a
|
|
73
|
+
diff reads in the words the editor typed under, and a custom section type
|
|
74
|
+
falls back to its raw key rather than dropping the row.
|
|
75
|
+
|
|
76
|
+
Whether a field changed is decided **structurally**, and the display summary is
|
|
77
|
+
used only to render it. Comparing the summaries is the obvious shortcut and it
|
|
78
|
+
loses real edits: the summary collapses an array to "N items", so retyping a
|
|
79
|
+
stats row while keeping the row count formats identically on both sides and the
|
|
80
|
+
field reports no change — no panel row and no canvas outline, on exactly the
|
|
81
|
+
edit a reviewer opened history to find. Repeaters are descended into row by
|
|
82
|
+
row, labelled through the registry's own nouns ("Stats · Stat 2 · Value"), so a
|
|
83
|
+
collapsed summary never has to stand in for a change it cannot express.
|
|
84
|
+
|
|
85
|
+
Visibility is diffed alongside content: hiding a section is the one structural
|
|
86
|
+
change a design-owned CMS gives an editor, and a history that omitted it would
|
|
87
|
+
be missing the only structural edit there is.
|
|
88
|
+
|
|
89
|
+
**Review mode is its own mode, deliberately.** It and site-preview mode both
|
|
90
|
+
drop the cursor, the hover outline and the section label, which makes one
|
|
91
|
+
shared suppression rule very tempting — and that rule hides the changed-section
|
|
92
|
+
label review mode exists to show. They are separate flags, with a test that
|
|
93
|
+
holds them apart. Editing is frozen throughout: every control that writes reads
|
|
94
|
+
one flag, so no surface can mutate the current page while the canvas shows a
|
|
95
|
+
different one.
|
|
96
|
+
|
|
97
|
+
**Two things found by testing this against a real browser rather than a mock:**
|
|
98
|
+
- Restore was nested inside the diff block, so a version with no computed
|
|
99
|
+
changes — the oldest snapshot held, or a metadata-only save — was reviewable
|
|
100
|
+
and not restorable. That is backwards: the oldest version is the one a
|
|
101
|
+
rollback most often wants. The prototype nests it the same way.
|
|
102
|
+
- Selection and disclosure were separate state, so the review bar's "Back to
|
|
103
|
+
current" could leave the panel describing one version while the canvas
|
|
104
|
+
rendered another, with Restore stranded on a row nobody could see. They are
|
|
105
|
+
the same act and are now one piece of state.
|
|
106
|
+
|
|
107
|
+
**And one the review bots found.** The inline site preview is a second editing
|
|
108
|
+
surface — an iframe of the real site with click-to-edit wired into the same
|
|
109
|
+
section state — and its handlers checked the user's role and nothing else. The
|
|
110
|
+
review lock, which every control in the rail honours, stopped at the iframe
|
|
111
|
+
boundary; so did the read-only lock on Page-Builder-owned pages. Both now read
|
|
112
|
+
the same single gate. A lock that covers only the rail is not a lock.
|
|
113
|
+
|
|
3
114
|
## 0.93.0
|
|
4
115
|
|
|
5
116
|
### Minor Changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-diff.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/lib/version-diff.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { changedSectionIds, diffVersions, formatValue, groupChangesBySection, } from '../../lib/version-diff.js';
|
|
3
|
+
function section(overrides) {
|
|
4
|
+
return {
|
|
5
|
+
sectionType: 'hero',
|
|
6
|
+
name: 'Hero Banner',
|
|
7
|
+
visible: true,
|
|
8
|
+
content: {},
|
|
9
|
+
settings: {},
|
|
10
|
+
...overrides,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
describe('formatValue', () => {
|
|
14
|
+
it('renders absent and blank values as an em dash so an empty diff cell is never blank', () => {
|
|
15
|
+
expect(formatValue(null)).toBe('—');
|
|
16
|
+
expect(formatValue(undefined)).toBe('—');
|
|
17
|
+
expect(formatValue('')).toBe('—');
|
|
18
|
+
expect(formatValue(' ')).toBe('—');
|
|
19
|
+
expect(formatValue([])).toBe('—');
|
|
20
|
+
expect(formatValue({})).toBe('—');
|
|
21
|
+
});
|
|
22
|
+
it('summarises structured values rather than dumping them', () => {
|
|
23
|
+
expect(formatValue([{ value: '1' }, { value: '2' }])).toBe('2 items');
|
|
24
|
+
expect(formatValue([{ value: '1' }])).toBe('1 item');
|
|
25
|
+
expect(formatValue({ name: 'hero.jpg', url: '/m/hero.jpg' })).toBe('hero.jpg');
|
|
26
|
+
// No name-ish key: fall back to a shape description, not "[object Object]".
|
|
27
|
+
expect(formatValue({ x: 1, y: 2 })).toBe('2 fields');
|
|
28
|
+
});
|
|
29
|
+
it('reads booleans and numbers as words the panel can show', () => {
|
|
30
|
+
expect(formatValue(true)).toBe('Yes');
|
|
31
|
+
expect(formatValue(false)).toBe('No');
|
|
32
|
+
expect(formatValue(0)).toBe('0');
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
describe('diffVersions', () => {
|
|
36
|
+
it('labels content fields through the section registry, not by raw key', () => {
|
|
37
|
+
const before = [section({ id: 's1', content: { heading: 'Old headline' } })];
|
|
38
|
+
const after = [section({ id: 's1', content: { heading: 'New headline' } })];
|
|
39
|
+
const changes = diffVersions(after, before);
|
|
40
|
+
expect(changes).toEqual([
|
|
41
|
+
{
|
|
42
|
+
sectionId: 's1',
|
|
43
|
+
sectionName: 'Hero Banner',
|
|
44
|
+
// 'heading' is `label: 'Heading'` on the hero type in the registry.
|
|
45
|
+
field: 'Heading',
|
|
46
|
+
from: 'Old headline',
|
|
47
|
+
to: 'New headline',
|
|
48
|
+
},
|
|
49
|
+
]);
|
|
50
|
+
});
|
|
51
|
+
it('falls back to the raw key for a type the registry does not describe', () => {
|
|
52
|
+
const before = [section({ id: 's1', sectionType: 'opal-pricing', content: { tiers: 'a' } })];
|
|
53
|
+
const after = [section({ id: 's1', sectionType: 'opal-pricing', content: { tiers: 'b' } })];
|
|
54
|
+
expect(diffVersions(after, before)[0]?.field).toBe('tiers');
|
|
55
|
+
});
|
|
56
|
+
it('reports a field cleared to nothing — the key exists only in the older snapshot', () => {
|
|
57
|
+
const before = [section({ id: 's1', content: { heading: 'Something' } })];
|
|
58
|
+
const after = [section({ id: 's1', content: {} })];
|
|
59
|
+
expect(diffVersions(after, before)).toEqual([
|
|
60
|
+
{ sectionId: 's1', sectionName: 'Hero Banner', field: 'Heading', from: 'Something', to: '—' },
|
|
61
|
+
]);
|
|
62
|
+
});
|
|
63
|
+
it('reports visibility as a state, because hiding a section is the one structural edit there is', () => {
|
|
64
|
+
const before = [section({ id: 's1', visible: true })];
|
|
65
|
+
const after = [section({ id: 's1', visible: false })];
|
|
66
|
+
expect(diffVersions(after, before)).toEqual([
|
|
67
|
+
{
|
|
68
|
+
sectionId: 's1',
|
|
69
|
+
sectionName: 'Hero Banner',
|
|
70
|
+
field: 'Visibility',
|
|
71
|
+
from: 'Shown',
|
|
72
|
+
to: 'Hidden',
|
|
73
|
+
},
|
|
74
|
+
]);
|
|
75
|
+
});
|
|
76
|
+
it('reports added and removed sections', () => {
|
|
77
|
+
const before = [section({ id: 's1' })];
|
|
78
|
+
const after = [section({ id: 's1' }), section({ id: 's2', name: 'CTA', sectionType: 'cta' })];
|
|
79
|
+
expect(diffVersions(after, before)).toEqual([
|
|
80
|
+
{ sectionId: 's2', sectionName: 'CTA', field: 'Section', from: '—', to: 'Added' },
|
|
81
|
+
]);
|
|
82
|
+
expect(diffVersions(before, after)).toEqual([
|
|
83
|
+
{ sectionId: 's2', sectionName: 'CTA', field: 'Section', from: 'Present', to: 'Removed' },
|
|
84
|
+
]);
|
|
85
|
+
});
|
|
86
|
+
it('reports nothing when the snapshots match', () => {
|
|
87
|
+
const same = [section({ id: 's1', content: { heading: 'Same' } })];
|
|
88
|
+
expect(diffVersions(same, [section({ id: 's1', content: { heading: 'Same' } })])).toEqual([]);
|
|
89
|
+
});
|
|
90
|
+
it('reports nothing against a missing predecessor', () => {
|
|
91
|
+
// The oldest version we hold is not the moment the page was created, so
|
|
92
|
+
// reporting every field as "added" would state something false.
|
|
93
|
+
expect(diffVersions([section({ id: 's1', content: { heading: 'x' } })], undefined)).toEqual([]);
|
|
94
|
+
expect(diffVersions([section({ id: 's1' })], null)).toEqual([]);
|
|
95
|
+
});
|
|
96
|
+
it('does not report a settings key that was merely absent versus explicitly default', () => {
|
|
97
|
+
// `{}` and `{ backgroundType: undefined }` format identically, so neither
|
|
98
|
+
// produces a row. Without this the first save after a schema addition
|
|
99
|
+
// would light up every section on the canvas.
|
|
100
|
+
const before = [section({ id: 's1', settings: {} })];
|
|
101
|
+
const after = [section({ id: 's1', settings: { backgroundType: undefined } })];
|
|
102
|
+
expect(diffVersions(after, before)).toEqual([]);
|
|
103
|
+
});
|
|
104
|
+
it('labels known settings and reports a real background change', () => {
|
|
105
|
+
const before = [section({ id: 's1', settings: { backgroundType: 'none' } })];
|
|
106
|
+
const after = [section({ id: 's1', settings: { backgroundType: 'solid' } })];
|
|
107
|
+
expect(diffVersions(after, before)).toEqual([
|
|
108
|
+
{
|
|
109
|
+
sectionId: 's1',
|
|
110
|
+
sectionName: 'Hero Banner',
|
|
111
|
+
field: 'Background type',
|
|
112
|
+
from: 'none',
|
|
113
|
+
to: 'solid',
|
|
114
|
+
},
|
|
115
|
+
]);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
describe('diffVersions — structured fields', () => {
|
|
119
|
+
const stats = (rows) => section({ id: 's1', sectionType: 'stats', name: 'By The Numbers', content: { stats: rows } });
|
|
120
|
+
it('catches an edit that keeps the row count', () => {
|
|
121
|
+
// The bug this exists for: deciding "did it change" from the DISPLAY
|
|
122
|
+
// summary collapses an array to "2 items", so retyping a row while keeping
|
|
123
|
+
// the count formats identically on both sides and the field reports no
|
|
124
|
+
// change — no panel row AND no outline on the canvas, which is exactly the
|
|
125
|
+
// edit a reviewer opened history to find.
|
|
126
|
+
const before = [
|
|
127
|
+
stats([
|
|
128
|
+
{ value: '10k', label: 'Users' },
|
|
129
|
+
{ value: '99%', label: 'Uptime' },
|
|
130
|
+
]),
|
|
131
|
+
];
|
|
132
|
+
const after = [
|
|
133
|
+
stats([
|
|
134
|
+
{ value: '20k', label: 'Users' },
|
|
135
|
+
{ value: '99%', label: 'Uptime' },
|
|
136
|
+
]),
|
|
137
|
+
];
|
|
138
|
+
const changes = diffVersions(after, before);
|
|
139
|
+
expect(changes).toHaveLength(1);
|
|
140
|
+
expect(changes[0]?.from).toBe('10k');
|
|
141
|
+
expect(changes[0]?.to).toBe('20k');
|
|
142
|
+
// Named down to the row and the sub-field, so "which one" has an answer.
|
|
143
|
+
expect(changes[0]?.field).toBe('Stats · Stat 1 · Value');
|
|
144
|
+
expect(changedSectionIds(changes).has('s1')).toBe(true);
|
|
145
|
+
});
|
|
146
|
+
it('never emits a row whose before and after both read as a bare count', () => {
|
|
147
|
+
const before = [
|
|
148
|
+
stats([
|
|
149
|
+
{ value: 'a', label: 'x' },
|
|
150
|
+
{ value: 'b', label: 'y' },
|
|
151
|
+
]),
|
|
152
|
+
];
|
|
153
|
+
const after = [
|
|
154
|
+
stats([
|
|
155
|
+
{ value: 'c', label: 'x' },
|
|
156
|
+
{ value: 'd', label: 'y' },
|
|
157
|
+
]),
|
|
158
|
+
];
|
|
159
|
+
for (const change of diffVersions(after, before)) {
|
|
160
|
+
expect(change.from).not.toBe(change.to);
|
|
161
|
+
expect(change.from).not.toMatch(/^\d+ items?$/);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
it('reports added and removed rows', () => {
|
|
165
|
+
const before = [stats([{ value: '10k', label: 'Users' }])];
|
|
166
|
+
const after = [
|
|
167
|
+
stats([
|
|
168
|
+
{ value: '10k', label: 'Users' },
|
|
169
|
+
{ value: '99%', label: 'Uptime' },
|
|
170
|
+
]),
|
|
171
|
+
];
|
|
172
|
+
expect(diffVersions(after, before)).toEqual([
|
|
173
|
+
expect.objectContaining({ field: 'Stats · Stat 2', from: '—', to: 'Added' }),
|
|
174
|
+
]);
|
|
175
|
+
expect(diffVersions(before, after)).toEqual([
|
|
176
|
+
expect.objectContaining({ field: 'Stats · Stat 2', from: 'Present', to: 'Removed' }),
|
|
177
|
+
]);
|
|
178
|
+
});
|
|
179
|
+
it('catches a nested change inside a media object', () => {
|
|
180
|
+
// Same failure one level down: two media objects with the same `name` used
|
|
181
|
+
// to format identically while pointing at different files.
|
|
182
|
+
const media = (url) => ({ name: 'hero.jpg', url });
|
|
183
|
+
const before = [section({ id: 's1', content: { imageUrl: media('/a.jpg') } })];
|
|
184
|
+
const after = [section({ id: 's1', content: { imageUrl: media('/b.jpg') } })];
|
|
185
|
+
expect(diffVersions(after, before)).toHaveLength(1);
|
|
186
|
+
});
|
|
187
|
+
it('treats every spelling of blank as unchanged', () => {
|
|
188
|
+
// Tightening the comparison must not start reporting "— → —".
|
|
189
|
+
for (const [before, after] of [
|
|
190
|
+
['', null],
|
|
191
|
+
[null, undefined],
|
|
192
|
+
[undefined, ' '],
|
|
193
|
+
[[], undefined],
|
|
194
|
+
[{}, null],
|
|
195
|
+
]) {
|
|
196
|
+
const changes = diffVersions([section({ id: 's1', content: { heading: after } })], [section({ id: 's1', content: { heading: before } })]);
|
|
197
|
+
expect(changes, `${JSON.stringify(before)} → ${JSON.stringify(after)}`).toEqual([]);
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
it('reports an unchanged repeater as no change at all', () => {
|
|
201
|
+
const rows = [{ value: '10k', label: 'Users' }];
|
|
202
|
+
expect(diffVersions([stats(rows)], [stats([...rows.map((r) => ({ ...r }))])])).toEqual([]);
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
describe('groupChangesBySection', () => {
|
|
206
|
+
it('groups by section in first-seen order', () => {
|
|
207
|
+
const before = [
|
|
208
|
+
section({ id: 's1', content: { heading: 'a', body: 'a' } }),
|
|
209
|
+
section({ id: 's2', name: 'CTA', sectionType: 'cta', content: { heading: 'a' } }),
|
|
210
|
+
];
|
|
211
|
+
const after = [
|
|
212
|
+
section({ id: 's1', content: { heading: 'b', body: 'b' } }),
|
|
213
|
+
section({ id: 's2', name: 'CTA', sectionType: 'cta', content: { heading: 'b' } }),
|
|
214
|
+
];
|
|
215
|
+
const groups = groupChangesBySection(diffVersions(after, before));
|
|
216
|
+
expect(groups.map((g) => g.sectionId)).toEqual(['s1', 's2']);
|
|
217
|
+
expect(groups[0]?.changes).toHaveLength(2);
|
|
218
|
+
expect(groups[1]?.changes).toHaveLength(1);
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
describe('changedSectionIds', () => {
|
|
222
|
+
it('collapses several changes on one section to a single outline', () => {
|
|
223
|
+
const before = [section({ id: 's1', content: { heading: 'a', body: 'a' } })];
|
|
224
|
+
const after = [section({ id: 's1', content: { heading: 'b', body: 'b' } })];
|
|
225
|
+
const ids = changedSectionIds(diffVersions(after, before));
|
|
226
|
+
expect(ids.size).toBe(1);
|
|
227
|
+
expect(ids.has('s1')).toBe(true);
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
//# sourceMappingURL=version-diff.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-diff.test.js","sourceRoot":"","sources":["../../../src/__tests__/lib/version-diff.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-history.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/lib/version-history.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { dayLabel, groupVersionsByDay, initials, toPageVersion, versionKind, } from '../../lib/version-history.js';
|
|
3
|
+
const NOW = new Date('2026-08-02T17:00:00Z');
|
|
4
|
+
function version(id, createdAt) {
|
|
5
|
+
return {
|
|
6
|
+
id,
|
|
7
|
+
changeType: 'UPDATE',
|
|
8
|
+
createdAt,
|
|
9
|
+
author: { id: 'u1', name: 'Sarah Mills' },
|
|
10
|
+
sections: [],
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
describe('toPageVersion', () => {
|
|
14
|
+
it('lifts the section snapshot out of the version payload', () => {
|
|
15
|
+
const mapped = toPageVersion({
|
|
16
|
+
id: 'v1',
|
|
17
|
+
changeType: 'PUBLISH',
|
|
18
|
+
createdAt: '2026-08-02T12:00:00Z',
|
|
19
|
+
data: {
|
|
20
|
+
sections: [
|
|
21
|
+
{ id: 's1', sectionType: 'hero', name: 'Hero', visible: true, content: {}, settings: {} },
|
|
22
|
+
],
|
|
23
|
+
},
|
|
24
|
+
changedBy: { id: 'u1', name: 'Sarah Mills', email: 's@example.com' },
|
|
25
|
+
});
|
|
26
|
+
expect(mapped.sections).toHaveLength(1);
|
|
27
|
+
expect(mapped.sections[0]?.id).toBe('s1');
|
|
28
|
+
expect(mapped.changeType).toBe('PUBLISH');
|
|
29
|
+
expect(mapped.author.name).toBe('Sarah Mills');
|
|
30
|
+
});
|
|
31
|
+
it('preserves an unmanaged section rather than dropping it from the snapshot', () => {
|
|
32
|
+
// Coercing a snapshot more strictly than the live document reads would
|
|
33
|
+
// make an externally-managed section look deleted in every version.
|
|
34
|
+
const mapped = toPageVersion({
|
|
35
|
+
id: 'v1',
|
|
36
|
+
changeType: 'UPDATE',
|
|
37
|
+
createdAt: '2026-08-02T12:00:00Z',
|
|
38
|
+
data: {
|
|
39
|
+
sections: [
|
|
40
|
+
{ id: 's1', sectionType: 'opal-pricing', name: 'Pricing', visible: true, content: {} },
|
|
41
|
+
],
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
expect(mapped.sections).toHaveLength(1);
|
|
45
|
+
expect(mapped.sections[0]?.sectionType).toBe('opal-pricing');
|
|
46
|
+
});
|
|
47
|
+
it('falls back through name → email → a real word for the avatar', () => {
|
|
48
|
+
expect(toPageVersion({ id: 'v', changeType: 'UPDATE', createdAt: '', data: null }).author.name).toBe('Unknown');
|
|
49
|
+
expect(toPageVersion({
|
|
50
|
+
id: 'v',
|
|
51
|
+
changeType: 'UPDATE',
|
|
52
|
+
createdAt: '',
|
|
53
|
+
data: null,
|
|
54
|
+
changedBy: { id: 'u', name: ' ', email: 'a@b.com' },
|
|
55
|
+
}).author.name).toBe('a@b.com');
|
|
56
|
+
});
|
|
57
|
+
it('yields no sections for a version whose payload has none', () => {
|
|
58
|
+
expect(toPageVersion({ id: 'v', changeType: 'DELETE', createdAt: '', data: {} }).sections).toEqual([]);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
describe('versionKind', () => {
|
|
62
|
+
it('marks a published snapshot as the one a visitor could have seen', () => {
|
|
63
|
+
expect(versionKind('PUBLISH')).toEqual({ label: 'Published', tone: 'live' });
|
|
64
|
+
});
|
|
65
|
+
it('calls UPDATE "Saved", never "Draft"', () => {
|
|
66
|
+
// Every row written before cms-core started recording PUBLISH is an UPDATE
|
|
67
|
+
// whether or not it went live, so "Draft" would be false for those.
|
|
68
|
+
expect(versionKind('UPDATE').label).toBe('Saved');
|
|
69
|
+
});
|
|
70
|
+
it('distinguishes a rollback from authored content', () => {
|
|
71
|
+
expect(versionKind('RESTORE').label).toBe('Restored');
|
|
72
|
+
});
|
|
73
|
+
it('degrades to a neutral label for an unrecognised type', () => {
|
|
74
|
+
expect(versionKind('SOMETHING_NEW').label).toBe('Saved');
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
describe('dayLabel', () => {
|
|
78
|
+
it('names today and yesterday', () => {
|
|
79
|
+
expect(dayLabel('2026-08-02T09:00:00', NOW)).toBe('Today');
|
|
80
|
+
expect(dayLabel('2026-08-01T23:59:00', NOW)).toBe('Yesterday');
|
|
81
|
+
});
|
|
82
|
+
it('drops the year within the current one and keeps it outside', () => {
|
|
83
|
+
expect(dayLabel('2026-07-27T09:00:00', NOW)).not.toMatch(/2026/);
|
|
84
|
+
expect(dayLabel('2025-07-27T09:00:00', NOW)).toMatch(/2025/);
|
|
85
|
+
});
|
|
86
|
+
it('does not throw on an unparseable timestamp', () => {
|
|
87
|
+
expect(dayLabel('not-a-date', NOW)).toBe('Unknown date');
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
describe('groupVersionsByDay', () => {
|
|
91
|
+
it('groups consecutive runs and keeps newest-first order', () => {
|
|
92
|
+
const groups = groupVersionsByDay([
|
|
93
|
+
version('v5', '2026-08-02T16:12:00'),
|
|
94
|
+
version('v4', '2026-08-02T11:03:00'),
|
|
95
|
+
version('v3', '2026-08-01T17:47:00'),
|
|
96
|
+
version('v1', '2026-07-27T09:30:00'),
|
|
97
|
+
], NOW);
|
|
98
|
+
expect(groups.map((g) => g.label)).toEqual(['Today', 'Yesterday', expect.stringMatching(/Jul/)]);
|
|
99
|
+
expect(groups[0]?.versions.map((v) => v.id)).toEqual(['v5', 'v4']);
|
|
100
|
+
});
|
|
101
|
+
it('does not merge two non-adjacent runs that share a label', () => {
|
|
102
|
+
// A Map keyed on the label would silently reorder an unsorted page into
|
|
103
|
+
// something that reads as chronological but is not.
|
|
104
|
+
const groups = groupVersionsByDay([
|
|
105
|
+
version('a', '2026-08-02T16:00:00'),
|
|
106
|
+
version('b', '2026-08-01T16:00:00'),
|
|
107
|
+
version('c', '2026-08-02T09:00:00'),
|
|
108
|
+
], NOW);
|
|
109
|
+
expect(groups.map((g) => g.label)).toEqual(['Today', 'Yesterday', 'Today']);
|
|
110
|
+
});
|
|
111
|
+
it('returns nothing for an empty list', () => {
|
|
112
|
+
expect(groupVersionsByDay([], NOW)).toEqual([]);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
describe('initials', () => {
|
|
116
|
+
it('takes first and last for a full name, two letters for one word', () => {
|
|
117
|
+
expect(initials('Sarah Mills')).toBe('SM');
|
|
118
|
+
expect(initials('Sarah Jane Mills')).toBe('SM');
|
|
119
|
+
expect(initials('sarah')).toBe('SA');
|
|
120
|
+
});
|
|
121
|
+
it('never renders an empty monogram', () => {
|
|
122
|
+
expect(initials(' ')).toBe('?');
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
//# sourceMappingURL=version-history.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-history.test.js","sourceRoot":"","sources":["../../../src/__tests__/lib/version-history.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EACL,QAAQ,EACR,kBAAkB,EAClB,QAAQ,EACR,aAAa,EACb,WAAW,GAEZ,MAAM,8BAA8B,CAAA;AAErC,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,sBAAsB,CAAC,CAAA;AAE5C,SAAS,OAAO,CAAC,EAAU,EAAE,SAAiB;IAC5C,OAAO;QACL,EAAE;QACF,UAAU,EAAE,QAAQ;QACpB,SAAS;QACT,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE;QACzC,QAAQ,EAAE,EAAE;KACb,CAAA;AACH,CAAC;AAED,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,MAAM,GAAG,aAAa,CAAC;YAC3B,EAAE,EAAE,IAAI;YACR,UAAU,EAAE,SAAS;YACrB,SAAS,EAAE,sBAAsB;YACjC,IAAI,EAAE;gBACJ,QAAQ,EAAE;oBACR,EAAE,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;iBAC1F;aACF;YACD,SAAS,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,eAAe,EAAE;SACrE,CAAC,CAAA;QAEF,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;QACvC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACzC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACzC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;IAChD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,0EAA0E,EAAE,GAAG,EAAE;QAClF,uEAAuE;QACvE,oEAAoE;QACpE,MAAM,MAAM,GAAG,aAAa,CAAC;YAC3B,EAAE,EAAE,IAAI;YACR,UAAU,EAAE,QAAQ;YACpB,SAAS,EAAE,sBAAsB;YACjC,IAAI,EAAE;gBACJ,QAAQ,EAAE;oBACR,EAAE,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,cAAc,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE;iBACvF;aACF;SACF,CAAC,CAAA;QAEF,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;QACvC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;IAC9D,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACtE,MAAM,CACJ,aAAa,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CACxF,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QAEjB,MAAM,CACJ,aAAa,CAAC;YACZ,EAAE,EAAE,GAAG;YACP,UAAU,EAAE,QAAQ;YACpB,SAAS,EAAE,EAAE;YACb,IAAI,EAAE,IAAI;YACV,SAAS,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE;SACrD,CAAC,CAAC,MAAM,CAAC,IAAI,CACf,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IACnB,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,CACJ,aAAa,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,CACnF,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IACf,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,iEAAiE,EAAE,GAAG,EAAE;QACzE,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;IAC9E,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,2EAA2E;QAC3E,oEAAoE;QACpE,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACnD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IACvD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAC1D,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;IACxB,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAC1D,MAAM,CAAC,QAAQ,CAAC,qBAAqB,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IAChE,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,MAAM,CAAC,QAAQ,CAAC,qBAAqB,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;QAChE,MAAM,CAAC,QAAQ,CAAC,qBAAqB,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IAC9D,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,CAAC,QAAQ,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;IAC1D,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,MAAM,MAAM,GAAG,kBAAkB,CAC/B;YACE,OAAO,CAAC,IAAI,EAAE,qBAAqB,CAAC;YACpC,OAAO,CAAC,IAAI,EAAE,qBAAqB,CAAC;YACpC,OAAO,CAAC,IAAI,EAAE,qBAAqB,CAAC;YACpC,OAAO,CAAC,IAAI,EAAE,qBAAqB,CAAC;SACrC,EACD,GAAG,CACJ,CAAA;QAED,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAChG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAA;IACpE,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,wEAAwE;QACxE,oDAAoD;QACpD,MAAM,MAAM,GAAG,kBAAkB,CAC/B;YACE,OAAO,CAAC,GAAG,EAAE,qBAAqB,CAAC;YACnC,OAAO,CAAC,GAAG,EAAE,qBAAqB,CAAC;YACnC,OAAO,CAAC,GAAG,EAAE,qBAAqB,CAAC;SACpC,EACD,GAAG,CACJ,CAAA;QAED,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAAA;IAC7E,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,CAAC,kBAAkB,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IACjD,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;IACxB,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACxE,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC1C,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC/C,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACtC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACnC,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"responsive-layer.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/styles/responsive-layer.test.ts"],"names":[],"mappings":""}
|