@morscherlab/mld-sdk 0.7.0 → 0.7.1

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.
@@ -16,4 +16,5 @@ export { useSequenceUtils, type SequenceType, type SequenceStats, } from './useS
16
16
  export { parseTime, formatTime, generateTimeSlots, rangesOverlap, durationMinutes, formatDuration, isTimeInRange, findAvailableSlots, snapToSlot, addMinutes, compareTime, } from './useTimeUtils';
17
17
  export { useScheduleDrag } from './useScheduleDrag';
18
18
  export { useFormBuilder, evaluateCondition } from './useFormBuilder';
19
+ export { usePluginConfig, type UsePluginConfigReturn } from './usePluginConfig';
19
20
  export { getFieldRegistryEntry, getTypeDefault, type RegistryEntry, } from './formBuilderRegistry';
@@ -16,6 +16,7 @@ import { useSequenceUtils } from "./useSequenceUtils.js";
16
16
  import { addMinutes, compareTime, durationMinutes, findAvailableSlots, formatDuration, formatTime, generateTimeSlots, isTimeInRange, parseTime, rangesOverlap, snapToSlot } from "./useTimeUtils.js";
17
17
  import { useScheduleDrag } from "./useScheduleDrag.js";
18
18
  import { evaluateCondition, useFormBuilder } from "./useFormBuilder.js";
19
+ import { usePluginConfig } from "./usePluginConfig.js";
19
20
  import { getFieldRegistryEntry, getTypeDefault } from "./formBuilderRegistry.js";
