ChatInput.vue 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. <script setup lang="ts">
  2. import { ref } from 'vue';
  3. interface Emits {
  4. (e: 'send', message: string): void;
  5. }
  6. const emit = defineEmits<Emits>();
  7. const userInput = ref('');
  8. async function sendMessage() {
  9. if (!userInput.value.trim()) return;
  10. emit('send', userInput.value);
  11. userInput.value = '';
  12. }
  13. function handleKeyPress(event: KeyboardEvent) {
  14. if (event.key === 'Enter' && !event.shiftKey) {
  15. event.preventDefault();
  16. sendMessage();
  17. }
  18. }
  19. </script>
  20. <template>
  21. <div class="input-area">
  22. <div class="input-container">
  23. <textarea
  24. v-model="userInput"
  25. class="message-input"
  26. placeholder="输入你的问题..."
  27. rows="1"
  28. @keydown="handleKeyPress"
  29. ></textarea>
  30. <button
  31. class="send-button"
  32. @click="sendMessage"
  33. :disabled="!userInput.trim()"
  34. >
  35. <svg width="20" height="20" viewBox="0 0 20 20" fill="none">
  36. <path
  37. d="M2.5 10L17.5 3L10 17.5M2.5 10L10 17.5M2.5 10H10"
  38. stroke="currentColor"
  39. stroke-width="1.5"
  40. stroke-linecap="round"
  41. stroke-linejoin="round"
  42. />
  43. </svg>
  44. </button>
  45. </div>
  46. <div class="input-footer">
  47. <span class="input-hint">Enter 发送,Shift + Enter 换行</span>
  48. </div>
  49. </div>
  50. </template>
  51. <style scoped lang="less">
  52. .input-area {
  53. padding: 16px 24px;
  54. border-top: 1px solid @cb-vscode-panel-border;
  55. background-color: @cb-vscode-editor-background;
  56. transition: background-color 0.3s, border-color 0.3s;
  57. }
  58. .input-container {
  59. display: flex;
  60. gap: 12px;
  61. align-items: flex-end;
  62. background-color: @cb-vscode-input-background;
  63. border: 1px solid @cb-vscode-widget-border;
  64. border-radius: 8px;
  65. padding: 8px;
  66. transition: border-color 0.2s, background-color 0.3s;
  67. }
  68. .input-container:focus-within {
  69. border-color: @cb-accent;
  70. }
  71. .message-input {
  72. flex: 1;
  73. background: transparent;
  74. border: none;
  75. color: @cb-text-primary;
  76. font-size: 14px;
  77. line-height: 1.5;
  78. resize: none;
  79. min-height: 24px;
  80. max-height: 200px;
  81. overflow-y: auto;
  82. font-family: inherit;
  83. transition: color 0.3s;
  84. }
  85. .message-input:focus {
  86. outline: none;
  87. }
  88. .message-input::placeholder {
  89. color: @cb-text-secondary;
  90. }
  91. .send-button {
  92. width: 32px;
  93. height: 32px;
  94. background-color: @cb-accent;
  95. color: white;
  96. border: none;
  97. border-radius: 6px;
  98. display: flex;
  99. align-items: center;
  100. justify-content: center;
  101. cursor: pointer;
  102. transition: background-color 0.2s;
  103. flex-shrink: 0;
  104. }
  105. .send-button:hover:not(:disabled) {
  106. background-color: @cb-accent-light;
  107. }
  108. .send-button:disabled {
  109. opacity: 0.5;
  110. cursor: not-allowed;
  111. }
  112. .input-footer {
  113. margin-top: 8px;
  114. text-align: center;
  115. }
  116. .input-hint {
  117. font-size: 11px;
  118. color: @cb-text-secondary;
  119. }
  120. </style>