@hjmds/react 1.20.0 → 1.21.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.
Files changed (81) hide show
  1. package/dist/actions.d.ts +10 -0
  2. package/dist/actions.d.ts.map +1 -1
  3. package/dist/actions.js +9 -3
  4. package/dist/actions.js.map +1 -1
  5. package/dist/authoring-tools.d.ts +38 -0
  6. package/dist/authoring-tools.d.ts.map +1 -0
  7. package/dist/authoring-tools.js +65 -0
  8. package/dist/authoring-tools.js.map +1 -0
  9. package/dist/calendar.d.ts.map +1 -1
  10. package/dist/calendar.js +1 -0
  11. package/dist/calendar.js.map +1 -1
  12. package/dist/chart.d.ts +157 -0
  13. package/dist/chart.d.ts.map +1 -0
  14. package/dist/chart.js +467 -0
  15. package/dist/chart.js.map +1 -0
  16. package/dist/collection-editing.d.ts +66 -0
  17. package/dist/collection-editing.d.ts.map +1 -0
  18. package/dist/collection-editing.js +126 -0
  19. package/dist/collection-editing.js.map +1 -0
  20. package/dist/communication.d.ts +51 -0
  21. package/dist/communication.d.ts.map +1 -0
  22. package/dist/communication.js +71 -0
  23. package/dist/communication.js.map +1 -0
  24. package/dist/data-table.d.ts +21 -1
  25. package/dist/data-table.d.ts.map +1 -1
  26. package/dist/data-table.js +105 -10
  27. package/dist/data-table.js.map +1 -1
  28. package/dist/data-workflows.d.ts +67 -0
  29. package/dist/data-workflows.d.ts.map +1 -0
  30. package/dist/data-workflows.js +60 -0
  31. package/dist/data-workflows.js.map +1 -0
  32. package/dist/evidence.d.ts +1 -1
  33. package/dist/evidence.js +1 -1
  34. package/dist/evidence.js.map +1 -1
  35. package/dist/internal/use-composition-action.d.ts +17 -0
  36. package/dist/internal/use-composition-action.d.ts.map +1 -0
  37. package/dist/internal/use-composition-action.js +18 -0
  38. package/dist/internal/use-composition-action.js.map +1 -0
  39. package/dist/media-transport.d.ts +22 -0
  40. package/dist/media-transport.d.ts.map +1 -0
  41. package/dist/media-transport.js +50 -0
  42. package/dist/media-transport.js.map +1 -0
  43. package/dist/navigation.d.ts +3 -1
  44. package/dist/navigation.d.ts.map +1 -1
  45. package/dist/navigation.js +29 -5
  46. package/dist/navigation.js.map +1 -1
  47. package/dist/screen-flows.d.ts +1 -1
  48. package/dist/screen-flows.d.ts.map +1 -1
  49. package/dist/screen-flows.js +1 -1
  50. package/dist/screen-flows.js.map +1 -1
  51. package/dist/screens.d.ts +8 -2
  52. package/dist/screens.d.ts.map +1 -1
  53. package/dist/screens.js +11 -5
  54. package/dist/screens.js.map +1 -1
  55. package/dist/social-compositions.d.ts +52 -0
  56. package/dist/social-compositions.d.ts.map +1 -0
  57. package/dist/social-compositions.js +41 -0
  58. package/dist/social-compositions.js.map +1 -0
  59. package/dist/streaming-answer.d.ts +24 -0
  60. package/dist/streaming-answer.d.ts.map +1 -0
  61. package/dist/streaming-answer.js +57 -0
  62. package/dist/streaming-answer.js.map +1 -0
  63. package/dist/styles.css +144 -1
  64. package/dist/styles.layered.css +144 -1
  65. package/dist/table-family.d.ts +66 -0
  66. package/dist/table-family.d.ts.map +1 -0
  67. package/dist/table-family.js +75 -0
  68. package/dist/table-family.js.map +1 -0
  69. package/dist/task-controls.d.ts +47 -0
  70. package/dist/task-controls.d.ts.map +1 -0
  71. package/dist/task-controls.js +46 -0
  72. package/dist/task-controls.js.map +1 -0
  73. package/dist/toggle-feedback.d.ts +26 -0
  74. package/dist/toggle-feedback.d.ts.map +1 -0
  75. package/dist/toggle-feedback.js +47 -0
  76. package/dist/toggle-feedback.js.map +1 -0
  77. package/dist/transfer-task.d.ts +18 -0
  78. package/dist/transfer-task.d.ts.map +1 -0
  79. package/dist/transfer-task.js +56 -0
  80. package/dist/transfer-task.js.map +1 -0
  81. package/package.json +58 -3