20
21
  export {
21
22
  ATOMIC_WEIGHTS,
@@ -44,6 +45,7 @@ export {
44
45
  useFormBuilder,
45
46
  usePasskey,
46
47
  usePlatformContext,
48
+ usePluginConfig,
47
49
  useProtocolTemplates,
48
50
  useRackEditor,
49
51
  useScheduleDrag,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,12 @@
1
+ import { Ref, ComputedRef } from 'vue';
2
+ export interface UsePluginConfigReturn {
3
+ config: Ref<Record<string, unknown>>;
4
+ isLoading: Ref<boolean>;
5
+ isSaving: Ref<boolean>;
6
+ error: Ref<string | null>;
7
+ isDirty: ComputedRef<boolean>;
8
+ load: () => Promise<void>;
9
+ save: () => Promise<boolean>;
10
+ reset: () => void;
11
+ }
12
+ export declare function usePluginConfig(pluginName?: string): UsePluginConfigReturn;
@@ -0,0 +1,77 @@
1
+ import { computed, ref, onMounted } from "vue";
2
+ import { useApi } from "./useApi.js";
3
+ import { usePlatformContext } from "./usePlatformContext.js";
4
+ function usePluginConfig(pluginName) {
5
+ const api = useApi();
6
+ const { plugin } = usePlatformContext();
7
+ const resolvedName = computed(() => {
8
+ var _a;
9
+ return pluginName ?? ((_a = plugin.value) == null ? void 0 : _a.name) ?? "";
10
+ });
11
+ const config = ref({});
12
+ const savedConfig = ref({});
13
+ const isLoading = ref(false);
14
+ const isSaving = ref(false);
15
+ const error = ref(null);
16
+ const isDirty = computed(() => {
17
+ return JSON.stringify(config.value) !== JSON.stringify(savedConfig.value);
18
+ });
19
+ async function load() {
20
+ const name = resolvedName.value;
21
+ if (!name) return;
22
+ isLoading.value = true;
23
+ error.value = null;
24
+ try {
25
+ const response = await api.get(
26
+ `/api/plugins/${encodeURIComponent(name)}/config`
27
+ );
28
+ config.value = { ...response.config };
29
+ savedConfig.value = { ...response.config };
30
+ } catch (e) {
31
+ error.value = e instanceof Error ? e.message : "Failed to load plugin config";
32
+ } finally {
33
+ isLoading.value = false;
34
+ }
35
+ }
36
+ async function save() {
37
+ const name = resolvedName.value;
38
+ if (!name) return false;
39
+ isSaving.value = true;
40
+ error.value = null;
41
+ try {
42
+ const response = await api.put(
43
+ `/api/plugins/${encodeURIComponent(name)}/config`,
44
+ { config: config.value }
45
+ );
46
+ config.value = { ...response.config };
47
+ savedConfig.value = { ...response.config };
48
+ return true;
49
+ } catch (e) {
50
+ error.value = e instanceof Error ? e.message : "Failed to save plugin config";
51
+ return false;
52
+ } finally {
53
+ isSaving.value = false;
54
+ }
55
+ }
56
+ function reset() {
57
+ config.value = { ...savedConfig.value };
58
+ error.value = null;
59
+ }
60
+ onMounted(() => {
61
+ load();
62
+ });
63
+ return {
64
+ config,
65
+ isLoading,
66
+ isSaving,
67
+ error,
68
+ isDirty,
69
+ load,
70
+ save,
71
+ reset
72
+ };
73
+ }
74
+ export {
75
+ usePluginConfig
76
+ };
77
+ //# sourceMappingURL=usePluginConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePluginConfig.js","sources":["../../src/composables/usePluginConfig.ts"],"sourcesContent":["import { ref, computed, onMounted, type Ref, type ComputedRef } from 'vue'\nimport { useApi } from './useApi'\nimport { usePlatformContext } from './usePlatformContext'\n\nexport interface UsePluginConfigReturn {\n config: Ref<Record<string, unknown>>\n isLoading: Ref<boolean>\n isSaving: Ref<boolean>\n error: Ref<string | null>\n isDirty: ComputedRef<boolean>\n load: () => Promise<void>\n save: () => Promise<boolean>\n reset: () => void\n}\n\nexport function usePluginConfig(pluginName?: string): UsePluginConfigReturn {\n const api = useApi()\n const { plugin } = usePlatformContext()\n\n const resolvedName = computed(() => pluginName ?? plugin.value?.name ?? '')\n\n const config = ref<Record<string, unknown>>({})\n const savedConfig = ref<Record<string, unknown>>({})\n const isLoading = ref(false)\n const isSaving = ref(false)\n const error = ref<string | null>(null)\n\n const isDirty = computed(() => {\n return JSON.stringify(config.value) !== JSON.stringify(savedConfig.value)\n })\n\n async function load(): Promise<void> {\n const name = resolvedName.value\n if (!name) return\n\n isLoading.value = true\n error.value = null\n try {\n const response = await api.get<{ plugin_name: string; config: Record<string, unknown> }>(\n `/api/plugins/${encodeURIComponent(name)}/config`,\n )\n config.value = { ...response.config }\n savedConfig.value = { ...response.config }\n } catch (e) {\n error.value = e instanceof Error ? e.message : 'Failed to load plugin config'\n } finally {\n isLoading.value = false\n }\n }\n\n async function save(): Promise<boolean> {\n const name = resolvedName.value\n if (!name) return false\n\n isSaving.value = true\n error.value = null\n try {\n const response = await api.put<{ plugin_name: string; config: Record<string, unknown> }>(\n `/api/plugins/${encodeURIComponent(name)}/config`,\n { config: config.value },\n )\n config.value = { ...response.config }\n savedConfig.value = { ...response.config }\n return true\n } catch (e) {\n error.value = e instanceof Error ? e.message : 'Failed to save plugin config'\n return false\n } finally {\n isSaving.value = false\n }\n }\n\n function reset(): void {\n config.value = { ...savedConfig.value }\n error.value = null\n }\n\n onMounted(() => {\n load()\n })\n\n return {\n config,\n isLoading,\n isSaving,\n error,\n isDirty,\n load,\n save,\n reset,\n }\n}\n"],"names":[],"mappings":";;;AAeO,SAAS,gBAAgB,YAA4C;AAC1E,QAAM,MAAM,OAAA;AACZ,QAAM,EAAE,OAAA,IAAW,mBAAA;AAEnB,QAAM,eAAe,SAAS,MAAA;;AAAM,2BAAc,YAAO,UAAP,mBAAc,SAAQ;AAAA,GAAE;AAE1E,QAAM,SAAS,IAA6B,EAAE;AAC9C,QAAM,cAAc,IAA6B,EAAE;AACnD,QAAM,YAAY,IAAI,KAAK;AAC3B,QAAM,WAAW,IAAI,KAAK;AAC1B,QAAM,QAAQ,IAAmB,IAAI;AAErC,QAAM,UAAU,SAAS,MAAM;AAC7B,WAAO,KAAK,UAAU,OAAO,KAAK,MAAM,KAAK,UAAU,YAAY,KAAK;AAAA,EAC1E,CAAC;AAED,iBAAe,OAAsB;AACnC,UAAM,OAAO,aAAa;AAC1B,QAAI,CAAC,KAAM;AAEX,cAAU,QAAQ;AAClB,UAAM,QAAQ;AACd,QAAI;AACF,YAAM,WAAW,MAAM,IAAI;AAAA,QACzB,gBAAgB,mBAAmB,IAAI,CAAC;AAAA,MAAA;AAE1C,aAAO,QAAQ,EAAE,GAAG,SAAS,OAAA;AAC7B,kBAAY,QAAQ,EAAE,GAAG,SAAS,OAAA;AAAA,IACpC,SAAS,GAAG;AACV,YAAM,QAAQ,aAAa,QAAQ,EAAE,UAAU;AAAA,IACjD,UAAA;AACE,gBAAU,QAAQ;AAAA,IACpB;AAAA,EACF;AAEA,iBAAe,OAAyB;AACtC,UAAM,OAAO,aAAa;AAC1B,QAAI,CAAC,KAAM,QAAO;AAElB,aAAS,QAAQ;AACjB,UAAM,QAAQ;AACd,QAAI;AACF,YAAM,WAAW,MAAM,IAAI;AAAA,QACzB,gBAAgB,mBAAmB,IAAI,CAAC;AAAA,QACxC,EAAE,QAAQ,OAAO,MAAA;AAAA,MAAM;AAEzB,aAAO,QAAQ,EAAE,GAAG,SAAS,OAAA;AAC7B,kBAAY,QAAQ,EAAE,GAAG,SAAS,OAAA;AAClC,aAAO;AAAA,IACT,SAAS,GAAG;AACV,YAAM,QAAQ,aAAa,QAAQ,EAAE,UAAU;AAC/C,aAAO;AAAA,IACT,UAAA;AACE,eAAS,QAAQ;AAAA,IACnB;AAAA,EACF;AAEA,WAAS,QAAc;AACrB,WAAO,QAAQ,EAAE,GAAG,YAAY,MAAA;AAChC,UAAM,QAAQ;AAAA,EAChB;AAEA,YAAU,MAAM;AACd,SAAA;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { MLDSdk, default } from './install';
2
2
  export { BaseButton, BaseInput, BaseTextarea, BaseSelect, BaseCheckbox, BaseToggle, BaseRadioGroup, BaseSlider, ColorSlider, BaseTabs, BaseModal, FormField, DatePicker, TimePicker, TagsInput, NumberInput, FileUploader, AlertBox, ToastNotification, IconButton, ThemeToggle, SettingsButton, CollapsibleCard, AppTopBar, AppSidebar, AppLayout, AppContainer, Skeleton, WellPlate, RackEditor, SampleLegend, PlateMapEditor, ExperimentTimeline, SampleSelector, GroupingModal, GroupAssigner, MoleculeInput, ConcentrationInput, DoseCalculator, ReagentList, SampleHierarchyTree, ProtocolStepEditor, SegmentedControl, MultiSelect, BasePill, DropdownButton, Calendar, DataFrame, LoadingSpinner, Divider, StatusIndicator, ProgressBar, Avatar, EmptyState, Breadcrumb, Tooltip, ConfirmDialog, ChartContainer, SettingsModal, ScientificNumber, ChemicalFormula, FormulaInput, SequenceInput, UnitInput, StepWizard, AuditTrail, BatchProgressList, DateTimePicker, TimeRangeInput, ScheduleCalendar, ResourceCard, } from './components';
3
- export { useApi, useAuth, usePasskey, useTheme, useToast, usePlatformContext, useWellPlateEditor, useConcentrationUnits, useDoseCalculator, useProtocolTemplates, useRackEditor, useChemicalFormula, ATOMIC_WEIGHTS, useSequenceUtils, type ApiClientOptions, type UseWellPlateEditorOptions, type UseWellPlateEditorReturn, type UseRackEditorOptions, type UseRackEditorReturn, type ConcentrationValue, type ConcentrationUnit, type VolumeValue, type VolumeUnit, type StepTemplate, type FormulaParseResult, type FormulaPart, type SequenceType, type SequenceStats, parseTime, formatTime, generateTimeSlots, rangesOverlap, durationMinutes, formatDuration, isTimeInRange, findAvailableSlots, snapToSlot, addMinutes, compareTime, useScheduleDrag, } from './composables';
3
+ export { useApi, useAuth, usePasskey, useTheme, useToast, usePlatformContext, useWellPlateEditor, useConcentrationUnits, useDoseCalculator, useProtocolTemplates, useRackEditor, useChemicalFormula, ATOMIC_WEIGHTS, useSequenceUtils, type ApiClientOptions, type UseWellPlateEditorOptions, type UseWellPlateEditorReturn, type UseRackEditorOptions, type UseRackEditorReturn, type ConcentrationValue, type ConcentrationUnit, type VolumeValue, type VolumeUnit, type StepTemplate, type FormulaParseResult, type FormulaPart, type SequenceType, type SequenceStats, parseTime, formatTime, generateTimeSlots, rangesOverlap, durationMinutes, formatDuration, isTimeInRange, findAvailableSlots, snapToSlot, addMinutes, compareTime, useScheduleDrag, usePluginConfig, type UsePluginConfigReturn, } from './composables';
4
4
  export { useAuthStore, useSettingsStore, colorPalettes, type SettingsState, } from './stores';
5
5
  export type { ContainerDirection, ButtonVariant, ButtonSize, InputType, ModalSize, AlertType, Toast, TabItem, SelectOption, RadioOption, FormFieldProps, SidebarToolSection, CollapsibleState, TopBarVariant, TopBarPage, TopBarTab, TopBarTabOption, TopBarSettingsConfig, WellPlateFormat, WellState, WellPlateSelectionMode, Well, HeatmapColorScale, HeatmapConfig, SlotPosition, WellExtendedData, WellEditData, WellEditField, WellLegendItem, Rack, SampleType, PlateMap, PlateMapEditorState, ProtocolStepType, ProtocolStepStatus, ProtocolStep, SampleGroup, GroupItem, FileUploaderMode, SegmentedOption, SegmentedControlVariant, SegmentedControlSize, MultiSelectOption, MultiSelectSize, PillVariant, PillSize, CalendarSelectionMode, CalendarMarker, CalendarDayContext, SortDirection, SortState, DataFrameColumn, PaginationState, SpinnerSize, SpinnerVariant, DividerSpacing, StatusType, ProgressVariant, ProgressSize, AvatarSize, EmptyStateColor, EmptyStateSize, BreadcrumbItem, TooltipPosition, ConfirmVariant, SettingsTab, NumberNotation, TimePickerFormat, TimeRange, ScheduleView, ScheduleEventStatus, ScheduleEvent, ScheduleBlockedSlot, ScheduleSlotContext, ScheduleEventCreateContext, ScheduleEventUpdateContext, ResourceStatus, ResourceSpec, UnitOption, WizardStep, WizardStepState, AuditEntryType, AuditEntry, BatchItemStatus, BatchItem, BatchSummary, AuthConfig, UserInfo, LoginResponse, TokenVerifyResponse, RegisterRequest, UpdateProfileRequest, CredentialInfo, PluginInfo, PluginNavItem, PluginSettings, PluginSettingField, PlatformContext, PlatformEventType, PlatformEvent, ThemeMode, ColorPalette, TableDensity, } from './types';
package/dist/index.js CHANGED
@@ -156,6 +156,7 @@ import { ATOMIC_WEIGHTS, useChemicalFormula } from "./composables/useChemicalFor
156
156
  import { useSequenceUtils } from "./composables/useSequenceUtils.js";
157
157
  import { addMinutes, compareTime, durationMinutes, findAvailableSlots, formatDuration, formatTime, generateTimeSlots, isTimeInRange, parseTime, rangesOverlap, snapToSlot } from "./composables/useTimeUtils.js";
158
158
  import { useScheduleDrag } from "./composables/useScheduleDrag.js";
159
+ import { usePluginConfig } from "./composables/usePluginConfig.js";
159
160
  import { useAuthStore } from "./stores/auth.js";
160
161
  import { colorPalettes, useSettingsStore } from "./stores/settings.js";
161
162
  export {
@@ -253,6 +254,7 @@ export {
253
254
  useDoseCalculator,
254
255
  usePasskey,
255
256
  usePlatformContext,
257
+ usePluginConfig,
256
258
  useProtocolTemplates,
257
259
  useRackEditor,
258
260
  useScheduleDrag,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/dist/styles.css CHANGED
@@ -3363,6 +3363,7 @@ html.dark .mld-checkbox__native:focus-visible + .mld-checkbox__box {
3363
3363
  /* NumberInput Component Styles */
3364
3364
  .mld-number-input {
3365
3365
  display: inline-flex;
3366
+ max-width: 100%;
3366
3367
  border-radius: 0.5rem;
3367
3368
  border: 1px solid var(--border-color);
3368
3369
  overflow: hidden;
@@ -3395,6 +3396,7 @@ html.dark .mld-checkbox__native:focus-visible + .mld-checkbox__box {
3395
3396
  display: flex;
3396
3397
  align-items: center;
3397
3398
  justify-content: center;
3399
+ flex-shrink: 0;
3398
3400
  background-color: var(--bg-tertiary);
3399
3401
  color: var(--text-muted);
3400
3402
  border: none;
@@ -3429,7 +3431,8 @@ html.dark .mld-checkbox__native:focus-visible + .mld-checkbox__box {
3429
3431
  height: 1rem;
3430
3432
  }
3431
3433
  .mld-number-input__input {
3432
- width: 5rem;
3434
+ flex: 1;
3435
+ min-width: 0;
3433
3436
  text-align: center;
3434
3437
  background-color: var(--bg-secondary);
3435
3438
  color: var(--text-primary);
@@ -14652,6 +14655,7 @@ to { transform: rotate(360deg);
14652
14655
  /* NumberInput Component Styles */
14653
14656
  .mld-number-input {
14654
14657
  display: inline-flex;
14658
+ max-width: 100%;
14655
14659
  border-radius: 0.5rem;
14656
14660
  border: 1px solid var(--border-color);
14657
14661
  overflow: hidden;
@@ -14684,6 +14688,7 @@ to { transform: rotate(360deg);
14684
14688
  display: flex;
14685
14689
  align-items: center;
14686
14690
  justify-content: center;
14691
+ flex-shrink: 0;
14687
14692
  background-color: var(--bg-tertiary);
14688
14693
  color: var(--text-muted);
14689
14694
  border: none;
@@ -14718,7 +14723,8 @@ to { transform: rotate(360deg);
14718
14723
  height: 1rem;
14719
14724
  }
14720
14725
  .mld-number-input__input {
14721
- width: 5rem;
14726
+ flex: 1;
14727
+ min-width: 0;
14722
14728
  text-align: center;
14723
14729
  background-color: var(--bg-secondary);
14724
14730
  color: var(--text-primary);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@morscherlab/mld-sdk",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "MLD Platform SDK - Vue 3 components, composables, and types for plugin development",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -86,6 +86,7 @@ export {
86
86
  } from './useTimeUtils'
87
87
  export { useScheduleDrag } from './useScheduleDrag'
88
88
  export { useFormBuilder, evaluateCondition } from './useFormBuilder'
89
+ export { usePluginConfig, type UsePluginConfigReturn } from './usePluginConfig'
89
90
  export {
90
91
  getFieldRegistryEntry,
91
92
  getTypeDefault,
@@ -0,0 +1,92 @@
1
+ import { ref, computed, onMounted, type Ref, type ComputedRef } from 'vue'
2
+ import { useApi } from './useApi'
3
+ import { usePlatformContext } from './usePlatformContext'
4
+
5
+ export interface UsePluginConfigReturn {
6
+ config: Ref<Record<string, unknown>>
7
+ isLoading: Ref<boolean>
8
+ isSaving: Ref<boolean>
9
+ error: Ref<string | null>
10
+ isDirty: ComputedRef<boolean>
11
+ load: () => Promise<void>
12
+ save: () => Promise<boolean>
13
+ reset: () => void
14
+ }
15
+
16
+ export function usePluginConfig(pluginName?: string): UsePluginConfigReturn {
17
+ const api = useApi()
18
+ const { plugin } = usePlatformContext()
19
+
20
+ const resolvedName = computed(() => pluginName ?? plugin.value?.name ?? '')
21
+
22
+ const config = ref<Record<string, unknown>>({})
23
+ const savedConfig = ref<Record<string, unknown>>({})
24
+ const isLoading = ref(false)
25
+ const isSaving = ref(false)
26
+ const error = ref<string | null>(null)
27
+
28
+ const isDirty = computed(() => {
29
+ return JSON.stringify(config.value) !== JSON.stringify(savedConfig.value)
30
+ })
31
+
32
+ async function load(): Promise<void> {
33
+ const name = resolvedName.value
34
+ if (!name) return
35
+
36
+ isLoading.value = true
37
+ error.value = null
38
+ try {
39
+ const response = await api.get<{ plugin_name: string; config: Record<string, unknown> }>(
40
+ `/api/plugins/${encodeURIComponent(name)}/config`,
41
+ )
42
+ config.value = { ...response.config }
43
+ savedConfig.value = { ...response.config }
44
+ } catch (e) {
45
+ error.value = e instanceof Error ? e.message : 'Failed to load plugin config'
46
+ } finally {
47
+ isLoading.value = false
48
+ }
49
+ }
50
+
51
+ async function save(): Promise<boolean> {
52
+ const name = resolvedName.value
53
+ if (!name) return false
54
+
55
+ isSaving.value = true
56
+ error.value = null
57
+ try {
58
+ const response = await api.put<{ plugin_name: string; config: Record<string, unknown> }>(
59
+ `/api/plugins/${encodeURIComponent(name)}/config`,
60
+ { config: config.value },
61
+ )
62
+ config.value = { ...response.config }
63
+ savedConfig.value = { ...response.config }
64
+ return true
65
+ } catch (e) {
66
+ error.value = e instanceof Error ? e.message : 'Failed to save plugin config'
67
+ return false
68
+ } finally {
69
+ isSaving.value = false
70
+ }
71
+ }
72
+
73
+ function reset(): void {
74
+ config.value = { ...savedConfig.value }
75
+ error.value = null
76
+ }
77
+
78
+ onMounted(() => {
79
+ load()
80
+ })
81
+
82
+ return {
83
+ config,
84
+ isLoading,
85
+ isSaving,
86
+ error,
87
+ isDirty,
88
+ load,
89
+ save,
90
+ reset,
91
+ }
92
+ }
package/src/index.ts CHANGED
@@ -133,6 +133,9 @@ export {
133
133
  compareTime,
134
134
  // Schedule drag
135
135
  useScheduleDrag,
136
+ // Plugin config
137
+ usePluginConfig,
138
+ type UsePluginConfigReturn,
136
139
  } from './composables'
137
140
 
138
141
  // Stores
@@ -2,6 +2,7 @@
2
2
 
3
3
  .mld-number-input {
4
4
  display: inline-flex;
5
+ max-width: 100%;
5
6
  border-radius: 0.5rem;
6
7
  border: 1px solid var(--border-color);
7
8
  overflow: hidden;
@@ -42,6 +43,7 @@
42
43
  display: flex;
43
44
  align-items: center;
44
45
  justify-content: center;
46
+ flex-shrink: 0;
45
47
  background-color: var(--bg-tertiary);
46
48
  color: var(--text-muted);
47
49
  border: none;
@@ -85,7 +87,8 @@
85
87
  }
86
88
 
87
89
  .mld-number-input__input {
88
- width: 5rem;
90
+ flex: 1;
91
+ min-width: 0;
89
92
  text-align: center;
90
93
  background-color: var(--bg-secondary);
91
94
  color: var(--text-primary);