style: affix & util
parent
c7492a0b59
commit
60e2597f7f
|
@ -0,0 +1,8 @@
|
|||
import UnreachableException from '../unreachableException';
|
||||
|
||||
describe('UnreachableException', () => {
|
||||
it('error thrown matches snapshot', () => {
|
||||
const exception = new UnreachableException('some value');
|
||||
expect(exception.error.message).toMatchInlineSnapshot(`"unreachable case: \\"some value\\""`);
|
||||
});
|
||||
});
|
|
@ -2,8 +2,8 @@ import canUseDom from './canUseDom';
|
|||
|
||||
export const canUseDocElement = () => canUseDom() && window.document.documentElement;
|
||||
|
||||
export const isStyleSupport = (styleName: string | Array<string>): boolean => {
|
||||
if (canUseDocElement()) {
|
||||
const isStyleNameSupport = (styleName: string | string[]): boolean => {
|
||||
if (canUseDom() && window.document.documentElement) {
|
||||
const styleNameList = Array.isArray(styleName) ? styleName : [styleName];
|
||||
const { documentElement } = window.document;
|
||||
|
||||
|
@ -12,6 +12,25 @@ export const isStyleSupport = (styleName: string | Array<string>): boolean => {
|
|||
return false;
|
||||
};
|
||||
|
||||
const isStyleValueSupport = (styleName: string, value: any) => {
|
||||
if (!isStyleNameSupport(styleName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const ele = document.createElement('div');
|
||||
const origin = ele.style[styleName];
|
||||
ele.style[styleName] = value;
|
||||
return ele.style[styleName] !== origin;
|
||||
};
|
||||
|
||||
export function isStyleSupport(styleName: string | string[], styleValue?: any) {
|
||||
if (!Array.isArray(styleName) && styleValue !== undefined) {
|
||||
return isStyleValueSupport(styleName, styleValue);
|
||||
}
|
||||
|
||||
return isStyleNameSupport(styleName);
|
||||
}
|
||||
|
||||
let flexGapSupported: boolean | undefined;
|
||||
export const detectFlexGapSupported = () => {
|
||||
if (!canUseDocElement()) {
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
export default class UnreachableException {
|
||||
error: Error;
|
||||
|
||||
constructor(value: never) {
|
||||
this.error = new Error(`unreachable case: ${JSON.stringify(value)}`);
|
||||
}
|
||||
}
|
|
@ -24,6 +24,7 @@ export default defineComponent({
|
|||
name: 'Wave',
|
||||
props: {
|
||||
insertExtraNode: Boolean,
|
||||
disabled: Boolean,
|
||||
},
|
||||
setup(props, { slots, expose }) {
|
||||
const instance = getCurrentInstance();
|
||||
|
@ -60,10 +61,11 @@ export default defineComponent({
|
|||
return insertExtraNode ? 'ant-click-animating' : 'ant-click-animating-without-extra-node';
|
||||
};
|
||||
const onClick = (node: HTMLElement, waveColor: string) => {
|
||||
if (!node || isHidden(node) || node.className.indexOf('-leave') >= 0) {
|
||||
const { insertExtraNode, disabled } = props;
|
||||
if (disabled || !node || isHidden(node) || node.className.indexOf('-leave') >= 0) {
|
||||
return;
|
||||
}
|
||||
const { insertExtraNode } = props;
|
||||
|
||||
extraNode = document.createElement('div');
|
||||
extraNode.className = 'ant-click-animating-node';
|
||||
const attributeName = getAttributeName();
|
||||
|
|
|
@ -23,9 +23,9 @@ Please note that Affix should not cover other content on the page, especially wh
|
|||
|
||||
### events
|
||||
|
||||
| Events Name | Description | Arguments | Version |
|
||||
| ----------- | ---------------------------------------- | ----------------- | ------- |
|
||||
| change | Callback for when Affix state is changed | Function(affixed) |
|
||||
| Events Name | Description | Arguments | Version |
|
||||
| ----------- | ---------------------------------------- | --------------------------- | ------- |
|
||||
| change | Callback for when Affix state is changed | (affixed?: boolean) => void | |
|
||||
|
||||
**Note:** Children of `Affix` must not have the property `position: absolute`, but you can set `position: absolute` on `Affix` itself:
|
||||
|
||||
|
@ -35,8 +35,12 @@ Please note that Affix should not cover other content on the page, especially wh
|
|||
|
||||
## FAQ
|
||||
|
||||
### Affix bind container with `target`, sometime move out of container.
|
||||
### When binding container with `target` in Affix, elements sometimes move out of the container.
|
||||
|
||||
We don't listen window scroll for performance consideration.
|
||||
We only listen to container scroll events for performance consideration. You can add custom listeners if you still want to, like react demo <https://codesandbox.io/s/2xyj5zr85p>
|
||||
|
||||
Related issues:[#3938](https://github.com/ant-design/ant-design/issues/3938) [#5642](https://github.com/ant-design/ant-design/issues/5642) [#16120](https://github.com/ant-design/ant-design/issues/16120)
|
||||
|
||||
### When Affix is used in a horizontal scroll container, the position of the element `left` is incorrect.
|
||||
|
||||
Affix is generally only applicable to areas with one-way scrolling, and only supports usage in vertical scrolling containers. If you want to use it in a horizontal container, you can consider implementing with the native `position: sticky` property.
|
||||
|
|
|
@ -179,10 +179,7 @@ const Affix = defineComponent({
|
|||
watch(
|
||||
() => props.target,
|
||||
val => {
|
||||
let newTarget = null;
|
||||
if (val) {
|
||||
newTarget = val() || null;
|
||||
}
|
||||
const newTarget = val?.() || null;
|
||||
if (state.prevTarget !== newTarget) {
|
||||
removeObserveTarget(currentInstance);
|
||||
if (newTarget) {
|
||||
|
|
|
@ -19,14 +19,14 @@ cover: https://gw.alipayobjects.com/zos/alicdn/tX6-md4H6/Affix.svg
|
|||
| 成员 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| offsetBottom | 距离窗口底部达到指定偏移量后触发 | number | | |
|
||||
| offsetTop | 距离窗口顶部达到指定偏移量后触发 | number | | |
|
||||
| offsetTop | 距离窗口顶部达到指定偏移量后触发 | number | 0 | |
|
||||
| target | 设置 `Affix` 需要监听其滚动事件的元素,值为一个返回对应 DOM 元素的函数 | () => HTMLElement | () => window | |
|
||||
|
||||
### 事件
|
||||
|
||||
| 事件名称 | 说明 | 回调参数 | 版本 |
|
||||
| -------- | ---------------------------- | ----------------- | ---- | --- |
|
||||
| change | 固定状态改变时触发的回调函数 | Function(affixed) | 无 | |
|
||||
| 事件名称 | 说明 | 回调参数 | 版本 |
|
||||
| -------- | ---------------------------- | --------------------------- | ---- | --- |
|
||||
| change | 固定状态改变时触发的回调函数 | (affixed?: boolean) => void | - | |
|
||||
|
||||
**注意:**`Affix` 内的元素不要使用绝对定位,如需要绝对定位的效果,可以直接设置 `Affix` 为绝对定位:
|
||||
|
||||
|
@ -38,6 +38,12 @@ cover: https://gw.alipayobjects.com/zos/alicdn/tX6-md4H6/Affix.svg
|
|||
|
||||
### Affix 使用 `target` 绑定容器时,元素会跑到容器外。
|
||||
|
||||
从性能角度考虑,我们只监听容器滚动事件。
|
||||
从性能角度考虑,我们只监听容器滚动事件。如果希望任意滚动,你可以在窗体添加滚动监听, 参考 react 版本示例 <https://codesandbox.io/s/2xyj5zr85p>
|
||||
|
||||
相关 issue:[#3938](https://github.com/ant-design/ant-design/issues/3938) [#5642](https://github.com/ant-design/ant-design/issues/5642) [#16120](https://github.com/ant-design/ant-design/issues/16120)
|
||||
|
||||
### Affix 在水平滚动容器中使用时, 元素 `left` 位置不正确。
|
||||
|
||||
Affix 一般只适用于单向滚动的区域,只支持在垂直滚动容器中使用。如果希望在水平容器中使用,你可以考虑使用 原生 `position: sticky` 实现。
|
||||
|
||||
相关 issue: [#29108](https://github.com/ant-design/ant-design/issues/29108)
|
||||
|
|
|
@ -3,19 +3,14 @@ import type { ComponentPublicInstance } from 'vue';
|
|||
import supportsPassive from '../_util/supportsPassive';
|
||||
|
||||
export type BindElement = HTMLElement | Window | null | undefined;
|
||||
export type Rect = ClientRect | DOMRect;
|
||||
|
||||
export function getTargetRect(target: BindElement): ClientRect {
|
||||
export function getTargetRect(target: BindElement): DOMRect {
|
||||
return target !== window
|
||||
? (target as HTMLElement).getBoundingClientRect()
|
||||
: ({ top: 0, bottom: window.innerHeight } as ClientRect);
|
||||
: ({ top: 0, bottom: window.innerHeight } as DOMRect);
|
||||
}
|
||||
|
||||
export function getFixedTop(
|
||||
placeholderReact: Rect,
|
||||
targetRect: Rect,
|
||||
offsetTop: number | undefined,
|
||||
) {
|
||||
export function getFixedTop(placeholderReact: DOMRect, targetRect: DOMRect, offsetTop: number) {
|
||||
if (offsetTop !== undefined && targetRect.top > placeholderReact.top - offsetTop) {
|
||||
return `${offsetTop + targetRect.top}px`;
|
||||
}
|
||||
|
@ -23,9 +18,9 @@ export function getFixedTop(
|
|||
}
|
||||
|
||||
export function getFixedBottom(
|
||||
placeholderReact: Rect,
|
||||
targetRect: Rect,
|
||||
offsetBottom: number | undefined,
|
||||
placeholderReact: DOMRect,
|
||||
targetRect: DOMRect,
|
||||
offsetBottom: number,
|
||||
) {
|
||||
if (offsetBottom !== undefined && targetRect.bottom < placeholderReact.bottom + offsetBottom) {
|
||||
const targetBottomOffset = window.innerHeight - targetRect.bottom;
|
||||
|
|
Loading…
Reference in New Issue