@morscherlab/mint-sdk 1.0.0-beta.3 → 1.0.0-beta.4

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.
Files changed (165) hide show
  1. package/README.md +9 -2
  2. package/dist/__tests__/composables/experiment-utils.test.d.ts +1 -0
  3. package/dist/__tests__/composables/useApi.test.d.ts +1 -0
  4. package/dist/components/AppContainer.vue.d.ts +1 -1
  5. package/dist/components/AppLayout.vue.d.ts +20 -1
  6. package/dist/components/AppSidebar.vue.d.ts +56 -4
  7. package/dist/components/AppTopBar.vue.d.ts +7 -25
  8. package/dist/components/BioTemplateExperimentWorkspaceView.vue.d.ts +3 -1
  9. package/dist/components/BioTemplatePackWorkspaceView.vue.d.ts +1 -0
  10. package/dist/components/BioTemplatePresetWorkspaceView.vue.d.ts +5 -0
  11. package/dist/components/ComponentBindingRenderer.vue.d.ts +44 -0
  12. package/dist/components/ControlWorkspaceView.vue.d.ts +24 -7
  13. package/dist/components/DoseDesignWorkspaceView.vue.d.ts +149 -0
  14. package/dist/components/ExperimentTimeline.vue.d.ts +1 -1
  15. package/dist/components/FormBuilder.vue.d.ts +9 -9
  16. package/dist/components/PlateMapEditor.vue.d.ts +1 -1
  17. package/dist/components/PluginWorkspaceView.vue.d.ts +310 -0
  18. package/dist/components/SettingsModal.vue.d.ts +1 -1
  19. package/dist/components/WellPlate.vue.d.ts +2 -2
  20. package/dist/components/index.d.ts +3 -12
  21. package/dist/components/index.js +3 -3
  22. package/dist/components/{AppPageSelector.vue.d.ts → internal/AppPageSelectorInternal.vue.d.ts} +1 -1
  23. package/dist/components/{AppPillNav.vue.d.ts → internal/AppPillNavInternal.vue.d.ts} +3 -1
  24. package/dist/components/{CalendarGridPanel.vue.d.ts → internal/CalendarGridPanelInternal.vue.d.ts} +1 -1
  25. package/dist/components/internal/FormSectionRenderer.vue.d.ts +4 -4
  26. package/dist/components/{WellEditPopup.vue.d.ts → internal/WellEditPopupInternal.vue.d.ts} +1 -1
  27. package/dist/{components-D_Sr0adg.js → components-BkGF4B4y.js} +4484 -3967
  28. package/dist/components-BkGF4B4y.js.map +1 -0
  29. package/dist/composables/experiment-utils.d.ts +8 -0
  30. package/dist/composables/index.d.ts +5 -7
  31. package/dist/composables/index.js +4 -4
  32. package/dist/composables/useAppExperiment.d.ts +31 -2
  33. package/dist/composables/useBioTemplateComponents.d.ts +5 -3
  34. package/dist/composables/useBioTemplatePackWorkspace.d.ts +3 -2
  35. package/dist/composables/useBioTemplatePresetWorkspace.d.ts +6 -5
  36. package/dist/composables/useBioTemplateWorkspace.d.ts +5 -4
  37. package/dist/composables/useControlSchema.d.ts +43 -21
  38. package/dist/composables/usePluginClient.d.ts +5 -2
  39. package/dist/{composables-C3dpXQN5.js → composables-CHsME9H1.js} +40 -28
  40. package/dist/composables-CHsME9H1.js.map +1 -0
  41. package/dist/index.d.ts +5 -12
  42. package/dist/index.js +5 -5
  43. package/dist/install.js +2 -2
  44. package/dist/styles.css +3625 -3651
  45. package/dist/templates/componentBindings.d.ts +13 -0
  46. package/dist/templates/index.d.ts +3 -3
  47. package/dist/templates/index.js +2 -2
  48. package/dist/{templates-50NPjaxL.js → templates-B5jmTWuk.js} +111 -56
  49. package/dist/templates-B5jmTWuk.js.map +1 -0
  50. package/dist/types/components.d.ts +6 -25
  51. package/dist/types/index.d.ts +1 -1
  52. package/dist/{useScheduleDrag-D4oWdh41.js → useScheduleDrag-BgzpQT53.js} +160 -117
  53. package/dist/useScheduleDrag-BgzpQT53.js.map +1 -0
  54. package/package.json +1 -1
  55. package/src/__tests__/components/ActionItem.test.ts +6 -6
  56. package/src/__tests__/components/AppLayout.test.ts +44 -0
  57. package/src/__tests__/components/AppPageSelector.test.ts +8 -8
  58. package/src/__tests__/components/AppPillNav.test.ts +53 -6
  59. package/src/__tests__/components/AppSidebar.test.ts +126 -0
  60. package/src/__tests__/components/AppToastContainer.test.ts +0 -11
  61. package/src/__tests__/components/AppTopBar.test.ts +182 -119
  62. package/src/__tests__/components/BioTemplateExperimentWorkspaceView.test.ts +7 -1
  63. package/src/__tests__/components/BioTemplatePackWorkspaceView.test.ts +15 -1
  64. package/src/__tests__/components/BioTemplatePresetWorkspaceView.test.ts +26 -1
  65. package/src/__tests__/components/CalendarGridPanel.test.ts +3 -3
  66. package/src/__tests__/components/ComponentBindingRenderer.test.ts +161 -0
  67. package/src/__tests__/components/ControlWorkspaceView.test.ts +134 -63
  68. package/src/__tests__/components/DateTimePicker.test.ts +2 -2
  69. package/src/__tests__/components/DoseDesignWorkspaceView.test.ts +185 -0
  70. package/src/__tests__/components/PluginWorkspaceView.test.ts +548 -0
  71. package/src/__tests__/composables/experiment-utils.test.ts +30 -0
  72. package/src/__tests__/composables/useApi.test.ts +30 -0
  73. package/src/__tests__/composables/useAppExperiment.test.ts +100 -1
  74. package/src/__tests__/composables/useBioTemplatePackWorkspace.test.ts +6 -3
  75. package/src/__tests__/composables/useBioTemplatePresetWorkspace.test.ts +6 -6
  76. package/src/__tests__/composables/useBioTemplateWorkspace.test.ts +6 -1
  77. package/src/__tests__/composables/useControlSchema.test.ts +150 -36
  78. package/src/__tests__/composables/usePluginClient.test.ts +99 -2
  79. package/src/__tests__/docs/frontendDocsCatalog.test.ts +120 -25
  80. package/src/__tests__/templates/templates.test.ts +12 -0
  81. package/src/components/AppAvatarMenu.vue +3 -3
  82. package/src/components/AppLayout.story.vue +39 -0
  83. package/src/components/AppLayout.vue +83 -2
  84. package/src/components/AppPluginSwitcher.vue +5 -5
  85. package/src/components/AppSidebar.story.vue +113 -5
  86. package/src/components/AppSidebar.vue +144 -24
  87. package/src/components/AppTopBar.story.vue +2 -5
  88. package/src/components/AppTopBar.vue +35 -425
  89. package/src/components/BioTemplateExperimentWorkspaceView.story.vue +2 -2
  90. package/src/components/BioTemplateExperimentWorkspaceView.vue +6 -0
  91. package/src/components/BioTemplatePackWorkspaceView.story.vue +4 -4
  92. package/src/components/BioTemplatePackWorkspaceView.vue +1 -0
  93. package/src/components/BioTemplatePresetWorkspaceView.story.vue +14 -2
  94. package/src/components/BioTemplatePresetWorkspaceView.vue +11 -2
  95. package/src/components/BioTemplateRenderer.vue +15 -227
  96. package/src/components/ComponentBindingRenderer.story.vue +57 -0
  97. package/src/components/ComponentBindingRenderer.vue +308 -0
  98. package/src/components/ControlWorkspaceView.story.vue +20 -9
  99. package/src/components/ControlWorkspaceView.vue +43 -12
  100. package/src/components/DatePicker.vue +2 -2
  101. package/src/components/DateTimePicker.vue +2 -2
  102. package/src/components/DoseDesignWorkspaceView.story.vue +77 -0
  103. package/src/components/DoseDesignWorkspaceView.vue +255 -0
  104. package/src/components/ExperimentPopover.vue +2 -6
  105. package/src/components/ExperimentSelectorModal.vue +6 -5
  106. package/src/components/FormBuilder.story.vue +190 -0
  107. package/src/components/PluginWorkspaceView.story.vue +334 -0
  108. package/src/components/PluginWorkspaceView.vue +708 -0
  109. package/src/components/SettingsModal.story.vue +87 -0
  110. package/src/components/WellPlate.vue +2 -2
  111. package/src/components/index.ts +3 -12
  112. package/src/components/{AppPageSelector.vue → internal/AppPageSelectorInternal.vue} +9 -9
  113. package/src/components/internal/AppPillNavInternal.vue +194 -0
  114. package/src/components/{CalendarGridPanel.vue → internal/CalendarGridPanelInternal.vue} +1 -1
  115. package/src/components/{WellEditPopup.vue → internal/WellEditPopupInternal.vue} +3 -3
  116. package/src/composables/experiment-utils.ts +26 -0
  117. package/src/composables/index.ts +21 -7
  118. package/src/composables/useApi.ts +9 -2
  119. package/src/composables/useAppExperiment.ts +85 -13
  120. package/src/composables/useBioTemplateComponents.ts +12 -0
  121. package/src/composables/useBioTemplatePackWorkspace.ts +6 -2
  122. package/src/composables/useBioTemplatePresetWorkspace.ts +10 -21
  123. package/src/composables/useBioTemplateWorkspace.ts +6 -4
  124. package/src/composables/useControlSchema.ts +157 -69
  125. package/src/composables/usePluginClient.ts +50 -9
  126. package/src/index.ts +6 -563
  127. package/src/styles/components/app-layout.css +82 -0
  128. package/src/styles/components/app-pill-nav.css +70 -0
  129. package/src/styles/components/app-sidebar.css +119 -0
  130. package/src/styles/components/app-top-bar.css +0 -235
  131. package/src/styles/index.css +0 -1
  132. package/src/templates/componentBindings.ts +38 -0
  133. package/src/templates/index.ts +4 -0
  134. package/src/types/components.ts +6 -31
  135. package/src/types/index.ts +2 -6
  136. package/dist/__tests__/composables/usePluginApi.test.d.ts +0 -13
  137. package/dist/components/FormFieldRenderer.vue.d.ts +0 -28
  138. package/dist/components/FormSection.vue.d.ts +0 -30
  139. package/dist/components/GroupingModal.vue.d.ts +0 -12
  140. package/dist/components/SettingsButton.vue.d.ts +0 -30
  141. package/dist/components/ToastNotification.vue.d.ts +0 -2
  142. package/dist/components-D_Sr0adg.js.map +0 -1
  143. package/dist/composables/usePluginApi.d.ts +0 -22
  144. package/dist/composables-C3dpXQN5.js.map +0 -1
  145. package/dist/templates-50NPjaxL.js.map +0 -1
  146. package/dist/useScheduleDrag-D4oWdh41.js.map +0 -1
  147. package/src/__tests__/components/FormCompatibility.test.ts +0 -94
  148. package/src/__tests__/components/GroupingModal.test.ts +0 -73
  149. package/src/__tests__/components/SettingsButton.test.ts +0 -44
  150. package/src/__tests__/composables/usePluginApi.test.ts +0 -81
  151. package/src/components/AppPillNav.vue +0 -71
  152. package/src/components/FormFieldRenderer.vue +0 -35
  153. package/src/components/FormSection.vue +0 -37
  154. package/src/components/GroupingModal.story.vue +0 -52
  155. package/src/components/GroupingModal.vue +0 -61
  156. package/src/components/SettingsButton.story.vue +0 -58
  157. package/src/components/SettingsButton.vue +0 -64
  158. package/src/components/ToastNotification.vue +0 -9
  159. package/src/composables/usePluginApi.ts +0 -32
  160. package/src/styles/components/settings-button.css +0 -31
  161. /package/dist/__tests__/components/{FormCompatibility.test.d.ts → ComponentBindingRenderer.test.d.ts} +0 -0
  162. /package/dist/__tests__/components/{GroupingModal.test.d.ts → DoseDesignWorkspaceView.test.d.ts} +0 -0
  163. /package/dist/__tests__/components/{SettingsButton.test.d.ts → PluginWorkspaceView.test.d.ts} +0 -0
  164. /package/dist/components/{ActionItem.vue.d.ts → internal/ActionItemInternal.vue.d.ts} +0 -0
  165. /package/src/components/{ActionItem.vue → internal/ActionItemInternal.vue} +0 -0
