mirror of
https://github.com/storytold/placeholder-artcraft.git
synced 2026-10-28 08:56:48 +00:00
mirror repo (WIP)
Need to remove secrets before entire repo can be made public.
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"presets": [
|
||||
[
|
||||
"@nx/react/babel",
|
||||
{
|
||||
"runtime": "automatic",
|
||||
"useBuiltIns": "usage"
|
||||
}
|
||||
]
|
||||
],
|
||||
"plugins": []
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# @storyteller/ui-progress
|
||||
|
||||
This library was generated with [Nx](https://nx.dev).
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `nx test @storyteller/ui-progress` to execute the unit tests via [Vitest](https://vitest.dev/).
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "@storyteller/ui-progress",
|
||||
"version": "0.0.1",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"development": "./src/index.ts",
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from "./lib/progress";
|
||||
export * from "./lib/progress-circle";
|
||||
@@ -0,0 +1,104 @@
|
||||
import { HTMLAttributes } from "react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
interface ProgressCircleProps extends HTMLAttributes<HTMLDivElement> {
|
||||
value?: number;
|
||||
max?: number;
|
||||
isLow?: boolean;
|
||||
size?: "small" | "large";
|
||||
showPercentage?: boolean;
|
||||
reverse?: boolean;
|
||||
}
|
||||
|
||||
export const ProgressCircle = ({
|
||||
value = 0,
|
||||
max = 100,
|
||||
isLow = false,
|
||||
size = "large",
|
||||
showPercentage = false,
|
||||
reverse = false,
|
||||
className,
|
||||
...props
|
||||
}: ProgressCircleProps) => {
|
||||
const percentage = Math.min(Math.max(0, value), max);
|
||||
const displayPercentage = percentage;
|
||||
|
||||
// Make small circles actually smaller
|
||||
const radius = size === "small" ? 8 : 40;
|
||||
const strokeWidth = size === "small" ? 4 : 6;
|
||||
const circumference = 2 * Math.PI * radius;
|
||||
|
||||
// Calculate stroke dashoffset differently based on direction
|
||||
const strokeDashoffset = reverse
|
||||
? (percentage / 100) * circumference // Counter-clockwise
|
||||
: circumference - (percentage / 100) * circumference; // Clockwise
|
||||
|
||||
const viewBoxSize = (radius + strokeWidth) * 2;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={twMerge(
|
||||
"relative inline-flex items-center justify-center",
|
||||
size === "small" ? "h-5 w-5" : "h-24 w-24",
|
||||
showPercentage && size === "small" ? "mr-6" : "", // Add margin for small with label
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{/* For small size, show percentage label outside to the right */}
|
||||
{showPercentage && size === "small" && (
|
||||
<div className="absolute -right-6 flex items-center justify-center">
|
||||
<span className="text-xs font-medium">
|
||||
{Math.round(displayPercentage)}%
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<svg
|
||||
className={`absolute h-full w-full ${
|
||||
reverse ? "rotate-90" : "-rotate-90"
|
||||
}`}
|
||||
viewBox={`0 0 ${viewBoxSize} ${viewBoxSize}`}
|
||||
>
|
||||
<circle
|
||||
className="stroke-white/20"
|
||||
cx={viewBoxSize / 2}
|
||||
cy={viewBoxSize / 2}
|
||||
r={radius}
|
||||
fill="none"
|
||||
strokeWidth={strokeWidth}
|
||||
/>
|
||||
<circle
|
||||
className={twMerge(
|
||||
"transition-all",
|
||||
isLow ? "stroke-red/80" : "stroke-primary"
|
||||
)}
|
||||
cx={viewBoxSize / 2}
|
||||
cy={viewBoxSize / 2}
|
||||
r={radius}
|
||||
fill="none"
|
||||
strokeWidth={strokeWidth}
|
||||
strokeDasharray={circumference}
|
||||
strokeDashoffset={strokeDashoffset}
|
||||
strokeLinecap="round"
|
||||
transform={
|
||||
reverse
|
||||
? `rotate(180, ${viewBoxSize / 2}, ${viewBoxSize / 2})`
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
</svg>
|
||||
|
||||
{/* For large size, show percentage in the center */}
|
||||
{showPercentage && size === "large" && (
|
||||
<div className="absolute flex flex-col items-center justify-center text-center">
|
||||
<span className="text-xl font-medium">
|
||||
{Math.round(displayPercentage)}%
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ProgressCircle;
|
||||
@@ -0,0 +1,7 @@
|
||||
/*
|
||||
* Replace this with your own classes
|
||||
*
|
||||
* e.g.
|
||||
* .container {
|
||||
* }
|
||||
*/
|
||||
@@ -0,0 +1,12 @@
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import StorytellerUiProgress from './progress';
|
||||
|
||||
describe('StorytellerUiProgress', () => {
|
||||
|
||||
it('should render successfully', () => {
|
||||
const { baseElement } = render(<StorytellerUiProgress />);
|
||||
expect(baseElement).toBeTruthy();
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,42 @@
|
||||
import { HTMLAttributes } from "react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
interface ProgressProps extends HTMLAttributes<HTMLDivElement> {
|
||||
value?: number;
|
||||
max?: number;
|
||||
isLow?: boolean;
|
||||
}
|
||||
|
||||
export const Progress = ({
|
||||
value = 0,
|
||||
max = 100,
|
||||
isLow = false,
|
||||
className,
|
||||
...props
|
||||
}: ProgressProps) => {
|
||||
const percentage = Math.min(Math.max(0, value), max);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={twMerge(
|
||||
"relative h-2 w-full overflow-hidden rounded-full bg-secondary",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<div
|
||||
className={twMerge(
|
||||
"h-full w-full flex-1 transition-all",
|
||||
isLow ? "bg-red/60" : "bg-primary"
|
||||
)}
|
||||
style={{ transform: `translateX(-${100 - percentage}%)` }}
|
||||
role="progressbar"
|
||||
aria-valuemin={0}
|
||||
aria-valuemax={max}
|
||||
aria-valuenow={percentage}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Progress;
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
],
|
||||
"extends": "../../../tsconfig.base.json"
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"types": [
|
||||
"node",
|
||||
"@nx/react/typings/cssmodule.d.ts",
|
||||
"@nx/react/typings/image.d.ts",
|
||||
"vite/client"
|
||||
],
|
||||
"rootDir": "src",
|
||||
"jsx": "react-jsx",
|
||||
"tsBuildInfoFile": "dist/tsconfig.lib.tsbuildinfo"
|
||||
},
|
||||
"exclude": [
|
||||
"out-tsc",
|
||||
"dist",
|
||||
"**/*.spec.ts",
|
||||
"**/*.test.ts",
|
||||
"**/*.spec.tsx",
|
||||
"**/*.test.tsx",
|
||||
"**/*.spec.js",
|
||||
"**/*.test.js",
|
||||
"**/*.spec.jsx",
|
||||
"**/*.test.jsx",
|
||||
"vite.config.ts",
|
||||
"vite.config.mts",
|
||||
"vitest.config.ts",
|
||||
"vitest.config.mts",
|
||||
"src/**/*.test.ts",
|
||||
"src/**/*.spec.ts",
|
||||
"src/**/*.test.tsx",
|
||||
"src/**/*.spec.tsx",
|
||||
"src/**/*.test.js",
|
||||
"src/**/*.spec.js",
|
||||
"src/**/*.test.jsx",
|
||||
"src/**/*.spec.jsx"
|
||||
],
|
||||
"include": [
|
||||
"src/**/*.js",
|
||||
"src/**/*.jsx",
|
||||
"src/**/*.ts",
|
||||
"src/**/*.tsx"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./out-tsc/vitest",
|
||||
"types": [
|
||||
"vitest/globals",
|
||||
"vitest/importMeta",
|
||||
"vite/client",
|
||||
"node",
|
||||
"vitest"
|
||||
],
|
||||
"jsx": "react-jsx"
|
||||
},
|
||||
"include": [
|
||||
"vite.config.ts",
|
||||
"vite.config.mts",
|
||||
"vitest.config.ts",
|
||||
"vitest.config.mts",
|
||||
"src/**/*.test.ts",
|
||||
"src/**/*.spec.ts",
|
||||
"src/**/*.test.tsx",
|
||||
"src/**/*.spec.tsx",
|
||||
"src/**/*.test.js",
|
||||
"src/**/*.spec.js",
|
||||
"src/**/*.test.jsx",
|
||||
"src/**/*.spec.jsx",
|
||||
"src/**/*.d.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/// <reference types='vitest' />
|
||||
import { defineConfig } from 'vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
import dts from 'vite-plugin-dts';
|
||||
import * as path from 'path';
|
||||
|
||||
export default defineConfig(() => ({
|
||||
root: __dirname,
|
||||
cacheDir: '../../../node_modules/.vite/libs/components/progress',
|
||||
plugins: [react(), dts({ entryRoot: 'src', tsconfigPath: path.join(__dirname, 'tsconfig.lib.json') })],
|
||||
// Uncomment this if you are using workers.
|
||||
// worker: {
|
||||
// plugins: [ nxViteTsPaths() ],
|
||||
// },
|
||||
// Configuration for building your library.
|
||||
// See: https://vitejs.dev/guide/build.html#library-mode
|
||||
build: {
|
||||
outDir: './dist',
|
||||
emptyOutDir: true,
|
||||
reportCompressedSize: true,
|
||||
commonjsOptions: {
|
||||
transformMixedEsModules: true,
|
||||
},
|
||||
lib: {
|
||||
// Could also be a dictionary or array of multiple entry points.
|
||||
entry: 'src/index.ts',
|
||||
name: '@storyteller/ui-progress',
|
||||
fileName: 'index',
|
||||
// Change this to the formats you want to support.
|
||||
// Don't forget to update your package.json as well.
|
||||
formats: ['es' as const]
|
||||
},
|
||||
rollupOptions: {
|
||||
// External packages that should not be bundled into your library.
|
||||
external: ['react','react-dom','react/jsx-runtime']
|
||||
},
|
||||
},
|
||||
test: {
|
||||
watch: false,
|
||||
globals: true,
|
||||
environment: 'jsdom',
|
||||
include: ['{src,tests}/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
||||
reporters: ['default'],
|
||||
coverage: {
|
||||
reportsDirectory: './test-output/vitest/coverage',
|
||||
provider: 'v8' as const,
|
||||
}
|
||||
},
|
||||
}));
|
||||
Reference in New Issue
Block a user