@ngrok/mantle 0.21.1 → 0.21.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -34,11 +34,21 @@ type Props = SvgAttributes & {
34
34
  };
35
35
  /**
36
36
  * A simple circular progress bar.
37
+ *
38
+ * @example
39
+ * <ProgressDonut value={60}>
40
+ * <ProgressDonutIndicator />
41
+ * </ProgressDonut>
37
42
  */
38
43
  declare const ProgressDonut: ({ children, className, max: _max, strokeWidth: _strokeWidth, value: _value, ...props }: Props) => react_jsx_runtime.JSX.Element;
39
44
  type ProgressDonutIndicatorProps = Omit<ComponentProps<"g">, "children">;
40
45
  /**
41
46
  * The indicator for the circular progress bar.
47
+ *
48
+ * @example
49
+ * <ProgressDonut value={60}>
50
+ * <ProgressDonutIndicator />
51
+ * </ProgressDonut>
42
52
  */
43
53
  declare const ProgressDonutIndicator: ({ className, ...props }: ProgressDonutIndicatorProps) => react_jsx_runtime.JSX.Element;
44
54
 
package/dist/progress.js CHANGED
@@ -1,2 +1,2 @@
1
- import{a as l}from"./chunk-AZ56JGNY.js";import y from"clsx";import{createContext as N,useContext as k,useId as C,useMemo as V}from"react";import{jsx as o,jsxs as d}from"react/jsx-runtime";var c=100,p={max:c,strokeWidth:"0.25rem",value:0},b=N(p),S=({children:e,className:t,max:r=c,strokeWidth:n=4,value:s,...u})=>{let a=I(r)?r:c,i=T(s,a)?s:s==null?0:"indeterminate",m=g(n??p.strokeWidth),x=f(i)?i:void 0,v=h(m),P=V(()=>({max:a,strokeWidth:m,value:i}),[a,m,i]);return o(b.Provider,{value:P,children:d("svg",{"aria-valuemax":a,"aria-valuemin":0,"aria-valuenow":x,className:y(i==="indeterminate"&&"animation-duration-[15s] transform-gpu animate-spin",l("size-6 text-gray-200 dark:text-gray-300",t)),"data-max":a,"data-min":0,"data-value":x,height:"100%",role:"progressbar",width:"100%",...u,children:[o("circle",{className:"[r:var(--radius)]",cx:"50%",cy:"50%",fill:"transparent",stroke:"currentColor",strokeWidth:m,style:{"--radius":v}}),e]})})},W=.6,w=({className:e,...t})=>{let r=C(),n=k(b)??p,s=(n.value==="indeterminate"?W:n.value/n.max)*100,u=g(n.strokeWidth),a=h(u);return d("g",{className:l("text-accent-600",e),...t,children:[n.value==="indeterminate"&&o("defs",{children:d("linearGradient",{id:r,children:[o("stop",{className:"stop-opacity-100 stop-color-current",offset:"0%"}),o("stop",{className:"stop-opacity-0 stop-color-current",offset:"95%"})]})}),o("circle",{className:"[r:var(--radius)]",cx:"50%",cy:"50%",fill:"transparent",pathLength:100,stroke:n.value==="indeterminate"?`url(#${r})`:"currentColor",strokeDasharray:100,strokeDashoffset:100-s,strokeLinecap:"round",strokeWidth:u,style:{"--radius":a},"transform-origin":"center",transform:"rotate(-90)"})]})};function D(e,{min:t,max:r}){return Math.min(r,Math.max(t,e))}function g(e){let t=4;if(e==null)return t;typeof e=="number"?t=e:e.endsWith("rem")?t=Number(e.replace("rem",""))*16:t=Number(e);let r=Number.isNaN(t)?4:t;return D(r,{min:1,max:12})}function f(e){return typeof e=="number"}function T(e,t){return f(e)&&!Number.isNaN(e)&&e<=t&&e>=0}function I(e){return f(e)&&!Number.isNaN(e)&&e>0}function h(e){return`calc(50% - ${e/2}px)`}export{S as ProgressDonut,w as ProgressDonutIndicator};
1
+ import{a as l}from"./chunk-AZ56JGNY.js";import b from"clsx";import{createContext as N,useContext as k,useId as C,useMemo as V}from"react";import{jsx as o,jsxs as d}from"react/jsx-runtime";var c=100,p={max:c,strokeWidth:"0.25rem",value:0},g=N(p),S=({children:e,className:t,max:r=c,strokeWidth:n=4,value:s,...u})=>{let a=I(r)?r:c,i=T(s,a)?s:s==null?0:"indeterminate",m=h(n??p.strokeWidth),f=x(i)?i:void 0,P=v(m),y=V(()=>({max:a,strokeWidth:m,value:i}),[a,m,i]);return o(g.Provider,{value:y,children:d("svg",{"aria-valuemax":a,"aria-valuemin":0,"aria-valuenow":f,className:b(i==="indeterminate"&&"animation-duration-[15s] transform-gpu animate-spin",l("size-6 text-gray-200 dark:text-gray-300",t)),"data-max":a,"data-min":0,"data-value":f,height:"100%",role:"progressbar",width:"100%",...u,children:[o("circle",{className:"[r:var(--radius)]",cx:"50%",cy:"50%",fill:"transparent",stroke:"currentColor",strokeWidth:m,style:{"--radius":P}}),e]})})},W=.6,w=({className:e,...t})=>{let r=C(),n=k(g)??p,s=(n.value==="indeterminate"?W:n.value/n.max)*100,u=h(n.strokeWidth),a=v(u);return d("g",{className:l("text-accent-600",e),...t,children:[n.value==="indeterminate"&&o("defs",{children:d("linearGradient",{id:r,children:[o("stop",{className:"stop-opacity-100 stop-color-current",offset:"0%"}),o("stop",{className:"stop-opacity-0 stop-color-current",offset:"95%"})]})}),o("circle",{className:b("[r:var(--radius)]","origin-center"),cx:"50%",cy:"50%",fill:"transparent",pathLength:100,stroke:n.value==="indeterminate"?`url(#${r})`:"currentColor",strokeDasharray:100,strokeDashoffset:100-s,strokeLinecap:"round",strokeWidth:u,style:{"--radius":a},transform:"rotate(-90)"})]})};function D(e,{min:t,max:r}){return Math.min(r,Math.max(t,e))}function h(e){let t=4;if(e==null)return t;typeof e=="number"?t=e:e.endsWith("rem")?t=Number(e.replace("rem",""))*16:t=Number(e);let r=Number.isNaN(t)?4:t;return D(r,{min:1,max:12})}function x(e){return typeof e=="number"}function T(e,t){return x(e)&&!Number.isNaN(e)&&e<=t&&e>=0}function I(e){return x(e)&&!Number.isNaN(e)&&e>0}function v(e){return`calc(50% - ${e/2}px)`}export{S as ProgressDonut,w as ProgressDonutIndicator};
2
2
  //# sourceMappingURL=progress.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/progress/progress-donut.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport { createContext, useContext, useId, useMemo } from \"react\";\nimport type { CSSProperties, ComponentProps, HTMLAttributes } from \"react\";\nimport { cx } from \"../../utils/cx/cx.js\";\n\ntype RemValue = `${number}rem`;\ntype StrokeWidth = number | RemValue;\ntype ValueType = number | \"indeterminate\";\n\n/**\n * The default maximum value of the progress bar.\n */\nconst defaultMax = 100;\n\ntype ProgressContextValue = {\n\tmax: number;\n\tstrokeWidth: StrokeWidth;\n\tvalue: ValueType;\n};\n\nconst defaultContextValue = {\n\tmax: defaultMax,\n\tstrokeWidth: \"0.25rem\",\n\tvalue: 0,\n} as const satisfies ProgressContextValue;\n\nconst ProgressContext =\n\tcreateContext<ProgressContextValue>(defaultContextValue);\n\ntype SvgAttributes = Omit<\n\tHTMLAttributes<SVGElement>,\n\t| \"viewBox\"\n\t| \"role\"\n\t| \"aria-valuemax\"\n\t| \"aria-valuemin\"\n\t| \"aria-valuenow\"\n\t| \"width\"\n\t| \"height\"\n>;\n\ntype Props = SvgAttributes & {\n\t/**\n\t * The maximum value of the progress bar.\n\t * This attribute describes how much work the task indicated by the progress element requires.\n\t * The max attribute, if present, must have a value greater than 0. The default value is 100.\n\t *\n\t * @default 100\n\t */\n\tmax?: number | undefined;\n\t/**\n\t * The width of the progress bar stroke.\n\t * Note, we clamp the stroke width to a minimum of 1px and max of 12px since\n\t * it is proportional to the viewbox size (0 0 32 32).\n\t *\n\t * @default 0.25rem (4px)\n\t */\n\tstrokeWidth?: StrokeWidth;\n\t/**\n\t * The current value of the progress bar.\n\t * This attribute specifies how much of the task that has been completed.\n\t * It must be a valid floating point number between 0 and max, or between 0 and 100 if max is omitted.\n\t * If set to `\"indeterminate\"`, the progress bar is considered indeterminate.\n\t *\n\t * @default 0\n\t */\n\tvalue?: ValueType | undefined;\n};\n\n/**\n * A simple circular progress bar.\n */\nconst ProgressDonut = ({\n\tchildren,\n\tclassName,\n\tmax: _max = defaultMax,\n\tstrokeWidth: _strokeWidth = 4,\n\tvalue: _value,\n\t...props\n}: Props) => {\n\tconst max = isValidMaxNumber(_max) ? _max : defaultMax;\n\tconst value = (\n\t\tisValidValueNumber(_value, max)\n\t\t\t? _value\n\t\t\t: _value == null\n\t\t\t\t? 0\n\t\t\t\t: \"indeterminate\"\n\t) satisfies ValueType;\n\tconst strokeWidthPx = deriveStrokeWidthPx(\n\t\t_strokeWidth ?? defaultContextValue.strokeWidth,\n\t);\n\tconst valueNow = isNumber(value) ? value : undefined;\n\tconst radius = calcRadius(strokeWidthPx);\n\n\tconst ctx: ProgressContextValue = useMemo(\n\t\t() => ({\n\t\t\tmax,\n\t\t\tstrokeWidth: strokeWidthPx,\n\t\t\tvalue,\n\t\t}),\n\t\t[max, strokeWidthPx, value],\n\t);\n\n\treturn (\n\t\t<ProgressContext.Provider value={ctx}>\n\t\t\t{/* biome-ignore lint/a11y/useFocusableInteractive: progress bars don't need to be focusable */}\n\t\t\t<svg\n\t\t\t\taria-valuemax={max}\n\t\t\t\taria-valuemin={0}\n\t\t\t\taria-valuenow={valueNow}\n\t\t\t\tclassName={clsx(\n\t\t\t\t\tvalue === \"indeterminate\" &&\n\t\t\t\t\t\t\"animation-duration-[15s] transform-gpu animate-spin\",\n\t\t\t\t\tcx(\"size-6 text-gray-200 dark:text-gray-300\", className),\n\t\t\t\t)}\n\t\t\t\tdata-max={max}\n\t\t\t\tdata-min={0}\n\t\t\t\tdata-value={valueNow}\n\t\t\t\theight=\"100%\"\n\t\t\t\t// biome-ignore lint/a11y/noNoninteractiveElementToInteractiveRole: this is a radial progress bar, which is possible by SVG\n\t\t\t\trole=\"progressbar\"\n\t\t\t\twidth=\"100%\"\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t<circle\n\t\t\t\t\tclassName=\"[r:var(--radius)]\"\n\t\t\t\t\tcx=\"50%\"\n\t\t\t\t\tcy=\"50%\"\n\t\t\t\t\tfill=\"transparent\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstrokeWidth={strokeWidthPx}\n\t\t\t\t\tstyle={{ \"--radius\": radius } as CSSProperties}\n\t\t\t\t/>\n\t\t\t\t{children}\n\t\t\t</svg>\n\t\t</ProgressContext.Provider>\n\t);\n};\n\n/**\n * Length (value) of the progress indicator tail when the progress bar is indeterminate.\n */\nconst indeterminateTailPercent = 0.6;\n\ntype ProgressDonutIndicatorProps = Omit<ComponentProps<\"g\">, \"children\">;\n\n/**\n * The indicator for the circular progress bar.\n */\nconst ProgressDonutIndicator = ({\n\tclassName,\n\t...props\n}: ProgressDonutIndicatorProps) => {\n\tconst gradientId = useId();\n\tconst ctx = useContext(ProgressContext) ?? defaultContextValue;\n\tconst percentage =\n\t\t(ctx.value === \"indeterminate\"\n\t\t\t? indeterminateTailPercent\n\t\t\t: ctx.value / ctx.max) * 100;\n\tconst strokeWidthPx = deriveStrokeWidthPx(ctx.strokeWidth);\n\tconst radius = calcRadius(strokeWidthPx);\n\n\treturn (\n\t\t<g className={cx(\"text-accent-600\", className)} {...props}>\n\t\t\t{ctx.value === \"indeterminate\" && (\n\t\t\t\t<defs>\n\t\t\t\t\t<linearGradient id={gradientId}>\n\t\t\t\t\t\t<stop className=\"stop-opacity-100 stop-color-current\" offset=\"0%\" />\n\t\t\t\t\t\t<stop className=\"stop-opacity-0 stop-color-current\" offset=\"95%\" />\n\t\t\t\t\t</linearGradient>\n\t\t\t\t</defs>\n\t\t\t)}\n\t\t\t<circle\n\t\t\t\tclassName=\"[r:var(--radius)]\"\n\t\t\t\tcx=\"50%\"\n\t\t\t\tcy=\"50%\"\n\t\t\t\tfill=\"transparent\"\n\t\t\t\tpathLength={100}\n\t\t\t\tstroke={\n\t\t\t\t\tctx.value === \"indeterminate\" ? `url(#${gradientId})` : \"currentColor\"\n\t\t\t\t}\n\t\t\t\tstrokeDasharray={100}\n\t\t\t\tstrokeDashoffset={100 - percentage}\n\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\tstrokeWidth={strokeWidthPx}\n\t\t\t\tstyle={{ \"--radius\": radius } as CSSProperties}\n\t\t\t\ttransform-origin=\"center\"\n\t\t\t\ttransform=\"rotate(-90)\" // rotate -90 degrees so it starts from the top\n\t\t\t/>\n\t\t</g>\n\t);\n};\n\nexport {\n\t//,\n\tProgressDonut,\n\tProgressDonutIndicator,\n};\n\n/**\n * Clamp a value between a minimum and maximum value.\n */\nfunction clamp(\n\tvalue: number,\n\t{ min, max }: { min: number; max: number },\n): number {\n\treturn Math.min(max, Math.max(min, value));\n}\n\n/**\n * Derive the stroke width in pixels as a number value or pixels/rem from a string value.\n * Note, this function clamps the stroke width to a minimum of 1 and max of 12 since\n * it is proportional to the viewbox size (0 0 32 32).\n */\nexport function deriveStrokeWidthPx(\n\tstrokeWidth: number | string | undefined | null,\n): number {\n\tlet value = 4;\n\tif (strokeWidth == null) {\n\t\treturn value;\n\t}\n\n\tif (typeof strokeWidth === \"number\") {\n\t\tvalue = strokeWidth;\n\t} else if (strokeWidth.endsWith(\"rem\")) {\n\t\tvalue = Number(strokeWidth.replace(\"rem\", \"\")) * 16;\n\t} else {\n\t\tvalue = Number(strokeWidth);\n\t}\n\n\tconst stroke = Number.isNaN(value) ? 4 : value;\n\treturn clamp(stroke, { min: 1, max: 12 });\n}\n\n/**\n * Check if a value is a number.\n */\nfunction isNumber(value: unknown): value is number {\n\treturn typeof value === \"number\";\n}\n\n/**\n * Check if a value is a valid number within the range of 0 to `max`.\n */\nfunction isValidValueNumber(value: unknown, max: number): value is number {\n\treturn isNumber(value) && !Number.isNaN(value) && value <= max && value >= 0;\n}\n\n/**\n * Check if a value is a valid number greater than 0.\n */\nfunction isValidMaxNumber(value: unknown): value is number {\n\treturn isNumber(value) && !Number.isNaN(value) && value > 0;\n}\n\n/**\n * Calculate the radius of the progress donut and indicator based on the stroke\n * width in pixels.\n */\nfunction calcRadius(strokeWidthPx: number) {\n\treturn `calc(50% - ${strokeWidthPx / 2}px)` as const;\n}\n"],"mappings":"wCAAA,OAAOA,MAAU,OACjB,OAAS,iBAAAC,EAAe,cAAAC,EAAY,SAAAC,EAAO,WAAAC,MAAe,QAwGvD,OAkBC,OAAAC,EAlBD,QAAAC,MAAA,oBA7FH,IAAMC,EAAa,IAQbC,EAAsB,CAC3B,IAAKD,EACL,YAAa,UACb,MAAO,CACR,EAEME,EACLC,EAAoCF,CAAmB,EA4ClDG,EAAgB,CAAC,CACtB,SAAAC,EACA,UAAAC,EACA,IAAKC,EAAOP,EACZ,YAAaQ,EAAe,EAC5B,MAAOC,EACP,GAAGC,CACJ,IAAa,CACZ,IAAMC,EAAMC,EAAiBL,CAAI,EAAIA,EAAOP,EACtCa,EACLC,EAAmBL,EAAQE,CAAG,EAC3BF,EACAA,GAAU,KACT,EACA,gBAECM,EAAgBC,EACrBR,GAAgBP,EAAoB,WACrC,EACMgB,EAAWC,EAASL,CAAK,EAAIA,EAAQ,OACrCM,EAASC,EAAWL,CAAa,EAEjCM,EAA4BC,EACjC,KAAO,CACN,IAAAX,EACA,YAAaI,EACb,MAAAF,CACD,GACA,CAACF,EAAKI,EAAeF,CAAK,CAC3B,EAEA,OACCf,EAACI,EAAgB,SAAhB,CAAyB,MAAOmB,EAEhC,SAAAtB,EAAC,OACA,gBAAeY,EACf,gBAAe,EACf,gBAAeM,EACf,UAAWM,EACVV,IAAU,iBACT,sDACDW,EAAG,0CAA2ClB,CAAS,CACxD,EACA,WAAUK,EACV,WAAU,EACV,aAAYM,EACZ,OAAO,OAEP,KAAK,cACL,MAAM,OACL,GAAGP,EAEJ,UAAAZ,EAAC,UACA,UAAU,oBACV,GAAG,MACH,GAAG,MACH,KAAK,cACL,OAAO,eACP,YAAaiB,EACb,MAAO,CAAE,WAAYI,CAAO,EAC7B,EACCd,GACF,EACD,CAEF,EAKMoB,EAA2B,GAO3BC,EAAyB,CAAC,CAC/B,UAAApB,EACA,GAAGI,CACJ,IAAmC,CAClC,IAAMiB,EAAaC,EAAM,EACnBP,EAAMQ,EAAW3B,CAAe,GAAKD,EACrC6B,GACJT,EAAI,QAAU,gBACZI,EACAJ,EAAI,MAAQA,EAAI,KAAO,IACrBN,EAAgBC,EAAoBK,EAAI,WAAW,EACnDF,EAASC,EAAWL,CAAa,EAEvC,OACChB,EAAC,KAAE,UAAWyB,EAAG,kBAAmBlB,CAAS,EAAI,GAAGI,EAClD,UAAAW,EAAI,QAAU,iBACdvB,EAAC,QACA,SAAAC,EAAC,kBAAe,GAAI4B,EACnB,UAAA7B,EAAC,QAAK,UAAU,sCAAsC,OAAO,KAAK,EAClEA,EAAC,QAAK,UAAU,oCAAoC,OAAO,MAAM,GAClE,EACD,EAEDA,EAAC,UACA,UAAU,oBACV,GAAG,MACH,GAAG,MACH,KAAK,cACL,WAAY,IACZ,OACCuB,EAAI,QAAU,gBAAkB,QAAQM,CAAU,IAAM,eAEzD,gBAAiB,IACjB,iBAAkB,IAAMG,EACxB,cAAc,QACd,YAAaf,EACb,MAAO,CAAE,WAAYI,CAAO,EAC5B,mBAAiB,SACjB,UAAU,cACX,GACD,CAEF,EAWA,SAASY,EACRC,EACA,CAAE,IAAAC,EAAK,IAAAC,CAAI,EACF,CACT,OAAO,KAAK,IAAIA,EAAK,KAAK,IAAID,EAAKD,CAAK,CAAC,CAC1C,CAOO,SAASG,EACfC,EACS,CACT,IAAIJ,EAAQ,EACZ,GAAII,GAAe,KAClB,OAAOJ,EAGJ,OAAOI,GAAgB,SAC1BJ,EAAQI,EACEA,EAAY,SAAS,KAAK,EACpCJ,EAAQ,OAAOI,EAAY,QAAQ,MAAO,EAAE,CAAC,EAAI,GAEjDJ,EAAQ,OAAOI,CAAW,EAG3B,IAAMC,EAAS,OAAO,MAAML,CAAK,EAAI,EAAIA,EACzC,OAAOD,EAAMM,EAAQ,CAAE,IAAK,EAAG,IAAK,EAAG,CAAC,CACzC,CAKA,SAASC,EAASN,EAAiC,CAClD,OAAO,OAAOA,GAAU,QACzB,CAKA,SAASO,EAAmBP,EAAgBE,EAA8B,CACzE,OAAOI,EAASN,CAAK,GAAK,CAAC,OAAO,MAAMA,CAAK,GAAKA,GAASE,GAAOF,GAAS,CAC5E,CAKA,SAASQ,EAAiBR,EAAiC,CAC1D,OAAOM,EAASN,CAAK,GAAK,CAAC,OAAO,MAAMA,CAAK,GAAKA,EAAQ,CAC3D,CAMA,SAASS,EAAWC,EAAuB,CAC1C,MAAO,cAAcA,EAAgB,CAAC,KACvC","names":["clsx","createContext","useContext","useId","useMemo","jsx","jsxs","defaultMax","defaultContextValue","ProgressContext","createContext","ProgressDonut","children","className","_max","_strokeWidth","_value","props","max","isValidMaxNumber","value","isValidValueNumber","strokeWidthPx","deriveStrokeWidthPx","valueNow","isNumber","radius","calcRadius","ctx","useMemo","clsx","cx","indeterminateTailPercent","ProgressDonutIndicator","gradientId","useId","useContext","percentage","clamp","value","min","max","deriveStrokeWidthPx","strokeWidth","stroke","isNumber","isValidValueNumber","isValidMaxNumber","calcRadius","strokeWidthPx"]}