@@ -9,6 +9,11 @@
9
9
  flex-shrink: 0;
10
10
  }
11
11
 
12
+ .mint-pill-nav__item-wrap {
13
+ position: relative;
14
+ display: inline-flex;
15
+ }
16
+
12
17
  .mint-pill-nav__item {
13
18
  display: inline-flex;
14
19
  align-items: center;
@@ -61,3 +66,68 @@
61
66
  height: 0.875rem;
62
67
  flex-shrink: 0;
63
68
  }
69
+
70
+ .mint-pill-nav__chevron {
71
+ width: 0.8125rem;
72
+ height: 0.8125rem;
73
+ flex-shrink: 0;
74
+ transition: transform 160ms ease;
75
+ }
76
+
77
+ .mint-pill-nav__chevron--open {
78
+ transform: rotate(180deg);
79
+ }
80
+
81
+ .mint-pill-nav__dropdown {
82
+ position: absolute;
83
+ top: calc(100% + 0.5rem);
84
+ left: 50%;
85
+ z-index: 45;
86
+ min-width: 18rem;
87
+ padding: 0.375rem;
88
+ border-radius: 0.75rem;
89
+ border: 1px solid var(--border-light);
90
+ background: var(--bg-card);
91
+ box-shadow: var(--shadow-lg);
92
+ transform: translateX(-50%);
93
+ }
94
+
95
+ .mint-pill-nav__dropdown-item {
96
+ display: flex;
97
+ align-items: baseline;
98
+ gap: 0.75rem;
99
+ width: 100%;
100
+ padding: 0.5rem 0.625rem;
101
+ border-radius: 0.5rem;
102
+ color: var(--text-secondary);
103
+ font-size: 0.8125rem;
104
+ text-decoration: none;
105
+ white-space: nowrap;
106
+ }
107
+
108
+ .mint-pill-nav__dropdown-item:hover:not(.mint-pill-nav__dropdown-item--disabled) {
109
+ color: var(--text-primary);
110
+ background: var(--bg-secondary);
111
+ }
112
+
113
+ .mint-pill-nav__dropdown-item--active {
114
+ color: var(--text-primary);
115
+ background: var(--bg-secondary);
116
+ font-weight: 600;
117
+ }
118
+
119
+ .mint-pill-nav__dropdown-item--disabled {
120
+ opacity: var(--mint-disabled-opacity);
121
+ cursor: not-allowed;
122
+ }
123
+
124
+ .mint-pill-nav__dropdown-label {
125
+ flex-shrink: 0;
126
+ }
127
+
128
+ .mint-pill-nav__dropdown-description {
129
+ margin-left: auto;
130
+ color: var(--text-muted);
131
+ font-size: 0.75rem;
132
+ font-weight: 400;
133
+ }
@@ -6,6 +6,7 @@
6
6
  height: 100%;
