trackhome-react 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +4 -2
  2. package/dist/index.d.ts +8 -3
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +51 -158
  5. package/dist/index.js.map +1 -1
  6. package/dist/widgets/categorical.d.ts +6 -0
  7. package/dist/widgets/categorical.d.ts.map +1 -0
  8. package/dist/widgets/categorical.js +37 -0
  9. package/dist/widgets/categorical.js.map +1 -0
  10. package/dist/widgets/common.d.ts +42 -0
  11. package/dist/widgets/common.d.ts.map +1 -0
  12. package/dist/widgets/common.js +39 -0
  13. package/dist/widgets/common.js.map +1 -0
  14. package/dist/widgets/funnel.d.ts +3 -0
  15. package/dist/widgets/funnel.d.ts.map +1 -0
  16. package/dist/widgets/funnel.js +83 -0
  17. package/dist/widgets/funnel.js.map +1 -0
  18. package/dist/widgets/index.d.ts +4 -0
  19. package/dist/widgets/index.d.ts.map +1 -0
  20. package/dist/widgets/index.js +4 -0
  21. package/dist/widgets/index.js.map +1 -0
  22. package/dist/widgets/inputs.d.ts +32 -0
  23. package/dist/widgets/inputs.d.ts.map +1 -0
  24. package/dist/widgets/inputs.js +312 -0
  25. package/dist/widgets/inputs.js.map +1 -0
  26. package/dist/widgets/metric.d.ts +3 -0
  27. package/dist/widgets/metric.d.ts.map +1 -0
  28. package/dist/widgets/metric.js +14 -0
  29. package/dist/widgets/metric.js.map +1 -0
  30. package/dist/widgets/registry.d.ts +26 -0
  31. package/dist/widgets/registry.d.ts.map +1 -0
  32. package/dist/widgets/registry.js +53 -0
  33. package/dist/widgets/registry.js.map +1 -0
  34. package/dist/widgets/timeseries.d.ts +4 -0
  35. package/dist/widgets/timeseries.d.ts.map +1 -0
  36. package/dist/widgets/timeseries.js +34 -0
  37. package/dist/widgets/timeseries.js.map +1 -0
  38. package/dist/widgets/types.d.ts +87 -0
  39. package/dist/widgets/types.d.ts.map +1 -0
  40. package/dist/widgets/types.js +18 -0
  41. package/dist/widgets/types.js.map +1 -0
  42. package/package.json +2 -7
