apptify 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,204 @@
1
+ # 组件 API 参考
2
+
3
+ 本页按 `src/index.ts` 合并的组件注册表列出当前 **68 个导出组件**,不是未来功能清单。组件名均可换成 kebab-case 模板标签,例如 `AppleOtpInput` 对应 `<apple-otp-input>`。
4
+
5
+ ## 公共约定
6
+
7
+ `secondary` 与 `outline` 都是描边按钮,`ghost` 是纯文字按钮且始终不启用 Ripple。所有 API 可直接从 JavaScript 和普通 Vue `<script>` 使用,TypeScript 不是消费前提。
8
+
9
+ Tabs、TabBar、SegmentedControl、DatePicker 日期/时间页签均不使用 Ripple;保留选中指示器位移与内容切换动画。
10
+
11
+ - `v-model` 表示 `modelValue` + `update:modelValue`;表格、树等命名模型在各行列出。
12
+ - `motion`(下文记为 M)接受 `inherit | auto | full | reduced | none`,默认 `inherit`。全局与系统减少动态效果策略是上限,局部只能进一步收敛。表中未列 M 的静态组件不提供该 prop。
13
+ - 每个输入应提供 `label` 或 `aria-label`。基础表单属性(下文记为 F)为 `label`、`hint`、`error`、`disabled`、`loading`、`required`、M。`error` / `hint` 为字符串,不是校验规则数组。
14
+ - 表单选项类型为 `AppleOption = { label: string; value: string | number; disabled?: boolean }`。数字值不会被基础 Select 强制转成字符串。
15
+ - 内容选项类型为 `AppleItem = { label; value; disabled?; description?; href?; content? }`;`value` 为唯一的 `string | number`。
16
+ - 组件并非 Vuetify 同名组件的透传包装。只依赖这里声明的接口,不假设任意 `v-*` prop、slot 或事件都可直接使用。
17
+
18
+ ## 动效组件 · 2
19
+
20
+ | 组件 | Props | 说明 |
21
+ | --- | --- | --- |
22
+ | `AppleAutoSize` | M;`axis=height`(height/both) | ResizeObserver 测量内容,通过实际像素尺寸连续动画;default slot。 |
23
+ | `AppleTransition` | M;`name=slide-y`(page/slide-x/slide-y/fade)、`mode=out-in`、`appear=true` | Vue Transition 包装,用于局部内容切换;单根 default slot。 |
24
+
25
+ 全局入场使用 `v-apple-entrance="pageKey"` 放在一个页面容器上:首次挂载及 key 改变时整体由下向上 14px,不复制旧页、不执行离场、不改变透明度。不应嵌套应用到同一页面的多层内容。
26
+
27
+ 另提供 `v-apple-ripple` 和 `v-apple-selection`;后者移动到后代 `[data-apple-selected="true"]`,也可传 `{selector}`。全局 none/reduced 与系统减少动态效果限制同样生效。
28
+
29
+ ## 基础组件 · 9
30
+
31
+ | 组件 | 主要 Props | Events / Slots / 说明 |
32
+ | --- | --- | --- |
33
+ | `AppleProvider` | `theme?: string`、`motion?: auto/full/reduced/none` | default slot;应用主题并自动挂载弹层宿主。无显式属性时复用插件上下文。 |
34
+ | `AppleButton` | M;`variant=primary`(primary/secondary/outline/ghost/danger)、`size=medium`(small/medium/large)、`icon: Component`、`iconOnly`、`label`、`disabled`、`loading`、`ripple=true`、`href`、`type=button` | `click(event)`;default slot。纯图标按钮须提供 label。只有允许完整动效时启用 Ripple。 |
35
+ | `AppleLink` | `href`、`external`、`disabled` | default slot;external 使用新窗口并设置 `noopener noreferrer`。 |
36
+ | `AppleCard` | M;`title`、`subtitle`、`text`、`eyebrow`、`icon: Component 或图片 URL`、`iconColor`、`image`、`imageAlt`、`href`、`zoom=small`(big/small/none)、`shadow=normal`(normal/static/focused/none) | default、media、icon、title、actions slots;href 为标题链接,不会把所有嵌套控件变成一个大按钮。 |
37
+ | `AppleImage` | M;必填 `src`、`alt`;`preview=true`、`gallery: string[]`、`index=0`、`squared`、`aspectRatio='4/3'`、`fit=cover`(cover/contain) | caption slot;默认点击预览;图片错误状态;squared 覆盖 aspectRatio。 |
38
+ | `AppleSearch` | `v-model: string`、`placeholder='搜索'`、`label='搜索'`、`disabled` | `search(value)` 在 Enter 时发出;清空更新 model。 |
39
+ | `AppleContainer` | `width=1200`(number/string) | default slot;数字宽度按 px,宽度不会超过可用空间。 |
40
+ | `AppleStack` | `direction=column`、`gap=16`、`align=stretch`、`wrap=true` | default slot;Flex 布局;数字 gap 按 px。 |
41
+ | `AppleGrid` | `min=240`、`gap=20` | default slot;基于最小列宽的自适应网格,两项单位均为 px。 |
42
+
43
+ ## 表单组件 · 18
44
+
45
+ | 组件 | 主要 Props | Events / Slots / 方法 |
46
+ | --- | --- | --- |
47
+ | `AppleInput` | F;`v-model: string/number`、`type=text`、`placeholder`、`clearable` | `change(value)`、`clear()`;prefix/suffix slots;`focus()`;输入事件实际返回字符串。password 类型带显隐按钮。 |
48
+ | `AppleTextarea` | F;`v-model: string`、`placeholder`、`rows=4`、`maxlength`、`counter`、`resize=true` | `change(value)`;`focus()`;resize=true 允许纵向缩放。 |
49
+ | `AppleSelect` | F;`v-model: string/number/null`、`items: AppleOption[]`、`placeholder='请选择'` | `change(value)`;自绘半透明模糊下拉,支持键盘导航和 required 校验。 |
50
+ | `AppleAutocomplete` | F;`v-model: string/number/null`、`items`、`placeholder`、`emptyText`、`clearable=true`、`filter(query,item)` | `change(value)`、`search(query)`;`focus()`;方向键/Enter/Escape;是单选过滤,不是多选标签输入。 |
51
+ | `AppleCheckbox` | F;`v-model: boolean`、`indeterminate` | `change(checked)`;default slot 替代 label 文本。 |
52
+ | `AppleRadioGroup` | F;`v-model: string/number/null`、`items`、`inline`、`name` | `change(value)`;原生 radio group。 |
53
+ | `AppleSwitch` | F;`v-model: boolean` | `change(checked)`;default slot 替代 label 文本。 |
54
+ | `AppleSlider` | F;`v-model: number`、`min=0`、`max=100`、`step=1`、`showValue=true`、`formatValue(value)` | `change(value)`;单值原生 range,不是双滑块范围选择。 |
55
+ | `AppleStepper` | F;`v-model: number`、`min=-Infinity`、`max=Infinity`、`step=1` | `change(value)`;减/加按钮及可编辑数值输入;提交时约束范围。 |
56
+ | `AppleSegmentedControl` | F;`v-model: string/number/null`、`items`、`name` | `change(value)`;基于 radio 的单选分段控件,不是 tabs 内容容器。 |
57
+ | `AppleDatePicker` | F;`v-model: string`、`min`、`max`、`format`、`granularity`、`type=date`(date/month/datetime-local) | `change(value)`;自绘分段输入、年月日历与时间页签;输入不自动跳段,占位时间在创建时冻结。 |
58
+ | `AppleColorPicker` | F;`v-model: string='#0071e3'`、`showValue=true` | `change(value)`;自绘色板和 HEX 输入,不打开原生颜色弹窗。 |
59
+ | `AppleUpload` | F;`v-model: File[]`、`accept`、`multiple`、`maxSize=Infinity`、`maxFiles=Infinity`、`capture=user/environment`、`buttonText` | `change(files)`、`reject({file,reason}[])`、`remove(file)`;default slot;maxSize 单位为字节;不发送网络请求。 |
60
+ | `AppleForm` | M;`disabled`、`loading`、`validator(FormData): boolean/string/Promise` | `submit(FormData)`、`invalid({type,message?})`、`reset()`;default slot `{loading}`;实例方法 `validate(): Promise<boolean>`、`submit()`、`reset()`。 |
61
+ | `AppleFormField` | F;`for` | default slot `{id,disabled,required,'aria-invalid','aria-describedby'}`;用于关联自定义输入及提示。 |
62
+ | `AppleOtpInput` | F;`label='验证码'`、`v-model: string`、`length=6`(1–12)、`numeric=true`、`name`、`mask` | `change(value)`、`complete(value)`;`focus(index=0)`;支持粘贴、退格、方向键与验证码自动填充提示。 |
63
+ | `AppleCascader` | F;`v-model: (string/number)[]`、`items: AppleCascaderOption[]`、`placeholder`、`levelLabels: string[]`、`name` | `change(path)`、`complete(path)`;选项递归增加 `children`;不内置行政区划数据。 |
64
+ | `AppleRate` | F;`label='评分'`、`v-model: number`、`max=5`(渲染 1–10)、`readonly`、`allowClear=true`、`name` | `change(value)`;整数星级;allowClear 时再次选择当前值返回 0;不支持半星。 |
65
+
66
+ 原生 `name`、`autocomplete`、`inputmode` 等属性可用于输入控件;提交 `AppleForm` 的 FormData 时必须为需要提交的控件设置 name。`AppleForm.reset()` 重置浏览器控件并发出 reset,但不会替应用重置所有 Vue model,应在 `@reset` 中同步业务状态。
67
+
68
+ ```vue
69
+ <apple-form :validator="validateProfile" @submit="submitProfile" @reset="resetProfile">
70
+ <apple-input v-model="email" name="email" label="邮箱" type="email" required />
71
+ <apple-select v-model="region" name="region" label="地区" :items="regions" required />
72
+ <apple-button type="submit">保存</apple-button>
73
+ </apple-form>
74
+ ```
75
+
76
+ validator 返回 `true` 才通过;字符串作为错误信息,`false` 显示默认错误。原生约束校验通过后才执行自定义 validator。
77
+
78
+ 日期格式示例:`YYYY/MM`、`YYYY/MM/DD`、`YYYY/MM/DD HH:mm`、`YYYY/MM/DD HH:mm:ss`、`HH:mm`、`HH:mm:ss`。显示格式与模型格式分离:模型依次返回 `YYYY-MM`、`YYYY-MM-DD`、`YYYY-MM-DDTHH:mm[:ss]` 或 `HH:mm[:ss]`。独立 `AppleTimePicker` 已移除,纯时间使用 `<apple-date-picker format="HH:mm" />`;不支持原生 ISO week 模式及日期范围选择。
79
+
80
+ ## 内容与移动交互 · 29
81
+
82
+ 以下组件均接受 M。
83
+
84
+ | 组件 | 主要 Props | Events / Slots / 说明 |
85
+ | --- | --- | --- |
86
+ | `AppleNavibar` | `v-model: string/number`、`items: AppleItem[]`、`brand`、`brandHref='/'`、`label='主导航'`、`fixed=true`、`breakpoint=640` | `change(value,item)`、`toggle(open)`;brand、item `{item,active}`、actions `{close}` slots。固定模式自带占位;栏宽不超过 breakpoint 时折叠为三横杠菜单;选择、Escape、外部点击或焦点移出后收起。`fixed=false` 可嵌入容器。 |
87
+ | `AppleTabs` | `v-model: string/number`、`items`、`label`、`disabled` | `change(value)`;`panel-${value}` slot `{item}` 或 default `{item,value}`;可非受控;方向键/Home/End。 |
88
+ | `AppleTabBar` | 与 AppleTabs 相同 | 顶角圆角页签,移动选中背景与内容滑动。 |
89
+ | `AppleBreadcrumbs` | `items`、`label='当前位置'` | `click(item,event)`;非最后项使用 item.href 或按钮;最后项为当前页文本;无下划线。 |
90
+ | `ApplePagination` | `v-model: number=1`、`total=0`、`pageSize=10`、`disabled`、`label` | `change(page)`;页码从 1 开始,total 是总条目数。 |
91
+ | `AppleAccordion` | `v-model: string/number/array`、`items`、`multiple`、`disabled` | `change(value)`;`item-${value}` 或 item slot `{item,open}`;默认内容使用 item.content;multiple 时模型为数组。 |
92
+ | `AppleTable` | `columns: AppleColumn[]`、`rows: Record[]`、`rowKey=id`、`label`、`selectable`、`v-model:selected`、`v-model:sort-by`、`v-model:sort-direction`、`v-model:page`、`pageSize=0`、`loading`、`disabled`、`emptyText` | `sort({key,direction})`、`row-click(row)`;`cell-${key}` slot `{row,value,index}`、empty slot;本地排序/分页;pageSize=0 不分页。 |
93
+ | `AppleTree` | `items: AppleTreeItem[]`、`v-model`、`v-model:expanded`、`disabled`、`label` | `select(item)`;item slot `{item,expanded,selected}`;递归 children;单选与键盘树导航,不含勾选联动。 |
94
+ | `AppleList` | `items`、`v-model`、`selectable`、`disabled`、`label` | `select(item)`;item slot `{item,selected}`;selectable 时更新模型,否则 href 生成链接。 |
95
+ | `AppleAvatar` | `src`、`name='用户'`、`size=40`、`square` | `error(event)`;default slot;图片失败回退到姓名前两个字符。 |
96
+ | `AppleAvatarGroup` | `items: {name,src?,value?}[]`、`max=4`、`size=36`、`label` | default slot 可替换头像集合;超出数量显示 +N。 |
97
+ | `AppleBadge` | `value: string/number`、`max=99`、`dot`、`showZero`、`label`、`tone=danger` | default slot 为被标记内容;无 slot 可独立显示。 |
98
+ | `AppleTag` | `tone=neutral`、`closable`、`disabled`、`label` | `close(event)`;default slot;关闭事件不自动删除父级数据。 |
99
+ | `AppleAlert` | `v-model: boolean=true`、`title`、`message`、`tone=info`(info/success/warning/danger)、`closable` | `close()`;default slot 替代 message。 |
100
+ | `AppleProgress` | `modelValue: number=0`、`max=100`、`label`、`indeterminate`、`showValue`、`tone=accent` | 用 `:model-value` 传入只读进度,不主动发出 update;不定进度省略 aria-valuenow。 |
101
+ | `AppleSpinner` | `size=22`、`label='正在加载'` | default slot;状态语义与无动效退化。 |
102
+ | `AppleSkeleton` | `variant=text`(text/avatar/card/list/table/image)、`lines=3`、`rows=3`、`columns=4`、`width`、`height`、`avatar`、`animated=true`、`label` | lines 约束为 1–20;尺寸为数字时按 px。 |
103
+ | `AppleEmpty` | `title`、`description` | icon/default slots。 |
104
+ | `AppleDivider` | `label`、`vertical` | default slot;水平或垂直分隔语义。 |
105
+ | `AppleSteps` | `v-model: number=0`、`items`、`clickable`、`disabled`、`label` | `change(index)`;模型是从 0 开始的步骤位置,不是 item.value。 |
106
+ | `AppleTimeline` | `items: AppleTimelineItem[]`、`orientation=vertical`(horizontal/vertical)、`label` | item slot `{item}`;选项增加 `time?` 和 `tone?: default/success/danger`。 |
107
+ | `AppleCarousel` | `items: AppleSlide[]`、`v-model: number`、`label`、`disabled` | `change(index)`;item slot `{item,index,active}`;选项增加 src/alt;滚动吸附与按钮/键盘,不自动播放。 |
108
+ | `ApplePullRefresh` | `v-model: boolean`、`disabled`、`threshold=72`、`label` | `refresh(done)`;default slot `{refresh,refreshing}`;在滚动顶部下拉,也提供刷新按钮;完成必须调用 done 或将 model 设为 false。 |
109
+ | `AppleInfiniteScroll` | `loading`、`error: boolean/string`、`finished`、`disabled`、`distance=120`、`finishedText` | `load(done)`、`retry(done)`;default slot;IntersectionObserver 及手动加载按钮;完成后调用 done,或令 loading 从 true 回到 false。 |
110
+ | `AppleSwipeCell` | `v-model: boolean`、`disabled`、`label` | default、actions slot `{close}`;横向手势或操作按钮展开,Escape 关闭。 |
111
+ | `AppleBackTop` | `target: CSS selector=''`、`threshold=300`、`label`、`disabled` | `click(event)`;default slot;空 target 使用 window,达到滚动阈值才显示。 |
112
+ | `AppleFloatingGroup` | `backTop=true`、`threshold=300`、`target`、`label` | default slot 放附加操作,回顶按钮始终排最下;默认固定右下并考虑安全区。 |
113
+ | `AppleMarquee` | `text`、`duration=24`、`paused`、`label` | default slot;duration 单位为秒;带暂停按钮;减少动态效果时停止连续滚动。 |
114
+ | `AppleStatistic` | 必填 `label`;`value: string/number`、`prefix`、`suffix`、`precision=0`、`locale=zh-CN`、`description` | default slot;数值本地化格式,不会自动请求统计数据。 |
115
+
116
+ `AppleColumn = { key: string; label: string; sortable?: boolean; align?: 'left'|'center'|'right'; width?: number|string; minWidth?: number; maxWidth?: number; resizable?: boolean }`。表格 rows 应提供稳定唯一的 `rowKey`。
117
+
118
+ Table 另支持 `virtual=false`、`height=360`、`rowHeight=48`、`overscan=5`、`resizable=true` 和 `column-resize({key,width})`。列分隔线可拖拽,也可键盘左右调整。虚拟模式基于 TanStack Virtual,采用固定行高;与分页同时启用时,只虚拟化当前页。大列表通常设置 `pageSize=0`。不支持自动测量变高行或服务端分页协议。
119
+
120
+ ```vue
121
+ <apple-table
122
+ :columns="columns"
123
+ :rows="rows"
124
+ row-key="id"
125
+ selectable
126
+ v-model:selected="selected"
127
+ v-model:page="page"
128
+ :page-size="10"
129
+ >
130
+ <template #cell-name="{ row, value }">
131
+ <a :href="`/members/${row.id}`">{{ value }}</a>
132
+ </template>
133
+ </apple-table>
134
+ ```
135
+
136
+ ## 弹层组件 · 10
137
+
138
+ 以下组件除 Host 外均接受 M。
139
+
140
+ | 组件 | 主要 Props | Events / Slots / 说明 |
141
+ | --- | --- | --- |
142
+ | `AppleDialog` | `v-model: boolean=false`;以下 Modal 公共属性 | 默认显示确认/取消 footer。 |
143
+ | `AppleDrawer` | 同 Modal;`placement=right`(left/right);`width=440` | 默认无 footer;全高侧边抽屉。 |
144
+ | `AppleSheet` | 同 Modal;`width=440` | 默认无 footer;底部面板,移动端全宽;桌面样式最小设计宽度 540px,仍受可用宽度约束。 |
145
+ | `AppleSnackbar` | `v-model: boolean=true`、`message`、`title`、`tone=default`(default/info/success/warning/danger/error)、`duration=4000`、`action`、`closable=true` | `close(value,reason)`、`action()`;default slot;duration 单位毫秒,0 常驻;直接使用时位置由业务布局决定。 |
146
+ | `AppleOverlayHost` | 无公开配置 | 自动渲染当前上下文 overlays.entries;Provider 已包含,不要重复挂载。 |
147
+ | `ApplePopover` | `v-model?: boolean`、`label='更多'`、`disabled`、`placement=bottom`(top/bottom/left/right)、`align=start`(start/center/end)、`width=280`、`role=dialog`、`openOnHover`、`trapFocus=true`、`panelClass` | `open()`、`close()`;activator `{props,open,close,isOpen}`、default `{close}`;支持非受控模式与屏幕边缘避让。 |
148
+ | `AppleTooltip` | 必填 `text`;`placement=top`、`disabled` | default slot 为触发元素;悬停/焦点显示,Escape 关闭;短文本提示。 |
149
+ | `AppleMenu` | `v-model?: boolean`、`label='操作'`、`items: AppleMenuItem[]`、`selected`、`disabled` | `select(value,item)`;activator slot 同 Popover、item slot `{item}`;选择后关闭,方向键/Home/End。 |
150
+ | `AppleActionSheet` | `v-model: boolean`、`title`、`message`、`items: AppleMenuItem[]`、`cancelText='取消'` | `select(value,item)`、`close(value,reason)`;选择返回条目 value。 |
151
+ | `AppleImageViewer` | `v-model: boolean`、`images: (string/AppleViewerImage)[]`、`v-model:index=0`、`loop` | `change(index)`、`close()`、`error(event)`;缩放与手势来自 @panzoom/panzoom,滚轮按实际滚动量连续缩放并保持鼠标焦点。 |
152
+
153
+ Modal 公共属性:`title`、`message`、`ariaLabel='对话框'`、`persistent`、`loading`、`closeOnConfirm=true`、`confirmText='确定'`、`cancelText='取消'`、`showFooter`、`closable=true`、`width`、`tone=default`。Dialog 默认 width 为 480px。空按钮文本会隐藏对应按钮。
154
+
155
+ Modal 事件:`update:modelValue`、`open()`、`after-close()`、`confirm(true)`、`cancel(false)`、`close(value,reason)`。reason 为 `escape | backdrop | cancel | confirm | close`。`persistent` 阻止 Escape 和背景关闭,不会禁用显式关闭按钮;`loading` 阻止交互关闭。
156
+
157
+ Modal slots:`title`、default `{close}`、footer `{close,confirm,cancel}`。带自定义 footer 时无需同时开启 showFooter。异步确认使用 `:close-on-confirm="false"` 与 loading,由应用完成请求后修改 model。
158
+
159
+ ```vue
160
+ <apple-dialog
161
+ v-model="opened"
162
+ title="保存修改"
163
+ :loading="saving"
164
+ :close-on-confirm="false"
165
+ @confirm="save"
166
+ >
167
+ <apple-input v-model="name" label="姓名" />
168
+ </apple-dialog>
169
+
170
+ <apple-menu :items="actions" @select="performAction">
171
+ <template #activator="{ props }">
172
+ <apple-button v-bind="props" variant="secondary">操作</apple-button>
173
+ </template>
174
+ </apple-menu>
175
+ ```
176
+
177
+ `AppleMenuItem = { label; value: string|number; disabled?; danger?; description?; icon?: Component }`。
178
+
179
+ `AppleViewerImage = { src: string; alt?: string; title?: string }`。数组字符串是 URL;需要可访问描述或标题时传对象。index 从 0 开始。
180
+
181
+ ## 上下文与服务
182
+
183
+ `createAppleUI(options)` 创建可安装插件;`createApple(options)` 创建独立上下文,不执行组件注册。`appleKey` 用于 Options API 注入,`useApple()` 用于 setup。可单独导入 `createMessageBus()`、`createOverlayService()`、`resolveMotion()`、`themeStyle()`、`builtInThemes` 及公开类型。
184
+
185
+ | API | 作用 |
186
+ | --- | --- |
187
+ | `theme.set(name)` | 切换注册主题或 system。未知名称抛出错误。 |
188
+ | `theme.register(name,tokens,scheme='light')` | 注册自定义主题并补齐基础 token。 |
189
+ | `theme.name / resolved / current / themes` | 当前配置名、解析后名称、主题内容、主题注册表。 |
190
+ | `motion.set(mode)` | 即时修改全局动效策略。 |
191
+ | `onMessage(channel,listener)` | 注册监听器,返回取消订阅函数。 |
192
+ | `sendMessage(channel,payload?)` | 返回该 channel 全部监听器的返回值数组。 |
193
+ | `dialog(options)` | 打开 dialog 并返回独立句柄。 |
194
+ | `notify(message,options?)` | 打开通知,默认 duration=4000。 |
195
+ | `overlays.open(options)` | 支持 kind 为 dialog/drawer/sheet/snackbar。 |
196
+ | `overlays.close(id,value?) / closeTop(value?) / clear()` | 精确关闭、关闭顶层非通知、清空当前上下文。 |
197
+
198
+ `OverlayOptions` 实际字段为 `kind?`、`title?`、`message?`、`component?`、`props?`、`onMessage?`、`persistent?`、`confirmText?`、`cancelText?`、`tone?`、`duration?`。不要把声明式组件的 width、loading、action 等属性假定成当前服务参数;需要这些控制时使用声明式组件或自定义内容。
199
+
200
+ 返回的 `OverlayHandle<T>` 为 `{ id, close(value?), update(patch), result: Promise<T | undefined> }`。`props` 传给动态内容组件;宿主额外注入 `close` 和 `sendMessage`。`onMessage(channel,payload)` 可返回普通值或 Promise,实现双向请求与响应,示例见 [README](../README.md#dialog-与反向通道)。
201
+
202
+ ## 验证边界
203
+
204
+ 这是当前接口清单,不是全平台兼容认证。自动化测试覆盖了部分状态与键盘交互;真实输入法、软键盘、触屏滚动、读屏器和各 WebView 行为需要在应用目标设备上验证。导入安全与服务端渲染 / hydration 是不同结论;当前不承诺未经验证的完整 SSR 支持。
@@ -0,0 +1,36 @@
1
+ # 验证记录
2
+
3
+ 验证日期:2026-09-26。以下是本次实际执行的验证,不代表所有设备和业务场景的认证。
4
+
5
+ ## 已执行
6
+
7
+ - `npm test`:8 个测试文件、113 项测试通过。覆盖表单交互、消息回传、主题隔离与实时更新、动效策略、组件生命周期、弹层焦点与滚动锁,以及虚拟表格、日期分段、无 Ripple 页签和尺寸动画取消。
8
+ - `npm run test:e2e -- --workers=2`:45 项 Chrome 和 WebKit 浏览器交互测试通过。四种概览视口为 1440、768、390、320 CSS px;包含资源加载、文档无横向溢出、主题切换不刷新、减少动态效果、堆叠弹窗、图片预览、表单、上传和表格。
9
+ - 全部 66 个公开组件均有独立示例,逐项检查非空渲染、无未解析组件、无运行时页面异常。
10
+ - WebKit 390px、触屏/移动视口模拟验证了输入、叠层弹窗、滚动锁、图片加载与翻页以及系统减少动态效果。
11
+ - `npm run test:package`:TypeScript 检查、展示站构建、ESM 库构建、声明生成,以及通过包名 `apptify` 和 `apptify/style.css` 导入的独立消费示例均通过。消费者使用纯 JavaScript Options API,不要求 TypeScript。
12
+ - `npm audit`:本次锁文件检查为 0 项已知漏洞。此结果仅代表当时的软件漏洞数据库。
13
+ - 未发布到 npm;旧 tgz 是整改前版本,当前源码需重新 `npm pack`。演示图片不进入组件库安装包。
14
+
15
+ ## 回归修复
16
+
17
+ 浏览器快速切换组件时发现 Carousel 的延迟 scroll 回调可能在卸载后访问失效的 DOM 引用。已增加卸载后空引用判断,并补充单元测试及全目录切换回归。
18
+
19
+ 本轮增加真实动画中的断言,而非只在关闭动效后截图:弹层退出时保留节点与滚动锁、图片滚轮缩放和透明度、Toast 横移、Tabs/Segmented 指示条移动、Accordion 中间高度、Autocomplete 高度插值、主题颜色插值、5000 行表格的有限 DOM 和列宽拖动。
20
+
21
+ 全局入场已简化为一个容器从下方 14px 上移,无全局离场、旧页面复制或嵌套入场。侧栏使用静态平直灰色选中态,不做纵向滑动;Tabs、TabBar、SegmentedControl 和日历页签不使用 Ripple。
22
+
23
+ 截图在实际可见图片和日期弹窗动效完成后采集,避免把隐藏的预加载图片或切换间隙误判为最终展示。Esc 在弹层内优先关闭内联下拉和日历。整改前基线提交为 `2a052fe`。
24
+
25
+ ## 视觉产物
26
+
27
+ 工作区 `artifacts/` 保留桌面、手机、320px、平板、深色、叠层弹窗、图片预览及 WebKit 手机截图。截图属于开发验收材料,不随 npm 安装包分发。
28
+
29
+ ## 尚未验证
30
+
31
+ - 实体 iPhone/iPad、Android 机型、微信 WebView、软键盘与真实多指手势矩阵。
32
+ - VoiceOver/NVDA 等屏幕阅读器的人工验收,以及整库 WCAG 对比度认证。
33
+ - SSR 全组件 hydration 与主题首屏无闪烁;当前只有导入安全的设计和实例隔离测试。
34
+ - 可变行高、服务端数据协议和所有大规模数据场景;Table 当前的虚拟滚动为固定行高,已验证 5000 行示例及原地追加数据。
35
+
36
+ 测试执行环境为 macOS、Node.js 23.11.0。构建与测试实际通过,但 Vitest 将奇数版本 Node 标记为非支持版本;日常开发和 CI 建议使用 Node.js 22 或 24 LTS。
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "apptify",
3
+ "version": "0.2.0",
4
+ "description": "An Apple-inspired, responsive Vue 3 component library with Vuetify ripple.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "files": [
8
+ "dist",
9
+ "docs"
10
+ ],
11
+ "main": "./dist/apptify.js",
12
+ "module": "./dist/apptify.js",
13
+ "types": "./dist/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/index.d.ts",
17
+ "import": "./dist/apptify.js"
18
+ },
19
+ "./style.css": "./dist/apptify.css"
20
+ },
21
+ "sideEffects": [
22
+ "**/*.css"
23
+ ],
24
+ "scripts": {
25
+ "dev": "vite --host 127.0.0.1",
26
+ "build": "vue-tsc --noEmit && vite build && vite build --config vite.lib.config.ts && vue-tsc -p tsconfig.lib.json",
27
+ "typecheck": "vue-tsc --noEmit",
28
+ "test": "vitest run",
29
+ "test:e2e": "playwright test",
30
+ "test:package": "npm run build && vite build --config vite.consumer.config.ts",
31
+ "preview": "vite preview --host 127.0.0.1"
32
+ },
33
+ "peerDependencies": {
34
+ "vue": "^3.5.0",
35
+ "vuetify": "^3.9.0"
36
+ },
37
+ "dependencies": {
38
+ "@panzoom/panzoom": "^4.6.2",
39
+ "@tanstack/virtual-core": "^3.17.11",
40
+ "date-fns": "^4.4.0",
41
+ "lucide-vue-next": "^0.468.0"
42
+ },
43
+ "devDependencies": {
44
+ "@playwright/test": "^1.51.1",
45
+ "@vitejs/plugin-vue": "^5.2.3",
46
+ "@vue/test-utils": "^2.4.6",
47
+ "jsdom": "^26.0.0",
48
+ "typescript": "^5.8.2",
49
+ "vite": "^6.3.4",
50
+ "vitest": "^4.1.11",
51
+ "vue": "^3.5.13",
52
+ "vue-tsc": "^2.2.8",
53
+ "vuetify": "^3.9.0"
54
+ }
55
+ }