From 261a263180fc1a0b98dcdc34ae6bfddeb21d25c1 Mon Sep 17 00:00:00 2001 From: ZhangAo Date: Tue, 2 Sep 2025 17:30:58 +0800 Subject: [PATCH] u --- code/base-project/base-vue/package.json | 1 + .../ao-design/src/_styles/theme/index.scss | 4 + .../packages/ao-design/src/button/index.scss | 72 ++++--- .../packages/ao-design/src/button/index.tsx | 58 +++--- .../packages/ao-design/src/icon/index.tsx | 43 ++-- .../packages/ao-design/src/index.scss | 7 + .../packages/ao-design/src/input/index.scss | 168 +++++++++++----- .../packages/ao-design/src/input/index.tsx | 106 +++++++--- code/base-project/base-vue/pnpm-lock.yaml | 187 ++++++++++++++++++ code/base-project/base-vue/src/App.vue | 62 +++--- code/base-project/base-vue/src/main.ts | 1 + code/base-project/base-vue/src/style.scss | 4 +- code/base-project/base-vue/test.html | 121 +++++++++--- 13 files changed, 635 insertions(+), 199 deletions(-) diff --git a/code/base-project/base-vue/package.json b/code/base-project/base-vue/package.json index 09d08fd2..bd8966e7 100644 --- a/code/base-project/base-vue/package.json +++ b/code/base-project/base-vue/package.json @@ -11,6 +11,7 @@ "dependencies": { "@ao/ao-design": "workspace:*", "@iconify/vue": "5.0.0", + "naive-ui": "^2.42.0", "vue": "^3.5.18" }, "devDependencies": { diff --git a/code/base-project/base-vue/packages/ao-design/src/_styles/theme/index.scss b/code/base-project/base-vue/packages/ao-design/src/_styles/theme/index.scss index 44bd9c27..321f235d 100644 --- a/code/base-project/base-vue/packages/ao-design/src/_styles/theme/index.scss +++ b/code/base-project/base-vue/packages/ao-design/src/_styles/theme/index.scss @@ -5,3 +5,7 @@ $primary-color: $default-color !default; $danger-color: #f93920 !default; $warning-color: #fc8800 !default; $success-color: #22c55e !default; + +$input-hover-color: $default-color; +$input-focus-color: $default-color; +$input-focus-shadow: 0 0 0 2px #edf4ff; diff --git a/code/base-project/base-vue/packages/ao-design/src/button/index.scss b/code/base-project/base-vue/packages/ao-design/src/button/index.scss index ce1d8cbd..8622146b 100644 --- a/code/base-project/base-vue/packages/ao-design/src/button/index.scss +++ b/code/base-project/base-vue/packages/ao-design/src/button/index.scss @@ -5,54 +5,69 @@ $btn-prefix: #{$prefix}-btn; $btn-hover-bgcolor: #f4f5f5; $btn-active-bgcolor: #eceded; -/* ====== 通用颜色交互函数(新版写法) ====== */ @function color-hover($color, $amount: 8%) { - $l: color.channel($color, 'lightness', $space: hsl); - @if $l > 50% { - // 亮色:向暗靠近 - @return color.scale($color, $lightness: -$amount); - } @else { - // 暗色:向亮靠近 - @return color.scale($color, $lightness: $amount); - } + @return color.scale($color, $lightness: -$amount); } @function color-active($color, $amount: 12%) { - $l: color.channel($color, 'lightness', $space: hsl); - @if $l > 50% { - @return color.scale($color, $lightness: -$amount); - } @else { - @return color.scale($color, $lightness: $amount); - } + @return color.scale($color, $lightness: -$amount); } .#{$btn-prefix} { display: inline-flex; align-items: center; justify-content: center; - gap: 4px; box-sizing: border-box; + outline: none; + vertical-align: middle; user-select: none; + vertical-align: middle; border-radius: 2px; - border: 1px solid transparent; cursor: pointer; transition: all 0.2s ease; font-weight: 500; + border: 1px solid transparent; + + &-small { + height: 24px; + padding: 0 12px; + font-size: 12px; + } + + &-medium { + height: 28px; + padding: 0 14px; + font-size: 13px; + } + + &-large { + height: 32px; + padding: 0 16px; + font-size: 14px; + } + &-block { width: 100%; } &-icon-left { - margin-right: 4px; display: inline-flex; align-items: center; } + &-icon-right { - margin-left: 4px; display: inline-flex; align-items: center; } + &-icon-left-has-text { + margin-right: 4px; + } + + &-icon-right-has-text { + margin-left: 4px; + } + &:disabled { cursor: not-allowed; opacity: 0.6; @@ -176,23 +191,4 @@ $btn-active-bgcolor: #eceded; } } } - - /* ===== 尺寸 ===== */ - &-small { - height: 24px; - padding: 0 12px; - font-size: 12px; - } - - &-medium { - height: 28px; - padding: 0 14px; - font-size: 12px; - } - - &-large { - height: 32px; - padding: 0 16px; - font-size: 13px; - } } diff --git a/code/base-project/base-vue/packages/ao-design/src/button/index.tsx b/code/base-project/base-vue/packages/ao-design/src/button/index.tsx index 98573f77..89969a49 100644 --- a/code/base-project/base-vue/packages/ao-design/src/button/index.tsx +++ b/code/base-project/base-vue/packages/ao-design/src/button/index.tsx @@ -36,35 +36,39 @@ export default defineComponent({ const map = { small: 14, medium: 16, large: 16 } return map[props.size] }) + const hasContent = !!slots.default?.().length - return () => ( - - ) + {props.iconPosition === 'right' && props.icon && ( + + )} + + ) + } }, }) diff --git a/code/base-project/base-vue/packages/ao-design/src/icon/index.tsx b/code/base-project/base-vue/packages/ao-design/src/icon/index.tsx index a7ff4ff3..b7299371 100644 --- a/code/base-project/base-vue/packages/ao-design/src/icon/index.tsx +++ b/code/base-project/base-vue/packages/ao-design/src/icon/index.tsx @@ -5,29 +5,50 @@ import { getPrefixCls } from '../_utils/getPrefixCls' import './index.scss' export default defineComponent({ - name: 'Icon', + name: 'AIcon', + inheritAttrs: false, props: { icon: { type: String as PropType, required: true }, - width: { type: Number, default: 16 }, - height: { type: Number, default: 16 }, + size: { type: Number, default: 16 }, color: { type: String, default: 'currentColor' }, spin: { type: Boolean, default: false }, rotate: { type: Number, default: 360 }, + onClick: Function as PropType<(e: MouseEvent) => void>, // 明确 MouseEvent 类型 }, - setup(props) { + setup(props, { attrs }) { const prefixCls = getPrefixCls('icon') + + // 安全调用 onClick + const handleClick = (e: MouseEvent) => { + props.onClick?.(e) + // 如果 attrs 上也传了 onClick,做类型断言 + if (attrs.onClick) { + (attrs.onClick as (e: MouseEvent) => void)(e) + } + } + return () => ( - + onClick={handleClick} + > + + ) }, }) diff --git a/code/base-project/base-vue/packages/ao-design/src/index.scss b/code/base-project/base-vue/packages/ao-design/src/index.scss index b54fa760..1415f90d 100644 --- a/code/base-project/base-vue/packages/ao-design/src/index.scss +++ b/code/base-project/base-vue/packages/ao-design/src/index.scss @@ -1,2 +1,9 @@ @use './button/index.scss' as *; @use './input/index.scss' as *; + +input, +button, +select, +textarea { + font-family: 'PingFang SC', 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif; +} diff --git a/code/base-project/base-vue/packages/ao-design/src/input/index.scss b/code/base-project/base-vue/packages/ao-design/src/input/index.scss index e13e4692..f6f620bb 100644 --- a/code/base-project/base-vue/packages/ao-design/src/input/index.scss +++ b/code/base-project/base-vue/packages/ao-design/src/input/index.scss @@ -7,65 +7,139 @@ $input-prefix: #{$prefix}-input; display: flex; align-items: center; width: 100%; + border: 1px solid #ddd; + box-sizing: border-box; - border: 1px solid #d9d9d9; border-radius: 2px; - background-color: #fff; - color: #000000d9; + padding: 0 8px; + transition: - border-color 0.2s, - box-shadow 0.2s; + border cubic-bezier(0.38, 0, 0.24, 1) 0.2s, + box-shadow cubic-bezier(0.38, 0, 0.24, 1) 0.2s, + background-color cubic-bezier(0.38, 0, 0.24, 1) 0.2s; - &:hover:not(&-disabled) { - border-color: $primary-color; + .#{$input-prefix}-input { + width: 100%; + border: none; + outline: none; + background: transparent; + box-sizing: border-box; + padding: 0; + font-size: inherit; + line-height: inherit; + display: flex; + align-items: center; + height: 100%; + + &::placeholder { + color: #999999; + } } - &:focus-within:not(&-disabled) { - border-color: $primary-color; - box-shadow: 0 0 0 1px color.change($primary-color, $alpha: 0.1); + &:hover { + border-color: $input-hover-color; } - &-disabled { - color: #00000040; - background-color: #f5f5f5; - border-color: #d9d9d9; + &:focus-within { + border-color: $input-focus-color; + box-shadow: $input-focus-shadow; + } + + &.#{$input-prefix}-size { + &-small { + height: 24px; + font-size: 12px; + } + + &-medium { + height: 28px; + font-size: 13px; + } + + &-large { + height: 32px; + font-size: 14px; + } + } + + .#{$input-prefix}-align { + &-left { + text-align: left; + } + &-right { + text-align: right; + } + &-center { + text-align: center; + } + } + + .#{$input-prefix}-prefix, + .#{$input-prefix}-suffix { + display: inline-flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + } + + .#{$input-prefix}-prefix { + margin-right: 4px; + } + + .#{$input-prefix}-suffix { + margin-left: 4px; + } + + &.#{$input-prefix}-disabled { + background-color: #fafafc; cursor: not-allowed; + + .#{$input-prefix}-input { + color: #a8a8a8; + } + .#{$input-prefix}-input::placeholder { + color: #a8a8a8; + } + .#{$input-prefix}-prefix, + .#{$input-prefix}-suffix { + color: #a8a8a8; + } + + &:hover, + &:focus-within { + border-color: #ddd; + box-shadow: none; + } } - /* 尺寸变体 */ - &-small { - height: 24px; - font-size: 12px; + &.#{$input-prefix}-readonly { + background-color: #fdfdfd; } - &-medium { - height: 28px; - font-size: 14px; + + .#{$input-prefix}-clear { + cursor: pointer; + transition: color 0.2s; + margin-left: 4px; + + &:hover { + color: red !important; + } } - &-large { - height: 32px; - font-size: 16px; + + .#{$input-prefix}-count { + flex-shrink: 0; + margin-left: 4px; + white-space: nowrap; + } + + .#{$input-prefix}-password-toggle { + display: inline-flex; + align-items: center; + cursor: pointer; + margin-left: 4px; + + .hidden { + display: none; + } } } - -.#{$input-prefix}-inner { - flex: 1; - border: none; - outline: none; - background: transparent; - width: 100%; - height: 100%; - font-family: inherit; - - &::placeholder { - color: #00000040; - } -} - -.#{$input-prefix}-icon { - display: flex; - align-items: center; - justify-content: center; - color: #00000040; - margin: 0 4px; -} - \ No newline at end of file diff --git a/code/base-project/base-vue/packages/ao-design/src/input/index.tsx b/code/base-project/base-vue/packages/ao-design/src/input/index.tsx index 72b618ab..901f2794 100644 --- a/code/base-project/base-vue/packages/ao-design/src/input/index.tsx +++ b/code/base-project/base-vue/packages/ao-design/src/input/index.tsx @@ -1,59 +1,113 @@ import type { PropType } from 'vue' -import { computed, defineComponent, h, ref } from 'vue' +import { computed, defineComponent, ref } from 'vue' import { getPrefixCls } from '../_utils/getPrefixCls' import Icon from '../icon' export default defineComponent({ name: 'AInput', props: { + modelValue: String, size: { type: String as PropType<'small' | 'medium' | 'large'>, default: 'medium', }, + align: { + type: String as PropType<'left' | 'center' | 'right'>, + default: 'left', + }, placeholder: String, disabled: Boolean, + readonly: Boolean, + clearable: Boolean, prefixIcon: String, suffixIcon: String, + showCount: Boolean, + maxlength: Number, + password: Boolean, }, - setup(props, { slots }) { - const inputRef = ref(null) + emits: ['update:modelValue'], + setup(props, { slots, emit }) { const prefixCls = getPrefixCls('input') + const inputValue = ref(props.modelValue || '') - const wrapperCls = computed(() => [ - `${prefixCls}-wrapper`, - `${prefixCls}-wrapper-${props.size}`, - { [`${prefixCls}-wrapper-disabled`]: props.disabled }, - ]) + // 控制密码显示/隐藏 + const showPassword = ref(false) - const iconSizeMap: Record = { small: 12, medium: 14, large: 16 } - - const renderIcon = (slot: any, iconProp?: string) => { - if (slot) - return typeof slot === 'function' ? slot() : slot - if (iconProp) - return h(Icon, { icon: iconProp, width: iconSizeMap[props.size], height: iconSizeMap[props.size] }) - return null + const updateValue = (val: string) => { + if (props.maxlength) + val = val.slice(0, props.maxlength) + inputValue.value = val + emit('update:modelValue', val) } + const countText = computed(() => { + const len = inputValue.value.length + return props.maxlength ? `${len} / ${props.maxlength}` : `${len}` + }) + + const inputType = computed(() => { + if (!props.password) + return 'text' + return showPassword.value ? 'text' : 'password' + }) + return () => ( -
+
{(slots.prefix || props.prefixIcon) && ( - - {renderIcon(slots.prefix, props.prefixIcon)} - +
+ {slots.prefix?.() ?? } +
)} updateValue((e.target as HTMLInputElement).value)} /> - {(slots.suffix || props.suffixIcon) && ( - - {renderIcon(slots.suffix, props.suffixIcon)} - + {props.clearable && inputValue.value && !props.disabled && !props.readonly && ( + updateValue('')} + /> + )} + + {/* 密码切换图标 */} + {props.password && ( +
+ (showPassword.value = true)} + /> + (showPassword.value = false)} + /> +
+ )} + + {(slots.suffix || props.suffixIcon) && !props.password && ( +
+ {slots.suffix?.() ?? } +
+ )} + + {props.showCount && ( + {countText.value} )}
) diff --git a/code/base-project/base-vue/pnpm-lock.yaml b/code/base-project/base-vue/pnpm-lock.yaml index d2880964..4209d950 100644 --- a/code/base-project/base-vue/pnpm-lock.yaml +++ b/code/base-project/base-vue/pnpm-lock.yaml @@ -14,6 +14,9 @@ importers: '@iconify/vue': specifier: 5.0.0 version: 5.0.0(vue@3.5.19(typescript@5.8.3)) + naive-ui: + specifier: ^2.42.0 + version: 2.42.0(vue@3.5.19(typescript@5.8.3)) vue: specifier: ^3.5.18 version: 3.5.19(typescript@5.8.3) @@ -264,6 +267,16 @@ packages: '@clack/prompts@0.11.0': resolution: {integrity: sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw==} + '@css-render/plugin-bem@0.15.14': + resolution: {integrity: sha512-QK513CJ7yEQxm/P3EwsI+d+ha8kSOcjGvD6SevM41neEMxdULE+18iuQK6tEChAWMOQNQPLG/Rw3Khb69r5neg==} + peerDependencies: + css-render: ~0.15.14 + + '@css-render/vue3-ssr@0.15.14': + resolution: {integrity: sha512-//8027GSbxE9n3QlD73xFY6z4ZbHbvrOVB7AO6hsmrEzGbg+h2A09HboUyDgu+xsmj7JnvJD39Irt+2D0+iV8g==} + peerDependencies: + vue: ^3.0.11 + '@dprint/formatter@0.3.0': resolution: {integrity: sha512-N9fxCxbaBOrDkteSOzaCqwWjso5iAe+WJPsHC021JfHNj2ThInPNEF13ORDKta3llq5D1TlclODCvOvipH7bWQ==} @@ -273,6 +286,9 @@ packages: '@dprint/toml@0.6.4': resolution: {integrity: sha512-bZXIUjxr0LIuHWshZr/5mtUkOrnh0NKVZEF6ACojW5z7zkJu7s9sV2mMXm8XQDqN4cJzdHYUYzUyEGdfciaLJA==} + '@emotion/hash@0.8.0': + resolution: {integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==} + '@es-joy/jsdoccomment@0.50.2': resolution: {integrity: sha512-YAdE/IJSpwbOTiaURNCKECdAwqrJuFiZhylmesBcIRawtYKnBR2wxPhoIewMg+Yu+QuYvHfJNReWpoxGBKOChA==} engines: {node: '>=18'} @@ -538,6 +554,9 @@ packages: '@jridgewell/trace-mapping@0.3.30': resolution: {integrity: sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==} + '@juggle/resize-observer@3.4.0': + resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -579,36 +598,42 @@ packages: engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] + libc: [glibc] '@parcel/watcher-linux-arm-musl@2.5.1': resolution: {integrity: sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==} engines: {node: '>= 10.0.0'} cpu: [arm] os: [linux] + libc: [musl] '@parcel/watcher-linux-arm64-glibc@2.5.1': resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] + libc: [glibc] '@parcel/watcher-linux-arm64-musl@2.5.1': resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==} engines: {node: '>= 10.0.0'} cpu: [arm64] os: [linux] + libc: [musl] '@parcel/watcher-linux-x64-glibc@2.5.1': resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] + libc: [glibc] '@parcel/watcher-linux-x64-musl@2.5.1': resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==} engines: {node: '>= 10.0.0'} cpu: [x64] os: [linux] + libc: [musl] '@parcel/watcher-win32-arm64@2.5.1': resolution: {integrity: sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==} @@ -680,56 +705,67 @@ packages: resolution: {integrity: sha512-JWnrj8qZgLWRNHr7NbpdnrQ8kcg09EBBq8jVOjmtlB3c8C6IrynAJSMhMVGME4YfTJzIkJqvSUSVJRqkDnu/aA==} cpu: [arm] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.48.0': resolution: {integrity: sha512-9xu92F0TxuMH0tD6tG3+GtngwdgSf8Bnz+YcsPG91/r5Vgh5LNofO48jV55priA95p3c92FLmPM7CvsVlnSbGQ==} cpu: [arm] os: [linux] + libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.48.0': resolution: {integrity: sha512-NLtvJB5YpWn7jlp1rJiY0s+G1Z1IVmkDuiywiqUhh96MIraC0n7XQc2SZ1CZz14shqkM+XN2UrfIo7JB6UufOA==} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.48.0': resolution: {integrity: sha512-QJ4hCOnz2SXgCh+HmpvZkM+0NSGcZACyYS8DGbWn2PbmA0e5xUk4bIP8eqJyNXLtyB4gZ3/XyvKtQ1IFH671vQ==} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-loongarch64-gnu@4.48.0': resolution: {integrity: sha512-Pk0qlGJnhILdIC5zSKQnprFjrGmjfDM7TPZ0FKJxRkoo+kgMRAg4ps1VlTZf8u2vohSicLg7NP+cA5qE96PaFg==} cpu: [loong64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-ppc64-gnu@4.48.0': resolution: {integrity: sha512-/dNFc6rTpoOzgp5GKoYjT6uLo8okR/Chi2ECOmCZiS4oqh3mc95pThWma7Bgyk6/WTEvjDINpiBCuecPLOgBLQ==} cpu: [ppc64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-gnu@4.48.0': resolution: {integrity: sha512-YBwXsvsFI8CVA4ej+bJF2d9uAeIiSkqKSPQNn0Wyh4eMDY4wxuSp71BauPjQNCKK2tD2/ksJ7uhJ8X/PVY9bHQ==} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.48.0': resolution: {integrity: sha512-FI3Rr2aGAtl1aHzbkBIamsQyuauYtTF9SDUJ8n2wMXuuxwchC3QkumZa1TEXYIv/1AUp1a25Kwy6ONArvnyeVQ==} cpu: [riscv64] os: [linux] + libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.48.0': resolution: {integrity: sha512-Dx7qH0/rvNNFmCcIRe1pyQ9/H0XO4v/f0SDoafwRYwc2J7bJZ5N4CHL/cdjamISZ5Cgnon6iazAVRFlxSoHQnQ==} cpu: [s390x] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.48.0': resolution: {integrity: sha512-GUdZKTeKBq9WmEBzvFYuC88yk26vT66lQV8D5+9TgkfbewhLaTHRNATyzpQwwbHIfJvDJ3N9WJ90wK/uR3cy3Q==} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.48.0': resolution: {integrity: sha512-ao58Adz/v14MWpQgYAb4a4h3fdw73DrDGtaiF7Opds5wNyEQwtO6M9dBh89nke0yoZzzaegq6J/EXs7eBebG8A==} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-win32-arm64-msvc@4.48.0': resolution: {integrity: sha512-kpFno46bHtjZVdRIOxqaGeiABiToo2J+st7Yce+aiAoo1H0xPi2keyQIP04n2JjDVuxBN6bSz9R6RdTK5hIppw==} @@ -761,6 +797,15 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@types/katex@0.16.7': + resolution: {integrity: sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==} + + '@types/lodash-es@4.17.12': + resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} + + '@types/lodash@4.17.20': + resolution: {integrity: sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==} + '@types/mdast@4.0.4': resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} @@ -969,6 +1014,9 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + async-validator@4.2.5: + resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==} + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -1071,14 +1119,28 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + css-render@0.15.14: + resolution: {integrity: sha512-9nF4PdUle+5ta4W5SyZdLCCmFd37uVimSjg1evcTqKJCyvCEEj12WKzOSBNak6r4im4J4iYXKH1OWpUV5LBYFg==} + cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} hasBin: true + csstype@3.0.11: + resolution: {integrity: sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==} + csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + date-fns-tz@3.2.0: + resolution: {integrity: sha512-sg8HqoTEulcbbbVXeg84u5UnlsQa8GS5QXMqjjYIhS4abEVVKIUwe0/l/UhrZdKaL/W5eWZNlbTeEIiOXTcsBQ==} + peerDependencies: + date-fns: ^3.0.0 || ^4.0.0 + + date-fns@3.6.0: + resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} + de-indent@1.0.2: resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} @@ -1359,6 +1421,9 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + evtd@0.2.4: + resolution: {integrity: sha512-qaeGN5bx63s/AXgQo8gj6fBkxge+OoLddLniox5qtLAEY5HSnuSlISXVPxnSae1dWblvTh4/HoMIB+mbMsvZzw==} + exsolve@1.0.7: resolution: {integrity: sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==} @@ -1472,6 +1537,10 @@ packages: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true + highlight.js@11.11.1: + resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==} + engines: {node: '>=12.0.0'} + iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} @@ -1596,6 +1665,9 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} + lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} @@ -1774,6 +1846,11 @@ packages: muggle-string@0.4.1: resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} + naive-ui@2.42.0: + resolution: {integrity: sha512-c7cXR2YgOjgtBadXHwiWL4Y0tpGLAI5W5QzzHksOi22iuHXoSGMAzdkVTGVPE/PM0MSGQ/JtUIzCx2Y0hU0vTQ==} + peerDependencies: + vue: ^3.0.0 + nanoid@3.3.11: resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -1974,6 +2051,9 @@ packages: scule@1.3.0: resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} + seemly@0.3.10: + resolution: {integrity: sha512-2+SMxtG1PcsL0uyhkumlOU6Qo9TAQ/WyH7tthnPIOQB05/12jz9naq6GZ6iZ6ApVsO3rr2gsnTf3++OV63kE1Q==} + semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true @@ -2057,6 +2137,9 @@ packages: resolution: {integrity: sha512-khrZo4buq4qVmsGzS5yQjKe/WsFvV8fGfOjDQN0q4iy9FjRfPWRgTFrU8u1R2iu/SfWLhY9WnCi4Jhdrcbtg+g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + treemate@0.3.11: + resolution: {integrity: sha512-M8RGFoKtZ8dF+iwJfAJTOH/SM4KluKOKRJpjCMhI8bG3qB74zrFoArKZ62ll0Fr3mqkMJiQOmWYkdYgDeITYQg==} + ts-api-utils@2.1.0: resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} engines: {node: '>=18.12'} @@ -2156,6 +2239,11 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + vdirs@0.1.8: + resolution: {integrity: sha512-H9V1zGRLQZg9b+GdMk8MXDN2Lva0zx72MPahDKc30v+DtwKjfyOSXWRIX4t2mhDubM1H09gPhWeth/BJWPHGUw==} + peerDependencies: + vue: ^3.0.11 + vite@7.1.3: resolution: {integrity: sha512-OOUi5zjkDxYrKhTV3V7iKsoS37VUM7v40+HuwEmcrsf11Cdx9y3DIr2Px6liIcZFwt3XSRpQvFpL3WVy7ApkGw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2196,6 +2284,11 @@ packages: yaml: optional: true + vooks@0.2.12: + resolution: {integrity: sha512-iox0I3RZzxtKlcgYaStQYKEzWWGAduMmq+jS7OrNdQo1FgGfPMubGL3uGHOU9n97NIvfFDBGnpSvkWyb/NSn/Q==} + peerDependencies: + vue: ^3.0.0 + vscode-uri@3.1.0: resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} @@ -2219,6 +2312,11 @@ packages: typescript: optional: true + vueuc@0.4.64: + resolution: {integrity: sha512-wlJQj7fIwKK2pOEoOq4Aro8JdPOGpX8aWQhV8YkTW9OgWD2uj2O8ANzvSsIGjx7LTOc7QbS7sXdxHi6XvRnHPA==} + peerDependencies: + vue: ^3.0.11 + webpack-virtual-modules@0.6.2: resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} @@ -2492,12 +2590,22 @@ snapshots: picocolors: 1.1.1 sisteransi: 1.0.5 + '@css-render/plugin-bem@0.15.14(css-render@0.15.14)': + dependencies: + css-render: 0.15.14 + + '@css-render/vue3-ssr@0.15.14(vue@3.5.19(typescript@5.8.3))': + dependencies: + vue: 3.5.19(typescript@5.8.3) + '@dprint/formatter@0.3.0': {} '@dprint/markdown@0.17.8': {} '@dprint/toml@0.6.4': {} + '@emotion/hash@0.8.0': {} + '@es-joy/jsdoccomment@0.50.2': dependencies: '@types/estree': 1.0.8 @@ -2699,6 +2807,8 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@juggle/resize-observer@3.4.0': {} + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -2858,6 +2968,14 @@ snapshots: '@types/json-schema@7.0.15': {} + '@types/katex@0.16.7': {} + + '@types/lodash-es@4.17.12': + dependencies: + '@types/lodash': 4.17.20 + + '@types/lodash@4.17.20': {} + '@types/mdast@4.0.4': dependencies: '@types/unist': 3.0.3 @@ -3138,6 +3256,8 @@ snapshots: argparse@2.0.1: {} + async-validator@4.2.5: {} + balanced-match@1.0.2: {} binary-extensions@2.3.0: {} @@ -3236,10 +3356,23 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + css-render@0.15.14: + dependencies: + '@emotion/hash': 0.8.0 + csstype: 3.0.11 + cssesc@3.0.0: {} + csstype@3.0.11: {} + csstype@3.1.3: {} + date-fns-tz@3.2.0(date-fns@3.6.0): + dependencies: + date-fns: 3.6.0 + + date-fns@3.6.0: {} + de-indent@1.0.2: {} debug@4.4.1: @@ -3609,6 +3742,8 @@ snapshots: esutils@2.0.3: {} + evtd@0.2.4: {} + exsolve@1.0.7: {} fast-deep-equal@3.1.3: {} @@ -3698,6 +3833,8 @@ snapshots: he@1.2.0: {} + highlight.js@11.11.1: {} + iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 @@ -3807,6 +3944,8 @@ snapshots: dependencies: p-locate: 5.0.0 + lodash-es@4.17.21: {} + lodash.merge@4.6.2: {} lodash@4.17.21: {} @@ -4171,6 +4310,29 @@ snapshots: muggle-string@0.4.1: {} + naive-ui@2.42.0(vue@3.5.19(typescript@5.8.3)): + dependencies: + '@css-render/plugin-bem': 0.15.14(css-render@0.15.14) + '@css-render/vue3-ssr': 0.15.14(vue@3.5.19(typescript@5.8.3)) + '@types/katex': 0.16.7 + '@types/lodash': 4.17.20 + '@types/lodash-es': 4.17.12 + async-validator: 4.2.5 + css-render: 0.15.14 + csstype: 3.1.3 + date-fns: 3.6.0 + date-fns-tz: 3.2.0(date-fns@3.6.0) + evtd: 0.2.4 + highlight.js: 11.11.1 + lodash: 4.17.21 + lodash-es: 4.17.21 + seemly: 0.3.10 + treemate: 0.3.11 + vdirs: 0.1.8(vue@3.5.19(typescript@5.8.3)) + vooks: 0.2.12(vue@3.5.19(typescript@5.8.3)) + vue: 3.5.19(typescript@5.8.3) + vueuc: 0.4.64(vue@3.5.19(typescript@5.8.3)) + nanoid@3.3.11: {} natural-compare@1.4.0: {} @@ -4370,6 +4532,8 @@ snapshots: scule@1.3.0: {} + seemly@0.3.10: {} + semver@5.7.2: optional: true @@ -4439,6 +4603,8 @@ snapshots: dependencies: eslint-visitor-keys: 3.4.3 + treemate@0.3.11: {} + ts-api-utils@2.1.0(typescript@5.8.3): dependencies: typescript: 5.8.3 @@ -4557,6 +4723,11 @@ snapshots: util-deprecate@1.0.2: {} + vdirs@0.1.8(vue@3.5.19(typescript@5.8.3)): + dependencies: + evtd: 0.2.4 + vue: 3.5.19(typescript@5.8.3) + vite@7.1.3(@types/node@24.3.0)(less@4.4.1)(sass@1.90.0)(tsx@4.20.5)(yaml@2.8.1): dependencies: esbuild: 0.25.9 @@ -4573,6 +4744,11 @@ snapshots: tsx: 4.20.5 yaml: 2.8.1 + vooks@0.2.12(vue@3.5.19(typescript@5.8.3)): + dependencies: + evtd: 0.2.4 + vue: 3.5.19(typescript@5.8.3) + vscode-uri@3.1.0: {} vue-eslint-parser@10.2.0(eslint@9.34.0): @@ -4603,6 +4779,17 @@ snapshots: optionalDependencies: typescript: 5.8.3 + vueuc@0.4.64(vue@3.5.19(typescript@5.8.3)): + dependencies: + '@css-render/vue3-ssr': 0.15.14(vue@3.5.19(typescript@5.8.3)) + '@juggle/resize-observer': 3.4.0 + css-render: 0.15.14 + evtd: 0.2.4 + seemly: 0.3.10 + vdirs: 0.1.8(vue@3.5.19(typescript@5.8.3)) + vooks: 0.2.12(vue@3.5.19(typescript@5.8.3)) + vue: 3.5.19(typescript@5.8.3) + webpack-virtual-modules@0.6.2: {} which@2.0.2: diff --git a/code/base-project/base-vue/src/App.vue b/code/base-project/base-vue/src/App.vue index 71ebab53..dbddb1cd 100644 --- a/code/base-project/base-vue/src/App.vue +++ b/code/base-project/base-vue/src/App.vue @@ -1,31 +1,47 @@