@@ -0,0 +1,37 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Field, RankedBars, MetricField, EventTypeField, TagPrefixField } from './common.js';
3
+ /** All categorical kinds resolve to a ranked [{type|tag, count}] list. */
4
+ function CategoricalRender({ data, theme }) {
5
+ const d = data ?? [];
6
+ const rows = d.map((x) => ({ label: x.type ?? x.tag ?? '—', count: x.count }));
7
+ return _jsx(RankedBars, { rows: rows, theme: theme });
8
+ }
9
+ function BreakdownEditForm({ draft, update, ctx }) {
10
+ return (_jsxs(_Fragment, { children: [_jsx(Field, { label: "Breakdown", ctx: ctx, children: _jsxs("select", { style: ctx.inputStyle, value: draft.breakdown ?? 'event_type', onChange: (e) => update({ breakdown: e.target.value }), children: [_jsx("option", { value: "event_type", children: "Event type" }), _jsx("option", { value: "tag", children: "Tag value" })] }) }), draft.breakdown === 'tag' && _jsx(TagPrefixField, { draft: draft, update: update, ctx: ctx }), _jsx(MetricField, { draft: draft, update: update, ctx: ctx }), _jsx(EventTypeField, { draft: draft, update: update, ctx: ctx })] }));
11
+ }
12
+ const breakdownConfig = () => ({ breakdown: 'event_type', metric: 'count' });
13
+ export const barWidget = {
14
+ meta: { value: 'bar', label: 'Bar', hint: 'Vertical categorical bars' },
15
+ defaultConfig: breakdownConfig,
16
+ Render: CategoricalRender,
17
+ EditForm: BreakdownEditForm,
18
+ };
19
+ export const pieWidget = {
20
+ meta: { value: 'pie', label: 'Pie', hint: 'Donut share-of-total' },
21
+ defaultConfig: breakdownConfig,
22
+ Render: CategoricalRender,
23
+ EditForm: BreakdownEditForm,
24
+ };
25
+ export const topEventsWidget = {
26
+ meta: { value: 'top_events', label: 'Top events', hint: 'Ranked event-type list' },
27
+ defaultConfig: () => ({ metric: 'count' }),
28
+ Render: CategoricalRender,
29
+ EditForm: ({ draft, update, ctx }) => (_jsxs(_Fragment, { children: [_jsx(MetricField, { draft: draft, update: update, ctx: ctx }), _jsx(EventTypeField, { draft: draft, update: update, ctx: ctx })] })),
30
+ };
31
+ export const topTagsWidget = {
32
+ meta: { value: 'top_tags', label: 'Top tags', hint: 'Ranked tag-value list (needs prefix)' },
33
+ defaultConfig: () => ({ metric: 'count' }),
34
+ Render: CategoricalRender,
35
+ EditForm: ({ draft, update, ctx }) => (_jsxs(_Fragment, { children: [_jsx(TagPrefixField, { draft: draft, update: update, ctx: ctx }), _jsx(MetricField, { draft: draft, update: update, ctx: ctx })] })),
36
+ };
37
+ //# sourceMappingURL=categorical.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"categorical.js","sourceRoot":"","sources":["../../src/widgets/categorical.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7F,0EAA0E;AAC1E,SAAS,iBAAiB,CAAC,EAAE,IAAI,EAAE,KAAK,EAAe;IACrD,MAAM,CAAC,GAAI,IAAgE,IAAI,EAAE,CAAC;IAClF,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC/E,OAAO,KAAC,UAAU,IAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,GAAI,CAAC;AAClD,CAAC;AAED,SAAS,iBAAiB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAiB;IAC9D,OAAO,CACL,8BACE,KAAC,KAAK,IAAC,KAAK,EAAC,WAAW,EAAC,GAAG,EAAE,GAAG,YAC/B,kBACE,KAAK,EAAE,GAAG,CAAC,UAAU,EACrB,KAAK,EAAE,KAAK,CAAC,SAAS,IAAI,YAAY,EACtC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,KAA6B,EAAE,CAAC,aAE9E,iBAAQ,KAAK,EAAC,YAAY,2BAAoB,EAC9C,iBAAQ,KAAK,EAAC,KAAK,0BAAmB,IAC/B,GACH,EACP,KAAK,CAAC,SAAS,KAAK,KAAK,IAAI,KAAC,cAAc,IAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,GAAI,EACxF,KAAC,WAAW,IAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,GAAI,EACvD,KAAC,cAAc,IAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,GAAI,IACzD,CACJ,CAAC;AACJ,CAAC;AAED,MAAM,eAAe,GAAG,GAAoB,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;AAE9F,MAAM,CAAC,MAAM,SAAS,GAAa;IACjC,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,2BAA2B,EAAE;IACvE,aAAa,EAAE,eAAe;IAC9B,MAAM,EAAE,iBAAiB;IACzB,QAAQ,EAAE,iBAAiB;CAC5B,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAa;IACjC,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,sBAAsB,EAAE;IAClE,aAAa,EAAE,eAAe;IAC9B,MAAM,EAAE,iBAAiB;IACzB,QAAQ,EAAE,iBAAiB;CAC5B,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAa;IACvC,IAAI,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,wBAAwB,EAAE;IAClF,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IAC1C,MAAM,EAAE,iBAAiB;IACzB,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAiB,EAAE,EAAE,CAAC,CACnD,8BACE,KAAC,WAAW,IAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,GAAI,EACvD,KAAC,cAAc,IAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,GAAI,IACzD,CACJ;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAa;IACrC,IAAI,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,sCAAsC,EAAE;IAC5F,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IAC1C,MAAM,EAAE,iBAAiB;IACzB,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAiB,EAAE,EAAE,CAAC,CACnD,8BACE,KAAC,cAAc,IAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,GAAI,EAC1D,KAAC,WAAW,IAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,GAAI,IACtD,CACJ;CACF,CAAC"}
@@ -0,0 +1,42 @@
1
+ /** Render + form building blocks shared across widget kinds. */
2
+ import React from 'react';
3
+ import type { Theme, EditCtx, Widget } from './types.js';
4
+ export declare function NoData({ theme, label }: {
5
+ theme: Theme;
6
+ label?: string;
7
+ }): React.JSX.Element;
8
+ /** Horizontal ranked-bar list used by bar/pie/top_events/top_tags/funnel. */
9
+ export declare function RankedBars({ rows, theme, barHeight, }: {
10
+ rows: {
11
+ label: string;
12
+ count: number;
13
+ suffix?: string;
14
+ }[];
15
+ theme: Theme;
16
+ barHeight?: number;
17
+ }): React.JSX.Element;
18
+ /** Labeled field wrapper for EditForms. */
19
+ export declare function Field({ label, ctx, children }: {
20
+ label: string;
21
+ ctx: EditCtx;
22
+ children: React.ReactNode;
23
+ }): React.JSX.Element;
24
+ /** Metric <select> reused by every value-based widget. */
25
+ export declare function MetricField({ draft, update, ctx, }: {
26
+ draft: Widget;
27
+ update: (patch: Partial<Widget>) => void;
28
+ ctx: EditCtx;
29
+ }): React.JSX.Element;
30
+ /** Optional event-type filter with autosuggest. */
31
+ export declare function EventTypeField({ draft, update, ctx, }: {
32
+ draft: Widget;
33
+ update: (patch: Partial<Widget>) => void;
34
+ ctx: EditCtx;
35
+ }): React.JSX.Element;
36
+ /** Tag-prefix field with autosuggest. */
37
+ export declare function TagPrefixField({ draft, update, ctx, }: {
38
+ draft: Widget;
39
+ update: (patch: Partial<Widget>) => void;
40
+ ctx: EditCtx;
41
+ }): React.JSX.Element;
42
+ //# sourceMappingURL=common.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/widgets/common.tsx"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAU,MAAM,YAAY,CAAC;AAIjE,wBAAgB,MAAM,CAAC,EAAE,KAAK,EAAE,KAAkB,EAAE,EAAE;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,qBAErF;AAED,6EAA6E;AAC7E,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,KAAK,EACL,SAAa,GACd,EAAE;IACD,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC1D,KAAK,EAAE,KAAK,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,qBAgCA;AAED,2CAA2C;AAC3C,wBAAgB,KAAK,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,qBAOzG;AAED,0DAA0D;AAC1D,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,MAAM,EACN,GAAG,GACJ,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;IACzC,GAAG,EAAE,OAAO,CAAC;CACd,qBAeA;AAED,mDAAmD;AACnD,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,MAAM,EACN,GAAG,GACJ,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;IACzC,GAAG,EAAE,OAAO,CAAC;CACd,qBAgBA;AAED,yCAAyC;AACzC,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,MAAM,EACN,GAAG,GACJ,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;IACzC,GAAG,EAAE,OAAO,CAAC;CACd,qBAgBA"}
@@ -0,0 +1,39 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { ACCENT, subTextColor, trackColor } from './types.js';
3
+ import { AutosuggestInput } from './inputs.js';
4
+ export function NoData({ theme, label = 'No data.' }) {
5
+ return _jsx("div", { style: { fontSize: 12, color: subTextColor(theme) }, children: label });
6
+ }
7
+ /** Horizontal ranked-bar list used by bar/pie/top_events/top_tags/funnel. */
8
+ export function RankedBars({ rows, theme, barHeight = 8, }) {
9
+ const subtext = subTextColor(theme);
10
+ if (rows.length === 0)
11
+ return _jsx(NoData, { theme: theme });
12
+ const max = Math.max(...rows.map((r) => r.count), 1);
13
+ return (_jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: 4 }, children: rows.map((r, i) => (_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 8 }, children: [_jsx("div", { style: {
14
+ fontSize: 11,
15
+ color: subtext,
16
+ width: 120,
17
+ overflow: 'hidden',
18
+ textOverflow: 'ellipsis',
19
+ whiteSpace: 'nowrap',
20
+ fontFamily: 'monospace',
21
+ }, children: r.label }), _jsx("div", { style: { flex: 1, height: barHeight, background: trackColor(theme), borderRadius: 4, overflow: 'hidden' }, children: _jsx("div", { style: { width: `${(r.count / max) * 100}%`, height: '100%', background: ACCENT, borderRadius: 4 } }) }), _jsxs("div", { style: { fontSize: 11, color: subtext, minWidth: 50, textAlign: 'right' }, children: [r.count.toLocaleString(), r.suffix ?? ''] })] }, i))) }));
22
+ }
23
+ /** Labeled field wrapper for EditForms. */
24
+ export function Field({ label, ctx, children }) {
25
+ return (_jsxs("label", { children: [_jsx("span", { style: ctx.labelStyle, children: label }), children] }));
26
+ }
27
+ /** Metric <select> reused by every value-based widget. */
28
+ export function MetricField({ draft, update, ctx, }) {
29
+ return (_jsx(Field, { label: "Metric", ctx: ctx, children: _jsxs("select", { style: ctx.inputStyle, value: draft.metric ?? 'count', onChange: (e) => update({ metric: e.target.value }), children: [_jsx("option", { value: "count", children: "Count" }), _jsx("option", { value: "unique", children: "Unique visitors" }), _jsx("option", { value: "sum", children: "Sum" }), _jsx("option", { value: "avg", children: "Average" })] }) }));
30
+ }
31
+ /** Optional event-type filter with autosuggest. */
32
+ export function EventTypeField({ draft, update, ctx, }) {
33
+ return (_jsx(Field, { label: "Event type filter (optional)", ctx: ctx, children: _jsx(AutosuggestInput, { endpoint: ctx.endpoint, authKey: ctx.authKey, uid: ctx.uid, suggestPath: "events", value: draft.eventType ?? '', onChange: (v) => update({ eventType: v || undefined }), placeholder: "e.g. page_view", theme: ctx.theme, inputStyle: ctx.inputStyle }) }));
34
+ }
35
+ /** Tag-prefix field with autosuggest. */
36
+ export function TagPrefixField({ draft, update, ctx, }) {
37
+ return (_jsx(Field, { label: "Tag prefix", ctx: ctx, children: _jsx(AutosuggestInput, { endpoint: ctx.endpoint, authKey: ctx.authKey, uid: ctx.uid, suggestPath: "prefixes", value: draft.tagPrefix ?? '', onChange: (v) => update({ tagPrefix: v || undefined }), placeholder: "e.g. variant:", theme: ctx.theme, inputStyle: ctx.inputStyle }) }));
38
+ }
39
+ //# sourceMappingURL=common.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/widgets/common.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { WidgetUI } from './types.js';
2
+ export declare const funnelWidget: WidgetUI;
3
+ //# sourceMappingURL=funnel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"funnel.d.ts","sourceRoot":"","sources":["../../src/widgets/funnel.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAA0C,MAAM,YAAY,CAAC;AA4MnF,eAAO,MAAM,YAAY,EAAE,QAK1B,CAAC"}
@@ -0,0 +1,83 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { ACCENT, subTextColor, trackColor } from './types.js';
3
+ import { Field, NoData } from './common.js';
4
+ import { AutosuggestInput, TagsAutosuggestInput } from './inputs.js';
5
+ /** Compact waterfall: per-step visitors bar + overall conversion %. */
6
+ function FunnelRender({ widget, data, theme }) {
7
+ const d = data ?? {};
8
+ const steps = d.steps ?? [];
9
+ if (steps.length === 0) {
10
+ const hint = (widget.steps?.length ?? 0) < 2 ? 'Add at least 2 steps to this funnel.' : 'No funnel data.';
11
+ return _jsx(NoData, { theme: theme, label: hint });
12
+ }
13
+ const subtext = subTextColor(theme);
14
+ const max = Math.max(...steps.map((s) => s.visitors), 1);
15
+ return (_jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: 4 }, children: steps.map((s, i) => (_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 8 }, children: [_jsxs("div", { style: {
16
+ fontSize: 11,
17
+ color: subtext,
18
+ width: 120,
19
+ overflow: 'hidden',
20
+ textOverflow: 'ellipsis',
21
+ whiteSpace: 'nowrap',
22
+ fontFamily: 'monospace',
23
+ }, children: [i + 1, ". ", s.type] }), _jsx("div", { style: { flex: 1, height: 10, background: trackColor(theme), borderRadius: 4, overflow: 'hidden' }, children: _jsx("div", { style: { width: `${(s.visitors / max) * 100}%`, height: '100%', background: ACCENT, borderRadius: 4 } }) }), _jsxs("div", { style: { fontSize: 11, color: subtext, minWidth: 78, textAlign: 'right', fontVariantNumeric: 'tabular-nums' }, children: [s.visitors.toLocaleString(), " \u00B7 ", Math.round(s.conversionOverall * 100), "%"] })] }, i))) }));
24
+ }
25
+ function FunnelEditForm({ draft, update, ctx }) {
26
+ const steps = draft.steps ?? [];
27
+ const setSteps = (next) => update({ steps: next });
28
+ const updateStep = (i, patch) => setSteps(steps.map((s, idx) => (idx === i ? { ...s, ...patch } : s)));
29
+ const stepBoxStyle = {
30
+ border: `1px solid ${ctx.theme === 'dark' ? '#334155' : '#cbd5e1'}`,
31
+ borderRadius: 8,
32
+ padding: 8,
33
+ display: 'flex',
34
+ flexDirection: 'column',
35
+ gap: 6,
36
+ };
37
+ return (_jsxs(_Fragment, { children: [_jsx(Field, { label: "Window (minutes between steps)", ctx: ctx, children: _jsx("input", { type: "number", min: 1, style: ctx.inputStyle, value: draft.windowMinutes ?? 30, onChange: (e) => update({ windowMinutes: Number(e.target.value) || 30 }) }) }), _jsxs("div", { children: [_jsx("div", { style: { ...ctx.labelStyle, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }, children: _jsxs("span", { children: ["Steps (", steps.length, ")"] }) }), _jsx("div", { style: { display: 'flex', flexDirection: 'column', gap: 8 }, children: steps.map((step, i) => (_jsxs("div", { style: stepBoxStyle, children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8 }, children: [_jsxs("span", { style: { fontSize: 11, fontWeight: 600, color: ctx.subLabelColor }, children: ["Step ", i + 1] }), _jsxs("div", { style: { display: 'flex', gap: 2 }, children: [_jsx("button", { type: "button", title: "Move up", disabled: i === 0, onClick: () => {
38
+ if (i === 0)
39
+ return;
40
+ const next = steps.slice();
41
+ [next[i - 1], next[i]] = [next[i], next[i - 1]];
42
+ setSteps(next);
43
+ }, style: miniBtn(ctx.theme, i === 0), children: "\u2191" }), _jsx("button", { type: "button", title: "Move down", disabled: i === steps.length - 1, onClick: () => {
44
+ if (i === steps.length - 1)
45
+ return;
46
+ const next = steps.slice();
47
+ [next[i + 1], next[i]] = [next[i], next[i + 1]];
48
+ setSteps(next);
49
+ }, style: miniBtn(ctx.theme, i === steps.length - 1), children: "\u2193" }), _jsx("button", { type: "button", title: "Remove step", onClick: () => setSteps(steps.filter((_, idx) => idx !== i)), style: { ...miniBtn(ctx.theme, false), background: '#ef4444', color: '#fff' }, children: "\u00D7" })] })] }), _jsx(AutosuggestInput, { endpoint: ctx.endpoint, authKey: ctx.authKey, uid: ctx.uid, suggestPath: "events", value: step.type, onChange: (v) => updateStep(i, { type: v }), placeholder: "event type, e.g. signup", theme: ctx.theme, inputStyle: ctx.inputStyle }), _jsx(TagsAutosuggestInput, { endpoint: ctx.endpoint, authKey: ctx.authKey, uid: ctx.uid, tags: step.tags ?? [], onChange: (t) => updateStep(i, { tags: t }), placeholder: "step tag filters (optional)", theme: ctx.theme, inputStyle: ctx.inputStyle, inputId: `funnel-step-${i}-tags` })] }, i))) }), _jsx("button", { type: "button", onClick: () => setSteps([...steps, { type: '', tags: [] }]), style: {
50
+ marginTop: 8,
51
+ width: '100%',
52
+ padding: '6px 10px',
53
+ fontSize: 12,
54
+ fontWeight: 600,
55
+ borderRadius: 6,
56
+ border: `1px dashed ${ACCENT}`,
57
+ background: 'transparent',
58
+ color: ACCENT,
59
+ cursor: 'pointer',
60
+ }, children: "+ Add step" })] }), _jsx(Field, { label: "Funnel tag filter (optional, applies to all steps)", ctx: ctx, children: _jsx(TagsAutosuggestInput, { endpoint: ctx.endpoint, authKey: ctx.authKey, uid: ctx.uid, tags: draft.filterTags ?? [], onChange: (t) => update({ filterTags: t }), placeholder: "type to search, Enter to add", theme: ctx.theme, inputStyle: ctx.inputStyle, inputId: "funnel-filter-tags" }) })] }));
61
+ }
62
+ function miniBtn(theme, disabled) {
63
+ return {
64
+ background: theme === 'dark' ? '#475569' : '#e2e8f0',
65
+ color: theme === 'dark' ? '#f1f5f9' : '#1e293b',
66
+ border: 'none',
67
+ borderRadius: 4,
68
+ width: 22,
69
+ height: 22,
70
+ fontSize: 13,
71
+ cursor: disabled ? 'not-allowed' : 'pointer',
72
+ opacity: disabled ? 0.3 : 1,
73
+ padding: 0,
74
+ lineHeight: 1,
75
+ };
76
+ }
77
+ export const funnelWidget = {
78
+ meta: { value: 'funnel', label: 'Funnel', hint: 'Funnel waterfall (inline steps)' },
79
+ defaultConfig: () => ({ steps: [], windowMinutes: 30, filterTags: [] }),
80
+ Render: FunnelRender,
81
+ EditForm: FunnelEditForm,
82
+ };
83
+ //# sourceMappingURL=funnel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"funnel.js","sourceRoot":"","sources":["../../src/widgets/funnel.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export * from './types.js';
2
+ export * from './registry.js';
3
+ export { AutosuggestInput, TagsAutosuggestInput } from './inputs.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/widgets/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from './types.js';
2
+ export * from './registry.js';
3
+ export { AutosuggestInput, TagsAutosuggestInput } from './inputs.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/widgets/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Autosuggest inputs shared by every widget EditForm.
3
+ *
4
+ * Zero deps; each fetches /e/<key>/<uid>/suggest/* with a 150ms debounce.
5
+ * - AutosuggestInput — single value (event type / tag prefix)
6
+ * - TagsAutosuggestInput — multi value chips (tag filters)
7
+ */
8
+ import React from 'react';
9
+ import type { Theme } from './types.js';
10
+ export declare function AutosuggestInput({ endpoint, authKey, uid, suggestPath, value, onChange, placeholder, theme, inputStyle, }: {
11
+ endpoint: string;
12
+ authKey: string;
13
+ uid: string;
14
+ suggestPath: 'events' | 'prefixes';
15
+ value: string;
16
+ onChange: (v: string) => void;
17
+ placeholder?: string;
18
+ theme: Theme;
19
+ inputStyle: React.CSSProperties;
20
+ }): React.JSX.Element;
21
+ export declare function TagsAutosuggestInput({ endpoint, authKey, uid, tags, onChange, placeholder, theme, inputStyle, inputId, }: {
22
+ endpoint: string;
23
+ authKey: string;
24
+ uid: string;
25
+ tags: string[];
26
+ onChange: (tags: string[]) => void;
27
+ placeholder?: string;
28
+ theme: Theme;
29
+ inputStyle: React.CSSProperties;
30
+ inputId?: string;
31
+ }): React.JSX.Element;
32
+ //# sourceMappingURL=inputs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inputs.d.ts","sourceRoot":"","sources":["../../src/widgets/inputs.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAA8B,MAAM,OAAO,CAAC;AACnD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAgBxC,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,EACR,OAAO,EACP,GAAG,EACH,WAAW,EACX,KAAK,EACL,QAAQ,EACR,WAAW,EACX,KAAK,EACL,UAAU,GACX,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,QAAQ,GAAG,UAAU,CAAC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,KAAK,CAAC;IACb,UAAU,EAAE,KAAK,CAAC,aAAa,CAAC;CACjC,qBAqKA;AAED,wBAAgB,oBAAoB,CAAC,EACnC,QAAQ,EACR,OAAO,EACP,GAAG,EACH,IAAI,EACJ,QAAQ,EACR,WAAW,EACX,KAAK,EACL,UAAU,EACV,OAA8B,GAC/B,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,KAAK,CAAC;IACb,UAAU,EAAE,KAAK,CAAC,aAAa,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,qBAkPA"}
@@ -0,0 +1,312 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Autosuggest inputs shared by every widget EditForm.
4
+ *
5
+ * Zero deps; each fetches /e/<key>/<uid>/suggest/* with a 150ms debounce.
6
+ * - AutosuggestInput — single value (event type / tag prefix)
7
+ * - TagsAutosuggestInput — multi value chips (tag filters)
8
+ */
9
+ import { useState, useEffect } from 'react';
10
+ function useDebounced(value, delayMs) {
11
+ const [debounced, setDebounced] = useState(value);
12
+ useEffect(() => {
13
+ const t = setTimeout(() => setDebounced(value), delayMs);
14
+ return () => clearTimeout(t);
15
+ }, [value, delayMs]);
16
+ return debounced;
17
+ }
18
+ export function AutosuggestInput({ endpoint, authKey, uid, suggestPath, value, onChange, placeholder, theme, inputStyle, }) {
19
+ const [text, setText] = useState(value);
20
+ const [open, setOpen] = useState(false);
21
+ const [highlight, setHighlight] = useState(0);
22
+ const [items, setItems] = useState([]);
23
+ const [loading, setLoading] = useState(false);
24
+ const debounced = useDebounced(text.trim(), 150);
25
+ useEffect(() => {
26
+ setText(value);
27
+ }, [value]);
28
+ useEffect(() => {
29
+ let cancelled = false;
30
+ if (!open || debounced.length === 0) {
31
+ setItems([]);
32
+ setLoading(false);
33
+ return;
34
+ }
35
+ setLoading(true);
36
+ const url = `${endpoint.replace(/\/$/, '')}/e/${authKey}/${uid}/suggest/${suggestPath}?q=${encodeURIComponent(debounced)}&limit=10`;
37
+ fetch(url)
38
+ .then((r) => (r.ok ? r.json() : Promise.reject(new Error(String(r.status)))))
39
+ .then((body) => {
40
+ if (cancelled)
41
+ return;
42
+ setItems(body.items ?? []);
43
+ setHighlight(0);
44
+ })
45
+ .catch(() => {
46
+ if (cancelled)
47
+ return;
48
+ setItems([]);
49
+ })
50
+ .finally(() => {
51
+ if (!cancelled)
52
+ setLoading(false);
53
+ });
54
+ return () => {
55
+ cancelled = true;
56
+ };
57
+ }, [endpoint, authKey, uid, suggestPath, debounced, open]);
58
+ const showItemCreate = text.trim().length > 0 && !items.some((it) => it.value === text.trim());
59
+ function commit(v) {
60
+ setText(v);
61
+ onChange(v);
62
+ setOpen(false);
63
+ }
64
+ function onKeyDown(e) {
65
+ const totalOptions = items.length + (showItemCreate ? 1 : 0);
66
+ if (e.key === 'ArrowDown' && totalOptions > 0) {
67
+ e.preventDefault();
68
+ setOpen(true);
69
+ setHighlight((h) => Math.min(h + 1, totalOptions - 1));
70
+ }
71
+ else if (e.key === 'ArrowUp' && totalOptions > 0) {
72
+ e.preventDefault();
73
+ setHighlight((h) => Math.max(h - 1, 0));
74
+ }
75
+ else if (e.key === 'Enter') {
76
+ if (open && totalOptions > 0) {
77
+ e.preventDefault();
78
+ if (highlight < items.length)
79
+ commit(items[highlight].value);
80
+ else
81
+ commit(text.trim());
82
+ }
83
+ }
84
+ else if (e.key === 'Escape') {
85
+ setOpen(false);
86
+ }
87
+ }
88
+ const dropdownBg = theme === 'dark' ? '#0f172a' : '#ffffff';
89
+ const dropdownBorder = theme === 'dark' ? '#334155' : '#cbd5e1';
90
+ const hoverBg = theme === 'dark' ? '#1e293b' : '#eef2ff';
91
+ const subText = theme === 'dark' ? '#94a3b8' : '#64748b';
92
+ return (_jsxs("div", { style: { position: 'relative' }, children: [_jsx("input", { style: inputStyle, value: text, onChange: (e) => {
93
+ setText(e.target.value);
94
+ onChange(e.target.value);
95
+ setOpen(true);
96
+ setHighlight(0);
97
+ }, onFocus: () => setOpen(true), onBlur: () => setTimeout(() => setOpen(false), 120), onKeyDown: onKeyDown, placeholder: placeholder, autoComplete: "off", spellCheck: false }), open && text.trim().length > 0 && (_jsxs("div", { style: {
98
+ position: 'absolute',
99
+ top: 'calc(100% + 2px)',
100
+ left: 0,
101
+ right: 0,
102
+ background: dropdownBg,
103
+ border: `1px solid ${dropdownBorder}`,
104
+ borderRadius: 6,
105
+ boxShadow: '0 8px 24px rgba(0,0,0,0.15)',
106
+ zIndex: 1100,
107
+ maxHeight: 240,
108
+ overflowY: 'auto',
109
+ fontSize: 12,
110
+ }, onMouseDown: (e) => e.preventDefault(), children: [loading && _jsx("div", { style: { padding: '8px 10px', color: subText }, children: "Searching\u2026" }), !loading && items.length === 0 && !showItemCreate && (_jsx("div", { style: { padding: '8px 10px', color: subText }, children: "No matches." })), items.map((it, i) => (_jsxs("div", { onMouseEnter: () => setHighlight(i), onMouseDown: (e) => {
111
+ e.preventDefault();
112
+ commit(it.value);
113
+ }, style: {
114
+ padding: '6px 10px',
115
+ cursor: 'pointer',
116
+ display: 'flex',
117
+ justifyContent: 'space-between',
118
+ gap: 8,
119
+ background: i === highlight ? hoverBg : 'transparent',
120
+ borderRadius: 4,
121
+ fontFamily: suggestPath === 'prefixes' ? 'monospace' : undefined,
122
+ }, children: [_jsx("span", { style: { overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }, children: it.value }), _jsx("span", { style: { color: subText, flexShrink: 0, fontVariantNumeric: 'tabular-nums' }, children: it.count.toLocaleString() })] }, it.value))), showItemCreate && (_jsxs("div", { onMouseEnter: () => setHighlight(items.length), onMouseDown: (e) => {
123
+ e.preventDefault();
124
+ commit(text.trim());
125
+ }, style: {
126
+ padding: '6px 10px',
127
+ cursor: 'pointer',
128
+ borderTop: `1px dashed ${dropdownBorder}`,
129
+ marginTop: items.length > 0 ? 4 : 0,
130
+ background: highlight === items.length ? hoverBg : 'transparent',
131
+ borderRadius: 4,
132
+ color: '#4f46e5',
133
+ fontStyle: 'italic',
134
+ }, children: ["Use \"", text.trim(), "\"", suggestPath === 'prefixes' ? ' (new prefix)' : ' (new)'] }))] }))] }));
135
+ }
136
+ export function TagsAutosuggestInput({ endpoint, authKey, uid, tags, onChange, placeholder, theme, inputStyle, inputId = 'tag-input-internal', }) {
137
+ const [text, setText] = useState('');
138
+ const [open, setOpen] = useState(false);
139
+ const [highlight, setHighlight] = useState(0);
140
+ const [items, setItems] = useState([]);
141
+ const [loading, setLoading] = useState(false);
142
+ const debounced = useDebounced(text.trim(), 150);
143
+ useEffect(() => {
144
+ let cancelled = false;
145
+ if (!open || debounced.length === 0) {
146
+ setItems([]);
147
+ setLoading(false);
148
+ return;
149
+ }
150
+ setLoading(true);
151
+ const url = `${endpoint.replace(/\/$/, '')}/e/${authKey}/${uid}/suggest/tags?q=${encodeURIComponent(debounced)}&limit=10`;
152
+ fetch(url)
153
+ .then((r) => (r.ok ? r.json() : Promise.reject(new Error(String(r.status)))))
154
+ .then((body) => {
155
+ if (cancelled)
156
+ return;
157
+ setItems(body.items ?? []);
158
+ setHighlight(0);
159
+ })
160
+ .catch(() => {
161
+ if (cancelled)
162
+ return;
163
+ setItems([]);
164
+ })
165
+ .finally(() => {
166
+ if (!cancelled)
167
+ setLoading(false);
168
+ });
169
+ return () => {
170
+ cancelled = true;
171
+ };
172
+ }, [endpoint, authKey, uid, debounced, open]);
173
+ function addTag(raw) {
174
+ const v = raw.trim();
175
+ if (!v)
176
+ return;
177
+ const next = Array.from(new Set([...tags, v]));
178
+ onChange(next);
179
+ setText('');
180
+ setItems([]);
181
+ setHighlight(0);
182
+ }
183
+ function removeTag(t) {
184
+ onChange(tags.filter((x) => x !== t));
185
+ }
186
+ function onKeyDown(e) {
187
+ const totalOptions = items.length + (text.trim().length > 0 && !items.some((it) => it.value === text.trim()) ? 1 : 0);
188
+ if (e.key === 'ArrowDown' && totalOptions > 0) {
189
+ e.preventDefault();
190
+ setOpen(true);
191
+ setHighlight((h) => Math.min(h + 1, totalOptions - 1));
192
+ }
193
+ else if (e.key === 'ArrowUp' && totalOptions > 0) {
194
+ e.preventDefault();
195
+ setHighlight((h) => Math.max(h - 1, 0));
196
+ }
197
+ else if (e.key === 'Enter' || e.key === ',') {
198
+ e.preventDefault();
199
+ if (open && totalOptions > 0) {
200
+ if (highlight < items.length)
201
+ addTag(items[highlight].value);
202
+ else
203
+ addTag(text.trim());
204
+ }
205
+ else {
206
+ addTag(text.trim());
207
+ }
208
+ }
209
+ else if (e.key === 'Backspace' && text === '' && tags.length > 0) {
210
+ removeTag(tags[tags.length - 1]);
211
+ }
212
+ else if (e.key === 'Escape') {
213
+ setOpen(false);
214
+ }
215
+ }
216
+ const dropdownBg = theme === 'dark' ? '#0f172a' : '#ffffff';
217
+ const dropdownBorder = theme === 'dark' ? '#334155' : '#cbd5e1';
218
+ const hoverBg = theme === 'dark' ? '#1e293b' : '#eef2ff';
219
+ const subText = theme === 'dark' ? '#94a3b8' : '#64748b';
220
+ const chipBg = theme === 'dark' ? '#334155' : '#e0e7ff';
221
+ const chipText = theme === 'dark' ? '#f1f5f9' : '#3730a3';
222
+ const showItemCreate = text.trim().length > 0 && !items.some((it) => it.value === text.trim());
223
+ return (_jsxs("div", { style: {
224
+ ...inputStyle,
225
+ display: 'flex',
226
+ flexWrap: 'wrap',
227
+ gap: 4,
228
+ alignItems: 'center',
229
+ padding: '4px 6px',
230
+ cursor: 'text',
231
+ minHeight: inputStyle.padding ?? 36,
232
+ }, onMouseDown: () => {
233
+ const i = document.getElementById(inputId);
234
+ if (i)
235
+ i.focus();
236
+ }, children: [tags.map((t) => (_jsxs("span", { style: {
237
+ display: 'inline-flex',
238
+ alignItems: 'center',
239
+ gap: 4,
240
+ background: chipBg,
241
+ color: chipText,
242
+ padding: '2px 4px 2px 8px',
243
+ borderRadius: 4,
244
+ fontSize: 11,
245
+ fontFamily: 'monospace',
246
+ }, children: [t, _jsx("button", { type: "button", onMouseDown: (e) => {
247
+ e.preventDefault();
248
+ e.stopPropagation();
249
+ removeTag(t);
250
+ }, style: {
251
+ border: 'none',
252
+ background: 'transparent',
253
+ color: chipText,
254
+ cursor: 'pointer',
255
+ fontSize: 13,
256
+ lineHeight: 1,
257
+ padding: '0 4px',
258
+ }, "aria-label": `Remove ${t}`, children: "\u00D7" })] }, t))), _jsxs("div", { style: { position: 'relative', flex: 1, minWidth: 80 }, children: [_jsx("input", { id: inputId, style: {
259
+ width: '100%',
260
+ background: 'transparent',
261
+ border: 'none',
262
+ outline: 'none',
263
+ color: 'inherit',
264
+ fontSize: 13,
265
+ padding: '4px 2px',
266
+ fontFamily: 'monospace',
267
+ }, value: text, onChange: (e) => {
268
+ const next = e.target.value.replace(/,/g, '');
269
+ setText(next);
270
+ setOpen(true);
271
+ setHighlight(0);
272
+ }, onFocus: () => setOpen(true), onBlur: () => setTimeout(() => setOpen(false), 120), onKeyDown: onKeyDown, placeholder: tags.length === 0 ? placeholder : '', autoComplete: "off", spellCheck: false }), open && text.trim().length > 0 && (_jsxs("div", { style: {
273
+ position: 'absolute',
274
+ top: 'calc(100% + 2px)',
275
+ left: 0,
276
+ right: 0,
277
+ background: dropdownBg,
278
+ border: `1px solid ${dropdownBorder}`,
279
+ borderRadius: 6,
280
+ boxShadow: '0 8px 24px rgba(0,0,0,0.15)',
281
+ zIndex: 1100,
282
+ maxHeight: 240,
283
+ overflowY: 'auto',
284
+ fontSize: 12,
285
+ }, onMouseDown: (e) => e.preventDefault(), children: [loading && _jsx("div", { style: { padding: '8px 10px', color: subText }, children: "Searching\u2026" }), !loading && items.length === 0 && !showItemCreate && (_jsx("div", { style: { padding: '8px 10px', color: subText }, children: "No matches." })), items.map((it, i) => (_jsxs("div", { onMouseEnter: () => setHighlight(i), onMouseDown: (e) => {
286
+ e.preventDefault();
287
+ addTag(it.value);
288
+ }, style: {
289
+ padding: '6px 10px',
290
+ cursor: 'pointer',
291
+ display: 'flex',
292
+ justifyContent: 'space-between',
293
+ gap: 8,
294
+ background: i === highlight ? hoverBg : 'transparent',
295
+ borderRadius: 4,
296
+ fontFamily: 'monospace',
297
+ }, children: [_jsx("span", { style: { overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }, children: it.value }), _jsx("span", { style: { color: subText, flexShrink: 0, fontVariantNumeric: 'tabular-nums' }, children: it.count.toLocaleString() })] }, it.value))), showItemCreate && (_jsxs("div", { onMouseEnter: () => setHighlight(items.length), onMouseDown: (e) => {
298
+ e.preventDefault();
299
+ addTag(text.trim());
300
+ }, style: {
301
+ padding: '6px 10px',
302
+ cursor: 'pointer',
303
+ borderTop: `1px dashed ${dropdownBorder}`,
304
+ marginTop: items.length > 0 ? 4 : 0,
305
+ background: highlight === items.length ? hoverBg : 'transparent',
306
+ borderRadius: 4,
307
+ color: '#4f46e5',
308
+ fontStyle: 'italic',
309
+ fontFamily: 'monospace',
310
+ }, children: ["Add \"", text.trim(), "\" (new tag)"] }))] }))] })] }));
311
+ }
312
+ //# sourceMappingURL=inputs.js.map