@hjmds/react 1.27.2 → 1.28.0
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.
- package/dist/auth-screen.d.ts +32 -2
- package/dist/auth-screen.d.ts.map +1 -1
- package/dist/auth-screen.js +52 -4
- package/dist/auth-screen.js.map +1 -1
- package/dist/chart.d.ts +1 -1
- package/dist/chart.js.map +1 -1
- package/dist/collection-editing.js.map +1 -1
- package/dist/communication.js +1 -1
- package/dist/communication.js.map +1 -1
- package/dist/data-table.d.ts +2 -2
- package/dist/data-table.d.ts.map +1 -1
- package/dist/data-table.js.map +1 -1
- package/dist/display.d.ts.map +1 -1
- package/dist/display.js +5 -2
- package/dist/display.js.map +1 -1
- package/dist/evidence.d.ts +1 -1
- package/dist/evidence.js +2 -2
- package/dist/evidence.js.map +1 -1
- package/dist/feedback.d.ts +10 -0
- package/dist/feedback.d.ts.map +1 -1
- package/dist/feedback.js +6 -1
- package/dist/feedback.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/internal/list-row-scroll-room.d.ts +16 -0
- package/dist/internal/list-row-scroll-room.d.ts.map +1 -0
- package/dist/internal/list-row-scroll-room.js +17 -0
- package/dist/internal/list-row-scroll-room.js.map +1 -0
- package/dist/notification-bell.d.ts +4 -1
- package/dist/notification-bell.d.ts.map +1 -1
- package/dist/notification-bell.js +5 -2
- package/dist/notification-bell.js.map +1 -1
- package/dist/overlays.js +2 -2
- package/dist/overlays.js.map +1 -1
- package/dist/screen-flows.d.ts +2 -2
- package/dist/screen-flows.d.ts.map +1 -1
- package/dist/screen-flows.js +1 -1
- package/dist/screen-flows.js.map +1 -1
- package/dist/screens.d.ts +1 -1
- package/dist/screens.d.ts.map +1 -1
- package/dist/screens.js.map +1 -1
- package/dist/selection.d.ts.map +1 -1
- package/dist/selection.js +2 -2
- package/dist/selection.js.map +1 -1
- package/dist/styles.css +183 -108
- package/dist/styles.layered.css +183 -108
- package/dist/theme.d.ts.map +1 -1
- package/dist/theme.js +14 -3
- package/dist/theme.js.map +1 -1
- package/dist/top.js +1 -1
- package/dist/top.js.map +1 -1
- package/dist/virtual-list.js +4 -4
- package/dist/virtual-list.js.map +1 -1
- package/package.json +3 -3
package/dist/auth-screen.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AuthScreenDescriptor } from "@hjmds/design-contracts/components/auth-screen";
|
|
1
|
+
import { type AuthScreenDensity, type AuthScreenDescriptor, type AuthScreenHeroDescriptor, type AuthScreenPolicyLinkDescriptor } from "@hjmds/design-contracts/components/auth-screen";
|
|
2
2
|
import { type HTMLAttributes, type ReactNode } from "react";
|
|
3
3
|
import type { HjmCompositionStyleProp } from "./composition-style.js";
|
|
4
4
|
export type AuthScreenLayoutProps = Omit<HTMLAttributes<HTMLElement>, "children"> & AuthScreenDescriptor & Readonly<{
|
|
@@ -24,7 +24,7 @@ export type AuthScreenLayoutProps = Omit<HTMLAttributes<HTMLElement>, "children"
|
|
|
24
24
|
* properties so the stylesheet keeps one source of truth with the contract.
|
|
25
25
|
*/
|
|
26
26
|
export declare const AuthScreenLayout: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLElement>, "children"> & Readonly<{
|
|
27
|
-
density?:
|
|
27
|
+
density?: AuthScreenDensity;
|
|
28
28
|
hasFooter?: boolean;
|
|
29
29
|
}> & Readonly<{
|
|
30
30
|
/** Use section inside a product shell that already owns the main landmark. */
|
|
@@ -43,4 +43,34 @@ export declare const AuthScreenLayout: import("react").ForwardRefExoticComponent
|
|
|
43
43
|
/** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
|
|
44
44
|
layoutStyle?: HjmCompositionStyleProp;
|
|
45
45
|
}> & import("react").RefAttributes<HTMLElement>>;
|
|
46
|
+
export type AuthScreenHeroProps = AuthScreenHeroDescriptor & Readonly<{
|
|
47
|
+
/** Product mark asset. HJM never ships product marks. */
|
|
48
|
+
mark?: ReactNode;
|
|
49
|
+
}>;
|
|
50
|
+
/**
|
|
51
|
+
* The `hero` slot content: mark, eyebrow, tagline and one description line. The
|
|
52
|
+
* product supplies the strings and mark; the type steps, tones and gaps come from
|
|
53
|
+
* `authScreenRecipe.hero` so a login slogan never borrows the page-heading size.
|
|
54
|
+
*/
|
|
55
|
+
export declare function AuthScreenHero({ mark, title, eyebrow, description, headingLevel }: AuthScreenHeroProps): import("react").JSX.Element;
|
|
56
|
+
export type AuthScreenPolicyLink = AuthScreenPolicyLinkDescriptor & Readonly<{
|
|
57
|
+
/** Document URL; renders an anchor. */
|
|
58
|
+
href?: string;
|
|
59
|
+
/** In-app handler; renders a button when there is no `href`. */
|
|
60
|
+
onClick?: () => void;
|
|
61
|
+
}>;
|
|
62
|
+
export type AuthScreenFooterProps = Readonly<{
|
|
63
|
+
/** Optional consent notice (LS-04). */
|
|
64
|
+
notice?: ReactNode;
|
|
65
|
+
/** Terms and privacy links; at least one is required (LS-04). */
|
|
66
|
+
links: readonly AuthScreenPolicyLink[];
|
|
67
|
+
/** Extra product content under the links. */
|
|
68
|
+
children?: ReactNode;
|
|
69
|
+
}>;
|
|
70
|
+
/**
|
|
71
|
+
* The `footer` slot content: consent notice plus dot-separated policy links. The
|
|
72
|
+
* visible gap between two links is `linkGap` + separator + `linkGap`; the 44px
|
|
73
|
+
* touch target is an invisible hit area, not visible padding.
|
|
74
|
+
*/
|
|
75
|
+
export declare function AuthScreenFooter({ notice, links, children }: AuthScreenFooterProps): import("react").JSX.Element;
|
|
46
76
|
//# sourceMappingURL=auth-screen.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-screen.d.ts","sourceRoot":"","sources":["../src/auth-screen.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"auth-screen.d.ts","sourceRoot":"","sources":["../src/auth-screen.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,8BAA8B,EACpC,MAAM,gDAAgD,CAAC;AAExD,OAAO,EAA+G,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEzK,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAKtE,MAAM,MAAM,qBAAqB,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,UAAU,CAAC,GAC/E,oBAAoB,GACpB,QAAQ,CAAC;IACP,8EAA8E;IAC9E,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,+EAA+E;IAC/E,IAAI,EAAE,SAAS,CAAC;IAChB,sFAAsF;IACtF,IAAI,EAAE,SAAS,CAAC;IAChB,2FAA2F;IAC3F,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4FAA4F;IAC5F,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qEAAqE;IACrE,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gGAAgG;IAChG,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEL;;;;GAIG;AACH,eAAO,MAAM,gBAAgB;;;;IAtBzB,8EAA8E;SACzE,MAAM,GAAG,SAAS;IACvB,+EAA+E;UACzE,SAAS;IACf,sFAAsF;UAChF,SAAS;IACf,2FAA2F;mBAC5E,MAAM;IACrB,4FAA4F;eACjF,OAAO;IAClB,qEAAqE;aAC5D,SAAS;gBACN,MAAM;IAClB,gGAAgG;kBAClF,uBAAuB;gDAkExC,CAAC;AASF,MAAM,MAAM,mBAAmB,GAAG,wBAAwB,GACxD,QAAQ,CAAC;IACP,yDAAyD;IACzD,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB,CAAC,CAAC;AAEL;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,YAAgB,EAAE,EAAE,mBAAmB,+BA4B1G;AAED,MAAM,MAAM,oBAAoB,GAAG,8BAA8B,GAC/D,QAAQ,CAAC;IACP,uCAAuC;IACvC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB,CAAC,CAAC;AAEL,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C,uCAAuC;IACvC,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,iEAAiE;IACjE,KAAK,EAAE,SAAS,oBAAoB,EAAE,CAAC;IACvC,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,CAAC,CAAC;AAEH;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,qBAAqB,+BAwBlF"}
|
package/dist/auth-screen.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { resolveAuthScreenDescriptor, } from "@hjmds/design-contracts/components/auth-screen";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { authScreenRecipe, resolveAuthScreenDescriptor, validateAuthScreenHeroDescriptor, validateAuthScreenPolicyLinks, } from "@hjmds/design-contracts/components/auth-screen";
|
|
3
|
+
import { typography } from "@hjmds/design-contracts/foundations";
|
|
4
|
+
import { createContext, createElement, forwardRef, Fragment, useContext, useLayoutEffect, useRef } from "react";
|
|
5
|
+
import { classNames, useDesignProfileDefaults } from "./internal.js";
|
|
6
|
+
// The hero follows the layout density without the product passing it twice.
|
|
7
|
+
const AuthScreenDensityContext = createContext(undefined);
|
|
5
8
|
/**
|
|
6
9
|
* Two regions: hero + main stay one vertically centred block, the footer sits at
|
|
7
10
|
* the bottom. The measurements come from the resolved descriptor as custom
|
|
@@ -37,7 +40,52 @@ export const AuthScreenLayout = forwardRef(function AuthScreenLayout({ hero, mai
|
|
|
37
40
|
["--hjm-auth-screen-padding-block"]: `${resolved.paddingBlock}px`,
|
|
38
41
|
...props.style,
|
|
39
42
|
...layoutStyle,
|
|
40
|
-
}, children: [_jsxs("div", { className: "hjm-auth-screen__block", children: [_jsx("div", { className: "hjm-auth-screen__hero", children: hero }), _jsxs("div", { className: "hjm-auth-screen__main", "data-card": mainCard || undefined, "aria-busy": pending || undefined, children: [_jsx("div", { ref: actionsRef, className: "hjm-auth-screen__actions", inert: pending, "aria-hidden": pending || undefined, onFocusCapture: event => { focusedAction.current = event.target; }, onBlurCapture: event => { if (!pending && !event.currentTarget.contains(event.relatedTarget))
|
|
43
|
+
}, children: [_jsxs("div", { className: "hjm-auth-screen__block", children: [_jsx(AuthScreenDensityContext.Provider, { value: resolved.density, children: _jsx("div", { className: "hjm-auth-screen__hero", children: hero }) }), _jsxs("div", { className: "hjm-auth-screen__main", "data-card": mainCard || undefined, "aria-busy": pending || undefined, children: [_jsx("div", { ref: actionsRef, className: "hjm-auth-screen__actions", inert: pending, "aria-hidden": pending || undefined, onFocusCapture: event => { focusedAction.current = event.target; }, onBlurCapture: event => { if (!pending && !event.currentTarget.contains(event.relatedTarget))
|
|
41
44
|
focusedAction.current = null; }, style: pending ? { visibility: "hidden" } : undefined, children: main }), pending ? _jsx("div", { className: "hjm-auth-screen__pending", role: "status", "aria-label": pendingLabel, children: _jsx("span", { className: "hjm-auth-provider-button__spinner", "aria-hidden": "true" }) }) : null] })] }), showFooter ? _jsx("div", { className: "hjm-auth-screen__footer", children: footer }) : null] }));
|
|
42
45
|
});
|
|
46
|
+
/** Token weight per variant, following the nearest design profile like `Text` does. */
|
|
47
|
+
function useTypeWeight() {
|
|
48
|
+
const profile = useDesignProfileDefaults();
|
|
49
|
+
const tokens = profile?.tokens.typography ?? typography;
|
|
50
|
+
return variant => tokens[variant].fontWeight;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The `hero` slot content: mark, eyebrow, tagline and one description line. The
|
|
54
|
+
* product supplies the strings and mark; the type steps, tones and gaps come from
|
|
55
|
+
* `authScreenRecipe.hero` so a login slogan never borrows the page-heading size.
|
|
56
|
+
*/
|
|
57
|
+
export function AuthScreenHero({ mark, title, eyebrow, description, headingLevel = 1 }) {
|
|
58
|
+
validateAuthScreenHeroDescriptor({ title, ...(eyebrow === undefined ? {} : { eyebrow }), ...(description === undefined ? {} : { description }), headingLevel });
|
|
59
|
+
const density = useContext(AuthScreenDensityContext);
|
|
60
|
+
const variant = resolveAuthScreenDescriptor(density === undefined ? {} : { density }).titleVariant;
|
|
61
|
+
const weight = useTypeWeight();
|
|
62
|
+
const recipe = authScreenRecipe.hero;
|
|
63
|
+
// Fragment: the mark and the copy are direct children of the hero so the
|
|
64
|
+
// recipe hero gap separates them on both platforms.
|
|
65
|
+
return (_jsxs(Fragment, { children: [mark ? _jsx("div", { className: "hjm-auth-screen__mark", children: mark }) : null, _jsxs("div", { className: "hjm-auth-screen__copy", children: [eyebrow ? _jsx("p", { className: "hjm-text hjm-auth-screen__eyebrow", "data-variant": recipe.eyebrow.textVariant, "data-font-role": "ui", "data-tone": recipe.eyebrow.tone, style: { marginBlockEnd: recipe.eyebrow.gapBelow, fontWeight: weight(recipe.eyebrow.textVariant) }, children: eyebrow }) : null, createElement(`h${headingLevel}`, {
|
|
66
|
+
className: "hjm-text hjm-auth-screen__title",
|
|
67
|
+
"data-variant": variant,
|
|
68
|
+
"data-font-role": "display",
|
|
69
|
+
"data-tone": recipe.title.tone,
|
|
70
|
+
// The title step's own weight (500), not Text's regular default outside a profile.
|
|
71
|
+
style: { fontWeight: weight(variant) },
|
|
72
|
+
}, title), description ? _jsx("p", { className: "hjm-text hjm-auth-screen__description", "data-variant": recipe.description.textVariant, "data-font-role": "ui", "data-tone": recipe.description.tone, style: { marginBlockStart: recipe.description.gapAbove, fontWeight: weight(recipe.description.textVariant) }, children: description }) : null] })] }));
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* The `footer` slot content: consent notice plus dot-separated policy links. The
|
|
76
|
+
* visible gap between two links is `linkGap` + separator + `linkGap`; the 44px
|
|
77
|
+
* touch target is an invisible hit area, not visible padding.
|
|
78
|
+
*/
|
|
79
|
+
export function AuthScreenFooter({ notice, links, children }) {
|
|
80
|
+
validateAuthScreenPolicyLinks(links);
|
|
81
|
+
const recipe = authScreenRecipe.footer;
|
|
82
|
+
const weight = useTypeWeight();
|
|
83
|
+
const linkStyle = { fontWeight: weight(recipe.link.textVariant) };
|
|
84
|
+
return (_jsxs("div", { className: "hjm-auth-screen__footer-content", style: { gap: recipe.noticeGap }, children: [notice ? _jsx("p", { className: "hjm-text", "data-variant": recipe.notice.textVariant, "data-font-role": "ui", "data-tone": recipe.notice.tone, style: { fontWeight: weight(recipe.notice.textVariant) }, children: notice }) : null, _jsx("div", { className: "hjm-auth-screen__links", style: {
|
|
85
|
+
["--hjm-auth-screen-link-gap"]: `${recipe.linkGap}px`,
|
|
86
|
+
["--hjm-auth-screen-link-target"]: `${authScreenRecipe.footerMinTouchTarget}px`,
|
|
87
|
+
}, children: links.map((link, index) => (_jsxs(Fragment, { children: [index > 0 ? _jsx("span", { className: "hjm-text hjm-auth-screen__separator", "data-variant": recipe.link.textVariant, "data-tone": recipe.notice.tone, "aria-hidden": "true", children: recipe.separator }) : null, link.href !== undefined
|
|
88
|
+
? _jsx("a", { className: "hjm-text hjm-auth-screen__link", "data-variant": recipe.link.textVariant, "data-font-role": "ui", "data-tone": recipe.link.tone, style: linkStyle, href: link.href, onClick: link.onClick, children: link.label })
|
|
89
|
+
: _jsx("button", { type: "button", className: "hjm-text hjm-auth-screen__link", "data-variant": recipe.link.textVariant, "data-font-role": "ui", "data-tone": recipe.link.tone, style: linkStyle, onClick: link.onClick, children: link.label })] }, `${index}:${link.label}`))) }), children] }));
|
|
90
|
+
}
|
|
43
91
|
//# sourceMappingURL=auth-screen.js.map
|
package/dist/auth-screen.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-screen.js","sourceRoot":"","sources":["../src/auth-screen.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n resolveAuthScreenDescriptor,\n type AuthScreenDescriptor,\n} from \"@hjmds/design-contracts/components/auth-screen\";\nimport { forwardRef, useLayoutEffect, useRef, type HTMLAttributes, type ReactNode } from \"react\";\nimport { classNames } from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type AuthScreenLayoutProps = Omit<HTMLAttributes<HTMLElement>, \"children\"> &\n AuthScreenDescriptor &\n Readonly<{\n /** Use section inside a product shell that already owns the main landmark. */\n as?: \"main\" | \"section\";\n /** Product mark, title and description. The product owns every string here. */\n hero: ReactNode;\n /** The primary action block — provider buttons, or a product's own sign-in bundle. */\n main: ReactNode;\n /** Product-localized progress label; presence replaces actions with one centred loader. */\n pendingLabel?: string;\n /** Let the layout own the action card; omit when the product already supplies a surface. */\n mainCard?: boolean;\n /** Consent notice and policy links. Omit with `hasFooter: false`. */\n footer?: ReactNode;\n className?: string;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\n/**\n * Two regions: hero + main stay one vertically centred block, the footer sits at\n * the bottom. The measurements come from the resolved descriptor as custom\n * properties so the stylesheet keeps one source of truth with the contract.\n */\nexport const AuthScreenLayout = forwardRef<HTMLElement, AuthScreenLayoutProps>(\n function AuthScreenLayout(\n { hero, main, footer, density, hasFooter, pendingLabel, mainCard = false, className, as: Element = \"main\", layoutStyle, ...props },\n forwardedRef,\n ) {\n const resolved = resolveAuthScreenDescriptor({\n ...(density === undefined ? {} : { density }),\n ...(hasFooter === undefined ? {} : { hasFooter }),\n });\n const showFooter = resolved.hasFooter && footer !== undefined && footer !== null;\n const pending = pendingLabel !== undefined;\n const actionsRef = useRef<HTMLDivElement>(null);\n const focusedAction = useRef<HTMLElement | null>(null);\n const wasPending = useRef(pending);\n useLayoutEffect(() => {\n // Inert loading content sends keyboard focus to body. Resume at the same\n // action after failure/cancellation, unless the user moved somewhere else.\n const target = focusedAction.current;\n if (wasPending.current && !pending && document.activeElement === document.body && target?.isConnected && actionsRef.current?.contains(target)) {\n target.focus({ preventScroll: true });\n }\n wasPending.current = pending;\n }, [pending]);\n if (pending && !pendingLabel.trim()) throw new TypeError(\"AuthScreen pendingLabel must not be empty\");\n return (\n <Element\n {...props}\n ref={forwardedRef}\n className={classNames(\"hjm-auth-screen\", className)}\n data-density={resolved.density}\n style={{\n [\"--hjm-auth-screen-max-width\" as string]: `${resolved.maxWidth}px`,\n [\"--hjm-auth-screen-hero-gap\" as string]: `${resolved.heroGap}px`,\n [\"--hjm-auth-screen-main-gap\" as string]: `${resolved.mainGap}px`,\n [\"--hjm-auth-screen-footer-gap\" as string]: `${resolved.footerGap}px`,\n [\"--hjm-auth-screen-padding-inline\" as string]: `${resolved.paddingInline}px`,\n [\"--hjm-auth-screen-padding-block\" as string]: `${resolved.paddingBlock}px`,\n ...props.style,\n ...layoutStyle,\n }}\n >\n <div className=\"hjm-auth-screen__block\">\n <div className=\"hjm-auth-screen__hero\">{hero}</div>\n <div className=\"hjm-auth-screen__main\" data-card={mainCard || undefined} aria-busy={pending || undefined}>\n {/* Keep the action block in flow so the card never collapses; inert also removes keyboard access. */}\n <div ref={actionsRef} className=\"hjm-auth-screen__actions\" inert={pending} aria-hidden={pending || undefined}\n onFocusCapture={event => { focusedAction.current = event.target; }}\n onBlurCapture={event => { if (!pending && !event.currentTarget.contains(event.relatedTarget)) focusedAction.current = null; }}\n style={pending ? { visibility: \"hidden\" } : undefined}>{main}</div>\n {pending ? <div className=\"hjm-auth-screen__pending\" role=\"status\" aria-label={pendingLabel}>\n <span className=\"hjm-auth-provider-button__spinner\" aria-hidden=\"true\" />\n </div> : null}\n </div>\n </div>\n {showFooter ? <div className=\"hjm-auth-screen__footer\">{footer}</div> : null}\n </Element>\n );\n },\n);\n"]}
|
|
1
|
+
{"version":3,"file":"auth-screen.js","sourceRoot":"","sources":["../src/auth-screen.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n authScreenRecipe,\n resolveAuthScreenDescriptor,\n validateAuthScreenHeroDescriptor,\n validateAuthScreenPolicyLinks,\n type AuthScreenDensity,\n type AuthScreenDescriptor,\n type AuthScreenHeroDescriptor,\n type AuthScreenPolicyLinkDescriptor,\n} from \"@hjmds/design-contracts/components/auth-screen\";\nimport { typography, type TextVariant } from \"@hjmds/design-contracts/foundations\";\nimport { createContext, createElement, forwardRef, Fragment, useContext, useLayoutEffect, useRef, type CSSProperties, type HTMLAttributes, type ReactNode } from \"react\";\nimport { classNames, useDesignProfileDefaults } from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\n// The hero follows the layout density without the product passing it twice.\nconst AuthScreenDensityContext = createContext<AuthScreenDensity | undefined>(undefined);\n\nexport type AuthScreenLayoutProps = Omit<HTMLAttributes<HTMLElement>, \"children\"> &\n AuthScreenDescriptor &\n Readonly<{\n /** Use section inside a product shell that already owns the main landmark. */\n as?: \"main\" | \"section\";\n /** Product mark, title and description. The product owns every string here. */\n hero: ReactNode;\n /** The primary action block — provider buttons, or a product's own sign-in bundle. */\n main: ReactNode;\n /** Product-localized progress label; presence replaces actions with one centred loader. */\n pendingLabel?: string;\n /** Let the layout own the action card; omit when the product already supplies a surface. */\n mainCard?: boolean;\n /** Consent notice and policy links. Omit with `hasFooter: false`. */\n footer?: ReactNode;\n className?: string;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\n/**\n * Two regions: hero + main stay one vertically centred block, the footer sits at\n * the bottom. The measurements come from the resolved descriptor as custom\n * properties so the stylesheet keeps one source of truth with the contract.\n */\nexport const AuthScreenLayout = forwardRef<HTMLElement, AuthScreenLayoutProps>(\n function AuthScreenLayout(\n { hero, main, footer, density, hasFooter, pendingLabel, mainCard = false, className, as: Element = \"main\", layoutStyle, ...props },\n forwardedRef,\n ) {\n const resolved = resolveAuthScreenDescriptor({\n ...(density === undefined ? {} : { density }),\n ...(hasFooter === undefined ? {} : { hasFooter }),\n });\n const showFooter = resolved.hasFooter && footer !== undefined && footer !== null;\n const pending = pendingLabel !== undefined;\n const actionsRef = useRef<HTMLDivElement>(null);\n const focusedAction = useRef<HTMLElement | null>(null);\n const wasPending = useRef(pending);\n useLayoutEffect(() => {\n // Inert loading content sends keyboard focus to body. Resume at the same\n // action after failure/cancellation, unless the user moved somewhere else.\n const target = focusedAction.current;\n if (wasPending.current && !pending && document.activeElement === document.body && target?.isConnected && actionsRef.current?.contains(target)) {\n target.focus({ preventScroll: true });\n }\n wasPending.current = pending;\n }, [pending]);\n if (pending && !pendingLabel.trim()) throw new TypeError(\"AuthScreen pendingLabel must not be empty\");\n return (\n <Element\n {...props}\n ref={forwardedRef}\n className={classNames(\"hjm-auth-screen\", className)}\n data-density={resolved.density}\n style={{\n [\"--hjm-auth-screen-max-width\" as string]: `${resolved.maxWidth}px`,\n [\"--hjm-auth-screen-hero-gap\" as string]: `${resolved.heroGap}px`,\n [\"--hjm-auth-screen-main-gap\" as string]: `${resolved.mainGap}px`,\n [\"--hjm-auth-screen-footer-gap\" as string]: `${resolved.footerGap}px`,\n [\"--hjm-auth-screen-padding-inline\" as string]: `${resolved.paddingInline}px`,\n [\"--hjm-auth-screen-padding-block\" as string]: `${resolved.paddingBlock}px`,\n ...props.style,\n ...layoutStyle,\n }}\n >\n <div className=\"hjm-auth-screen__block\">\n <AuthScreenDensityContext.Provider value={resolved.density}><div className=\"hjm-auth-screen__hero\">{hero}</div></AuthScreenDensityContext.Provider>\n <div className=\"hjm-auth-screen__main\" data-card={mainCard || undefined} aria-busy={pending || undefined}>\n {/* Keep the action block in flow so the card never collapses; inert also removes keyboard access. */}\n <div ref={actionsRef} className=\"hjm-auth-screen__actions\" inert={pending} aria-hidden={pending || undefined}\n onFocusCapture={event => { focusedAction.current = event.target; }}\n onBlurCapture={event => { if (!pending && !event.currentTarget.contains(event.relatedTarget)) focusedAction.current = null; }}\n style={pending ? { visibility: \"hidden\" } : undefined}>{main}</div>\n {pending ? <div className=\"hjm-auth-screen__pending\" role=\"status\" aria-label={pendingLabel}>\n <span className=\"hjm-auth-provider-button__spinner\" aria-hidden=\"true\" />\n </div> : null}\n </div>\n </div>\n {showFooter ? <div className=\"hjm-auth-screen__footer\">{footer}</div> : null}\n </Element>\n );\n },\n);\n\n/** Token weight per variant, following the nearest design profile like `Text` does. */\nfunction useTypeWeight(): (variant: TextVariant) => number | string {\n const profile = useDesignProfileDefaults();\n const tokens = profile?.tokens.typography ?? typography;\n return variant => tokens[variant].fontWeight;\n}\n\nexport type AuthScreenHeroProps = AuthScreenHeroDescriptor &\n Readonly<{\n /** Product mark asset. HJM never ships product marks. */\n mark?: ReactNode;\n }>;\n\n/**\n * The `hero` slot content: mark, eyebrow, tagline and one description line. The\n * product supplies the strings and mark; the type steps, tones and gaps come from\n * `authScreenRecipe.hero` so a login slogan never borrows the page-heading size.\n */\nexport function AuthScreenHero({ mark, title, eyebrow, description, headingLevel = 1 }: AuthScreenHeroProps) {\n validateAuthScreenHeroDescriptor({ title, ...(eyebrow === undefined ? {} : { eyebrow }), ...(description === undefined ? {} : { description }), headingLevel });\n const density = useContext(AuthScreenDensityContext);\n const variant = resolveAuthScreenDescriptor(density === undefined ? {} : { density }).titleVariant;\n const weight = useTypeWeight();\n const recipe = authScreenRecipe.hero;\n // Fragment: the mark and the copy are direct children of the hero so the\n // recipe hero gap separates them on both platforms.\n return (\n <Fragment>\n {mark ? <div className=\"hjm-auth-screen__mark\">{mark}</div> : null}\n <div className=\"hjm-auth-screen__copy\">\n {eyebrow ? <p className=\"hjm-text hjm-auth-screen__eyebrow\" data-variant={recipe.eyebrow.textVariant} data-font-role=\"ui\" data-tone={recipe.eyebrow.tone}\n style={{ marginBlockEnd: recipe.eyebrow.gapBelow, fontWeight: weight(recipe.eyebrow.textVariant) }}>{eyebrow}</p> : null}\n {/* A real heading element: the tagline is the route's first heading. */}\n {createElement(`h${headingLevel}`, {\n className: \"hjm-text hjm-auth-screen__title\",\n \"data-variant\": variant,\n \"data-font-role\": \"display\",\n \"data-tone\": recipe.title.tone,\n // The title step's own weight (500), not Text's regular default outside a profile.\n style: { fontWeight: weight(variant) },\n }, title)}\n {description ? <p className=\"hjm-text hjm-auth-screen__description\" data-variant={recipe.description.textVariant} data-font-role=\"ui\" data-tone={recipe.description.tone}\n style={{ marginBlockStart: recipe.description.gapAbove, fontWeight: weight(recipe.description.textVariant) }}>{description}</p> : null}\n </div>\n </Fragment>\n );\n}\n\nexport type AuthScreenPolicyLink = AuthScreenPolicyLinkDescriptor &\n Readonly<{\n /** Document URL; renders an anchor. */\n href?: string;\n /** In-app handler; renders a button when there is no `href`. */\n onClick?: () => void;\n }>;\n\nexport type AuthScreenFooterProps = Readonly<{\n /** Optional consent notice (LS-04). */\n notice?: ReactNode;\n /** Terms and privacy links; at least one is required (LS-04). */\n links: readonly AuthScreenPolicyLink[];\n /** Extra product content under the links. */\n children?: ReactNode;\n}>;\n\n/**\n * The `footer` slot content: consent notice plus dot-separated policy links. The\n * visible gap between two links is `linkGap` + separator + `linkGap`; the 44px\n * touch target is an invisible hit area, not visible padding.\n */\nexport function AuthScreenFooter({ notice, links, children }: AuthScreenFooterProps) {\n validateAuthScreenPolicyLinks(links);\n const recipe = authScreenRecipe.footer;\n const weight = useTypeWeight();\n const linkStyle = { fontWeight: weight(recipe.link.textVariant) };\n return (\n <div className=\"hjm-auth-screen__footer-content\" style={{ gap: recipe.noticeGap }}>\n {notice ? <p className=\"hjm-text\" data-variant={recipe.notice.textVariant} data-font-role=\"ui\" data-tone={recipe.notice.tone} style={{ fontWeight: weight(recipe.notice.textVariant) }}>{notice}</p> : null}\n <div className=\"hjm-auth-screen__links\" style={{\n [\"--hjm-auth-screen-link-gap\" as string]: `${recipe.linkGap}px`,\n [\"--hjm-auth-screen-link-target\" as string]: `${authScreenRecipe.footerMinTouchTarget}px`,\n } as CSSProperties}>\n {links.map((link, index) => (\n <Fragment key={`${index}:${link.label}`}>\n {index > 0 ? <span className=\"hjm-text hjm-auth-screen__separator\" data-variant={recipe.link.textVariant} data-tone={recipe.notice.tone} aria-hidden=\"true\">{recipe.separator}</span> : null}\n {link.href !== undefined\n ? <a className=\"hjm-text hjm-auth-screen__link\" data-variant={recipe.link.textVariant} data-font-role=\"ui\" data-tone={recipe.link.tone} style={linkStyle} href={link.href} onClick={link.onClick}>{link.label}</a>\n : <button type=\"button\" className=\"hjm-text hjm-auth-screen__link\" data-variant={recipe.link.textVariant} data-font-role=\"ui\" data-tone={recipe.link.tone} style={linkStyle} onClick={link.onClick}>{link.label}</button>}\n </Fragment>\n ))}\n </div>\n {children}\n </div>\n );\n}\n"]}
|
package/dist/chart.d.ts
CHANGED
|
@@ -54,7 +54,7 @@ export type LineChartProps = CartesianCommon & FocusProps & Readonly<{
|
|
|
54
54
|
animateChanges?: boolean;
|
|
55
55
|
/** Keep the chosen side in series color; mute the other side. */
|
|
56
56
|
scrubEmphasis?: "before" | "after";
|
|
57
|
-
/** Value labels only (rank charts: "1
|
|
57
|
+
/** Value labels only (rank charts: "#1" at the top). */
|
|
58
58
|
valueAxis?: boolean;
|
|
59
59
|
/** Overrides grid/label ticks. */
|
|
60
60
|
ticks?: readonly number[];
|