list.vue 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. <script setup lang="ts">
  2. import { UserOutlined } from '@ant-design/icons-vue';
  3. import { BubbleList } from 'ant-design-x-vue';
  4. import { Button, Flex, Switch } from 'ant-design-vue';
  5. import type { BubbleListProps, BubbleProps } from 'ant-design-x-vue';
  6. import type { SwitchProps } from 'ant-design-vue';
  7. import { ref, h } from 'vue';
  8. defineOptions({ name: 'AXBubbleListSetup' });
  9. const rolesAsObject: BubbleListProps['roles'] = {
  10. ai: {
  11. placement: 'start',
  12. avatar: { icon: h(UserOutlined), style: { background: '#fde3cf' } },
  13. typing: { step: 5, interval: 20 },
  14. style: {
  15. maxWidth: '600px',
  16. },
  17. },
  18. user: {
  19. placement: 'end',
  20. avatar: { icon: h(UserOutlined), style: { background: '#87d068' } },
  21. },
  22. };
  23. const rolesAsFunction = (bubbleData: BubbleProps, index: number) => {
  24. const RenderIndex: BubbleProps['messageRender'] = (content) =>
  25. h(Flex, null, [h('text', null, `#${index}: ${content}`)]);
  26. switch (bubbleData.role) {
  27. case 'ai':
  28. return {
  29. placement: 'start' as const,
  30. avatar: { icon: h(UserOutlined), style: { background: '#fde3cf' } },
  31. typing: { step: 5, interval: 20 },
  32. style: {
  33. maxWidth: 600,
  34. },
  35. messageRender: RenderIndex,
  36. };
  37. case 'user':
  38. return {
  39. placement: 'end' as const,
  40. avatar: { icon: h(UserOutlined), style: { background: '#87d068' } },
  41. messageRender: RenderIndex,
  42. };
  43. default:
  44. return { messageRender: RenderIndex };
  45. }
  46. };
  47. const count = ref<number>(3);
  48. const useRolesAsFunction = ref(false);
  49. // const listRef = useTemplateRef<InstanceType<typeof BubbleList>>(null);
  50. const listRef = ref<InstanceType<typeof BubbleList>>(null);
  51. const handleChange = (checked: SwitchProps['checked']) => {
  52. useRolesAsFunction.value = checked as boolean;
  53. };
  54. </script>
  55. <template>
  56. <Flex vertical gap="small">
  57. <Flex gap="large" align="center">
  58. Use roles as:
  59. <Switch
  60. :checked="useRolesAsFunction"
  61. @change="handleChange"
  62. checkedChildren="Function"
  63. unCheckedChildren="Object"
  64. />
  65. </Flex>
  66. <Flex gap="small" :style="{ alignSelf: 'flex-end' }">
  67. <Button
  68. @click="
  69. () => {
  70. count++;
  71. }
  72. "
  73. >
  74. Add Bubble
  75. </Button>
  76. <Button
  77. @click="
  78. () => {
  79. listRef?.scrollTo({ key: 0, block: 'nearest' });
  80. }
  81. "
  82. >
  83. Scroll To First
  84. </Button>
  85. </Flex>
  86. <BubbleList
  87. ref="listRef"
  88. :style="{ maxHeight: '300px' }"
  89. :roles="useRolesAsFunction ? rolesAsFunction : rolesAsObject"
  90. :items="
  91. Array.from({ length: count }).map((_, i) => {
  92. const isAI = !!(i % 2);
  93. const content = isAI
  94. ? 'Mock AI content. '.repeat(20)
  95. : 'Mock user content.';
  96. return {
  97. key: i,
  98. role: isAI ? 'ai' : 'user',
  99. content,
  100. };
  101. })
  102. "
  103. />
  104. </Flex>
  105. </template>