Skip to content

Commit

Permalink
feat: progress circle transition
Browse files Browse the repository at this point in the history
  • Loading branch information
junghyeonsu committed Sep 12, 2024
1 parent 0a46ae9 commit e00fc8b
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 101 deletions.
116 changes: 47 additions & 69 deletions component-docs/src/components/ProgressCircleControls.tsx
Original file line number Diff line number Diff line change
@@ -1,87 +1,65 @@
import * as React from "react";

import { BoxButton } from "@/seed-design/ui/box-button";
import {
useProgressCircleMaxValue,
useProgressCircleMinValue,
useProgressCircleActions,
useProgressCircleDuration,
useProgressCircleEasing,
useProgressCircleValue,
useProgressCircleActions,
} from "@/src/stores/progress-circle";
import * as React from "react";

import * as css from "./ProgressCircleControls.css";

export const ProgressCircleControls = () => {
const [value, setValue] = React.useState(useProgressCircleValue());
const [maxValue, setMaxValue] = React.useState(useProgressCircleMaxValue());
const [minValue, setMinValue] = React.useState(useProgressCircleMinValue());
const { set } = useProgressCircleActions();

const [duration, setDuration] = React.useState(useProgressCircleDuration());
const [easing, setEasing] = React.useState(useProgressCircleEasing());

const { set } = useProgressCircleActions();

return (
<div>
<div className={css.controlBlock}>
<label className={css.controlLabel} htmlFor="value">
value
</label>
<input
className={css.controlInput}
id="value"
value={value}
onChange={(e) => setValue(Number(e.target.value))}
min={minValue}
max={maxValue}
/>
</div>
<div className={css.controlBlock}>
<label className={css.controlLabel} htmlFor="min-value">
Min Value
</label>
<input
className={css.controlInput}
id="min-value"
value={minValue}
onChange={(e) => setMinValue(Number(e.target.value))}
/>
</div>
<div className={css.controlBlock}>
<label className={css.controlLabel} htmlFor="max-value">
Max Value
</label>
<input
className={css.controlInput}
id="max-value"
value={maxValue}
onChange={(e) => setMaxValue(Number(e.target.value))}
/>
</div>
<div className={css.controlBlock}>
<label className={css.controlLabel} htmlFor="duration">
Duration
</label>
<input
className={css.controlInput}
id="duration"
value={duration}
onChange={(e) => setDuration(e.target.value)}
/>
</div>
<div className={css.controlBlock}>
<label className={css.controlLabel} htmlFor="easing">
Easing
</label>
<input
className={css.controlInput}
id="easing"
value={easing}
onChange={(e) => setEasing(e.target.value)}
/>
</div>
<BoxButton type="button" onClick={() => set({ value, minValue, maxValue, duration, easing })}>
적용
<BoxButton type="button" onClick={() => set({ value: 0 })}>
0%
</BoxButton>
<BoxButton type="button" onClick={() => set({ value: 25 })}>
25%
</BoxButton>
<BoxButton type="button" onClick={() => set({ value: 50 })}>
50%
</BoxButton>
<BoxButton type="button" onClick={() => set({ value: 75 })}>
75%
</BoxButton>
<BoxButton type="button" onClick={() => set({ value: 100 })}>
100%
</BoxButton>

<div>
<div className={css.controlBlock}>
<label className={css.controlLabel} htmlFor="duration">
Duration
</label>
<input
className={css.controlInput}
id="duration"
value={duration}
onChange={(e) => setDuration(e.target.value)}
/>
</div>
<div className={css.controlBlock}>
<label className={css.controlLabel} htmlFor="easing">
Easing
</label>
<input
className={css.controlInput}
id="easing"
value={easing}
onChange={(e) => setEasing(e.target.value)}
/>
</div>
<BoxButton type="button" onClick={() => set({ duration, easing })}>
적용
</BoxButton>
</div>
</div>
);
};
6 changes: 3 additions & 3 deletions component-docs/src/stores/progress-circle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ interface ProgressCircleState {
setValue: (value: number) => void;
setMinValue: (minValue: number) => void;
setMaxValue: (maxValue: number) => void;
set: (state: Omit<ProgressCircleState, "actions">) => void;
set: (state: Partial<Omit<ProgressCircleState, "actions">>) => void;
};
}

