|
1 | 1 | <script setup lang="ts"> |
2 | 2 | import { useColorMode, useDebounceFn } from '@vueuse/core' |
| 3 | +import { useFuse } from '@vueuse/integrations/useFuse' |
3 | 4 | import type { ComponentMeta, CompodiumHooks } from '#module/types' |
4 | 5 | import type { PropertyMeta } from 'vue-component-meta' |
5 | 6 | import { camelCase, pascalCase } from 'scule' |
@@ -136,6 +137,19 @@ function onResetState() { |
136 | 137 | props.value = { ...defaultProps.value, ...compodiumDefaultProps.value } |
137 | 138 | updateRendererDebounced() |
138 | 139 | } |
| 140 | +
|
| 141 | +const componentProps = computed(() => componentMeta.value?.meta?.props ?? []) |
| 142 | +
|
| 143 | +const propsSearchTerm = ref() |
| 144 | +const { results: fuseResults } = useFuse<PropertyMeta>(propsSearchTerm, componentProps, { |
| 145 | + fuseOptions: { |
| 146 | + ignoreLocation: true, |
| 147 | + threshold: 0.1, |
| 148 | + keys: ['name', 'description'] |
| 149 | + }, |
| 150 | + matchAllWhenSearchEmpty: true |
| 151 | +}) |
| 152 | +const visibleProps = computed(() => new Set(fuseResults.value?.map(result => result.item.name))) |
139 | 153 | </script> |
140 | 154 |
|
| 141 | 155 | <template> |
@@ -173,29 +187,40 @@ function onResetState() { |
173 | 187 | <UTabs |
174 | 188 | variant="link" |
175 | 189 | :items="tabs" |
176 | | - class="relative h-screen flex flex-col overflow-y-scroll gap-0" |
177 | | - :ui="{ list: 'sticky top-0 bg-(--ui-bg) border-b border-(--ui-border) z-50', content: 'grow' }" |
| 190 | + class="h-screen flex flex-col gap-0" |
| 191 | + :ui="{ content: 'grow relative overflow-y-scroll' }" |
178 | 192 | > |
179 | 193 | <template #props> |
180 | | - <div |
181 | | - v-for="prop in componentMeta?.meta.props" |
182 | | - :key="componentMeta.componentId + '-prop-' + prop.name" |
183 | | - class="px-3 py-2 border-b border-(--ui-border)" |
184 | | - > |
185 | | - <ComponentPropInput |
186 | | - v-model="props[prop.name]" |
187 | | - :schema="prop.schema" |
188 | | - :name="prop.name" |
189 | | - :description="prop.description" |
190 | | - class="p-4 rounded" |
191 | | - @update:model-value="updateRendererDebounced" |
192 | | - /> |
| 194 | + <div class="overflow-y-scroll h-full"> |
| 195 | + <div class="bg-(--ui-bg) p-0.5 border-y border-(--ui-border) sticky top-0 z-1"> |
| 196 | + <UInput |
| 197 | + v-model="propsSearchTerm" |
| 198 | + placeholder="Search props..." |
| 199 | + trailing-icon="lucide:search" |
| 200 | + variant="none" |
| 201 | + class="w-full" |
| 202 | + /> |
| 203 | + </div> |
| 204 | + <div |
| 205 | + v-for="prop in componentMeta?.meta.props" |
| 206 | + v-show="visibleProps.has(prop.name)" |
| 207 | + :key="componentMeta.componentId + '-prop-' + prop.name" |
| 208 | + class="grow px-3 py-2 border-b border-(--ui-border)" |
| 209 | + > |
| 210 | + <ComponentPropInput |
| 211 | + v-model="props[prop.name]" |
| 212 | + :schema="prop.schema" |
| 213 | + :name="prop.name" |
| 214 | + :description="prop.description" |
| 215 | + class="p-4 rounded" |
| 216 | + @update:model-value="updateRendererDebounced" |
| 217 | + /> |
| 218 | + </div> |
193 | 219 | </div> |
194 | 220 | </template> |
195 | 221 |
|
196 | 222 | <template #code> |
197 | 223 | <ComponentCode |
198 | | - class="" |
199 | 224 | :component="componentMeta" |
200 | 225 | :example="exampleId" |
201 | 226 | :props="props" |
|
0 commit comments