+
+// ============================================
+// All Types Overview
+// ============================================
+
+export const AllTypes: Story = {
+ args: {
+ project: sodiumProject,
+ },
+ render: () => ({
+ components: { ContentCard },
+ setup() {
+ const toggleOn = ref(true)
+ const toggleOff = ref(false)
+
+ const cards = [
+ {
+ label: 'Full featured (all actions)',
+ project: sodiumProject,
+ version: sodiumVersion,
+ owner: sodiumOwner,
+ enabled: toggleOn,
+ hasUpdate: true,
+ hasDelete: true,
+ hasOverflow: true,
+ },
+ {
+ label: 'With toggle only',
+ project: modMenuProject,
+ version: modMenuVersion,
+ owner: { id: 'u2', name: 'Prospector', type: 'user' },
+ enabled: toggleOn,
+ },
+ {
+ label: 'With update available',
+ project: fabricApiProject,
+ version: fabricApiVersion,
+ owner: fabricApiOwner,
+ hasUpdate: true,
+ },
+ {
+ label: 'Minimal (project only)',
+ project: sodiumProject,
+ },
+ {
+ label: 'With version info only',
+ project: modMenuProject,
+ version: modMenuVersion,
+ },
+ {
+ label: 'With owner only',
+ project: fabricApiProject,
+ owner: fabricApiOwner,
+ },
+ {
+ label: 'Disabled state',
+ project: sodiumProject,
+ version: sodiumVersion,
+ owner: sodiumOwner,
+ enabled: toggleOff,
+ disabled: true,
+ },
+ {
+ label: 'Delete button only',
+ project: modMenuProject,
+ version: modMenuVersion,
+ hasDelete: true,
+ },
+ {
+ label: 'Toggle off',
+ project: fabricApiProject,
+ version: fabricApiVersion,
+ owner: fabricApiOwner,
+ enabled: toggleOff,
+ },
+ ]
+
+ return { cards }
+ },
+ template: /*html*/ `
+
+
+ {{ card.label }}
+ {} : undefined"
+ @delete="card.hasDelete ? () => {} : undefined"
+ @update:enabled="card.enabled ? (v) => card.enabled.value = v : undefined"
+ :overflow-options="card.hasOverflow ? [
+ { id: 'view', action: () => {} },
+ { divider: true },
+ { id: 'remove', action: () => {}, color: 'red' },
+ ] : undefined"
+ >
+ View on Modrinth
+ Remove
+
+
+
+ `,
+ }),
+}
+
+// ============================================
+// Basic Stories
+// ============================================
+
+export const Default: Story = {
+ args: {
+ project: sodiumProject,
+ version: sodiumVersion,
+ owner: sodiumOwner,
+ enabled: true,
+ overflowOptions: [
+ { id: 'view', action: () => console.log('View clicked') },
+ { id: 'edit', action: () => console.log('Edit clicked') },
+ { divider: true },
+ { id: 'remove', action: () => console.log('Remove clicked'), color: 'red' },
+ ],
+ onDelete: fn(),
+ onUpdate: fn(),
+ 'onUpdate:enabled': fn(),
+ },
+}
+
+export const MinimalProjectOnly: Story = {
+ args: {
+ project: sodiumProject,
+ },
+}
+
+export const WithVersion: Story = {
+ args: {
+ project: modMenuProject,
+ version: modMenuVersion,
+ },
+}
+
+export const WithUserOwner: Story = {
+ args: {
+ project: sodiumProject,
+ version: sodiumVersion,
+ owner: sodiumOwner,
+ },
+}
+
+export const WithOrganizationOwner: Story = {
+ args: {
+ project: fabricApiProject,
+ version: fabricApiVersion,
+ owner: fabricApiOwner,
+ },
+}
+
+export const WithToggle: Story = {
+ args: {
+ project: sodiumProject,
+ version: sodiumVersion,
+ enabled: true,
+ 'onUpdate:enabled': fn(),
+ },
+}
+
+export const ToggleDisabled: Story = {
+ args: {
+ project: sodiumProject,
+ version: sodiumVersion,
+ enabled: false,
+ 'onUpdate:enabled': fn(),
+ },
+}
+
+// ============================================
+// Action Button Stories
+// ============================================
+
+export const WithDeleteButton: Story = {
+ args: {
+ project: modMenuProject,
+ version: modMenuVersion,
+ owner: sodiumOwner,
+ onDelete: fn(),
+ },
+}
+
+export const WithUpdateButton: Story = {
+ args: {
+ project: fabricApiProject,
+ version: fabricApiVersion,
+ owner: fabricApiOwner,
+ onUpdate: fn(),
+ },
+}
+
+export const WithAllActions: Story = {
+ args: {
+ project: sodiumProject,
+ version: sodiumVersion,
+ owner: sodiumOwner,
+ enabled: true,
+ onDelete: fn(),
+ onUpdate: fn(),
+ 'onUpdate:enabled': fn(),
+ overflowOptions: [
+ { id: 'view', action: () => console.log('View') },
+ { id: 'openFolder', action: () => console.log('Open folder') },
+ { divider: true },
+ { id: 'copyLink', action: () => console.log('Copy link') },
+ ],
+ },
+}
+
+// ============================================
+// State Stories
+// ============================================
+
+export const Disabled: Story = {
+ args: {
+ project: sodiumProject,
+ version: sodiumVersion,
+ owner: sodiumOwner,
+ enabled: false,
+ disabled: true,
+ 'onUpdate:enabled': fn(),
+ },
+}
+
+export const LongProjectName: Story = {
+ args: {
+ project: {
+ id: 'test123',
+ slug: 'very-long-project-name',
+ title: '[EMF] Entity Model Features - The Ultimate Entity Rendering Mod',
+ icon_url: sodiumProject.icon_url,
+ },
+ version: {
+ id: 'v1',
+ version_number: '2.4.1',
+ file_name: 'Entity_model_features_fabric_1.21.1-2.4.1.jar',
+ },
+ owner: {
+ id: 'u1',
+ name: 'Traben',
+ type: 'user',
+ },
+ enabled: true,
+ onDelete: fn(),
+ 'onUpdate:enabled': fn(),
+ },
+}
+
+// ============================================
+// Overflow Menu Stories
+// ============================================
+
+export const WithOverflowMenu: Story = {
+ render: (args) => ({
+ components: { ContentCard, EditIcon, EyeIcon, FolderOpenIcon, LinkIcon },
+ setup() {
+ return { args }
+ },
+ template: /*html*/ `
+
+
+ View on Modrinth
+
+
+ Edit settings
+
+
+ Open folder
+
+
+ Copy link
+
+
+ `,
+ }),
+ args: {
+ project: sodiumProject,
+ version: sodiumVersion,
+ owner: sodiumOwner,
+ overflowOptions: [
+ { id: 'view', action: () => console.log('View') },
+ { id: 'edit', action: () => console.log('Edit') },
+ { id: 'openFolder', action: () => console.log('Open folder') },
+ { divider: true },
+ { id: 'copyLink', action: () => console.log('Copy link') },
+ ],
+ },
+}
+
+// ============================================
+// Slot Stories
+// ============================================
+
+export const WithAdditionalButtons: Story = {
+ render: (args) => ({
+ components: { ContentCard, ButtonStyled, EyeIcon, FolderOpenIcon },
+ setup() {
+ return { args }
+ },
+ template: /*html*/ `
+
+
+
+
+
+
+
+
+
+
+
+
+ `,
+ }),
+ args: {
+ project: modMenuProject,
+ version: modMenuVersion,
+ enabled: true,
+ onDelete: fn(),
+ 'onUpdate:enabled': fn(),
+ },
+}
+
+// ============================================
+// Interactive Stories
+// ============================================
+
+export const InteractiveToggle: Story = {
+ args: {
+ project: sodiumProject,
+ },
+ render: () => ({
+ components: { ContentCard },
+ setup() {
+ const enabled = ref(true)
+ return {
+ enabled,
+ project: sodiumProject,
+ version: sodiumVersion,
+ owner: sodiumOwner,
+ }
+ },
+ template: /*html*/ `
+
+
+
+ Mod is currently: {{ enabled ? 'Enabled' : 'Disabled' }}
+
+
+ `,
+ }),
+}
+
+// ============================================
+// List Stories
+// ============================================
+
+export const ModList: Story = {
+ args: {
+ project: sodiumProject,
+ },
+ render: () => ({
+ components: { ContentCard },
+ setup() {
+ const mods = ref([
+ { project: sodiumProject, version: sodiumVersion, owner: sodiumOwner, enabled: true },
+ {
+ project: modMenuProject,
+ version: modMenuVersion,
+ owner: { id: 'u2', name: 'Prospector', type: 'user' as const },
+ enabled: true,
+ },
+ {
+ project: fabricApiProject,
+ version: fabricApiVersion,
+ owner: fabricApiOwner,
+ enabled: true,
+ },
+ ])
+
+ const handleDelete = (index: number) => {
+ mods.value.splice(index, 1)
+ }
+
+ const handleToggle = (index: number, value: boolean) => {
+ mods.value[index].enabled = value
+ }
+
+ return { mods, handleDelete, handleToggle }
+ },
+ template: /*html*/ `
+
+ handleToggle(index, val)"
+ @delete="() => handleDelete(index)"
+ :overflow-options="[
+ { id: 'view', action: () => console.log('View', mod.project.slug) },
+ { divider: true },
+ { id: 'remove', action: () => handleDelete(index), color: 'red' },
+ ]"
+ >
+ View on Modrinth
+ Remove from instance
+
+
+ `,
+ }),
+}
+
+export const MixedStates: Story = {
+ args: {
+ project: sodiumProject,
+ },
+ render: () => ({
+ components: { ContentCard },
+ setup() {
+ return {
+ sodiumProject,
+ sodiumVersion,
+ sodiumOwner,
+ modMenuProject,
+ modMenuVersion,
+ fabricApiProject,
+ fabricApiVersion,
+ fabricApiOwner,
+ }
+ },
+ template: /*html*/ `
+
+
+ console.log('Update sodium')"
+ @update:enabled="() => {}"
+ @delete="() => {}"
+ />
+
+
+ {}"
+ />
+
+
+
+
+ `,
+ }),
+}
+
+// ============================================
+// Responsive Stories
+// ============================================
+
+export const ResponsiveView: Story = {
+ args: {
+ project: sodiumProject,
+ },
+ render: () => ({
+ components: { ContentCard },
+ setup() {
+ return {
+ project: sodiumProject,
+ version: sodiumVersion,
+ owner: sodiumOwner,
+ }
+ },
+ template: /*html*/ `
+
+
+
Desktop (version info visible)
+
+ {}"
+ @delete="() => {}"
+ @update="() => {}"
+ />
+
+
+
+
Mobile (<768px - version info hidden)
+
+ {}"
+ @delete="() => {}"
+ />
+
+
+
+ `,
+ }),
+}
+
+// ============================================
+// Edge Cases
+// ============================================
+
+export const NoIcon: Story = {
+ args: {
+ project: {
+ id: 'test',
+ slug: 'no-icon-mod',
+ title: 'Mod Without Icon',
+ icon_url: undefined,
+ },
+ version: {
+ id: 'v1',
+ version_number: '1.0.0',
+ file_name: 'no-icon-mod-1.0.0.jar',
+ },
+ enabled: true,
+ 'onUpdate:enabled': fn(),
+ },
+}
+
+export const NoOwnerAvatar: Story = {
+ args: {
+ project: sodiumProject,
+ version: sodiumVersion,
+ owner: {
+ id: 'u1',
+ name: 'Anonymous',
+ avatar_url: undefined,
+ type: 'user',
+ },
+ enabled: true,
+ 'onUpdate:enabled': fn(),
+ },
+}