const useProgressCircle = create<ProgressCircleState>((set) => ({
duration: "0.3s",
easing: "cubic-bezier(0.35, 0.25, 0.65, 0.75)",
duration: "0.4s",
easing: "cubic-bezier(0, 0, 0.15, 1)",
value: 0,
minValue: 0,
maxValue: 100,
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"build:dts": "ultra -r --build build:dts",
"build:style": "ultra -r --build build:style",
"build:style:re": "ultra -r --rebuild build:style",
"build:style:watch": "watchlist packages -- yarn build:style",
"build:style:watch": "watchlist packages -- yarn build:style:re",
"build:headless": "ultra -r --filter 'packages/react-headless/*' build",
"build-only-package": "ultra -r --filter 'packages/*' build",
"generate": "ultra -r generate",
Expand Down
10 changes: 10 additions & 0 deletions packages/component-spec/artifacts/progress-circle.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,19 @@ variant=indeterminate:
root:
track:
indicator:
indicator-path:
headDashDuration: 1.2s
tailDashDuration: 1.2s
rotateDuration: 1.2s
headDashTimingFunction: cubic-bezier(0.35, 0, 0.65, 1)
tailDashTimingFunction: cubic-bezier(0.35, 0, 0.65, 0.6)
rotateTimingFunction: cubic-bezier(0.35, 0.25, 0.65, 0.75)

variant=determinate:
enabled:
root:
track:
indicator:
indicator-path:
transitionDuration: 0.4s
transitionTimingFunction: cubic-bezier(0, 0, 0.15, 1)

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 6 additions & 16 deletions packages/recipe-generator/preset/src/progress-circle.recipe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,30 +62,20 @@ const progressCircle = defineRecipe({
variant: {
indeterminate: {
root: {
"--seed-spinner-indeterminate-duration": "1.2s",
"--seed-spinner-indeterminate-timing-function": "cubic-bezier(0.35, 0.25, 0.65, 0.75)",

animation:
"rotate var(--seed-spinner-indeterminate-duration) var(--seed-spinner-indeterminate-timing-function) 0s infinite normal none running",
animation: `rotate ${vars.variantIndeterminate.enabled["indicator-path"].rotateDuration} ${vars.variantIndeterminate.enabled["indicator-path"].rotateTimingFunction} infinite`,
},
"indicator-path": {
"--seed-spinner-indeterminate-head-dash-timing-function":
"cubic-bezier(0.35, 0, 0.65, 1)",
"--seed-spinner-indeterminate-tail-dash-timing-function":
"cubic-bezier(0.35, 0, 0.65, 0.6)",

animation: `
headDash var(--seed-spinner-indeterminate-duration) var(--seed-spinner-indeterminate-head-dash-timing-function) 0s infinite normal none running,
tailDash var(--seed-spinner-indeterminate-duration) var(--seed-spinner-indeterminate-tail-dash-timing-function) 0s infinite normal none running
headDash ${vars.variantIndeterminate.enabled["indicator-path"].headDashDuration} ${vars.variantIndeterminate.enabled["indicator-path"].headDashTimingFunction} infinite normal none running,
tailDash ${vars.variantIndeterminate.enabled["indicator-path"].tailDashDuration} ${vars.variantIndeterminate.enabled["indicator-path"].tailDashTimingFunction} infinite normal none running
`,
},
},
determinate: {
"indicator-path": {
transitionDuration: "var(--seed-spinner-determinate-duration, 0.3s)",
transitionTimingFunction:
"var(--seed-spinner-determinate-timing-function, cubic-bezier(0.35, 0.25, 0.65, 0.75))",
transitionProperty: "stroke-dasharray, stroke-linecap",
transitionDuration: `var(--seed-spinner-determinate-duration, ${vars.variantDeterminate.enabled["indicator-path"].transitionDuration})`,
transitionTimingFunction: `var(--seed-spinner-determinate-timing-function, ${vars.variantDeterminate.enabled["indicator-path"].transitionTimingFunction})`,
transitionProperty: "stroke-dasharray",
},
},
},
Expand Down
16 changes: 6 additions & 10 deletions packages/stylesheet/progressCircle.css
Original file line number Diff line number Diff line change
Expand Up @@ -38,22 +38,18 @@
height: var(--seed-unit-10)
}
.progressCircle__root--variant_indeterminate {
--seed-spinner-indeterminate-duration: 1.2s;
--seed-spinner-indeterminate-timing-function: cubic-bezier(0.35, 0.25, 0.65, 0.75);
animation: rotate var(--seed-spinner-indeterminate-duration) var(--seed-spinner-indeterminate-timing-function) 0s infinite normal none running
animation: rotate 1.2s cubic-bezier(0.35, 0.25, 0.65, 0.75) infinite
}
.progressCircle__indicator-path--variant_indeterminate {
--seed-spinner-indeterminate-head-dash-timing-function: cubic-bezier(0.35, 0, 0.65, 1);
--seed-spinner-indeterminate-tail-dash-timing-function: cubic-bezier(0.35, 0, 0.65, 0.6);
animation:
headDash var(--seed-spinner-indeterminate-duration) var(--seed-spinner-indeterminate-head-dash-timing-function) 0s infinite normal none running,
tailDash var(--seed-spinner-indeterminate-duration) var(--seed-spinner-indeterminate-tail-dash-timing-function) 0s infinite normal none running
headDash 1.2s cubic-bezier(0.35, 0, 0.65, 1) infinite normal none running,
tailDash 1.2s cubic-bezier(0.35, 0, 0.65, 0.6) infinite normal none running

}
.progressCircle__indicator-path--variant_determinate {
transition-duration: var(--seed-spinner-determinate-duration, 0.3s);
transition-timing-function: var(--seed-spinner-determinate-timing-function, cubic-bezier(0.35, 0.25, 0.65, 0.75));
transition-property: stroke-dasharray, stroke-linecap
transition-duration: var(--seed-spinner-determinate-duration, 0.4s);
transition-timing-function: var(--seed-spinner-determinate-timing-function, cubic-bezier(0, 0, 0.15, 1));
transition-property: stroke-dasharray
}
@keyframes rotate {
from {
Expand Down

0 comments on commit e00fc8b

Please sign in to comment.