Skip to content

Commit

Permalink
feat: styled pull-to-refresh
Browse files Browse the repository at this point in the history
  • Loading branch information
malangcat committed Feb 3, 2025
1 parent 2f5bbce commit 2ad0d0d
Show file tree
Hide file tree
Showing 16 changed files with 157 additions and 11 deletions.
2 changes: 1 addition & 1 deletion examples/stackflow-spa/src/activities/ActivityHome.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const ActivityHome: ActivityComponentType = () => {
return (
<AppScreen>
<AppBar>
<AppBarMain title="Home" subtitle="Subtitle" />
<AppBarMain title="Home" />
</AppBar>
<AppScreenContent
ptr
Expand Down
2 changes: 1 addition & 1 deletion examples/stackflow-spa/src/activities/ActivityLayerBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const ActivityLayerBar: ActivityComponentType = () => {
<AppBarLeft>
<AppBarBackButton />
</AppBarLeft>
<AppBarMain>Random Long Title Hello World</AppBarMain>
<AppBarMain title="Random Long Title Hello World" subtitle="Subtitle" />
<AppBarRight>
<AppBarIconButton>
<IconBellLine />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { PullToRefresh, usePullToRefreshContext } from "@seed-design/react/primitive";
import { PullToRefresh } from "@seed-design/react";
import { usePullToRefreshContext } from "@seed-design/react/primitive";
import { AppScreen as SeedAppScreen } from "@seed-design/stackflow";
import { useActions } from "@stackflow/react";
import { forwardRef } from "react";
Expand Down Expand Up @@ -52,7 +53,7 @@ export const AppScreenContent = forwardRef<HTMLDivElement, AppScreenContentProps
<PullToRefresh.Root asChild onPtrReady={onPtrReady} onPtrRefresh={onPtrRefresh}>
<SeedAppScreen.Layer ref={ref} {...otherProps}>
<PullToRefresh.Indicator>
{(props) => <ProgressCircle tone="brand" {...props} />}
{(props) => <ProgressCircle size="24" tone="brand" {...props} />}
</PullToRefresh.Indicator>
<PullToRefresh.Content asChild>{children}</PullToRefresh.Content>
<Debug />
Expand Down
2 changes: 2 additions & 0 deletions packages/qvism-preset/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import identityPlaceholder from "./recipes/identity-placeholder";
import inlineBanner from "./recipes/inline-banner";
import mannerTempBadge from "./recipes/manner-temp-badge";
import progressCircle from "./recipes/progress-circle";
import pullToRefresh from "./recipes/pull-to-refresh";
import radio from "./recipes/radio";
import reactionButton from "./recipes/reaction-button";
import segmentedControl from "./recipes/segmented-control";
Expand Down Expand Up @@ -85,6 +86,7 @@ const recipes = {
appScreen,
appBar,
appBarMain,
pullToRefresh,
};

export default recipes;
22 changes: 22 additions & 0 deletions packages/qvism-preset/src/recipes/pull-to-refresh.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { vars } from "@seed-design/vars";
import { defineRecipe } from "../utils/define-recipe";

const pullToRefresh = defineRecipe({
name: "pullToRefresh",
slots: ["root", "indicator"],
base: {
root: {
"--ptr-size": "44px",
"--ptr-transition-duration": vars.$duration.s6,
},
indicator: {
display: "flex",
alignItems: "center",
justifyContent: "center",
},
},
variants: {},
defaultVariants: {},
});

export default pullToRefresh;
10 changes: 7 additions & 3 deletions packages/react-headless/pull-to-refresh/src/PullToRefresh.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,17 @@ export const PullToRefreshRoot = forwardRef<HTMLDivElement, PullToRefreshRootPro
);
PullToRefreshRoot.displayName = "PullToRefreshRoot";

export interface PullToRefreshIndicatorProps {
export interface PullToRefreshIndicatorProps
extends Omit<React.HTMLAttributes<HTMLDivElement>, "children"> {
children: (props: PullToRefreshIndicatorRenderProps) => React.ReactNode;
}

export const PullToRefreshIndicator = ({ children }: PullToRefreshIndicatorProps) => {
export const PullToRefreshIndicator = (props: PullToRefreshIndicatorProps) => {
const { children, ...otherProps } = props;
const { indicatorProps, getIndicatorRenderProps } = usePullToRefreshContext();
return <div {...indicatorProps}>{children(getIndicatorRenderProps())}</div>;
return (
<div {...mergeProps(indicatorProps, otherProps)}>{children(getIndicatorRenderProps())}</div>
);
};

export interface PullToRefreshContentProps
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,6 @@ export function usePullToRefresh(props: UsePullToRefreshProps) {
width: "100%",
height: `var(--ptr-size, ${threshold}px)`,
marginBottom: `calc(var(--ptr-size, ${threshold}px) * -1)`,
display: "flex",
justifyContent: "center",
alignItems: "center",
},
}),
getIndicatorRenderProps: () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export {
PullToRefreshContent as Content,
PullToRefreshIndicator as Indicator,
PullToRefreshRoot as Root,
type PullToRefreshContentProps as ContentProps,
type PullToRefreshIndicatorProps as IndicatorProps,
type PullToRefreshRootProps as RootProps,
} from "./PullToRefresh";
25 changes: 25 additions & 0 deletions packages/react/src/components/PullToRefresh/PullToRefresh.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { PullToRefresh as PullToRefreshPrimitive } from "@seed-design/react-pull-to-refresh";
import { pullToRefresh, type PullToRefreshVariantProps } from "@seed-design/recipe/pullToRefresh";
import { createStyleContext } from "../../utils/createStyleContext";

const { withContext, withProvider } = createStyleContext(pullToRefresh);

export interface PullToRefreshRootProps
extends PullToRefreshVariantProps,
PullToRefreshPrimitive.RootProps {}

export const PullToRefreshRoot = withProvider<SVGSVGElement, PullToRefreshRootProps>(
PullToRefreshPrimitive.Root,
"root",
);

export interface PullToRefreshIndicatorProps extends PullToRefreshPrimitive.IndicatorProps {}

export const PullToRefreshIndicator = withContext<SVGCircleElement, PullToRefreshIndicatorProps>(
PullToRefreshPrimitive.Indicator,
"indicator",
);

export interface PullToRefreshContentProps extends PullToRefreshPrimitive.ContentProps {}

export const PullToRefreshContent = PullToRefreshPrimitive.Content;
10 changes: 10 additions & 0 deletions packages/react/src/components/PullToRefresh/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export {
PullToRefreshContent,
PullToRefreshIndicator,
PullToRefreshRoot,
type PullToRefreshContentProps,
type PullToRefreshIndicatorProps,
type PullToRefreshRootProps,
} from "./PullToRefresh";

export * as PullToRefresh from "./PullToRefresh.namespace";
1 change: 1 addition & 0 deletions packages/react/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export * from "./Inline";
export * from "./InlineBanner";
export * from "./MannerTempBadge";
export * from "./ProgressCircle";
export * from "./PullToRefresh";
export * from "./ReactionButton";
export * from "./SegmentedControl";
export * from "./SelectBox";
Expand Down
21 changes: 21 additions & 0 deletions packages/recipe/lib/pullToRefresh.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
declare interface PullToRefreshVariant {

}

declare type PullToRefreshVariantMap = {
[key in keyof PullToRefreshVariant]: Array<PullToRefreshVariant[key]>;
};

export declare type PullToRefreshVariantProps = Partial<PullToRefreshVariant>;

export declare type PullToRefreshSlotName = "root" | "indicator";

export declare const pullToRefreshVariantMap: PullToRefreshVariantMap;

export declare const pullToRefresh: ((
props?: PullToRefreshVariantProps,
) => Record<PullToRefreshSlotName, string>) & {
splitVariantProps: <T extends PullToRefreshVariantProps>(
props: T,
) => [PullToRefreshVariantProps, Omit<T, keyof PullToRefreshVariantProps>];
}
35 changes: 35 additions & 0 deletions packages/recipe/lib/pullToRefresh.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { createClassName } from "./className.mjs";
import { mergeVariants } from "./mergeVariants.mjs";
import { splitVariantProps } from "./splitVariantProps.mjs";

const pullToRefreshSlotNames = [
[
"root",
"pullToRefresh__root"
],
[
"indicator",
"pullToRefresh__indicator"
]
];

const defaultVariant = {};

const compoundVariants = [];

export const pullToRefreshVariantMap = {};

export const pullToRefreshVariantKeys = Object.keys(pullToRefreshVariantMap);

export function pullToRefresh(props) {
return Object.fromEntries(
pullToRefreshSlotNames.map(([slot, className]) => {
return [
slot,
createClassName(className, mergeVariants(defaultVariant, props), compoundVariants),
];
}),
);
}

Object.assign(pullToRefresh, { splitVariantProps: (props) => splitVariantProps(props, pullToRefreshVariantMap) });
11 changes: 11 additions & 0 deletions packages/stylesheet/component.css
Original file line number Diff line number Diff line change
Expand Up @@ -5127,3 +5127,14 @@
.appBarMain__root--tone_transparent, .appBarMain__title--tone_transparent, .appBarMain__subtitle--tone_transparent {
color: var(--seed-v3-color-palette-static-white);
}

.pullToRefresh__root {
--ptr-size: 44px;
--ptr-transition-duration: var(--seed-v3-duration-s6);
}

.pullToRefresh__indicator {
justify-content: center;
align-items: center;
display: flex;
}
2 changes: 1 addition & 1 deletion packages/stylesheet/component.min.css

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions packages/stylesheet/pullToRefresh.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.pullToRefresh__root {
--ptr-size: 44px;
--ptr-transition-duration: var(--seed-v3-duration-s6)
}
.pullToRefresh__indicator {
display: flex;
align-items: center;
justify-content: center
}

0 comments on commit 2ad0d0d

Please sign in to comment.