feat: implement PageLoader component and register maritime loader as the default theme loader

This commit is contained in:
estifanos
2026-08-14 11:35:34 +00:00
parent 652503d1de
commit f31e75c3de
16 changed files with 219 additions and 36 deletions

View File

@@ -1,4 +1,4 @@
import type { CSSProperties, ComponentPropsWithoutRef } from "react";
import type { CSSProperties, ComponentPropsWithoutRef, Ref } from "react";
export interface MaritimeLoaderProps extends Omit<
ComponentPropsWithoutRef<"span">,
@@ -8,8 +8,9 @@ export interface MaritimeLoaderProps extends Omit<
size?: number | string;
/** Standalone CSS color. Mantine's Loader color is used automatically when omitted. */
color?: string;
/** Accessible status text. */
/** Accessible status text (aria-label only — renders no visible text). */
label?: string;
ref?: Ref<HTMLSpanElement>;
}
const styles = `
@@ -231,15 +232,6 @@ const styles = `
fill: currentColor;
}
}
.ema-loader__label {
display: block;
text-align: center;
font-size: 12px;
line-height: 1.2;
margin-top: 4px;
color: currentColor;
}
`;
function toCssSize(value: number | string | undefined) {
@@ -252,6 +244,7 @@ export function MaritimeLoader({
label = "Loading maritime services",
className,
style,
ref,
...props
}: MaritimeLoaderProps) {
const cssVariables = {
@@ -263,12 +256,15 @@ export function MaritimeLoader({
return (
<span
{...props}
ref={ref}
className={["ema-loader", className].filter(Boolean).join(" ")}
style={cssVariables}
role="status"
aria-label={label}
>
<style>{styles}</style>
<style href="ema-maritime-loader" precedence="low">
{styles}
</style>
<svg
className="ema-loader__svg"
@@ -419,18 +415,8 @@ export function MaritimeLoader({
<path d="M200 108c14 1 24-1 35-5" />
</g>
</svg>
{label && <span className="ema-loader__label">{label}</span>}
</span>
);
}
export default MaritimeLoader;
// how to use this component.
// <Center style={{ width: "90vw", height: "90vh" }}>
// <MaritimeLoader
// size={120}
// color="#075985"
// label="Loading Maritime Services..."
// />
// </Center>