7
7
  overflow: hidden;
8
8
  background-color: var(--bg-secondary);
9
+ transition: width 180ms ease;
9
10
  }
10
11
 
11
12
  .mint-sidebar--hidden {
@@ -40,10 +41,118 @@
40
41
  border-right: 1px solid var(--border-color);
41
42
  }
42
43
 
44
+ .mint-sidebar--analysis {
45
+ background-color: var(--bg-secondary);
46
+ }
47
+
48
+ .mint-sidebar--analysis .mint-sidebar__header {
49
+ padding: 1rem;
50
+ }
51
+
52
+ .mint-sidebar--analysis .mint-sidebar__sections {
53
+ padding: 0.75rem;
54
+ gap: 0.75rem;
55
+ }
56
+
43
57
  /* Header / Footer slots */
44
58
  .mint-sidebar__header {
45
59
  padding: 0.75rem;
46
60
  flex-shrink: 0;
61
+ display: flex;
62
+ align-items: center;
63
+ justify-content: space-between;
64
+ gap: 0.5rem;
65
+ border-bottom: 1px solid var(--border-color);
66
+ }
67
+
68
+ .mint-sidebar__heading {
69
+ min-width: 0;
70
+ display: flex;
71
+ flex: 1;
72
+ align-items: center;
73
+ gap: 0.5rem;
74
+ }
75
+
76
+ .mint-sidebar__heading-copy {
77
+ min-width: 0;
78
+ flex: 1;
79
+ }
80
+
81
+ .mint-sidebar__title {
82
+ margin: 0;
83
+ overflow: hidden;
84
+ color: var(--text-primary);
85
+ font-size: 0.9375rem;
86
+ font-weight: 650;
87
+ line-height: 1.25;
88
+ text-overflow: ellipsis;
89
+ white-space: nowrap;
90
+ }
91
+
92
+ .mint-sidebar__subtitle {
93
+ margin: 0.125rem 0 0;
94
+ overflow: hidden;
95
+ color: var(--text-muted);
96
+ font-size: 0.75rem;
97
+ line-height: 1.25;
98
+ text-overflow: ellipsis;
99
+ white-space: nowrap;
100
+ }
101
+
102
+ .mint-sidebar__badge {
103
+ flex-shrink: 0;
104
+ min-width: 1.375rem;
105
+ padding: 0.125rem 0.375rem;
106
+ border-radius: 9999px;
107
+ background: color-mix(in srgb, var(--color-cta) 14%, transparent);
108
+ color: var(--color-cta);
109
+ font-size: 0.6875rem;
110
+ font-weight: 700;
111
+ line-height: 1.1;
112
+ text-align: center;
113
+ font-variant-numeric: tabular-nums;
114
+ }
115
+
116
+ .mint-sidebar__collapse-button {
117
+ display: inline-flex;
118
+ align-items: center;
119
+ justify-content: center;
120
+ flex-shrink: 0;
121
+ width: 1.875rem;
122
+ height: 1.875rem;
123
+ border: 0;
124
+ border-radius: var(--radius-md);
125
+ color: var(--text-secondary);
126
+ background: transparent;
127
+ cursor: pointer;
128
+ transition:
129
+ color 160ms ease,
130
+ background-color 160ms ease;
131
+ }
132
+
133
+ .mint-sidebar__collapse-button:hover {
134
+ color: var(--text-primary);
135
+ background: var(--bg-tertiary);
136
+ }
137
+
138
+ .mint-sidebar__collapse-button:focus-visible {
139
+ outline: none;
140
+ box-shadow: var(--focus-ring);
141
+ }
142
+
143
+ .mint-sidebar__collapse-icon {
144
+ width: 1rem;
145
+ height: 1rem;
146
+ transition: transform 160ms ease;
147
+ }
148
+
149
+ .mint-sidebar__collapse-icon--collapsed {
150
+ transform: rotate(180deg);
151
+ }
152
+
153
+ .mint-sidebar--collapsed .mint-sidebar__header {
154
+ justify-content: center;
155
+ padding-inline: 0.5rem;
47
156
  }
