@hjmds/react 1.48.0 → 1.50.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/advanced-display.d.ts +3 -1
- package/dist/advanced-display.d.ts.map +1 -1
- package/dist/advanced-display.js +23 -15
- package/dist/advanced-display.js.map +1 -1
- package/dist/display.d.ts +4 -0
- package/dist/display.d.ts.map +1 -1
- package/dist/display.js +3 -3
- package/dist/display.js.map +1 -1
- package/dist/drawing-editor.d.ts +7 -0
- package/dist/drawing-editor.d.ts.map +1 -0
- package/dist/drawing-editor.js +123 -0
- package/dist/drawing-editor.js.map +1 -0
- package/dist/evidence.d.ts +1 -1
- package/dist/evidence.js +1 -1
- package/dist/evidence.js.map +1 -1
- package/dist/image-choice.js +2 -1
- package/dist/image-choice.js.map +1 -1
- package/dist/overlays.d.ts.map +1 -1
- package/dist/overlays.js +81 -2
- package/dist/overlays.js.map +1 -1
- package/dist/public-exports.generated.d.ts +1 -0
- package/dist/public-exports.generated.d.ts.map +1 -1
- package/dist/public-exports.generated.js +3 -0
- package/dist/public-exports.generated.js.map +1 -1
- package/dist/styles.css +23 -1
- package/dist/styles.layered.css +23 -1
- package/package.json +8 -3
package/dist/display.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"display.js","sourceRoot":"","sources":["../src/display.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\nimport { IdentityAction } from \"./internal/identity-action.js\";\n\nimport {\n badgeRecipe,\n listRowRecipe,\n type BadgeAdornmentContext,\n type BadgeSize,\n type BadgeTone,\n type BadgeVariant as ContractBadgeVariant,\n resolveBadgeCategoryColor,\n validateListRowTrailingAccessory,\n type BadgeCategoryColor,\n type ListRowDensity,\n type ListRowLeadingShape,\n type ListRowTrailingAccessory,\n} from \"@hjmds/design-contracts/recipes\";\nimport { THEMES } from \"@hjmds/design-contracts/colors\";\nimport { glyph } from \"@hjmds/design-contracts/foundations\";\nimport {\n resolveTagDescriptor,\n type TagTone,\n} from \"@hjmds/design-contracts/components/tag\";\nimport {\n cardRecipe,\n type CardHeadingLevel,\n} from \"@hjmds/design-contracts/components/card\";\nimport {\n surfaceGeometry,\n type SurfacePadding,\n type SurfaceRadius,\n type SurfaceTone,\n} from \"@hjmds/design-contracts/recipes/base\";\nimport {\n createElement,\n forwardRef,\n type CSSProperties,\n type HTMLAttributes,\n type MouseEventHandler,\n type ReactNode,\n} from \"react\";\nimport { classNames } from \"./internal.js\";\nimport { useHjmDensityDefault, useOptionalHjmTheme } from \"./provider.js\";\nimport { Surface, Text } from \"./layout.js\";\nimport { Icon } from \"./supplemental-display.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type { CardHeadingLevel } from \"@hjmds/design-contracts/components/card\";\nexport type { TagTone } from \"@hjmds/design-contracts/components/tag\";\nexport type BadgeVariant = ContractBadgeVariant;\n\nexport type BadgeProps = HTMLAttributes<HTMLSpanElement> &\n Readonly<{\n tone?: BadgeTone;\n /**\n * Product classification color per theme (series, grade…) in place of `tone`. HJM keeps the frame and picks the\n * label ink; a color whose label cannot reach AA 4.5 throws instead of rendering unreadable.\n */\n categoryColor?: BadgeCategoryColor;\n size?: BadgeSize;\n variant?: BadgeVariant;\n leading?: ReactNode | ((context: BadgeAdornmentContext) => ReactNode);\n trailing?: ReactNode | ((context: BadgeAdornmentContext) => ReactNode);\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const Badge = forwardRef<HTMLSpanElement, BadgeProps>(function Badge(\n {\n tone: toneProp,\n categoryColor,\n size = badgeRecipe.defaults.size,\n variant = badgeRecipe.defaults.variant,\n leading,\n trailing,\n className,\n children,\n layoutStyle,\n style,\n ...props\n },\n ref,\n) {\n if (categoryColor !== undefined && toneProp !== undefined) throw new TypeError(\"Badge takes either tone or categoryColor, not both\");\n const tone = toneProp ?? badgeRecipe.defaults.tone;\n // Outside a provider the stylesheet paints the light palette, so the category resolves against it too.\n const theme = useOptionalHjmTheme();\n const category = categoryColor === undefined ? null : resolveBadgeCategoryColor(categoryColor, {\n theme: theme?.environment.theme ?? \"light\",\n variant,\n palette: theme?.palette.theme ?? THEMES.light,\n });\n const iconContext = { color: \"currentColor\", size: badgeRecipe.sizes[size].iconSize, strokeWidth: badgeRecipe.iconStrokeWidth };\n return (\n <span\n {...props}\n style={{\n ...style,\n ...(category ? {\n \"--hjm-badge-category-content\": category.content,\n \"--hjm-badge-category-background\": category.background ?? \"transparent\",\n \"--hjm-badge-category-border\": category.border ?? \"transparent\",\n } as CSSProperties : {}),\n ...layoutStyle,\n }}\n ref={ref}\n className={classNames(\"hjm-badge\", className)}\n data-tone={category ? \"category\" : tone}\n data-size={size}\n data-variant={variant}\n >\n {leading === undefined ? null : (\n <span aria-hidden=\"true\" className=\"hjm-badge__icon\">\n {typeof leading === \"function\" ? leading(iconContext) : leading}\n </span>\n )}\n <span className=\"hjm-badge__label\">{children}</span>\n {trailing === undefined ? null : (\n <span aria-hidden=\"true\" className=\"hjm-badge__icon\">{typeof trailing === \"function\" ? trailing(iconContext) : trailing}</span>\n )}\n </span>\n );\n});\n\nexport type TagProps = Omit<HTMLAttributes<HTMLSpanElement>, \"children\"> &\n Readonly<{\n children: string;\n tone?: TagTone;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const Tag = forwardRef<HTMLSpanElement, TagProps>(function Tag(\n { children, tone, className, layoutStyle, style, ...props },\n ref,\n) {\n const descriptor = resolveTagDescriptor({\n label: children,\n ...(tone === undefined ? {} : { tone }),\n });\n return (\n <span\n {...props}\n style={{ ...style, ...layoutStyle }}\n ref={ref}\n className={classNames(\"hjm-tag\", className)}\n data-tone={descriptor.tone}\n >\n <span className=\"hjm-tag__label\">{descriptor.label}</span>\n </span>\n );\n});\n\nexport type CardProps = Omit<HTMLAttributes<HTMLElement>, \"title\"> &\n Readonly<{\n title?: ReactNode;\n description?: ReactNode;\n leading?: ReactNode;\n /** Independent identity destination, outside the card activation host. */\n leadingAction?: Readonly<{label:string;onPress():void; disabled?: boolean }>;\n media?: ReactNode;\n /** Decorative artwork behind the shared body/actions; its host determines the available height. */\n backgroundMedia?: ReactNode;\n /** Platform gesture/accessibility host behind content. Requires backgroundMedia; never put metadata/actions here. */\n backgroundInteraction?: ReactNode;\n /** Non-interactive cover classification at the shared top/end inset. Requires backgroundMedia. */\n mediaBadges?: ReactNode;\n badges?: ReactNode;\n /** Centre short metadata beneath artwork without product-owned badge layout. */\n badgesAlign?: \"start\" | \"center\";\n /** Activate only the passive cover; other card content/actions keep independent targets. */\n mediaAction?: Readonly<{ label: string; onActivate(): void; icon?: (context: Readonly<{ color: string; size: number }>) => ReactNode }>;\n actions?: ReactNode;\n /** Independent commands at the header end; never nested in whole-card activation. */\n headerActions?: ReactNode;\n headingLevel?: CardHeadingLevel;\n selected?: boolean;\n /**\n * Whole-card activation. With `actions`, the card stays an article and a separate full-card button sits under the\n * action region, so actions remain independent buttons (never a button inside a button). Keep other children passive.\n */\n onActivate?: () => void;\n /** A native anchor preserves new-tab, copy-link and browser previews; it is exclusive with onActivate. */\n href?: string;\n /** Framework routing and product effects can wrap the shared anchor without replacing its placement. */\n renderLink?: (props: React.ComponentPropsWithRef<\"a\">) => ReactNode;\n disabled?: boolean;\n tone?: SurfaceTone;\n bordered?: boolean;\n padding?: SurfacePadding;\n radius?: SurfaceRadius;\n /** Canonical layout-only placement; forwarded to the root Surface, which applies it. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\nexport const Card = forwardRef<HTMLElement, CardProps>(function Card(\n {\n title,\n description,\n leading,\n leadingAction,\n media,\n backgroundMedia,\n backgroundInteraction,\n mediaBadges,\n badges,\n badgesAlign = cardRecipe.defaults.badgesAlign,\n mediaAction,\n actions,\n headerActions,\n headingLevel = cardRecipe.defaults.headingLevel,\n // An omitted selection is an ordinary action, not an unpressed toggle.\n selected,\n onActivate, href, renderLink,\n disabled = false,\n tone = cardRecipe.defaults.tone,\n bordered = cardRecipe.defaults.bordered,\n padding = cardRecipe.defaults.padding,\n radius,\n className,\n children,\n ...props\n },\n ref,\n) {\n if (href !== undefined && (!href.trim() || onActivate)) throw new TypeError(\"Card href requires a destination and cannot combine with onActivate\");\n if (renderLink && href === undefined) throw new TypeError(\"Card renderLink requires href\");\n if ((onActivate || href !== undefined) && !props[\"aria-label\"]?.trim()) {\n throw new TypeError(\"Interactive Card requires aria-label\");\n }\n if (mediaAction && (onActivate || href !== undefined || !media || !mediaAction.label.trim())) throw new TypeError(\"Card mediaAction requires passive media, a label, and no whole-card activation\");\n if (backgroundMedia && (media || mediaAction || onActivate || href !== undefined)) throw new TypeError(\"Card backgroundMedia is decorative and cannot combine with media, mediaAction, onActivate or href\");\n if ((backgroundInteraction !== undefined || mediaBadges !== undefined) && !backgroundMedia) throw new TypeError(\"Card backgroundInteraction/mediaBadges require backgroundMedia\");\n const hasHeader =\n leading !== undefined || title !== undefined || description !== undefined || headerActions !== undefined;\n // Whole-card open plus separate commands (2026-10-18 unairplane journey card: open + delete). A root button cannot\n // contain the action buttons, so the root stays an article and an overlay button carries the card's name and state.\n const overlay = href !== undefined || (onActivate !== undefined && Boolean(actions || headerActions || leadingAction));\n const { \"aria-label\": activationLabel, ...rootProps } = props;\n const activate = () => { if (!disabled) onActivate?.(); };\n\n const linkProps: React.ComponentPropsWithRef<\"a\"> = {\n href: disabled ? undefined : href, role: \"link\", className: \"hjm-card__activator\",\n \"aria-label\": activationLabel, \"aria-disabled\": disabled || undefined, tabIndex: disabled ? -1 : undefined,\n };\n // Link activation belongs to the shared card; a product-owned stretched link was its own second layout (Diairy).\n const destination = href === undefined ? null : !disabled && renderLink ? renderLink(linkProps) : <a {...linkProps} />;\n return (\n <Surface\n {...(overlay ? rootProps : props)}\n ref={ref}\n as={onActivate && !overlay ? \"button\" : \"article\"}\n {...(onActivate && !overlay ? {\n type: \"button\" as const, disabled, \"aria-pressed\": selected,\n \"data-interactive\": true, onClick: activate,\n } : {})}\n {...(overlay ? { \"data-activation\": \"overlay\" } : {})}\n tone={selected ? cardRecipe.selectedTone : tone}\n bordered={bordered}\n {...(radius === undefined ? {} : { radius })}\n className={classNames(\"hjm-card\", className)}\n data-background-media={backgroundMedia ? true : undefined}\n data-state={(onActivate || href !== undefined || mediaAction) && disabled ? \"disabled\" : selected ? \"selected\" : \"idle\"}\n style={{ \"--hjm-card-background-scrim\": cardRecipe.backgroundMedia.scrim, \"--hjm-card-background-foreground\": cardRecipe.backgroundMedia.foreground, \"--hjm-card-disabled-opacity\": cardRecipe.interaction.disabledOpacity,\n \"--hjm-card-pressed-opacity\": cardRecipe.interaction.pressedOpacity, ...props.style } as CSSProperties}\n >\n {backgroundMedia ? <div className=\"hjm-card__background\" aria-hidden=\"true\">{backgroundMedia}<span className=\"hjm-card__scrim\" /></div> : null}\n {backgroundInteraction === undefined ? null : <div className=\"hjm-card__background-interaction\" data-slot=\"background-interaction\">{backgroundInteraction}</div>}\n {mediaBadges === undefined ? null : <div className=\"hjm-card__media-badges\" data-slot=\"media-badges\">{mediaBadges}</div>}\n {media ? <div className=\"hjm-card__media\" data-slot=\"media\">{mediaAction ? <button type=\"button\" className=\"hjm-card__media-action\" aria-label={mediaAction.label} disabled={disabled} onClick={() => { if (!disabled) mediaAction.onActivate(); }}>\n {media}\n {mediaAction.icon ? <span className=\"hjm-card__media-icon\" aria-hidden=\"true\" style={{ insetInlineEnd: cardRecipe.mediaAction.inset, insetBlockEnd: cardRecipe.mediaAction.inset, width: cardRecipe.mediaAction.diameter, height: cardRecipe.mediaAction.diameter }}>{mediaAction.icon({ color: \"currentColor\", size: cardRecipe.mediaAction.iconSize })}</span> : null}\n </button> : media}</div> : null}\n <div\n className=\"hjm-card__body\"\n data-slot=\"body\"\n style={{ padding: surfaceGeometry.paddings[padding] }}\n >\n {badges === undefined ? null : <div className=\"hjm-card__badges\" data-slot=\"badges\" data-align={badgesAlign}>{badges}</div>}\n {hasHeader ? (\n <div className=\"hjm-card__header\" data-slot=\"header\">\n {leading === undefined ? null : (\n <span className=\"hjm-card__leading\" data-slot=\"leading\" data-interactive={leadingAction?\"\":undefined}>\n {leadingAction?<IdentityAction action={leadingAction}>{leading}</IdentityAction>:leading}\n </span>\n )}\n <div className=\"hjm-card__copy\">\n {title === undefined\n ? null\n : createElement(\n `h${headingLevel}`,\n { className: \"hjm-card__title\", \"data-slot\": \"title\" },\n title,\n )}\n {description === undefined ? null : (\n <Text\n as=\"p\"\n tone=\"muted\"\n className=\"hjm-card__description\"\n data-slot=\"description\"\n >\n {description}\n </Text>\n )}\n </div>\n {headerActions === undefined ? null : <div className=\"hjm-card__header-actions\" data-slot=\"header-actions\">{headerActions}</div>}\n </div>\n ) : null}\n {children === undefined ? null : (\n <div className=\"hjm-card__content\" data-slot=\"content\">{children}</div>\n )}\n </div>\n {destination}\n {overlay && href === undefined ? (\n <button\n type=\"button\"\n className=\"hjm-card__activator\"\n data-slot=\"activator\"\n aria-label={activationLabel}\n aria-pressed={selected}\n disabled={disabled}\n onClick={activate}\n />\n ) : null}\n {actions ? <div className=\"hjm-card__actions\" data-slot=\"actions\">{actions}</div> : null}\n </Surface>\n );\n});\n\n/** An attributed quotation reuses Card material while keeping quotation semantics and its caption together. */\nexport type QuoteCardProps = Omit<HTMLAttributes<HTMLElement>, \"children\" | \"title\"> & Readonly<{\n children: ReactNode;\n attribution?: string;\n renderMark?: (context: { color: string; size: number }) => ReactNode;\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport function QuoteCard({ children, attribution, renderMark, ...props }: QuoteCardProps) {\n return <Card {...props} leading={<span className=\"hjm-quote-card__mark\" aria-hidden=\"true\">{renderMark?.({ color: \"currentColor\", size: cardRecipe.quotation.markSize }) ?? \"“\"}</span>}>\n <blockquote className=\"hjm-quote-card__body\">\n {children}\n {attribution === undefined ? null : <footer><Text variant=\"caption\" tone=\"muted\">{attribution}</Text></footer>}\n </blockquote>\n </Card>;\n}\n\nexport type ListRowProps = Omit<HTMLAttributes<HTMLElement>, \"title\" | \"onClick\"> &\n Readonly<{\n title: ReactNode;\n description?: ReactNode;\n leading?: ReactNode;\n /** Independent member destination; rendered beside, never inside, the row command. */\n leadingAction?: Readonly<{ label: string; onPress(): void; disabled?: boolean }>;\n trailing?: ReactNode;\n /**\n * `disclosure`: the row opens another screen. HJM draws the decorative chevron after `trailing`, inside the row\n * command (before any `trailingAction`), mirrored in RTL; size and color come from `listRowRecipe.accessories`.\n */\n trailingAccessory?: ListRowTrailingAccessory;\n /** Independent command outside the row's navigation target. */\n trailingAction?: ReactNode;\n /** Supply a framework Link without replacing the shared row layout. */\n renderLink?: (props: React.ComponentPropsWithRef<\"a\">) => ReactNode;\n density?: ListRowDensity;\n /** Semantic emphasis for destructive destinations; selection stays independent. */\n tone?: keyof typeof listRowRecipe.tones;\n /** Frame the ListRow paints around `leading`; the recipe owns its size. */\n leadingShape?: ListRowLeadingShape;\n /** Large member portraits use the shared 48px frame; icons retain the default frame. */\n leadingSize?: \"default\" | \"large\";\n selected?: boolean;\n disabled?: boolean;\n /**\n * Placeholder row while the real one loads. It keeps the row's own height\n * and slot geometry, so a list does not jump when the content arrives —\n * which is exactly what a product-owned skeleton next to the list cannot do.\n */\n loading?: boolean;\n /** Localized status text announced while `loading`. */\n loadingLabel?: string;\n href?: string;\n onClick?: MouseEventHandler<HTMLElement>;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const ListRow = forwardRef<HTMLElement, ListRowProps>(function ListRow(\n {\n title,\n description,\n leading,\n leadingAction,\n trailing,\n trailingAccessory = listRowRecipe.defaults.trailingAccessory,\n trailingAction,\n renderLink,\n density: densityProp,\n tone = listRowRecipe.defaults.tone,\n leadingShape = \"square\",\n leadingSize = leadingShape === \"circle\" ? \"large\" : \"default\",\n selected,\n disabled = false,\n loading = false,\n loadingLabel,\n href,\n onClick,\n className,\n layoutStyle,\n style,\n ...props\n },\n ref,\n) {\n // The hook runs unconditionally — `??` would short-circuit it and break the\n // rules of hooks on the very first row that passes `density`.\n const separateActions = Boolean(trailingAction || leadingAction);\n const densityDefault = useHjmDensityDefault({\n comfortable: listRowRecipe.defaults.density,\n compact: \"compact\",\n });\n const density = densityProp ?? densityDefault;\n validateListRowTrailingAccessory(trailingAccessory);\n const accessory = trailingAccessory === \"none\" ? null : listRowRecipe.accessories[trailingAccessory];\n if (loading) {\n // A loading row is never interactive: there is nothing to activate yet.\n return (\n <div\n {...props}\n ref={ref as React.Ref<HTMLDivElement>}\n role={loadingLabel ? \"status\" : undefined}\n aria-busy={loadingLabel ? true : undefined}\n aria-hidden={loadingLabel ? undefined : true}\n aria-label={loadingLabel}\n className={classNames(\"hjm-list-row\", \"hjm-list-row--loading\", className)}\n data-density={density}\n data-leading={leading ? \"\" : undefined}\n data-lines={description ? \"two\" : \"one\"}\n data-state=\"loading\"\n style={{ ...style, ...layoutStyle }}\n >\n {leading ? <span className=\"hjm-list-row__leading\" data-shape={leadingShape} data-size={leadingSize} data-placeholder=\"\" /> : null}\n <span className=\"hjm-list-row__content\">\n <span className=\"hjm-list-row__title\" data-placeholder=\"\" style={{ width: `${listRowRecipe.loading.titleWidthPercent}%` }} />\n {description ? <span className=\"hjm-list-row__description\" data-placeholder=\"\" style={{ width: `${listRowRecipe.loading.descriptionWidthPercent}%` }} /> : null}\n </span>\n {trailing ? <span className=\"hjm-list-row__trailing\" data-placeholder=\"\" style={{ width: listRowRecipe.loading.trailingWidth }} /> : null}\n {/* Keep the accessory's box so the text column does not shift when the real row arrives. */}\n {accessory ? <span className=\"hjm-list-row__accessory\" data-accessory={trailingAccessory} style={{ inlineSize: glyph[accessory.glyph], blockSize: glyph[accessory.glyph] }} /> : null}\n </div>\n );\n }\n const element = href ? \"a\" : onClick ? \"button\" : \"div\";\n const interactiveProps = href\n ? {\n href: disabled ? undefined : href,\n \"aria-current\": selected ? (\"page\" as const) : undefined,\n \"aria-disabled\": disabled || undefined,\n tabIndex: disabled ? -1 : undefined,\n }\n : onClick\n ? {\n type: \"button\" as const,\n onClick: disabled ? undefined : onClick,\n disabled,\n \"aria-pressed\": selected,\n }\n : {};\n\n const row = createElement(\n element,\n {\n ...props,\n ...interactiveProps,\n ref,\n className: classNames(\"hjm-list-row\", className),\n \"data-density\": density,\n // Exposes the text column to the enclosing List: its indented separator starts after the leading frame\n // (listRecipe.separators.indented.leadingInsetStart) only when this row has one.\n \"data-leading\": leading ? \"\" : undefined,\n \"data-tone\": tone,\n // One- and two-line rows have different minimum heights in the recipe;\n // the web renderer used a single hardcoded value until now.\n \"data-lines\": description ? \"two\" : \"one\",\n \"data-state\": disabled ? \"disabled\" : selected ? \"selected\" : \"idle\",\n // Placement wins over the legacy `style`, matching Surface's ordering.\n // With trailingAction the frame is the placed root, as Native's outer View.\n style: separateActions ? style : { ...style, ...layoutStyle },\n },\n leading && !leadingAction\n ? <span className=\"hjm-list-row__leading\" data-shape={leadingShape} data-size={leadingSize}>{leading}</span>\n : null,\n <span className=\"hjm-list-row__content\">\n <span className=\"hjm-list-row__title\">{title}</span>\n {description ? (\n <span className=\"hjm-list-row__description\">{description}</span>\n ) : null}\n </span>,\n trailing ? <span className=\"hjm-list-row__trailing\">{trailing}</span> : null,\n accessory\n ? <span className=\"hjm-list-row__accessory\" data-accessory={trailingAccessory} aria-hidden=\"true\">\n <Icon name={accessory.icon} size={accessory.glyph} weight={accessory.weight} />\n </span>\n : null,\n );\n const linked = href && renderLink ? renderLink(row.props as React.ComponentPropsWithRef<\"a\">) : row;\n // The frame owns the row surface and its bleed so the command and the separate action share one fill, as Native;\n // the action stays outside the link/button (styles.css `.hjm-list-row-frame`).\n return separateActions ? (\n <div className=\"hjm-list-row-frame\" data-leading-action={leadingAction ? \"\" : undefined} data-trailing-action={trailingAction ? \"\" : undefined} data-density={density} data-leading={leading ? \"\" : undefined}\n data-state={disabled ? \"disabled\" : selected ? \"selected\" : \"idle\"} style={layoutStyle}>\n {leadingAction && leading ? <div className=\"hjm-list-row__profile\"><IdentityAction action={leadingAction}>{leading}</IdentityAction></div> : null}\n {linked}\n {trailingAction ? <div className=\"hjm-list-row__action\">{trailingAction}</div> : null}\n </div>\n ) : linked;\n});\n"]}
|
|
1
|
+
{"version":3,"file":"display.js","sourceRoot":"","sources":["../src/display.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AACb,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D,OAAO,EACL,WAAW,EACX,aAAa,EAKb,yBAAyB,EACzB,gCAAgC,GAKjC,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,gCAAgC,CAAC;AACxD,OAAO,EAAE,KAAK,EAAE,MAAM,qCAAqC,CAAC;AAC5D,OAAO,EACL,oBAAoB,GAErB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,UAAU,GAEX,MAAM,yCAAyC,CAAC;AACjD,OAAO,EACL,eAAe,GAIhB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,aAAa,EACb,UAAU,GAKX,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,2BAA2B,CAAC;AAuBjD,MAAM,CAAC,MAAM,KAAK,GAAG,UAAU,CAA8B,SAAS,KAAK,CACzE,EACE,IAAI,EAAE,QAAQ,EACd,aAAa,EACb,IAAI,GAAG,WAAW,CAAC,QAAQ,CAAC,IAAI,EAChC,OAAO,GAAG,WAAW,CAAC,QAAQ,CAAC,OAAO,EACtC,OAAO,EACP,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,WAAW,EACX,KAAK,EACL,GAAG,KAAK,EACT,EACD,GAAG;IAEH,IAAI,aAAa,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS;QAAE,MAAM,IAAI,SAAS,CAAC,oDAAoD,CAAC,CAAC;IACrI,MAAM,IAAI,GAAG,QAAQ,IAAI,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC;IACnD,uGAAuG;IACvG,MAAM,KAAK,GAAG,mBAAmB,EAAE,CAAC;IACpC,MAAM,QAAQ,GAAG,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,yBAAyB,CAAC,aAAa,EAAE;QAC7F,KAAK,EAAE,KAAK,EAAE,WAAW,CAAC,KAAK,IAAI,OAAO;QAC1C,OAAO;QACP,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK;KAC9C,CAAC,CAAC;IACH,MAAM,WAAW,GAAG,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,WAAW,EAAE,WAAW,CAAC,eAAe,EAAE,CAAC;IAChI,OAAO,CACL,mBACM,KAAK,EACT,KAAK,EAAE;YACL,GAAG,KAAK;YACR,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;gBACb,8BAA8B,EAAE,QAAQ,CAAC,OAAO;gBAChD,iCAAiC,EAAE,QAAQ,CAAC,UAAU,IAAI,aAAa;gBACvE,6BAA6B,EAAE,QAAQ,CAAC,MAAM,IAAI,aAAa;aAC/C,CAAC,CAAC,CAAC,EAAE,CAAC;YACxB,GAAG,WAAW;SACf,EACD,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,UAAU,CAAC,WAAW,EAAE,SAAS,CAAC,eAClC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,eAC5B,IAAI,kBACD,OAAO,aAEpB,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAC9B,8BAAkB,MAAM,EAAC,SAAS,EAAC,iBAAiB,YACjD,OAAO,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,OAAO,GAC1D,CACR,EACD,eAAM,SAAS,EAAC,kBAAkB,YAAE,QAAQ,GAAQ,EACnD,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAC/B,8BAAkB,MAAM,EAAC,SAAS,EAAC,iBAAiB,YAAE,OAAO,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAQ,CAChI,IACI,CACR,CAAC;AACJ,CAAC,CAAC,CAAC;AAUH,MAAM,CAAC,MAAM,GAAG,GAAG,UAAU,CAA4B,SAAS,GAAG,CACnE,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,EAC3D,GAAG;IAEH,MAAM,UAAU,GAAG,oBAAoB,CAAC;QACtC,KAAK,EAAE,QAAQ;QACf,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;KACxC,CAAC,CAAC;IACH,OAAO,CACL,kBACM,KAAK,EACT,KAAK,EAAE,EAAE,GAAG,KAAK,EAAE,GAAG,WAAW,EAAE,EACnC,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,UAAU,CAAC,SAAS,EAAE,SAAS,CAAC,eAChC,UAAU,CAAC,IAAI,YAE1B,eAAM,SAAS,EAAC,gBAAgB,YAAE,UAAU,CAAC,KAAK,GAAQ,GACrD,CACR,CAAC;AACJ,CAAC,CAAC,CAAC;AA8CH,MAAM,CAAC,MAAM,IAAI,GAAG,UAAU,CAAyB,SAAS,IAAI,CAClE,EACE,KAAK,EACL,WAAW,EACX,OAAO,EACP,aAAa,EACb,KAAK,EACL,eAAe,EACf,qBAAqB,EACrB,WAAW,EACX,MAAM,EACN,WAAW,GAAG,UAAU,CAAC,QAAQ,CAAC,WAAW,EAC7C,eAAe,GAAG,UAAU,CAAC,QAAQ,CAAC,eAAe,EACrD,WAAW,EACX,OAAO,EACP,aAAa,EACb,YAAY,GAAG,UAAU,CAAC,QAAQ,CAAC,YAAY;AAC/C,uEAAuE;AACvE,QAAQ,EACR,UAAU,EAAE,IAAI,EAAE,UAAU,EAC5B,QAAQ,GAAG,KAAK,EAChB,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,IAAI,EAC/B,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,QAAQ,EACvC,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,OAAO,EACrC,MAAM,EACN,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EACD,GAAG;IAEH,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,UAAU,CAAC;QAAE,MAAM,IAAI,SAAS,CAAC,qEAAqE,CAAC,CAAC;IACnJ,IAAI,UAAU,IAAI,IAAI,KAAK,SAAS;QAAE,MAAM,IAAI,SAAS,CAAC,+BAA+B,CAAC,CAAC;IAC3F,IAAI,CAAC,UAAU,IAAI,IAAI,KAAK,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC;QACvE,MAAM,IAAI,SAAS,CAAC,sCAAsC,CAAC,CAAC;IAC9D,CAAC;IACD,IAAI,WAAW,IAAI,CAAC,UAAU,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,KAAK,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAAE,MAAM,IAAI,SAAS,CAAC,gFAAgF,CAAC,CAAC;IACpM,IAAI,eAAe,IAAI,CAAC,KAAK,IAAI,WAAW,IAAI,UAAU,IAAI,IAAI,KAAK,SAAS,CAAC;QAAE,MAAM,IAAI,SAAS,CAAC,mGAAmG,CAAC,CAAC;IAC5M,IAAI,CAAC,qBAAqB,KAAK,SAAS,IAAI,WAAW,KAAK,SAAS,CAAC,IAAI,CAAC,eAAe;QAAE,MAAM,IAAI,SAAS,CAAC,gEAAgE,CAAC,CAAC;IAClL,MAAM,SAAS,GACb,OAAO,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,IAAI,WAAW,KAAK,SAAS,IAAI,aAAa,KAAK,SAAS,CAAC;IAC3G,mHAAmH;IACnH,oHAAoH;IACpH,MAAM,OAAO,GAAG,IAAI,KAAK,SAAS,IAAI,CAAC,UAAU,KAAK,SAAS,IAAI,OAAO,CAAC,OAAO,IAAI,aAAa,IAAI,aAAa,CAAC,CAAC,CAAC;IACvH,MAAM,EAAE,YAAY,EAAE,eAAe,EAAE,GAAG,SAAS,EAAE,GAAG,KAAK,CAAC;IAC9D,MAAM,QAAQ,GAAG,GAAG,EAAE,GAAG,IAAI,CAAC,QAAQ;QAAE,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IAE1D,MAAM,SAAS,GAAqC;QAClD,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,qBAAqB;QACjF,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,QAAQ,IAAI,SAAS,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;KAC3G,CAAC;IACF,iHAAiH;IACjH,MAAM,WAAW,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,eAAO,SAAS,GAAI,CAAC;IACvH,OAAO,CACL,MAAC,OAAO,OACF,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,EACjC,GAAG,EAAE,GAAG,EACR,EAAE,EAAE,UAAU,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,KAC7C,CAAC,UAAU,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;YAC5B,IAAI,EAAE,QAAiB,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ;YAC3D,kBAAkB,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ;SAC5C,CAAC,CAAC,CAAC,EAAE,CAAC,KACH,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EACrD,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,EAC/C,QAAQ,EAAE,QAAQ,KACd,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAC5C,SAAS,EAAE,UAAU,CAAC,UAAU,EAAE,SAAS,CAAC,2BACrB,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,gBAC7C,CAAC,UAAU,IAAI,IAAI,KAAK,SAAS,IAAI,WAAW,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,EACvH,KAAK,EAAE,EAAE,6BAA6B,EAAE,UAAU,CAAC,eAAe,CAAC,KAAK,EAAE,kCAAkC,EAAE,UAAU,CAAC,eAAe,CAAC,UAAU,EAAE,6BAA6B,EAAE,UAAU,CAAC,WAAW,CAAC,eAAe;YACxN,4BAA4B,EAAE,UAAU,CAAC,WAAW,CAAC,cAAc,EAAE,GAAG,KAAK,CAAC,KAAK,EAAmB,aAEvG,MAAM,KAAK,SAAS,IAAI,eAAe,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAK,SAAS,EAAC,yBAAyB,eAAW,eAAe,EAAC,KAAK,EAAE,EAAE,GAAG,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,UAAU,UAAU,CAAC,WAAW,CAAC,QAAQ,MAAM,EAAE,YAAG,MAAM,GAAO,CAAC,CAAC,CAAC,IAAI,EAC9R,eAAe,CAAC,CAAC,CAAC,eAAK,SAAS,EAAC,sBAAsB,iBAAa,MAAM,aAAE,eAAe,EAAC,eAAM,SAAS,EAAC,iBAAiB,GAAG,IAAM,CAAC,CAAC,CAAC,IAAI,EAC7I,qBAAqB,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,cAAK,SAAS,EAAC,kCAAkC,eAAW,wBAAwB,YAAE,qBAAqB,GAAO,EAC/J,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,cAAK,SAAS,EAAC,wBAAwB,eAAW,cAAc,YAAE,WAAW,GAAO,EACvH,KAAK,CAAC,CAAC,CAAC,cAAK,SAAS,EAAC,iBAAiB,eAAW,OAAO,YAAE,WAAW,CAAC,CAAC,CAAC,kBAAQ,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,wBAAwB,gBAAa,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,QAAQ;wBAAE,WAAW,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,aAC/O,KAAK,EACL,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,eAAM,SAAS,EAAC,sBAAsB,iBAAa,MAAM,EAAC,KAAK,EAAE,EAAE,cAAc,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,EAAE,aAAa,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,WAAW,CAAC,QAAQ,EAAE,YAAG,WAAW,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,UAAU,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,GAAQ,CAAC,CAAC,CAAC,IAAI,IAChW,CAAC,CAAC,CAAC,KAAK,GAAO,CAAC,CAAC,CAAC,IAAI,EAC/B,eACE,SAAS,EAAC,gBAAgB,eAChB,MAAM,EAChB,KAAK,EAAE,EAAE,OAAO,EAAE,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,aAEpD,MAAM,KAAK,SAAS,IAAI,eAAe,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,cAAK,SAAS,EAAC,kBAAkB,eAAW,QAAQ,gBAAa,WAAW,YAAG,MAAM,GAAO,EACxJ,SAAS,CAAC,CAAC,CAAC,CACX,eAAK,SAAS,EAAC,kBAAkB,eAAW,QAAQ,aACjD,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAC9B,eAAM,SAAS,EAAC,mBAAmB,eAAW,SAAS,sBAAmB,aAAa,CAAA,CAAC,CAAA,EAAE,CAAA,CAAC,CAAA,SAAS,YACjG,aAAa,CAAA,CAAC,CAAA,KAAC,cAAc,IAAC,MAAM,EAAE,aAAa,YAAG,OAAO,GAAkB,CAAA,CAAC,CAAA,OAAO,GACnF,CACR,EACD,eAAK,SAAS,EAAC,gBAAgB,aAC5B,KAAK,KAAK,SAAS;wCAClB,CAAC,CAAC,IAAI;wCACN,CAAC,CAAC,aAAa,CACX,IAAI,YAAY,EAAE,EAClB,EAAE,SAAS,EAAE,iBAAiB,EAAE,WAAW,EAAE,OAAO,EAAE,EACtD,KAAK,CACN,EACJ,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAClC,KAAC,IAAI,IACH,EAAE,EAAC,GAAG,EACN,IAAI,EAAC,OAAO,EACZ,SAAS,EAAC,uBAAuB,eACvB,aAAa,YAEtB,WAAW,GACP,CACR,IACG,EACL,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,cAAK,SAAS,EAAC,0BAA0B,eAAW,gBAAgB,YAAE,aAAa,GAAO,IAC5H,CACP,CAAC,CAAC,CAAC,IAAI,EACP,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAC/B,cAAK,SAAS,EAAC,mBAAmB,eAAW,SAAS,YAAE,QAAQ,GAAO,CACxE,IACG,EACL,WAAW,EACX,OAAO,IAAI,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAC/B,iBACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAC,qBAAqB,eACrB,WAAW,gBACT,eAAe,kBACb,QAAQ,EACtB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,QAAQ,GACjB,CACH,CAAC,CAAC,CAAC,IAAI,EACP,OAAO,CAAC,CAAC,CAAC,cAAK,SAAS,EAAC,mBAAmB,eAAW,SAAS,YAAE,OAAO,GAAO,CAAC,CAAC,CAAC,IAAI,IAChF,CACX,CAAC;AACJ,CAAC,CAAC,CAAC;AAUH,MAAM,UAAU,SAAS,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,KAAK,EAAkB;IACvF,OAAO,KAAC,IAAI,OAAK,KAAK,EAAE,OAAO,EAAE,eAAM,SAAS,EAAC,sBAAsB,iBAAa,MAAM,YAAE,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,UAAU,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,IAAI,GAAG,GAAQ,YACrL,sBAAY,SAAS,EAAC,sBAAsB,aACzC,QAAQ,EACR,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,2BAAQ,KAAC,IAAI,IAAC,OAAO,EAAC,SAAS,EAAC,IAAI,EAAC,OAAO,YAAE,WAAW,GAAQ,GAAS,IACnG,GACR,CAAC;AACV,CAAC;AA0CD,MAAM,CAAC,MAAM,OAAO,GAAG,UAAU,CAA4B,SAAS,OAAO,CAC3E,EACE,KAAK,EACL,WAAW,EACX,OAAO,EACP,aAAa,EACb,QAAQ,EACR,iBAAiB,GAAG,aAAa,CAAC,QAAQ,CAAC,iBAAiB,EAC5D,cAAc,EACd,UAAU,EACV,OAAO,EAAE,WAAW,EACpB,IAAI,GAAG,aAAa,CAAC,QAAQ,CAAC,IAAI,EAClC,YAAY,GAAG,QAAQ,EACvB,WAAW,GAAG,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAC7D,QAAQ,EACR,QAAQ,GAAG,KAAK,EAChB,OAAO,GAAG,KAAK,EACf,YAAY,EACZ,IAAI,EACJ,OAAO,EACP,SAAS,EACT,WAAW,EACX,KAAK,EACL,GAAG,KAAK,EACT,EACD,GAAG;IAEH,4EAA4E;IAC5E,8DAA8D;IAC9D,MAAM,eAAe,GAAG,OAAO,CAAC,cAAc,IAAI,aAAa,CAAC,CAAC;IACjE,MAAM,cAAc,GAAG,oBAAoB,CAAC;QAC1C,WAAW,EAAE,aAAa,CAAC,QAAQ,CAAC,OAAO;QAC3C,OAAO,EAAE,SAAS;KACnB,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,WAAW,IAAI,cAAc,CAAC;IAC9C,gCAAgC,CAAC,iBAAiB,CAAC,CAAC;IACpD,MAAM,SAAS,GAAG,iBAAiB,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC;IACrG,IAAI,OAAO,EAAE,CAAC;QACZ,wEAAwE;QACxE,OAAO,CACL,kBACM,KAAK,EACT,GAAG,EAAE,GAAgC,EACrC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,eAC9B,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,iBAC7B,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,gBAChC,YAAY,EACxB,SAAS,EAAE,UAAU,CAAC,cAAc,EAAE,uBAAuB,EAAE,SAAS,CAAC,kBAC3D,OAAO,kBACP,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,gBAC1B,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,gBAC5B,SAAS,EACpB,KAAK,EAAE,EAAE,GAAG,KAAK,EAAE,GAAG,WAAW,EAAE,aAElC,OAAO,CAAC,CAAC,CAAC,eAAM,SAAS,EAAC,uBAAuB,gBAAa,YAAY,eAAa,WAAW,sBAAmB,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,EAClI,gBAAM,SAAS,EAAC,uBAAuB,aACrC,eAAM,SAAS,EAAC,qBAAqB,sBAAkB,EAAE,EAAC,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,aAAa,CAAC,OAAO,CAAC,iBAAiB,GAAG,EAAE,GAAI,EAC5H,WAAW,CAAC,CAAC,CAAC,eAAM,SAAS,EAAC,2BAA2B,sBAAkB,EAAE,EAAC,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,aAAa,CAAC,OAAO,CAAC,uBAAuB,GAAG,EAAE,GAAI,CAAC,CAAC,CAAC,IAAI,IAC1J,EACN,QAAQ,CAAC,CAAC,CAAC,eAAM,SAAS,EAAC,wBAAwB,sBAAkB,EAAE,EAAC,KAAK,EAAE,EAAE,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,aAAa,EAAE,GAAI,CAAC,CAAC,CAAC,IAAI,EAExI,SAAS,CAAC,CAAC,CAAC,eAAM,SAAS,EAAC,yBAAyB,oBAAiB,iBAAiB,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,GAAI,CAAC,CAAC,CAAC,IAAI,IACjL,CACP,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;IACxD,MAAM,gBAAgB,GAAG,IAAI;QAC3B,CAAC,CAAC;YACE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI;YACjC,cAAc,EAAE,QAAQ,CAAC,CAAC,CAAE,MAAgB,CAAC,CAAC,CAAC,SAAS;YACxD,eAAe,EAAE,QAAQ,IAAI,SAAS;YACtC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;SACpC;QACH,CAAC,CAAC,OAAO;YACP,CAAC,CAAC;gBACE,IAAI,EAAE,QAAiB;gBACvB,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO;gBACvC,QAAQ;gBACR,cAAc,EAAE,QAAQ;aACzB;YACH,CAAC,CAAC,EAAE,CAAC;IAET,MAAM,GAAG,GAAG,aAAa,CACvB,OAAO,EACP;QACE,GAAG,KAAK;QACR,GAAG,gBAAgB;QACnB,GAAG;QACH,SAAS,EAAE,UAAU,CAAC,cAAc,EAAE,SAAS,CAAC;QAChD,cAAc,EAAE,OAAO;QACvB,uGAAuG;QACvG,iFAAiF;QACjF,cAAc,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;QACxC,WAAW,EAAE,IAAI;QACjB,uEAAuE;QACvE,4DAA4D;QAC5D,YAAY,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK;QACzC,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM;QACpE,uEAAuE;QACvE,4EAA4E;QAC5E,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,GAAG,WAAW,EAAE;KAC9D,EACD,OAAO,IAAI,CAAC,aAAa;QACvB,CAAC,CAAC,eAAM,SAAS,EAAC,uBAAuB,gBAAa,YAAY,eAAa,WAAW,YAAG,OAAO,GAAQ;QAC5G,CAAC,CAAC,IAAI,EACR,gBAAM,SAAS,EAAC,uBAAuB,aACrC,eAAM,SAAS,EAAC,qBAAqB,YAAE,KAAK,GAAQ,EACnD,WAAW,CAAC,CAAC,CAAC,CACb,eAAM,SAAS,EAAC,2BAA2B,YAAE,WAAW,GAAQ,CACjE,CAAC,CAAC,CAAC,IAAI,IACH,EACP,QAAQ,CAAC,CAAC,CAAC,eAAM,SAAS,EAAC,wBAAwB,YAAE,QAAQ,GAAQ,CAAC,CAAC,CAAC,IAAI,EAC5E,SAAS;QACP,CAAC,CAAC,eAAM,SAAS,EAAC,yBAAyB,oBAAiB,iBAAiB,iBAAc,MAAM,YAC7F,KAAC,IAAI,IAAC,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,GAAI,GAC1E;QACT,CAAC,CAAC,IAAI,CACT,CAAC;IACF,MAAM,MAAM,GAAG,IAAI,IAAI,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,KAAyC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IACpG,iHAAiH;IACjH,+EAA+E;IAC/E,OAAO,eAAe,CAAC,CAAC,CAAC,CACvB,eAAK,SAAS,EAAC,oBAAoB,yBAAsB,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,0BAAwB,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,kBAAgB,OAAO,kBAAgB,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,gBAC/L,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,WAAW,aACrF,aAAa,IAAI,OAAO,CAAC,CAAC,CAAC,cAAK,SAAS,EAAC,uBAAuB,YAAC,KAAC,cAAc,IAAC,MAAM,EAAE,aAAa,YAAG,OAAO,GAAkB,GAAM,CAAC,CAAC,CAAC,IAAI,EAChJ,MAAM,EACN,cAAc,CAAC,CAAC,CAAC,cAAK,SAAS,EAAC,sBAAsB,YAAE,cAAc,GAAO,CAAC,CAAC,CAAC,IAAI,IACjF,CACP,CAAC,CAAC,CAAC,MAAM,CAAC;AACb,CAAC,CAAC,CAAC","sourcesContent":["\"use client\";\nimport { IdentityAction } from \"./internal/identity-action.js\";\n\nimport {\n badgeRecipe,\n listRowRecipe,\n type BadgeAdornmentContext,\n type BadgeSize,\n type BadgeTone,\n type BadgeVariant as ContractBadgeVariant,\n resolveBadgeCategoryColor,\n validateListRowTrailingAccessory,\n type BadgeCategoryColor,\n type ListRowDensity,\n type ListRowLeadingShape,\n type ListRowTrailingAccessory,\n} from \"@hjmds/design-contracts/recipes\";\nimport { THEMES } from \"@hjmds/design-contracts/colors\";\nimport { glyph } from \"@hjmds/design-contracts/foundations\";\nimport {\n resolveTagDescriptor,\n type TagTone,\n} from \"@hjmds/design-contracts/components/tag\";\nimport {\n cardRecipe,\n type CardHeadingLevel,\n} from \"@hjmds/design-contracts/components/card\";\nimport {\n surfaceGeometry,\n type SurfacePadding,\n type SurfaceRadius,\n type SurfaceTone,\n} from \"@hjmds/design-contracts/recipes/base\";\nimport {\n createElement,\n forwardRef,\n type CSSProperties,\n type HTMLAttributes,\n type MouseEventHandler,\n type ReactNode,\n} from \"react\";\nimport { classNames } from \"./internal.js\";\nimport { useHjmDensityDefault, useOptionalHjmTheme } from \"./provider.js\";\nimport { Surface, Text } from \"./layout.js\";\nimport { Icon } from \"./supplemental-display.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type { CardHeadingLevel } from \"@hjmds/design-contracts/components/card\";\nexport type { TagTone } from \"@hjmds/design-contracts/components/tag\";\nexport type BadgeVariant = ContractBadgeVariant;\n\nexport type BadgeProps = HTMLAttributes<HTMLSpanElement> &\n Readonly<{\n tone?: BadgeTone;\n /**\n * Product classification color per theme (series, grade…) in place of `tone`. HJM keeps the frame and picks the\n * label ink; a color whose label cannot reach AA 4.5 throws instead of rendering unreadable.\n */\n categoryColor?: BadgeCategoryColor;\n size?: BadgeSize;\n variant?: BadgeVariant;\n leading?: ReactNode | ((context: BadgeAdornmentContext) => ReactNode);\n trailing?: ReactNode | ((context: BadgeAdornmentContext) => ReactNode);\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const Badge = forwardRef<HTMLSpanElement, BadgeProps>(function Badge(\n {\n tone: toneProp,\n categoryColor,\n size = badgeRecipe.defaults.size,\n variant = badgeRecipe.defaults.variant,\n leading,\n trailing,\n className,\n children,\n layoutStyle,\n style,\n ...props\n },\n ref,\n) {\n if (categoryColor !== undefined && toneProp !== undefined) throw new TypeError(\"Badge takes either tone or categoryColor, not both\");\n const tone = toneProp ?? badgeRecipe.defaults.tone;\n // Outside a provider the stylesheet paints the light palette, so the category resolves against it too.\n const theme = useOptionalHjmTheme();\n const category = categoryColor === undefined ? null : resolveBadgeCategoryColor(categoryColor, {\n theme: theme?.environment.theme ?? \"light\",\n variant,\n palette: theme?.palette.theme ?? THEMES.light,\n });\n const iconContext = { color: \"currentColor\", size: badgeRecipe.sizes[size].iconSize, strokeWidth: badgeRecipe.iconStrokeWidth };\n return (\n <span\n {...props}\n style={{\n ...style,\n ...(category ? {\n \"--hjm-badge-category-content\": category.content,\n \"--hjm-badge-category-background\": category.background ?? \"transparent\",\n \"--hjm-badge-category-border\": category.border ?? \"transparent\",\n } as CSSProperties : {}),\n ...layoutStyle,\n }}\n ref={ref}\n className={classNames(\"hjm-badge\", className)}\n data-tone={category ? \"category\" : tone}\n data-size={size}\n data-variant={variant}\n >\n {leading === undefined ? null : (\n <span aria-hidden=\"true\" className=\"hjm-badge__icon\">\n {typeof leading === \"function\" ? leading(iconContext) : leading}\n </span>\n )}\n <span className=\"hjm-badge__label\">{children}</span>\n {trailing === undefined ? null : (\n <span aria-hidden=\"true\" className=\"hjm-badge__icon\">{typeof trailing === \"function\" ? trailing(iconContext) : trailing}</span>\n )}\n </span>\n );\n});\n\nexport type TagProps = Omit<HTMLAttributes<HTMLSpanElement>, \"children\"> &\n Readonly<{\n children: string;\n tone?: TagTone;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const Tag = forwardRef<HTMLSpanElement, TagProps>(function Tag(\n { children, tone, className, layoutStyle, style, ...props },\n ref,\n) {\n const descriptor = resolveTagDescriptor({\n label: children,\n ...(tone === undefined ? {} : { tone }),\n });\n return (\n <span\n {...props}\n style={{ ...style, ...layoutStyle }}\n ref={ref}\n className={classNames(\"hjm-tag\", className)}\n data-tone={descriptor.tone}\n >\n <span className=\"hjm-tag__label\">{descriptor.label}</span>\n </span>\n );\n});\n\nexport type CardProps = Omit<HTMLAttributes<HTMLElement>, \"title\"> &\n Readonly<{\n title?: ReactNode;\n description?: ReactNode;\n leading?: ReactNode;\n /** Independent identity destination, outside the card activation host. */\n leadingAction?: Readonly<{label:string;onPress():void; disabled?: boolean }>;\n media?: ReactNode;\n /** Decorative artwork behind the shared body/actions; its host determines the available height. */\n backgroundMedia?: ReactNode;\n /** Platform gesture/accessibility host behind content. Requires backgroundMedia; never put metadata/actions here. */\n backgroundInteraction?: ReactNode;\n /** Non-interactive cover classification at the shared top/end inset. Requires backgroundMedia. */\n mediaBadges?: ReactNode;\n badges?: ReactNode;\n /** Corner labels float above content without changing card height; keep their copy short. */\n badgesPlacement?: \"body\" | \"corner\";\n /** Centre short metadata beneath artwork without product-owned badge layout. */\n badgesAlign?: \"start\" | \"center\";\n /** Activate only the passive cover; other card content/actions keep independent targets. */\n mediaAction?: Readonly<{ label: string; onActivate(): void; icon?: (context: Readonly<{ color: string; size: number }>) => ReactNode }>;\n actions?: ReactNode;\n /** Independent commands at the header end; never nested in whole-card activation. */\n headerActions?: ReactNode;\n headingLevel?: CardHeadingLevel;\n selected?: boolean;\n /**\n * Whole-card activation. With `actions`, the card stays an article and a separate full-card button sits under the\n * action region, so actions remain independent buttons (never a button inside a button). Keep other children passive.\n */\n onActivate?: () => void;\n /** A native anchor preserves new-tab, copy-link and browser previews; it is exclusive with onActivate. */\n href?: string;\n /** Framework routing and product effects can wrap the shared anchor without replacing its placement. */\n renderLink?: (props: React.ComponentPropsWithRef<\"a\">) => ReactNode;\n disabled?: boolean;\n tone?: SurfaceTone;\n bordered?: boolean;\n padding?: SurfacePadding;\n radius?: SurfaceRadius;\n /** Canonical layout-only placement; forwarded to the root Surface, which applies it. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\nexport const Card = forwardRef<HTMLElement, CardProps>(function Card(\n {\n title,\n description,\n leading,\n leadingAction,\n media,\n backgroundMedia,\n backgroundInteraction,\n mediaBadges,\n badges,\n badgesAlign = cardRecipe.defaults.badgesAlign,\n badgesPlacement = cardRecipe.defaults.badgesPlacement,\n mediaAction,\n actions,\n headerActions,\n headingLevel = cardRecipe.defaults.headingLevel,\n // An omitted selection is an ordinary action, not an unpressed toggle.\n selected,\n onActivate, href, renderLink,\n disabled = false,\n tone = cardRecipe.defaults.tone,\n bordered = cardRecipe.defaults.bordered,\n padding = cardRecipe.defaults.padding,\n radius,\n className,\n children,\n ...props\n },\n ref,\n) {\n if (href !== undefined && (!href.trim() || onActivate)) throw new TypeError(\"Card href requires a destination and cannot combine with onActivate\");\n if (renderLink && href === undefined) throw new TypeError(\"Card renderLink requires href\");\n if ((onActivate || href !== undefined) && !props[\"aria-label\"]?.trim()) {\n throw new TypeError(\"Interactive Card requires aria-label\");\n }\n if (mediaAction && (onActivate || href !== undefined || !media || !mediaAction.label.trim())) throw new TypeError(\"Card mediaAction requires passive media, a label, and no whole-card activation\");\n if (backgroundMedia && (media || mediaAction || onActivate || href !== undefined)) throw new TypeError(\"Card backgroundMedia is decorative and cannot combine with media, mediaAction, onActivate or href\");\n if ((backgroundInteraction !== undefined || mediaBadges !== undefined) && !backgroundMedia) throw new TypeError(\"Card backgroundInteraction/mediaBadges require backgroundMedia\");\n const hasHeader =\n leading !== undefined || title !== undefined || description !== undefined || headerActions !== undefined;\n // Whole-card open plus separate commands (2026-10-18 unairplane journey card: open + delete). A root button cannot\n // contain the action buttons, so the root stays an article and an overlay button carries the card's name and state.\n const overlay = href !== undefined || (onActivate !== undefined && Boolean(actions || headerActions || leadingAction));\n const { \"aria-label\": activationLabel, ...rootProps } = props;\n const activate = () => { if (!disabled) onActivate?.(); };\n\n const linkProps: React.ComponentPropsWithRef<\"a\"> = {\n href: disabled ? undefined : href, role: \"link\", className: \"hjm-card__activator\",\n \"aria-label\": activationLabel, \"aria-disabled\": disabled || undefined, tabIndex: disabled ? -1 : undefined,\n };\n // Link activation belongs to the shared card; a product-owned stretched link was its own second layout (Diairy).\n const destination = href === undefined ? null : !disabled && renderLink ? renderLink(linkProps) : <a {...linkProps} />;\n return (\n <Surface\n {...(overlay ? rootProps : props)}\n ref={ref}\n as={onActivate && !overlay ? \"button\" : \"article\"}\n {...(onActivate && !overlay ? {\n type: \"button\" as const, disabled, \"aria-pressed\": selected,\n \"data-interactive\": true, onClick: activate,\n } : {})}\n {...(overlay ? { \"data-activation\": \"overlay\" } : {})}\n tone={selected ? cardRecipe.selectedTone : tone}\n bordered={bordered}\n {...(radius === undefined ? {} : { radius })}\n className={classNames(\"hjm-card\", className)}\n data-background-media={backgroundMedia ? true : undefined}\n data-state={(onActivate || href !== undefined || mediaAction) && disabled ? \"disabled\" : selected ? \"selected\" : \"idle\"}\n style={{ \"--hjm-card-background-scrim\": cardRecipe.backgroundMedia.scrim, \"--hjm-card-background-foreground\": cardRecipe.backgroundMedia.foreground, \"--hjm-card-disabled-opacity\": cardRecipe.interaction.disabledOpacity,\n \"--hjm-card-pressed-opacity\": cardRecipe.interaction.pressedOpacity, ...props.style } as CSSProperties}\n >\n {badges !== undefined && badgesPlacement === \"corner\" ? <div className=\"hjm-card__corner-badges\" data-slot=\"corner-badges\" style={{ top: cardRecipe.cornerBadge.inset, right: cardRecipe.cornerBadge.inset, transform: `rotate(${cardRecipe.cornerBadge.rotation}deg)` }}>{badges}</div> : null}\n {backgroundMedia ? <div className=\"hjm-card__background\" aria-hidden=\"true\">{backgroundMedia}<span className=\"hjm-card__scrim\" /></div> : null}\n {backgroundInteraction === undefined ? null : <div className=\"hjm-card__background-interaction\" data-slot=\"background-interaction\">{backgroundInteraction}</div>}\n {mediaBadges === undefined ? null : <div className=\"hjm-card__media-badges\" data-slot=\"media-badges\">{mediaBadges}</div>}\n {media ? <div className=\"hjm-card__media\" data-slot=\"media\">{mediaAction ? <button type=\"button\" className=\"hjm-card__media-action\" aria-label={mediaAction.label} disabled={disabled} onClick={() => { if (!disabled) mediaAction.onActivate(); }}>\n {media}\n {mediaAction.icon ? <span className=\"hjm-card__media-icon\" aria-hidden=\"true\" style={{ insetInlineEnd: cardRecipe.mediaAction.inset, insetBlockEnd: cardRecipe.mediaAction.inset, width: cardRecipe.mediaAction.diameter, height: cardRecipe.mediaAction.diameter }}>{mediaAction.icon({ color: \"currentColor\", size: cardRecipe.mediaAction.iconSize })}</span> : null}\n </button> : media}</div> : null}\n <div\n className=\"hjm-card__body\"\n data-slot=\"body\"\n style={{ padding: surfaceGeometry.paddings[padding] }}\n >\n {badges === undefined || badgesPlacement !== \"body\" ? null : <div className=\"hjm-card__badges\" data-slot=\"badges\" data-align={badgesAlign}>{badges}</div>}\n {hasHeader ? (\n <div className=\"hjm-card__header\" data-slot=\"header\">\n {leading === undefined ? null : (\n <span className=\"hjm-card__leading\" data-slot=\"leading\" data-interactive={leadingAction?\"\":undefined}>\n {leadingAction?<IdentityAction action={leadingAction}>{leading}</IdentityAction>:leading}\n </span>\n )}\n <div className=\"hjm-card__copy\">\n {title === undefined\n ? null\n : createElement(\n `h${headingLevel}`,\n { className: \"hjm-card__title\", \"data-slot\": \"title\" },\n title,\n )}\n {description === undefined ? null : (\n <Text\n as=\"p\"\n tone=\"muted\"\n className=\"hjm-card__description\"\n data-slot=\"description\"\n >\n {description}\n </Text>\n )}\n </div>\n {headerActions === undefined ? null : <div className=\"hjm-card__header-actions\" data-slot=\"header-actions\">{headerActions}</div>}\n </div>\n ) : null}\n {children === undefined ? null : (\n <div className=\"hjm-card__content\" data-slot=\"content\">{children}</div>\n )}\n </div>\n {destination}\n {overlay && href === undefined ? (\n <button\n type=\"button\"\n className=\"hjm-card__activator\"\n data-slot=\"activator\"\n aria-label={activationLabel}\n aria-pressed={selected}\n disabled={disabled}\n onClick={activate}\n />\n ) : null}\n {actions ? <div className=\"hjm-card__actions\" data-slot=\"actions\">{actions}</div> : null}\n </Surface>\n );\n});\n\n/** An attributed quotation reuses Card material while keeping quotation semantics and its caption together. */\nexport type QuoteCardProps = Omit<HTMLAttributes<HTMLElement>, \"children\" | \"title\"> & Readonly<{\n children: ReactNode;\n attribution?: string;\n renderMark?: (context: { color: string; size: number }) => ReactNode;\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport function QuoteCard({ children, attribution, renderMark, ...props }: QuoteCardProps) {\n return <Card {...props} leading={<span className=\"hjm-quote-card__mark\" aria-hidden=\"true\">{renderMark?.({ color: \"currentColor\", size: cardRecipe.quotation.markSize }) ?? \"“\"}</span>}>\n <blockquote className=\"hjm-quote-card__body\">\n {children}\n {attribution === undefined ? null : <footer><Text variant=\"caption\" tone=\"muted\">{attribution}</Text></footer>}\n </blockquote>\n </Card>;\n}\n\nexport type ListRowProps = Omit<HTMLAttributes<HTMLElement>, \"title\" | \"onClick\"> &\n Readonly<{\n title: ReactNode;\n description?: ReactNode;\n leading?: ReactNode;\n /** Independent member destination; rendered beside, never inside, the row command. */\n leadingAction?: Readonly<{ label: string; onPress(): void; disabled?: boolean }>;\n trailing?: ReactNode;\n /**\n * `disclosure`: the row opens another screen. HJM draws the decorative chevron after `trailing`, inside the row\n * command (before any `trailingAction`), mirrored in RTL; size and color come from `listRowRecipe.accessories`.\n */\n trailingAccessory?: ListRowTrailingAccessory;\n /** Independent command outside the row's navigation target. */\n trailingAction?: ReactNode;\n /** Supply a framework Link without replacing the shared row layout. */\n renderLink?: (props: React.ComponentPropsWithRef<\"a\">) => ReactNode;\n density?: ListRowDensity;\n /** Semantic emphasis for destructive destinations; selection stays independent. */\n tone?: keyof typeof listRowRecipe.tones;\n /** Frame the ListRow paints around `leading`; the recipe owns its size. */\n leadingShape?: ListRowLeadingShape;\n /** Large member portraits use the shared 48px frame; icons retain the default frame. */\n leadingSize?: \"default\" | \"large\";\n selected?: boolean;\n disabled?: boolean;\n /**\n * Placeholder row while the real one loads. It keeps the row's own height\n * and slot geometry, so a list does not jump when the content arrives —\n * which is exactly what a product-owned skeleton next to the list cannot do.\n */\n loading?: boolean;\n /** Localized status text announced while `loading`. */\n loadingLabel?: string;\n href?: string;\n onClick?: MouseEventHandler<HTMLElement>;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const ListRow = forwardRef<HTMLElement, ListRowProps>(function ListRow(\n {\n title,\n description,\n leading,\n leadingAction,\n trailing,\n trailingAccessory = listRowRecipe.defaults.trailingAccessory,\n trailingAction,\n renderLink,\n density: densityProp,\n tone = listRowRecipe.defaults.tone,\n leadingShape = \"square\",\n leadingSize = leadingShape === \"circle\" ? \"large\" : \"default\",\n selected,\n disabled = false,\n loading = false,\n loadingLabel,\n href,\n onClick,\n className,\n layoutStyle,\n style,\n ...props\n },\n ref,\n) {\n // The hook runs unconditionally — `??` would short-circuit it and break the\n // rules of hooks on the very first row that passes `density`.\n const separateActions = Boolean(trailingAction || leadingAction);\n const densityDefault = useHjmDensityDefault({\n comfortable: listRowRecipe.defaults.density,\n compact: \"compact\",\n });\n const density = densityProp ?? densityDefault;\n validateListRowTrailingAccessory(trailingAccessory);\n const accessory = trailingAccessory === \"none\" ? null : listRowRecipe.accessories[trailingAccessory];\n if (loading) {\n // A loading row is never interactive: there is nothing to activate yet.\n return (\n <div\n {...props}\n ref={ref as React.Ref<HTMLDivElement>}\n role={loadingLabel ? \"status\" : undefined}\n aria-busy={loadingLabel ? true : undefined}\n aria-hidden={loadingLabel ? undefined : true}\n aria-label={loadingLabel}\n className={classNames(\"hjm-list-row\", \"hjm-list-row--loading\", className)}\n data-density={density}\n data-leading={leading ? \"\" : undefined}\n data-lines={description ? \"two\" : \"one\"}\n data-state=\"loading\"\n style={{ ...style, ...layoutStyle }}\n >\n {leading ? <span className=\"hjm-list-row__leading\" data-shape={leadingShape} data-size={leadingSize} data-placeholder=\"\" /> : null}\n <span className=\"hjm-list-row__content\">\n <span className=\"hjm-list-row__title\" data-placeholder=\"\" style={{ width: `${listRowRecipe.loading.titleWidthPercent}%` }} />\n {description ? <span className=\"hjm-list-row__description\" data-placeholder=\"\" style={{ width: `${listRowRecipe.loading.descriptionWidthPercent}%` }} /> : null}\n </span>\n {trailing ? <span className=\"hjm-list-row__trailing\" data-placeholder=\"\" style={{ width: listRowRecipe.loading.trailingWidth }} /> : null}\n {/* Keep the accessory's box so the text column does not shift when the real row arrives. */}\n {accessory ? <span className=\"hjm-list-row__accessory\" data-accessory={trailingAccessory} style={{ inlineSize: glyph[accessory.glyph], blockSize: glyph[accessory.glyph] }} /> : null}\n </div>\n );\n }\n const element = href ? \"a\" : onClick ? \"button\" : \"div\";\n const interactiveProps = href\n ? {\n href: disabled ? undefined : href,\n \"aria-current\": selected ? (\"page\" as const) : undefined,\n \"aria-disabled\": disabled || undefined,\n tabIndex: disabled ? -1 : undefined,\n }\n : onClick\n ? {\n type: \"button\" as const,\n onClick: disabled ? undefined : onClick,\n disabled,\n \"aria-pressed\": selected,\n }\n : {};\n\n const row = createElement(\n element,\n {\n ...props,\n ...interactiveProps,\n ref,\n className: classNames(\"hjm-list-row\", className),\n \"data-density\": density,\n // Exposes the text column to the enclosing List: its indented separator starts after the leading frame\n // (listRecipe.separators.indented.leadingInsetStart) only when this row has one.\n \"data-leading\": leading ? \"\" : undefined,\n \"data-tone\": tone,\n // One- and two-line rows have different minimum heights in the recipe;\n // the web renderer used a single hardcoded value until now.\n \"data-lines\": description ? \"two\" : \"one\",\n \"data-state\": disabled ? \"disabled\" : selected ? \"selected\" : \"idle\",\n // Placement wins over the legacy `style`, matching Surface's ordering.\n // With trailingAction the frame is the placed root, as Native's outer View.\n style: separateActions ? style : { ...style, ...layoutStyle },\n },\n leading && !leadingAction\n ? <span className=\"hjm-list-row__leading\" data-shape={leadingShape} data-size={leadingSize}>{leading}</span>\n : null,\n <span className=\"hjm-list-row__content\">\n <span className=\"hjm-list-row__title\">{title}</span>\n {description ? (\n <span className=\"hjm-list-row__description\">{description}</span>\n ) : null}\n </span>,\n trailing ? <span className=\"hjm-list-row__trailing\">{trailing}</span> : null,\n accessory\n ? <span className=\"hjm-list-row__accessory\" data-accessory={trailingAccessory} aria-hidden=\"true\">\n <Icon name={accessory.icon} size={accessory.glyph} weight={accessory.weight} />\n </span>\n : null,\n );\n const linked = href && renderLink ? renderLink(row.props as React.ComponentPropsWithRef<\"a\">) : row;\n // The frame owns the row surface and its bleed so the command and the separate action share one fill, as Native;\n // the action stays outside the link/button (styles.css `.hjm-list-row-frame`).\n return separateActions ? (\n <div className=\"hjm-list-row-frame\" data-leading-action={leadingAction ? \"\" : undefined} data-trailing-action={trailingAction ? \"\" : undefined} data-density={density} data-leading={leading ? \"\" : undefined}\n data-state={disabled ? \"disabled\" : selected ? \"selected\" : \"idle\"} style={layoutStyle}>\n {leadingAction && leading ? <div className=\"hjm-list-row__profile\"><IdentityAction action={leadingAction}>{leading}</IdentityAction></div> : null}\n {linked}\n {trailingAction ? <div className=\"hjm-list-row__action\">{trailingAction}</div> : null}\n </div>\n ) : linked;\n});\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type DrawingEditorProps } from '@hjmds/design-contracts/components/drawing-editor';
|
|
2
|
+
export type { DrawingEditorProps, DrawingEditorLabels, DrawingImage } from '@hjmds/design-contracts/components/drawing-editor';
|
|
3
|
+
/** Shared paint editor extracted from Diairy and Spint (2026-10-27).
|
|
4
|
+
* Tools, history, crop preview and failed-save draft preservation have one owner per renderer.
|
|
5
|
+
* The product supplies localized labels, upload and navigation; SVG/lucide stay optional entry peers. */
|
|
6
|
+
export declare function DrawingEditor({ labels, onSave, onCancel, cropPreview, testID }: DrawingEditorProps): import("react").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=drawing-editor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drawing-editor.d.ts","sourceRoot":"","sources":["../src/drawing-editor.tsx"],"names":[],"mappings":"AAWA,OAAO,EAE4E,KAAK,kBAAkB,EACzG,MAAM,mDAAmD,CAAC;AAC3D,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,mDAAmD,CAAC;AAK/H;;yGAEyG;AACzG,wBAAgB,aAAa,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAoB,EAAE,MAAyB,EAAE,EAAE,kBAAkB,+BA4H9H"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useReducer, useRef, useState } from 'react';
|
|
4
|
+
import { PaintBucket, Redo2, Palette, Trash2, Undo2 } from 'lucide-react';
|
|
5
|
+
import { EditorScreen } from './screen-flows.js';
|
|
6
|
+
import { Stack } from './layout.js';
|
|
7
|
+
import { SegmentedControl } from './selection.js';
|
|
8
|
+
import { ColorPicker, ColorSwatchPicker } from './color-picker.js';
|
|
9
|
+
import { Slider } from './slider.js';
|
|
10
|
+
import { Sheet } from './overlays.js';
|
|
11
|
+
import { Notice } from './feedback.js';
|
|
12
|
+
import { IconButton } from './actions.js';
|
|
13
|
+
import { DRAWING_BACKGROUND_COLORS, DRAWING_INK_COLORS, DRAWING_PAPER, drawingInkPath, drawingReducer, emptyDrawing, drawingHasContent, drawingQuickColors, drawingStrokeColor, drawingEditorRecipe, } from '@hjmds/design-contracts/components/drawing-editor';
|
|
14
|
+
/** How long the brush-size circle stays on the canvas after the size slider is released. */
|
|
15
|
+
const SIZE_PREVIEW_MS = drawingEditorRecipe.sizePreviewMs;
|
|
16
|
+
/** Shared paint editor extracted from Diairy and Spint (2026-10-27).
|
|
17
|
+
* Tools, history, crop preview and failed-save draft preservation have one owner per renderer.
|
|
18
|
+
* The product supplies localized labels, upload and navigation; SVG/lucide stay optional entry peers. */
|
|
19
|
+
export function DrawingEditor({ labels, onSave, onCancel, cropPreview = 'none', testID = 'drawing-editor' }) {
|
|
20
|
+
const [history, dispatch] = useReducer(drawingReducer, emptyDrawing);
|
|
21
|
+
const [draft, setDraft] = useState(null);
|
|
22
|
+
const strokes = draft ? [...history.present, draft] : history.present;
|
|
23
|
+
const [brushWidth, setBrushWidth] = useState(drawingEditorRecipe.brush.initial);
|
|
24
|
+
const [colorOpen, setColorOpen] = useState(false);
|
|
25
|
+
const [color, setColor] = useState(DRAWING_INK_COLORS[0]);
|
|
26
|
+
const [background, setBackground] = useState(DRAWING_PAPER);
|
|
27
|
+
const [backgroundOpen, setBackgroundOpen] = useState(false);
|
|
28
|
+
const [sizePreview, setSizePreview] = useState(false);
|
|
29
|
+
const [pointer, setPointer] = useState(null);
|
|
30
|
+
const sizeTimer = useRef(null);
|
|
31
|
+
useEffect(() => () => { if (sizeTimer.current)
|
|
32
|
+
clearTimeout(sizeTimer.current); }, []);
|
|
33
|
+
const [recent, setRecent] = useState([]);
|
|
34
|
+
const [tool, setTool] = useState('pen');
|
|
35
|
+
const saving = useRef(false);
|
|
36
|
+
const [busy, setBusy] = useState(false);
|
|
37
|
+
const [failed, setFailed] = useState(false);
|
|
38
|
+
const active = useRef(null);
|
|
39
|
+
const svg = useRef(null);
|
|
40
|
+
const hasInk = drawingHasContent(strokes, background);
|
|
41
|
+
// Pen and eraser share the slider value: the size shown is the size drawn (2026-10-25; a hidden 2× eraser confused people).
|
|
42
|
+
const strokeWidth = brushWidth;
|
|
43
|
+
const quickColors = drawingQuickColors(recent);
|
|
44
|
+
const point = (event) => {
|
|
45
|
+
const rect = event.currentTarget.getBoundingClientRect();
|
|
46
|
+
return [Math.max(0, Math.min(256, (event.clientX - rect.left) / rect.width * 256)), Math.max(0, Math.min(256, (event.clientY - rect.top) / rect.height * 256))];
|
|
47
|
+
};
|
|
48
|
+
const finishStroke = (event) => {
|
|
49
|
+
if (!active.current || active.current.pointer !== event.pointerId)
|
|
50
|
+
return;
|
|
51
|
+
dispatch({ type: 'add', stroke: active.current.stroke });
|
|
52
|
+
active.current = null;
|
|
53
|
+
setDraft(null);
|
|
54
|
+
};
|
|
55
|
+
const pickColor = (next) => { setColor(next); setTool('pen'); };
|
|
56
|
+
const closeColors = (open) => {
|
|
57
|
+
setColorOpen(open);
|
|
58
|
+
if (!open)
|
|
59
|
+
setRecent(previous => previous.includes(color) || quickColors.includes(color) ? previous : [color, ...previous].slice(0, 4));
|
|
60
|
+
};
|
|
61
|
+
const paths = strokes.map((stroke, index) => _jsx("path", { d: drawingInkPath(stroke), stroke: drawingStrokeColor(stroke, background), strokeWidth: stroke.width, strokeLinecap: "round", strokeLinejoin: "round", fill: "none" }, index));
|
|
62
|
+
const store = async () => {
|
|
63
|
+
if (saving.current || busy || draft || !svg.current || !hasInk)
|
|
64
|
+
return;
|
|
65
|
+
saving.current = true;
|
|
66
|
+
setBusy(true);
|
|
67
|
+
setFailed(false);
|
|
68
|
+
try {
|
|
69
|
+
const markup = new XMLSerializer().serializeToString(svg.current);
|
|
70
|
+
const url = URL.createObjectURL(new Blob([markup], { type: 'image/svg+xml' }));
|
|
71
|
+
let photo;
|
|
72
|
+
try {
|
|
73
|
+
const image = new Image();
|
|
74
|
+
await new Promise((resolve, reject) => { image.onload = () => resolve(); image.onerror = () => reject(new Error('drawing_decode')); image.src = url; });
|
|
75
|
+
const canvas = document.createElement('canvas');
|
|
76
|
+
canvas.width = canvas.height = 512;
|
|
77
|
+
const context = canvas.getContext('2d');
|
|
78
|
+
if (!context)
|
|
79
|
+
throw new Error('drawing_canvas');
|
|
80
|
+
context.drawImage(image, 0, 0, 512, 512);
|
|
81
|
+
photo = canvas.toDataURL('image/jpeg', 0.9).split(',')[1];
|
|
82
|
+
}
|
|
83
|
+
finally {
|
|
84
|
+
URL.revokeObjectURL(url);
|
|
85
|
+
}
|
|
86
|
+
await onSave({ base64: photo, mimeType: 'image/jpeg' });
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
setFailed(true);
|
|
90
|
+
}
|
|
91
|
+
finally {
|
|
92
|
+
saving.current = false;
|
|
93
|
+
setBusy(false);
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
const showSize = (width) => { setBrushWidth(width); setSizePreview(true); if (sizeTimer.current)
|
|
97
|
+
clearTimeout(sizeTimer.current); };
|
|
98
|
+
const hideSize = () => { if (sizeTimer.current)
|
|
99
|
+
clearTimeout(sizeTimer.current); sizeTimer.current = setTimeout(() => setSizePreview(false), SIZE_PREVIEW_MS); };
|
|
100
|
+
return _jsxs(EditorScreen, { as: "section", title: labels.title, initialFocus: "none", dirty: hasInk, submit: { label: labels.save, disabled: !hasInk || !!draft, pending: busy, onAction: () => void store() }, cancel: { label: labels.close, disabled: busy, onAction: onCancel }, discard: { mode: 'confirm', title: labels.discardTitle, description: labels.discardBody, confirmLabel: labels.discardConfirm,
|
|
101
|
+
cancelLabel: labels.cancel, fallbackErrorMessage: labels.failed }, notice: failed ? _jsx(Notice, { tone: "danger", title: labels.failed }) : undefined, children: [_jsxs(Stack, { gap: "md", layoutStyle: { width: '100%', maxWidth: drawingEditorRecipe.maxCanvas, alignSelf: 'center' }, children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between' }, children: [_jsxs("div", { style: { display: 'flex' }, children: [_jsx(IconButton, { label: labels.undo, tone: "ghost", disabled: busy || !!draft || !history.past.length, onClick: () => dispatch({ type: 'undo' }), children: _jsx(Undo2, { "aria-hidden": true, size: 20 }) }), _jsx(IconButton, { label: labels.redo, tone: "ghost", disabled: busy || !!draft || !history.future.length, onClick: () => dispatch({ type: 'redo' }), children: _jsx(Redo2, { "aria-hidden": true, size: 20 }) })] }), _jsxs("div", { style: { display: 'flex' }, children: [_jsx(IconButton, { label: labels.background, tone: "ghost", disabled: busy || !!draft, onClick: () => setBackgroundOpen(true), children: _jsx(PaintBucket, { "aria-hidden": true, size: 20 }) }), _jsx(IconButton, { label: labels.clear, tone: "ghost", disabled: busy || !!draft || !strokes.length, onClick: () => dispatch({ type: 'clear' }), children: _jsx(Trash2, { "aria-hidden": true, size: 20 }) })] })] }), _jsxs("div", { style: { position: 'relative', width: '100%', aspectRatio: '1', borderRadius: drawingEditorRecipe.radius, overflow: 'hidden', border: '1px solid var(--hjm-color-border)' }, children: [_jsxs("svg", { ref: svg, xmlns: "http://www.w3.org/2000/svg", width: "512", height: "512", viewBox: "0 0 256 256", role: "img", "aria-label": labels.title, "data-testid": `${testID}-canvas`,
|
|
102
|
+
// touch-action none keeps a stroke from scrolling the page; the pointer capture keeps it on the canvas.
|
|
103
|
+
style: { display: 'block', width: '100%', height: '100%', touchAction: 'none', cursor: 'crosshair' }, onPointerDown: event => {
|
|
104
|
+
if (busy || active.current || event.button !== 0)
|
|
105
|
+
return;
|
|
106
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
107
|
+
const points = [point(event)];
|
|
108
|
+
const stroke = tool === 'eraser' ? { erase: true, width: strokeWidth, points } : { color, width: strokeWidth, points };
|
|
109
|
+
active.current = { pointer: event.pointerId, stroke };
|
|
110
|
+
setDraft(stroke);
|
|
111
|
+
}, onPointerMove: event => {
|
|
112
|
+
// The size ring follows a hovering mouse or pen as well as an active stroke.
|
|
113
|
+
setPointer(point(event));
|
|
114
|
+
if (!active.current || active.current.pointer !== event.pointerId)
|
|
115
|
+
return;
|
|
116
|
+
const stroke = { ...active.current.stroke, points: [...active.current.stroke.points, point(event)] };
|
|
117
|
+
active.current = { pointer: event.pointerId, stroke };
|
|
118
|
+
setDraft(stroke);
|
|
119
|
+
}, onPointerUp: finishStroke, onPointerCancel: finishStroke, onPointerLeave: () => setPointer(null), children: [_jsx("rect", { width: "256", height: "256", fill: background }), paths] }), _jsxs("svg", { "aria-hidden": true, viewBox: "0 0 256 256", style: { position: 'absolute', inset: 0, width: '100%', height: '100%', pointerEvents: 'none' }, children: [cropPreview === 'circle' ? _jsxs(_Fragment, { children: [_jsx("path", { d: "M0 0H256V256H0Z M128 0A128 128 0 1 0 128 256A128 128 0 1 0 128 0Z", fillRule: "evenodd", style: { fill: 'var(--hjm-color-text)', fillOpacity: 0.06 } }), _jsx("circle", { cx: "128", cy: "128", r: "127", fill: "none", strokeWidth: "1", strokeDasharray: "4 4", style: { stroke: 'var(--hjm-color-text-muted)', strokeOpacity: 0.5 } })] }) : null, sizePreview && !draft ? _jsx("circle", { "data-testid": `${testID}-size`, cx: "128", cy: "128", r: strokeWidth / 2, fill: tool === 'eraser' ? background : color, strokeWidth: "0.5", style: { stroke: 'var(--hjm-color-text)', strokeOpacity: 0.4 } }) : null, pointer && !busy ? _jsx("circle", { cx: pointer[0], cy: pointer[1], r: strokeWidth / 2 + 1, fill: "none", strokeWidth: "0.5", style: { stroke: 'var(--hjm-color-text)', strokeOpacity: 0.5 } }) : null] })] }), _jsx(SegmentedControl, { value: tool, onValueChange: setTool, disabled: busy, label: labels.pen, items: [{ value: 'pen', label: labels.pen }, { value: 'eraser', label: labels.eraser }] }), _jsx(Slider, { label: labels.width, min: drawingEditorRecipe.brush.min, max: drawingEditorRecipe.brush.max, step: drawingEditorRecipe.brush.step, value: brushWidth, onValueChange: showSize, onValueChangeEnd: hideSize, disabled: busy }), _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 4 }, children: [_jsx(ColorSwatchPicker, { label: labels.penColor, labelVisibility: "hidden", layout: "scroll", layoutStyle: { flex: 1, minWidth: 0 }, colors: quickColors, value: tool === 'pen' && quickColors.includes(color) ? color : null, onValueChange: pickColor, disabled: busy }), _jsx(IconButton, { label: labels.moreColors, tone: "secondary", disabled: busy, onClick: () => setColorOpen(true), children: _jsx(Palette, { "aria-hidden": true, size: 20 }) })] })] }), _jsx(Sheet, { open: colorOpen, onOpenChange: closeColors, title: labels.moreColors, closeLabel: labels.close, children: _jsx(ColorPicker, { label: labels.penColor, value: color, onValueChange: pickColor, disabled: busy, labels: { hex: labels.hex, hue: labels.hue, saturation: labels.saturation, brightness: labels.brightness,
|
|
120
|
+
opacity: labels.opacity, invalid: labels.invalidColor } }) }), _jsx(Sheet, { open: backgroundOpen, onOpenChange: setBackgroundOpen, title: labels.background, closeLabel: labels.close, children: _jsx(ColorPicker, { label: labels.background, value: background, onValueChange: setBackground, disabled: busy, presets: DRAWING_BACKGROUND_COLORS, labels: { hex: labels.hex, hue: labels.hue, saturation: labels.saturation, brightness: labels.brightness,
|
|
121
|
+
opacity: labels.opacity, invalid: labels.invalidColor, presets: labels.backgroundPresets } }) })] });
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=drawing-editor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drawing-editor.js","sourceRoot":"","sources":["../src/drawing-editor.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\nimport { useEffect, useReducer, useRef, useState, type PointerEvent } from 'react';\nimport { PaintBucket, Redo2, Palette, Trash2, Undo2 } from 'lucide-react';\nimport { EditorScreen } from './screen-flows.js';\nimport { Stack } from './layout.js';\nimport { SegmentedControl } from './selection.js';\nimport { ColorPicker, ColorSwatchPicker } from './color-picker.js';\nimport { Slider } from './slider.js';\nimport { Sheet } from './overlays.js';\nimport { Notice } from './feedback.js';\nimport { IconButton } from './actions.js';\nimport {\n DRAWING_BACKGROUND_COLORS, DRAWING_INK_COLORS, DRAWING_PAPER, drawingInkPath, drawingReducer, emptyDrawing, drawingHasContent,\n drawingQuickColors, drawingStrokeColor, drawingEditorRecipe, type DrawingStroke, type DrawingEditorProps,\n} from '@hjmds/design-contracts/components/drawing-editor';\nexport type { DrawingEditorProps, DrawingEditorLabels, DrawingImage } from '@hjmds/design-contracts/components/drawing-editor';\n\n/** How long the brush-size circle stays on the canvas after the size slider is released. */\nconst SIZE_PREVIEW_MS = drawingEditorRecipe.sizePreviewMs;\n\n/** Shared paint editor extracted from Diairy and Spint (2026-10-27).\n * Tools, history, crop preview and failed-save draft preservation have one owner per renderer.\n * The product supplies localized labels, upload and navigation; SVG/lucide stay optional entry peers. */\nexport function DrawingEditor({ labels, onSave, onCancel, cropPreview = 'none', testID = 'drawing-editor' }: DrawingEditorProps) {\n const [history, dispatch] = useReducer(drawingReducer, emptyDrawing);\n const [draft, setDraft] = useState<DrawingStroke | null>(null);\n const strokes = draft ? [...history.present, draft] : history.present;\n const [brushWidth, setBrushWidth] = useState<number>(drawingEditorRecipe.brush.initial);\n const [colorOpen, setColorOpen] = useState(false);\n const [color, setColor] = useState<string>(DRAWING_INK_COLORS[0]);\n const [background, setBackground] = useState<string>(DRAWING_PAPER);\n const [backgroundOpen, setBackgroundOpen] = useState(false);\n const [sizePreview, setSizePreview] = useState(false);\n const [pointer, setPointer] = useState<[number, number] | null>(null);\n const sizeTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n useEffect(() => () => { if (sizeTimer.current) clearTimeout(sizeTimer.current); }, []);\n const [recent, setRecent] = useState<readonly string[]>([]);\n const [tool, setTool] = useState('pen');\n const saving = useRef(false);\n const [busy, setBusy] = useState(false);\n const [failed, setFailed] = useState(false);\n const active = useRef<{ pointer: number; stroke: DrawingStroke } | null>(null);\n const svg = useRef<SVGSVGElement>(null);\n const hasInk = drawingHasContent(strokes, background);\n // Pen and eraser share the slider value: the size shown is the size drawn (2026-10-25; a hidden 2× eraser confused people).\n const strokeWidth = brushWidth;\n const quickColors = drawingQuickColors(recent);\n const point = (event: PointerEvent<SVGSVGElement>): [number, number] => {\n const rect = event.currentTarget.getBoundingClientRect();\n return [Math.max(0, Math.min(256, (event.clientX - rect.left) / rect.width * 256)), Math.max(0, Math.min(256, (event.clientY - rect.top) / rect.height * 256))];\n };\n const finishStroke = (event: PointerEvent<SVGSVGElement>) => {\n if (!active.current || active.current.pointer !== event.pointerId) return;\n dispatch({ type: 'add', stroke: active.current.stroke }); active.current = null; setDraft(null);\n };\n const pickColor = (next: string) => { setColor(next); setTool('pen'); };\n const closeColors = (open: boolean) => {\n setColorOpen(open);\n if (!open) setRecent(previous => previous.includes(color) || quickColors.includes(color) ? previous : [color, ...previous].slice(0, 4));\n };\n const paths = strokes.map((stroke, index) => <path key={index} d={drawingInkPath(stroke)} stroke={drawingStrokeColor(stroke, background)} strokeWidth={stroke.width} strokeLinecap=\"round\" strokeLinejoin=\"round\" fill=\"none\" />);\n const store = async () => {\n if (saving.current || busy || draft || !svg.current || !hasInk) return;\n saving.current = true; setBusy(true); setFailed(false);\n try {\n const markup = new XMLSerializer().serializeToString(svg.current);\n const url = URL.createObjectURL(new Blob([markup], { type: 'image/svg+xml' }));\n let photo: string;\n try {\n const image = new Image();\n await new Promise<void>((resolve, reject) => { image.onload = () => resolve(); image.onerror = () => reject(new Error('drawing_decode')); image.src = url; });\n const canvas = document.createElement('canvas'); canvas.width = canvas.height = 512;\n const context = canvas.getContext('2d'); if (!context) throw new Error('drawing_canvas');\n context.drawImage(image, 0, 0, 512, 512); photo = canvas.toDataURL('image/jpeg', 0.9).split(',')[1]!;\n } finally { URL.revokeObjectURL(url); }\n await onSave({ base64: photo, mimeType: 'image/jpeg' });\n } catch { setFailed(true); } finally { saving.current = false; setBusy(false); }\n };\n const showSize = (width: number) => { setBrushWidth(width); setSizePreview(true); if (sizeTimer.current) clearTimeout(sizeTimer.current); };\n const hideSize = () => { if (sizeTimer.current) clearTimeout(sizeTimer.current); sizeTimer.current = setTimeout(() => setSizePreview(false), SIZE_PREVIEW_MS); };\n\n return <EditorScreen as=\"section\" title={labels.title} initialFocus=\"none\" dirty={hasInk}\n submit={{ label: labels.save, disabled: !hasInk || !!draft, pending: busy, onAction: () => void store() }}\n cancel={{ label: labels.close, disabled: busy, onAction: onCancel }}\n discard={{ mode: 'confirm', title: labels.discardTitle, description: labels.discardBody, confirmLabel: labels.discardConfirm,\n cancelLabel: labels.cancel, fallbackErrorMessage: labels.failed }}\n notice={failed ? <Notice tone=\"danger\" title={labels.failed} /> : undefined}>\n <Stack gap=\"md\" layoutStyle={{ width: '100%', maxWidth: drawingEditorRecipe.maxCanvas, alignSelf: 'center' }}>\n <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>\n <div style={{ display: 'flex' }}>\n <IconButton label={labels.undo} tone=\"ghost\" disabled={busy || !!draft || !history.past.length} onClick={() => dispatch({ type: 'undo' })}><Undo2 aria-hidden size={20} /></IconButton>\n <IconButton label={labels.redo} tone=\"ghost\" disabled={busy || !!draft || !history.future.length} onClick={() => dispatch({ type: 'redo' })}><Redo2 aria-hidden size={20} /></IconButton>\n </div>\n <div style={{ display: 'flex' }}>\n <IconButton label={labels.background} tone=\"ghost\" disabled={busy || !!draft} onClick={() => setBackgroundOpen(true)}><PaintBucket aria-hidden size={20} /></IconButton>\n <IconButton label={labels.clear} tone=\"ghost\" disabled={busy || !!draft || !strokes.length} onClick={() => dispatch({ type: 'clear' })}><Trash2 aria-hidden size={20} /></IconButton>\n </div>\n </div>\n <div style={{ position: 'relative', width: '100%', aspectRatio: '1', borderRadius: drawingEditorRecipe.radius, overflow: 'hidden', border: '1px solid var(--hjm-color-border)' }}>\n <svg ref={svg} xmlns=\"http://www.w3.org/2000/svg\" width=\"512\" height=\"512\" viewBox=\"0 0 256 256\"\n role=\"img\" aria-label={labels.title} data-testid={`${testID}-canvas`}\n // touch-action none keeps a stroke from scrolling the page; the pointer capture keeps it on the canvas.\n style={{ display: 'block', width: '100%', height: '100%', touchAction: 'none', cursor: 'crosshair' }}\n onPointerDown={event => {\n if (busy || active.current || event.button !== 0) return;\n event.currentTarget.setPointerCapture(event.pointerId);\n const points: [number, number][] = [point(event)];\n const stroke: DrawingStroke = tool === 'eraser' ? { erase: true, width: strokeWidth, points } : { color, width: strokeWidth, points };\n active.current = { pointer: event.pointerId, stroke }; setDraft(stroke);\n }}\n onPointerMove={event => {\n // The size ring follows a hovering mouse or pen as well as an active stroke.\n setPointer(point(event));\n if (!active.current || active.current.pointer !== event.pointerId) return;\n const stroke = { ...active.current.stroke, points: [...active.current.stroke.points, point(event)] };\n active.current = { pointer: event.pointerId, stroke }; setDraft(stroke);\n }} onPointerUp={finishStroke} onPointerCancel={finishStroke} onPointerLeave={() => setPointer(null)}>\n <rect width=\"256\" height=\"256\" fill={background} />{paths}\n </svg>\n {/* The saved photo is shown as a circle; shade the corners it will lose. Not part of the exported image. */}\n <svg aria-hidden viewBox=\"0 0 256 256\" style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', pointerEvents: 'none' }}>\n {cropPreview === 'circle' ? <><path d=\"M0 0H256V256H0Z M128 0A128 128 0 1 0 128 256A128 128 0 1 0 128 0Z\" fillRule=\"evenodd\" style={{ fill: 'var(--hjm-color-text)', fillOpacity: 0.06 }} />\n <circle cx=\"128\" cy=\"128\" r=\"127\" fill=\"none\" strokeWidth=\"1\" strokeDasharray=\"4 4\" style={{ stroke: 'var(--hjm-color-text-muted)', strokeOpacity: 0.5 }} /></> : null}\n {sizePreview && !draft ? <circle data-testid={`${testID}-size`} cx=\"128\" cy=\"128\" r={strokeWidth / 2} fill={tool === 'eraser' ? background : color} strokeWidth=\"0.5\" style={{ stroke: 'var(--hjm-color-text)', strokeOpacity: 0.4 }} /> : null}\n {pointer && !busy ? <circle cx={pointer[0]} cy={pointer[1]} r={strokeWidth / 2 + 1} fill=\"none\" strokeWidth=\"0.5\" style={{ stroke: 'var(--hjm-color-text)', strokeOpacity: 0.5 }} /> : null}\n </svg>\n </div>\n <SegmentedControl value={tool} onValueChange={setTool} disabled={busy} label={labels.pen}\n items={[{ value: 'pen', label: labels.pen }, { value: 'eraser', label: labels.eraser }]} />\n <Slider label={labels.width} min={drawingEditorRecipe.brush.min} max={drawingEditorRecipe.brush.max} step={drawingEditorRecipe.brush.step} value={brushWidth} onValueChange={showSize} onValueChangeEnd={hideSize} disabled={busy} />\n <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>\n <ColorSwatchPicker label={labels.penColor} labelVisibility=\"hidden\" layout=\"scroll\" layoutStyle={{ flex: 1, minWidth: 0 }}\n colors={quickColors} value={tool === 'pen' && quickColors.includes(color) ? color : null} onValueChange={pickColor} disabled={busy} />\n <IconButton label={labels.moreColors} tone=\"secondary\" disabled={busy} onClick={() => setColorOpen(true)}><Palette aria-hidden size={20} /></IconButton>\n </div>\n </Stack>\n <Sheet open={colorOpen} onOpenChange={closeColors} title={labels.moreColors} closeLabel={labels.close}>\n <ColorPicker label={labels.penColor} value={color} onValueChange={pickColor} disabled={busy}\n labels={{ hex: labels.hex, hue: labels.hue, saturation: labels.saturation, brightness: labels.brightness,\n opacity: labels.opacity, invalid: labels.invalidColor }} />\n </Sheet>\n <Sheet open={backgroundOpen} onOpenChange={setBackgroundOpen} title={labels.background} closeLabel={labels.close}>\n <ColorPicker label={labels.background} value={background} onValueChange={setBackground} disabled={busy} presets={DRAWING_BACKGROUND_COLORS}\n labels={{ hex: labels.hex, hue: labels.hue, saturation: labels.saturation, brightness: labels.brightness,\n opacity: labels.opacity, invalid: labels.invalidColor, presets: labels.backgroundPresets }} />\n </Sheet>\n </EditorScreen>;\n}\n"]}
|
package/dist/evidence.d.ts
CHANGED
|
@@ -34,7 +34,7 @@ export type ReactRendererEvidenceManifest = Readonly<{
|
|
|
34
34
|
export declare const reactRendererEvidence: {
|
|
35
35
|
readonly schemaVersion: 2;
|
|
36
36
|
readonly packageName: "@hjmds/react";
|
|
37
|
-
readonly packageVersion: "1.
|
|
37
|
+
readonly packageVersion: "1.50.0";
|
|
38
38
|
readonly surface: "web";
|
|
39
39
|
readonly components: Readonly<{
|
|
40
40
|
/** Canonical component id from the design-contracts catalog. */
|
package/dist/evidence.js
CHANGED
|
@@ -135,7 +135,7 @@ const activeWebEntries = componentCatalog.filter((entry) => {
|
|
|
135
135
|
export const reactRendererEvidence = {
|
|
136
136
|
schemaVersion: reactRendererEvidenceSchemaVersion,
|
|
137
137
|
packageName: "@hjmds/react",
|
|
138
|
-
packageVersion: "1.
|
|
138
|
+
packageVersion: "1.50.0",
|
|
139
139
|
surface: "web",
|
|
140
140
|
components: activeWebEntries.map(derivedClaim),
|
|
141
141
|
};
|
package/dist/evidence.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evidence.js","sourceRoot":"","sources":["../src/evidence.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ShowcaseScenarioId } from \"@hjmds/design-contracts/showcase\";\nimport { getRequiredShowcaseEvidence } from \"@hjmds/design-contracts/showcase\";\nimport { componentCatalog, componentIdOf, getComponentSurfaceStatus, type ComponentCatalogEntry } from \"@hjmds/design-contracts/catalog\";\nimport { publicExportEntries } from \"./public-exports.generated.js\";\n\nexport const reactRendererEvidenceSchemaVersion = 2 as const;\n\nexport type ReactRendererEvidenceScenario = Exclude<ShowcaseScenarioId, \"contract\" | \"native-actions\">;\n\nexport type ReactRendererEvidenceComponent = Readonly<{\n /** Canonical component id from the design-contracts catalog. */\n componentId: string;\n /** Public symbols that implement this contract on the declared subpath. */\n exportNames: readonly string[];\n /** Granular @hjmds/react export used by consumers. */\n subpath: `./${string}`;\n /** Scenarios supported by automated first-party renderer evidence. */\n scenarios: readonly ReactRendererEvidenceScenario[];\n /** Repository-local executable proof for every claimed scenario. */\n proofs: readonly Readonly<{\n scenarios: readonly ReactRendererEvidenceScenario[];\n file: `test/${string}.test.tsx`;\n caseId: string;\n }>[];\n}>;\n\nexport type ReactRendererEvidenceManifest = Readonly<{\n schemaVersion: typeof reactRendererEvidenceSchemaVersion;\n packageName: \"@hjmds/react\";\n packageVersion: string;\n surface: \"web\";\n components: readonly ReactRendererEvidenceComponent[];\n}>;\n\nconst defaultProofFile = \"test/default-render.ssr.test.tsx\" as const;\nconst matrixProofFile = \"test/scenario-matrix.browser.test.tsx\" as const;\nconst stableCoreProofFile = \"test/stable-core.browser.test.tsx\" as const;\n\ntype ProofFile = `test/${string}.test.tsx`;\n\n/**\n * Scenarios a component does not pass yet. Each entry is promotion debt that\n * the generated evidence projection reports; remove it when the component is\n * fixed and the matrix case passes. Stable surfaces cannot carry a gap\n * (scripts/check-workspace-sync.mjs).\n */\nconst webScenarioGaps: Readonly<Record<string, readonly ReactRendererEvidenceScenario[]>> = {};\n\n/**\n * Proofs that live outside the shared default/matrix files: keyboard behavior in a dedicated browser test,\n * long copy proven inside a portal by the component's own test, or a whole matrix run in a component file.\n * Everything else about a claim derives from the catalog row (2026-10-18 registration input).\n */\ntype ClaimExtras = Readonly<{\n /** Extra proofs; their scenarios are removed from the shared matrix proof. */\n proofs?: readonly Readonly<{ scenarios: readonly ReactRendererEvidenceScenario[]; file: ProofFile }>[];\n /** Hooks or helpers published beside the component symbols on the same subpath. */\n exportNames?: readonly string[];\n}>;\n\nconst keyboard = (file: ProofFile = stableCoreProofFile): ClaimExtras => ({ proofs: [{ scenarios: [\"keyboard\"], file }] });\nconst keyboardAndLongCopy = (file: ProofFile): ClaimExtras => ({ proofs: [{ scenarios: [\"keyboard\", \"long-copy\"], file }] });\n\nconst claimExtras: Readonly<Record<string, ClaimExtras>> = {\n \"time-picker\": keyboard(\"test/time-picker.browser.test.tsx\"),\n \"design-system-provider\": { exportNames: [\"useHjmTheme\"] },\n layout: keyboard(),\n link: keyboard(),\n field: keyboard(),\n \"search-field\": keyboard(),\n \"password-field\": keyboard(),\n \"otp-field\": keyboard(),\n \"number-field\": keyboard(),\n slider: keyboard(),\n form: keyboard(\"test/form.keyboard.browser.test.tsx\"),\n \"date-picker\": keyboard(),\n calendar: keyboard(\"test/calendar.browser.test.tsx\"),\n \"file-picker\": keyboard(\"test/file-picker.keyboard.browser.test.tsx\"),\n checkbox: keyboard(),\n \"checkbox-group\": keyboard(),\n \"radio-group\": keyboard(),\n switch: keyboard(),\n \"segmented-control\": keyboard(),\n chip: keyboard(),\n tabs: keyboard(\"test/tabs.keyboard.browser.test.tsx\"),\n breadcrumb: keyboard(\"test/page-navigation.browser.test.tsx\"),\n pagination: keyboard(\"test/pagination.keyboard.browser.test.tsx\"),\n popover: keyboardAndLongCopy(\"test/popover.browser.test.tsx\"),\n \"side-panel\": keyboardAndLongCopy(\"test/side-panel.browser.test.tsx\"),\n splitter: keyboard(\"test/splitter.browser.test.tsx\"),\n tour: keyboardAndLongCopy(\"test/tour.browser.test.tsx\"),\n tree: keyboard(\"test/tree.browser.test.tsx\"),\n \"transfer-list\": keyboard(\"test/transfer-list.browser.test.tsx\"),\n mentions: keyboard(\"test/mentions.browser.test.tsx\"),\n \"command-palette\": keyboardAndLongCopy(\"test/command-palette.browser.test.tsx\"),\n agreement: keyboard(\"test/agreement.keyboard.browser.test.tsx\"),\n \"toggle-group\": keyboard(),\n \"tags-input\": keyboard(),\n \"skip-nav\": keyboardAndLongCopy(\"test/skip-nav.browser.test.tsx\"),\n sidebar: keyboard(\"test/sidebar.browser.test.tsx\"),\n \"date-range-picker\": keyboard(\"test/date-range.keyboard.browser.test.tsx\"),\n \"auth-provider-button\": keyboard(),\n \"data-table\": keyboard(\"test/data-table.keyboard.browser.test.tsx\"),\n collapsible: keyboard(\"test/collapsible.keyboard.browser.test.tsx\"),\n \"context-menu\": keyboardAndLongCopy(\"test/context-menu.interactions.browser.test.tsx\"),\n menubar: keyboard(\"test/menubar.keyboard.browser.test.tsx\"),\n anchor: keyboard(\"test/anchor.browser.test.tsx\"),\n \"bottom-navigation\": keyboard(\"test/bottom-navigation.keyboard.browser.test.tsx\"),\n \"load-more\": keyboard(\"test/load-more.interactions.browser.test.tsx\"),\n carousel: keyboard(\"test/carousel.browser.test.tsx\"),\n \"floating-action-button\": keyboard(),\n accordion: keyboard(\"test/accordion.keyboard.browser.test.tsx\"),\n \"upload-item\": keyboard(\"test/upload-item.browser.test.tsx\"),\n // ThinkingOrb runs its whole environment matrix in its own file (canvas timing), not in scenario-matrix.\n \"thinking-orb\": { proofs: [{ scenarios: [\"dark\", \"large-text\", \"rtl\", \"reduced-motion\", \"accessibility\"], file: \"test/thinking-orb.browser.test.tsx\" }] },\n \"color-picker\": keyboard(\"test/web-additions.browser.test.tsx\"),\n // SSR proves semantics but cannot catch the close-only row seen in BurnTok.\n // Keep real geometry evidence attached without promoting catalog maturity.\n toast: {\n exportNames: [\"useToast\"],\n proofs: [\n { scenarios: [\"keyboard\"], file: stableCoreProofFile },\n { scenarios: [\"dark\", \"long-copy\", \"large-text\", \"rtl\"], file: \"test/toast-layout.browser.test.tsx\" },\n ],\n },\n select: keyboard(),\n combobox: keyboard(),\n dialog: keyboard(\"test/advanced.browser.test.tsx\"),\n \"alert-dialog\": keyboardAndLongCopy(\"test/alert-dialog.keyboard.browser.test.tsx\"),\n sheet: keyboardAndLongCopy(\"test/sheet-layout.browser.test.tsx\"),\n tooltip: keyboard(\"test/tooltip.browser.test.tsx\"),\n menu: keyboardAndLongCopy(\"test/menu.keyboard.browser.test.tsx\"),\n};\n\nconst exportEntries: Readonly<Record<string, readonly `./${string}`[] | undefined>> = publicExportEntries;\n\n/**\n * One claim per active Web row of the catalog. The subpath is the symbol's canonical granular entry, the export\n * names are the row's own symbol plus the companions published on that entry, and the scenarios are the row's\n * required Web evidence minus recorded gaps. Keyboard is never implied: it comes only from a dedicated proof.\n */\nfunction derivedClaim(entry: ComponentCatalogEntry): ReactRendererEvidenceComponent {\n const componentId = componentIdOf(entry);\n const extras = claimExtras[componentId] ?? {};\n const symbols = entry.name === \"DesignSystemProvider\" ? [\"HjmProvider\"] : [entry.name, ...(entry.companions ?? [])];\n // A row whose own name is not a symbol (Chart) claims through its first published companion.\n const subpath = symbols.map((symbol) => exportEntries[symbol]?.[0]).find((entry) => entry !== undefined);\n if (!subpath) throw new Error(`${entry.name} has no granular @hjmds/react export to claim evidence on`);\n const exportNames = [\n ...symbols.filter((symbol) => exportEntries[symbol]?.includes(subpath)),\n ...(extras.exportNames ?? []),\n ];\n const required = getRequiredShowcaseEvidence(entry).find((evidence) => evidence.surface === \"web\")?.scenarios ?? [];\n const gaps = webScenarioGaps[componentId] ?? [];\n const extraProofs = extras.proofs ?? [];\n const proven = new Set(extraProofs.flatMap((proof) => proof.scenarios));\n const matrix = required.filter((scenario): scenario is ReactRendererEvidenceScenario =>\n scenario !== \"default\" && scenario !== \"keyboard\" && scenario !== \"native-actions\" && scenario !== \"contract\"\n && !gaps.includes(scenario as ReactRendererEvidenceScenario) && !proven.has(scenario as ReactRendererEvidenceScenario));\n const proofs = [\n { scenarios: [\"default\" as const], file: defaultProofFile, caseId: componentId },\n ...(matrix.length === 0 ? [] : [{ scenarios: matrix, file: matrixProofFile, caseId: componentId }]),\n ...extraProofs.map((proof) => ({ ...proof, caseId: componentId })),\n ];\n return {\n componentId,\n exportNames,\n subpath,\n scenarios: proofs.flatMap((proof) => proof.scenarios),\n proofs,\n };\n}\n\nconst activeWebEntries: readonly ComponentCatalogEntry[] = componentCatalog.filter((entry) => {\n const status = getComponentSurfaceStatus(entry, \"web\");\n return status === \"stable\" || status === \"beta\";\n});\n\n/**\n * First-party Web renderer claims. Scenario axes remain fail-closed: the\n * default scenario is an SSR render, the environment and accessibility\n * scenarios are computed-style assertions in scenario-matrix.browser.\n * Keyboard and cross-platform parity remain fail-closed until dedicated\n * interaction or paired-renderer proofs are mapped one-to-one.\n */\nexport const reactRendererEvidence = {\n schemaVersion: reactRendererEvidenceSchemaVersion,\n packageName: \"@hjmds/react\",\n packageVersion: \"1.48.0\",\n surface: \"web\",\n components: activeWebEntries.map(derivedClaim),\n} as const satisfies ReactRendererEvidenceManifest;\n"]}
|
|
1
|
+
{"version":3,"file":"evidence.js","sourceRoot":"","sources":["../src/evidence.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ShowcaseScenarioId } from \"@hjmds/design-contracts/showcase\";\nimport { getRequiredShowcaseEvidence } from \"@hjmds/design-contracts/showcase\";\nimport { componentCatalog, componentIdOf, getComponentSurfaceStatus, type ComponentCatalogEntry } from \"@hjmds/design-contracts/catalog\";\nimport { publicExportEntries } from \"./public-exports.generated.js\";\n\nexport const reactRendererEvidenceSchemaVersion = 2 as const;\n\nexport type ReactRendererEvidenceScenario = Exclude<ShowcaseScenarioId, \"contract\" | \"native-actions\">;\n\nexport type ReactRendererEvidenceComponent = Readonly<{\n /** Canonical component id from the design-contracts catalog. */\n componentId: string;\n /** Public symbols that implement this contract on the declared subpath. */\n exportNames: readonly string[];\n /** Granular @hjmds/react export used by consumers. */\n subpath: `./${string}`;\n /** Scenarios supported by automated first-party renderer evidence. */\n scenarios: readonly ReactRendererEvidenceScenario[];\n /** Repository-local executable proof for every claimed scenario. */\n proofs: readonly Readonly<{\n scenarios: readonly ReactRendererEvidenceScenario[];\n file: `test/${string}.test.tsx`;\n caseId: string;\n }>[];\n}>;\n\nexport type ReactRendererEvidenceManifest = Readonly<{\n schemaVersion: typeof reactRendererEvidenceSchemaVersion;\n packageName: \"@hjmds/react\";\n packageVersion: string;\n surface: \"web\";\n components: readonly ReactRendererEvidenceComponent[];\n}>;\n\nconst defaultProofFile = \"test/default-render.ssr.test.tsx\" as const;\nconst matrixProofFile = \"test/scenario-matrix.browser.test.tsx\" as const;\nconst stableCoreProofFile = \"test/stable-core.browser.test.tsx\" as const;\n\ntype ProofFile = `test/${string}.test.tsx`;\n\n/**\n * Scenarios a component does not pass yet. Each entry is promotion debt that\n * the generated evidence projection reports; remove it when the component is\n * fixed and the matrix case passes. Stable surfaces cannot carry a gap\n * (scripts/check-workspace-sync.mjs).\n */\nconst webScenarioGaps: Readonly<Record<string, readonly ReactRendererEvidenceScenario[]>> = {};\n\n/**\n * Proofs that live outside the shared default/matrix files: keyboard behavior in a dedicated browser test,\n * long copy proven inside a portal by the component's own test, or a whole matrix run in a component file.\n * Everything else about a claim derives from the catalog row (2026-10-18 registration input).\n */\ntype ClaimExtras = Readonly<{\n /** Extra proofs; their scenarios are removed from the shared matrix proof. */\n proofs?: readonly Readonly<{ scenarios: readonly ReactRendererEvidenceScenario[]; file: ProofFile }>[];\n /** Hooks or helpers published beside the component symbols on the same subpath. */\n exportNames?: readonly string[];\n}>;\n\nconst keyboard = (file: ProofFile = stableCoreProofFile): ClaimExtras => ({ proofs: [{ scenarios: [\"keyboard\"], file }] });\nconst keyboardAndLongCopy = (file: ProofFile): ClaimExtras => ({ proofs: [{ scenarios: [\"keyboard\", \"long-copy\"], file }] });\n\nconst claimExtras: Readonly<Record<string, ClaimExtras>> = {\n \"time-picker\": keyboard(\"test/time-picker.browser.test.tsx\"),\n \"design-system-provider\": { exportNames: [\"useHjmTheme\"] },\n layout: keyboard(),\n link: keyboard(),\n field: keyboard(),\n \"search-field\": keyboard(),\n \"password-field\": keyboard(),\n \"otp-field\": keyboard(),\n \"number-field\": keyboard(),\n slider: keyboard(),\n form: keyboard(\"test/form.keyboard.browser.test.tsx\"),\n \"date-picker\": keyboard(),\n calendar: keyboard(\"test/calendar.browser.test.tsx\"),\n \"file-picker\": keyboard(\"test/file-picker.keyboard.browser.test.tsx\"),\n checkbox: keyboard(),\n \"checkbox-group\": keyboard(),\n \"radio-group\": keyboard(),\n switch: keyboard(),\n \"segmented-control\": keyboard(),\n chip: keyboard(),\n tabs: keyboard(\"test/tabs.keyboard.browser.test.tsx\"),\n breadcrumb: keyboard(\"test/page-navigation.browser.test.tsx\"),\n pagination: keyboard(\"test/pagination.keyboard.browser.test.tsx\"),\n popover: keyboardAndLongCopy(\"test/popover.browser.test.tsx\"),\n \"side-panel\": keyboardAndLongCopy(\"test/side-panel.browser.test.tsx\"),\n splitter: keyboard(\"test/splitter.browser.test.tsx\"),\n tour: keyboardAndLongCopy(\"test/tour.browser.test.tsx\"),\n tree: keyboard(\"test/tree.browser.test.tsx\"),\n \"transfer-list\": keyboard(\"test/transfer-list.browser.test.tsx\"),\n mentions: keyboard(\"test/mentions.browser.test.tsx\"),\n \"command-palette\": keyboardAndLongCopy(\"test/command-palette.browser.test.tsx\"),\n agreement: keyboard(\"test/agreement.keyboard.browser.test.tsx\"),\n \"toggle-group\": keyboard(),\n \"tags-input\": keyboard(),\n \"skip-nav\": keyboardAndLongCopy(\"test/skip-nav.browser.test.tsx\"),\n sidebar: keyboard(\"test/sidebar.browser.test.tsx\"),\n \"date-range-picker\": keyboard(\"test/date-range.keyboard.browser.test.tsx\"),\n \"auth-provider-button\": keyboard(),\n \"data-table\": keyboard(\"test/data-table.keyboard.browser.test.tsx\"),\n collapsible: keyboard(\"test/collapsible.keyboard.browser.test.tsx\"),\n \"context-menu\": keyboardAndLongCopy(\"test/context-menu.interactions.browser.test.tsx\"),\n menubar: keyboard(\"test/menubar.keyboard.browser.test.tsx\"),\n anchor: keyboard(\"test/anchor.browser.test.tsx\"),\n \"bottom-navigation\": keyboard(\"test/bottom-navigation.keyboard.browser.test.tsx\"),\n \"load-more\": keyboard(\"test/load-more.interactions.browser.test.tsx\"),\n carousel: keyboard(\"test/carousel.browser.test.tsx\"),\n \"floating-action-button\": keyboard(),\n accordion: keyboard(\"test/accordion.keyboard.browser.test.tsx\"),\n \"upload-item\": keyboard(\"test/upload-item.browser.test.tsx\"),\n // ThinkingOrb runs its whole environment matrix in its own file (canvas timing), not in scenario-matrix.\n \"thinking-orb\": { proofs: [{ scenarios: [\"dark\", \"large-text\", \"rtl\", \"reduced-motion\", \"accessibility\"], file: \"test/thinking-orb.browser.test.tsx\" }] },\n \"color-picker\": keyboard(\"test/web-additions.browser.test.tsx\"),\n // SSR proves semantics but cannot catch the close-only row seen in BurnTok.\n // Keep real geometry evidence attached without promoting catalog maturity.\n toast: {\n exportNames: [\"useToast\"],\n proofs: [\n { scenarios: [\"keyboard\"], file: stableCoreProofFile },\n { scenarios: [\"dark\", \"long-copy\", \"large-text\", \"rtl\"], file: \"test/toast-layout.browser.test.tsx\" },\n ],\n },\n select: keyboard(),\n combobox: keyboard(),\n dialog: keyboard(\"test/advanced.browser.test.tsx\"),\n \"alert-dialog\": keyboardAndLongCopy(\"test/alert-dialog.keyboard.browser.test.tsx\"),\n sheet: keyboardAndLongCopy(\"test/sheet-layout.browser.test.tsx\"),\n tooltip: keyboard(\"test/tooltip.browser.test.tsx\"),\n menu: keyboardAndLongCopy(\"test/menu.keyboard.browser.test.tsx\"),\n};\n\nconst exportEntries: Readonly<Record<string, readonly `./${string}`[] | undefined>> = publicExportEntries;\n\n/**\n * One claim per active Web row of the catalog. The subpath is the symbol's canonical granular entry, the export\n * names are the row's own symbol plus the companions published on that entry, and the scenarios are the row's\n * required Web evidence minus recorded gaps. Keyboard is never implied: it comes only from a dedicated proof.\n */\nfunction derivedClaim(entry: ComponentCatalogEntry): ReactRendererEvidenceComponent {\n const componentId = componentIdOf(entry);\n const extras = claimExtras[componentId] ?? {};\n const symbols = entry.name === \"DesignSystemProvider\" ? [\"HjmProvider\"] : [entry.name, ...(entry.companions ?? [])];\n // A row whose own name is not a symbol (Chart) claims through its first published companion.\n const subpath = symbols.map((symbol) => exportEntries[symbol]?.[0]).find((entry) => entry !== undefined);\n if (!subpath) throw new Error(`${entry.name} has no granular @hjmds/react export to claim evidence on`);\n const exportNames = [\n ...symbols.filter((symbol) => exportEntries[symbol]?.includes(subpath)),\n ...(extras.exportNames ?? []),\n ];\n const required = getRequiredShowcaseEvidence(entry).find((evidence) => evidence.surface === \"web\")?.scenarios ?? [];\n const gaps = webScenarioGaps[componentId] ?? [];\n const extraProofs = extras.proofs ?? [];\n const proven = new Set(extraProofs.flatMap((proof) => proof.scenarios));\n const matrix = required.filter((scenario): scenario is ReactRendererEvidenceScenario =>\n scenario !== \"default\" && scenario !== \"keyboard\" && scenario !== \"native-actions\" && scenario !== \"contract\"\n && !gaps.includes(scenario as ReactRendererEvidenceScenario) && !proven.has(scenario as ReactRendererEvidenceScenario));\n const proofs = [\n { scenarios: [\"default\" as const], file: defaultProofFile, caseId: componentId },\n ...(matrix.length === 0 ? [] : [{ scenarios: matrix, file: matrixProofFile, caseId: componentId }]),\n ...extraProofs.map((proof) => ({ ...proof, caseId: componentId })),\n ];\n return {\n componentId,\n exportNames,\n subpath,\n scenarios: proofs.flatMap((proof) => proof.scenarios),\n proofs,\n };\n}\n\nconst activeWebEntries: readonly ComponentCatalogEntry[] = componentCatalog.filter((entry) => {\n const status = getComponentSurfaceStatus(entry, \"web\");\n return status === \"stable\" || status === \"beta\";\n});\n\n/**\n * First-party Web renderer claims. Scenario axes remain fail-closed: the\n * default scenario is an SSR render, the environment and accessibility\n * scenarios are computed-style assertions in scenario-matrix.browser.\n * Keyboard and cross-platform parity remain fail-closed until dedicated\n * interaction or paired-renderer proofs are mapped one-to-one.\n */\nexport const reactRendererEvidence = {\n schemaVersion: reactRendererEvidenceSchemaVersion,\n packageName: \"@hjmds/react\",\n packageVersion: \"1.50.0\",\n surface: \"web\",\n components: activeWebEntries.map(derivedClaim),\n} as const satisfies ReactRendererEvidenceManifest;\n"]}
|
package/dist/image-choice.js
CHANGED
|
@@ -63,7 +63,8 @@ function VirtualTileRows({ items, renderTile, label, role, height, overscan, est
|
|
|
63
63
|
if (rendered > 0 && rendered !== measuredTileHeight)
|
|
64
64
|
setMeasuredTileHeight(rendered);
|
|
65
65
|
});
|
|
66
|
-
|
|
66
|
+
// Preserve empty columns so a short list fills the same slots as a full row (Diairy, 2026-10-27).
|
|
67
|
+
const columns = width > 0 ? resolveImageChoiceColumns(width) : 0;
|
|
67
68
|
const stride = (measuredTileHeight || estimatedTileHeight) + imageChoiceRecipe.gap;
|
|
68
69
|
const rowCount = columns ? Math.ceil(items.length / columns) : 0;
|
|
69
70
|
const range = resolveVirtualWindow(rowCount, stride, height, scrollTop, overscan);
|