@@ -18,6 +17,7 @@
:never-empty="true"
:capitalize="true"
:disabled="isUploading"
+ hide-checkmark-icon
/>
@@ -61,25 +61,21 @@
diff --git a/packages/ui/src/components/base/index.ts b/packages/ui/src/components/base/index.ts
index f27ee0e2e..14f5382e3 100644
--- a/packages/ui/src/components/base/index.ts
+++ b/packages/ui/src/components/base/index.ts
@@ -79,6 +79,8 @@ export { default as StatItem } from './StatItem.vue'
export { default as StyledInput } from './StyledInput.vue'
export type { TableColumn } from './Table.vue'
export { default as Table } from './Table.vue'
+export type { TabsTab, TabsValue } from './Tabs.vue'
+export { default as Tabs } from './Tabs.vue'
export { default as TagItem } from './TagItem.vue'
export { default as TagTagItem } from './TagTagItem.vue'
export { default as Timeline } from './Timeline.vue'
diff --git a/packages/ui/src/stories/base/Combobox.stories.ts b/packages/ui/src/stories/base/Combobox.stories.ts
index 63dcd80fd..9fa6e693d 100644
--- a/packages/ui/src/stories/base/Combobox.stories.ts
+++ b/packages/ui/src/stories/base/Combobox.stories.ts
@@ -43,6 +43,24 @@ export const Searchable: Story = {
],
searchable: true,
searchPlaceholder: 'Search loaders...',
+ selectSearchTextOnFocus: true,
+ },
+}
+
+export const SearchableEmpty: Story = {
+ args: {
+ options: [],
+ searchable: true,
+ searchPlaceholder: 'Search projects...',
+ noOptionsMessage: 'No projects found',
+ },
+ parameters: {
+ docs: {
+ description: {
+ story:
+ 'Covers the idle empty searchable state: focusing the input should not open an empty dropdown until there is a query or footer content.',
+ },
+ },
},
}
diff --git a/packages/ui/src/stories/base/Tabs.stories.ts b/packages/ui/src/stories/base/Tabs.stories.ts
new file mode 100644
index 000000000..b15c9a34d
--- /dev/null
+++ b/packages/ui/src/stories/base/Tabs.stories.ts
@@ -0,0 +1,50 @@
+import { ChartIcon, DownloadIcon, UsersIcon } from '@modrinth/assets'
+import type { Meta, StoryObj } from '@storybook/vue3-vite'
+import { ref } from 'vue'
+
+import Tabs from '../../components/base/Tabs.vue'
+
+const meta = {
+ title: 'Base/Tabs',
+ component: Tabs,
+} satisfies Meta
+
+export default meta
+
+export const Default: StoryObj = {
+ render: () => ({
+ components: { Tabs },
+ setup() {
+ const value = ref('area')
+ const tabs = [
+ { value: 'line', label: 'Line' },
+ { value: 'area', label: 'Area' },
+ { value: 'bar', label: 'Bar' },
+ ]
+
+ return { value, tabs }
+ },
+ template: /* html */ `
+
+ `,
+ }),
+}
+
+export const WithIcons: StoryObj = {
+ render: () => ({
+ components: { Tabs },
+ setup() {
+ const value = ref('downloads')
+ const tabs = [
+ { value: 'overview', label: 'Overview', icon: ChartIcon },
+ { value: 'downloads', label: 'Downloads', icon: DownloadIcon },
+ { value: 'users', label: 'Users', icon: UsersIcon },
+ ]
+
+ return { value, tabs }
+ },
+ template: /* html */ `
+
+ `,
+ }),
+}