@morscherlab/mint-sdk
v1.0.45
Published
MINT Platform SDK — Vue 3 components, composables, and types for plugin development. MINT = Mass-spec INtegrated Toolkit.
Downloads
6,737
Maintainers
Readme
@morscherlab/mint-sdk (Frontend)
Vue 3 SDK for MINT Platform plugin development. Provides reusable components, composables, stores, and types for building consistent, well-integrated plugins.
Full Documentation: See the comprehensive docs for detailed API reference and guides.
- API Reference
- Component Catalog - All public components with props/events
- Composables Reference - All public composables with examples
- Theming Guide - CSS variables and customization
Installation
bun add @morscherlab/mint-sdkRequirements
- Vue 3.4+
- Pinia 2.1+
- Tailwind CSS 4.0+ (optional - SDK includes pre-built utility classes)
Quick Start
1. Import Styles
Import the SDK styles in your main entry point:
// main.ts
import '@morscherlab/mint-sdk/styles'The SDK includes all necessary CSS utility classes pre-built, so Tailwind CSS is optional. The styles work standalone or alongside Tailwind.
2. (Optional) Configure Tailwind
If you're using Tailwind CSS and want to extend the MINT theme:
import mintPreset from '@morscherlab/mint-sdk/tailwind.preset'
export default {
presets: [mintPreset],
content: [
'./src/**/*.vue',
'./node_modules/@morscherlab/mint-sdk/**/*.vue',
],
}3. Use Components
<script setup lang="ts">
import { BaseButton, BaseInput, FormField } from '@morscherlab/mint-sdk'
import { useToast, useAuth } from '@morscherlab/mint-sdk'
import type { ButtonVariant } from '@morscherlab/mint-sdk'
const { success } = useToast()
const { login } = useAuth()
async function handleSubmit() {
const result = await login(username, password)
if (result) {
success('Login successful!')
}
}
</script>
<template>
<FormField label="Username" required>
<BaseInput v-model="username" placeholder="Enter username" />
</FormField>
<BaseButton variant="primary" @click="handleSubmit">
Login
</BaseButton>
</template>4. Use Generated Plugin Clients
For plugin frontends scaffolded by mint init, run this from the plugin root:
mint sdk generateUse mint sdk generate --check --json when CI or editor tasks need machine-readable contract drift status.
Then call backend routes through the generated client:
import { useGeneratedPluginClient } from './generated/mint-plugin'
const pluginClient = useGeneratedPluginClient()
const health = await pluginClient.health()Generated files also expose typed plugin settings when the backend declares a
settings_model:
import { useGeneratedPluginSettings } from './generated/mint-plugin'
const { settings } = useGeneratedPluginSettings()
const threshold = settings.value?.thresholdThe generated client is built from backend plugin metadata, FastAPI routes, and Pydantic schemas, and uses the frontend SDK to resolve the API prefix automatically.
Routes with an experimentId path parameter can omit it inside an experiment page; the client reads the current platform experiment from injected context or the URL:
await pluginClient.analyze({ body: { parameters: { threshold: '0.05' } } })Use useCurrentExperiment() when a plugin view needs the platform experiment selected in the URL or injected context:
import { useCurrentExperiment } from '@morscherlab/mint-sdk'
const {
experimentId,
hasExperiment,
requireExperimentId,
experiment,
isLoading,
refresh,
} = useCurrentExperiment()
async function saveCurrentExperiment() {
if (!hasExperiment.value) return
const id = requireExperimentId()
// Use id for platform APIs or explicit cross-experiment overrides.
}5. Use Biology Data Templates
Plugin frontends can import standard biology template builders and adapters instead of inventing ad-hoc JSON shapes:
import {
createWellPlateScreenCollection,
createTemplateCollection,
createPlateMapTemplate,
createSampleSheetTemplate,
ensureTemplateFromCollection,
listBioTemplateCatalog,
listBioTemplatePresets,
toPlateMapEditorState,
toTemplateDataFrame,
} from '@morscherlab/mint-sdk/templates'
const catalog = listBioTemplateCatalog()
const presets = listBioTemplatePresets()
const template = createPlateMapTemplate({
samples: ['Control', 'Treatment'],
})
const plateEditorState = toPlateMapEditorState(template)
const sampleFrame = toTemplateDataFrame(createSampleSheetTemplate({
samples: [{ sampleId: 'S001', name: 'Control 1' }],
}))
// <DataFrame v-bind="sampleFrame" />
const collection = createTemplateCollection([template])
const loadedPlate = ensureTemplateFromCollection(collection, 'plate-map')
const screenCollection = createWellPlateScreenCollection({
samples: ['Control', 'Treatment'],
compounds: { 'Drug A': [10, 1, 0.1] },
unit: 'uM',
})For frontend wiring, useBioTemplateWorkspace() combines the generated
controls, sidebar/forms, renderer props, and SDK component bindings:
import { useBioTemplateWorkspace } from '@morscherlab/mint-sdk'
import { createWellPlateScreenCollection } from '@morscherlab/mint-sdk/templates'
const collection = createWellPlateScreenCollection({
samples: ['Control', 'Treatment'],
compounds: { 'Drug A': [10, 1, 0.1] },
})
const workspace = useBioTemplateWorkspace(collection)
// <AppSidebar v-bind="workspace.sidebar" />
// <FormBuilder v-bind="workspace.form" />
// <BioTemplateRenderer v-if="workspace.renderer" v-bind="workspace.renderer" />For editable built-in presets, useBioTemplatePresetWorkspace() also manages
the generated control values, collection updates, and current-experiment save:
import { BioTemplatePresetWorkspaceView, useBioTemplatePresetWorkspace } from '@morscherlab/mint-sdk'
const workspace = useBioTemplatePresetWorkspace('wellplate-screen')
// <BioTemplatePresetWorkspaceView :workspace="workspace" />For custom plugin tools, pass one workspace model to ControlWorkspaceView to
generate AppTopBar, AppSidebar, FormBuilder, component prop bindings, and
their shared values from the same source:
<script setup lang="ts">
import { ref } from 'vue'
import { ControlWorkspaceView, defineControlModel } from '@morscherlab/mint-sdk'
const workspaceModel = defineControlModel({
views: {
analysis: {
label: 'Analysis',
sections: {
parameters: {
label: 'Parameters',
controls: {
threshold: { type: 'number', default: 0.05, min: 0, max: 1 },
method: ['linear', 'logistic'],
saveResults: true,
},
},
},
},
},
})
const values = ref({})
</script>
<template>
<ControlWorkspaceView v-model="values" :model="workspaceModel" title="Analysis" />
</template>Use defineControls() for flat forms, and use useControlWorkspace()
directly only when a plugin needs full manual control over the generated
AppTopBar, AppSidebar, or FormBuilder bindings.
For WellPlate + DoseCalculator pages, start from the dose-design preset instead of writing the sidebar controls and component prop mappings yourself:
<script setup lang="ts">
import { ControlWorkspaceView, DoseCalculator, WellPlate, defineDoseDesignControlModel } from '@morscherlab/mint-sdk'
const workspaceModel = defineDoseDesignControlModel({
selectedWells: ['A1', 'A2'],
includeMolecularWeight: true,
})
</script>
<template>
<ControlWorkspaceView :model="workspaceModel" title="Dose Design" v-slot="{ componentPropsById }">
<WellPlate v-bind="componentPropsById.plate" />
<DoseCalculator v-bind="componentPropsById.dose" />
</ControlWorkspaceView>
</template>Built-in templates include plate-map, sample-sheet, sample-prep,
dose-response, calibration-curve, time-course, protocol-steps, assay-matrix,
reagent-list, flow-cytometry-panel, instrument-run, and qpcr-plate. In
plugin projects, mint add data-template <name> --page generates the
matching backend route, typed frontend composable, and starter view.
Generated composables use ensureTemplateEnvelope() to validate backend
template payloads before assigning typed frontend state. Use
createTemplateCollection(), extractTemplateCollection(), and
ensureTemplateFromCollection() when a plugin view reads or writes the shared
design_data.templates layout. mint add data-template-pack <name> --page
generates a pack-level composable that uses these helpers for curated
experiment scaffolds.
Use mint add data-template-pack <name> --page for curated sets such as
cell-culture-screen, omics-assay, longitudinal-study, and
molecular-assay.
For no-scaffold defaults that can be saved directly to design_data, use
template presets such as createWellPlateScreenCollection(),
createQpcrExpressionCollection(), createLcmsBatchCollection(), and
createWesternBlotAssayCollection().
Components
Base Components
BaseButton- Button with variants (primary, secondary, cta, danger, success, ghost)BaseInput- Text input with validation statesBaseSelect- Dropdown select with generic typingBaseTabs- Tab navigation with underline and pills variantsBaseModal- Modal dialog with Teleport
Form Components
FormField- Form field wrapper with label, error, and hintFormBuilder- Schema-driven forms from fullschemaobjects or compactcontrols
Feedback Components
AlertBox- Alert messages (success, error, warning, info)AppToastContainer- Toast notification container for the globaluseToast()queue
Action Components
IconButton- Icon-only button with accessibilityThemeToggle- Light/dark mode toggle
Layout Components
CollapsibleCard- Expandable card sections with optional icon badge and toggle switchAppTopBar- Application header with slotsAppSidebar- Context sidebar that accepts panels/forms or a compactcontrolsschema
Biological Template Components
BioTemplateRenderer- Render template envelopes or collections with matching SDK componentsBioTemplateExperimentWorkspaceView- Current-experiment load/save/reset workspace for one template or collectionBioTemplatePresetWorkspaceView- Full editable preset workspace fromuseBioTemplatePresetWorkspace()
File & Data Components
FileUploader- Drag-and-drop file upload with file/folder mode support
Sample Management Components
SampleSelector- Hierarchical sample grouping with auto-group, CSV metadata import, and optional experimentdesign_datasample loadingAutoGroupModal- Smart sample grouping wizard for names and design metadataGroupAssigner- Drag-and-drop group assignment for comparisons (e.g., Control vs Treatment)
Removed Compatibility APIs
The public SDK no longer exports ToastNotification, GroupingModal,
SettingsButton, FormSection, FormFieldRenderer, or usePluginApi().
Use AppToastContainer, AutoGroupModal, AppTopBar settings or
SettingsModal, FormBuilder, and generated useGeneratedPluginClient()
helpers instead. mint doctor still detects old imports and reports the
replacement path.
Composables
useApi(options?)
Generic API client with auth interceptor.
const api = useApi()
// GET request
const data = await api.get<User[]>('/users')
// POST with body
const created = await api.post<User>('/users', { name: 'John' })
// File upload
const result = await api.upload<UploadResponse>('/upload', file)
// Build URLs for external use
const downloadUrl = api.buildUrl('/files/123/download')useAuth()
Authentication methods.
const { login, logout, initializeAuth, getCurrentUser } = useAuth()
// Initialize on app mount
await initializeAuth()
// Login
const success = await login(username, password)
// Get current user
const user = await getCurrentUser()usePasskey()
WebAuthn/FIDO2 passkey support.
const { isSupported, registerPasskey, loginWithPasskey } = usePasskey()
if (isSupported()) {
await registerPasskey('My Device')
// or
await loginWithPasskey()
}useTheme()
Theme switching.
const { isDark, toggleTheme, setTheme } = useTheme()
toggleTheme()
setTheme(true) // dark modeuseToast()
Toast notification management.
const { success, error, warning, info } = useToast()
success('Operation completed!')
error('Something went wrong')
warning('Please review your input')
info('New update available')usePlatformContext()
Detect and interact with MINT Platform when running as a plugin.
const { isIntegrated, plugin, user, navigate, notify } = usePlatformContext()
if (isIntegrated.value) {
// Running under MINT Platform
console.log('Plugin:', plugin.value?.name)
notify('Hello from plugin!', 'info')
}useExperimentSamples(options?)
Load experiment design_data and derive SampleSelector-compatible sample values.
const { samples, sampleOptions, fetch } = useExperimentSamples({ experimentId: 42 })
await fetch()Stores
useAuthStore
Pinia store for authentication state.
const authStore = useAuthStore()
// State
authStore.token
authStore.userInfo
authStore.isAuthenticated
authStore.isAdmin
// Actions
authStore.initialize()
authStore.setToken(token, expiresIn)
authStore.logout()useSettingsStore
Pinia store for app settings.
const settingsStore = useSettingsStore()
// State
settingsStore.theme // 'light' | 'dark' | 'system'
settingsStore.colorPalette
// Methods
settingsStore.getApiBaseUrl()
settingsStore.getWsBaseUrl()
settingsStore.isDark()TypeScript Types
All types are exported from @morscherlab/mint-sdk:
import type {
// Components
ButtonVariant,
ButtonSize,
ModalSize,
AlertType,
Toast,
TabItem,
SelectOption,
// Sample Management
SampleGroup, // { name, color, samples[] }
GroupItem, // { name, color, count }
FileUploaderMode, // 'file' | 'folder'
// Auth
AuthConfig,
UserInfo,
LoginResponse,
// Platform
PluginInfo,
PlatformContext,
ThemeMode,
} from '@morscherlab/mint-sdk'CSS Utility Classes
The SDK provides ready-to-use CSS classes:
Buttons
.btn-primary- Blue primary button.btn-secondary- Outlined/bordered button.btn-cta- Orange call-to-action button.btn-success- Green success button.btn-danger- Red danger button
Inputs
.input-modern- Styled text input.select-modern- Styled dropdown select.label-modern- Uppercase label
Cards & Containers
.card- Card with border and shadow.card-hover- Card with hover effect.floating-card- Floating container pattern
Alerts
.alert-success- Green success alert.alert-error- Red error alert.alert-warning- Yellow warning alert.alert-info- Blue info alert
Form Controls
.toggle-switch- Toggle switch.checkbox-modern- Styled checkbox
Theming
The SDK uses CSS variables for theming. Override them to customize:
:root {
--bg-primary: #F8FAFC;
--bg-secondary: #FFFFFF;
--bg-tertiary: #F1F5F9;
--text-primary: #1E293B;
--text-secondary: #64748B;
--border-color: #E5E7EB;
--color-primary: #3B82F6;
}
html.dark {
--bg-primary: #0F172A;
--bg-secondary: #1E293B;
--bg-tertiary: #334155;
--text-primary: #F8FAFC;
--text-secondary: #94A3B8;
--border-color: #334155;
}License
MIT
