Navbar sizeVue demo works fine 1`] = `
data-v-5f535116=""
style="position: relative;"
>
-
+
@@ -1383,7 +1383,7 @@ exports[`Navbar > Navbar sizeVue demo works fine 1`] = `
/>
-
+
Navbar sizeVue demo works fine 1`] = `
data-v-5f535116=""
style="position: relative;"
>
-
+
@@ -1436,7 +1436,7 @@ exports[`Navbar > Navbar sizeVue demo works fine 1`] = `
/>
-
+
events > left-click 1`] = `
-
+
-
+
events > left-click 1`] = `
标题
-
+
h(TIconApp);
@@ -9,10 +9,10 @@ describe('navbar', () => {
describe('props', () => {
it('fixed', async () => {
const navbar = mount(
);
- expect(navbar.vm.navStyle).toContain('position: fixed');
+ expect(navbar.element.style.position).toBe('fixed')
await navbar.setProps({ fixed: false });
- expect(navbar.vm.navStyle).toContain('position: relative');
+ expect(navbar.element.style.position).toBe('relative')
});
it('leftArrow', () => {
diff --git a/src/navbar/index.ts b/src/navbar/index.ts
index 023dc382b..38f536113 100644
--- a/src/navbar/index.ts
+++ b/src/navbar/index.ts
@@ -1,4 +1,4 @@
-import Navbar from './navbar.vue';
+import Navbar from './navbar';
import { withInstall, WithInstallType } from '../shared';
import './style';
diff --git a/src/navbar/navbar.tsx b/src/navbar/navbar.tsx
new file mode 100644
index 000000000..c34493bb2
--- /dev/null
+++ b/src/navbar/navbar.tsx
@@ -0,0 +1,96 @@
+import { defineComponent, computed } from 'vue';
+import { ChevronLeftIcon as TChevronLeftIcon } from 'tdesign-icons-vue-next';
+import config from '../config';
+import props from './props';
+import { usePrefixClass } from '@/hooks/useClass';
+import { useTNodeJSX } from '@/hooks/tnode';
+
+const { prefix } = config;
+const name = `${prefix}-navbar`;
+
+export default defineComponent({
+ name,
+ components: { TChevronLeftIcon },
+ props,
+ emits: ['left-click', 'right-click'],
+ setup(props, { slots }) {
+ const navbarClass = usePrefixClass('navbar');
+ const renderTNodeJSX = useTNodeJSX();
+
+ const animationSuffix = computed(() => (props.animation ? '-animation' : ''));
+ const navClass = computed(() => [
+ navbarClass.value,
+ {
+ [`${navbarClass.value}--fixed`]: props.fixed,
+ },
+ props.visible
+ ? `${navbarClass.value}--visible${animationSuffix.value}`
+ : `${navbarClass.value}--hide${animationSuffix.value}`,
+ ]);
+
+ const navStyle = computed(() => `position: ${props.fixed ? 'fixed' : 'relative'};`);
+
+ const handleLeftClick = () => {
+ props.onLeftClick?.();
+ };
+
+ const handleRightClick = () => {
+ props.onRightClick?.();
+ };
+
+ return () => {
+ const { fixed, titleMaxLength, title, leftArrow } = props;
+
+ const renderRightContent = () => {
+ const rightContent = renderTNodeJSX('right');
+ if (!rightContent) {
+ return null;
+ }
+ return (
+
+ {rightContent}
+
+ );
+ };
+
+ const renderCapsuleContent = () => {
+ const capsuleContent = renderTNodeJSX('capsule');
+ if (!capsuleContent) {
+ return null;
+ }
+ return
{capsuleContent}
;
+ };
+
+ const renderTitleContent = () => {
+ const isStringTitle = typeof title === 'string' && !slots.title;
+ let titleContent = renderTNodeJSX('title');
+ if (!titleContent) {
+ return null;
+ }
+ if (titleMaxLength != null && title) {
+ if (titleMaxLength <= 0) {
+ console.warn('titleMaxLength must be greater than 0');
+ } else {
+ titleContent = title.length <= titleMaxLength ? title : `${(title as string).slice(0, titleMaxLength)}...`;
+ }
+ }
+
+ return isStringTitle ?
{titleContent} : titleContent;
+ };
+ return (
+
+ {fixed &&
}
+
+
+ {leftArrow && }
+ {renderTNodeJSX('left')}
+ {renderCapsuleContent()}
+
+
{renderTitleContent()}
+ {renderRightContent()}
+
+
+ );
+ };
+ },
+});
diff --git a/src/navbar/navbar.vue b/src/navbar/navbar.vue
deleted file mode 100644
index 171703dec..000000000
--- a/src/navbar/navbar.vue
+++ /dev/null
@@ -1,95 +0,0 @@
-
-
-
-
-
-
- {{ titleContent }}
-
-
-
-
-
-
-
-
-
-