@seedgrid/fe-components 2026.6.8 → 2026.7.1
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/ai/seedgrid-components.manifest.json +7114 -330
- package/dist/commons/SgToaster.d.ts +2 -0
- package/dist/commons/SgToaster.d.ts.map +1 -1
- package/dist/commons/SgToaster.js +2 -2
- package/dist/commons/SgToaster.meta.d.ts.map +1 -1
- package/dist/commons/SgToaster.meta.js +2 -1
- package/dist/commons/SgWhistleHost.d.ts +16 -15
- package/dist/commons/SgWhistleHost.d.ts.map +1 -1
- package/dist/commons/SgWhistleHost.js +38 -147
- package/dist/commons/SgWhistleHost.meta.d.ts.map +1 -1
- package/dist/commons/SgWhistleHost.meta.js +17 -15
- package/dist/commons/SgWhistler.d.ts +20 -0
- package/dist/commons/SgWhistler.d.ts.map +1 -0
- package/dist/commons/SgWhistler.js +168 -0
- package/dist/commons/SgWhistler.meta.d.ts +4 -0
- package/dist/commons/SgWhistler.meta.d.ts.map +1 -0
- package/dist/commons/SgWhistler.meta.js +47 -0
- package/dist/commons/sgWhistleHostRegistry.d.ts +7 -0
- package/dist/commons/sgWhistleHostRegistry.d.ts.map +1 -0
- package/dist/commons/sgWhistleHostRegistry.js +42 -0
- package/dist/gadgets/clock/themes/SgClockThemePicker.d.ts.map +1 -1
- package/dist/gadgets/clock/themes/SgClockThemePicker.js +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/inputs/SgCombobox.d.ts.map +1 -1
- package/dist/inputs/SgCombobox.js +6 -2
- package/dist/inputs/SgInputPassword.d.ts +1 -0
- package/dist/inputs/SgInputPassword.d.ts.map +1 -1
- package/dist/inputs/SgPeriodSelector.d.ts +103 -0
- package/dist/inputs/SgPeriodSelector.d.ts.map +1 -0
- package/dist/inputs/SgPeriodSelector.js +368 -0
- package/dist/inputs/SgPeriodSelector.meta.d.ts +4 -0
- package/dist/inputs/SgPeriodSelector.meta.d.ts.map +1 -0
- package/dist/inputs/SgPeriodSelector.meta.js +55 -0
- package/dist/layout/SgMenu.d.ts.map +1 -1
- package/dist/layout/SgMenu.js +1 -1
- package/dist/rhf.d.ts +20 -5
- package/dist/rhf.d.ts.map +1 -1
- package/dist/sandbox.cjs +45 -45
- package/package.json +3 -3
|
@@ -14,6 +14,8 @@ export type SgToasterProps = Omit<React.HTMLAttributes<HTMLDivElement>, "childre
|
|
|
14
14
|
closeButton?: boolean;
|
|
15
15
|
richColors?: boolean;
|
|
16
16
|
transparency?: number;
|
|
17
|
+
/** Arredonda os cantos de cada toast (rounded-md). Desligue para cantos retos. */
|
|
18
|
+
rounded?: boolean;
|
|
17
19
|
customColors?: SgToasterCustomColors;
|
|
18
20
|
};
|
|
19
21
|
/** @internal — used by SgToastHost to skip the host-presence check */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SgToaster.d.ts","sourceRoot":"","sources":["../../src/commons/SgToaster.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAqC,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AAQlF,MAAM,MAAM,iBAAiB,GACzB,WAAW,GACX,UAAU,GACV,YAAY,GACZ,cAAc,GACd,aAAa,GACb,eAAe,CAAC;AAEpB,MAAM,MAAM,mBAAmB,GAAG;IAChC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,OAAO,CACzC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,mBAAmB,CAAC,CACnD,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC,GAAG;IACpF,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,qBAAqB,CAAC;CACtC,CAAC;AAgGF,sEAAsE;AACtE,eAAO,MAAM,oBAAoB,wBAA6B,CAAC;AAE/D,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"SgToaster.d.ts","sourceRoot":"","sources":["../../src/commons/SgToaster.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAqC,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AAQlF,MAAM,MAAM,iBAAiB,GACzB,WAAW,GACX,UAAU,GACV,YAAY,GACZ,cAAc,GACd,aAAa,GACb,eAAe,CAAC;AAEpB,MAAM,MAAM,mBAAmB,GAAG;IAChC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,OAAO,CACzC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,mBAAmB,CAAC,CACnD,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC,GAAG;IACpF,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kFAAkF;IAClF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,qBAAqB,CAAC;CACtC,CAAC;AAgGF,sEAAsE;AACtE,eAAO,MAAM,oBAAoB,wBAA6B,CAAC;AAE/D,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,kDAgJ9C"}
|
|
@@ -97,7 +97,7 @@ function resolveToastColors(type, richColors, customColors) {
|
|
|
97
97
|
export const SgToasterHostContext = React.createContext(false);
|
|
98
98
|
export function SgToaster(props) {
|
|
99
99
|
const renderedByHost = React.useContext(SgToasterHostContext);
|
|
100
|
-
const { position = "top-right", duration = 4000, visibleToasts = 6, closeButton = true, richColors = true, transparency = 0, customColors, className, style, ...rest } = props;
|
|
100
|
+
const { position = "top-right", duration = 4000, visibleToasts = 6, closeButton = true, richColors = true, transparency = 0, rounded = true, customColors, className, style, ...rest } = props;
|
|
101
101
|
const i18n = useComponentsI18n();
|
|
102
102
|
const [toasts, setToasts] = React.useState([]);
|
|
103
103
|
const timersRef = React.useRef({});
|
|
@@ -155,7 +155,7 @@ export function SgToaster(props) {
|
|
|
155
155
|
return (_jsx("div", { className: cn("pointer-events-none fixed z-[1100] flex max-h-screen w-full flex-col gap-2 p-4 sm:w-auto", POSITION_CLASS[position], className), style: style, ...rest, children: visible.map((toast) => {
|
|
156
156
|
const typeColors = resolveToastColors(toast.type, richColors, customColors);
|
|
157
157
|
const canClose = toast.closeButton ?? closeButton;
|
|
158
|
-
return (_jsxs("div", { className: cn("pointer-events-auto flex min-w-[260px] max-w-[420px] items-start gap-3
|
|
158
|
+
return (_jsxs("div", { className: cn("pointer-events-auto flex min-w-[260px] max-w-[420px] items-start gap-3 border px-3 py-2 shadow-lg", rounded ? "rounded-md" : "rounded-none", toast.className), style: {
|
|
159
159
|
borderColor: typeColors.border,
|
|
160
160
|
backgroundColor: typeColors.bg,
|
|
161
161
|
color: typeColors.fg,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SgToaster.meta.d.ts","sourceRoot":"","sources":["../../src/commons/SgToaster.meta.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE9D,eAAO,MAAM,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"SgToaster.meta.d.ts","sourceRoot":"","sources":["../../src/commons/SgToaster.meta.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE9D,eAAO,MAAM,MAAM,EAAE,QA6BpB,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,WAmBrB,CAAC"}
|
|
@@ -16,7 +16,8 @@ export const sgMeta = {
|
|
|
16
16
|
{ name: "duration", type: "number", default: 4000, description: "Duracao padrao dos toasts em milissegundos.", semanticRole: "behavior", bindable: true },
|
|
17
17
|
{ name: "visibleToasts", type: "number", default: 6, description: "Quantidade maxima de toasts visiveis simultaneamente.", semanticRole: "behavior", bindable: true },
|
|
18
18
|
{ name: "closeButton", type: "boolean", default: true, description: "Exibe botao de fechar em cada toast.", semanticRole: "appearance", bindable: true },
|
|
19
|
-
{ name: "richColors", type: "boolean", default: true, description: "Ativa paleta visual rica por tipo de toast.", semanticRole: "appearance", bindable: true }
|
|
19
|
+
{ name: "richColors", type: "boolean", default: true, description: "Ativa paleta visual rica por tipo de toast.", semanticRole: "appearance", bindable: true },
|
|
20
|
+
{ name: "rounded", type: "boolean", default: true, description: "Arredonda os cantos de cada toast (desligue para cantos retos).", semanticRole: "appearance", bindable: true }
|
|
20
21
|
],
|
|
21
22
|
states: ["idle", "showing-toasts"],
|
|
22
23
|
examples: [
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
1
|
+
import { type SgWhistlerProps } from "./SgWhistler";
|
|
2
|
+
export type SgWhistleHostProps = SgWhistlerProps;
|
|
3
|
+
/**
|
|
4
|
+
* SgWhistleHost — marca o local onde os whistles vao aparecer.
|
|
5
|
+
*
|
|
6
|
+
* Monte em qualquer ponto da arvore. Se existirem varios hosts ao mesmo tempo
|
|
7
|
+
* (ex.: um no topo e outro embaixo do layout), o mais profundo na arvore React
|
|
8
|
+
* (ultimo a montar) tem prioridade. Quando ele desmonta, o host montado mais
|
|
9
|
+
* recentemente antes dele volta a ficar ativo automaticamente.
|
|
10
|
+
*
|
|
11
|
+
* Quando qualquer SgWhistleHost esta presente, o SgWhistler "solto" cede a vez
|
|
12
|
+
* e para de renderizar, para os dois coexistirem sem duplicar.
|
|
13
|
+
*
|
|
14
|
+
* Aceita os mesmos props do SgWhistler (max, newestOnTop, gap, roundBorder, etc.).
|
|
15
|
+
*/
|
|
16
|
+
export declare function SgWhistleHost(props: SgWhistleHostProps): import("react/jsx-runtime").JSX.Element | null;
|
|
16
17
|
//# sourceMappingURL=SgWhistleHost.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SgWhistleHost.d.ts","sourceRoot":"","sources":["../../src/commons/SgWhistleHost.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SgWhistleHost.d.ts","sourceRoot":"","sources":["../../src/commons/SgWhistleHost.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAqC,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAavF,MAAM,MAAM,kBAAkB,GAAG,eAAe,CAAC;AAEjD;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,kDAiCtD"}
|
|
@@ -1,154 +1,45 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import React from "react";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
},
|
|
20
|
-
info: {
|
|
21
|
-
bg: "#eff6ff",
|
|
22
|
-
fg: "#1e3a8a",
|
|
23
|
-
border: "#93c5fd"
|
|
24
|
-
},
|
|
25
|
-
warning: {
|
|
26
|
-
bg: "#fffbeb",
|
|
27
|
-
fg: "#78350f",
|
|
28
|
-
border: "#fcd34d"
|
|
29
|
-
},
|
|
30
|
-
error: {
|
|
31
|
-
bg: "#fef2f2",
|
|
32
|
-
fg: "#7f1d1d",
|
|
33
|
-
border: "#fca5a5"
|
|
34
|
-
},
|
|
35
|
-
loading: {
|
|
36
|
-
bg: "#eff6ff",
|
|
37
|
-
fg: "#1d4ed8",
|
|
38
|
-
border: "#60a5fa"
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
function clampOpacity(value) {
|
|
42
|
-
if (value === undefined || Number.isNaN(value)) {
|
|
43
|
-
return 1;
|
|
44
|
-
}
|
|
45
|
-
return Math.max(0, Math.min(1, value));
|
|
46
|
-
}
|
|
47
|
-
function resolveColors(severity, customColors) {
|
|
48
|
-
const base = DEFAULT_COLORS[severity];
|
|
49
|
-
const custom = customColors?.[severity];
|
|
50
|
-
return {
|
|
51
|
-
bg: custom?.bg ?? base.bg,
|
|
52
|
-
fg: custom?.fg ?? base.fg,
|
|
53
|
-
border: custom?.border ?? base.border
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
function buildBorderStyle(borderStyle, colors) {
|
|
57
|
-
if (borderStyle === "none") {
|
|
58
|
-
return {
|
|
59
|
-
borderWidth: 0
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
if (borderStyle === "left-accent") {
|
|
63
|
-
return {
|
|
64
|
-
borderWidth: 1,
|
|
65
|
-
borderColor: colors.border,
|
|
66
|
-
borderLeftWidth: 4
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
if (borderStyle === "full-accent") {
|
|
70
|
-
return {
|
|
71
|
-
borderWidth: 1,
|
|
72
|
-
borderColor: colors.border,
|
|
73
|
-
boxShadow: `inset 0 0 0 1px ${colors.border}`
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
if (borderStyle === "soft") {
|
|
77
|
-
return {
|
|
78
|
-
borderWidth: 1,
|
|
79
|
-
borderColor: colors.border,
|
|
80
|
-
boxShadow: "0 1px 2px rgba(15, 23, 42, 0.06)"
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
return {
|
|
84
|
-
borderWidth: 1,
|
|
85
|
-
borderColor: colors.border
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
function renderWhistleContent(whistle) {
|
|
89
|
-
if (whistle.renderer !== undefined) {
|
|
90
|
-
return whistle.renderer;
|
|
91
|
-
}
|
|
92
|
-
return (_jsxs("div", { className: "min-w-0 flex-1", children: [whistle.title ? _jsx("div", { className: "text-sm font-semibold", children: whistle.title }) : null, whistle.message ? _jsx("div", { className: cn(whistle.title ? "mt-0.5" : undefined, "text-sm"), children: whistle.message }) : null] }));
|
|
93
|
-
}
|
|
4
|
+
import { SgWhistler, SgWhistlerHostContext } from "./SgWhistler";
|
|
5
|
+
import { registerWhistleHost, unregisterWhistleHost, getActiveWhistleHostId, subscribeWhistleHostRegistry, nextWhistleHostId } from "./sgWhistleHostRegistry";
|
|
6
|
+
/**
|
|
7
|
+
* SgWhistleHost — marca o local onde os whistles vao aparecer.
|
|
8
|
+
*
|
|
9
|
+
* Monte em qualquer ponto da arvore. Se existirem varios hosts ao mesmo tempo
|
|
10
|
+
* (ex.: um no topo e outro embaixo do layout), o mais profundo na arvore React
|
|
11
|
+
* (ultimo a montar) tem prioridade. Quando ele desmonta, o host montado mais
|
|
12
|
+
* recentemente antes dele volta a ficar ativo automaticamente.
|
|
13
|
+
*
|
|
14
|
+
* Quando qualquer SgWhistleHost esta presente, o SgWhistler "solto" cede a vez
|
|
15
|
+
* e para de renderizar, para os dois coexistirem sem duplicar.
|
|
16
|
+
*
|
|
17
|
+
* Aceita os mesmos props do SgWhistler (max, newestOnTop, gap, roundBorder, etc.).
|
|
18
|
+
*/
|
|
94
19
|
export function SgWhistleHost(props) {
|
|
95
|
-
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const items = whistles.slice(-max);
|
|
105
|
-
return newestOnTop ? [...items].reverse() : items;
|
|
106
|
-
}, [whistles, max, newestOnTop]);
|
|
107
|
-
React.useEffect(() => {
|
|
108
|
-
const activeIds = new Set();
|
|
109
|
-
visible.forEach((whistle) => {
|
|
110
|
-
activeIds.add(whistle.id);
|
|
111
|
-
if (timersRef.current[whistle.id]) {
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
if (whistle.severity === "loading") {
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
const timeout = whistle.duration ?? 5000;
|
|
118
|
-
if (timeout <= 0) {
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
timersRef.current[whistle.id] = setTimeout(() => {
|
|
122
|
-
dismissSgWhistle(whistle.id);
|
|
123
|
-
delete timersRef.current[whistle.id];
|
|
124
|
-
}, timeout);
|
|
125
|
-
});
|
|
126
|
-
Object.entries(timersRef.current).forEach(([id, timeoutRef]) => {
|
|
127
|
-
if (activeIds.has(id)) {
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
clearTimeout(timeoutRef);
|
|
131
|
-
delete timersRef.current[id];
|
|
132
|
-
});
|
|
133
|
-
}, [visible]);
|
|
20
|
+
// ID estavel entre re-renders, gerado uma vez por instancia.
|
|
21
|
+
const idRef = React.useRef(null);
|
|
22
|
+
if (idRef.current === null) {
|
|
23
|
+
idRef.current = nextWhistleHostId();
|
|
24
|
+
}
|
|
25
|
+
const id = idRef.current;
|
|
26
|
+
// Comeca inativo para evitar mismatch de hidratacao no SSR.
|
|
27
|
+
const [isActive, setIsActive] = React.useState(false);
|
|
28
|
+
// Registra no mount, desregistra no unmount.
|
|
134
29
|
React.useEffect(() => {
|
|
30
|
+
registerWhistleHost(id);
|
|
31
|
+
setIsActive(getActiveWhistleHostId() === id);
|
|
135
32
|
return () => {
|
|
136
|
-
|
|
137
|
-
timersRef.current = {};
|
|
33
|
+
unregisterWhistleHost(id);
|
|
138
34
|
};
|
|
139
|
-
}, []);
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}, role: "status", "aria-live": "polite", children: [whistle.icon ? _jsx("div", { className: "shrink-0 pt-0.5", children: whistle.icon }) : null, renderWhistleContent(whistle), whistle.action ? (_jsx("button", { type: "button", className: "shrink-0 rounded border border-current/25 px-2 py-1 text-xs font-medium", onClick: () => {
|
|
150
|
-
whistle.action?.onClick();
|
|
151
|
-
dismissSgWhistle(whistle.id);
|
|
152
|
-
}, children: whistle.action.label })) : null, dismissible ? (_jsx("button", { type: "button", className: "shrink-0 rounded px-1 py-0.5 text-sm leading-none opacity-80", "aria-label": t(i18n, "components.toaster.close"), onClick: () => dismissSgWhistle(whistle.id), children: "x" })) : null] }, whistle.id));
|
|
153
|
-
}) }));
|
|
35
|
+
}, [id]);
|
|
36
|
+
// Reage a outros hosts registrando / desregistrando.
|
|
37
|
+
React.useEffect(() => {
|
|
38
|
+
return subscribeWhistleHostRegistry(() => {
|
|
39
|
+
setIsActive(getActiveWhistleHostId() === id);
|
|
40
|
+
});
|
|
41
|
+
}, [id]);
|
|
42
|
+
if (!isActive)
|
|
43
|
+
return null;
|
|
44
|
+
return (_jsx(SgWhistlerHostContext.Provider, { value: true, children: _jsx(SgWhistler, { ...props }) }));
|
|
154
45
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SgWhistleHost.meta.d.ts","sourceRoot":"","sources":["../../src/commons/SgWhistleHost.meta.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE9D,eAAO,MAAM,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"SgWhistleHost.meta.d.ts","sourceRoot":"","sources":["../../src/commons/SgWhistleHost.meta.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE9D,eAAO,MAAM,MAAM,EAAE,QA2BpB,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,WAoBrB,CAAC"}
|
|
@@ -7,39 +7,41 @@ export const sgMeta = {
|
|
|
7
7
|
displayName: "SgWhistleHost",
|
|
8
8
|
category: "feedback",
|
|
9
9
|
subcategory: "whistle-host",
|
|
10
|
-
description: "
|
|
11
|
-
tags: ["feedback", "alerts", "host", "inline-notifications"],
|
|
12
|
-
capabilities: ["alert-stacking", "severity-colors", "dismissible-items", "timed-dismiss"],
|
|
10
|
+
description: "Marca o local onde os whistles aparecem. Suporta varios hosts simultaneos (ex.: topo e rodape) via registry: apenas o ultimo montado fica ativo, e o SgWhistler solto cede a vez quando qualquer host esta presente.",
|
|
11
|
+
tags: ["feedback", "alerts", "host", "inline-notifications", "registry"],
|
|
12
|
+
capabilities: ["alert-stacking", "severity-colors", "dismissible-items", "timed-dismiss", "multi-host-registry"],
|
|
13
13
|
fieldSemantics: ["alertHost", "persistentFeedback", "stackedAlerts"],
|
|
14
14
|
props: [
|
|
15
|
-
{ name: "max", type: "number", default: 4, description: "Quantidade maxima de whistle items visiveis.", semanticRole: "behavior", bindable: true },
|
|
15
|
+
{ name: "max", type: "number", default: 4, description: "Quantidade maxima de whistle items visiveis neste host.", semanticRole: "behavior", bindable: true },
|
|
16
16
|
{ name: "newestOnTop", type: "boolean", default: false, description: "Inverte a ordem visual para mostrar os mais novos primeiro.", semanticRole: "behavior", bindable: true },
|
|
17
|
-
{ name: "gap", type: "number", default: 12, description: "Espacamento entre os avisos renderizados.", semanticRole: "appearance", bindable: true }
|
|
17
|
+
{ name: "gap", type: "number", default: 12, description: "Espacamento entre os avisos renderizados.", semanticRole: "appearance", bindable: true },
|
|
18
|
+
{ name: "rounded", type: "boolean", default: true, description: "Arredonda os cantos de cada whistle (desligue para cantos retos).", semanticRole: "appearance", bindable: true }
|
|
18
19
|
],
|
|
19
|
-
states: ["idle", "showing-alerts"],
|
|
20
|
+
states: ["idle", "showing-alerts", "inactive"],
|
|
20
21
|
examples: [
|
|
21
|
-
{ id: "basic", title: "Basico", file: "apps/showcase/src/app/components/sg-whistle-host/samples/
|
|
22
|
+
{ id: "basic", title: "Basico", file: "apps/showcase/src/app/components/sg-whistle-host/samples/base-setup.tsx.sample", kind: "sample" },
|
|
22
23
|
{ id: "playground", title: "Playground", file: "apps/showcase/src/app/components/sg-whistle-host/sg-whistle-host.tsx.playground", kind: "playground" }
|
|
23
24
|
],
|
|
24
25
|
showcase: { route: "/components/sg-whistle-host", hasPlayground: true, hasPropsTable: true },
|
|
25
|
-
sdui: { rendererType: "feedback.whistle-host", acceptsDataBinding: false, defaultProps: { max: 4, newestOnTop: false } }
|
|
26
|
+
sdui: { rendererType: "feedback.whistle-host", acceptsDataBinding: false, defaultProps: { max: 4, newestOnTop: false, rounded: true } }
|
|
26
27
|
};
|
|
27
28
|
export const aiHints = {
|
|
28
29
|
version: "0.1",
|
|
29
30
|
preferredUseCases: [
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
31
|
+
"Definir um ou mais pontos fixos onde os avisos empilhados devem aparecer.",
|
|
32
|
+
"Layouts com hosts em zonas diferentes (ex.: um no topo e outro embaixo), com prioridade automatica ao ultimo montado.",
|
|
33
|
+
"Comunicar erros, warnings e mensagens operacionais inline em area fixa."
|
|
33
34
|
],
|
|
34
35
|
avoidUseCases: [
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
36
|
+
"Um unico ponto de exibicao sem necessidade de registry; ai o SgWhistler basta.",
|
|
37
|
+
"Feedback ultraleve e efemero; prefira toaster.",
|
|
38
|
+
"Modais de confirmacao."
|
|
38
39
|
],
|
|
39
|
-
synonyms: ["alert host", "message stack", "persistent notifications"],
|
|
40
|
+
synonyms: ["alert host", "message stack host", "persistent notifications host"],
|
|
40
41
|
relatedEntityFields: ["alerts", "warnings", "inlineMessages", "systemMessages"],
|
|
41
42
|
compositionHints: [
|
|
42
43
|
"Usar com a API `sgWhistle` para publicar avisos.",
|
|
44
|
+
"Espelha o par SgToaster/SgToastHost: SgWhistler e o renderizador, SgWhistleHost e o host com registry.",
|
|
43
45
|
"Combinar com SgCard ou SgPanel em dashboards operacionais."
|
|
44
46
|
],
|
|
45
47
|
rankingSignals: { freeText: 0, structuredChoice: 0, date: 0, number: 0, denseLayout: 0.7 }
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { type SgWhistleSeverity } from "./SgWhistle";
|
|
3
|
+
type SgWhistleColors = {
|
|
4
|
+
bg: string;
|
|
5
|
+
fg: string;
|
|
6
|
+
border: string;
|
|
7
|
+
};
|
|
8
|
+
export type SgWhistlerProps = Omit<React.HTMLAttributes<HTMLDivElement>, "children"> & {
|
|
9
|
+
max?: number;
|
|
10
|
+
newestOnTop?: boolean;
|
|
11
|
+
gap?: number;
|
|
12
|
+
/** Arredonda os cantos de cada whistle (rounded-lg). Desligue para cantos retos. */
|
|
13
|
+
rounded?: boolean;
|
|
14
|
+
customColors?: Partial<Record<SgWhistleSeverity, SgWhistleColors>>;
|
|
15
|
+
};
|
|
16
|
+
/** @internal — usado por SgWhistleHost para pular a checagem de presenca de host. */
|
|
17
|
+
export declare const SgWhistlerHostContext: React.Context<boolean>;
|
|
18
|
+
export declare function SgWhistler(props: SgWhistlerProps): import("react/jsx-runtime").JSX.Element | null;
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=SgWhistler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SgWhistler.d.ts","sourceRoot":"","sources":["../../src/commons/SgWhistler.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAKL,KAAK,iBAAiB,EACvB,MAAM,aAAa,CAAC;AAOrB,KAAK,eAAe,GAAG;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC,GAAG;IACrF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oFAAoF;IACpF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,eAAe,CAAC,CAAC,CAAC;CACpE,CAAC;AAEF,qFAAqF;AACrF,eAAO,MAAM,qBAAqB,wBAA6B,CAAC;AA2GhE,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,kDA6IhD"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import React from "react";
|
|
4
|
+
import { t, useComponentsI18n } from "../i18n";
|
|
5
|
+
import { dismissSgWhistle, subscribeSgWhistles } from "./SgWhistle";
|
|
6
|
+
import { hasAnyWhistleHost, subscribeWhistleHostRegistry } from "./sgWhistleHostRegistry";
|
|
7
|
+
function cn(...parts) {
|
|
8
|
+
return parts.filter(Boolean).join(" ");
|
|
9
|
+
}
|
|
10
|
+
/** @internal — usado por SgWhistleHost para pular a checagem de presenca de host. */
|
|
11
|
+
export const SgWhistlerHostContext = React.createContext(false);
|
|
12
|
+
const DEFAULT_COLORS = {
|
|
13
|
+
default: {
|
|
14
|
+
bg: "hsl(var(--background))",
|
|
15
|
+
fg: "hsl(var(--foreground))",
|
|
16
|
+
border: "hsl(var(--border))"
|
|
17
|
+
},
|
|
18
|
+
success: {
|
|
19
|
+
bg: "#f0fdf4",
|
|
20
|
+
fg: "#14532d",
|
|
21
|
+
border: "#86efac"
|
|
22
|
+
},
|
|
23
|
+
info: {
|
|
24
|
+
bg: "#eff6ff",
|
|
25
|
+
fg: "#1e3a8a",
|
|
26
|
+
border: "#93c5fd"
|
|
27
|
+
},
|
|
28
|
+
warning: {
|
|
29
|
+
bg: "#fffbeb",
|
|
30
|
+
fg: "#78350f",
|
|
31
|
+
border: "#fcd34d"
|
|
32
|
+
},
|
|
33
|
+
error: {
|
|
34
|
+
bg: "#fef2f2",
|
|
35
|
+
fg: "#7f1d1d",
|
|
36
|
+
border: "#fca5a5"
|
|
37
|
+
},
|
|
38
|
+
loading: {
|
|
39
|
+
bg: "#eff6ff",
|
|
40
|
+
fg: "#1d4ed8",
|
|
41
|
+
border: "#60a5fa"
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
function clampOpacity(value) {
|
|
45
|
+
if (value === undefined || Number.isNaN(value)) {
|
|
46
|
+
return 1;
|
|
47
|
+
}
|
|
48
|
+
return Math.max(0, Math.min(1, value));
|
|
49
|
+
}
|
|
50
|
+
function resolveColors(severity, customColors) {
|
|
51
|
+
const base = DEFAULT_COLORS[severity];
|
|
52
|
+
const custom = customColors?.[severity];
|
|
53
|
+
return {
|
|
54
|
+
bg: custom?.bg ?? base.bg,
|
|
55
|
+
fg: custom?.fg ?? base.fg,
|
|
56
|
+
border: custom?.border ?? base.border
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function buildBorderStyle(borderStyle, colors) {
|
|
60
|
+
if (borderStyle === "none") {
|
|
61
|
+
return {
|
|
62
|
+
borderWidth: 0
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
if (borderStyle === "left-accent") {
|
|
66
|
+
return {
|
|
67
|
+
borderWidth: 1,
|
|
68
|
+
borderColor: colors.border,
|
|
69
|
+
borderLeftWidth: 4
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
if (borderStyle === "full-accent") {
|
|
73
|
+
return {
|
|
74
|
+
borderWidth: 1,
|
|
75
|
+
borderColor: colors.border,
|
|
76
|
+
boxShadow: `inset 0 0 0 1px ${colors.border}`
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
if (borderStyle === "soft") {
|
|
80
|
+
return {
|
|
81
|
+
borderWidth: 1,
|
|
82
|
+
borderColor: colors.border,
|
|
83
|
+
boxShadow: "0 1px 2px rgba(15, 23, 42, 0.06)"
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
borderWidth: 1,
|
|
88
|
+
borderColor: colors.border
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function renderWhistleContent(whistle) {
|
|
92
|
+
if (whistle.renderer !== undefined) {
|
|
93
|
+
return whistle.renderer;
|
|
94
|
+
}
|
|
95
|
+
return (_jsxs("div", { className: "min-w-0 flex-1", children: [whistle.title ? _jsx("div", { className: "text-sm font-semibold", children: whistle.title }) : null, whistle.message ? _jsx("div", { className: cn(whistle.title ? "mt-0.5" : undefined, "text-sm"), children: whistle.message }) : null] }));
|
|
96
|
+
}
|
|
97
|
+
export function SgWhistler(props) {
|
|
98
|
+
const renderedByHost = React.useContext(SgWhistlerHostContext);
|
|
99
|
+
const { max = 4, newestOnTop = false, gap = 12, rounded = true, customColors, className, style, ...rest } = props;
|
|
100
|
+
const i18n = useComponentsI18n();
|
|
101
|
+
const [whistles, setWhistles] = React.useState([]);
|
|
102
|
+
const timersRef = React.useRef({});
|
|
103
|
+
// Se houver algum SgWhistleHost montado, o SgWhistler "solto" cede a vez (evita duplicar).
|
|
104
|
+
const [hostPresent, setHostPresent] = React.useState(() => !renderedByHost && hasAnyWhistleHost());
|
|
105
|
+
React.useEffect(() => subscribeSgWhistles(setWhistles), []);
|
|
106
|
+
React.useEffect(() => {
|
|
107
|
+
if (renderedByHost)
|
|
108
|
+
return;
|
|
109
|
+
setHostPresent(hasAnyWhistleHost());
|
|
110
|
+
return subscribeWhistleHostRegistry(() => setHostPresent(hasAnyWhistleHost()));
|
|
111
|
+
}, [renderedByHost]);
|
|
112
|
+
const visible = React.useMemo(() => {
|
|
113
|
+
if (max <= 0) {
|
|
114
|
+
return [];
|
|
115
|
+
}
|
|
116
|
+
const items = whistles.slice(-max);
|
|
117
|
+
return newestOnTop ? [...items].reverse() : items;
|
|
118
|
+
}, [whistles, max, newestOnTop]);
|
|
119
|
+
React.useEffect(() => {
|
|
120
|
+
const activeIds = new Set();
|
|
121
|
+
visible.forEach((whistle) => {
|
|
122
|
+
activeIds.add(whistle.id);
|
|
123
|
+
if (timersRef.current[whistle.id]) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (whistle.severity === "loading") {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const timeout = whistle.duration ?? 5000;
|
|
130
|
+
if (timeout <= 0) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
timersRef.current[whistle.id] = setTimeout(() => {
|
|
134
|
+
dismissSgWhistle(whistle.id);
|
|
135
|
+
delete timersRef.current[whistle.id];
|
|
136
|
+
}, timeout);
|
|
137
|
+
});
|
|
138
|
+
Object.entries(timersRef.current).forEach(([id, timeoutRef]) => {
|
|
139
|
+
if (activeIds.has(id)) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
clearTimeout(timeoutRef);
|
|
143
|
+
delete timersRef.current[id];
|
|
144
|
+
});
|
|
145
|
+
}, [visible]);
|
|
146
|
+
React.useEffect(() => {
|
|
147
|
+
return () => {
|
|
148
|
+
Object.values(timersRef.current).forEach((timeoutRef) => clearTimeout(timeoutRef));
|
|
149
|
+
timersRef.current = {};
|
|
150
|
+
};
|
|
151
|
+
}, []);
|
|
152
|
+
if (hostPresent)
|
|
153
|
+
return null;
|
|
154
|
+
return (_jsx("div", { className: cn("flex flex-col", className), style: { gap, ...style }, ...rest, children: visible.map((whistle) => {
|
|
155
|
+
const colors = resolveColors(whistle.severity, customColors);
|
|
156
|
+
const dismissible = whistle.dismissible ?? true;
|
|
157
|
+
return (_jsxs("div", { className: cn("flex items-start gap-3 px-3 py-2", rounded ? "rounded-lg" : "rounded-none", whistle.borderStyle === "none" ? undefined : "border", whistle.className), style: {
|
|
158
|
+
backgroundColor: colors.bg,
|
|
159
|
+
color: colors.fg,
|
|
160
|
+
opacity: clampOpacity(whistle.opacity),
|
|
161
|
+
...buildBorderStyle(whistle.borderStyle ?? "solid", colors),
|
|
162
|
+
...whistle.style
|
|
163
|
+
}, role: "status", "aria-live": "polite", children: [whistle.icon ? _jsx("div", { className: "shrink-0 pt-0.5", children: whistle.icon }) : null, renderWhistleContent(whistle), whistle.action ? (_jsx("button", { type: "button", className: "shrink-0 rounded border border-current/25 px-2 py-1 text-xs font-medium", onClick: () => {
|
|
164
|
+
whistle.action?.onClick();
|
|
165
|
+
dismissSgWhistle(whistle.id);
|
|
166
|
+
}, children: whistle.action.label })) : null, dismissible ? (_jsx("button", { type: "button", className: "shrink-0 rounded px-1 py-0.5 text-sm leading-none opacity-80", "aria-label": t(i18n, "components.toaster.close"), onClick: () => dismissSgWhistle(whistle.id), children: "x" })) : null] }, whistle.id));
|
|
167
|
+
}) }));
|
|
168
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SgWhistler.meta.d.ts","sourceRoot":"","sources":["../../src/commons/SgWhistler.meta.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE9D,eAAO,MAAM,MAAM,EAAE,QA2BpB,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,WAmBrB,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export const sgMeta = {
|
|
2
|
+
version: "0.1",
|
|
3
|
+
componentId: "feedback.whistler",
|
|
4
|
+
package: "@seedgrid/fe-components",
|
|
5
|
+
exportName: "SgWhistler",
|
|
6
|
+
slug: "sg-whistler",
|
|
7
|
+
displayName: "SgWhistler",
|
|
8
|
+
category: "feedback",
|
|
9
|
+
subcategory: "whistler",
|
|
10
|
+
description: "Renderizador de avisos persistentes ou semi-persistentes em pilha, com cores por severidade, acao opcional e controle de maximo visivel. Cede a vez quando um SgWhistleHost esta presente.",
|
|
11
|
+
tags: ["feedback", "alerts", "renderer", "inline-notifications"],
|
|
12
|
+
capabilities: ["alert-stacking", "severity-colors", "dismissible-items", "timed-dismiss"],
|
|
13
|
+
fieldSemantics: ["alertRenderer", "persistentFeedback", "stackedAlerts"],
|
|
14
|
+
props: [
|
|
15
|
+
{ name: "max", type: "number", default: 4, description: "Quantidade maxima de whistle items visiveis.", semanticRole: "behavior", bindable: true },
|
|
16
|
+
{ name: "newestOnTop", type: "boolean", default: false, description: "Inverte a ordem visual para mostrar os mais novos primeiro.", semanticRole: "behavior", bindable: true },
|
|
17
|
+
{ name: "gap", type: "number", default: 12, description: "Espacamento entre os avisos renderizados.", semanticRole: "appearance", bindable: true },
|
|
18
|
+
{ name: "rounded", type: "boolean", default: true, description: "Arredonda os cantos de cada whistle (desligue para cantos retos).", semanticRole: "appearance", bindable: true }
|
|
19
|
+
],
|
|
20
|
+
states: ["idle", "showing-alerts"],
|
|
21
|
+
examples: [
|
|
22
|
+
{ id: "basic", title: "Basico", file: "apps/showcase/src/app/components/sg-whistler/samples/base-setup.tsx.sample", kind: "sample" },
|
|
23
|
+
{ id: "playground", title: "Playground", file: "apps/showcase/src/app/components/sg-whistler/sg-whistler.tsx.playground", kind: "playground" }
|
|
24
|
+
],
|
|
25
|
+
showcase: { route: "/components/sg-whistler", hasPlayground: true, hasPropsTable: true },
|
|
26
|
+
sdui: { rendererType: "feedback.whistler", acceptsDataBinding: false, defaultProps: { max: 4, newestOnTop: false, rounded: true } }
|
|
27
|
+
};
|
|
28
|
+
export const aiHints = {
|
|
29
|
+
version: "0.1",
|
|
30
|
+
preferredUseCases: [
|
|
31
|
+
"Exibir avisos empilhados mais persistentes do que um toast em uma area fixa.",
|
|
32
|
+
"Comunicar erros, warnings e mensagens operacionais inline.",
|
|
33
|
+
"Agrupar alertas com acao e dismiss local, sem precisar de multiplos pontos de montagem."
|
|
34
|
+
],
|
|
35
|
+
avoidUseCases: [
|
|
36
|
+
"Precisar de varios pontos de montagem coexistindo; nesses casos use SgWhistleHost.",
|
|
37
|
+
"Feedback ultraleve e efemero; prefira toaster.",
|
|
38
|
+
"Modais de confirmacao."
|
|
39
|
+
],
|
|
40
|
+
synonyms: ["alert renderer", "message stack", "persistent notifications"],
|
|
41
|
+
relatedEntityFields: ["alerts", "warnings", "inlineMessages", "systemMessages"],
|
|
42
|
+
compositionHints: [
|
|
43
|
+
"Usar com a API `sgWhistle` para publicar avisos.",
|
|
44
|
+
"Para varios locais de exibicao no layout, prefira SgWhistleHost (host com registry)."
|
|
45
|
+
],
|
|
46
|
+
rankingSignals: { freeText: 0, structuredChoice: 0, date: 0, number: 0, denseLayout: 0.7 }
|
|
47
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function registerWhistleHost(id: string): void;
|
|
2
|
+
export declare function unregisterWhistleHost(id: string): void;
|
|
3
|
+
export declare function getActiveWhistleHostId(): string | null;
|
|
4
|
+
export declare function hasAnyWhistleHost(): boolean;
|
|
5
|
+
export declare function subscribeWhistleHostRegistry(fn: () => void): () => void;
|
|
6
|
+
export declare function nextWhistleHostId(): string;
|
|
7
|
+
//# sourceMappingURL=sgWhistleHostRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sgWhistleHostRegistry.d.ts","sourceRoot":"","sources":["../../src/commons/sgWhistleHostRegistry.ts"],"names":[],"mappings":"AAgBA,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,MAAM,QAK7C;AAED,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,QAM/C;AAED,wBAAgB,sBAAsB,IAAI,MAAM,GAAG,IAAI,CAEtD;AAED,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED,wBAAgB,4BAA4B,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAKvE;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAG1C"}
|