48
157
 
49
158
  .mint-sidebar__footer {
@@ -63,6 +172,16 @@
63
172
  gap: 0.5rem;
64
173
  }
65
174
 
175
+ .mint-sidebar__collapsed {
176
+ flex: 1 1 0;
177
+ min-height: 0;
178
+ padding: 0.5rem;
179
+ display: flex;
180
+ flex-direction: column;
181
+ align-items: center;
182
+ gap: 0.5rem;
183
+ }
184
+
66
185
  /* Dense sidebar variant — compact sections */
67
186
  .mint-sidebar--dense .mint-sidebar__sections {
68
187
  padding: 0.5rem;
@@ -48,15 +48,6 @@
48
48
  pointer-events: auto;
49
49
  }
50
50
 
51
- /* Left content cluster */
52
- .mint-topbar__left {
53
- display: flex;
54
- align-items: center;
55
- gap: 0.75rem;
56
- flex: 1;
57
- min-width: 0;
58
- }
59
-
60
51
  .mint-topbar__right {
61
52
  display: flex;
62
53
  align-items: center;
@@ -67,19 +58,6 @@
67
58
  margin-left: auto;
68
59
  }
69
60
 
70
- /* Tabs render with the same pill-nav visual language as
71
- AppPillNav — container pill with inset items that gain white background +
72
- shadow when active. See app-pill-nav.css for the canonical treatment. */
73
- .mint-topbar__tabs {
74
- display: inline-flex;
75
- align-items: center;
76
- padding: 0.1875rem;
77
- border-radius: 9999px;
78
- background: var(--bg-tertiary);
79
- border: 1px solid var(--border-light);
80
- flex-shrink: 0;
81
- }
82
-
83
61
  /* Logo styles */
