Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/bug #892

Merged
merged 4 commits into from
Feb 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions packages/core/src/fixed-view/fixed-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ import classNames from "classnames";
import * as _ from "lodash";
import * as React from "react";
import { type PropsWithChildren, useRef } from "react";
import { type PlaceholderProps, usePlaceholder } from "../placeholder";
import { type PlaceholderProps } from "../placeholder";
import SafeArea, { type SafeAreaPosition } from "../safe-area";
import { prefixClassname } from "../styles";
import type { FixedViewPosition } from "./fixed-view.shared";
import { useHeight } from "../hooks";
import { addUnitPx } from "../utils/format/unit";
import mergeStyle from "../utils/merge-style"

function useFixedViewPlaceholder(placeholder?: boolean | string | PlaceholderProps) {
if (placeholder === true) {
Expand Down Expand Up @@ -46,7 +49,7 @@ function FixedView<T>(props: FixedViewProps & T) {
} = props;
const rootRef = useRef();
const placeholder = useFixedViewPlaceholder(placeholderProp);
const Placeholder = usePlaceholder(rootRef);
const height = useHeight(rootRef);

if (position !== "top" && position !== "bottom" && position !== true) {
return children as JSX.Element;
Expand All @@ -72,12 +75,14 @@ function FixedView<T>(props: FixedViewProps & T) {
);

if (placeholder) {
const { className: placeholderClassName, ...restPlaceholder } = placeholder;
const { className: placeholderClassName, style: styleProp, ...restPlaceholder } = placeholder;
const style = mergeStyle(styleProp, height ? { height: addUnitPx(height) } : {});
return (
<Placeholder
<View
className={classNames(prefixClassname("fixed-view__placeholder"), placeholderClassName)}
{...restPlaceholder}
style={style}
children={content}
{...restPlaceholder}
/>
);
}
Expand Down
10 changes: 8 additions & 2 deletions packages/core/src/hooks/use-height.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import { DependencyList, useState, useCallback } from "react"
import { DependencyList, useState, useCallback, useRef } from "react"
import { nextTick } from "@tarojs/taro"
import { getRect } from "../utils/dom/rect"
import { useRenderedEffect, useMounted, useWindowResize } from "./index"

export default function useHeight(elementOrRef: any, deps?: DependencyList) {
const [height, _setHeight] = useState<number>(0)
const heightRef = useRef(0)

const setHeight = useCallback(() => {
getRect(elementOrRef)
.then((rect) => rect?.height)
.then(_setHeight)
.then((val) => {
if (val !== heightRef.current) {
heightRef.current = val
_setHeight(val)
}
})
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])

Expand Down
1 change: 1 addition & 0 deletions packages/core/src/input/native-input.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
width: inherit;
min-width: inherit;
height: inherit;
min-height: inherit;
line-height: inherit;
color: inherit;
resize: inherit;
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/list/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ function ErrorList() {

### 下拉刷新

List 组件可以与 [PullRefresh](/components/pull-refresh/) 组件结合使用,实现下拉刷新的效果。
List 组件可以与 [PullRefresh](/components/pull-refresh/) 组件结合使用,实现下拉刷新的效果。固定高度时,scrollTop可以从onScroll中获取`(e.detail.scrollTop)`

```tsx
function PullRefreshList() {
Expand Down Expand Up @@ -231,6 +231,7 @@ function PullRefreshList() {
| ---------------------------------------------------------------------- | ---------------------------------- | -------- |
| onLoad | 滚动条与底部距离小于 offset 时触发 | - |
| <span style="color: red">~~onLoading~~ <br>`v0.1.1-alpha.2移除`</span> | 内部 loading 改变时触发 | - |
| onScroll | 滚动时触发 | e |

### 方法

Expand Down
46 changes: 41 additions & 5 deletions packages/core/src/list/list.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useGetter, useToRef } from "@taroify/hooks"
import { View, ScrollView } from "@tarojs/components"
import { View, ScrollView, ScrollViewProps, BaseEventOrig } from "@tarojs/components"
import { ViewProps } from "@tarojs/components/types/View"
import classNames from "classnames"
import * as React from "react"
Expand All @@ -13,6 +13,7 @@ import { getScrollParent } from "../utils/dom/scroll"
import { raf } from "../utils/raf"
import { debounce } from "../utils/lodash-polyfill"
import { ListDirection, ListInstance } from "./list.shared"
import PullRefreshContext from "../pull-refresh/pull-refresh.context"

function useAssignLoading<T = any>(state?: T | (() => T)) {
const getState = useGetter(state)
Expand Down Expand Up @@ -46,6 +47,7 @@ export interface ListProps extends ViewProps {
fixedHeight?: boolean
children?: ReactNode
onLoad?(): void
onScroll?(e: BaseEventOrig<ScrollViewProps.onScrollDetail>): void
}

function List(props: ListProps, ref: ForwardedRef<ListInstance>) {
Expand All @@ -55,19 +57,25 @@ function List(props: ListProps, ref: ForwardedRef<ListInstance>) {
hasMore = true,
direction = "down",
offset = 100,
immediateCheck: _immediateCheck = true,
immediateCheck: immediateCheckProp = true,
fixedHeight = false,
disabled = false,
children,
onLoad,
onScroll: onScrollProp,
...restProps
} = props
const rootRef = useRef<HTMLElement>()
const scrollRef = useRef<HTMLElement>()
const edgeRef = useRef<HTMLElement>()
const onLoadRef = useToRef(onLoad)
const immediateCheck = useToRef(_immediateCheck)
const immediateCheck = useToRef(immediateCheckProp)
const { isLoading, setLoading } = useAssignLoading(loadingProp)
const {
onTouchStart: onPullRefreshTouchStart,
onTouchEnd: onPullRefreshTouchEnd,
onTouchMove: onPullRefreshTouchMove
} = React.useContext(PullRefreshContext)

const check = useMemoizedFn(debounce(() => {
raf(async () => {
Expand Down Expand Up @@ -107,12 +115,31 @@ function List(props: ListProps, ref: ForwardedRef<ListInstance>) {
}
})

const onScroll = () => {
const onScroll = (e) => {
onScrollProp?.(e)
if (fixedHeight) {
check()
}
}

const onTouchStart = (e) => {
if (fixedHeight) {
onPullRefreshTouchStart?.(e)
}
}

const onTouchMove = (e) => {
if (fixedHeight) {
onPullRefreshTouchMove?.(e)
}
}

const onTouchEnd = (e) => {
if (fixedHeight) {
onPullRefreshTouchEnd?.(e)
}
}

useDidEffect(() => {
check()
}, [loadingProp, hasMore, check])
Expand Down Expand Up @@ -140,7 +167,16 @@ function List(props: ListProps, ref: ForwardedRef<ListInstance>) {
)

return (
<Wrapper ref={rootRef} scrollY={fixedHeight} className={classNames(prefixClassname("list"), className)} {...restProps} onScroll={onScroll}>
<Wrapper
ref={rootRef}
scrollY={fixedHeight}
className={classNames(prefixClassname("list"), className)}
{...restProps}
onScroll={onScroll}
onTouchStart={onTouchStart}
onTouchMove={onTouchMove}
onTouchEnd={onTouchEnd}
>
{direction === "down" ? children : listEdge}
{direction === "up" ? children : listEdge}
</Wrapper>
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/navbar/navbar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
color: $navbar-icon-color;
}

&__placeholder {
height: $navbar-height;
}

&__content {
position: relative;
display: flex;
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/placeholder/use-placeholder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface PlaceholderProps extends PropsWithChildren<ViewProps> {
}

export default function usePlaceholder(contentRef: any, { className }: UsePlaceholderOptions = {}) {
console.warn("[Taroify] usePlaceholder is deprecated, please don't use it.")
return ({ className: classNameProp, style = {}, children, ...restProps }: PlaceholderProps) => {
// eslint-disable-next-line react-hooks/rules-of-hooks
const height = useHeight(contentRef, [children])
Expand Down
6 changes: 6 additions & 0 deletions packages/core/src/pull-refresh/pull-refresh.context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@ import { createContext } from "react"

interface PullRefreshContextValue {
distance: number
onTouchStart(event: any): void
onTouchMove(event: any): void
onTouchEnd(event: any): void
}

const PullRefreshContext = createContext<PullRefreshContextValue>({
distance: 0,
onTouchStart: () => {},
onTouchMove: () => {},
onTouchEnd: () => {},
})

export default PullRefreshContext
6 changes: 3 additions & 3 deletions packages/core/src/pull-refresh/pull-refresh.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@ function PullRefresh(props: PullRefreshProps) {
setTimeout(() => nextTick(() => updateStatus(0)), +completedDuration)
}, [completedDuration, updateStatus])

const contextValue = useMemo(() => ({ distance, onTouchStart, onTouchMove, onTouchEnd }), [distance, onTouchStart, onTouchMove, onTouchEnd])

useEffect(() => {
if (loading) {
updateStatus(headHeight, true)
Expand Down Expand Up @@ -319,9 +321,7 @@ function PullRefresh(props: PullRefreshProps) {

return (
<PullRefreshContext.Provider
value={{
distance,
}}
value={contextValue}
>
<View className={classNames(prefixClassname("pull-refresh"), className)} {...restProps}>
<View
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/tabs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ function TabsWithCustomTitle() {
| bordered | 是否显示标签栏外边框,仅在 `type="line"` 时有效 | _boolean_ | `false` |
| ellipsis | 是否省略过长的标题文字 | _boolean_ | `true` |
| sticky | 是否使用粘性定位布局 | _boolean \| { offsetTop }_ | `false` |
| shrink | 是否使用收缩布局 | _boolean | `false` |
| swipeable | 是否开启手势左右滑动切换 | _boolean_ | `false` |
| swipeThreshold <br>`v0.1.0-alpha.8` | 滚动阈值,标签数量超过阈值且总宽度超过标签栏宽度时开始横向滚动 | _number_ | `5` |
| lazyRender | 是否延迟渲染未展示的选项卡 | _boolean_ | `false` |
Expand Down
11 changes: 11 additions & 0 deletions packages/core/src/tabs/tabs-header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@
border-radius: $tabs-card-border-radius;
}

&--shrink {
width: auto;
}

&::-webkit-scrollbar {
display: none;
}
Expand All @@ -49,6 +53,9 @@
.#{$component-prefix}tabs__tab {
flex: 1 0 auto;
padding: 0 var(--padding-sm, $padding-sm);
&--shrink {
flex: none;
}
}
}
}
Expand Down Expand Up @@ -77,6 +84,10 @@
border-right: 0 none;
}

&--shrink {
flex: none;
}

&--active {
color: var(--white, $white);
background: $tabs-active-color;
Expand Down
9 changes: 6 additions & 3 deletions packages/core/src/tabs/tabs-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,15 @@ interface TabsHeaderProps {
theme?: TabsTheme
bordered?: boolean
ellipsis?: boolean
shrink?: boolean
tabObjects: TabObject[]
swipeThreshold: number

onTabClick?(event: TabEvent): void
}

export default function TabsHeader(props: TabsHeaderProps) {
const { value: activeValue, theme, ellipsis, bordered, tabObjects, swipeThreshold, onTabClick } = props
const { value: activeValue, theme, ellipsis, bordered, shrink, tabObjects, swipeThreshold, onTabClick } = props
const themeLine = theme === "line"
const themeCard = theme === "card"

Expand Down Expand Up @@ -79,8 +80,9 @@ export default function TabsHeader(props: TabsHeaderProps) {
}, [])

const flexBasis = useMemo(() => {
if (shrink) return ""
return ellipsis && themeLine ? `${88 / swipeThreshold}%` : ""
}, [ellipsis, themeLine, swipeThreshold])
}, [ellipsis, themeLine, swipeThreshold, shrink])

useEffect(() => nextTick(resize), [resize, tabObjects])

Expand Down Expand Up @@ -109,6 +111,7 @@ export default function TabsHeader(props: TabsHeaderProps) {
className={classNames(prefixClassname("tabs__wrap__scroll"), {
[prefixClassname("tabs__wrap__scroll--line")]: themeLine,
[prefixClassname("tabs__wrap__scroll--card")]: themeCard,
[prefixClassname("tabs__wrap__scroll--shrink")]: shrink && themeCard,
})}
>
<View
Expand All @@ -126,7 +129,7 @@ export default function TabsHeader(props: TabsHeaderProps) {
flexBasis={flexBasis}
// TODO swipeThreshold does not support
// flexBasis={themeLine && ellipsis ? `${88 / 4}%` : ""}
className={tabObject?.classNames?.title}
className={classNames(tabObject?.classNames?.title, { [prefixClassname("tabs__tab--shrink")]: shrink })}
dot={tabObject.dot}
badge={tabObject.badge}
active={activeValue === tabObject.value}
Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/tabs/tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export interface TabsProps extends ViewProps {
ellipsis?: boolean
swipeThreshold?: number
children?: ReactNode
shrink?: boolean

onChange?(value: any, event: TabEvent): void

Expand All @@ -102,6 +103,7 @@ function Tabs(props: TabsProps) {
bordered,
swipeThreshold = 5,
children: childrenProp,
shrink,
onTabClick,
onChange,
onScroll,
Expand Down Expand Up @@ -154,6 +156,7 @@ function Tabs(props: TabsProps) {
theme={theme}
bordered={bordered}
ellipsis={ellipsis}
shrink={shrink}
tabObjects={tabObjects}
swipeThreshold={swipeThreshold}
onTabClick={handleTabClick}
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/textarea/native-textarea.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
box-sizing: border-box;
display: block;
width: 100%;
min-width: 0;
min-width: inherit;
height: 100%;
min-height: inherit;
padding: 0;
margin: 0;
line-height: inherit;
Expand Down
Loading