@@ -1 +1 @@
1
- {"version":3,"file":"screens.js","sourceRoot":"","sources":["../src/screens.tsx"],"names":[],"mappings":"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","sourcesContent":["import { resolveDesignProfileScreen, type DesignProfileScreenPresentation } from \"@hjmds/design-contracts/design-profile-layout\";\nimport { MessageReactions } from \"./internal/message-reactions.js\";\nimport type { ReactionPickerProps } from \"./reaction-picker.js\";\nimport { Button, IconButton } from \"./actions.js\";\nimport { useOptionalHjmTheme } from \"./provider.js\";\nimport { TextArea } from \"./forms.js\";\nimport { useId, useLayoutEffect, useRef, useState, type Ref, type ReactNode } from \"react\";\nimport { isReplySwipe, timestampRevealOffset, shouldSubmitMessageKey, canSubmitMessage, validateMessageAttachments, type MessageAttachmentDescriptor, resolveScreenContentState, screenPatternRecipe, type ChatMessageDescriptor, type MessageComposerDescriptor, type ScreenContentState } from \"@hjmds/design-contracts/screen-patterns\";\nimport { Heading } from \"./heading.js\";\nimport { Spinner } from \"./internal/spinner.js\";\nimport { Section, Stack, Text } from \"./layout.js\";\nimport { ListRow, type ListRowProps } from \"./display.js\";\nimport { classNames, useDesignProfileDefaults } from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type ScreenLayoutProps = Readonly<{\n title: string;\n /** Preserve host navigation while the shared shell owns content and state. */\n header?: ReactNode;\n contentInset?: \"default\" | \"none\";\n /** Explicit layout wins over the nearest design profile. */\n presentation?: DesignProfileScreenPresentation;\n description?: string;\n leading?: ReactNode;\n actions?: ReactNode;\n notice?: ReactNode;\n footer?: ReactNode;\n state?: ScreenContentState;\n stateAction?: ReactNode;\n children?: ReactNode;\n /** A virtualized list must own scrolling; never nest it inside a second scroll container. */\n scroll?: \"screen\" | \"content\";\n as?: \"main\" | \"section\";\n className?: string;\n /**\n * Canonical layout-only placement on the screen root (for example `flex` or `width` in a split\n * view), matching Native ScreenLayout. Every screen built on ScreenLayout forwards it.\n */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\n/** Shared screen shell. Routing, data, permission checks and mutation state remain product-owned. */\nexport function ScreenLayout({ title, header, contentInset = \"default\", presentation: suppliedPresentation, description, leading, actions, notice, footer, state = { kind: \"ready\" }, stateAction, children, scroll = \"screen\", as: Element = \"main\", className, layoutStyle }: ScreenLayoutProps) {\n const id = useId();\n // Screens historically work with the stylesheet alone. Optional context keeps\n // that path while inheriting profiles from an enclosing Provider when present.\n const designProfile = useDesignProfileDefaults();\n const presentation = suppliedPresentation ?? designProfile?.screens.overview;\n const profileLayout = presentation === undefined ? undefined : resolveDesignProfileScreen(presentation);\n const resolved = resolveScreenContentState(state);\n // Replacement text owns scrolling even when the ready state delegates it to\n // a virtual list. Use the rendered mode for keyboard access as well as CSS.\n const bodyScroll = resolved.replacesContent ? \"screen\" : scroll;\n const bodyRef = useRef<HTMLDivElement>(null);\n const lastBodyFocus = useRef<HTMLElement | null>(null);\n useLayoutEffect(() => {\n // Replacing a focused retry/input removes its DOM node. Keep keyboard users\n // in the same content region without stealing focus moved to another control.\n const previous = lastBodyFocus.current;\n if (previous && !previous.isConnected && document.activeElement === document.body) {\n bodyRef.current?.focus({ preventScroll: true });\n }\n if (previous && !previous.isConnected) lastBodyFocus.current = null;\n });\n const recipe = screenPatternRecipe;\n return <Element aria-labelledby={header ? undefined : id} aria-label={header ? title : undefined} data-content-inset={contentInset} data-presentation={presentation} className={classNames(\"hjm-screen\", className)}\n style={{ backgroundColor: designProfile?.material.canvas ? \"transparent\" : undefined, \"--hjm-screen-width\": `${profileLayout?.maxWidth ?? recipe.maxWidth}px`, \"--hjm-screen-padding\": `${contentInset === \"none\" ? 0 : recipe.padding}px`, \"--hjm-screen-gap\": `${profileLayout?.gap ?? recipe.sectionGap}px`, \"--hjm-screen-item-gap\": `${recipe.itemGap}px`, \"--hjm-screen-state-gap\": `${recipe.stateGap}px`, \"--hjm-screen-header-min\": `${recipe.headerMinWidth}px`, ...layoutStyle } as React.CSSProperties}>\n {header ?? <header className=\"hjm-screen__header\" style={profileLayout ? { flexDirection: profileLayout.headerAxis, alignItems: profileLayout.centered ? \"center\" : undefined, textAlign: profileLayout.centered ? \"center\" : undefined } : undefined}>\n {leading}<div className=\"hjm-screen__heading\"><Heading level=\"level3\" semanticLevel={1} id={id}>{title}</Heading>\n {description ? <Text as=\"p\" tone=\"muted\">{description}</Text> : null}</div>{actions}\n </header>}\n {notice ? <div className=\"hjm-screen__notice\">{notice}</div> : null}\n {/* Scrollable read-only screens still need a keyboard entry point. */}\n <div ref={bodyRef} tabIndex={bodyScroll === \"content\" ? -1 : 0}\n onFocusCapture={event => { lastBodyFocus.current = event.target as HTMLElement; }}\n onBlurCapture={event => {\n // A connected input blurred to the document intentionally relinquishes\n // focus too; only removal of the currently focused node needs recovery.\n if (event.relatedTarget ? !event.currentTarget.contains(event.relatedTarget as Node) : (event.target as HTMLElement).isConnected) {\n lastBodyFocus.current = null;\n }\n }}\n className=\"hjm-screen__body\" data-scroll={bodyScroll} data-replacement={resolved.replacesContent || undefined} aria-busy={resolved.busy || undefined}>\n {state.kind === \"ready\" ? children : <div className=\"hjm-screen__state\">\n {/* Loading copy is an accessible name; visible copy beside the spinner\n contradicts the shared spinner-only loading contract. */}\n {resolved.busy ? <Spinner label={[state.title, state.description].filter(Boolean).join(\". \")} /> : <div role={state.kind === \"error\" ? \"alert\" : \"status\"}>\n <Stack gap=\"sm\" align=\"center\"><Text variant=\"title\">{state.title}</Text>\n {state.description ? <Text tone=\"muted\">{state.description}</Text> : null}</Stack>\n </div>}\n {stateAction}\n </div>}\n </div>\n {footer ? <footer className=\"hjm-screen__footer\">{footer}</footer> : null}\n </Element>;\n}\n\nexport type SettingsScreenSection = Readonly<{ id: string; title: string; description?: string; children: ReactNode }>;\nexport type SettingsScreenProps = Omit<ScreenLayoutProps, \"children\" | \"scroll\"> & Readonly<{ profile?: ReactNode; sections: readonly SettingsScreenSection[] }>;\nexport function SettingsScreen({ profile, sections, ...props }: SettingsScreenProps) {\n // Keep semantic section headings while using the smaller settings label role.\n return <ScreenLayout {...props}><Stack gap=\"md\">{profile}{sections.map(section =>\n <Section className=\"hjm-settings-section\" key={section.id} title={<Text variant=\"label\" emphasis=\"strong\" tone=\"muted\">{section.title}</Text>} description={section.description}>{section.children}</Section>)}</Stack></ScreenLayout>;\n}\n\nexport type NotificationInboxScreenProps = Omit<ScreenLayoutProps, \"children\"> & Readonly<{\n filters?: ReactNode;\n children: ReactNode;\n}>;\nexport function NotificationInboxScreen({ filters, children, notice, ...props }: NotificationInboxScreenProps) {\n return <ScreenLayout {...props} notice={<Stack gap=\"sm\">{notice}{filters}</Stack>}>{children}</ScreenLayout>;\n}\n\n/** Read/unread is announced in localized copy as well as emphasis; rendering never marks an item read. */\nexport type NotificationItemProps = Omit<ListRowProps, \"description\" | \"selected\"> & Readonly<{\n read: boolean;\n statusLabel: string;\n timestamp: string;\n description?: ReactNode;\n}>;\nexport function NotificationItem({ read, statusLabel, timestamp, description, title, className, ...props }: NotificationItemProps) {\n return <ListRow {...props} className={classNames(\"hjm-notification-item\", className)} data-unread={!read || undefined} title={<Text emphasis={read ? \"regular\" : \"strong\"}>{title}</Text>}\n description={<Stack gap=\"xxs\">{description}<Text variant=\"caption\" tone=\"muted\">{statusLabel} · {timestamp}</Text></Stack>} />;\n}\n\nexport type ChatScreenProps = Omit<ScreenLayoutProps, \"footer\"> & Readonly<{ composer: ReactNode }>;\n/** Caller supplies a virtualized timeline and keyboard-aware composer; no implicit auto-scroll or send. */\nexport function ChatScreen({ composer, scroll = \"content\", ...props }: ChatScreenProps) {\n // An empty conversation must still allow its first message; unavailable states hide input.\n return <ScreenLayout {...props} scroll={scroll} footer={!props.state || props.state.kind === \"ready\" || props.state.kind === \"empty\" ? composer : null} />;\n}\n\nexport type MessageComposerProps = Omit<MessageComposerDescriptor, \"attachmentCount\"> & Readonly<{\n maxLength?: number;\n sendDisabled?: boolean;\n additionalContent?: boolean;\n leadingAction?: ReactNode;\n inputRef?: Ref<HTMLTextAreaElement>;\n /** Release typing presence when the host input loses focus. */\n onBlur?: () => void;\n onValueChange(value: string): void;\n onSend(value: string): void;\n context?: ReactNode;\n replyTo?: Readonly<{ author: string; excerpt: string; cancelLabel: string; onCancel(): void }>;\n /** Icon mode puts the send/attachment action inside the growing field. */\n sendIcon?: ReactNode;\n /** Reference comment layout: a filled circular send action inside the field. */\n sendPresentation?: \"inline\" | \"circle\";\n attachmentAction?: Readonly<{ label: string; icon: ReactNode; onPress(): void; disabled?: boolean }>;\n attachments?: readonly (MessageAttachmentDescriptor & Readonly<{ preview: ReactNode }>)[];\n onRemoveAttachment?: (id: string) => void;\n /** Canonical layout-only placement on the composer root. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\nexport function MessageComposer({ value, label, sendLabel, placeholder = label, description, error, invalid = false, submitMode = \"newline\", onBlur, disabled = false, pending = false, onValueChange, onSend, maxLength, sendDisabled = false, additionalContent = false, leadingAction, inputRef, context, replyTo, sendIcon, sendPresentation = \"inline\", attachmentAction, attachments = [], onRemoveAttachment, layoutStyle }: MessageComposerProps) {\n validateMessageAttachments(attachments);\n if (attachments.length && !onRemoveAttachment) throw new TypeError(\"Attachments require a removal callback\");\n const canSend = !sendDisabled && canSubmitMessage({ value, label, sendLabel, disabled, pending, attachmentCount: attachments.length + (additionalContent ? 1 : 0) });\n const locked = disabled || pending;\n // A bounded corner radius keeps multiline/large-text content inside the field instead of a tall pill.\n const hasContent = !!value.trim() || attachments.length > 0 || additionalContent;\n const attach = attachmentAction ? <IconButton label={attachmentAction.label} tone=\"ghost\" disabled={locked || attachmentAction.disabled} onClick={attachmentAction.onPress}>{attachmentAction.icon}</IconButton> : null;\n const send = sendIcon ? <IconButton label={sendLabel} size={sendPresentation === \"circle\" ? \"small\" : \"medium\"} shape=\"circle\" tone={sendPresentation === \"circle\" ? \"primary\" : \"ghost\"} disabled={!canSend} loading={pending} onClick={() => { if (canSend) onSend(value); }}>{sendIcon}</IconButton> : <Button disabled={!canSend} loading={pending} onClick={() => { if (canSend) onSend(value); }}>{sendLabel}</Button>;\n // Readonly pending input preserves the keyboard/focus for receipt failure recovery; disabling it would blur desktop chat.\n // Enter is opt-in and IME-safe; receipt-driven clearing and failed-send recovery belong to the host.\n return <div className=\"hjm-message-composer\" data-send-presentation={sendPresentation} style={{\"--hjm-message-composer-gap\": `${screenPatternRecipe.itemGap}px`, \"--hjm-attachment-size\": `${screenPatternRecipe.attachmentSize}px`, \"--hjm-attachment-remove-size\": `${screenPatternRecipe.attachmentRemoveSize}px`, ...layoutStyle} as React.CSSProperties}>{context}{replyTo ? <Stack axis=\"inline\" gap=\"sm\" align=\"center\"><Stack gap=\"xxs\"><Text variant=\"caption\" emphasis=\"strong\">{replyTo.author}</Text><Text variant=\"caption\" tone=\"muted\">{replyTo.excerpt}</Text></Stack><IconButton label={replyTo.cancelLabel} tone=\"ghost\" disabled={locked} onClick={replyTo.onCancel}><Text>×</Text></IconButton></Stack> : null}\n {attachments.length ? <div className=\"hjm-message-composer__attachments\">{attachments.map(item => <div key={item.id} className=\"hjm-message-composer__attachment\"><div className=\"hjm-message-composer__preview\">{item.preview}</div><span className=\"hjm-message-composer__remove\"><IconButton label={item.removeLabel} tone=\"ghost\" size=\"small\" disabled={locked || item.disabled} onClick={() => { if (!locked && !item.disabled) onRemoveAttachment?.(item.id); }}><span className=\"hjm-message-composer__remove-glyph\" aria-hidden=\"true\">×</span></IconButton></span></div>)}{attach}</div> : null}\n <div className=\"hjm-message-composer__row\"><TextArea ref={inputRef} maxLength={maxLength} leadingAction={leadingAction} shape=\"large\" rows={screenPatternRecipe.composerMinLines} aria-label={label} placeholder={placeholder} description={description} error={error} aria-invalid={invalid || undefined} onBlur={onBlur} value={value} disabled={disabled} readOnly={pending} aria-busy={pending || undefined}\n onKeyDown={event => { if (shouldSubmitMessageKey({key:event.key, shiftKey:event.shiftKey, isComposing:event.nativeEvent.isComposing, keyCode:event.nativeEvent.keyCode}, submitMode)) { event.preventDefault(); if (canSend) onSend(value); } }}\n onChange={event => { if (!locked) onValueChange(event.currentTarget.value); }} minVisibleLines={screenPatternRecipe.composerMinLines} maxVisibleLines={screenPatternRecipe.composerMaxLines}\n {...(sendIcon ? { trailing: hasContent || pending ? send : attach } : {})} />\n {sendIcon ? null : send}\n </div></div>;\n}\n\nexport type ChatMessageProps = ChatMessageDescriptor & Readonly<{ children: ReactNode; interactiveContent?: boolean; avatar?: ReactNode; reply?: ReactNode; actions?: ReactNode; replyAction?: Readonly<{label:string; onPress():void; disabled?:boolean}>; replyLink?: Readonly<{label:string; onPress():void}>; reactions?: ReactionPickerProps & Readonly<{ closeLabel: string; menuAction?: Readonly<{ label: string; onPress(): void; disabled?: boolean }> }>;\n /** Canonical layout-only placement on the message row. The swipe offset still owns `transform`. */\n layoutStyle?: HjmCompositionStyleProp }>;\nexport function ChatMessage({ direction, author, timestamp, timestampPresentation = \"always\", bubbleTail = false, deliveryLabel, avatar, reply, actions, replyAction, replyLink, reactions, children, interactiveContent=false, layoutStyle }: ChatMessageProps) {\n const theme = useOptionalHjmTheme();\n const revealTime = timestampPresentation === \"swipe\" && !!timestamp;\n // Only the pointer that began a drag can finish it; another touch must not reply or cancel it.\n const start = useRef<{x:number;y:number;pointerId:number} | null>(null);\n const [offset, setOffset] = useState(0);\n const finish = () => { start.current = null; setOffset(0); };\n return <article tabIndex={replyAction && !replyAction.disabled ? 0 : undefined}\n aria-keyshortcuts={replyAction ? \"Alt+ArrowLeft Alt+ArrowRight\" : undefined} aria-description={replyAction?.label}\n onKeyDown={event => { if (event.target === event.currentTarget && event.altKey && (event.key === \"ArrowLeft\" || event.key === \"ArrowRight\") && replyAction && !replyAction.disabled) { event.preventDefault(); replyAction.onPress(); } }}\n onPointerDown={event => { if (start.current || (!revealTime && (!replyAction || replyAction.disabled)) || event.button !== 0 || (event.target as HTMLElement).closest(\"button,a,input,textarea\")) return; start.current = {x:event.clientX,y:event.clientY,pointerId:event.pointerId}; }}\n onPointerMove={event => { if (!start.current || start.current.pointerId !== event.pointerId) return; const dx=event.clientX-start.current.x,dy=event.clientY-start.current.y; if (Math.abs(dy)>10 && Math.abs(dy)>Math.abs(dx)) {finish();return;} if (revealTime) setOffset((direction === \"outgoing\" ? -1 : 1) * timestampRevealOffset(direction === \"outgoing\" ? -dx : dx,dy)); else if (Math.abs(dx)>Math.abs(dy)*2) setOffset(Math.max(-72,Math.min(72,dx))); }}\n onPointerUp={event => { if (start.current?.pointerId !== event.pointerId) return; if (!revealTime && start.current && replyAction && !replyAction.disabled && isReplySwipe(event.clientX-start.current.x,event.clientY-start.current.y)) replyAction.onPress(); finish(); }} onPointerCancel={event => { if (start.current?.pointerId === event.pointerId) finish(); }} onPointerLeave={event => { if (start.current?.pointerId === event.pointerId) finish(); }}\n style={{ ...layoutStyle, position: \"relative\", overflow: \"hidden\", paddingInline: bubbleTail ? \"var(--hjm-space-xs)\" : undefined, touchAction: revealTime || replyAction ? \"pan-y\" : undefined }} aria-label={author}>\n {revealTime ? <time style={{ position: \"absolute\", ...(direction === \"outgoing\" ? { right: 0, justifyContent: \"flex-end\" } : { left: 0 }), top: 0, bottom: 0, width: 80, display: \"flex\", alignItems: \"center\", opacity: offset !== 0 ? 1 : 0, pointerEvents: \"none\" }}><Text variant=\"caption\" tone=\"muted\">{timestamp}</Text></time> : null}\n <div className=\"hjm-chat-message\" style={{ transform: `translateX(${offset}px)`, transition: start.current || theme?.environment.reducedMotion ? \"none\" : \"transform var(--hjm-motion-normal, 200ms) ease-out\", \"--hjm-message-max-width\": screenPatternRecipe.messageMaxWidth } as React.CSSProperties} data-direction={direction} data-tail={bubbleTail || undefined}>\n {avatar ? <div className=\"hjm-chat-message__avatar\">{avatar}</div> : null}\n <div className=\"hjm-chat-message__content\">{author?<Text variant=\"caption\" tone=\"muted\">{author}</Text>:null}\n {reply && replyLink ? <Button tone=\"ghost\" aria-label={replyLink.label} onClick={replyLink.onPress}>{reply}</Button> : null}\n {reactions ? <MessageReactions {...reactions} interactiveContent={interactiveContent}>{reply && !replyLink ? <div className=\"hjm-chat-message__reply\">{reply}</div> : null}{children}</MessageReactions> : <div className=\"hjm-chat-message__bubble\">{reply && !replyLink ? <div className=\"hjm-chat-message__reply\">{reply}</div> : null}{children}</div>}\n {(!revealTime && timestamp)||deliveryLabel||actions?<div className=\"hjm-chat-message__meta\">{(!revealTime && timestamp)||deliveryLabel?<Text variant=\"caption\" tone=\"muted\">{[revealTime ? \"\" : timestamp, deliveryLabel].filter(Boolean).join(\" · \")}</Text>:null}{actions}</div>:null}\n </div>\n </div>\n </article>;\n}\n"]}
1
+ {"version":3,"file":"screens.js","sourceRoot":"","sources":["../src/screens.tsx"],"names":[],"mappings":"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","sourcesContent":["import { resolveComposerLimit, type ComposerLengthFeedback } from \"@hjmds/design-contracts/communication\";\nimport { Progress } from \"./feedback.js\";\nimport { resolveDesignProfileScreen, type DesignProfileScreenPresentation } from \"@hjmds/design-contracts/design-profile-layout\";\nimport { MessageReactions } from \"./internal/message-reactions.js\";\nimport type { ReactionPickerProps } from \"./reaction-picker.js\";\nimport { Button, IconButton } from \"./actions.js\";\nimport { useOptionalHjmTheme } from \"./provider.js\";\nimport { TextArea } from \"./forms.js\";\nimport { useId, useLayoutEffect, useRef, useState, type Ref, type ReactNode } from \"react\";\nimport { isReplySwipe, timestampRevealOffset, shouldSubmitMessageKey, canSubmitMessage, validateMessageAttachments, type MessageAttachmentDescriptor, resolveScreenContentState, screenPatternRecipe, type ChatMessageDescriptor, type MessageComposerDescriptor, type ScreenContentState } from \"@hjmds/design-contracts/screen-patterns\";\nimport { Heading } from \"./heading.js\";\nimport { Spinner } from \"./internal/spinner.js\";\nimport { Section, Stack, Text } from \"./layout.js\";\nimport { ListRow, type ListRowProps } from \"./display.js\";\nimport { classNames, useDesignProfileDefaults } from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type ScreenLayoutProps = Readonly<{\n title: string;\n /** Hide redundant route names while retaining descriptions and a named screen. */\n titleVisibility?: \"visible\" | \"hidden\";\n headerAlignment?: \"start\" | \"center\";\n /** Preserve host navigation while the shared shell owns content and state. */\n header?: ReactNode;\n contentInset?: \"default\" | \"none\";\n /** Explicit layout wins over the nearest design profile. */\n presentation?: DesignProfileScreenPresentation;\n description?: string;\n leading?: ReactNode;\n actions?: ReactNode;\n notice?: ReactNode;\n footer?: ReactNode;\n state?: ScreenContentState;\n stateAction?: ReactNode;\n children?: ReactNode;\n /** A virtualized list must own scrolling; never nest it inside a second scroll container. */\n scroll?: \"screen\" | \"content\";\n as?: \"main\" | \"section\";\n className?: string;\n /**\n * Canonical layout-only placement on the screen root (for example `flex` or `width` in a split\n * view), matching Native ScreenLayout. Every screen built on ScreenLayout forwards it.\n */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\n/** Shared screen shell. Routing, data, permission checks and mutation state remain product-owned. */\nexport function ScreenLayout({ title, titleVisibility = \"visible\", headerAlignment = \"start\", header, contentInset = \"default\", presentation: suppliedPresentation, description, leading, actions, notice, footer, state = { kind: \"ready\" }, stateAction, children, scroll = \"screen\", as: Element = \"main\", className, layoutStyle }: ScreenLayoutProps) {\n const id = useId();\n const showHeader = titleVisibility === \"visible\" || !!description || !!leading || !!actions;\n // Screens historically work with the stylesheet alone. Optional context keeps\n // that path while inheriting profiles from an enclosing Provider when present.\n const designProfile = useDesignProfileDefaults();\n const presentation = suppliedPresentation ?? designProfile?.screens.overview;\n const profileLayout = presentation === undefined ? undefined : resolveDesignProfileScreen(presentation);\n const resolved = resolveScreenContentState(state);\n // Replacement text owns scrolling even when the ready state delegates it to\n // a virtual list. Use the rendered mode for keyboard access as well as CSS.\n const bodyScroll = resolved.replacesContent ? \"screen\" : scroll;\n const bodyRef = useRef<HTMLDivElement>(null);\n const lastBodyFocus = useRef<HTMLElement | null>(null);\n useLayoutEffect(() => {\n // Replacing a focused retry/input removes its DOM node. Keep keyboard users\n // in the same content region without stealing focus moved to another control.\n const previous = lastBodyFocus.current;\n if (previous && !previous.isConnected && document.activeElement === document.body) {\n bodyRef.current?.focus({ preventScroll: true });\n }\n if (previous && !previous.isConnected) lastBodyFocus.current = null;\n });\n const recipe = screenPatternRecipe;\n return <Element aria-labelledby={header || titleVisibility === \"hidden\" ? undefined : id} aria-label={header || titleVisibility === \"hidden\" ? title : undefined} data-content-inset={contentInset} data-presentation={presentation} className={classNames(\"hjm-screen\", className)}\n style={{ backgroundColor: designProfile?.material.canvas ? \"transparent\" : undefined, \"--hjm-screen-width\": `${profileLayout?.maxWidth ?? recipe.maxWidth}px`, \"--hjm-screen-padding\": `${contentInset === \"none\" ? 0 : recipe.padding}px`, \"--hjm-screen-gap\": `${profileLayout?.gap ?? recipe.sectionGap}px`, \"--hjm-screen-item-gap\": `${recipe.itemGap}px`, \"--hjm-screen-state-gap\": `${recipe.stateGap}px`, \"--hjm-screen-header-min\": `${recipe.headerMinWidth}px`, ...layoutStyle } as React.CSSProperties}>\n {header ?? (showHeader ? headerAlignment === \"center\" ? <header className=\"hjm-screen__header\" style={{ display: \"grid\", gridTemplateColumns: \"minmax(0, 1fr) minmax(0, 2fr) minmax(0, 1fr)\", alignItems: \"center\" }}>\n <div>{leading}</div><div className=\"hjm-screen__heading\" style={{ textAlign: \"center\", minWidth: 0 }}>\n {titleVisibility === \"visible\" && <Heading level=\"level3\" semanticLevel={1} id={id}>{title}</Heading>}\n {description ? <Text as=\"p\" tone=\"muted\">{description}</Text> : null}</div><div style={{ justifySelf: \"end\" }}>{actions}</div>\n </header> : <header className=\"hjm-screen__header\" style={profileLayout ? { flexDirection: profileLayout.headerAxis, alignItems: profileLayout.centered ? \"center\" : undefined, textAlign: profileLayout.centered ? \"center\" : undefined } : undefined}>\n {leading}<div className=\"hjm-screen__heading\">{titleVisibility === \"visible\" && <Heading level=\"level3\" semanticLevel={1} id={id}>{title}</Heading>}\n {description ? <Text as=\"p\" tone=\"muted\">{description}</Text> : null}</div>{actions}\n </header> : null)}\n {notice ? <div className=\"hjm-screen__notice\">{notice}</div> : null}\n {/* Scrollable read-only screens still need a keyboard entry point. */}\n <div ref={bodyRef} tabIndex={bodyScroll === \"content\" ? -1 : 0}\n onFocusCapture={event => { lastBodyFocus.current = event.target as HTMLElement; }}\n onBlurCapture={event => {\n // A connected input blurred to the document intentionally relinquishes\n // focus too; only removal of the currently focused node needs recovery.\n if (event.relatedTarget ? !event.currentTarget.contains(event.relatedTarget as Node) : (event.target as HTMLElement).isConnected) {\n lastBodyFocus.current = null;\n }\n }}\n className=\"hjm-screen__body\" data-scroll={bodyScroll} data-replacement={resolved.replacesContent || undefined} aria-busy={resolved.busy || undefined}>\n {state.kind === \"ready\" ? children : <div className=\"hjm-screen__state\">\n {/* Loading copy is an accessible name; visible copy beside the spinner\n contradicts the shared spinner-only loading contract. */}\n {resolved.busy ? <Spinner label={[state.title, state.description].filter(Boolean).join(\". \")} /> : <div role={state.kind === \"error\" ? \"alert\" : \"status\"}>\n <Stack gap=\"sm\" align=\"center\"><Text variant=\"title\">{state.title}</Text>\n {state.description ? <Text tone=\"muted\">{state.description}</Text> : null}</Stack>\n </div>}\n {stateAction}\n </div>}\n </div>\n {footer ? <footer className=\"hjm-screen__footer\">{footer}</footer> : null}\n </Element>;\n}\n\nexport type SettingsScreenSection = Readonly<{ id: string; title: string; description?: string; children: ReactNode }>;\nexport type SettingsScreenProps = Omit<ScreenLayoutProps, \"children\" | \"scroll\"> & Readonly<{ profile?: ReactNode; sections: readonly SettingsScreenSection[] }>;\nexport function SettingsScreen({ profile, sections, ...props }: SettingsScreenProps) {\n // Keep semantic section headings while using the smaller settings label role.\n return <ScreenLayout {...props}><Stack gap=\"md\">{profile}{sections.map(section =>\n <Section className=\"hjm-settings-section\" key={section.id} title={<Text variant=\"label\" emphasis=\"strong\" tone=\"muted\">{section.title}</Text>} description={section.description}>{section.children}</Section>)}</Stack></ScreenLayout>;\n}\n\nexport type NotificationInboxScreenProps = Omit<ScreenLayoutProps, \"children\"> & Readonly<{\n filters?: ReactNode;\n children: ReactNode;\n}>;\nexport function NotificationInboxScreen({ filters, children, notice, ...props }: NotificationInboxScreenProps) {\n return <ScreenLayout {...props} notice={<Stack gap=\"sm\">{notice}{filters}</Stack>}>{children}</ScreenLayout>;\n}\n\n/** Read/unread is announced in localized copy as well as emphasis; rendering never marks an item read. */\nexport type NotificationItemProps = Omit<ListRowProps, \"description\" | \"selected\"> & Readonly<{\n read: boolean;\n statusLabel: string;\n timestamp: string;\n description?: ReactNode;\n}>;\nexport function NotificationItem({ read, statusLabel, timestamp, description, title, className, ...props }: NotificationItemProps) {\n return <ListRow {...props} className={classNames(\"hjm-notification-item\", className)} data-unread={!read || undefined} title={<Text emphasis={read ? \"regular\" : \"strong\"}>{title}</Text>}\n description={<Stack gap=\"xxs\">{description}<Text variant=\"caption\" tone=\"muted\">{statusLabel} · {timestamp}</Text></Stack>} />;\n}\n\nexport type ChatScreenProps = Omit<ScreenLayoutProps, \"footer\"> & Readonly<{ composer: ReactNode }>;\n/** Caller supplies a virtualized timeline and keyboard-aware composer; no implicit auto-scroll or send. */\nexport function ChatScreen({ composer, scroll = \"content\", ...props }: ChatScreenProps) {\n // An empty conversation must still allow its first message; unavailable states hide input.\n return <ScreenLayout {...props} scroll={scroll} footer={!props.state || props.state.kind === \"ready\" || props.state.kind === \"empty\" ? composer : null} />;\n}\n\nexport type MessageComposerProps = Omit<MessageComposerDescriptor, \"attachmentCount\"> & Readonly<{\n maxLength?: number;\n /** Opt-in count/ring appears only near the actual maxLength; never trims drafts. */\n lengthFeedback?: ComposerLengthFeedback;\n sendDisabled?: boolean;\n additionalContent?: boolean;\n leadingAction?: ReactNode;\n inputRef?: Ref<HTMLTextAreaElement>;\n /** Release typing presence when the host input loses focus. */\n onBlur?: () => void;\n onValueChange(value: string): void;\n onSend(value: string): void;\n context?: ReactNode;\n replyTo?: Readonly<{ author: string; excerpt: string; cancelLabel: string; onCancel(): void }>;\n /** Icon mode puts the send/attachment action inside the growing field. */\n sendIcon?: ReactNode;\n /** Reference comment layout: a filled circular send action inside the field. */\n sendPresentation?: \"inline\" | \"circle\";\n attachmentAction?: Readonly<{ label: string; icon: ReactNode; onPress(): void; disabled?: boolean }>;\n attachments?: readonly (MessageAttachmentDescriptor & Readonly<{ preview: ReactNode }>)[];\n onRemoveAttachment?: (id: string) => void;\n /** Canonical layout-only placement on the composer root. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\nexport function MessageComposer({ value, label, sendLabel, placeholder = label, description, error, invalid = false, submitMode = \"newline\", onBlur, disabled = false, pending = false, onValueChange, onSend, maxLength, lengthFeedback, sendDisabled = false, additionalContent = false, leadingAction, inputRef, context, replyTo, sendIcon, sendPresentation = \"inline\", attachmentAction, attachments = [], onRemoveAttachment, layoutStyle }: MessageComposerProps) {\n validateMessageAttachments(attachments);\n if (attachments.length && !onRemoveAttachment) throw new TypeError(\"Attachments require a removal callback\");\n if (lengthFeedback && maxLength === undefined) throw new TypeError(\"Composer length feedback requires maxLength\");\n const limit = !lengthFeedback ? null : resolveComposerLimit(value, maxLength!, lengthFeedback.threshold);\n const canSend = !sendDisabled && !limit?.exceeded && canSubmitMessage({ value, label, sendLabel, disabled, pending, attachmentCount: attachments.length + (additionalContent ? 1 : 0) });\n const locked = disabled || pending;\n // A bounded corner radius keeps multiline/large-text content inside the field instead of a tall pill.\n const hasContent = !!value.trim() || attachments.length > 0 || additionalContent;\n const attach = attachmentAction ? <IconButton label={attachmentAction.label} tone=\"ghost\" disabled={locked || attachmentAction.disabled} onClick={attachmentAction.onPress}>{attachmentAction.icon}</IconButton> : null;\n const send = sendIcon ? <IconButton label={sendLabel} size={sendPresentation === \"circle\" ? \"small\" : \"medium\"} shape=\"circle\" tone={sendPresentation === \"circle\" ? \"primary\" : \"ghost\"} disabled={!canSend} loading={pending} onClick={() => { if (canSend) onSend(value); }}>{sendIcon}</IconButton> : <Button disabled={!canSend} loading={pending} onClick={() => { if (canSend) onSend(value); }}>{sendLabel}</Button>;\n // Readonly pending input preserves the keyboard/focus for receipt failure recovery; disabling it would blur desktop chat.\n // Enter is opt-in and IME-safe; receipt-driven clearing and failed-send recovery belong to the host.\n return <div className=\"hjm-message-composer\" data-send-presentation={sendPresentation} style={{\"--hjm-message-composer-gap\": `${screenPatternRecipe.itemGap}px`, \"--hjm-attachment-size\": `${screenPatternRecipe.attachmentSize}px`, \"--hjm-attachment-remove-size\": `${screenPatternRecipe.attachmentRemoveSize}px`, ...layoutStyle} as React.CSSProperties}>{context}{replyTo ? <Stack axis=\"inline\" gap=\"sm\" align=\"center\"><Stack gap=\"xxs\"><Text variant=\"caption\" emphasis=\"strong\">{replyTo.author}</Text><Text variant=\"caption\" tone=\"muted\">{replyTo.excerpt}</Text></Stack><IconButton label={replyTo.cancelLabel} tone=\"ghost\" disabled={locked} onClick={replyTo.onCancel}><Text>×</Text></IconButton></Stack> : null}\n {attachments.length ? <div className=\"hjm-message-composer__attachments\">{attachments.map(item => <div key={item.id} className=\"hjm-message-composer__attachment\"><div className=\"hjm-message-composer__preview\">{item.preview}</div><span className=\"hjm-message-composer__remove\"><IconButton label={item.removeLabel} tone=\"ghost\" size=\"small\" disabled={locked || item.disabled} onClick={() => { if (!locked && !item.disabled) onRemoveAttachment?.(item.id); }}><span className=\"hjm-message-composer__remove-glyph\" aria-hidden=\"true\">×</span></IconButton></span></div>)}{attach}</div> : null}\n <div className=\"hjm-message-composer__row\"><TextArea ref={inputRef} maxLength={maxLength} leadingAction={leadingAction} shape=\"large\" rows={screenPatternRecipe.composerMinLines} aria-label={label} placeholder={placeholder} description={description} error={error} aria-invalid={invalid || undefined} onBlur={onBlur} value={value} disabled={disabled} readOnly={pending} aria-busy={pending || undefined}\n onKeyDown={event => { if (shouldSubmitMessageKey({key:event.key, shiftKey:event.shiftKey, isComposing:event.nativeEvent.isComposing, keyCode:event.nativeEvent.keyCode}, submitMode)) { event.preventDefault(); if (canSend) onSend(value); } }}\n onChange={event => { if (!locked) onValueChange(event.currentTarget.value); }} minVisibleLines={screenPatternRecipe.composerMinLines} maxVisibleLines={screenPatternRecipe.composerMaxLines}\n {...(sendIcon ? { trailing: hasContent || pending ? send : attach } : {})} />\n {sendIcon ? null : send}\n </div>{lengthFeedback && limit?.near ? <Progress shape=\"circular\" label={lengthFeedback.label} value={Math.min(limit.used, limit.max)} max={limit.max} valueText={lengthFeedback.formatCount(limit.used, limit.max)}><Text variant=\"caption\">{lengthFeedback.formatCount(limit.used, limit.max)}</Text></Progress> : null}</div>;\n}\n\nexport type ChatMessageProps = ChatMessageDescriptor & Readonly<{ children: ReactNode; interactiveContent?: boolean; avatar?: ReactNode; reply?: ReactNode; actions?: ReactNode; replyAction?: Readonly<{label:string; onPress():void; disabled?:boolean}>; replyLink?: Readonly<{label:string; onPress():void}>; reactions?: ReactionPickerProps & Readonly<{ closeLabel: string; menuAction?: Readonly<{ label: string; onPress(): void; disabled?: boolean }> }>;\n /** Canonical layout-only placement on the message row. The swipe offset still owns `transform`. */\n layoutStyle?: HjmCompositionStyleProp }>;\nexport function ChatMessage({ direction, author, timestamp, timestampPresentation = \"always\", bubbleTail = false, deliveryLabel, avatar, reply, actions, replyAction, replyLink, reactions, children, interactiveContent=false, layoutStyle }: ChatMessageProps) {\n const theme = useOptionalHjmTheme();\n const revealTime = timestampPresentation === \"swipe\" && !!timestamp;\n // Only the pointer that began a drag can finish it; another touch must not reply or cancel it.\n const start = useRef<{x:number;y:number;pointerId:number} | null>(null);\n const [offset, setOffset] = useState(0);\n const finish = () => { start.current = null; setOffset(0); };\n return <article tabIndex={replyAction && !replyAction.disabled ? 0 : undefined}\n aria-keyshortcuts={replyAction ? \"Alt+ArrowLeft Alt+ArrowRight\" : undefined} aria-description={replyAction?.label}\n onKeyDown={event => { if (event.target === event.currentTarget && event.altKey && (event.key === \"ArrowLeft\" || event.key === \"ArrowRight\") && replyAction && !replyAction.disabled) { event.preventDefault(); replyAction.onPress(); } }}\n onPointerDown={event => { if (start.current || (!revealTime && (!replyAction || replyAction.disabled)) || event.button !== 0 || (event.target as HTMLElement).closest(\"button,a,input,textarea\")) return; start.current = {x:event.clientX,y:event.clientY,pointerId:event.pointerId}; }}\n onPointerMove={event => { if (!start.current || start.current.pointerId !== event.pointerId) return; const dx=event.clientX-start.current.x,dy=event.clientY-start.current.y; if (Math.abs(dy)>10 && Math.abs(dy)>Math.abs(dx)) {finish();return;} if (revealTime) setOffset((direction === \"outgoing\" ? -1 : 1) * timestampRevealOffset(direction === \"outgoing\" ? -dx : dx,dy)); else if (Math.abs(dx)>Math.abs(dy)*2) setOffset(Math.max(-72,Math.min(72,dx))); }}\n onPointerUp={event => { if (start.current?.pointerId !== event.pointerId) return; if (!revealTime && start.current && replyAction && !replyAction.disabled && isReplySwipe(event.clientX-start.current.x,event.clientY-start.current.y)) replyAction.onPress(); finish(); }} onPointerCancel={event => { if (start.current?.pointerId === event.pointerId) finish(); }} onPointerLeave={event => { if (start.current?.pointerId === event.pointerId) finish(); }}\n style={{ ...layoutStyle, position: \"relative\", overflow: \"hidden\", paddingInline: bubbleTail ? \"var(--hjm-space-xs)\" : undefined, touchAction: revealTime || replyAction ? \"pan-y\" : undefined }} aria-label={author}>\n {revealTime ? <time style={{ position: \"absolute\", ...(direction === \"outgoing\" ? { right: 0, justifyContent: \"flex-end\" } : { left: 0 }), top: 0, bottom: 0, width: 80, display: \"flex\", alignItems: \"center\", opacity: offset !== 0 ? 1 : 0, pointerEvents: \"none\" }}><Text variant=\"caption\" tone=\"muted\">{timestamp}</Text></time> : null}\n <div className=\"hjm-chat-message\" style={{ transform: `translateX(${offset}px)`, transition: start.current || theme?.environment.reducedMotion ? \"none\" : \"transform var(--hjm-motion-normal, 200ms) ease-out\", \"--hjm-message-max-width\": screenPatternRecipe.messageMaxWidth } as React.CSSProperties} data-direction={direction} data-tail={bubbleTail || undefined}>\n {avatar ? <div className=\"hjm-chat-message__avatar\">{avatar}</div> : null}\n <div className=\"hjm-chat-message__content\">{author?<Text variant=\"caption\" tone=\"muted\">{author}</Text>:null}\n {reply && replyLink ? <Button tone=\"ghost\" aria-label={replyLink.label} onClick={replyLink.onPress}>{reply}</Button> : null}\n {reactions ? <MessageReactions {...reactions} interactiveContent={interactiveContent}>{reply && !replyLink ? <div className=\"hjm-chat-message__reply\">{reply}</div> : null}{children}</MessageReactions> : <div className=\"hjm-chat-message__bubble\">{reply && !replyLink ? <div className=\"hjm-chat-message__reply\">{reply}</div> : null}{children}</div>}\n {(!revealTime && timestamp)||deliveryLabel||actions?<div className=\"hjm-chat-message__meta\">{(!revealTime && timestamp)||deliveryLabel?<Text variant=\"caption\" tone=\"muted\">{[revealTime ? \"\" : timestamp, deliveryLabel].filter(Boolean).join(\" · \")}</Text>:null}{actions}</div>:null}\n </div>\n </div>\n </article>;\n}\n"]}
@@ -0,0 +1,52 @@
1
+ import { type ReactNode } from "react";
2
+ import { type FollowProfileState, type AttendanceChoice, type EventAttendanceState } from "@hjmds/design-contracts/social-compositions";
3
+ type Person = Readonly<{
4
+ id: string;
5
+ name: string;
6
+ avatar?: ReactNode;
7
+ }>;
8
+ export type FollowProfileCardProps = Readonly<{
9
+ /** Changing entities remounts the action scope and detaches old responses. */
10
+ profileId: string;
11
+ name: string;
12
+ description?: ReactNode;
13
+ avatar?: ReactNode;
14
+ state: FollowProfileState;
15
+ locale: string;
16
+ labels: Readonly<{
17
+ follow: string;
18
+ following: string;
19
+ pending: string;
20
+ count: string;
21
+ error: string;
22
+ }>;
23
+ /** Resolve only after the real mutation; update state with the server's confirmed snapshot. */
24
+ onFollowChange: (following: boolean) => void | Promise<void>;
25
+ disabled?: boolean;
26
+ }>;
27
+ export declare function FollowProfileCard(props: FollowProfileCardProps): import("react").JSX.Element;
28
+ export type EventAttendanceCardProps = Readonly<{
29
+ eventId: string;
30
+ title: string;
31
+ description?: ReactNode;
32
+ dateLabel: string;
33
+ state: EventAttendanceState;
34
+ choices: readonly AttendanceChoice[];
35
+ participants: readonly Person[];
36
+ locale: string;
37
+ labels: Readonly<{
38
+ response: string;
39
+ pending: string;
40
+ count: string;
41
+ calendar: string;
42
+ calendarAdded: string;
43
+ error: string;
44
+ }>;
45
+ onResponseChange: (responseId: string) => void | Promise<void>;
46
+ /** Actual calendar adapter, including platform permissions; rejection stays retryable. */
47
+ onAddToCalendar: () => void | Promise<void>;
48
+ disabled?: boolean;
49
+ }>;
50
+ export declare function EventAttendanceCard(props: EventAttendanceCardProps): import("react").JSX.Element;
51
+ export {};
52
+ //# sourceMappingURL=social-compositions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"social-compositions.d.ts","sourceRoot":"","sources":["../src/social-compositions.tsx"],"names":[],"mappings":"AACA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACjD,OAAO,EAAoD,KAAK,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,KAAK,oBAAoB,EAAE,MAAM,6CAA6C,CAAC;AAQ1L,KAAK,MAAM,GAAG,QAAQ,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,SAAS,CAAA;CAAE,CAAC,CAAC;AAIzE,MAAM,MAAM,sBAAsB,GAAG,QAAQ,CAAC;IAC5C,8EAA8E;IAC9E,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,SAAS,CAAC;IAAC,MAAM,CAAC,EAAE,SAAS,CAAC;IAC7E,KAAK,EAAE,kBAAkB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAC1C,MAAM,EAAE,QAAQ,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvG,+FAA+F;IAC/F,cAAc,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAClF,CAAC,CAAC;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,+BAG9D;AAgBD,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC9C,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAC3E,KAAK,EAAE,oBAAoB,CAAC;IAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IACnH,MAAM,EAAE,QAAQ,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/H,gBAAgB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/D,0FAA0F;IAC1F,eAAe,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACjE,CAAC,CAAC;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,wBAAwB,+BAGlE"}
@@ -0,0 +1,41 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useState } from "react";
4
+ import { resolveFollowProposal, resolveAttendanceProposal } from "@hjmds/design-contracts/social-compositions";
5
+ import { Button } from "./actions.js";
6
+ import { AnimatedStatistic } from "./statistic-motion.js";
7
+ import { Avatar } from "./advanced-display.js";
8
+ import { Card } from "./display.js";
9
+ import { Stack, Text } from "./layout.js";
10
+ import { useCompositionAction } from "./internal/use-composition-action.js";
11
+ function Failure({ failed, label }) {
12
+ return failed ? _jsx(Text, { role: "alert", style: { textAlign: "center" }, tone: "danger", children: label }) : null;
13
+ }
14
+ export function FollowProfileCard(props) {
15
+ if (!props.profileId.trim())
16
+ throw new TypeError("Follow profile requires a stable id");
17
+ return _jsx(FollowProfileBody, { ...props }, props.profileId);
18
+ }
19
+ function FollowProfileBody(props) {
20
+ resolveFollowProposal(props.state, props.state.following);
21
+ const action = useCompositionAction(props.disabled);
22
+ // Capture the proposal once; changing server counts during the request must not add the delta twice.
23
+ const displayed = action.active ?? props.state;
24
+ return _jsx(Card, { title: props.name, description: props.description, leading: props.avatar ?? _jsx(Avatar, { name: props.name, "aria-hidden": true }), children: _jsxs(Stack, { gap: "md", children: [_jsx(AnimatedStatistic, { descriptor: { id: "social-count", label: props.labels.count }, value: displayed.count, locale: props.locale }), _jsx(Button, { selected: displayed.following, loading: action.pending, "aria-label": action.pending ? props.labels.pending : undefined, disabled: props.disabled === true, onClick: () => { const proposal = resolveFollowProposal(props.state, !props.state.following); void action.run(proposal, () => props.onFollowChange(proposal.following)); }, children: displayed.following ? props.labels.following : props.labels.follow }), _jsx(Failure, { failed: action.failed, label: props.labels.error })] }) });
25
+ }
26
+ export function EventAttendanceCard(props) {
27
+ if (!props.eventId.trim())
28
+ throw new TypeError("Event attendance requires a stable id");
29
+ return _jsx(EventAttendanceBody, { ...props }, props.eventId);
30
+ }
31
+ function EventAttendanceBody(props) {
32
+ resolveAttendanceProposal(props.state, props.choices, props.state.responseId);
33
+ const action = useCompositionAction(props.disabled), [calendarAdded, setCalendarAdded] = useState(false);
34
+ const displayed = action.active === null || action.active === "calendar" ? props.state : action.active;
35
+ const locked = props.disabled === true || action.pending;
36
+ return _jsx(Card, { title: props.title, description: props.description, children: _jsxs(Stack, { gap: "md", children: [_jsx(Text, { children: props.dateLabel }), _jsx(AnimatedStatistic, { descriptor: { id: "social-count", label: props.labels.count }, value: displayed.count, locale: props.locale }), _jsx(Stack, { axis: "inline", gap: "xs", wrap: true, children: props.participants.map(person => _jsxs(Stack, { axis: "inline", gap: "xs", children: [person.avatar ?? _jsx(Avatar, { name: person.name, "aria-hidden": true }), _jsx(Text, { children: person.name })] }, person.id)) }), _jsx(Text, { emphasis: "strong", children: props.labels.response }), _jsx(Stack, { axis: "inline", gap: "xs", wrap: true, children: props.choices.map(choice => _jsx(Button, { selected: displayed.responseId === choice.id, disabled: locked || choice.disabled === true, loading: action.pending && action.active !== "calendar" && displayed.responseId === choice.id, "aria-label": action.pending ? props.labels.pending : undefined, onClick: () => { if (choice.disabled || choice.id === props.state.responseId)
37
+ return; const proposal = resolveAttendanceProposal(props.state, props.choices, choice.id); void action.run(proposal, () => props.onResponseChange(choice.id)); }, children: choice.label }, choice.id)) }), _jsx(Button, { tone: "secondary", disabled: locked || calendarAdded, loading: action.active === "calendar", "aria-label": action.pending ? props.labels.pending : undefined, onClick: () => { if (calendarAdded)
38
+ return; void action.run("calendar", props.onAddToCalendar).then(outcome => { if (outcome.status === "success")
39
+ setCalendarAdded(true); }); }, children: calendarAdded ? props.labels.calendarAdded : props.labels.calendar }), _jsx(Failure, { failed: action.failed, label: props.labels.error })] }) });
40
+ }
41
+ //# sourceMappingURL=social-compositions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"social-compositions.js","sourceRoot":"","sources":["../src/social-compositions.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\nimport { useState, type ReactNode } from \"react\";\nimport { resolveFollowProposal, resolveAttendanceProposal, type FollowProfileState, type AttendanceChoice, type EventAttendanceState } from \"@hjmds/design-contracts/social-compositions\";\nimport { Button } from \"./actions.js\";\nimport { AnimatedStatistic } from \"./statistic-motion.js\";\nimport { Avatar } from \"./advanced-display.js\";\nimport { Card } from \"./display.js\";\nimport { Stack, Text } from \"./layout.js\";\nimport { useCompositionAction } from \"./internal/use-composition-action.js\";\n\ntype Person = Readonly<{ id: string; name: string; avatar?: ReactNode }>;\nfunction Failure({ failed, label }: Readonly<{ failed: boolean; label: string }>) {\n return failed ? <Text role=\"alert\" style={{ textAlign: \"center\" }} tone=\"danger\">{label}</Text> : null;\n}\nexport type FollowProfileCardProps = Readonly<{\n /** Changing entities remounts the action scope and detaches old responses. */\n profileId: string; name: string; description?: ReactNode; avatar?: ReactNode;\n state: FollowProfileState; locale: string;\n labels: Readonly<{ follow: string; following: string; pending: string; count: string; error: string }>;\n /** Resolve only after the real mutation; update state with the server's confirmed snapshot. */\n onFollowChange: (following: boolean) => void | Promise<void>; disabled?: boolean;\n}>;\nexport function FollowProfileCard(props: FollowProfileCardProps) {\n if (!props.profileId.trim()) throw new TypeError(\"Follow profile requires a stable id\");\n return <FollowProfileBody key={props.profileId} {...props} />;\n}\nfunction FollowProfileBody(props: FollowProfileCardProps) {\n resolveFollowProposal(props.state, props.state.following);\n const action = useCompositionAction<FollowProfileState>(props.disabled);\n // Capture the proposal once; changing server counts during the request must not add the delta twice.\n const displayed: FollowProfileState = action.active ?? props.state;\n return <Card title={props.name} description={props.description} leading={props.avatar ?? <Avatar name={props.name} aria-hidden />}>\n <Stack gap=\"md\"><AnimatedStatistic descriptor={{ id: \"social-count\", label: props.labels.count }} value={displayed.count} locale={props.locale} />\n <Button selected={displayed.following} loading={action.pending} aria-label={action.pending ? props.labels.pending : undefined} disabled={props.disabled === true}\n onClick={() => { const proposal = resolveFollowProposal(props.state, !props.state.following); void action.run(proposal, () => props.onFollowChange(proposal.following)); }}>\n {displayed.following ? props.labels.following : props.labels.follow}\n </Button><Failure failed={action.failed} label={props.labels.error} />\n </Stack>\n </Card>;\n}\n\nexport type EventAttendanceCardProps = Readonly<{\n eventId: string; title: string; description?: ReactNode; dateLabel: string;\n state: EventAttendanceState; choices: readonly AttendanceChoice[]; participants: readonly Person[]; locale: string;\n labels: Readonly<{ response: string; pending: string; count: string; calendar: string; calendarAdded: string; error: string }>;\n onResponseChange: (responseId: string) => void | Promise<void>;\n /** Actual calendar adapter, including platform permissions; rejection stays retryable. */\n onAddToCalendar: () => void | Promise<void>; disabled?: boolean;\n}>;\nexport function EventAttendanceCard(props: EventAttendanceCardProps) {\n if (!props.eventId.trim()) throw new TypeError(\"Event attendance requires a stable id\");\n return <EventAttendanceBody key={props.eventId} {...props} />;\n}\nfunction EventAttendanceBody(props: EventAttendanceCardProps) {\n resolveAttendanceProposal(props.state, props.choices, props.state.responseId);\n const action = useCompositionAction<EventAttendanceState | \"calendar\">(props.disabled), [calendarAdded, setCalendarAdded] = useState(false);\n const displayed: EventAttendanceState = action.active === null || action.active === \"calendar\" ? props.state : action.active;\n const locked = props.disabled === true || action.pending;\n return <Card title={props.title} description={props.description}><Stack gap=\"md\">\n <Text>{props.dateLabel}</Text>\n <AnimatedStatistic descriptor={{ id: \"social-count\", label: props.labels.count }} value={displayed.count} locale={props.locale} />\n <Stack axis=\"inline\" gap=\"xs\" wrap>{props.participants.map(person => <Stack key={person.id} axis=\"inline\" gap=\"xs\">{person.avatar ?? <Avatar name={person.name} aria-hidden />}<Text>{person.name}</Text></Stack>)}</Stack>\n <Text emphasis=\"strong\">{props.labels.response}</Text>\n <Stack axis=\"inline\" gap=\"xs\" wrap>{props.choices.map(choice => <Button key={choice.id} selected={displayed.responseId === choice.id}\n disabled={locked || choice.disabled === true} loading={action.pending && action.active !== \"calendar\" && displayed.responseId === choice.id} aria-label={action.pending ? props.labels.pending : undefined}\n onClick={() => { if (choice.disabled || choice.id === props.state.responseId) return; const proposal = resolveAttendanceProposal(props.state, props.choices, choice.id); void action.run(proposal, () => props.onResponseChange(choice.id)); }}>{choice.label}</Button>)}</Stack>\n <Button tone=\"secondary\" disabled={locked || calendarAdded} loading={action.active === \"calendar\"} aria-label={action.pending ? props.labels.pending : undefined}\n onClick={() => { if (calendarAdded) return; void action.run(\"calendar\", props.onAddToCalendar).then(outcome => { if (outcome.status === \"success\") setCalendarAdded(true); }); }}>{calendarAdded ? props.labels.calendarAdded : props.labels.calendar}</Button>\n <Failure failed={action.failed} label={props.labels.error} />\n </Stack></Card>;\n}\n"]}
@@ -0,0 +1,24 @@
1
+ import { type ReactNode } from "react";
2
+ import { type AnswerStreamEvent, type AnswerGenerationContext } from "@hjmds/design-contracts/streaming-answer";
3
+ export type StreamingAnswerProps = Readonly<{
4
+ answerId: string;
5
+ initialText?: string;
6
+ label: string;
7
+ onGenerate: (context: AnswerGenerationContext) => AsyncIterable<AnswerStreamEvent> | Promise<AsyncIterable<AnswerStreamEvent>>;
8
+ labels: Readonly<{
9
+ generate: string;
10
+ regenerate: string;
11
+ stop: string;
12
+ thinking: string;
13
+ streaming: string;
14
+ stopping: string;
15
+ complete: string;
16
+ stopped: string;
17
+ error: string;
18
+ }>;
19
+ thinkingIndicator?: ReactNode;
20
+ renderText?: (text: string) => ReactNode;
21
+ disabled?: boolean;
22
+ }>;
23
+ export declare function StreamingAnswer(props: StreamingAnswerProps): import("react").JSX.Element;
24
+ //# sourceMappingURL=streaming-answer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming-answer.d.ts","sourceRoot":"","sources":["../src/streaming-answer.tsx"],"names":[],"mappings":"AACA,OAAO,EAA+B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACpE,OAAO,EAAuB,KAAK,iBAAiB,EAAE,KAAK,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AAKrI,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,QAAQ,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IACtD,UAAU,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,aAAa,CAAC,iBAAiB,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAC/H,MAAM,EAAE,QAAQ,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClL,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAAC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7F,CAAC,CAAC;AAEH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,+BAG1D"}
@@ -0,0 +1,57 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useRef, useState } from "react";
4
+ import { consumeAnswerStream } from "@hjmds/design-contracts/streaming-answer";
5
+ import { Button } from "./actions.js";
6
+ import { Progress } from "./feedback.js";
7
+ import { Stack, Text } from "./layout.js";
8
+ import { useCompositionAction } from "./internal/use-composition-action.js";
9
+ export function StreamingAnswer(props) {
10
+ if (!props.answerId.trim())
11
+ throw new TypeError("Streaming answers require a stable id");
12
+ return _jsx(AnswerBody, { ...props }, props.answerId);
13
+ }
14
+ function AnswerBody(props) {
15
+ const [text, setText] = useState(props.initialText ?? ""), [phase, setPhase] = useState(props.initialText ? "complete" : "idle");
16
+ const action = useCompositionAction(props.disabled), request = useRef(null), mounted = useRef(true), disabled = useRef(props.disabled), requestWasRegenerate = useRef(false);
17
+ disabled.current = props.disabled;
18
+ useEffect(() => { mounted.current = true; return () => { mounted.current = false; request.current?.abort(); request.current = null; }; }, []);
19
+ const generate = () => {
20
+ if (!mounted.current || disabled.current || request.current)
21
+ return;
22
+ const controller = new AbortController();
23
+ request.current = controller;
24
+ const previousText = text, regenerate = phase !== "idle";
25
+ requestWasRegenerate.current = regenerate;
26
+ setPhase("thinking");
27
+ const current = () => mounted.current && request.current === controller;
28
+ void action.run("generate", async () => {
29
+ try {
30
+ const source = await props.onGenerate({ signal: controller.signal, previousText, regenerate });
31
+ const result = await consumeAnswerStream(source, controller.signal, previousText, value => { if (current()) {
32
+ setText(value);
33
+ setPhase("streaming");
34
+ } });
35
+ if (current()) {
36
+ setText(result.text);
37
+ setPhase(result.phase);
38
+ }
39
+ }
40
+ catch (error) {
41
+ const aborted = controller.signal.aborted && error && typeof error === "object" && "name" in error && error.name === "AbortError";
42
+ if (current())
43
+ setPhase(aborted ? "stopped" : "error");
44
+ throw error;
45
+ }
46
+ }).then(() => { if (request.current === controller)
47
+ request.current = null; });
48
+ };
49
+ const stop = () => { if (mounted.current && !disabled.current && request.current && !request.current.signal.aborted) {
50
+ setPhase("stopping");
51
+ request.current.abort();
52
+ } };
53
+ const pending = action.pending;
54
+ const status = phase === "idle" ? null : props.labels[phase];
55
+ return _jsxs(Stack, { gap: "md", children: [_jsx(Text, { emphasis: "strong", children: props.label }), text ? (props.renderText ? props.renderText(text) : _jsx(Text, { style: { whiteSpace: "pre-wrap", overflowWrap: "anywhere" }, children: text })) : null, phase === "thinking" ? _jsx(Stack, { align: "center", justify: "center", children: props.thinkingIndicator ?? _jsx(Progress, { label: props.labels.thinking }) }) : null, _jsxs(Stack, { axis: "inline", gap: "sm", wrap: true, children: [_jsx(Button, { loading: pending, disabled: props.disabled === true, onClick: generate, children: (pending ? requestWasRegenerate.current : phase !== "idle") ? props.labels.regenerate : props.labels.generate }), pending ? _jsx(Button, { tone: "secondary", disabled: props.disabled === true || phase === "stopping", onClick: stop, children: props.labels.stop }) : null] }), status && phase !== "thinking" ? _jsx(Text, { role: phase === "error" ? "alert" : "status", style: { textAlign: "center" }, tone: phase === "error" ? "danger" : "primary", children: status }) : null] });
56
+ }
57
+ //# sourceMappingURL=streaming-answer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming-answer.js","sourceRoot":"","sources":["../src/streaming-answer.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\nimport { useEffect, useRef, useState, type ReactNode } from \"react\";\nimport { consumeAnswerStream, type AnswerStreamEvent, type AnswerGenerationContext } from \"@hjmds/design-contracts/streaming-answer\";\nimport { Button } from \"./actions.js\";\nimport { Progress } from \"./feedback.js\";\nimport { Stack, Text } from \"./layout.js\";\nimport { useCompositionAction } from \"./internal/use-composition-action.js\";\nexport type StreamingAnswerProps = Readonly<{\n answerId: string; initialText?: string; label: string;\n onGenerate: (context: AnswerGenerationContext) => AsyncIterable<AnswerStreamEvent> | Promise<AsyncIterable<AnswerStreamEvent>>;\n labels: Readonly<{ generate: string; regenerate: string; stop: string; thinking: string; streaming: string; stopping: string; complete: string; stopped: string; error: string }>;\n thinkingIndicator?: ReactNode; renderText?: (text: string) => ReactNode; disabled?: boolean;\n}>;\ntype Phase = \"idle\" | \"thinking\" | \"streaming\" | \"stopping\" | \"complete\" | \"stopped\" | \"error\";\nexport function StreamingAnswer(props: StreamingAnswerProps) {\n if (!props.answerId.trim()) throw new TypeError(\"Streaming answers require a stable id\");\n return <AnswerBody key={props.answerId} {...props} />;\n}\nfunction AnswerBody(props: StreamingAnswerProps) {\n const [text, setText] = useState(props.initialText ?? \"\"), [phase, setPhase] = useState<Phase>(props.initialText ? \"complete\" : \"idle\");\n const action = useCompositionAction(props.disabled), request = useRef<AbortController | null>(null), mounted = useRef(true), disabled = useRef(props.disabled), requestWasRegenerate = useRef(false);\n disabled.current = props.disabled;\n useEffect(() => { mounted.current = true; return () => { mounted.current = false; request.current?.abort(); request.current = null; }; }, []);\n const generate = () => {\n if (!mounted.current || disabled.current || request.current) return;\n const controller = new AbortController(); request.current = controller;\n const previousText = text, regenerate = phase !== \"idle\"; requestWasRegenerate.current = regenerate;\n setPhase(\"thinking\");\n const current = () => mounted.current && request.current === controller;\n void action.run(\"generate\", async () => {\n try {\n const source = await props.onGenerate({ signal: controller.signal, previousText, regenerate });\n const result = await consumeAnswerStream(source, controller.signal, previousText, value => { if (current()) { setText(value); setPhase(\"streaming\"); } });\n if (current()) { setText(result.text); setPhase(result.phase); }\n } catch (error) {\n const aborted = controller.signal.aborted && error && typeof error === \"object\" && \"name\" in error && error.name === \"AbortError\";\n if (current()) setPhase(aborted ? \"stopped\" : \"error\");\n throw error;\n }\n }).then(() => { if (request.current === controller) request.current = null; });\n };\n const stop = () => { if (mounted.current && !disabled.current && request.current && !request.current.signal.aborted) { setPhase(\"stopping\"); request.current.abort(); } };\n const pending = action.pending;\n const status = phase === \"idle\" ? null : props.labels[phase];\n return <Stack gap=\"md\"><Text emphasis=\"strong\">{props.label}</Text>\n {text ? (props.renderText ? props.renderText(text) : <Text style={{ whiteSpace: \"pre-wrap\", overflowWrap: \"anywhere\" }}>{text}</Text>) : null}\n {phase === \"thinking\" ? <Stack align=\"center\" justify=\"center\">{props.thinkingIndicator ?? <Progress label={props.labels.thinking} />}</Stack> : null}\n <Stack axis=\"inline\" gap=\"sm\" wrap><Button loading={pending} disabled={props.disabled === true} onClick={generate}>{(pending ? requestWasRegenerate.current : phase !== \"idle\") ? props.labels.regenerate : props.labels.generate}</Button>\n {pending ? <Button tone=\"secondary\" disabled={props.disabled === true || phase === \"stopping\"} onClick={stop}>{props.labels.stop}</Button> : null}</Stack>\n {status && phase !== \"thinking\" ? <Text role={phase === \"error\" ? \"alert\" : \"status\"} style={{ textAlign: \"center\" }} tone={phase === \"error\" ? \"danger\" : \"primary\"}>{status}</Text> : null}\n </Stack>;\n}\n"]}
package/dist/styles.css CHANGED
@@ -1218,6 +1218,149 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
1218
1218
  .hjm-data-table__table tr[data-disabled] { color: var(--hjm-color-text-weak); }
