@morscherlab/mint-sdk 1.4.0-beta.10 → 1.4.0-beta.11
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/dist/__tests__/styles/v2AuditRules.test.d.ts +1 -0
- package/dist/index.js +4 -4
- package/dist/{install-CsPFJSx3.js → install-mB8-IyvO.js} +4 -4
- package/dist/{install-CsPFJSx3.js.map → install-mB8-IyvO.js.map} +1 -1
- package/dist/install.js +1 -1
- package/dist/{lab-MHzp-_J8.js → lab-D5bIX426.js} +2 -2
- package/dist/{lab-MHzp-_J8.js.map → lab-D5bIX426.js.map} +1 -1
- package/dist/lab.js +2 -2
- package/dist/{runtime-8bs8EogX.js → runtime-D7vKpfbF.js} +2 -2
- package/dist/{runtime-8bs8EogX.js.map → runtime-D7vKpfbF.js.map} +1 -1
- package/dist/runtime.js +2 -2
- package/dist/styles.css +44 -28
- package/dist/{useRackEditor-DiwCt77M.js → useRackEditor-Q8xO-cCy.js} +2 -2
- package/dist/{useRackEditor-DiwCt77M.js.map → useRackEditor-Q8xO-cCy.js.map} +1 -1
- package/package.json +1 -1
- package/src/__tests__/styles/v2AuditRules.test.ts +96 -0
- package/src/components/GeneratedResultRenderer.vue +3 -4
- package/src/styles/components/app-layout.css +3 -2
- package/src/styles/components/app-top-bar.css +3 -3
- package/src/styles/components/dataframe.css +1 -1
- package/src/styles/components/modal.css +2 -2
- package/src/styles/components/number-input.css +1 -1
- package/src/styles/components/progress-bar.css +3 -3
- package/src/styles/components/section-card.css +4 -2
- package/src/styles/components/settings-modal.css +7 -2
- package/src/styles/variables.css +10 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@morscherlab/mint-sdk",
|
|
3
|
-
"version": "1.4.0-beta.
|
|
3
|
+
"version": "1.4.0-beta.11",
|
|
4
4
|
"description": "MINT Platform SDK — Vue 3 components, composables, and types for plugin development. MINT = Mass-spec INtegrated Toolkit.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs'
|
|
2
|
+
import { dirname, join, resolve } from 'node:path'
|
|
3
|
+
import { fileURLToPath } from 'node:url'
|
|
4
|
+
import { describe, expect, it } from 'vitest'
|
|
5
|
+
|
|
6
|
+
// v2 design audit (2026-10-28) fixes in the SDK stylesheets.
|
|
7
|
+
|
|
8
|
+
const srcRoot = resolve(dirname(fileURLToPath(import.meta.url)), '../..')
|
|
9
|
+
const stylesDir = join(srcRoot, 'styles')
|
|
10
|
+
|
|
11
|
+
function css(path: string): string {
|
|
12
|
+
return readFileSync(join(stylesDir, path), 'utf-8').replace(/\/\*[\s\S]*?\*\//g, '')
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function rule(text: string, selector: string): string {
|
|
16
|
+
const escaped = selector.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
17
|
+
return new RegExp(`(?:^|\\})\\s*${escaped}\\s*\\{([^}]*)\\}`).exec(text)?.[1] ?? ''
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const rem = (value: string): number => Number(value.replace('rem', '')) * 16
|
|
21
|
+
|
|
22
|
+
describe('v2 audit style rules', () => {
|
|
23
|
+
it('should keep the outermost cards at least 16px from the window edge', () => {
|
|
24
|
+
const inset = /--mint-page-inset:\s*([\d.]+rem)/.exec(css('variables.css'))?.[1] ?? '0rem'
|
|
25
|
+
expect(rem(inset)).toBeGreaterThanOrEqual(16)
|
|
26
|
+
expect(rule(css('components/app-layout.css'), '.mint-layout--floating')).toMatch(/padding:\s*var\(--mint-page-inset\)/)
|
|
27
|
+
const topBarCard = rule(css('components/app-top-bar.css'), '.mint-topbar--card')
|
|
28
|
+
expect(topBarCard).toMatch(/width:\s*calc\(100% - 2 \* var\(--mint-page-inset\)\)/)
|
|
29
|
+
expect(topBarCard).toMatch(/margin:\s*var\(--mint-page-inset\) var\(--mint-page-inset\) 0/)
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it('should put the SDK utility classes in the utilities layer so host variants beat them', () => {
|
|
33
|
+
const vars = css('variables.css')
|
|
34
|
+
const order = vars.indexOf('@layer theme, base, components, utilities;')
|
|
35
|
+
const layer = vars.indexOf('@layer utilities {')
|
|
36
|
+
expect(order).toBeGreaterThan(-1)
|
|
37
|
+
expect(order).toBeLessThan(vars.indexOf('@layer base {'))
|
|
38
|
+
const utilities = vars.slice(layer, vars.indexOf('@media (prefers-reduced-motion'))
|
|
39
|
+
expect(layer).toBeGreaterThan(-1)
|
|
40
|
+
for (const selector of ['.flex-col {', '.text-text-muted {', '.truncate {', '.max-w-sm {']) {
|
|
41
|
+
expect(utilities).toContain(selector)
|
|
42
|
+
}
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it('should drop the last DataFrame row rule over the !important cell border', () => {
|
|
46
|
+
const body = rule(css('components/dataframe.css'), '.mint-dataframe__row:last-child .mint-dataframe__td')
|
|
47
|
+
expect(body).toMatch(/border-bottom:\s*none\s*!important/)
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
it('should round the modal close button with --radius-md', () => {
|
|
51
|
+
expect(rule(css('components/modal.css'), '.mint-modal__close')).toMatch(/border-radius:\s*var\(--radius-md\)/)
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('should draw no capsule on the progress rail or the sheet grab hint', () => {
|
|
55
|
+
expect(css('components/progress-bar.css')).not.toMatch(/9999px/)
|
|
56
|
+
expect(rule(css('components/modal.css'), '.mint-modal__grab-hint')).not.toMatch(/9999px/)
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it('should keep a 28px header control inside the section card header strip', () => {
|
|
60
|
+
const text = css('components/section-card.css')
|
|
61
|
+
const cases: Array<[string, number]> = [
|
|
62
|
+
['.mint-section-card__header', 28],
|
|
63
|
+
['[data-density="comfortable"] .mint-section-card__header', 32],
|
|
64
|
+
]
|
|
65
|
+
for (const [selector, control] of cases) {
|
|
66
|
+
const body = rule(text, selector)
|
|
67
|
+
const minHeight = rem(/min-height:\s*([\d.]+rem)/.exec(body)?.[1] ?? '0rem')
|
|
68
|
+
const padTop = rem(/padding:\s*([\d.]+rem)/.exec(body)?.[1] ?? '0rem')
|
|
69
|
+
expect(control + 2 * padTop + 1, selector).toBeLessThanOrEqual(minHeight)
|
|
70
|
+
}
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
it('should end the settings pane without a closing row hairline and draw no box around the density preview', () => {
|
|
74
|
+
const text = css('components/settings-modal.css')
|
|
75
|
+
const last = rule(
|
|
76
|
+
text,
|
|
77
|
+
'.mint-settings-modal__group:last-of-type > .mint-settings-modal__group-grid > .mint-settings-modal__row:last-child',
|
|
78
|
+
)
|
|
79
|
+
expect(last).toMatch(/border-bottom:\s*none/)
|
|
80
|
+
expect(rule(text, '.mint-settings-modal__density-preview')).not.toMatch(/(^|;)\s*border(-radius)?:/)
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
it('should set the md number input text no smaller than the sm one', () => {
|
|
84
|
+
const text = css('components/number-input.css')
|
|
85
|
+
const size = (variant: string) =>
|
|
86
|
+
rem(/font-size:\s*([\d.]+rem)/.exec(rule(text, `.mint-number-input__input--${variant}`))?.[1] ?? '0rem')
|
|
87
|
+
expect(size('md')).toBeGreaterThan(size('sm'))
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
it('should give the generated JSON block a token radius and no frame', () => {
|
|
91
|
+
const sfc = readFileSync(join(srcRoot, 'components/GeneratedResultRenderer.vue'), 'utf-8')
|
|
92
|
+
const body = /\.mint-generated-result__json\s*\{([^}]*overflow:[^}]*)\}/.exec(sfc)?.[1] ?? ''
|
|
93
|
+
expect(body).toMatch(/border-radius:\s*var\(--radius-md\)/)
|
|
94
|
+
expect(body).not.toMatch(/(^|;)\s*border:/)
|
|
95
|
+
})
|
|
96
|
+
})
|
|
@@ -130,10 +130,9 @@ function humanize(value: string): string {
|
|
|
130
130
|
|
|
131
131
|
.mint-generated-result__json {
|
|
132
132
|
overflow: auto;
|
|
133
|
-
padding: 1rem;
|
|
134
|
-
border:
|
|
135
|
-
|
|
136
|
-
background: var(--bg-secondary);
|
|
133
|
+
padding: 0.75rem 1rem;
|
|
134
|
+
border-radius: var(--radius-md);
|
|
135
|
+
background: var(--bg-tertiary);
|
|
137
136
|
font-size: 0.8125rem;
|
|
138
137
|
line-height: 1.55;
|
|
139
138
|
white-space: pre-wrap;
|
|
@@ -60,10 +60,11 @@
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
/* Floating variant: all sections appear as separate cards on a background,
|
|
63
|
-
spaced by the density gutter (8px, 12px
|
|
63
|
+
16px from the window edge and spaced by the density gutter (8px, 12px
|
|
64
|
+
comfortable). */
|
|
64
65
|
.mint-layout--floating {
|
|
65
66
|
background-color: var(--bg-primary);
|
|
66
|
-
padding: var(--mint-
|
|
67
|
+
padding: var(--mint-page-inset);
|
|
67
68
|
gap: var(--mint-gutter);
|
|
68
69
|
}
|
|
69
70
|
|
|
@@ -110,10 +110,10 @@
|
|
|
110
110
|
padding: 0 0.375rem 0 0;
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
/* Variant: card - flat floating card, inset
|
|
113
|
+
/* Variant: card - flat floating card, inset 16px from the window edge */
|
|
114
114
|
.mint-topbar--card {
|
|
115
|
-
width: calc(100% - 2 * var(--mint-
|
|
116
|
-
margin: var(--mint-
|
|
115
|
+
width: calc(100% - 2 * var(--mint-page-inset));
|
|
116
|
+
margin: var(--mint-page-inset) var(--mint-page-inset) 0;
|
|
117
117
|
padding: 0.375rem 0.5rem 0.375rem 0.625rem;
|
|
118
118
|
border-radius: var(--radius-lg);
|
|
119
119
|
border: 1px solid var(--border-color);
|
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
width: 2.5rem;
|
|
116
116
|
height: 3px;
|
|
117
117
|
background-color: var(--border-color);
|
|
118
|
-
border-radius:
|
|
118
|
+
border-radius: var(--radius-sm);
|
|
119
119
|
margin: 0.5rem auto 0;
|
|
120
120
|
flex-shrink: 0;
|
|
121
121
|
}
|
|
@@ -163,7 +163,7 @@
|
|
|
163
163
|
width: 1.75rem;
|
|
164
164
|
height: 1.75rem;
|
|
165
165
|
padding: 0;
|
|
166
|
-
border-radius:
|
|
166
|
+
border-radius: var(--radius-md);
|
|
167
167
|
color: var(--text-secondary);
|
|
168
168
|
background: none;
|
|
169
169
|
border: none;
|
|
@@ -121,7 +121,7 @@
|
|
|
121
121
|
/* Horizontal padding matches BaseInput canonical scale (10/12/16) so FormField's
|
|
122
122
|
12px label indent aligns with the numeric text across all input types. */
|
|
123
123
|
.mint-number-input__input--sm { padding: 0.25rem 0.625rem; font-size: 0.8125rem; }
|
|
124
|
-
.mint-number-input__input--md { padding: 0.375rem 0.75rem; font-size: 0.
|
|
124
|
+
.mint-number-input__input--md { padding: 0.375rem 0.75rem; font-size: 0.875rem; }
|
|
125
125
|
.mint-number-input__input--lg { padding: 0.5rem 1rem; font-size: 1rem; }
|
|
126
126
|
|
|
127
127
|
/* ---------- Unit suffix ---------- */
|
|
@@ -22,13 +22,13 @@
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
/* ========================================================================
|
|
25
|
-
Rail variant (default) — single filled track,
|
|
25
|
+
Rail variant (default) — single filled track, square-ish ends (v2: no capsules)
|
|
26
26
|
======================================================================== */
|
|
27
27
|
|
|
28
28
|
.mint-progress__track {
|
|
29
29
|
width: 100%;
|
|
30
30
|
background-color: var(--bg-tertiary);
|
|
31
|
-
border-radius:
|
|
31
|
+
border-radius: var(--radius-sm);
|
|
32
32
|
overflow: hidden;
|
|
33
33
|
}
|
|
34
34
|
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
|
|
39
39
|
.mint-progress__bar {
|
|
40
40
|
height: 100%;
|
|
41
|
-
border-radius:
|
|
41
|
+
border-radius: var(--radius-sm);
|
|
42
42
|
transition: width 0.3s ease;
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -34,7 +34,9 @@
|
|
|
34
34
|
gap: 0.625rem;
|
|
35
35
|
box-sizing: border-box;
|
|
36
36
|
min-height: 2.5rem;
|
|
37
|
-
padding:
|
|
37
|
+
/* 4px block padding: a 28px header control plus padding plus the 1px rule
|
|
38
|
+
stays inside the 40px strip (6px made it 41px). */
|
|
39
|
+
padding: 0.25rem 0.625rem 0.25rem 0.75rem;
|
|
38
40
|
border-bottom: 1px solid var(--border-color);
|
|
39
41
|
flex-shrink: 0;
|
|
40
42
|
}
|
|
@@ -131,7 +133,7 @@ button.mint-section-card__row:hover {
|
|
|
131
133
|
/* Comfortable density gives the header and rows back their height. */
|
|
132
134
|
[data-density="comfortable"] .mint-section-card__header {
|
|
133
135
|
min-height: 2.75rem;
|
|
134
|
-
padding: 0.
|
|
136
|
+
padding: 0.25rem 0.75rem 0.25rem 0.875rem;
|
|
135
137
|
}
|
|
136
138
|
|
|
137
139
|
[data-density="comfortable"] .mint-section-card__row {
|
|
@@ -37,6 +37,12 @@
|
|
|
37
37
|
border-bottom-color: var(--border-color);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
/* The pane ends after the last group's last row: no closing hairline there,
|
|
41
|
+
it would sit on the footer rule with nothing between them. */
|
|
42
|
+
.mint-settings-modal__group:last-of-type > .mint-settings-modal__group-grid > .mint-settings-modal__row:last-child {
|
|
43
|
+
border-bottom: none;
|
|
44
|
+
}
|
|
45
|
+
|
|
40
46
|
/* The field cell anchors the ↺ reset, which sits just left of the control (5d).
|
|
41
47
|
--_settings-control-w is the control's width; stacked fields (text, custom slots)
|
|
42
48
|
keep 0 and put the reset at the right end of their label line. */
|
|
@@ -655,10 +661,9 @@
|
|
|
655
661
|
.mint-settings-modal__density-preview {
|
|
656
662
|
--_density-row: 2.125rem;
|
|
657
663
|
|
|
664
|
+
/* A hairline table in the setting row, not a bordered box inside the modal. */
|
|
658
665
|
grid-column: 1 / -1;
|
|
659
666
|
overflow: hidden;
|
|
660
|
-
border: 1px solid var(--border-color);
|
|
661
|
-
border-radius: var(--radius-md);
|
|
662
667
|
font-size: 0.75rem;
|
|
663
668
|
}
|
|
664
669
|
|
package/src/styles/variables.css
CHANGED
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
|
|
6
6
|
@import url('https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700&family=Geist+Mono:wght@400;500;600&display=swap');
|
|
7
7
|
|
|
8
|
+
/* Tailwind v4's layer order, declared first so the SDK's base and utilities
|
|
9
|
+
layers sort the same way with or without Tailwind in the host. */
|
|
10
|
+
@layer theme, base, components, utilities;
|
|
11
|
+
|
|
8
12
|
/* ==========================================================================
|
|
9
13
|
CSS Variables - Light Mode
|
|
10
14
|
========================================================================== */
|
|
@@ -135,6 +139,8 @@
|
|
|
135
139
|
--form-height-md: 2rem;
|
|
136
140
|
--form-height-lg: 2.5rem;
|
|
137
141
|
--mint-gutter: 0.5rem;
|
|
142
|
+
/* Distance from the outermost cards to the window edge, in every density. */
|
|
143
|
+
--mint-page-inset: 1rem;
|
|
138
144
|
|
|
139
145
|
/* Semantic colors */
|
|
140
146
|
--mint-success: #10B981;
|
|
@@ -344,6 +350,9 @@ button, input, select, textarea {
|
|
|
344
350
|
/* ==========================================================================
|
|
345
351
|
MINT Utility Classes (for Tailwind v4 compatibility)
|
|
346
352
|
========================================================================== */
|
|
353
|
+
/* In Tailwind's utilities layer: unlayered, these beat every layered rule, so a
|
|
354
|
+
host's responsive variant (`lg:flex-row`) lost to the SDK's `.flex-col`. */
|
|
355
|
+
@layer utilities {
|
|
347
356
|
.bg-bg-hover {
|
|
348
357
|
background-color: var(--bg-tertiary);
|
|
349
358
|
}
|
|
@@ -719,6 +728,7 @@ button, input, select, textarea {
|
|
|
719
728
|
.max-w-sm {
|
|
720
729
|
max-width: 24rem;
|
|
721
730
|
}
|
|
731
|
+
} /* @layer utilities */
|
|
722
732
|
|
|
723
733
|
/* ==========================================================================
|
|
724
734
|
Reduced Motion
|