84
62
  .mint-topbar__logo {
85
63
  display: flex;
@@ -159,219 +137,6 @@
159
137
  line-height: 1.25;
160
138
  }
161
139
 
162
- .mint-topbar-breadcrumb {
163
- display: flex;
164
- align-items: center;
165
- gap: 0.5rem;
166
- position: relative;
167
- }
168
-
169
- .mint-topbar-plugin-name {
170
- display: flex;
171
- align-items: center;
172
- gap: 0.25rem;
173
- padding: 0.25rem 0.5rem;
174
- border: none;
175
- background: transparent;
176
- border-radius: var(--radius-sm);
177
- color: var(--text-secondary);
178
- font-weight: 500;
179
- font-size: inherit;
180
- cursor: pointer;
181
- transition: all 0.15s ease;
182
- }
183
-
184
- .mint-topbar-plugin-name:hover {
185
- background: var(--bg-hover);
186
- color: var(--text-primary);
187
- }
188
-
189
- .mint-topbar-plugin-name--static {
190
- padding: 0.25rem 0.5rem;
191
- color: var(--text-secondary);
192
- font-weight: 500;
193
- }
194
-
195
- .mint-topbar-chevron {
196
- transition: transform 0.15s ease;
197
- }
198
-
199
- .mint-topbar-chevron--open {
200
- transform: rotate(180deg);
201
- }
202
-
203
- .mint-topbar-separator {
204
- width: 1rem;
205
- height: 1rem;
206
- color: var(--text-muted);
207
- flex-shrink: 0;
208
- }
209
-
210
- .mint-topbar-current-page {
211
- font-weight: 600;
212
- color: var(--text-primary);
213
- }
214
-
215
- .mint-topbar-dropdown {
216
- position: absolute;
217
- top: calc(100% + 0.5rem);
218
- left: 0;
219
- min-width: 200px;
220
- background: var(--bg-card);
221
- border: 1px solid var(--border-color);
222
- border-radius: var(--radius);
223
- box-shadow: var(--shadow-md);
224
- z-index: 50;
225
- overflow: hidden;
226
- }
227
-
228
- .mint-topbar-dropdown-item {
229
- display: flex;
230
- flex-direction: column;
231
- align-items: flex-start;
232
- width: 100%;
233
- padding: 0.75rem 1rem;
234
- text-decoration: none;
235
- color: inherit;
236
- background: none;
237
- border: none;
238
- font: inherit;
239
- text-align: left;
240
- transition: background-color 0.15s ease;
241
- cursor: pointer;
242
- }
243
-
244
- .mint-topbar-dropdown-item:hover:not(.mint-topbar-dropdown-item--disabled) {
245
- background: var(--bg-hover);
246
- }
247
-
248
- .mint-topbar-dropdown-item--active {
249
- background: var(--color-primary-soft);
250
- color: var(--color-primary);
251
- }
252
-
253
- .mint-topbar-dropdown-item--disabled {
254
- opacity: var(--mint-disabled-opacity);
255
- cursor: not-allowed;
256
- }
257
-
258
- .mint-topbar-dropdown-item__page {
259
- display: flex;
260
- align-items: flex-start;
261
- gap: 0.625rem;
262
- width: 100%;
263
- }
264
-
265
- .mint-topbar-dropdown-item__icon {
266
- width: 1rem;
267
- height: 1rem;
268
- flex-shrink: 0;
269
- margin-top: 0.125rem;
270
- }
271
-
272
- .mint-topbar-dropdown-item__icon.mint-plugin-icon--sm {
273
- width: 1.375rem;
274
- height: 1.375rem;
275
- border-radius: 0.3125rem;
276
- margin-top: -0.0625rem;
277
- }
278
-
279
- .mint-topbar-dropdown-item__copy {
280
- display: flex;
281
- min-width: 0;
282
- flex-direction: column;
283
- align-items: flex-start;
284
- }
285
-
286
- .mint-topbar-dropdown-item__label {
287
- font-weight: 500;
288
- }
289
-
290
- .mint-topbar-dropdown-item__description {
291
- font-size: 0.75rem;
292
- color: var(--text-muted);
293
- margin-top: 0.125rem;
294
- }
295
-
296
- .mint-topbar-dropdown-item--active .mint-topbar-dropdown-item__description {
297
- color: var(--color-primary);
298
- opacity: 0.8;
299
- }
300
-
301
- .mint-topbar-tab-wrapper {
302
- position: relative;
303
- }
304
-
305
- .mint-topbar-tab {
306
- display: inline-flex;
307
- align-items: center;
308
- gap: 0.25rem;
309
- padding: 0.375rem 0.875rem;
310
- border: 0;
311
- background: transparent;
312
- border-radius: 9999px;
313
- color: var(--text-secondary);
314
- font-weight: 500;
315
- font-size: 0.8125rem;
316
- font-family: inherit;
317
- text-decoration: none;
318
- cursor: pointer;
319
- transition:
320
- color 220ms var(--mint-ease-out-quart, cubic-bezier(0.25, 1, 0.5, 1)),
321
- background-color 220ms var(--mint-ease-out-quart, cubic-bezier(0.25, 1, 0.5, 1)),
322
- box-shadow 220ms var(--mint-ease-out-quart, cubic-bezier(0.25, 1, 0.5, 1));
323
- }
324
-
325
- .mint-topbar-tab:hover:not(.mint-topbar-tab--disabled):not(.mint-topbar-tab--active) {
326
- color: var(--text-primary);
327
- }
328
-
329
- .mint-topbar-tab--active {
330
- color: var(--text-primary);
331
- background: var(--bg-card);
332
- box-shadow: var(--shadow-sm);
333
- font-weight: 600;
334
- }
335
-
336
- @media (prefers-reduced-motion: reduce) {
337
- .mint-topbar-tab {
338
- transition: none;
339
- }
340
- }
341
-
342
- .mint-topbar-tab--disabled {
343
- opacity: var(--mint-disabled-opacity);
344
- cursor: not-allowed;
345
- }
346
-
347
- .mint-topbar-tab-chevron {
348
- transition: transform 0.15s ease;
349
- }
350
-
351
- .mint-topbar-tab-icon {
352
- width: 0.875rem;
353
- height: 0.875rem;
354
- flex-shrink: 0;
355
- }
356
-
357
- .mint-topbar-tab-chevron--open {
358
- transform: rotate(180deg);
359
- }
360
-
361
- .mint-topbar-tab-dropdown {
362
- position: absolute;
363
- top: calc(100% + 0.5rem);
364
- left: 50%;
365
- transform: translateX(-50%);
366
- min-width: 180px;
367
- background: var(--bg-card);
368
- border: 1px solid var(--border-color);
369
- border-radius: var(--radius);
370
- box-shadow: var(--shadow-md);
371
- z-index: 50;
372
- overflow: hidden;
373
- }
374
-
375
140
  /* New: generic icon button (notifications, etc.) */
