@santi020k/lumen-react 3.0.0 → 4.0.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/README.md +666 -13
- package/dist/ai-surfaces.d.ts +49 -0
- package/dist/ai-surfaces.d.ts.map +1 -0
- package/dist/ai-surfaces.js +88 -0
- package/dist/amount-field.d.ts +11 -0
- package/dist/amount-field.d.ts.map +1 -0
- package/dist/amount-field.js +37 -0
- package/dist/attachments.d.ts +17 -0
- package/dist/attachments.d.ts.map +1 -0
- package/dist/attachments.js +23 -0
- package/dist/bullet-chart.d.ts +14 -0
- package/dist/bullet-chart.d.ts.map +1 -0
- package/dist/bullet-chart.js +22 -0
- package/dist/change-summary.d.ts +14 -0
- package/dist/change-summary.d.ts.map +1 -0
- package/dist/change-summary.js +4 -0
- package/dist/chart-inspection.d.ts +10 -0
- package/dist/chart-inspection.d.ts.map +1 -0
- package/dist/chart-inspection.js +11 -0
- package/dist/chart-interaction.d.ts +17 -0
- package/dist/chart-interaction.d.ts.map +1 -0
- package/dist/chart-interaction.js +50 -0
- package/dist/chart-label.d.ts +3 -0
- package/dist/chart-label.d.ts.map +1 -0
- package/dist/chart-label.js +1 -0
- package/dist/chart-recipes.d.ts +8 -0
- package/dist/chart-recipes.d.ts.map +1 -1
- package/dist/chart-recipes.js +35 -0
- package/dist/combobox.d.ts +9 -0
- package/dist/combobox.d.ts.map +1 -0
- package/dist/combobox.js +137 -0
- package/dist/comparison-chart.d.ts +13 -0
- package/dist/comparison-chart.d.ts.map +1 -0
- package/dist/comparison-chart.js +18 -0
- package/dist/components.d.ts +106 -70
- package/dist/components.d.ts.map +1 -1
- package/dist/components.js +4 -1947
- package/dist/dashboard.d.ts +20 -0
- package/dist/dashboard.d.ts.map +1 -0
- package/dist/dashboard.js +19 -0
- package/dist/data-table-range-model.d.ts +8 -0
- package/dist/data-table-range-model.d.ts.map +1 -0
- package/dist/data-table-range-model.js +31 -0
- package/dist/data-table-range.d.ts +17 -0
- package/dist/data-table-range.d.ts.map +1 -0
- package/dist/data-table-range.js +8 -0
- package/dist/data-table-saved-views.d.ts +30 -0
- package/dist/data-table-saved-views.d.ts.map +1 -0
- package/dist/data-table-saved-views.js +49 -0
- package/dist/data-table-selection-model.d.ts +23 -0
- package/dist/data-table-selection-model.d.ts.map +1 -0
- package/dist/data-table-selection-model.js +36 -0
- package/dist/data-table-selection.d.ts +11 -0
- package/dist/data-table-selection.d.ts.map +1 -0
- package/dist/data-table-selection.js +10 -0
- package/dist/data-table-state.d.ts +6 -0
- package/dist/data-table-state.d.ts.map +1 -0
- package/dist/data-table-state.js +38 -0
- package/dist/data-table-view.d.ts +88 -0
- package/dist/data-table-view.d.ts.map +1 -0
- package/dist/data-table-view.js +1 -0
- package/dist/data-table.d.ts +60 -0
- package/dist/data-table.d.ts.map +1 -0
- package/dist/data-table.js +1 -0
- package/dist/date-range-calendar.d.ts +29 -0
- package/dist/date-range-calendar.d.ts.map +1 -0
- package/dist/date-range-calendar.js +69 -0
- package/dist/date-range-input.d.ts +25 -0
- package/dist/date-range-input.d.ts.map +1 -0
- package/dist/date-range-input.js +195 -0
- package/dist/device-frame.d.ts +13 -0
- package/dist/device-frame.d.ts.map +1 -0
- package/dist/device-frame.js +23 -0
- package/dist/dialog-lifecycle.d.ts +3 -0
- package/dist/dialog-lifecycle.d.ts.map +1 -0
- package/dist/dialog-lifecycle.js +70 -0
- package/dist/expanded-charts.d.ts +26 -0
- package/dist/expanded-charts.d.ts.map +1 -0
- package/dist/expanded-charts.js +46 -0
- package/dist/floating-panel.d.ts +11 -0
- package/dist/floating-panel.d.ts.map +1 -0
- package/dist/floating-panel.js +1 -0
- package/dist/form-workflow.d.ts +77 -0
- package/dist/form-workflow.d.ts.map +1 -0
- package/dist/form-workflow.js +337 -0
- package/dist/hooks.d.ts +24 -21
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +1 -2468
- package/dist/image-comparison.d.ts +20 -0
- package/dist/image-comparison.d.ts.map +1 -0
- package/dist/image-comparison.js +55 -0
- package/dist/index.d.ts +25 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -0
- package/dist/interval-charts.d.ts +21 -0
- package/dist/interval-charts.d.ts.map +1 -0
- package/dist/interval-charts.js +23 -0
- package/dist/media-selection.d.ts +18 -0
- package/dist/media-selection.d.ts.map +1 -0
- package/dist/media-selection.js +12 -0
- package/dist/media-viewport.d.ts +16 -0
- package/dist/media-viewport.d.ts.map +1 -0
- package/dist/media-viewport.js +37 -0
- package/dist/motion.d.ts +597 -0
- package/dist/motion.d.ts.map +1 -0
- package/dist/motion.js +22 -0
- package/dist/review-workflow.d.ts +32 -0
- package/dist/review-workflow.d.ts.map +1 -0
- package/dist/review-workflow.js +76 -0
- package/dist/rich-text-editor.d.ts +21 -0
- package/dist/rich-text-editor.d.ts.map +1 -0
- package/dist/rich-text-editor.js +143 -0
- package/dist/select-form.d.ts +3 -0
- package/dist/select-form.d.ts.map +1 -0
- package/dist/select-form.js +1 -0
- package/dist/server-components.d.ts +24 -4
- package/dist/server-components.d.ts.map +1 -1
- package/dist/server-components.js +11 -3
- package/dist/server.d.ts +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +1 -0
- package/dist/toast-context.d.ts +4 -0
- package/dist/toast-context.d.ts.map +1 -0
- package/dist/toast-context.js +10 -0
- package/dist/toast-provider.d.ts +3 -0
- package/dist/toast-provider.d.ts.map +1 -0
- package/dist/toast-provider.js +3 -0
- package/dist/use-copy-feedback.d.ts +17 -0
- package/dist/use-copy-feedback.d.ts.map +1 -0
- package/dist/use-copy-feedback.js +54 -0
- package/dist/virtual-list-data.d.ts +13 -0
- package/dist/virtual-list-data.d.ts.map +1 -0
- package/dist/virtual-list-data.js +87 -0
- package/dist/virtual-list.d.ts +14 -0
- package/dist/virtual-list.d.ts.map +1 -0
- package/dist/virtual-list.js +24 -0
- package/dist/visual-interactions.d.ts +16 -0
- package/dist/visual-interactions.d.ts.map +1 -0
- package/dist/visual-interactions.js +30 -0
- package/dist/world-map.d.ts +26 -0
- package/dist/world-map.d.ts.map +1 -0
- package/dist/world-map.js +81 -0
- package/package.json +99 -11
- package/styles/critical.css +634 -61
- package/styles/data-table-view.css +36 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { ComponentPropsWithoutRef, ReactNode } from 'react';
|
|
2
|
+
import { type LumenApprovalResponseDetail, type LumenApprovalStatus, type LumenPromptSubmitDetail, type LumenStreamStatus, type LumenToolStatus } from '@santi020k/lumen-core';
|
|
3
|
+
export interface PromptComposerProps extends Omit<ComponentPropsWithoutRef<'form'>, 'defaultValue'> {
|
|
4
|
+
actions?: ReactNode;
|
|
5
|
+
defaultValue?: string;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
label?: string;
|
|
8
|
+
maxLength?: number;
|
|
9
|
+
onPromptSubmit?: (detail: LumenPromptSubmitDetail) => void;
|
|
10
|
+
onStop?: () => void;
|
|
11
|
+
onValueChange?: (value: string) => void;
|
|
12
|
+
pending?: boolean;
|
|
13
|
+
sendLabel?: string;
|
|
14
|
+
stopLabel?: string;
|
|
15
|
+
submitOnEnter?: boolean;
|
|
16
|
+
value?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare const PromptComposer: ({ actions, children, className, defaultValue, disabled, id, label, maxLength, onPromptSubmit, onStop, onValueChange, pending, sendLabel, stopLabel, submitOnEnter, value, onReset, ...props }: PromptComposerProps) => import("react").JSX.Element;
|
|
19
|
+
export interface StreamMessageProps extends ComponentPropsWithoutRef<'article'> {
|
|
20
|
+
actions?: ReactNode;
|
|
21
|
+
label?: string;
|
|
22
|
+
sources?: ReactNode;
|
|
23
|
+
status?: LumenStreamStatus;
|
|
24
|
+
statusLabel: string;
|
|
25
|
+
}
|
|
26
|
+
export declare const StreamMessage: ({ actions, children, className, label, sources, status, statusLabel, ...props }: StreamMessageProps) => import("react").JSX.Element;
|
|
27
|
+
export interface SourceCitationProps extends Omit<ComponentPropsWithoutRef<'a'>, 'href'> {
|
|
28
|
+
href: string;
|
|
29
|
+
label: string;
|
|
30
|
+
}
|
|
31
|
+
export declare const SourceCitation: ({ children, className, href, label, ...props }: SourceCitationProps) => import("react").JSX.Element;
|
|
32
|
+
export interface ToolActivityProps extends ComponentPropsWithoutRef<'details'> {
|
|
33
|
+
label: string;
|
|
34
|
+
status?: LumenToolStatus;
|
|
35
|
+
statusLabel: string;
|
|
36
|
+
}
|
|
37
|
+
export declare const ToolActivity: ({ children, className, label, status, statusLabel, ...props }: ToolActivityProps) => import("react").JSX.Element;
|
|
38
|
+
export interface ApprovalCardProps extends ComponentPropsWithoutRef<'div'> {
|
|
39
|
+
approveLabel?: string;
|
|
40
|
+
disabled?: boolean;
|
|
41
|
+
label: string;
|
|
42
|
+
onResponse?: (detail: LumenApprovalResponseDetail) => void;
|
|
43
|
+
rejectLabel?: string;
|
|
44
|
+
requestId: string;
|
|
45
|
+
status?: LumenApprovalStatus;
|
|
46
|
+
statusLabel: string;
|
|
47
|
+
}
|
|
48
|
+
export declare const ApprovalCard: ({ approveLabel, children, className, disabled, label, onResponse, rejectLabel, requestId, status, statusLabel, ...props }: ApprovalCardProps) => import("react").JSX.Element;
|
|
49
|
+
//# sourceMappingURL=ai-surfaces.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-surfaces.d.ts","sourceRoot":"","sources":["../src/ai-surfaces.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGhE,OAAO,EAKL,KAAK,2BAA2B,EAChC,KAAK,mBAAmB,EAExB,KAAK,uBAAuB,EAC5B,KAAK,iBAAiB,EACtB,KAAK,eAAe,EAKrB,MAAM,uBAAuB,CAAA;AAI9B,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,EAAE,cAAc,CAAC;IACjG,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,uBAAuB,KAAK,IAAI,CAAA;IAC1D,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;IACnB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAMD,eAAO,MAAM,cAAc,GAAI,+LAI5B,mBAAmB,gCAmGrB,CAAA;AAED,MAAM,WAAW,kBAAmB,SAAQ,wBAAwB,CAAC,SAAS,CAAC;IAC7E,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,MAAM,CAAC,EAAE,iBAAiB,CAAA;IAC1B,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,eAAO,MAAM,aAAa,GAAI,iFAAwG,kBAAkB,gCASvJ,CAAA;AAED,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AAExH,eAAO,MAAM,cAAc,GAAI,gDAAgD,mBAAmB,gCAgBjG,CAAA;AAED,MAAM,WAAW,iBAAkB,SAAQ,wBAAwB,CAAC,SAAS,CAAC;IAAG,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,eAAe,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE;AAE/I,eAAO,MAAM,YAAY,GAAI,+DAA0E,iBAAiB,gCAQvH,CAAA;AAED,MAAM,WAAW,iBAAkB,SAAQ,wBAAwB,CAAC,KAAK,CAAC;IACxE,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,2BAA2B,KAAK,IAAI,CAAA;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,mBAAmB,CAAA;IAC5B,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,eAAO,MAAM,YAAY,GAAI,2HAAsK,iBAAiB,gCAwCnN,CAAA"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useId, useRef, useState } from 'react';
|
|
4
|
+
import { bindLumenApprovalCard, canSubmitLumenPrompt, composeClassName, createLumenPromptComposerController, normalizeLumenPromptLimit, readLumenApprovalResponseDetail, readLumenPromptSubmitDetail, resolveLumenCitationHref } from '@santi020k/lumen-core';
|
|
5
|
+
import { Button, Card, Collapsible, Form, Label, Link, Message, Prose, Stack, Textarea } from './components.js';
|
|
6
|
+
const promptLabels = (label, sendLabel, stopLabel) => ({
|
|
7
|
+
label: label ?? 'Message', sendLabel: sendLabel ?? 'Send', stopLabel: stopLabel ?? 'Stop'
|
|
8
|
+
});
|
|
9
|
+
export const PromptComposer = ({ actions, children, className, defaultValue = '', disabled = false, id, label, maxLength, onPromptSubmit, onStop, onValueChange, pending = false, sendLabel, stopLabel, submitOnEnter = false, value, onReset, ...props }) => {
|
|
10
|
+
const generatedId = useId();
|
|
11
|
+
const inputId = id === undefined ? generatedId : `${id}-input`;
|
|
12
|
+
const [draft, setDraft] = useState(defaultValue);
|
|
13
|
+
const text = value ?? draft;
|
|
14
|
+
const limit = normalizeLumenPromptLimit(maxLength);
|
|
15
|
+
const formRef = useRef(null);
|
|
16
|
+
const controllerRef = useRef(null);
|
|
17
|
+
const labels = promptLabels(label, sendLabel, stopLabel);
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
const form = formRef.current;
|
|
20
|
+
if (!form)
|
|
21
|
+
return;
|
|
22
|
+
controllerRef.current = createLumenPromptComposerController(form);
|
|
23
|
+
const submit = (event) => {
|
|
24
|
+
if (!('detail' in event))
|
|
25
|
+
return;
|
|
26
|
+
const detail = readLumenPromptSubmitDetail(event.detail);
|
|
27
|
+
if (detail && onPromptSubmit) {
|
|
28
|
+
event.preventDefault();
|
|
29
|
+
onPromptSubmit(detail);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
const stop = () => {
|
|
33
|
+
onStop?.();
|
|
34
|
+
};
|
|
35
|
+
form.addEventListener('ui:prompt-submit', submit);
|
|
36
|
+
form.addEventListener('ui:prompt-stop', stop);
|
|
37
|
+
return () => {
|
|
38
|
+
controllerRef.current?.destroy();
|
|
39
|
+
controllerRef.current = null;
|
|
40
|
+
form.removeEventListener('ui:prompt-submit', submit);
|
|
41
|
+
form.removeEventListener('ui:prompt-stop', stop);
|
|
42
|
+
};
|
|
43
|
+
}, [onPromptSubmit, onStop]);
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
controllerRef.current?.sync();
|
|
46
|
+
}, [text, limit, disabled, pending]);
|
|
47
|
+
return (_jsxs(Form, { ...props, id: id, ref: formRef, className: composeClassName('ui-prompt-composer', className), "data-disabled": String(disabled), "data-pending": String(pending), "data-submit-on-enter": String(submitOnEnter), "data-ui-prompt-composer": true, enhance: false, method: "post", onReset: event => {
|
|
48
|
+
onReset?.(event);
|
|
49
|
+
if (!event.defaultPrevented && value === undefined) {
|
|
50
|
+
setDraft(defaultValue);
|
|
51
|
+
onValueChange?.(defaultValue);
|
|
52
|
+
}
|
|
53
|
+
}, status: pending ? 'submitting' : 'idle', children: [_jsx(Label, { htmlFor: inputId, children: labels.label }), _jsx(Textarea, { id: inputId, "data-ui-prompt-input": true, disabled: disabled, maxLength: limit, name: "prompt", onChange: event => {
|
|
54
|
+
if (value === undefined)
|
|
55
|
+
setDraft(event.currentTarget.value);
|
|
56
|
+
onValueChange?.(event.currentTarget.value);
|
|
57
|
+
}, rows: 3, required: true, value: text }), _jsxs(Stack, { direction: "horizontal", gap: "related", wrap: true, children: [actions, _jsx(Button, { "data-ui-prompt-send": true, disabled: disabled || pending || !canSubmitLumenPrompt(text, limit), type: "submit", children: labels.sendLabel }), _jsx(Button, { "data-ui-prompt-stop": true, disabled: disabled, hidden: !pending, type: "button", variant: "secondary", children: labels.stopLabel })] }), children] }));
|
|
58
|
+
};
|
|
59
|
+
export const StreamMessage = ({ actions, children, className, label = 'Assistant', sources, status = 'idle', statusLabel, ...props }) => (_jsxs(Message, { ...props, "aria-label": label, className: composeClassName('ui-stream-message', className), "data-status": status, from: "assistant", children: [_jsx(Prose, { "aria-busy": status === 'streaming', "aria-live": "off", "data-ui-stream-content": true, children: children }), _jsxs(Stack, { direction: "horizontal", gap: "related", wrap: true, children: [_jsx("span", { "aria-live": "polite", role: "status", children: statusLabel }), actions] }), sources] }));
|
|
60
|
+
export const SourceCitation = ({ children, className, href, label, ...props }) => {
|
|
61
|
+
const safeHref = resolveLumenCitationHref(href);
|
|
62
|
+
return safeHref ?
|
|
63
|
+
(_jsxs(Link, { ...props, className: composeClassName('ui-source-citation', className), href: safeHref, rel: "noopener noreferrer", children: [label, children] })) :
|
|
64
|
+
(_jsxs("span", { className: composeClassName('ui-source-citation', className), children: [label, children] }));
|
|
65
|
+
};
|
|
66
|
+
export const ToolActivity = ({ children, className, label, status = 'queued', statusLabel, ...props }) => (_jsxs(Collapsible, { ...props, className: composeClassName('ui-tool-activity', className), "data-status": status, children: [_jsx("summary", { children: label }), _jsxs(Stack, { gap: "related", children: [_jsx("span", { role: "status", children: statusLabel }), children] })] }));
|
|
67
|
+
export const ApprovalCard = ({ approveLabel = 'Approve', children, className, disabled = false, label, onResponse, rejectLabel = 'Reject', requestId, status = 'pending', statusLabel, ...props }) => {
|
|
68
|
+
const ref = useRef(null);
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
const root = ref.current;
|
|
71
|
+
if (!root)
|
|
72
|
+
return;
|
|
73
|
+
const cleanup = bindLumenApprovalCard(root);
|
|
74
|
+
const respond = (event) => {
|
|
75
|
+
if (!('detail' in event))
|
|
76
|
+
return;
|
|
77
|
+
const detail = readLumenApprovalResponseDetail(event.detail);
|
|
78
|
+
if (detail)
|
|
79
|
+
onResponse?.(detail);
|
|
80
|
+
};
|
|
81
|
+
root.addEventListener('ui:approval-response', respond);
|
|
82
|
+
return () => {
|
|
83
|
+
cleanup();
|
|
84
|
+
root.removeEventListener('ui:approval-response', respond);
|
|
85
|
+
};
|
|
86
|
+
}, [onResponse]);
|
|
87
|
+
return (_jsx(Card, { ...props, ref: ref, "aria-label": label, className: composeClassName('ui-approval-card', className), "data-disabled": String(disabled), "data-request-id": requestId, "data-status": status, "data-ui-approval-card": true, children: _jsxs(Stack, { gap: "group", children: [_jsx("strong", { children: label }), children, _jsx("span", { role: "status", children: statusLabel }), _jsxs(Stack, { direction: "horizontal", gap: "related", wrap: true, children: [_jsx(Button, { "data-ui-approval-response": "approve", disabled: disabled || status !== 'pending', type: "button", children: approveLabel }), _jsx(Button, { "data-ui-approval-response": "reject", disabled: disabled || status !== 'pending', type: "button", variant: "secondary", children: rejectLabel })] })] }) }));
|
|
88
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ComponentPropsWithRef } from 'react';
|
|
2
|
+
import { type LumenAmountChangeDetail, type LumenAmountOptions } from '@santi020k/lumen-core';
|
|
3
|
+
export interface AmountFieldProps extends Omit<ComponentPropsWithRef<'input'>, 'value' | 'defaultValue' | 'type' | 'min' | 'max' | 'step'>, LumenAmountOptions {
|
|
4
|
+
value?: string;
|
|
5
|
+
defaultValue?: string;
|
|
6
|
+
invalidMessage?: string;
|
|
7
|
+
onValueChange?: (draft: string, detail: LumenAmountChangeDetail) => void;
|
|
8
|
+
}
|
|
9
|
+
/** Formatting owns no currency conversion, rounding or domain validation. */
|
|
10
|
+
export declare const AmountField: ({ value, defaultValue, locale, fractionDigits, allowNegative, invalidMessage, onValueChange, name, form, disabled, readOnly, className, ...props }: AmountFieldProps) => import("react").JSX.Element;
|
|
11
|
+
//# sourceMappingURL=amount-field.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"amount-field.d.ts","sourceRoot":"","sources":["../src/amount-field.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAA;AAGlD,OAAO,EAAmG,KAAK,uBAAuB,EAAmC,KAAK,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAE/N,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,cAAc,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC,EAAE,kBAAkB;IAC5J,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,uBAAuB,KAAK,IAAI,CAAA;CACzE;AAED,6EAA6E;AAC7E,eAAO,MAAM,WAAW,GAAI,oJAA+K,gBAAgB,gCA0D1N,CAAA"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useLayoutEffect, useRef, useState } from 'react';
|
|
4
|
+
import { composeClassName, createLumenAmountFieldController, formatLumenAmountDraft, getLumenAmountValue } from '@santi020k/lumen-core';
|
|
5
|
+
/** Formatting owns no currency conversion, rounding or domain validation. */
|
|
6
|
+
export const AmountField = ({ value, defaultValue = '', locale = 'en-US', fractionDigits = 2, allowNegative = false, invalidMessage, onValueChange, name, form, disabled, readOnly, className, ...props }) => {
|
|
7
|
+
const rootRef = useRef(null);
|
|
8
|
+
const controllerRef = useRef(undefined);
|
|
9
|
+
const latestRef = useRef({ value, onValueChange });
|
|
10
|
+
const options = { locale, fractionDigits, allowNegative };
|
|
11
|
+
const initial = value ?? defaultValue;
|
|
12
|
+
const [draft, setDraft] = useState(initial);
|
|
13
|
+
useLayoutEffect(() => {
|
|
14
|
+
latestRef.current = { value, onValueChange };
|
|
15
|
+
});
|
|
16
|
+
useLayoutEffect(() => {
|
|
17
|
+
const root = rootRef.current;
|
|
18
|
+
if (!root)
|
|
19
|
+
return;
|
|
20
|
+
const controller = createLumenAmountFieldController(root, detail => {
|
|
21
|
+
setDraft(detail.draft);
|
|
22
|
+
latestRef.current.onValueChange?.(detail.draft, detail);
|
|
23
|
+
if (latestRef.current.value !== undefined)
|
|
24
|
+
controller.setValue(latestRef.current.value);
|
|
25
|
+
});
|
|
26
|
+
controllerRef.current = controller;
|
|
27
|
+
return () => {
|
|
28
|
+
controller.destroy();
|
|
29
|
+
controllerRef.current = undefined;
|
|
30
|
+
};
|
|
31
|
+
}, [locale, fractionDigits, allowNegative, form]);
|
|
32
|
+
useLayoutEffect(() => {
|
|
33
|
+
if (value !== undefined)
|
|
34
|
+
controllerRef.current?.setValue(value);
|
|
35
|
+
}, [value]);
|
|
36
|
+
return (_jsxs("span", { ref: rootRef, "data-ui-amount-field": true, locale, 'fraction-digits': String(fractionDigits), 'allow-negative': allowNegative ? '' : undefined, value: value ?? draft, 'default-value': defaultValue, 'invalid-message': invalidMessage, children: [_jsx("input", { ...props, className: composeClassName('ui-input ui-amount-field', className), defaultValue: formatLumenAmountDraft(initial, options), "data-ui-amount-input": true, disabled: disabled, readOnly: readOnly, form: form, type: "text", inputMode: "decimal" }), _jsx("input", { "data-ui-amount-value": true, type: "hidden", name: name, form: form, disabled: disabled, value: getLumenAmountValue(value ?? draft) ?? '' })] }));
|
|
37
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ComponentPropsWithRef, ReactNode } from 'react';
|
|
2
|
+
import { type LumenAttachmentPreviewLabels, type LumenAttachmentPreviewState } from '@santi020k/lumen-core';
|
|
3
|
+
export interface AttachmentPreviewProps extends ComponentPropsWithRef<'figure'> {
|
|
4
|
+
actions?: ReactNode;
|
|
5
|
+
alt: string;
|
|
6
|
+
caption?: ReactNode;
|
|
7
|
+
contentType?: string;
|
|
8
|
+
labels?: Partial<LumenAttachmentPreviewLabels>;
|
|
9
|
+
onStateChange?: (state: LumenAttachmentPreviewState) => void;
|
|
10
|
+
retryKey?: number | string;
|
|
11
|
+
src?: string;
|
|
12
|
+
state?: LumenAttachmentPreviewState;
|
|
13
|
+
}
|
|
14
|
+
export declare const AttachmentPreview: ({ actions, alt, caption, children, className, contentType, labels, onStateChange, retryKey, src, state: requested, ...props }: AttachmentPreviewProps) => import("react").JSX.Element;
|
|
15
|
+
export type AttachmentListProps = ComponentPropsWithRef<'ul'>;
|
|
16
|
+
export declare const AttachmentList: ({ className, ...props }: AttachmentListProps) => import("react").JSX.Element;
|
|
17
|
+
//# sourceMappingURL=attachments.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachments.d.ts","sourceRoot":"","sources":["../src/attachments.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAG7D,OAAO,EAEL,KAAK,4BAA4B,EAEjC,KAAK,2BAA2B,EAEjC,MAAM,uBAAuB,CAAA;AAI9B,MAAM,WAAW,sBAAuB,SAAQ,qBAAqB,CAAC,QAAQ,CAAC;IAC7E,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC,4BAA4B,CAAC,CAAA;IAC9C,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,2BAA2B,KAAK,IAAI,CAAA;IAC5D,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,2BAA2B,CAAA;CACpC;AAED,eAAO,MAAM,iBAAiB,GAAI,+HAG/B,sBAAsB,gCAwCxB,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAA;AAC7D,eAAO,MAAM,cAAc,GAAI,yBAAyB,mBAAmB,gCAE1E,CAAA"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useRef, useState } from 'react';
|
|
4
|
+
import { composeClassName, lumenAttachmentPreviewLabels, resolveLumenAttachmentPreviewState } from '@santi020k/lumen-core';
|
|
5
|
+
import { Image } from './components.js';
|
|
6
|
+
export const AttachmentPreview = ({ actions, alt, caption, children, className, contentType, labels, onStateChange, retryKey, src, state: requested, ...props }) => {
|
|
7
|
+
const [failure, setFailure] = useState(null);
|
|
8
|
+
const failed = failure !== null && failure.src === src && failure.key === retryKey;
|
|
9
|
+
const state = resolveLumenAttachmentPreviewState(src, contentType, requested, failed);
|
|
10
|
+
const previousStateRef = useRef(state);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (previousStateRef.current !== state) {
|
|
13
|
+
previousStateRef.current = state;
|
|
14
|
+
onStateChange?.(state);
|
|
15
|
+
}
|
|
16
|
+
}, [onStateChange, state]);
|
|
17
|
+
const canPreview = resolveLumenAttachmentPreviewState(src, contentType) === 'ready';
|
|
18
|
+
const copy = { ...lumenAttachmentPreviewLabels, ...labels };
|
|
19
|
+
return (_jsxs("figure", { ...props, className: composeClassName('ui-attachment-preview', className), "aria-busy": state === 'loading', "data-state": state, children: [_jsx("div", { "data-slot": "attachment-preview-media", hidden: state !== 'ready', children: canPreview && (_jsx(Image, { src: src, alt: alt, fit: "contain", radius: "none", loading: "eager", onError: () => {
|
|
20
|
+
setFailure({ src, key: retryKey });
|
|
21
|
+
} }, `${src ?? ''}:${retryKey ?? ''}`)) }), _jsx("p", { role: "status", "data-slot": "attachment-preview-fallback", hidden: state === 'ready', children: state === 'ready' ? '' : copy[state] }), caption && _jsx("figcaption", { children: caption }), children, actions && _jsx("div", { "data-slot": "attachment-preview-actions", children: actions })] }));
|
|
22
|
+
};
|
|
23
|
+
export const AttachmentList = ({ className, ...props }) => (_jsx("ul", { ...props, className: composeClassName('ui-attachment-list', className), "data-slot": "attachment-list" }));
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type LumenBulletOptions, type LumenChartLabels, type LumenChartTone } from '@santi020k/lumen-core';
|
|
2
|
+
import { type ChartProps } from './components.js';
|
|
3
|
+
export interface BulletChartProps extends Omit<ChartProps, 'children' | 'value'>, LumenBulletOptions {
|
|
4
|
+
formatValue?: (value: number) => string;
|
|
5
|
+
labels?: Partial<LumenChartLabels>;
|
|
6
|
+
showTable?: boolean;
|
|
7
|
+
target: number;
|
|
8
|
+
targetLabel?: string;
|
|
9
|
+
tone?: LumenChartTone;
|
|
10
|
+
value: number | null;
|
|
11
|
+
valueLabel?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare const BulletChart: (props: BulletChartProps) => import("react").JSX.Element;
|
|
14
|
+
//# sourceMappingURL=bullet-chart.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bullet-chart.d.ts","sourceRoot":"","sources":["../src/bullet-chart.tsx"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EAEpB,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EAAS,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAExD,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,EAAE,kBAAkB;IAClG,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IACvC,MAAM,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAA;IAClC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,cAAc,CAAA;IACrB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAyGD,eAAO,MAAM,WAAW,GAAI,OAAO,gBAAgB,gCAElD,CAAA"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { composeClassName, createLumenBulletGeometry, getLumenChartToneClassName, resolveLumenChartLabels } from '@santi020k/lumen-core';
|
|
4
|
+
import { Chart } from './components.js';
|
|
5
|
+
const resolveBulletProps = (props) => ({
|
|
6
|
+
...props,
|
|
7
|
+
formatValue: props.formatValue ?? String,
|
|
8
|
+
showTable: props.showTable ?? true,
|
|
9
|
+
targetLabel: props.targetLabel ?? 'Target',
|
|
10
|
+
tone: props.tone ?? 'series-1'
|
|
11
|
+
});
|
|
12
|
+
const BulletContent = ({ className, domain, formatValue, labels, ranges, showTable, summary, target, targetLabel, tone, value, valueLabel, ...props }) => {
|
|
13
|
+
const text = resolveLumenChartLabels(labels);
|
|
14
|
+
const model = createLumenBulletGeometry(value, target, { domain, ranges });
|
|
15
|
+
const title = valueLabel ?? text.value;
|
|
16
|
+
const actual = model.valid && value !== null ? formatValue(value) : text.notAvailable;
|
|
17
|
+
const factual = model.valid ? `${title}: ${actual}. ${targetLabel}: ${formatValue(target)}.` : text.invalidData;
|
|
18
|
+
return (_jsx(Chart, { ...props, className: className, summary: summary ?? factual, children: model.valid ?
|
|
19
|
+
(_jsxs(_Fragment, { children: [_jsxs("div", { className: "ui-bullet-chart__values", children: [_jsxs("div", { children: [_jsx("span", { children: title }), _jsx("strong", { children: actual })] }), _jsxs("p", { children: [_jsx("span", { className: "ui-bullet-chart__target-key", "aria-hidden": "true" }), targetLabel, _jsx("strong", { children: formatValue(target) })] })] }), _jsxs("div", { "aria-hidden": "true", className: "ui-bullet-chart__plot", children: [_jsxs("div", { className: "ui-bullet-chart__track", children: [model.ranges.map((range, index) => (_jsx("span", { className: composeClassName('ui-bullet-chart__range', getLumenChartToneClassName(range.tone ?? 'neutral')), style: { left: `${range.startRatio * 100}%`, width: `${(range.endRatio - range.startRatio) * 100}%`, opacity: 0.08 + index / Math.max(1, model.ranges.length - 1) * 0.14 } }, range.end))), value !== null && _jsx("span", { className: composeClassName('ui-bullet-chart__bar', getLumenChartToneClassName(tone)), style: { left: `${model.valueStartRatio * 100}%`, width: `${model.valueWidthRatio * 100}%` } }), _jsx("span", { className: "ui-bullet-chart__target", style: { left: `${model.targetRatio * 100}%` } })] }), _jsx("div", { className: "ui-bullet-chart__ticks", children: model.ticks.map(tick => _jsx("span", { children: formatValue(tick.value) }, tick.position)) })] }), model.ranges.length > 0 && (_jsx("ul", { className: "ui-bullet-chart__ranges", children: model.ranges.map(range => (_jsxs("li", { className: getLumenChartToneClassName(range.tone ?? 'neutral'), children: [_jsx("span", { children: range.label }), _jsxs("span", { children: [formatValue(range.start), "\u2013", formatValue(range.end)] })] }, range.end))) })), showTable && (_jsxs("details", { className: "ui-chart__data", children: [_jsx("summary", { children: text.viewData }), _jsx("div", { role: "group", tabIndex: 0, "aria-label": text.chartData, children: _jsxs("table", { children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { scope: "col", children: text.category }), _jsx("th", { scope: "col", children: text.value })] }) }), _jsxs("tbody", { children: [_jsxs("tr", { children: [_jsx("th", { scope: "row", children: title }), _jsx("td", { children: actual })] }), _jsxs("tr", { children: [_jsx("th", { scope: "row", children: targetLabel }), _jsx("td", { children: formatValue(target) })] }), model.ranges.map(range => (_jsxs("tr", { children: [_jsx("th", { scope: "row", children: range.label }), _jsxs("td", { children: [formatValue(range.start), "\u2013", formatValue(range.end)] })] }, range.end)))] })] }) })] }))] })) :
|
|
20
|
+
_jsx("p", { className: "ui-chart__empty", role: "status", children: text.invalidData }) }));
|
|
21
|
+
};
|
|
22
|
+
export const BulletChart = (props) => (_jsx(BulletContent, { ...resolveBulletProps(props), className: composeClassName('ui-bullet-chart', props.className) }));
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ComponentPropsWithRef } from 'react';
|
|
2
|
+
import { type LumenChangeSummaryItem } from '@santi020k/lumen-core';
|
|
3
|
+
export interface ChangeSummaryProps extends ComponentPropsWithRef<'section'> {
|
|
4
|
+
items?: readonly LumenChangeSummaryItem[];
|
|
5
|
+
label?: string;
|
|
6
|
+
beforeLabel?: string;
|
|
7
|
+
afterLabel?: string;
|
|
8
|
+
changedLabel?: string;
|
|
9
|
+
unchangedLabel?: string;
|
|
10
|
+
/** Localized count text, supplied by the host. */
|
|
11
|
+
summary?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare const ChangeSummary: ({ items, label, beforeLabel, afterLabel, changedLabel, unchangedLabel, summary, className, children, ...props }: ChangeSummaryProps) => import("react").JSX.Element;
|
|
14
|
+
//# sourceMappingURL=change-summary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"change-summary.d.ts","sourceRoot":"","sources":["../src/change-summary.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAA;AAElD,OAAO,EAAoB,KAAK,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAErF,MAAM,WAAW,kBAAmB,SAAQ,qBAAqB,CAAC,SAAS,CAAC;IAC1E,KAAK,CAAC,EAAE,SAAS,sBAAsB,EAAE,CAAA;IACzC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,kDAAkD;IAClD,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAID,eAAO,MAAM,aAAa,GAAI,iHAG3B,kBAAkB,gCAwBpB,CAAA"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { composeClassName } from '@santi020k/lumen-core';
|
|
3
|
+
const noChanges = [];
|
|
4
|
+
export const ChangeSummary = ({ items = noChanges, label = 'Changes', beforeLabel = 'Before', afterLabel = 'After', changedLabel = 'Changed', unchangedLabel = 'Unchanged', summary, className, children, ...props }) => (_jsxs("section", { className: composeClassName('ui-change-summary', className), "aria-label": label, ...props, children: [_jsx("h3", { className: "ui-change-summary__heading", children: label }), summary && _jsx("p", { className: "ui-change-summary__summary", children: summary }), _jsx("dl", { className: "ui-change-summary__list", children: items.map(item => (_jsxs("div", { className: "ui-change-summary__item", "data-changed": item.changed, children: [_jsxs("dt", { children: [item.label, _jsx("span", { className: "ui-change-summary__state", children: item.changed ? changedLabel : unchangedLabel })] }), _jsxs("dd", { children: [_jsx("span", { className: "ui-change-summary__value-label", children: beforeLabel }), item.before] }), _jsxs("dd", { children: [_jsx("span", { className: "ui-change-summary__value-label", children: afterLabel }), item.after] })] }, item.id))) }), children] }));
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type createLumenLineChartModel, type LumenChartLabels } from '@santi020k/lumen-core';
|
|
2
|
+
interface ChartInspectionProps {
|
|
3
|
+
formatCategory?: (value: number | string) => string;
|
|
4
|
+
formatValue: (value: number) => string;
|
|
5
|
+
labels: Readonly<LumenChartLabels>;
|
|
6
|
+
model: ReturnType<typeof createLumenLineChartModel>;
|
|
7
|
+
}
|
|
8
|
+
export declare const ChartInspection: ({ formatCategory, formatValue, labels, model }: ChartInspectionProps) => import("react").JSX.Element;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=chart-inspection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-inspection.d.ts","sourceRoot":"","sources":["../src/chart-inspection.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,yBAAyB,EAA0D,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAErJ,UAAU,oBAAoB;IAC5B,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,KAAK,MAAM,CAAA;IACnD,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IACtC,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAAA;IAClC,KAAK,EAAE,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAA;CACpD;AAED,eAAO,MAAM,eAAe,GAAI,gDAAgD,oBAAoB,gCAmCnG,CAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { getLumenChartCategoryLabel, getLumenChartToneClassName } from '@santi020k/lumen-core';
|
|
3
|
+
export const ChartInspection = ({ formatCategory, formatValue, labels, model }) => {
|
|
4
|
+
const lookup = model.series.map(series => new Map(series.data.map(datum => [datum.x, datum])));
|
|
5
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { className: "ui-chart__inspection", "data-ui-chart-inspection": true, hidden: true, children: model.categories.map((category, index) => (_jsxs("div", { "data-ui-chart-point": JSON.stringify(category), "data-ui-chart-position": model.positions[index], hidden: true, children: [_jsx("strong", { children: getLumenChartCategoryLabel(model.series, category, formatCategory, 'detail') }), model.series.map((series, seriesIndex) => {
|
|
6
|
+
const value = lookup[seriesIndex]?.get(category)?.y;
|
|
7
|
+
return (_jsxs("span", { className: getLumenChartToneClassName(series.tone, seriesIndex), "data-ui-chart-series-value": series.id, children: [_jsx("i", { "aria-hidden": "true" }), series.label, ' ', _jsx("b", { children: value === null || value === undefined || !Number.isFinite(value) ?
|
|
8
|
+
labels.notAvailable :
|
|
9
|
+
formatValue(value) })] }, series.id));
|
|
10
|
+
})] }, `${typeof category}:${category}`))) }), _jsx("p", { "aria-live": "polite", "aria-atomic": "true", className: "ui-sr-only", "data-ui-chart-announcement": true })] }));
|
|
11
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type createLumenLineChartModel, type LumenChartCursorChangeDetail } from '@santi020k/lumen-core';
|
|
3
|
+
export interface ChartInteractionProps {
|
|
4
|
+
interactive?: boolean;
|
|
5
|
+
onCursorChange?: (detail: LumenChartCursorChangeDetail) => void;
|
|
6
|
+
/** A stable X identity; null clears the cursor. */
|
|
7
|
+
cursor?: number | string | null;
|
|
8
|
+
syncGroup?: string;
|
|
9
|
+
}
|
|
10
|
+
interface ChartInteractionContainerProps extends ChartInteractionProps {
|
|
11
|
+
children: ReactNode;
|
|
12
|
+
showLegend: boolean;
|
|
13
|
+
model: ReturnType<typeof createLumenLineChartModel>;
|
|
14
|
+
}
|
|
15
|
+
export declare const ChartInteraction: ({ children, model, showLegend, syncGroup, ...props }: ChartInteractionContainerProps) => import("react").JSX.Element;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=chart-interaction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-interaction.d.ts","sourceRoot":"","sources":["../src/chart-interaction.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAqB,MAAM,OAAO,CAAA;AAEzD,OAAO,EAEL,KAAK,yBAAyB,EAC9B,KAAK,4BAA4B,EAElC,MAAM,uBAAuB,CAAA;AAE9B,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,4BAA4B,KAAK,IAAI,CAAA;IAC/D,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAyDD,UAAU,8BAA+B,SAAQ,qBAAqB;IACpE,QAAQ,EAAE,SAAS,CAAA;IACnB,UAAU,EAAE,OAAO,CAAA;IACnB,KAAK,EAAE,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAA;CACpD;AAED,eAAO,MAAM,gBAAgB,GAAI,sDAE9B,8BAA8B,gCAQhC,CAAA"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useRef } from 'react';
|
|
4
|
+
import { createLumenChartInteractionController } from '@santi020k/lumen-core';
|
|
5
|
+
const useChartInteraction = ({ cursor, interactive, onCursorChange }, bindingKey) => {
|
|
6
|
+
const ref = useRef(null);
|
|
7
|
+
const controllerRef = useRef(null);
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
if (!interactive || !ref.current)
|
|
10
|
+
return;
|
|
11
|
+
const root = ref.current;
|
|
12
|
+
const instance = createLumenChartInteractionController(root);
|
|
13
|
+
controllerRef.current = instance;
|
|
14
|
+
return () => {
|
|
15
|
+
instance.destroy();
|
|
16
|
+
controllerRef.current = null;
|
|
17
|
+
};
|
|
18
|
+
}, [interactive, bindingKey]);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
controllerRef.current?.setControlledCursor(cursor);
|
|
21
|
+
}, [cursor, interactive, bindingKey]);
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
const root = ref.current;
|
|
24
|
+
if (!root || !onCursorChange)
|
|
25
|
+
return;
|
|
26
|
+
const CustomEventType = root.ownerDocument.defaultView?.CustomEvent;
|
|
27
|
+
const listener = (event) => {
|
|
28
|
+
if (!CustomEventType || !(event instanceof CustomEventType))
|
|
29
|
+
return;
|
|
30
|
+
const detail = event.detail;
|
|
31
|
+
if (detail === null || typeof detail !== 'object' || !('x' in detail))
|
|
32
|
+
return;
|
|
33
|
+
const x = detail.x;
|
|
34
|
+
if (x === null || typeof x === 'string' || (typeof x === 'number' && Number.isFinite(x)))
|
|
35
|
+
onCursorChange({ x });
|
|
36
|
+
};
|
|
37
|
+
root.addEventListener('ui:chart-cursor-change', listener);
|
|
38
|
+
return () => {
|
|
39
|
+
root.removeEventListener('ui:chart-cursor-change', listener);
|
|
40
|
+
};
|
|
41
|
+
}, [onCursorChange]);
|
|
42
|
+
return ref;
|
|
43
|
+
};
|
|
44
|
+
export const ChartInteraction = ({ children, model, showLegend, syncGroup, ...props }) => {
|
|
45
|
+
const bindingKey = JSON.stringify([
|
|
46
|
+
model.categories, model.positions, model.series.map(series => series.id), showLegend, syncGroup
|
|
47
|
+
]);
|
|
48
|
+
const ref = useChartInteraction(props, bindingKey);
|
|
49
|
+
return _jsx("div", { className: "ui-chart__content", "data-ui-chart-sync": syncGroup, ref: ref, children: children });
|
|
50
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-label.d.ts","sourceRoot":"","sources":["../src/chart-label.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,eAAO,MAAM,iBAAiB,GAC5B,OAAO,MAAM,GAAG,SAAS,EAAE,SAAS,SAAS,EAAE,UAAU,MAAM,KAC9D,MAAqE,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const getChartPlotLabel = (label, heading, fallback) => label ?? (typeof heading === 'string' ? heading : fallback);
|
package/dist/chart-recipes.d.ts
CHANGED
|
@@ -1,2 +1,10 @@
|
|
|
1
|
+
import { type LumenChartDatumActivationDetail, type LumenChartLabels } from '@santi020k/lumen-core';
|
|
2
|
+
export interface ReactChartDatumAction {
|
|
3
|
+
key: string;
|
|
4
|
+
label: string;
|
|
5
|
+
serialized: string;
|
|
6
|
+
}
|
|
7
|
+
export declare const createReactChartDatumAction: (detail: LumenChartDatumActivationDetail | null, context: string, labels: Readonly<LumenChartLabels>) => ReactChartDatumAction | null;
|
|
8
|
+
export declare const readReactChartDatumActivation: (root: HTMLElement, target: EventTarget | null) => LumenChartDatumActivationDetail | null;
|
|
1
9
|
export declare const formatReactChartTableValue: (value: number | null | undefined, formatValue: (value: number) => string, notAvailable?: string) => string;
|
|
2
10
|
//# sourceMappingURL=chart-recipes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-recipes.d.ts","sourceRoot":"","sources":["../src/chart-recipes.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,0BAA0B,GACrC,OAAO,MAAM,GAAG,IAAI,GAAG,SAAS,EAChC,aAAa,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,EACtC,qBAA8B,KAC7B,MAEiB,CAAA"}
|
|
1
|
+
{"version":3,"file":"chart-recipes.d.ts","sourceRoot":"","sources":["../src/chart-recipes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,+BAA+B,EAAE,KAAK,gBAAgB,EAAkC,MAAM,uBAAuB,CAAA;AAEnI,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;CACnB;AAUD,eAAO,MAAM,2BAA2B,GACtC,QAAQ,+BAA+B,GAAG,IAAI,EAC9C,SAAS,MAAM,EACf,QAAQ,QAAQ,CAAC,gBAAgB,CAAC,KACjC,qBAAqB,GAAG,IAMrB,CAAA;AAEN,eAAO,MAAM,6BAA6B,GACxC,MAAM,WAAW,EACjB,QAAQ,WAAW,GAAG,IAAI,KACzB,+BAA+B,GAAG,IAsBpC,CAAA;AAED,eAAO,MAAM,0BAA0B,GACrC,OAAO,MAAM,GAAG,IAAI,GAAG,SAAS,EAChC,aAAa,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,EACtC,qBAA8B,KAC7B,MAEiB,CAAA"}
|
package/dist/chart-recipes.js
CHANGED
|
@@ -1,3 +1,38 @@
|
|
|
1
|
+
import { parseLumenChartDatumActivation } from '@santi020k/lumen-core';
|
|
2
|
+
const datumActionKey = (detail) => {
|
|
3
|
+
if (detail.kind === 'series')
|
|
4
|
+
return JSON.stringify([detail.kind, detail.seriesId, detail.x, detail.datumId]);
|
|
5
|
+
if (detail.kind === 'heatmap')
|
|
6
|
+
return JSON.stringify([detail.kind, detail.x, detail.y, detail.datumId]);
|
|
7
|
+
return JSON.stringify([detail.kind, detail.x, detail.datumId]);
|
|
8
|
+
};
|
|
9
|
+
export const createReactChartDatumAction = (detail, context, labels) => detail ?
|
|
10
|
+
{
|
|
11
|
+
key: datumActionKey(detail),
|
|
12
|
+
label: labels.formatDatumAction(context),
|
|
13
|
+
serialized: JSON.stringify(detail)
|
|
14
|
+
} :
|
|
15
|
+
null;
|
|
16
|
+
export const readReactChartDatumActivation = (root, target) => {
|
|
17
|
+
const ElementType = root.ownerDocument.defaultView?.Element;
|
|
18
|
+
if (!root.isConnected || !ElementType || !(target instanceof ElementType))
|
|
19
|
+
return null;
|
|
20
|
+
const element = target.closest('[data-ui-chart-datum]');
|
|
21
|
+
if (element?.closest('[data-ui-chart-activation]') !== root)
|
|
22
|
+
return null;
|
|
23
|
+
if (element.closest('[inert], [hidden], [disabled], [aria-disabled="true"]'))
|
|
24
|
+
return null;
|
|
25
|
+
const serialized = element.getAttribute('data-ui-chart-datum');
|
|
26
|
+
if (!serialized)
|
|
27
|
+
return null;
|
|
28
|
+
try {
|
|
29
|
+
const input = JSON.parse(serialized);
|
|
30
|
+
return parseLumenChartDatumActivation(input);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
1
36
|
export const formatReactChartTableValue = (value, formatValue, notAvailable = 'Not available') => value === null || value === undefined || !Number.isFinite(value) ?
|
|
2
37
|
notAvailable :
|
|
3
38
|
formatValue(value);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ComponentPropsWithoutRef, ReactNode } from 'react';
|
|
2
|
+
export interface ComboboxProps extends ComponentPropsWithoutRef<'input'> {
|
|
3
|
+
label?: ReactNode;
|
|
4
|
+
list: string;
|
|
5
|
+
options?: string[];
|
|
6
|
+
wrapperClassName?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const Combobox: ({ className, defaultValue, disabled, readOnly, form, id, label, list, onBlur, onChange, onFocus, onKeyDown, options: rawOptions, type, value: valueProp, wrapperClassName, ...props }: ComboboxProps) => import("react").JSX.Element;
|
|
9
|
+
//# sourceMappingURL=combobox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"combobox.d.ts","sourceRoot":"","sources":["../src/combobox.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAiB,SAAS,EAAE,MAAM,OAAO,CAAA;AA0B/E,MAAM,WAAW,aAAc,SAAQ,wBAAwB,CAAC,OAAO,CAAC;IACtE,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED,eAAO,MAAM,QAAQ,GAAI,uLAkBtB,aAAa,gCA0Of,CAAA"}
|