1
+ {"version":3,"sources":["../src/components/progress/progress-donut.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport { createContext, useContext, useId, useMemo } from \"react\";\nimport type { CSSProperties, ComponentProps, HTMLAttributes } from \"react\";\nimport { cx } from \"../../utils/cx/cx.js\";\n\ntype RemValue = `${number}rem`;\ntype StrokeWidth = number | RemValue;\ntype ValueType = number | \"indeterminate\";\n\n/**\n * The default maximum value of the progress bar.\n */\nconst defaultMax = 100;\n\ntype ProgressContextValue = {\n\tmax: number;\n\tstrokeWidth: StrokeWidth;\n\tvalue: ValueType;\n};\n\nconst defaultContextValue = {\n\tmax: defaultMax,\n\tstrokeWidth: \"0.25rem\",\n\tvalue: 0,\n} as const satisfies ProgressContextValue;\n\nconst ProgressContext =\n\tcreateContext<ProgressContextValue>(defaultContextValue);\n\ntype SvgAttributes = Omit<\n\tHTMLAttributes<SVGElement>,\n\t| \"viewBox\"\n\t| \"role\"\n\t| \"aria-valuemax\"\n\t| \"aria-valuemin\"\n\t| \"aria-valuenow\"\n\t| \"width\"\n\t| \"height\"\n>;\n\ntype Props = SvgAttributes & {\n\t/**\n\t * The maximum value of the progress bar.\n\t * This attribute describes how much work the task indicated by the progress element requires.\n\t * The max attribute, if present, must have a value greater than 0. The default value is 100.\n\t *\n\t * @default 100\n\t */\n\tmax?: number | undefined;\n\t/**\n\t * The width of the progress bar stroke.\n\t * Note, we clamp the stroke width to a minimum of 1px and max of 12px since\n\t * it is proportional to the viewbox size (0 0 32 32).\n\t *\n\t * @default 0.25rem (4px)\n\t */\n\tstrokeWidth?: StrokeWidth;\n\t/**\n\t * The current value of the progress bar.\n\t * This attribute specifies how much of the task that has been completed.\n\t * It must be a valid floating point number between 0 and max, or between 0 and 100 if max is omitted.\n\t * If set to `\"indeterminate\"`, the progress bar is considered indeterminate.\n\t *\n\t * @default 0\n\t */\n\tvalue?: ValueType | undefined;\n};\n\n/**\n * A simple circular progress bar.\n *\n * @example\n * <ProgressDonut value={60}>\n * <ProgressDonutIndicator />\n * </ProgressDonut>\n */\nconst ProgressDonut = ({\n\tchildren,\n\tclassName,\n\tmax: _max = defaultMax,\n\tstrokeWidth: _strokeWidth = 4,\n\tvalue: _value,\n\t...props\n}: Props) => {\n\tconst max = isValidMaxNumber(_max) ? _max : defaultMax;\n\tconst value = (\n\t\tisValidValueNumber(_value, max)\n\t\t\t? _value\n\t\t\t: _value == null\n\t\t\t\t? 0\n\t\t\t\t: \"indeterminate\"\n\t) satisfies ValueType;\n\tconst strokeWidthPx = deriveStrokeWidthPx(\n\t\t_strokeWidth ?? defaultContextValue.strokeWidth,\n\t);\n\tconst valueNow = isNumber(value) ? value : undefined;\n\tconst radius = calcRadius(strokeWidthPx);\n\n\tconst ctx: ProgressContextValue = useMemo(\n\t\t() => ({\n\t\t\tmax,\n\t\t\tstrokeWidth: strokeWidthPx,\n\t\t\tvalue,\n\t\t}),\n\t\t[max, strokeWidthPx, value],\n\t);\n\n\treturn (\n\t\t<ProgressContext.Provider value={ctx}>\n\t\t\t{/* biome-ignore lint/a11y/useFocusableInteractive: progress bars don't need to be focusable */}\n\t\t\t<svg\n\t\t\t\taria-valuemax={max}\n\t\t\t\taria-valuemin={0}\n\t\t\t\taria-valuenow={valueNow}\n\t\t\t\tclassName={clsx(\n\t\t\t\t\tvalue === \"indeterminate\" &&\n\t\t\t\t\t\t\"animation-duration-[15s] transform-gpu animate-spin\",\n\t\t\t\t\tcx(\"size-6 text-gray-200 dark:text-gray-300\", className),\n\t\t\t\t)}\n\t\t\t\tdata-max={max}\n\t\t\t\tdata-min={0}\n\t\t\t\tdata-value={valueNow}\n\t\t\t\theight=\"100%\"\n\t\t\t\t// biome-ignore lint/a11y/noNoninteractiveElementToInteractiveRole: this is a radial progress bar, which is possible by SVG\n\t\t\t\trole=\"progressbar\"\n\t\t\t\twidth=\"100%\"\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t<circle\n\t\t\t\t\tclassName=\"[r:var(--radius)]\"\n\t\t\t\t\tcx=\"50%\"\n\t\t\t\t\tcy=\"50%\"\n\t\t\t\t\tfill=\"transparent\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstrokeWidth={strokeWidthPx}\n\t\t\t\t\tstyle={{ \"--radius\": radius } as CSSProperties}\n\t\t\t\t/>\n\t\t\t\t{children}\n\t\t\t</svg>\n\t\t</ProgressContext.Provider>\n\t);\n};\n\n/**\n * Length (value) of the progress indicator tail when the progress bar is indeterminate.\n */\nconst indeterminateTailPercent = 0.6;\n\ntype ProgressDonutIndicatorProps = Omit<ComponentProps<\"g\">, \"children\">;\n\n/**\n * The indicator for the circular progress bar.\n *\n * @example\n * <ProgressDonut value={60}>\n * <ProgressDonutIndicator />\n * </ProgressDonut>\n */\nconst ProgressDonutIndicator = ({\n\tclassName,\n\t...props\n}: ProgressDonutIndicatorProps) => {\n\tconst gradientId = useId();\n\tconst ctx = useContext(ProgressContext) ?? defaultContextValue;\n\tconst percentage =\n\t\t(ctx.value === \"indeterminate\"\n\t\t\t? indeterminateTailPercent\n\t\t\t: ctx.value / ctx.max) * 100;\n\tconst strokeWidthPx = deriveStrokeWidthPx(ctx.strokeWidth);\n\tconst radius = calcRadius(strokeWidthPx);\n\n\treturn (\n\t\t<g className={cx(\"text-accent-600\", className)} {...props}>\n\t\t\t{ctx.value === \"indeterminate\" && (\n\t\t\t\t<defs>\n\t\t\t\t\t<linearGradient id={gradientId}>\n\t\t\t\t\t\t<stop className=\"stop-opacity-100 stop-color-current\" offset=\"0%\" />\n\t\t\t\t\t\t<stop className=\"stop-opacity-0 stop-color-current\" offset=\"95%\" />\n\t\t\t\t\t</linearGradient>\n\t\t\t\t</defs>\n\t\t\t)}\n\t\t\t<circle\n\t\t\t\tclassName={clsx(\n\t\t\t\t\t\"[r:var(--radius)]\", // set the circle radius to be the value of the calc'd CSS variable set on the style\n\t\t\t\t\t\"origin-center\",\n\t\t\t\t)}\n\t\t\t\tcx=\"50%\"\n\t\t\t\tcy=\"50%\"\n\t\t\t\tfill=\"transparent\"\n\t\t\t\tpathLength={100}\n\t\t\t\tstroke={\n\t\t\t\t\tctx.value === \"indeterminate\" ? `url(#${gradientId})` : \"currentColor\"\n\t\t\t\t}\n\t\t\t\tstrokeDasharray={100}\n\t\t\t\tstrokeDashoffset={100 - percentage}\n\t\t\t\tstrokeLinecap=\"round\"\n\t\t\t\tstrokeWidth={strokeWidthPx}\n\t\t\t\tstyle={{ \"--radius\": radius } as CSSProperties}\n\t\t\t\ttransform=\"rotate(-90)\" // rotate -90 degrees so it starts from the top\n\t\t\t/>\n\t\t</g>\n\t);\n};\n\nexport {\n\t//,\n\tProgressDonut,\n\tProgressDonutIndicator,\n};\n\n/**\n * Clamp a value between a minimum and maximum value.\n */\nfunction clamp(\n\tvalue: number,\n\t{ min, max }: { min: number; max: number },\n): number {\n\treturn Math.min(max, Math.max(min, value));\n}\n\n/**\n * Derive the stroke width in pixels as a number value or pixels/rem from a string value.\n * Note, this function clamps the stroke width to a minimum of 1 and max of 12 since\n * it is proportional to the viewbox size (0 0 32 32).\n */\nexport function deriveStrokeWidthPx(\n\tstrokeWidth: number | string | undefined | null,\n): number {\n\tlet value = 4;\n\tif (strokeWidth == null) {\n\t\treturn value;\n\t}\n\n\tif (typeof strokeWidth === \"number\") {\n\t\tvalue = strokeWidth;\n\t} else if (strokeWidth.endsWith(\"rem\")) {\n\t\tvalue = Number(strokeWidth.replace(\"rem\", \"\")) * 16;\n\t} else {\n\t\tvalue = Number(strokeWidth);\n\t}\n\n\tconst stroke = Number.isNaN(value) ? 4 : value;\n\treturn clamp(stroke, { min: 1, max: 12 });\n}\n\n/**\n * Check if a value is a number.\n */\nfunction isNumber(value: unknown): value is number {\n\treturn typeof value === \"number\";\n}\n\n/**\n * Check if a value is a valid number within the range of 0 to `max`.\n */\nfunction isValidValueNumber(value: unknown, max: number): value is number {\n\treturn isNumber(value) && !Number.isNaN(value) && value <= max && value >= 0;\n}\n\n/**\n * Check if a value is a valid number greater than 0.\n */\nfunction isValidMaxNumber(value: unknown): value is number {\n\treturn isNumber(value) && !Number.isNaN(value) && value > 0;\n}\n\n/**\n * Calculate the radius of the progress donut and indicator based on the stroke\n * width in pixels.\n */\nfunction calcRadius(strokeWidthPx: number) {\n\treturn `calc(50% - ${strokeWidthPx / 2}px)` as const;\n}\n"],"mappings":"wCAAA,OAAOA,MAAU,OACjB,OAAS,iBAAAC,EAAe,cAAAC,EAAY,SAAAC,EAAO,WAAAC,MAAe,QA6GvD,OAkBC,OAAAC,EAlBD,QAAAC,MAAA,oBAlGH,IAAMC,EAAa,IAQbC,EAAsB,CAC3B,IAAKD,EACL,YAAa,UACb,MAAO,CACR,EAEME,EACLC,EAAoCF,CAAmB,EAiDlDG,EAAgB,CAAC,CACtB,SAAAC,EACA,UAAAC,EACA,IAAKC,EAAOP,EACZ,YAAaQ,EAAe,EAC5B,MAAOC,EACP,GAAGC,CACJ,IAAa,CACZ,IAAMC,EAAMC,EAAiBL,CAAI,EAAIA,EAAOP,EACtCa,EACLC,EAAmBL,EAAQE,CAAG,EAC3BF,EACAA,GAAU,KACT,EACA,gBAECM,EAAgBC,EACrBR,GAAgBP,EAAoB,WACrC,EACMgB,EAAWC,EAASL,CAAK,EAAIA,EAAQ,OACrCM,EAASC,EAAWL,CAAa,EAEjCM,EAA4BC,EACjC,KAAO,CACN,IAAAX,EACA,YAAaI,EACb,MAAAF,CACD,GACA,CAACF,EAAKI,EAAeF,CAAK,CAC3B,EAEA,OACCf,EAACI,EAAgB,SAAhB,CAAyB,MAAOmB,EAEhC,SAAAtB,EAAC,OACA,gBAAeY,EACf,gBAAe,EACf,gBAAeM,EACf,UAAWM,EACVV,IAAU,iBACT,sDACDW,EAAG,0CAA2ClB,CAAS,CACxD,EACA,WAAUK,EACV,WAAU,EACV,aAAYM,EACZ,OAAO,OAEP,KAAK,cACL,MAAM,OACL,GAAGP,EAEJ,UAAAZ,EAAC,UACA,UAAU,oBACV,GAAG,MACH,GAAG,MACH,KAAK,cACL,OAAO,eACP,YAAaiB,EACb,MAAO,CAAE,WAAYI,CAAO,EAC7B,EACCd,GACF,EACD,CAEF,EAKMoB,EAA2B,GAY3BC,EAAyB,CAAC,CAC/B,UAAApB,EACA,GAAGI,CACJ,IAAmC,CAClC,IAAMiB,EAAaC,EAAM,EACnBP,EAAMQ,EAAW3B,CAAe,GAAKD,EACrC6B,GACJT,EAAI,QAAU,gBACZI,EACAJ,EAAI,MAAQA,EAAI,KAAO,IACrBN,EAAgBC,EAAoBK,EAAI,WAAW,EACnDF,EAASC,EAAWL,CAAa,EAEvC,OACChB,EAAC,KAAE,UAAWyB,EAAG,kBAAmBlB,CAAS,EAAI,GAAGI,EAClD,UAAAW,EAAI,QAAU,iBACdvB,EAAC,QACA,SAAAC,EAAC,kBAAe,GAAI4B,EACnB,UAAA7B,EAAC,QAAK,UAAU,sCAAsC,OAAO,KAAK,EAClEA,EAAC,QAAK,UAAU,oCAAoC,OAAO,MAAM,GAClE,EACD,EAEDA,EAAC,UACA,UAAWyB,EACV,oBACA,eACD,EACA,GAAG,MACH,GAAG,MACH,KAAK,cACL,WAAY,IACZ,OACCF,EAAI,QAAU,gBAAkB,QAAQM,CAAU,IAAM,eAEzD,gBAAiB,IACjB,iBAAkB,IAAMG,EACxB,cAAc,QACd,YAAaf,EACb,MAAO,CAAE,WAAYI,CAAO,EAC5B,UAAU,cACX,GACD,CAEF,EAWA,SAASY,EACRC,EACA,CAAE,IAAAC,EAAK,IAAAC,CAAI,EACF,CACT,OAAO,KAAK,IAAIA,EAAK,KAAK,IAAID,EAAKD,CAAK,CAAC,CAC1C,CAOO,SAASG,EACfC,EACS,CACT,IAAIJ,EAAQ,EACZ,GAAII,GAAe,KAClB,OAAOJ,EAGJ,OAAOI,GAAgB,SAC1BJ,EAAQI,EACEA,EAAY,SAAS,KAAK,EACpCJ,EAAQ,OAAOI,EAAY,QAAQ,MAAO,EAAE,CAAC,EAAI,GAEjDJ,EAAQ,OAAOI,CAAW,EAG3B,IAAMC,EAAS,OAAO,MAAML,CAAK,EAAI,EAAIA,EACzC,OAAOD,EAAMM,EAAQ,CAAE,IAAK,EAAG,IAAK,EAAG,CAAC,CACzC,CAKA,SAASC,EAASN,EAAiC,CAClD,OAAO,OAAOA,GAAU,QACzB,CAKA,SAASO,EAAmBP,EAAgBE,EAA8B,CACzE,OAAOI,EAASN,CAAK,GAAK,CAAC,OAAO,MAAMA,CAAK,GAAKA,GAASE,GAAOF,GAAS,CAC5E,CAKA,SAASQ,EAAiBR,EAAiC,CAC1D,OAAOM,EAASN,CAAK,GAAK,CAAC,OAAO,MAAMA,CAAK,GAAKA,EAAQ,CAC3D,CAMA,SAASS,EAAWC,EAAuB,CAC1C,MAAO,cAAcA,EAAgB,CAAC,KACvC","names":["clsx","createContext","useContext","useId","useMemo","jsx","jsxs","defaultMax","defaultContextValue","ProgressContext","createContext","ProgressDonut","children","className","_max","_strokeWidth","_value","props","max","isValidMaxNumber","value","isValidValueNumber","strokeWidthPx","deriveStrokeWidthPx","valueNow","isNumber","radius","calcRadius","ctx","useMemo","clsx","cx","indeterminateTailPercent","ProgressDonutIndicator","gradientId","useId","useContext","percentage","clamp","value","min","max","deriveStrokeWidthPx","strokeWidth","stroke","isNumber","isValidValueNumber","isValidMaxNumber","calcRadius","strokeWidthPx"]}
@@ -33,7 +33,7 @@ type Theme = (typeof themes)[number];
33
33
  /**
34
34
  * $theme is a helper which translates the Theme type into a string literal type.
35
35
  */