376
141
  .mint-topbar__icon-btn {
377
142
  position: relative;
@@ -27,7 +27,6 @@
27
27
  @import './components/radio-group.css';
28
28
  @import './components/sample-legend.css';
29
29
  @import './components/select.css';
30
- @import './components/settings-button.css';
31
30
  @import './components/skeleton.css';
32
31
  @import './components/slider.css';
33
32
  @import './components/tabs.css';
@@ -62,6 +62,16 @@ export interface BioTemplateComponentPropsBinding extends BioTemplateComponentBi
62
62
  propsObject: Record<string, unknown>
63
63
  }
64
64
 
65
+ export interface BioTemplateResolvedComponentBinding extends Omit<BioTemplateComponentBinding, 'props'> {
66
+ /** Prop names advertised by the static template/component compatibility catalog. */
67
+ propNames: readonly string[]
68
+ /** Concrete props ready for direct `v-bind="componentBindingsById[id].props"` use. */
69
+ props: Record<string, unknown>
70
+ /** Backward-compatible alias for callers that already consume componentProps entries. */
71
+ propsObject: Record<string, unknown>
72
+ }
73
+
74
+ export type BioTemplateComponentBindingsById = Record<string, BioTemplateResolvedComponentBinding>
65
75
  export type BioTemplateComponentPropsById = Record<string, Record<string, unknown>>