1219
1219
  .hjm-data-table__state { margin: 0; color: var(--hjm-color-text-muted); }
1220
1220
  .hjm-data-table__footer { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--hjm-space-sm); }
1221
+ /* Pinned start columns (2026-10-14): the table scrolls inside its own box so sticky cells have a
1222
+ scroll container; pinned cells paint the canvas so scrolled text never shows through. */
1223
+ .hjm-data-table__scroll { overflow-x: auto; min-inline-size: 0; }
1224
+ .hjm-data-table__scroll > .hjm-data-table__table { inline-size: max-content; min-inline-size: 100%; }
1225
+ .hjm-data-table__table .hjm-data-table__pinned { position: sticky; z-index: 1; background: var(--hjm-color-bg); }
1226
+ .hjm-data-table__table .hjm-data-table__pinned-edge { box-shadow: inset -1px 0 0 var(--hjm-color-border); }
1227
+ .hjm-data-table__table .hjm-data-table__pinned-edge:dir(rtl) { box-shadow: inset 1px 0 0 var(--hjm-color-border); }
1228
+ .hjm-data-table__table tfoot td { border-block-start: 1px solid var(--hjm-color-border); border-block-end: 0; font-weight: var(--hjm-font-weight-semibold); }
1229
+
1230
+ /* DataTable family (2026-10-14): header bands, row groups, sub-row indent, tone/heat, bounded
1231
+ height. Colors mirror dataTableFamilyRecipe; heat is a background-image so pinned cells keep
1232
+ their opaque canvas under the tint. */
1233
+ .hjm-data-table__bands > th,
1234
+ .hjm-data-table__bands > td { padding-block-end: 0; border-block-end: 0; }
1235
+ .hjm-data-table__band { text-align: center; color: var(--hjm-color-text-muted); font-size: var(--hjm-type-label-size); }
1236
+ .hjm-data-table__band > span { display: block; padding-block-end: var(--hjm-space-xxs); border-block-end: 1px solid color-mix(in srgb, var(--hjm-color-border) 70%, transparent); }
1237
+ .hjm-data-table__group > th {
1238
+ padding-block: var(--hjm-space-xs);
1239
+ background: var(--hjm-color-surface-alt);
1240
+ color: var(--hjm-color-text-muted);
1241
+ font-size: var(--hjm-type-label-size);
1242
+ font-weight: var(--hjm-font-weight-bold);
1243
+ text-align: start;
1244
+ }
1245
+ /* The label stays in view while a wide table scrolls sideways. */
1246
+ .hjm-data-table__group > th > span { position: sticky; inset-inline-start: var(--hjm-space-md); }
1247
+ .hjm-data-table__table td[data-depth] { padding-inline-start: calc(var(--hjm-space-md) + var(--hjm-data-table-indent, 0px)); }
1248
+ .hjm-data-table[data-density="compact"] .hjm-data-table__table td[data-depth] { padding-inline-start: calc(var(--hjm-space-sm) + var(--hjm-data-table-indent, 0px)); }
1249
+ .hjm-table-family__heat { background-image: linear-gradient(var(--hjm-data-table-heat), var(--hjm-data-table-heat)); }
1250
+ .hjm-data-table__table td[data-tone], .hjm-data-table__table td[data-heat] { font-variant-numeric: tabular-nums; }
1251
+ .hjm-data-table__scroll[data-bounded] { overflow: auto; }
1252
+ /* Sticky thead (not each th) keeps band and leaf rows stacked without measuring the band height. */
1253
+ .hjm-data-table__scroll[data-bounded] thead { position: sticky; inset-block-start: 0; z-index: 2; background: var(--hjm-color-bg); box-shadow: inset 0 -1px 0 var(--hjm-color-border); }
1254
+
1255
+ /* LineScore / MatrixTable / ComparisonTable ---------------------------------- */
1256
+ .hjm-table-family { min-inline-size: 0; overflow-x: auto; border-radius: var(--hjm-radius-md); background: var(--hjm-color-surface); }
1257
+ .hjm-line-score__table, .hjm-matrix-table__table { inline-size: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
1258
+ .hjm-line-score__table th, .hjm-line-score__table td { padding: var(--hjm-space-xs) var(--hjm-space-xxs); text-align: center; white-space: nowrap; }
1259
+ .hjm-line-score__table thead th { color: var(--hjm-color-text-muted); font-size: var(--hjm-type-label-size); font-weight: var(--hjm-font-weight-bold); }
1260
+ .hjm-line-score__table th.hjm-line-score__team { padding-inline: var(--hjm-space-sm); text-align: start; color: var(--hjm-color-text-muted); font-weight: var(--hjm-font-weight-semibold); }
1261
+ .hjm-line-score__team-content { display: inline-flex; align-items: center; gap: var(--hjm-space-xs); }
1262
+ .hjm-line-score__table tr[data-leader] th.hjm-line-score__team { color: var(--hjm-color-text); font-weight: var(--hjm-font-weight-bold); }
1263
+ .hjm-line-score__table td.hjm-line-score__period { min-inline-size: 26px; color: var(--hjm-color-text-sub); }
1264
+ .hjm-line-score__table td[data-scored] { color: var(--hjm-color-text); font-weight: var(--hjm-font-weight-bold); }
1265
+ .hjm-line-score__table [data-current] { background: var(--hjm-table-family-selected); }
1266
+ .hjm-line-score__table th[data-current] { color: var(--hjm-color-content-brand); }
1267
+ .hjm-line-score__total { min-inline-size: 30px; color: var(--hjm-color-text-muted); font-weight: var(--hjm-font-weight-semibold); }
1268
+ .hjm-line-score__total-edge { border-inline-start: 1px solid var(--hjm-color-border); }
1269
+ .hjm-line-score__table tbody .hjm-line-score__total-edge { color: var(--hjm-color-text); font-weight: var(--hjm-font-weight-bold); }
1270
+ .hjm-matrix-table__table th, .hjm-matrix-table__table td { padding: var(--hjm-space-xs); text-align: center; white-space: nowrap; border-block-start: 1px solid var(--hjm-color-border); }
1271
+ .hjm-matrix-table__table thead th { border-block-start: 0; color: var(--hjm-color-text-muted); font-size: var(--hjm-type-label-size); font-weight: var(--hjm-font-weight-bold); }
1272
+ .hjm-matrix-table__table tbody th { text-align: start; padding-inline: var(--hjm-space-sm); color: var(--hjm-color-text); font-weight: var(--hjm-font-weight-bold); border-inline-end: 1px solid var(--hjm-color-border); }
1273
+ .hjm-matrix-table__table td { color: var(--hjm-color-text-muted); }
1274
+ .hjm-matrix-table__table thead td { border-block-start: 0; }
1275
+ .hjm-matrix-table__self { background: var(--hjm-color-surface-alt); }
1276
+ .hjm-matrix-table__table tr[data-highlighted] > * { background-color: var(--hjm-table-family-selected); }
1277
+ .hjm-comparison-table { padding-block: var(--hjm-space-xs); }
1278
+ .hjm-comparison-table__sides { display: flex; justify-content: space-between; padding: var(--hjm-space-xs) var(--hjm-space-md); font-weight: var(--hjm-font-weight-bold); }
1279
+ .hjm-comparison-table__rows { margin: 0; padding: 0; list-style: none; }
1280
+ .hjm-comparison-table__row { display: grid; gap: var(--hjm-space-xxs); padding: var(--hjm-space-xs) var(--hjm-space-md); border-block-start: 1px solid var(--hjm-color-border); }
1281
+ .hjm-comparison-table__values { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: var(--hjm-space-sm); font-variant-numeric: tabular-nums; color: var(--hjm-color-text-sub); }
1282
+ .hjm-comparison-table__values > :last-child { text-align: end; }
1283
+ .hjm-comparison-table__values > [data-win] { color: var(--hjm-color-text); font-weight: var(--hjm-font-weight-bold); }
1284
+ .hjm-comparison-table__label { color: var(--hjm-color-text-muted); font-size: var(--hjm-type-label-size); }
1285
+ .hjm-comparison-table__bars { display: grid; grid-template-columns: 1fr 1fr; gap: var(--hjm-space-xs); block-size: 4px; }
1286
+ .hjm-comparison-table__track { display: flex; justify-content: flex-end; border-radius: 2px; background: var(--hjm-color-surface-alt); overflow: hidden; }
1287
+ .hjm-comparison-table__track[data-side="1"] { justify-content: flex-start; }
1288
+ .hjm-comparison-table__bar { display: block; block-size: 100%; border-radius: 2px; }
1289
+
1290
+ /* Chart ------------------------------------------------------------------- */
1291
+ /* Colors come from chartRecipe.chrome via --hjm-chart-* set inline by the renderer (2026-10-14). */
1292
+ .hjm-chart { position: relative; display: flex; flex-direction: column; gap: var(--hjm-space-xs); inline-size: 100%; min-inline-size: 0; }
1293
+ .hjm-chart__plot {
1294
+ position: relative;
1295
+ /* Horizontal drags scrub; vertical drags keep scrolling the page. */
1296
+ touch-action: pan-y;
1297
+ user-select: none;
1298
+ -webkit-user-select: none;
1299
+ border-radius: var(--hjm-radius-sm);
1300
+ outline: none;
1301
+ }
1302
+ .hjm-chart__plot:focus-visible { outline: var(--hjm-focus-width) solid var(--hjm-color-focus); outline-offset: var(--hjm-focus-offset); }
1303
+ .hjm-chart svg, .hjm-sparkline { display: block; overflow: visible; }
1304
+ .hjm-chart__grid { stroke: var(--hjm-chart-grid-line); stroke-width: var(--hjm-chart-grid-width); }
1305
+ .hjm-chart__reference { stroke: var(--hjm-chart-axis-label); stroke-width: 1; }
1306
+ .hjm-chart__cursor { stroke: var(--hjm-chart-axis-label); }
1307
+ .hjm-chart__dot { stroke: var(--hjm-color-bg); }
1308
+ .hjm-chart__label { fill: var(--hjm-chart-axis-label); font-family: inherit; font-size: var(--hjm-type-caption-size); }
1309
+ .hjm-chart__label[data-focused], .hjm-chart__axis-name, .hjm-chart__value { fill: var(--hjm-chart-legend-label); font-weight: var(--hjm-font-weight-semibold); }
1310
+ .hjm-chart__extreme { font-weight: var(--hjm-font-weight-semibold); }
1311
+ .hjm-chart__bubble {
1312
+ position: absolute;
1313
+ inset-block-start: 0;
1314
+ transform: translateX(-50%);
1315
+ padding: 2px var(--hjm-space-xs);
1316
+ border: 1px solid var(--hjm-chart-tooltip-border);
1317
+ border-radius: var(--hjm-radius-sm);
1318
+ background: var(--hjm-chart-tooltip-surface);
1319
+ color: var(--hjm-chart-tooltip-content);
1320
+ font-size: var(--hjm-type-caption-size);
1321
+ line-height: var(--hjm-type-caption-line-height);
1322
+ font-weight: var(--hjm-font-weight-bold);
1323
+ white-space: nowrap;
1324
+ pointer-events: none;
1325
+ }
1326
+ .hjm-chart__pie, .hjm-chart__radar { position: relative; align-self: center; }
1327
+ .hjm-chart__pie-center { position: absolute; inset: 0; display: grid; place-items: center; text-align: center; pointer-events: none; }
1328
+ .hjm-chart__slice[role="button"], .hjm-chart--pie .hjm-chart__slice[data-id] { cursor: pointer; }
1329
+ .hjm-chart__slice:focus-visible { outline: none; stroke: var(--hjm-color-focus); stroke-width: var(--hjm-focus-width); }
1330
+ .hjm-chart__slice-label { fill: #ffffff; font-family: inherit; font-size: var(--hjm-type-caption-size); font-weight: var(--hjm-font-weight-bold); }
1331
+ .hjm-chart__axis-titles { display: flex; justify-content: space-between; color: var(--hjm-chart-axis-label); font-size: var(--hjm-type-caption-size); line-height: var(--hjm-type-caption-line-height); }
1332
+ .hjm-chart-legend {
1333
+ display: flex;
1334
+ flex-wrap: wrap;
1335
+ gap: var(--hjm-space-xxs) var(--hjm-space-md);
1336
+ margin: 0;
1337
+ padding: 0;
1338
+ list-style: none;
1339
+ color: var(--hjm-chart-legend-label);
1340
+ font-size: var(--hjm-type-label-size);
1341
+ line-height: var(--hjm-type-label-line-height);
1342
+ }
1343
+ .hjm-chart-legend[data-interactive] { flex-direction: column; flex-wrap: nowrap; }
1344
+ .hjm-chart-legend__item, .hjm-chart-legend__button { display: flex; align-items: center; gap: var(--hjm-space-xs); }
1345
+ .hjm-chart-legend__item[data-dimmed] { opacity: 0.5; }
1346
+ .hjm-chart-legend__button {
1347
+ position: relative;
1348
+ flex: 1;
1349
+ min-block-size: var(--hjm-control-min-touch-target);
1350
+ padding: 0 var(--hjm-space-xs);
1351
+ border: 0;
1352
+ border-radius: var(--hjm-radius-sm);
1353
+ background: transparent;
1354
+ color: inherit;
1355
+ font: inherit;
1356
+ text-align: start;
1357
+ cursor: pointer;
1358
+ }
1359
+ .hjm-chart-legend__button[aria-pressed="true"] { background: var(--hjm-color-surface); }
1360
+ .hjm-chart-legend__button:focus-visible { outline: var(--hjm-focus-width) solid var(--hjm-color-focus); outline-offset: var(--hjm-focus-offset); }
1361
+ .hjm-chart-legend__swatch { flex: none; inline-size: 10px; block-size: 10px; border-radius: 3px; }
1362
+ .hjm-chart-legend[data-interactive] .hjm-chart-legend__label { flex: 1; }
1363
+ .hjm-chart-legend__value { font-weight: var(--hjm-font-weight-bold); font-variant-numeric: tabular-nums; }
1221
1364
 
1222
1365
  /* Mentions ---------------------------------------------------------------- */
1223
1366
  /*
@@ -2695,7 +2838,7 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
2695
2838
  .hjm-date-picker__calendar-close:focus-visible { outline: 2px solid var(--hjm-color-focus); outline-offset: 2px; }
2696
2839
 
2697
2840
  /* Reserve a common annotation row; dates with a dot must not sit above their neighbours. */
2698
- .hjm-calendar__day-label { display: grid; place-items: center; inline-size: var(--hjm-calendar-cell-size); min-block-size: var(--hjm-calendar-cell-size); border: 1px solid transparent; border-radius: var(--hjm-radius-full); }
2841
+ .hjm-calendar__day-label { display: grid; place-items: center; inline-size: var(--hjm-calendar-indicator-size, var(--hjm-calendar-cell-size)); min-block-size: var(--hjm-calendar-indicator-size, var(--hjm-calendar-cell-size)); border: 1px solid transparent; border-radius: var(--hjm-radius-full); }
2699
2842
 
2700
2843
  .hjm-calendar__day-label { font-size: var(--hjm-type-body-size); line-height: var(--hjm-type-body-line-height); }
2701
2844
  .hjm-calendar[data-size="large"] .hjm-calendar__day-label { font-size: var(--hjm-type-body-large-size); line-height: var(--hjm-type-body-large-line-height); }