feat(circular-progress): api improved

This commit is contained in:
Junior Garcia 2023-04-01 10:21:05 -03:00
parent c8a57a25fe
commit 6cdbe86ef2
8 changed files with 39 additions and 35 deletions

View File

@ -53,7 +53,7 @@ export function useCircularProgress(originalProps: UseCircularProgressProps) {
styles, styles,
label, label,
valueLabel, valueLabel,
value = 0, value = undefined,
minValue = 0, minValue = 0,
maxValue = 100, maxValue = 100,
showValueLabel = false, showValueLabel = false,
@ -73,7 +73,8 @@ export function useCircularProgress(originalProps: UseCircularProgressProps) {
delay: 100, delay: 100,
}); });
const isIndeterminate = originalProps.isIndeterminate; // default isIndeterminate to true
const isIndeterminate = (originalProps.isIndeterminate ?? true) && value === undefined;
const {progressBarProps, labelProps} = useAriaProgress({ const {progressBarProps, labelProps} = useAriaProgress({
id, id,
@ -92,8 +93,9 @@ export function useCircularProgress(originalProps: UseCircularProgressProps) {
() => () =>
circularProgress({ circularProgress({
...variantProps, ...variantProps,
isIndeterminate,
}), }),
[...Object.values(variantProps)], [isIndeterminate, ...Object.values(variantProps)],
); );
const selfMounted = originalProps.disableAnimation ? true : isMounted; const selfMounted = originalProps.disableAnimation ? true : isMounted;
@ -103,11 +105,18 @@ export function useCircularProgress(originalProps: UseCircularProgressProps) {
const radius = 16 - strokeWidth; const radius = 16 - strokeWidth;
const circumference = 2 * radius * Math.PI; const circumference = 2 * radius * Math.PI;
const percentage = !selfMounted const percentage = useMemo(() => {
? 0 if (!selfMounted) {
: isIndeterminate return 0;
? 0.25 }
: (value - minValue) / (maxValue - minValue);
if (isIndeterminate) {
return 0.25;
}
return value ? (value - minValue) / (maxValue - minValue) : 0;
}, [selfMounted, value, minValue, maxValue, isIndeterminate]);
const offset = circumference - percentage * circumference; const offset = circumference - percentage * circumference;
const getProgressBarProps = useCallback<PropGetter>( const getProgressBarProps = useCallback<PropGetter>(

View File

@ -30,7 +30,6 @@ export default {
const defaultProps = { const defaultProps = {
...circularProgress.defaultVariants, ...circularProgress.defaultVariants,
value: 70,
}; };
const Template: ComponentStory<typeof CircularProgress> = (args: CircularProgressProps) => ( const Template: ComponentStory<typeof CircularProgress> = (args: CircularProgressProps) => (
@ -43,7 +42,7 @@ const IntervalTemplate: ComponentStory<typeof CircularProgress> = (args: Circula
React.useEffect(() => { React.useEffect(() => {
const interval = setInterval(() => { const interval = setInterval(() => {
setValue((v) => (v >= 100 ? 0 : v + 10)); setValue((v) => (v >= 100 ? 0 : v + 10));
}, 800); }, 500);
return () => clearInterval(interval); return () => clearInterval(interval);
}, []); }, []);
@ -67,6 +66,7 @@ export const WithValueLabel = IntervalTemplate.bind({});
WithValueLabel.args = { WithValueLabel.args = {
...defaultProps, ...defaultProps,
size: "lg", size: "lg",
value: 70,
color: "secondary", color: "secondary",
showValueLabel: true, showValueLabel: true,
}; };
@ -76,13 +76,8 @@ WithValueFormatting.args = {
...defaultProps, ...defaultProps,
label: "Loading...", label: "Loading...",
size: "xl", size: "xl",
value: 70,
color: "warning", color: "warning",
showValueLabel: true, showValueLabel: true,
formatOptions: {style: "unit", unit: "kilometer"}, formatOptions: {style: "unit", unit: "kilometer"},
}; };
export const Indeterminate = Template.bind({});
Indeterminate.args = {
...defaultProps,
isIndeterminate: true,
};

View File

@ -51,7 +51,7 @@ const IntervalTemplate: ComponentStory<typeof Progress> = (args: ProgressProps)
React.useEffect(() => { React.useEffect(() => {
const interval = setInterval(() => { const interval = setInterval(() => {
setValue((v) => (v >= 100 ? 0 : v + 10)); setValue((v) => (v >= 100 ? 0 : v + 10));
}, 800); }, 500);
return () => clearInterval(interval); return () => clearInterval(interval);
}, []); }, []);

View File

@ -27,7 +27,7 @@ const circularProgress = tv({
svgWrapper: "relative block", svgWrapper: "relative block",
svg: "z-0 relative overflow-hidden", svg: "z-0 relative overflow-hidden",
circle: "h-full stroke-current", circle: "h-full stroke-current",
value: "absolute font-normal top-0 left-0 w-full h-full flex items-center justify-center", value: "absolute font-normal inset-0 flex items-center justify-center",
}, },
variants: { variants: {
color: { color: {
@ -64,16 +64,16 @@ const circularProgress = tv({
md: { md: {
svg: "w-10 h-10", svg: "w-10 h-10",
label: "text-sm", label: "text-sm",
value: "text-[0.6rem]", value: "text-[0.55rem]",
}, },
lg: { lg: {
svg: "w-12 h-12", svg: "w-12 h-12",
label: "text-base", label: "text-base",
value: "text-xs", value: "text-[0.6rem]",
}, },
xl: { xl: {
svg: "w-14 h-14", svg: "w-14 h-14",
label: "text-lg", label: "text-base",
value: "text-xs", value: "text-xs",
}, },
}, },
@ -97,7 +97,6 @@ const circularProgress = tv({
defaultVariants: { defaultVariants: {
color: "primary", color: "primary",
size: "md", size: "md",
isIndeterminate: false,
isDisabled: false, isDisabled: false,
disableAnimation: false, disableAnimation: false,
}, },

View File

@ -1,14 +1,17 @@
import React from "react"; import React from "react";
import addons from "@storybook/addons";
import {themes} from "@storybook/theming"; import {themes} from "@storybook/theming";
import Style from "./style"; import Style from "./style";
import {Analytics} from "@vercel/analytics/react";
export const decorators = [ export const decorators = [
(Story) => ( (Story) => (
<div className="bg-dark"> <>
<Style /> <div className="bg-dark">
<Story /> <Style />
</div> <Story />
</div>
<Analytics />
</>
), ),
]; ];
@ -17,7 +20,7 @@ export const parameters = {
options: { options: {
storySort: { storySort: {
method: "alphabetical", method: "alphabetical",
order:["Foundations", "Components"], order: ["Foundations", "Components"],
}, },
}, },
controls: { controls: {

View File

@ -136,5 +136,5 @@ import {link, button} from "@nextui-org/theme";
<br /> <br />
<div class="block text-xs text-neutral-400"> <div class="block text-xs text-neutral-400">
Last updated on <time datetime="2023-03-07">March 30, 2023</time> Last updated on <time datetime="2023-03-07">April 01, 2023</time>
</div> </div>

View File

@ -35,6 +35,7 @@
}, },
"dependencies": { "dependencies": {
"@nextui-org/theme": "workspace:*", "@nextui-org/theme": "workspace:*",
"@vercel/analytics": "^0.1.6",
"react": "^18.0.0", "react": "^18.0.0",
"react-dom": "^18.0.0" "react-dom": "^18.0.0"
}, },

9
pnpm-lock.yaml generated
View File

@ -890,9 +890,6 @@ importers:
packages/components/progress: packages/components/progress:
dependencies: dependencies:
'@nextui-org/aria-utils':
specifier: workspace:*
version: link:../../utilities/aria-utils
'@nextui-org/dom-utils': '@nextui-org/dom-utils':
specifier: workspace:* specifier: workspace:*
version: link:../../utilities/dom-utils version: link:../../utilities/dom-utils
@ -1081,9 +1078,6 @@ importers:
packages/components/tooltip: packages/components/tooltip:
dependencies: dependencies:
'@nextui-org/aria-utils':
specifier: workspace:*
version: link:../../utilities/aria-utils
'@nextui-org/dom-utils': '@nextui-org/dom-utils':
specifier: workspace:* specifier: workspace:*
version: link:../../utilities/dom-utils version: link:../../utilities/dom-utils
@ -1446,6 +1440,9 @@ importers:
'@nextui-org/theme': '@nextui-org/theme':
specifier: workspace:* specifier: workspace:*
version: link:../core/theme version: link:../core/theme
'@vercel/analytics':
specifier: ^0.1.6
version: 0.1.6(react@18.2.0)
react: react:
specifier: ^18.2.0 specifier: ^18.2.0
version: 18.2.0 version: 18.2.0