UNPKG

@mantine/core

Version:

React components library focused on usability, accessibility and developer experience

1 lines 7.59 kB
{"version":3,"file":"SemiCircleProgress.cjs","names":["createVarsResolver","getThemeColor","rem","factory","useProps","useStyles","Box","classes"],"sources":["../../../src/components/SemiCircleProgress/SemiCircleProgress.tsx"],"sourcesContent":["import { clamp } from '@mantine/hooks';\nimport {\n Box,\n BoxProps,\n createVarsResolver,\n ElementProps,\n factory,\n Factory,\n getThemeColor,\n MantineColor,\n rem,\n StylesApiProps,\n useProps,\n useStyles,\n} from '../../core';\nimport classes from './SemiCircleProgress.module.css';\n\nexport type SemiCircleProgressStylesNames =\n | 'root'\n | 'svg'\n | 'emptySegment'\n | 'filledSegment'\n | 'label';\n\nexport type SemiCircleProgressCssVariables = {\n root:\n | '--scp-filled-segment-color'\n | '--scp-empty-segment-color'\n | '--scp-rotation'\n | '--scp-transition-duration'\n | '--scp-thickness';\n};\n\nexport interface SemiCircleProgressProps\n extends BoxProps, StylesApiProps<SemiCircleProgressFactory>, ElementProps<'div'> {\n /** Progress value from `0` to `100` */\n value: number;\n\n /** Width of the component and diameter of the full circle in px. The visible SVG height will be size/2 @default 200 */\n size?: number;\n\n /** Stroke width of the circle segments in px @default 12 */\n thickness?: number;\n\n /** Orientation of the circle @default 'up' */\n orientation?: 'up' | 'down';\n\n /** Direction from which the circle is filled @default 'left-to-right' */\n fillDirection?: 'right-to-left' | 'left-to-right';\n\n /** Key of `theme.colors` or any valid CSS color value @default theme.primaryColor */\n filledSegmentColor?: MantineColor;\n\n /** Key of `theme.colors` or any valid CSS color value @default 'gray.2' in light mode, 'dark.4' in dark mode */\n emptySegmentColor?: MantineColor;\n\n /** Transition duration for the filled segment progress changes in ms. Does not affect color transitions @default 0 */\n transitionDuration?: number;\n\n /** Label rendered inside the circle */\n label?: React.ReactNode;\n\n /** Label position relative to the circle center @default 'bottom' */\n labelPosition?: 'center' | 'bottom';\n}\n\nexport type SemiCircleProgressFactory = Factory<{\n props: SemiCircleProgressProps;\n ref: HTMLDivElement;\n stylesNames: SemiCircleProgressStylesNames;\n vars: SemiCircleProgressCssVariables;\n}>;\n\nconst defaultProps = {\n size: 200,\n thickness: 12,\n orientation: 'up',\n fillDirection: 'left-to-right',\n labelPosition: 'bottom',\n} satisfies Partial<SemiCircleProgressProps>;\n\nfunction getRotation({\n orientation,\n fillDirection,\n}: Pick<SemiCircleProgressProps, 'orientation' | 'fillDirection'>) {\n if (orientation === 'down') {\n if (fillDirection === 'right-to-left') {\n return 'rotate(180deg) rotateY(180deg)';\n }\n return 'rotate(180deg)';\n }\n if (fillDirection === 'left-to-right') {\n return 'rotateY(180deg)';\n }\n\n return undefined;\n}\n\nconst varsResolver = createVarsResolver<SemiCircleProgressFactory>(\n (\n theme,\n {\n filledSegmentColor,\n emptySegmentColor,\n orientation,\n fillDirection,\n transitionDuration,\n thickness,\n }\n ) => ({\n root: {\n '--scp-filled-segment-color': filledSegmentColor\n ? getThemeColor(filledSegmentColor, theme)\n : undefined,\n '--scp-empty-segment-color': emptySegmentColor\n ? getThemeColor(emptySegmentColor, theme)\n : undefined,\n '--scp-rotation': getRotation({ orientation, fillDirection }),\n '--scp-transition-duration': transitionDuration ? `${transitionDuration}ms` : undefined,\n '--scp-thickness': rem(thickness),\n },\n })\n);\n\nexport const SemiCircleProgress = factory<SemiCircleProgressFactory>((_props) => {\n const props = useProps('SemiCircleProgress', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n size,\n thickness,\n value,\n orientation,\n fillDirection,\n filledSegmentColor,\n emptySegmentColor,\n transitionDuration,\n label,\n labelPosition,\n attributes,\n ...others\n } = props;\n\n const getStyles = useStyles<SemiCircleProgressFactory>({\n name: 'SemiCircleProgress',\n classes,\n props,\n className,\n style,\n classNames,\n styles,\n unstyled,\n attributes,\n vars,\n varsResolver,\n });\n\n const coordinateForCircle = size / 2;\n const radius = (size - 2 * thickness) / 2;\n const circumference = Math.PI * radius;\n const semiCirclePercentage = clamp(value, 0, 100) * (circumference / 100);\n\n return (\n <Box size={size} {...getStyles('root')} {...others}>\n {label && (\n <div {...getStyles('label')} data-position={labelPosition} data-orientation={orientation}>\n {label}\n </div>\n )}\n\n <svg width={size} height={size / 2} {...getStyles('svg')}>\n <circle\n cx={coordinateForCircle}\n cy={coordinateForCircle}\n r={radius}\n fill=\"none\"\n stroke=\"var(--scp-empty-segment-color)\"\n strokeWidth={thickness}\n strokeDasharray={circumference}\n {...getStyles('emptySegment', { style: { strokeDashoffset: circumference } })}\n />\n\n <circle\n cx={coordinateForCircle}\n cy={coordinateForCircle}\n r={radius}\n fill=\"none\"\n stroke=\"var(--scp-filled-segment-color)\"\n strokeWidth={thickness}\n strokeDasharray={circumference}\n {...getStyles('filledSegment', { style: { strokeDashoffset: semiCirclePercentage } })}\n />\n </svg>\n </Box>\n );\n});\n\nSemiCircleProgress.displayName = '@mantine/core/SemiCircleProgress';\nSemiCircleProgress.classes = classes;\nSemiCircleProgress.varsResolver = varsResolver;\n"],"mappings":";;;;;;;;;;;;;AAyEA,MAAM,eAAe;CACnB,MAAM;CACN,WAAW;CACX,aAAa;CACb,eAAe;CACf,eAAe;CAChB;AAED,SAAS,YAAY,EACnB,aACA,iBACiE;AACjE,KAAI,gBAAgB,QAAQ;AAC1B,MAAI,kBAAkB,gBACpB,QAAO;AAET,SAAO;;AAET,KAAI,kBAAkB,gBACpB,QAAO;;AAMX,MAAM,eAAeA,6BAAAA,oBAEjB,OACA,EACE,oBACA,mBACA,aACA,eACA,oBACA,iBAEE,EACJ,MAAM;CACJ,8BAA8B,qBAC1BC,wBAAAA,cAAc,oBAAoB,MAAM,GACxC,KAAA;CACJ,6BAA6B,oBACzBA,wBAAAA,cAAc,mBAAmB,MAAM,GACvC,KAAA;CACJ,kBAAkB,YAAY;EAAE;EAAa;EAAe,CAAC;CAC7D,6BAA6B,qBAAqB,GAAG,mBAAmB,MAAM,KAAA;CAC9E,mBAAmBC,YAAAA,IAAI,UAAU;CAClC,EACF,EACF;AAED,MAAa,qBAAqBC,gBAAAA,SAAoC,WAAW;CAC/E,MAAM,QAAQC,kBAAAA,SAAS,sBAAsB,cAAc,OAAO;CAClE,MAAM,EACJ,YACA,WACA,OACA,QACA,UACA,MACA,MACA,WACA,OACA,aACA,eACA,oBACA,mBACA,oBACA,OACA,eACA,YACA,GAAG,WACD;CAEJ,MAAM,YAAYC,mBAAAA,UAAqC;EACrD,MAAM;EACN,SAAA,kCAAA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;CAEF,MAAM,sBAAsB,OAAO;CACnC,MAAM,UAAU,OAAO,IAAI,aAAa;CACxC,MAAM,gBAAgB,KAAK,KAAK;CAChC,MAAM,wBAAA,GAAA,eAAA,OAA6B,OAAO,GAAG,IAAI,IAAI,gBAAgB;AAErE,QACE,iBAAA,GAAA,kBAAA,MAACC,YAAAA,KAAD;EAAW;EAAM,GAAI,UAAU,OAAO;EAAE,GAAI;YAA5C,CACG,SACC,iBAAA,GAAA,kBAAA,KAAC,OAAD;GAAK,GAAI,UAAU,QAAQ;GAAE,iBAAe;GAAe,oBAAkB;aAC1E;GACG,CAAA,EAGR,iBAAA,GAAA,kBAAA,MAAC,OAAD;GAAK,OAAO;GAAM,QAAQ,OAAO;GAAG,GAAI,UAAU,MAAM;aAAxD,CACE,iBAAA,GAAA,kBAAA,KAAC,UAAD;IACE,IAAI;IACJ,IAAI;IACJ,GAAG;IACH,MAAK;IACL,QAAO;IACP,aAAa;IACb,iBAAiB;IACjB,GAAI,UAAU,gBAAgB,EAAE,OAAO,EAAE,kBAAkB,eAAe,EAAE,CAAC;IAC7E,CAAA,EAEF,iBAAA,GAAA,kBAAA,KAAC,UAAD;IACE,IAAI;IACJ,IAAI;IACJ,GAAG;IACH,MAAK;IACL,QAAO;IACP,aAAa;IACb,iBAAiB;IACjB,GAAI,UAAU,iBAAiB,EAAE,OAAO,EAAE,kBAAkB,sBAAsB,EAAE,CAAC;IACrF,CAAA,CACE;KACF;;EAER;AAEF,mBAAmB,cAAc;AACjC,mBAAmB,UAAUC,kCAAAA;AAC7B,mBAAmB,eAAe"}