pixelon 0.3.28 → 0.3.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/molecules/chat/StructuredContent/helpers/AnsweredSummary.d.ts +5 -0
- package/dist/components/molecules/chat/StructuredContent/helpers/types.d.ts +18 -0
- package/dist/components/molecules/chat/StructuredContent/helpers/useComponentInteraction.d.ts +1 -1
- package/dist/core/eventBus/chatEventBus.d.ts +2 -0
- package/dist/index.esm.js +67 -3
- package/dist/index.js +67 -3
- package/package.json +3 -1
|
@@ -1,7 +1,24 @@
|
|
|
1
1
|
import type { ChatEventBus } from '../../../../../core/eventBus';
|
|
2
|
+
export interface ComponentAction {
|
|
3
|
+
id: string;
|
|
4
|
+
label: string;
|
|
5
|
+
kind?: string;
|
|
6
|
+
emits_value?: boolean;
|
|
7
|
+
value?: unknown;
|
|
8
|
+
intent?: 'primary' | 'secondary' | 'danger';
|
|
9
|
+
}
|
|
2
10
|
export interface UIComponentData {
|
|
3
11
|
type: string;
|
|
4
12
|
props: Record<string, unknown>;
|
|
13
|
+
status?: string;
|
|
14
|
+
visibility_policy?: 'hide_on_terminal' | 'keep_visible' | 'collapse';
|
|
15
|
+
actions?: ComponentAction[];
|
|
16
|
+
/** SPEC-023: respuesta persistida por el backend al cerrar el componente */
|
|
17
|
+
selected_values?: Array<{
|
|
18
|
+
value: unknown;
|
|
19
|
+
label: string;
|
|
20
|
+
}>;
|
|
21
|
+
/** @deprecated contrato legacy (pre SPEC-023); usar status */
|
|
5
22
|
answered?: boolean;
|
|
6
23
|
}
|
|
7
24
|
export interface ChatComponentProps {
|
|
@@ -10,4 +27,5 @@ export interface ChatComponentProps {
|
|
|
10
27
|
assistantMessageId?: string;
|
|
11
28
|
}
|
|
12
29
|
export type OnConfirm = (value: unknown, label: string) => void;
|
|
30
|
+
export declare const TERMINAL_STATUS: Set<string>;
|
|
13
31
|
export declare const DISPLAY_COMPONENTS: Set<string>;
|
package/dist/components/molecules/chat/StructuredContent/helpers/useComponentInteraction.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ interface UseComponentInteractionParams {
|
|
|
6
6
|
assistantMessageId: string;
|
|
7
7
|
}
|
|
8
8
|
export declare function useComponentInteraction({ eventBus, fieldName, componentType, assistantMessageId, }: UseComponentInteractionParams): {
|
|
9
|
-
emitInteraction: (value: unknown, label: string) => void;
|
|
9
|
+
emitInteraction: (value: unknown, label: string, actionId?: string) => void;
|
|
10
10
|
isConfirmed: boolean;
|
|
11
11
|
};
|
|
12
12
|
export {};
|
|
@@ -26,6 +26,8 @@ export type ChatEvents = {
|
|
|
26
26
|
label: string;
|
|
27
27
|
componentType: string;
|
|
28
28
|
assistantMessageId: string;
|
|
29
|
+
/** SPEC-023 T8: id de la Action disparada (opcional) */
|
|
30
|
+
actionId?: string;
|
|
29
31
|
};
|
|
30
32
|
/** Consumer -> Chat: update the displayed messages */
|
|
31
33
|
messagesUpdated: {
|
package/dist/index.esm.js
CHANGED
|
@@ -1618,8 +1618,47 @@ function parseContent(content) {
|
|
|
1618
1618
|
return null;
|
|
1619
1619
|
}
|
|
1620
1620
|
|
|
1621
|
+
const TERMINAL_STATUS = /* @__PURE__ */ new Set(["answered", "cancelled", "expired"]);
|
|
1621
1622
|
const DISPLAY_COMPONENTS = /* @__PURE__ */ new Set(["card", "badge", "reactive_form", "carousel"]);
|
|
1622
1623
|
|
|
1624
|
+
const AnsweredSummary = ({ component }) => {
|
|
1625
|
+
const status = component.status;
|
|
1626
|
+
const values = component.selected_values ?? [];
|
|
1627
|
+
const labels = values.map((v) => v.label).filter(Boolean).join(", ");
|
|
1628
|
+
let icon = "\u2713";
|
|
1629
|
+
let text = labels || "Respondido";
|
|
1630
|
+
let color = "#3a8a3a";
|
|
1631
|
+
if (status === "cancelled") {
|
|
1632
|
+
icon = "\u2715";
|
|
1633
|
+
text = "Cancelado";
|
|
1634
|
+
color = "#999";
|
|
1635
|
+
} else if (status === "expired") {
|
|
1636
|
+
icon = "\u231B";
|
|
1637
|
+
text = "Expir\xF3";
|
|
1638
|
+
color = "#b58a00";
|
|
1639
|
+
}
|
|
1640
|
+
return /* @__PURE__ */ jsxs(
|
|
1641
|
+
"div",
|
|
1642
|
+
{
|
|
1643
|
+
style: {
|
|
1644
|
+
display: "inline-flex",
|
|
1645
|
+
alignItems: "center",
|
|
1646
|
+
gap: "6px",
|
|
1647
|
+
padding: "6px 12px",
|
|
1648
|
+
borderRadius: "999px",
|
|
1649
|
+
background: "rgba(0,0,0,0.04)",
|
|
1650
|
+
color,
|
|
1651
|
+
fontSize: "0.875rem",
|
|
1652
|
+
fontWeight: 500
|
|
1653
|
+
},
|
|
1654
|
+
children: [
|
|
1655
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": true, children: icon }),
|
|
1656
|
+
/* @__PURE__ */ jsx("span", { children: text })
|
|
1657
|
+
]
|
|
1658
|
+
}
|
|
1659
|
+
);
|
|
1660
|
+
};
|
|
1661
|
+
|
|
1623
1662
|
const useAppHeight$5 = () => {
|
|
1624
1663
|
useEffect(() => {
|
|
1625
1664
|
const setDrawerHeight = () => {
|
|
@@ -1796,13 +1835,14 @@ function useComponentInteraction({
|
|
|
1796
1835
|
}) {
|
|
1797
1836
|
const [isConfirmed, setIsConfirmed] = useState(false);
|
|
1798
1837
|
const emitInteraction = useCallback(
|
|
1799
|
-
(value, label) => {
|
|
1838
|
+
(value, label, actionId) => {
|
|
1800
1839
|
eventBus?.emit(CHAT_EVENT.COMPONENT_INTERACTION, {
|
|
1801
1840
|
fieldName,
|
|
1802
1841
|
value,
|
|
1803
1842
|
label,
|
|
1804
1843
|
componentType,
|
|
1805
|
-
assistantMessageId
|
|
1844
|
+
assistantMessageId,
|
|
1845
|
+
actionId
|
|
1806
1846
|
});
|
|
1807
1847
|
setIsConfirmed(true);
|
|
1808
1848
|
},
|
|
@@ -2639,6 +2679,22 @@ const ConfirmButton = ({
|
|
|
2639
2679
|
assistantMessageId
|
|
2640
2680
|
});
|
|
2641
2681
|
if (isConfirmed) return null;
|
|
2682
|
+
const actions = component.actions;
|
|
2683
|
+
if (actions && actions.length > 0) {
|
|
2684
|
+
return /* @__PURE__ */ jsx("div", { style: { display: "flex", gap: "8px", flexWrap: "wrap" }, children: actions.map((a) => /* @__PURE__ */ jsx(
|
|
2685
|
+
Button$1,
|
|
2686
|
+
{
|
|
2687
|
+
variant: a.intent === "primary" ? "primary" : "secondary",
|
|
2688
|
+
onClick: () => emitInteraction(
|
|
2689
|
+
a.emits_value ? component.props.value : a.value,
|
|
2690
|
+
a.label,
|
|
2691
|
+
a.id
|
|
2692
|
+
),
|
|
2693
|
+
children: a.label
|
|
2694
|
+
},
|
|
2695
|
+
a.id
|
|
2696
|
+
)) });
|
|
2697
|
+
}
|
|
2642
2698
|
return /* @__PURE__ */ jsx(
|
|
2643
2699
|
Button$1,
|
|
2644
2700
|
{
|
|
@@ -5098,7 +5154,15 @@ const COMPONENT_MAP = {
|
|
|
5098
5154
|
};
|
|
5099
5155
|
function renderComponent(props) {
|
|
5100
5156
|
const { component } = props;
|
|
5101
|
-
if (component.
|
|
5157
|
+
if (component.status) {
|
|
5158
|
+
if (TERMINAL_STATUS.has(component.status)) {
|
|
5159
|
+
const policy = component.visibility_policy ?? "hide_on_terminal";
|
|
5160
|
+
if (policy === "hide_on_terminal") return null;
|
|
5161
|
+
if (component.selected_values && component.selected_values.length > 0) {
|
|
5162
|
+
return /* @__PURE__ */ jsx(AnsweredSummary, { component });
|
|
5163
|
+
}
|
|
5164
|
+
}
|
|
5165
|
+
} else if (component.answered && !DISPLAY_COMPONENTS.has(component.type)) {
|
|
5102
5166
|
return null;
|
|
5103
5167
|
}
|
|
5104
5168
|
const Component = COMPONENT_MAP[component.type];
|
package/dist/index.js
CHANGED
|
@@ -1639,8 +1639,47 @@ function parseContent(content) {
|
|
|
1639
1639
|
return null;
|
|
1640
1640
|
}
|
|
1641
1641
|
|
|
1642
|
+
const TERMINAL_STATUS = /* @__PURE__ */ new Set(["answered", "cancelled", "expired"]);
|
|
1642
1643
|
const DISPLAY_COMPONENTS = /* @__PURE__ */ new Set(["card", "badge", "reactive_form", "carousel"]);
|
|
1643
1644
|
|
|
1645
|
+
const AnsweredSummary = ({ component }) => {
|
|
1646
|
+
const status = component.status;
|
|
1647
|
+
const values = component.selected_values ?? [];
|
|
1648
|
+
const labels = values.map((v) => v.label).filter(Boolean).join(", ");
|
|
1649
|
+
let icon = "\u2713";
|
|
1650
|
+
let text = labels || "Respondido";
|
|
1651
|
+
let color = "#3a8a3a";
|
|
1652
|
+
if (status === "cancelled") {
|
|
1653
|
+
icon = "\u2715";
|
|
1654
|
+
text = "Cancelado";
|
|
1655
|
+
color = "#999";
|
|
1656
|
+
} else if (status === "expired") {
|
|
1657
|
+
icon = "\u231B";
|
|
1658
|
+
text = "Expir\xF3";
|
|
1659
|
+
color = "#b58a00";
|
|
1660
|
+
}
|
|
1661
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1662
|
+
"div",
|
|
1663
|
+
{
|
|
1664
|
+
style: {
|
|
1665
|
+
display: "inline-flex",
|
|
1666
|
+
alignItems: "center",
|
|
1667
|
+
gap: "6px",
|
|
1668
|
+
padding: "6px 12px",
|
|
1669
|
+
borderRadius: "999px",
|
|
1670
|
+
background: "rgba(0,0,0,0.04)",
|
|
1671
|
+
color,
|
|
1672
|
+
fontSize: "0.875rem",
|
|
1673
|
+
fontWeight: 500
|
|
1674
|
+
},
|
|
1675
|
+
children: [
|
|
1676
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": true, children: icon }),
|
|
1677
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: text })
|
|
1678
|
+
]
|
|
1679
|
+
}
|
|
1680
|
+
);
|
|
1681
|
+
};
|
|
1682
|
+
|
|
1644
1683
|
const useAppHeight$5 = () => {
|
|
1645
1684
|
React.useEffect(() => {
|
|
1646
1685
|
const setDrawerHeight = () => {
|
|
@@ -1817,13 +1856,14 @@ function useComponentInteraction({
|
|
|
1817
1856
|
}) {
|
|
1818
1857
|
const [isConfirmed, setIsConfirmed] = React.useState(false);
|
|
1819
1858
|
const emitInteraction = React.useCallback(
|
|
1820
|
-
(value, label) => {
|
|
1859
|
+
(value, label, actionId) => {
|
|
1821
1860
|
eventBus?.emit(CHAT_EVENT.COMPONENT_INTERACTION, {
|
|
1822
1861
|
fieldName,
|
|
1823
1862
|
value,
|
|
1824
1863
|
label,
|
|
1825
1864
|
componentType,
|
|
1826
|
-
assistantMessageId
|
|
1865
|
+
assistantMessageId,
|
|
1866
|
+
actionId
|
|
1827
1867
|
});
|
|
1828
1868
|
setIsConfirmed(true);
|
|
1829
1869
|
},
|
|
@@ -2660,6 +2700,22 @@ const ConfirmButton = ({
|
|
|
2660
2700
|
assistantMessageId
|
|
2661
2701
|
});
|
|
2662
2702
|
if (isConfirmed) return null;
|
|
2703
|
+
const actions = component.actions;
|
|
2704
|
+
if (actions && actions.length > 0) {
|
|
2705
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", gap: "8px", flexWrap: "wrap" }, children: actions.map((a) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2706
|
+
Button$1,
|
|
2707
|
+
{
|
|
2708
|
+
variant: a.intent === "primary" ? "primary" : "secondary",
|
|
2709
|
+
onClick: () => emitInteraction(
|
|
2710
|
+
a.emits_value ? component.props.value : a.value,
|
|
2711
|
+
a.label,
|
|
2712
|
+
a.id
|
|
2713
|
+
),
|
|
2714
|
+
children: a.label
|
|
2715
|
+
},
|
|
2716
|
+
a.id
|
|
2717
|
+
)) });
|
|
2718
|
+
}
|
|
2663
2719
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2664
2720
|
Button$1,
|
|
2665
2721
|
{
|
|
@@ -5119,7 +5175,15 @@ const COMPONENT_MAP = {
|
|
|
5119
5175
|
};
|
|
5120
5176
|
function renderComponent(props) {
|
|
5121
5177
|
const { component } = props;
|
|
5122
|
-
if (component.
|
|
5178
|
+
if (component.status) {
|
|
5179
|
+
if (TERMINAL_STATUS.has(component.status)) {
|
|
5180
|
+
const policy = component.visibility_policy ?? "hide_on_terminal";
|
|
5181
|
+
if (policy === "hide_on_terminal") return null;
|
|
5182
|
+
if (component.selected_values && component.selected_values.length > 0) {
|
|
5183
|
+
return /* @__PURE__ */ jsxRuntime.jsx(AnsweredSummary, { component });
|
|
5184
|
+
}
|
|
5185
|
+
}
|
|
5186
|
+
} else if (component.answered && !DISPLAY_COMPONENTS.has(component.type)) {
|
|
5123
5187
|
return null;
|
|
5124
5188
|
}
|
|
5125
5189
|
const Component = COMPONENT_MAP[component.type];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pixelon",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.29",
|
|
4
4
|
"description": "Design system de la marca goluti",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -24,6 +24,8 @@
|
|
|
24
24
|
"test:run": "vitest run",
|
|
25
25
|
"mobile": "npx storybook dev -p 6006",
|
|
26
26
|
"get:ip": "ipconfig getifaddr en0",
|
|
27
|
+
"gen:ux-types": "node scripts/gen-ux-types.mjs",
|
|
28
|
+
"gen:ux-types:check": "node scripts/gen-ux-types.mjs --check",
|
|
27
29
|
"prepublishOnly": "npm run build:lib"
|
|
28
30
|
},
|
|
29
31
|
"keywords": [
|