66
76
  export type BioTemplateComponentPropsByComponent = Record<string, Record<string, unknown>[]>
67
77
 
@@ -169,6 +179,22 @@ export function toBioTemplateComponentProps(
169
179
  return Object.values(collection).flatMap(template => propsForTemplate(template))
170
180
  }
171
181
 
182
+ /** Return resolved component bindings with concrete props for direct slot rendering. */
183
+ export function toBioTemplateComponentBindings(
184
+ target: BioTemplateEnvelope<unknown> | TemplateCollectionEnvelope,
185
+ ): BioTemplateResolvedComponentBinding[] {
186
+ return toBioTemplateComponentProps(target).map(toResolvedComponentBinding)
187
+ }
188
+
189
+ /** Return resolved component bindings keyed by stable template component id. */
190
+ export function toBioTemplateComponentBindingsById(
191
+ target: BioTemplateEnvelope<unknown> | TemplateCollectionEnvelope,
192
+ ): BioTemplateComponentBindingsById {
193
+ return Object.fromEntries(
194
+ toBioTemplateComponentBindings(target).map(binding => [binding.id, binding]),
195
+ )
196
+ }
197
+
172
198
  /** Return component props keyed by stable binding id for direct `v-bind="componentPropsById[id]"` use. */
173
199
  export function toBioTemplateComponentPropsById(
174
200
  target: BioTemplateEnvelope<unknown> | TemplateCollectionEnvelope,
@@ -205,6 +231,18 @@ export function getBioTemplateComponentProps(
205
231
  })?.propsObject
206
232
  }
207
233
 
