|
1 | | -import { EditIcon, TrashIcon } from '@modrinth/assets' |
| 1 | +import { EditIcon, MoreVerticalIcon, TrashIcon } from '@modrinth/assets' |
2 | 2 | import type { Meta, StoryObj } from '@storybook/vue3-vite' |
3 | 3 | import { ref } from 'vue' |
4 | 4 | import Badge from '../../components/base/Badge.vue' |
5 | 5 | import ButtonStyled from '../../components/base/ButtonStyled.vue' |
| 6 | +import OverflowMenu from '../../components/base/OverflowMenu.vue' |
6 | 7 | import Table from '../../components/base/Table.vue' |
7 | 8 |
|
8 | 9 | interface User { |
@@ -365,3 +366,89 @@ export const FullFeatured: StoryObj = { |
365 | 366 | `, |
366 | 367 | }), |
367 | 368 | } |
| 369 | + |
| 370 | +export const WithOverflowMenu: StoryObj = { |
| 371 | + args: {}, |
| 372 | + render: () => ({ |
| 373 | + components: { Table, Badge, ButtonStyled, OverflowMenu, MoreVerticalIcon, EditIcon, TrashIcon }, |
| 374 | + setup() { |
| 375 | + const columns = [ |
| 376 | + { key: 'name', label: 'Name' }, |
| 377 | + { key: 'email', label: 'Email' }, |
| 378 | + { key: 'status', label: 'Status', align: 'center' as const, width: '20%' }, |
| 379 | + { key: 'role', label: 'Role' }, |
| 380 | + { key: 'actions', label: '', width: '48px' }, |
| 381 | + ] |
| 382 | + const data = sampleUsers |
| 383 | + |
| 384 | + const statusColor = (status: string) => { |
| 385 | + switch (status) { |
| 386 | + case 'active': |
| 387 | + return 'green' |
| 388 | + case 'inactive': |
| 389 | + return 'red' |
| 390 | + case 'pending': |
| 391 | + return 'orange' |
| 392 | + default: |
| 393 | + return 'gray' |
| 394 | + } |
| 395 | + } |
| 396 | + |
| 397 | + const getMenuOptions = (row: User) => [ |
| 398 | + { |
| 399 | + id: 'edit', |
| 400 | + action: () => alert(`Edit user: ${row.name}`), |
| 401 | + }, |
| 402 | + { |
| 403 | + id: 'duplicate', |
| 404 | + action: () => alert(`Duplicate user: ${row.name}`), |
| 405 | + }, |
| 406 | + { divider: true }, |
| 407 | + { |
| 408 | + id: 'delete', |
| 409 | + color: 'red' as const, |
| 410 | + hoverFilled: true, |
| 411 | + action: () => alert(`Delete user: ${row.name}`), |
| 412 | + }, |
| 413 | + ] |
| 414 | + |
| 415 | + return { columns, data, statusColor, getMenuOptions } |
| 416 | + }, |
| 417 | + template: /* html */ ` |
| 418 | + <Table :columns="columns" :data="data"> |
| 419 | + <template #cell-name="{ value }"> |
| 420 | + <span class="font-semibold">{{ value }}</span> |
| 421 | + </template> |
| 422 | + <template #cell-status="{ value }"> |
| 423 | + <div class="flex justify-center"> |
| 424 | + <Badge :color="statusColor(value)">{{ value }}</Badge> |
| 425 | + </div> |
| 426 | + </template> |
| 427 | + <template #cell-actions="{ row }"> |
| 428 | + <div class="flex justify-end"> |
| 429 | + <ButtonStyled circular type="transparent"> |
| 430 | + <OverflowMenu |
| 431 | + :options="getMenuOptions(row)" |
| 432 | + aria-label="More options" |
| 433 | + > |
| 434 | + <MoreVerticalIcon aria-hidden="true" /> |
| 435 | + <template #edit> |
| 436 | + <EditIcon class="size-4" aria-hidden="true" /> |
| 437 | + Edit |
| 438 | + </template> |
| 439 | + <template #duplicate> |
| 440 | + <EditIcon class="size-4" aria-hidden="true" /> |
| 441 | + Duplicate |
| 442 | + </template> |
| 443 | + <template #delete> |
| 444 | + <TrashIcon class="size-4" aria-hidden="true" /> |
| 445 | + Delete |
| 446 | + </template> |
| 447 | + </OverflowMenu> |
| 448 | + </ButtonStyled> |
| 449 | + </div> |
| 450 | + </template> |
| 451 | + </Table> |
| 452 | + `, |
| 453 | + }), |
| 454 | +} |
0 commit comments