36
- declare const $theme: <T extends Theme = "dark" | "light" | "light-high-contrast" | "dark-high-contrast" | "system">(value: T) => T;
36
+ declare const $theme: <T extends Theme = Theme>(value: T) => T;
37
37
  /**
38
38
  * Type predicate that checks if a value is a valid theme.
39
39
  */
@@ -41,7 +41,7 @@ declare function isTheme(value: unknown): value is Theme;
41
41
  /**
42
42
  * $resolvedTheme is a helper which translates the ResolvedTheme type into a string literal type.
43
43
  */
44
- declare const $resolvedTheme: <T extends ResolvedTheme = "dark" | "light" | "light-high-contrast" | "dark-high-contrast">(value: T) => T;
44
+ declare const $resolvedTheme: <T extends ResolvedTheme = ResolvedTheme>(value: T) => T;
45
45
  /**
46
46
  * Type predicate that checks if a value is a valid resolved theme.
47
47
  */
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "mantle is ngrok's UI library and design system.",
4
4
  "author": "ngrok",
5
5
  "license": "MIT",
6
- "version": "0.21.1",
6
+ "version": "0.21.3",
7
7
  "homepage": "https://mantle.ngrok.com",
8
8
  "repository": {
9
9
  "type": "git",
@@ -44,7 +44,7 @@
44
44
  "clsx": "2.1.1",
45
45
  "prismjs": "1.29.0",
46
46
  "react-day-picker": "8.10.1",
47
- "sonner": "2.0.0",
47
+ "sonner": "2.0.1",
48
48
  "tailwind-merge": "2.6.0",
49
49
  "tailwindcss-animate": "1.0.7",
50
50
  "tiny-invariant": "1.3.3"
@@ -55,7 +55,7 @@
55
55
  "@testing-library/jest-dom": "6.6.3",
56
56
  "@testing-library/react": "16.2.0",
57
57
  "@testing-library/user-event": "14.6.1",
58
- "@types/node": "22.13.4",
58
+ "@types/node": "22.13.9",
59
59
  "@types/prismjs": "1.26.5",
60
60
  "@types/react": "18.3.18",
61
61
  "@types/react-dom": "18.3.5",
@@ -69,8 +69,8 @@
69
69
  "react-dom": "18.3.1",
70
70
  "react-router": "7.2.0",
71
71
  "tailwindcss": "3.4.17",
72
- "tsup": "8.3.6",
73
- "typescript": "5.7.3",
72
+ "tsup": "8.4.0",
73
+ "typescript": "5.8.2",
74
74
  "zod": "3.24.2",
75
75
  "@cfg/tsconfig": "1.0.0"
76
76
  },