234
+ function toResolvedComponentBinding(
235
+ binding: BioTemplateComponentPropsBinding,
236
+ ): BioTemplateResolvedComponentBinding {
237
+ const { props: propNames, propsObject, ...rest } = binding
238
+ return {
239
+ ...rest,
240
+ propNames,
241
+ props: propsObject,
242
+ propsObject,
243
+ }
244
+ }
245
+
208
246
  export function toBioTemplateComponentImports(
209
247
  target: BioTemplateComponentTarget
210
248
  ): BioTemplateComponentImport[] {
@@ -71,6 +71,8 @@ export {
71
71
  getBioTemplateComponentProps,
72
72
  getBioTemplateComponentBindings,
73
73
  listBioTemplateComponentBindings,
74
+ toBioTemplateComponentBindings,
75
+ toBioTemplateComponentBindingsById,
74
76
  toBioTemplateComponentImports,
75
77
  toBioTemplateComponentProps,
76
78
  toBioTemplateComponentPropsByComponent,
@@ -80,6 +82,7 @@ export {
80
82
  } from './componentBindings'
81
83
 
82
84
  export type {
85
+ BioTemplateComponentBindingsById,
83
86
  BioTemplateComponentPropsByComponent,
84
87
  BioTemplateComponentPropsById,
85
88
  BioTemplateComponentPropsLookupOptions,
@@ -293,6 +296,7 @@ export type {
293
296
  BioTemplateComponentBinding,
294
297
  BioTemplateComponentImport,
295
298
  BioTemplateComponentPropsBinding,
299
+ BioTemplateResolvedComponentBinding,
296
300
  BioTemplateComponentSnippet,
297
301
  BioTemplateComponentSnippetOptions,
298
302
  BioTemplateComponentTarget,
@@ -89,31 +89,7 @@ export interface CollapsibleState {
89
89
  // TopBar types
90
90
  export type TopBarVariant = 'card' | 'default'
91
91
 
92
- // TopBar page navigation types
93
- export interface TopBarPage {
94
- id: string
95
- label: string
96
- to?: string // vue-router path
97
- href?: string // External link
98
- icon?: string // Optional icon
99
- description?: string // Optional subtitle in dropdown
100
- disabled?: boolean
101
- }
102
-
103
- export type TopBarPageInput = TopBarPage | string
104
-
105
- // TopBar tab types (displayed in middle of topbar)
106
- export interface TopBarTab {
107
- id: string
108
- label: string
109
- to?: string // vue-router path
110
- href?: string // External link
111
- icon?: string // Optional icon
112
- disabled?: boolean
113
- children?: TopBarTabOption[] // Dropdown options
114
- }
115
-
116
- export interface TopBarTabOption {
92
+ export interface PillNavOption {
117
93
  id: string
118
94
  label: string
119
95
  to?: string
@@ -122,11 +98,7 @@ export interface TopBarTabOption {
122
98
  disabled?: boolean
123
99
  }
124
100
 
125
- export type TopBarTabOptionInput = TopBarTabOption | string
126
-
127
- export type TopBarTabInput = (Omit<TopBarTab, 'children'> & {
128
- children?: TopBarTabOptionInput[]
129
- }) | string
101
+ export type PillNavOptionInput = PillNavOption | string
130
102
 
131
103
  // TopBar settings config (pass-through for built-in SettingsModal)
132
104
  export interface TopBarSettingsConfig {
@@ -159,9 +131,12 @@ export interface PillNavItem {
159
131
  to?: string
160
132
  href?: string
161
133
  disabled?: boolean
134
+ children?: PillNavOption[]
162
135
  }
163
136
 
164
- export type PillNavItemInput = PillNavItem | string
137
+ export type PillNavItemInput = (Omit<PillNavItem, 'children'> & {
138
+ children?: PillNavOptionInput[]
139
+ }) | string
165
140
 
166
141
  // TopBar page selector items (left-side "go to page" dropdown)
167
142
  export interface PageSelectorItem {
@@ -19,13 +19,9 @@ export type {
19
19
  SidebarToolSection,
20
20
  CollapsibleState,
21
21
  TopBarVariant,
22
- TopBarPage,
23
- TopBarPageInput,
24
- TopBarTab,
25
- TopBarTabInput,
26
- TopBarTabOption,
27
- TopBarTabOptionInput,
28
22
  TopBarSettingsConfig,
23
+ PillNavOption,
24
+ PillNavOptionInput,
29
25
  PillNavItem,
30
26
  PillNavItemInput,
31
27
  PageSelectorItem,
@@ -1,13 +0,0 @@
1
- /**
2
- * Tests for usePluginApi.
3
- *
4
- * Exercises the baseUrl resolution priority that every plugin relies on:
5
- * 1. VITE_API_PREFIX (build-time env override)
6
- * 2. fallbackPrefix option (plugin's route prefix)
7
- * 3. '/api' default
8
- *
9
- * The SDK-wide axios client is a singleton, so these tests stub axios
10
- * with a MockAdapter-style approach via vi.spyOn to observe the
11
- * baseURL actually used at request time.
12
- */
13
- export {};
@@ -1,28 +0,0 @@
1
- import { FormFieldSchema } from '../types/form-builder';
2
- import { UseFormReturn } from '../composables/useForm';
3
- interface Props {
4
- field: FormFieldSchema;
5
- resolvedProps: Record<string, unknown>;
6
- form: UseFormReturn<Record<string, unknown>>;
7
- }
8
- declare function __VLS_template(): {
9
- attrs: Partial<{}>;
10
- slots: Readonly<{
11
- [name: string]: ((props: Record<string, unknown>) => unknown) | undefined;
12
- '`field:${field.name}`'?: (props: Record<string, unknown>) => unknown;
13
- }> & {
14
- [name: string]: ((props: Record<string, unknown>) => unknown) | undefined;
15
- '`field:${field.name}`'?: (props: Record<string, unknown>) => unknown;
16
- };
17
- refs: {};
18
- rootEl: HTMLDivElement;
19
- };
20
- type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
21
- declare const __VLS_component: import('vue').DefineComponent<Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
22
- declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
23
- export default _default;
24
- type __VLS_WithTemplateSlots<T, S> = T & {
25
- new (): {
26
- $slots: S;
27
- };
28
- };