@sybilion/uilib 1.3.85 → 1.3.87

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 (26) hide show
  1. package/dist/agent-glossary/content.generated.ts +4 -6
  2. package/dist/agent-glossary/content.md +4 -6
  3. package/dist/agent-glossary/workspace.generated.ts +4 -6
  4. package/dist/agent-glossary/workspace.md +4 -6
  5. package/dist/esm/components/ui/Chat/ChatEmptyState/ChatEmptyState.js +3 -2
  6. package/dist/esm/components/ui/Chat/ChatSheet/ChatSelector.js +3 -2
  7. package/dist/esm/components/ui/Chat/ChatSheet/ChatSelector.styl.js +2 -2
  8. package/dist/esm/components/ui/Chat/ChatSheet/ChatSheet.js +1 -1
  9. package/dist/esm/components/ui/Select/Select.styl.js +1 -1
  10. package/dist/esm/types/src/components/ui/Chat/ChatEmptyState/ChatEmptyState.d.ts +2 -2
  11. package/dist/esm/types/src/components/ui/Chat/ChatEmptyState/ChatEmptyState.types.d.ts +1 -0
  12. package/dist/esm/types/src/components/ui/Chat/ChatSheet/ChatSelector.d.ts +3 -2
  13. package/dist/esm/types/src/components/ui/Chat/ChatSheet/ChatSheet.d.ts +1 -1
  14. package/package.json +1 -1
  15. package/src/components/ui/ChartAreaInteractive/AGENT.md +0 -1
  16. package/src/components/ui/Chat/ChatEmptyState/ChatEmptyState.tsx +4 -3
  17. package/src/components/ui/Chat/ChatEmptyState/ChatEmptyState.types.ts +1 -0
  18. package/src/components/ui/Chat/ChatSheet/ChatSelector.styl +18 -2
  19. package/src/components/ui/Chat/ChatSheet/ChatSelector.styl.d.ts +2 -0
  20. package/src/components/ui/Chat/ChatSheet/ChatSelector.tsx +23 -6
  21. package/src/components/ui/Chat/ChatSheet/ChatSheet.tsx +2 -2
  22. package/src/components/ui/Select/Select.styl +15 -6
  23. package/src/components/widgets/DriverMap/AGENT.md +1 -1
  24. package/src/components/widgets/DriversComparisonChart/AGENT.md +2 -2
  25. package/src/components/widgets/PerformanceChart/AGENT.md +1 -2
  26. package/src/docs/pages/SelectPage.tsx +73 -16
@@ -180,7 +180,6 @@ Host provides:
180
180
  - \`chartData\`, \`forecastData\` built from API
181
181
  - \`timeRange\` / \`onTimeRangeChange\` or brush-only range
182
182
  - Optional \`mode\`: pin | intervals | thresholds + overlay state
183
- - Analysis selector and fetch outside widget
184
183
 
185
184
  Report tile: \`dataset_card\` — host loads dataset + analysis; chart inside dashboard card.
186
185
 
@@ -201,7 +200,7 @@ Host provides:
201
200
  - Controlled \`selectedDriver\` + \`setSelectedDriver\`
202
201
  - \`isLoading\` while fetching drivers
203
202
 
204
- Report tile: \`drivers_map\` — tile resolves analysis id, fetches drivers, passes list + selection (see EmbeddedAnalysisSelector pattern).
203
+ Report tile: \`drivers_map\` — tile resolves analysis id, fetches drivers, passes list + selection.
205
204
 
206
205
  Requires: \`drivers\`; \`isLoading\`; \`selectedDriver\`; \`setSelectedDriver\`.
207
206
 
@@ -217,10 +216,9 @@ Not when: simple forecast card or driver backtests — use ChartAreaInteractive
217
216
  Host provides:
218
217
 
219
218
  - \`performanceData\` (PerformanceChartPayload) and \`historicalData\` from performance API
220
- - Analysis selection and fetch outside widget
221
219
  - Optional \`forecastData\`, \`customPerformanceMatrix\`, \`userSeries\` for spaghetti
222
220
 
223
- Report tile: \`performance_chart\` — host loads performance payload + dataset series; built-in analysis selector.
221
+ Report tile: \`performance_chart\` — host loads performance payload + dataset series.
224
222
 
225
223
  Requires: \`performanceData\` — model/drift forecasts and metrics; \`historicalData\` — baseline series; \`loading\` / \`chartLoading\` / \`performanceDataLoading\` — spinners; \`runAnalysisHint\` / \`statusHint\` — empty states.
226
224
 
@@ -240,9 +238,9 @@ Host provides:
240
238
  - \`seriesInitKey\` when selected analysis changes
241
239
  - \`viewTab\` / \`onViewTabChange\`: \`lagged\` (calendar-aligned, raw dates) or \`overlapped\` (driver series shifted backward by parsed lag months)
242
240
 
243
- View tabs: host should render uilib \`Tabs variant="button"\` with **Lagged** / **Overlapped** in the toolbar (analysis selector left, tabs right). Chart applies \`applyDriversComparisonViewToPayload\` internally.
241
+ View tabs: host should render uilib \`Tabs variant="button"\` with **Lagged** / **Overlapped** in the toolbar. Chart applies \`applyDriversComparisonViewToPayload\` internally.
244
242
 
245
- Report tile: \`drivers_comparison_chart\` — host loads normalized backtests payload + dataset historical; built-in analysis selector.
243
+ Report tile: \`drivers_comparison_chart\` — host loads normalized backtests payload + dataset historical.
246
244
 
247
245
  Requires: \`payload\` — target + driver normalized_series; \`loading\` / \`chartLoading\` — spinners; \`seriesInitKey\` — reset visible series on analysis or view tab change; \`runAnalysisHint\` / \`statusHint\` — empty/error text.
248
246
 
@@ -179,7 +179,6 @@ Host provides:
179
179
  - `chartData`, `forecastData` built from API
180
180
  - `timeRange` / `onTimeRangeChange` or brush-only range
181
181
  - Optional `mode`: pin | intervals | thresholds + overlay state
182
- - Analysis selector and fetch outside widget
183
182
 
184
183
  Report tile: `dataset_card` — host loads dataset + analysis; chart inside dashboard card.
185
184
 
@@ -200,7 +199,7 @@ Host provides:
200
199
  - Controlled `selectedDriver` + `setSelectedDriver`
201
200
  - `isLoading` while fetching drivers
202
201
 
203
- Report tile: `drivers_map` — tile resolves analysis id, fetches drivers, passes list + selection (see EmbeddedAnalysisSelector pattern).
202
+ Report tile: `drivers_map` — tile resolves analysis id, fetches drivers, passes list + selection.
204
203
 
205
204
  Requires: `drivers`; `isLoading`; `selectedDriver`; `setSelectedDriver`.
206
205
 
@@ -216,10 +215,9 @@ Not when: simple forecast card or driver backtests — use ChartAreaInteractive
216
215
  Host provides:
217
216
 
218
217
  - `performanceData` (PerformanceChartPayload) and `historicalData` from performance API
219
- - Analysis selection and fetch outside widget
220
218
  - Optional `forecastData`, `customPerformanceMatrix`, `userSeries` for spaghetti
221
219
 
222
- Report tile: `performance_chart` — host loads performance payload + dataset series; built-in analysis selector.
220
+ Report tile: `performance_chart` — host loads performance payload + dataset series.
223
221
 
224
222
  Requires: `performanceData` — model/drift forecasts and metrics; `historicalData` — baseline series; `loading` / `chartLoading` / `performanceDataLoading` — spinners; `runAnalysisHint` / `statusHint` — empty states.
225
223
 
@@ -239,9 +237,9 @@ Host provides:
239
237
  - `seriesInitKey` when selected analysis changes
240
238
  - `viewTab` / `onViewTabChange`: `lagged` (calendar-aligned, raw dates) or `overlapped` (driver series shifted backward by parsed lag months)
241
239
 
242
- View tabs: host should render uilib `Tabs variant="button"` with **Lagged** / **Overlapped** in the toolbar (analysis selector left, tabs right). Chart applies `applyDriversComparisonViewToPayload` internally.
240
+ View tabs: host should render uilib `Tabs variant="button"` with **Lagged** / **Overlapped** in the toolbar. Chart applies `applyDriversComparisonViewToPayload` internally.
243
241
 
244
- Report tile: `drivers_comparison_chart` — host loads normalized backtests payload + dataset historical; built-in analysis selector.
242
+ Report tile: `drivers_comparison_chart` — host loads normalized backtests payload + dataset historical.
245
243
 
246
244
  Requires: `payload` — target + driver normalized_series; `loading` / `chartLoading` — spinners; `seriesInitKey` — reset visible series on analysis or view tab change; `runAnalysisHint` / `statusHint` — empty/error text.
247
245
 
@@ -199,7 +199,6 @@ Host provides:
199
199
  - \`chartData\`, \`forecastData\` built from API
200
200
  - \`timeRange\` / \`onTimeRangeChange\` or brush-only range
201
201
  - Optional \`mode\`: pin | intervals | thresholds + overlay state
202
- - Analysis selector and fetch outside widget
203
202
 
204
203
  Report tile: \`dataset_card\` — host loads dataset + analysis; chart inside dashboard card.
205
204
 
@@ -220,7 +219,7 @@ Host provides:
220
219
  - Controlled \`selectedDriver\` + \`setSelectedDriver\`
221
220
  - \`isLoading\` while fetching drivers
222
221
 
223
- Report tile: \`drivers_map\` — tile resolves analysis id, fetches drivers, passes list + selection (see EmbeddedAnalysisSelector pattern).
222
+ Report tile: \`drivers_map\` — tile resolves analysis id, fetches drivers, passes list + selection.
224
223
 
225
224
  Requires: \`drivers\`; \`isLoading\`; \`selectedDriver\`; \`setSelectedDriver\`.
226
225
 
@@ -236,10 +235,9 @@ Not when: simple forecast card or driver backtests — use ChartAreaInteractive
236
235
  Host provides:
237
236
 
238
237
  - \`performanceData\` (PerformanceChartPayload) and \`historicalData\` from performance API
239
- - Analysis selection and fetch outside widget
240
238
  - Optional \`forecastData\`, \`customPerformanceMatrix\`, \`userSeries\` for spaghetti
241
239
 
242
- Report tile: \`performance_chart\` — host loads performance payload + dataset series; built-in analysis selector.
240
+ Report tile: \`performance_chart\` — host loads performance payload + dataset series.
243
241
 
244
242
  Requires: \`performanceData\` — model/drift forecasts and metrics; \`historicalData\` — baseline series; \`loading\` / \`chartLoading\` / \`performanceDataLoading\` — spinners; \`runAnalysisHint\` / \`statusHint\` — empty states.
245
243
 
@@ -259,9 +257,9 @@ Host provides:
259
257
  - \`seriesInitKey\` when selected analysis changes
260
258
  - \`viewTab\` / \`onViewTabChange\`: \`lagged\` (calendar-aligned, raw dates) or \`overlapped\` (driver series shifted backward by parsed lag months)
261
259
 
262
- View tabs: host should render uilib \`Tabs variant="button"\` with **Lagged** / **Overlapped** in the toolbar (analysis selector left, tabs right). Chart applies \`applyDriversComparisonViewToPayload\` internally.
260
+ View tabs: host should render uilib \`Tabs variant="button"\` with **Lagged** / **Overlapped** in the toolbar. Chart applies \`applyDriversComparisonViewToPayload\` internally.
263
261
 
264
- Report tile: \`drivers_comparison_chart\` — host loads normalized backtests payload + dataset historical; built-in analysis selector.
262
+ Report tile: \`drivers_comparison_chart\` — host loads normalized backtests payload + dataset historical.
265
263
 
266
264
  Requires: \`payload\` — target + driver normalized_series; \`loading\` / \`chartLoading\` — spinners; \`seriesInitKey\` — reset visible series on analysis or view tab change; \`runAnalysisHint\` / \`statusHint\` — empty/error text.
267
265
 
@@ -198,7 +198,6 @@ Host provides:
198
198
  - `chartData`, `forecastData` built from API
199
199
  - `timeRange` / `onTimeRangeChange` or brush-only range
200
200
  - Optional `mode`: pin | intervals | thresholds + overlay state
201
- - Analysis selector and fetch outside widget
202
201
 
203
202
  Report tile: `dataset_card` — host loads dataset + analysis; chart inside dashboard card.
204
203
 
@@ -219,7 +218,7 @@ Host provides:
219
218
  - Controlled `selectedDriver` + `setSelectedDriver`
220
219
  - `isLoading` while fetching drivers
221
220
 
222
- Report tile: `drivers_map` — tile resolves analysis id, fetches drivers, passes list + selection (see EmbeddedAnalysisSelector pattern).
221
+ Report tile: `drivers_map` — tile resolves analysis id, fetches drivers, passes list + selection.
223
222
 
224
223
  Requires: `drivers`; `isLoading`; `selectedDriver`; `setSelectedDriver`.
225
224
 
@@ -235,10 +234,9 @@ Not when: simple forecast card or driver backtests — use ChartAreaInteractive
235
234
  Host provides:
236
235
 
237
236
  - `performanceData` (PerformanceChartPayload) and `historicalData` from performance API
238
- - Analysis selection and fetch outside widget
239
237
  - Optional `forecastData`, `customPerformanceMatrix`, `userSeries` for spaghetti
240
238
 
241
- Report tile: `performance_chart` — host loads performance payload + dataset series; built-in analysis selector.
239
+ Report tile: `performance_chart` — host loads performance payload + dataset series.
242
240
 
243
241
  Requires: `performanceData` — model/drift forecasts and metrics; `historicalData` — baseline series; `loading` / `chartLoading` / `performanceDataLoading` — spinners; `runAnalysisHint` / `statusHint` — empty states.
244
242
 
@@ -258,9 +256,9 @@ Host provides:
258
256
  - `seriesInitKey` when selected analysis changes
259
257
  - `viewTab` / `onViewTabChange`: `lagged` (calendar-aligned, raw dates) or `overlapped` (driver series shifted backward by parsed lag months)
260
258
 
261
- View tabs: host should render uilib `Tabs variant="button"` with **Lagged** / **Overlapped** in the toolbar (analysis selector left, tabs right). Chart applies `applyDriversComparisonViewToPayload` internally.
259
+ View tabs: host should render uilib `Tabs variant="button"` with **Lagged** / **Overlapped** in the toolbar. Chart applies `applyDriversComparisonViewToPayload` internally.
262
260
 
263
- Report tile: `drivers_comparison_chart` — host loads normalized backtests payload + dataset historical; built-in analysis selector.
261
+ Report tile: `drivers_comparison_chart` — host loads normalized backtests payload + dataset historical.
264
262
 
265
263
  Requires: `payload` — target + driver normalized_series; `loading` / `chartLoading` — spinners; `seriesInitKey` — reset visible series on analysis or view tab change; `runAnalysisHint` / `statusHint` — empty/error text.
266
264
 
@@ -1,9 +1,10 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import S from './ChatEmptyState.styl.js';
3
3
  import SparklesIcon from './icons/sparkles.svg.js';
4
+ import cn from 'classnames';
4
5
 
5
- function ChatEmptyState({ icon = jsx(SparklesIcon, {}), title = 'Start a conversation', description, additionalContent, children, }) {
6
- return (jsxs("div", { className: S.root, children: [icon && jsx("div", { className: S.icon, children: icon }), title && jsx("h2", { children: title }), description && jsx("p", { children: description }), additionalContent, children] }));
6
+ function ChatEmptyState({ icon = jsx(SparklesIcon, {}), title = 'Start a conversation', description, additionalContent, children, className, }) {
7
+ return (jsxs("div", { className: cn(S.root, className), children: [icon && jsx("div", { className: S.icon, children: icon }), title && jsx("h2", { children: title }), description && jsx("p", { children: description }), additionalContent, children] }));
7
8
  }
8
9
 
9
10
  export { ChatEmptyState };
@@ -6,7 +6,8 @@ import { Button } from '../../Button/Button.js';
6
6
  import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from '../../Select/Select.js';
7
7
  import S from './ChatSelector.styl.js';
8
8
 
9
- function ChatSelector({ id, wrapperClassName, className, onChatDeleted, onNewChat, }) {
9
+ const deleteIconSize = (s) => s === 'sm' ? 16 : s === 'md' ? 18 : 20;
10
+ function ChatSelector({ id, size = 'sm', variant = 'clear', wrapperClassName, className, onChatDeleted, onNewChat, }) {
10
11
  const { chats, currentChatId, setCurrentChatId, newChat, deleteChat } = useChatsForScopeId(id);
11
12
  const handleValueChange = (value) => {
12
13
  if (value === 'new') {
@@ -39,7 +40,7 @@ function ChatSelector({ id, wrapperClassName, className, onChatDeleted, onNewCha
39
40
  }
40
41
  return 'New chat';
41
42
  };
42
- return (jsxs("div", { className: cn(S.wrapper, wrapperClassName), children: [jsx("div", { className: S.selectGrow, children: jsxs(Select, { variant: "clear", value: currentChatId?.toString() ?? '', onValueChange: handleValueChange, children: [jsx(SelectTrigger, { size: "sm", className: className ? cn(S.selectTrigger, className) : S.selectTrigger, children: jsx(SelectValue, { placeholder: "Select chat" }) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "new", children: "+ New Chat" }), chats.map(chat => (jsx(SelectItem, { value: chat.session_id.toString(), selected: chat.session_id === currentChatId, children: getChatDisplayName(chat) }, chat.session_id)))] })] }) }), currentChatId && chats.length > 0 && (jsx(Button, { type: "button", variant: "ghost", size: "sm", className: S.deleteBtn, "aria-label": "Delete chat", onClick: handleDeleteChat, children: jsx(Trash2Icon, { size: 16 }) }))] }));
43
+ return (jsxs("div", { className: cn(S.wrapper, variant === 'clear' ? S.variantClear : S.variantDefault, wrapperClassName), children: [jsx("div", { className: S.selectGrow, children: jsxs(Select, { variant: variant, value: currentChatId?.toString() ?? '', onValueChange: handleValueChange, children: [jsx(SelectTrigger, { size: size, variant: variant, className: className ? cn(S.selectTrigger, className) : S.selectTrigger, children: jsx(SelectValue, { placeholder: "Select chat" }) }), jsxs(SelectContent, { children: [jsx(SelectItem, { value: "new", children: "+ New Chat" }), chats.map(chat => (jsx(SelectItem, { value: chat.session_id.toString(), selected: chat.session_id === currentChatId, children: getChatDisplayName(chat) }, chat.session_id)))] })] }) }), currentChatId && chats.length > 0 && (jsx(Button, { type: "button", variant: "ghost", size: size, className: S.deleteBtn, "aria-label": "Delete chat", onClick: handleDeleteChat, children: jsx(Trash2Icon, { size: deleteIconSize(size) }) }))] }));
43
44
  }
44
45
 
45
46
  export { ChatSelector };
@@ -1,7 +1,7 @@
1
1
  import styleInject from 'style-inject';
2
2
 
3
- var css_248z = "@media (max-width:768px){:root{--page-x-padding:var(--p-6);--page-y-padding:var(--p-6)}}.ChatSelector_wrapper__8Z4wN{align-items:center;display:flex;gap:var(--p-2);min-width:200px;z-index:1000}.ChatSelector_selectGrow__bGR0A{flex:1;min-width:0}.ChatSelector_selectTrigger__DASfc{width:100%}.ChatSelector_deleteBtn__oJ-9b{border-radius:50px;flex-shrink:0;opacity:0;pointer-events:none}.ChatSelector_wrapper__8Z4wN:hover .ChatSelector_deleteBtn__oJ-9b{opacity:1;pointer-events:auto}";
4
- var S = {"wrapper":"ChatSelector_wrapper__8Z4wN","selectGrow":"ChatSelector_selectGrow__bGR0A","selectTrigger":"ChatSelector_selectTrigger__DASfc","deleteBtn":"ChatSelector_deleteBtn__oJ-9b"};
3
+ var css_248z = "@media (max-width:768px){:root{--page-x-padding:var(--p-6);--page-y-padding:var(--p-6)}}.ChatSelector_wrapper__8Z4wN{align-items:center;display:flex;gap:var(--p-1);min-width:160px;z-index:1000}.ChatSelector_selectGrow__bGR0A{flex:1;min-width:0}.ChatSelector_selectTrigger__DASfc{width:100%}.ChatSelector_deleteBtn__oJ-9b{border-radius:50px;flex-shrink:0;opacity:0;pointer-events:none}.ChatSelector_wrapper__8Z4wN:hover .ChatSelector_deleteBtn__oJ-9b{opacity:1;pointer-events:auto}.ChatSelector_variantClear__ZN0MI .ChatSelector_selectTrigger__DASfc{background-color:transparent;border:none;box-shadow:none}.ChatSelector_variantClear__ZN0MI .ChatSelector_selectTrigger__DASfc:hover{background-color:transparent;box-shadow:none}.ChatSelector_variantDefault__y-WeT .ChatSelector_selectTrigger__DASfc{background-color:var(--background)}.ChatSelector_variantDefault__y-WeT .ChatSelector_selectTrigger__DASfc:hover{box-shadow:0 0 0 2px var(--background)}";
4
+ var S = {"wrapper":"ChatSelector_wrapper__8Z4wN","selectGrow":"ChatSelector_selectGrow__bGR0A","selectTrigger":"ChatSelector_selectTrigger__DASfc","deleteBtn":"ChatSelector_deleteBtn__oJ-9b","variantClear":"ChatSelector_variantClear__ZN0MI","variantDefault":"ChatSelector_variantDefault__y-WeT"};
5
5
  styleInject(css_248z);
6
6
 
7
7
  export { S as default };
@@ -34,7 +34,7 @@ function ChatSheet({ triggerLabel = 'Open Chat', triggerAriaLabel, actionsRef, r
34
34
  if (inline) {
35
35
  return jsx(ChatChrome, { ...model.chromeProps });
36
36
  }
37
- return (jsxs(Fragment, { children: [renderTrigger?.(model.toggleOpen) ?? (jsx(Button, { variant: "outline", "aria-label": triggerAriaLabel, onClick: model.toggleOpen, children: triggerLabel })), model.isOpen &&
37
+ return (jsxs(Fragment, { children: [renderTrigger?.(model.toggleOpen, model.isOpen) ?? (jsx(Button, { variant: "outline", "aria-label": triggerAriaLabel, onClick: model.toggleOpen, children: triggerLabel })), model.isOpen &&
38
38
  model.chatPanelContainer &&
39
39
  createPortal(jsx(ChatChrome, { ...model.chromeProps }), model.chatPanelContainer)] }));
40
40
  }
@@ -1,6 +1,6 @@
1
1
  import styleInject from 'style-inject';
2
2
 
3
- var css_248z = ".Select_selectTrigger__oTOBl{align-items:center;background-color:var(--background);border:none;border-radius:var(--p-4);box-shadow:none;color:var(--foreground);cursor:pointer;display:flex;font-size:var(--text-sm);font-weight:500;gap:var(--p-1);justify-content:space-between;max-width:calc(90vw - var(--page-x-padding)*2);outline:none;overflow:hidden;padding:var(--p-1) var(--p-3);position:relative;transition:all .2s ease-in-out;white-space:nowrap;width:-moz-fit-content;width:fit-content}.Select_selectTrigger__oTOBl:before{background-image:linear-gradient(to right,transparent,var(--background));content:\"\";display:block;height:100%;left:60vw;min-height:100%;min-width:var(--page-x-padding);position:absolute;width:var(--page-x-padding);width:20%}.Select_selectTrigger__oTOBl[aria-expanded=true]:before{display:none}.Select_selectTrigger__oTOBl.Select_darker__wwisI{background-color:var(--muted)}.Select_selectTrigger__oTOBl:hover{box-shadow:0 0 0 2px var(--background)}.Select_selectTrigger__oTOBl[data-size=md]{height:1.75rem}.Select_selectTrigger__oTOBl[data-size=sm]{font-size:var(--text-xs);height:1.75rem}.Select_selectTrigger__oTOBl[data-size=lg]{font-size:var(--text-sm);height:2.25rem}.Select_selectTrigger__oTOBl[data-placeholder]{color:var(--muted-foreground)}.Select_selectTrigger__oTOBl:focus-visible{border-color:var(--ring)}.Select_selectTrigger__oTOBl[aria-invalid=true]{border-color:var(--destructive)}.Select_selectTrigger__oTOBl:disabled{cursor:not-allowed;opacity:.5}.Select_selectTrigger__oTOBl [data-slot=select-value]{align-items:center;display:flex;gap:var(--p-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.Select_selectTrigger__oTOBl svg{flex-shrink:0;pointer-events:none}.Select_selectTrigger__oTOBl svg:not([class*=text-]){color:var(--foreground)}.Select_selectTrigger__oTOBl svg:not([class*=size-]){height:1rem;width:1rem}.dark .Select_selectTrigger__oTOBl:not(.Select_darker__wwisI){background-color:var(--background)}.dark .Select_selectTrigger__oTOBl:not(.Select_darker__wwisI):hover{background-color:var(--background-alpha-800)}.Select_clear__vxo-N{background-color:transparent;border:none;box-shadow:none;padding:0}.Select_clear__vxo-N:focus-visible{border:none;box-shadow:none}@media (prefers-color-scheme:dark){.Select_clear__vxo-N,.Select_clear__vxo-N:hover{background-color:transparent}}.Select_selectContent__Wbegi{background-color:var(--popover);border:1px solid var(--border);border-radius:var(--p-4);box-shadow:0 10px 15px -3px rgba(0,0,0,.1);color:var(--popover-foreground);max-height:var(--radix-select-content-available-height);min-width:8rem;overflow-x:hidden;overflow-y:auto;position:relative;transform-origin:var(--radix-select-content-transform-origin);z-index:1100}.Select_selectContent__Wbegi[data-state=open]{animation:Select_fadeIn__hm7v- .25s,Select_zoomIn__ep77v .1s}.Select_selectContent__Wbegi[data-state=closed]{animation:Select_fadeOut__A-ccN .25s,Select_zoomOut__pZ-7e .1s}.Select_selectContent__Wbegi[data-side=bottom]{animation:Select_fadeIn__hm7v- .25s,Select_slideInFromTop__O1LeF .1s}.Select_selectContent__Wbegi[data-side=left]{animation:Select_fadeIn__hm7v- .25s,Select_slideInFromRight__iJq-J .1s}.Select_selectContent__Wbegi[data-side=right]{animation:Select_fadeIn__hm7v- .25s,Select_slideInFromLeft__8tm7S .1s}.Select_selectContent__Wbegi[data-side=top]{animation:Select_fadeIn__hm7v- .25s,Select_slideInFromBottom__PsvX6 .1s}.Select_selectContentPopper__TU8Jn[data-side=bottom]{transform:translateY(.25rem)}.Select_selectContentPopper__TU8Jn[data-side=left]{transform:translateX(-.25rem)}.Select_selectContentPopper__TU8Jn[data-side=right]{transform:translateX(.25rem)}.Select_selectContentPopper__TU8Jn[data-side=top]{transform:translateY(-.25rem)}.Select_selectViewport__OtOW7{padding:var(--p-1)}.Select_selectViewportPopper__dUoFi{height:var(--radix-select-trigger-height);min-width:var(--radix-select-trigger-width);scroll-margin:var(--p-1) 0;width:100%}.Select_selectLabel__rX9cj{color:var(--muted-foreground);font-size:var(--text-xs);padding:var(--p-2) var(--p-2);padding-bottom:var(--p-2);padding-top:var(--p-2)}.Select_selectItem__JLg4D{align-items:center;border-radius:var(--radius-sm);cursor:default;display:flex;flex-grow:1;font-size:var(--text-sm);gap:var(--p-2);outline:none;padding:var(--p-1) var(--p-2);position:relative;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:100%}.Select_selectItem__JLg4D.Select_selected__tmqut{background-color:var(--accent);font-weight:600}.Select_selectItem__JLg4D:first-child{border-top-left-radius:var(--p-3);border-top-right-radius:var(--p-3)}.Select_selectItem__JLg4D:last-child{border-bottom-left-radius:var(--p-3);border-bottom-right-radius:var(--p-3)}.Select_selectItem__JLg4D:focus{background-color:var(--accent);color:var(--accent-foreground)}.Select_selectItem__JLg4D[data-disabled]{opacity:.5;pointer-events:none}.Select_selectItem__JLg4D svg{flex-shrink:0;pointer-events:none}.Select_selectItem__JLg4D svg:not([class*=text-]){color:var(--muted-foreground)}.Select_selectItem__JLg4D svg:not([class*=size-]){height:1rem;width:1rem}.Select_selectItem__JLg4D span:not([data-slot=analysis-icon]){display:flex;flex-grow:1;width:100%}.Select_selectItem__JLg4D span:last-child{align-items:center;display:flex;gap:var(--p-2)}.Select_selectItemText__9JXv9{align-items:center;display:flex;gap:var(--p-1)}.Select_selectItemIndicatorContainer__Vte2-{align-items:center;display:flex;height:var(--p-8);justify-content:center;position:absolute;right:0;width:var(--p-8)}.Select_selectItemIndicator__9HcxQ{height:1rem;width:1rem}.Select_selectSeparator__OZw53{background-color:var(--border);height:1px;margin:-.25rem var(--p-1) var(--p-1);pointer-events:none}.Select_selectScrollButton__-z-iR{align-items:center;cursor:default;display:flex;justify-content:center;padding:var(--p-1) 0}.Select_selectIcon__-TfP9{height:1rem;margin-right:calc(var(--p-1)*-1);opacity:.5;width:1rem}.Select_selectScrollIcon__ZyTUI{height:1rem;width:1rem}@keyframes Select_fadeIn__hm7v-{0%{opacity:0}to{opacity:1}}@keyframes Select_fadeOut__A-ccN{0%{opacity:1}to{opacity:0}}@keyframes Select_zoomIn__ep77v{0%{transform:scale(.95)}to{transform:scale(1)}}@keyframes Select_zoomOut__pZ-7e{0%{transform:scale(1)}to{transform:scale(.95)}}@keyframes Select_slideInFromTop__O1LeF{0%{transform:translateY(-.5rem)}to{transform:translateY(.2)}}@keyframes Select_slideInFromBottom__PsvX6{0%{transform:translateY(.5rem)}to{transform:translateY(.2)}}@keyframes Select_slideInFromLeft__8tm7S{0%{transform:translateX(-.5rem)}to{transform:translateX(.2)}}@keyframes Select_slideInFromRight__iJq-J{0%{transform:translateX(.5rem)}to{transform:translateY(.2)}}";
3
+ var css_248z = ".Select_selectTrigger__oTOBl{align-items:center;background-color:var(--background);border:none;border-radius:var(--p-4);box-shadow:none;color:var(--foreground);cursor:pointer;display:flex;font-size:var(--text-sm);font-weight:500;gap:var(--p-1);justify-content:space-between;max-width:calc(90vw - var(--page-x-padding)*2);outline:none;overflow:hidden;padding:var(--p-1) var(--p-3);position:relative;transition:all .2s ease-in-out;white-space:nowrap;width:-moz-fit-content;width:fit-content}.Select_selectTrigger__oTOBl:before{background-image:linear-gradient(to right,transparent,var(--background));content:\"\";display:block;height:100%;left:60vw;min-height:100%;min-width:var(--page-x-padding);position:absolute;width:var(--page-x-padding);width:20%}.Select_selectTrigger__oTOBl[aria-expanded=true]:before{display:none}.Select_selectTrigger__oTOBl.Select_darker__wwisI{background-color:var(--muted)}.Select_selectTrigger__oTOBl:hover{box-shadow:0 0 0 2px var(--background)}.Select_selectTrigger__oTOBl[data-size=sm]{border-radius:var(--p-4);font-size:var(--text-xs);height:auto;min-height:28px;padding:0 var(--p-4)}.Select_selectTrigger__oTOBl[data-size=md]{border-radius:var(--p-4);font-size:var(--text-sm);height:auto;min-height:40px;padding:var(--p-3) var(--p-4)}.Select_selectTrigger__oTOBl[data-size=lg]{border-radius:var(--p-4);font-size:var(--text-sm);height:auto;min-height:auto;padding:var(--p-4) var(--p-6)}.Select_selectTrigger__oTOBl[data-placeholder]{color:var(--muted-foreground)}.Select_selectTrigger__oTOBl:focus-visible{border-color:var(--ring)}.Select_selectTrigger__oTOBl[aria-invalid=true]{border-color:var(--destructive)}.Select_selectTrigger__oTOBl:disabled{cursor:not-allowed;opacity:.5}.Select_selectTrigger__oTOBl [data-slot=select-value]{align-items:center;display:flex;gap:var(--p-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.Select_selectTrigger__oTOBl svg{flex-shrink:0;pointer-events:none}.Select_selectTrigger__oTOBl svg:not([class*=text-]){color:var(--foreground)}.Select_selectTrigger__oTOBl svg:not([class*=size-]){height:1rem;width:1rem}.dark .Select_selectTrigger__oTOBl:not(.Select_darker__wwisI){background-color:var(--background)}.dark .Select_selectTrigger__oTOBl:not(.Select_darker__wwisI):hover{background-color:var(--background-alpha-800)}.Select_clear__vxo-N{background-color:transparent;border:none;box-shadow:none}.Select_clear__vxo-N:focus-visible{border:none;box-shadow:none}@media (prefers-color-scheme:dark){.Select_clear__vxo-N,.Select_clear__vxo-N:hover{background-color:transparent}}.Select_selectContent__Wbegi{background-color:var(--popover);border:1px solid var(--border);border-radius:var(--p-4);box-shadow:0 10px 15px -3px rgba(0,0,0,.1);color:var(--popover-foreground);max-height:var(--radix-select-content-available-height);min-width:8rem;overflow-x:hidden;overflow-y:auto;position:relative;transform-origin:var(--radix-select-content-transform-origin);z-index:1100}.Select_selectContent__Wbegi[data-state=open]{animation:Select_fadeIn__hm7v- .25s,Select_zoomIn__ep77v .1s}.Select_selectContent__Wbegi[data-state=closed]{animation:Select_fadeOut__A-ccN .25s,Select_zoomOut__pZ-7e .1s}.Select_selectContent__Wbegi[data-side=bottom]{animation:Select_fadeIn__hm7v- .25s,Select_slideInFromTop__O1LeF .1s}.Select_selectContent__Wbegi[data-side=left]{animation:Select_fadeIn__hm7v- .25s,Select_slideInFromRight__iJq-J .1s}.Select_selectContent__Wbegi[data-side=right]{animation:Select_fadeIn__hm7v- .25s,Select_slideInFromLeft__8tm7S .1s}.Select_selectContent__Wbegi[data-side=top]{animation:Select_fadeIn__hm7v- .25s,Select_slideInFromBottom__PsvX6 .1s}.Select_selectContentPopper__TU8Jn[data-side=bottom]{transform:translateY(.25rem)}.Select_selectContentPopper__TU8Jn[data-side=left]{transform:translateX(-.25rem)}.Select_selectContentPopper__TU8Jn[data-side=right]{transform:translateX(.25rem)}.Select_selectContentPopper__TU8Jn[data-side=top]{transform:translateY(-.25rem)}.Select_selectViewport__OtOW7{padding:var(--p-1)}.Select_selectViewportPopper__dUoFi{height:var(--radix-select-trigger-height);min-width:var(--radix-select-trigger-width);scroll-margin:var(--p-1) 0;width:100%}.Select_selectLabel__rX9cj{color:var(--muted-foreground);font-size:var(--text-xs);padding:var(--p-2) var(--p-2);padding-bottom:var(--p-2);padding-top:var(--p-2)}.Select_selectItem__JLg4D{align-items:center;border-radius:var(--radius-sm);cursor:default;display:flex;flex-grow:1;font-size:var(--text-sm);gap:var(--p-2);outline:none;padding:var(--p-1) var(--p-2);position:relative;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:100%}.Select_selectItem__JLg4D.Select_selected__tmqut{background-color:var(--accent);font-weight:600}.Select_selectItem__JLg4D:first-child{border-top-left-radius:var(--p-3);border-top-right-radius:var(--p-3)}.Select_selectItem__JLg4D:last-child{border-bottom-left-radius:var(--p-3);border-bottom-right-radius:var(--p-3)}.Select_selectItem__JLg4D:focus{background-color:var(--accent);color:var(--accent-foreground)}.Select_selectItem__JLg4D[data-disabled]{opacity:.5;pointer-events:none}.Select_selectItem__JLg4D svg{flex-shrink:0;pointer-events:none}.Select_selectItem__JLg4D svg:not([class*=text-]){color:var(--muted-foreground)}.Select_selectItem__JLg4D svg:not([class*=size-]){height:1rem;width:1rem}.Select_selectItem__JLg4D span:not([data-slot=analysis-icon]){display:flex;flex-grow:1;width:100%}.Select_selectItem__JLg4D span:last-child{align-items:center;display:flex;gap:var(--p-2)}.Select_selectItemText__9JXv9{align-items:center;display:flex;gap:var(--p-1)}.Select_selectItemIndicatorContainer__Vte2-{align-items:center;display:flex;height:var(--p-8);justify-content:center;position:absolute;right:0;width:var(--p-8)}.Select_selectItemIndicator__9HcxQ{height:1rem;width:1rem}.Select_selectSeparator__OZw53{background-color:var(--border);height:1px;margin:-.25rem var(--p-1) var(--p-1);pointer-events:none}.Select_selectScrollButton__-z-iR{align-items:center;cursor:default;display:flex;justify-content:center;padding:var(--p-1) 0}.Select_selectIcon__-TfP9{height:1rem;margin-right:calc(var(--p-1)*-1);opacity:.5;width:1rem}.Select_selectScrollIcon__ZyTUI{height:1rem;width:1rem}@keyframes Select_fadeIn__hm7v-{0%{opacity:0}to{opacity:1}}@keyframes Select_fadeOut__A-ccN{0%{opacity:1}to{opacity:0}}@keyframes Select_zoomIn__ep77v{0%{transform:scale(.95)}to{transform:scale(1)}}@keyframes Select_zoomOut__pZ-7e{0%{transform:scale(1)}to{transform:scale(.95)}}@keyframes Select_slideInFromTop__O1LeF{0%{transform:translateY(-.5rem)}to{transform:translateY(.2)}}@keyframes Select_slideInFromBottom__PsvX6{0%{transform:translateY(.5rem)}to{transform:translateY(.2)}}@keyframes Select_slideInFromLeft__8tm7S{0%{transform:translateX(-.5rem)}to{transform:translateX(.2)}}@keyframes Select_slideInFromRight__iJq-J{0%{transform:translateX(.5rem)}to{transform:translateY(.2)}}";
4
4
  var S = {"selectTrigger":"Select_selectTrigger__oTOBl","darker":"Select_darker__wwisI","clear":"Select_clear__vxo-N","selectContent":"Select_selectContent__Wbegi","fadeIn":"Select_fadeIn__hm7v-","zoomIn":"Select_zoomIn__ep77v","fadeOut":"Select_fadeOut__A-ccN","zoomOut":"Select_zoomOut__pZ-7e","slideInFromTop":"Select_slideInFromTop__O1LeF","slideInFromRight":"Select_slideInFromRight__iJq-J","slideInFromLeft":"Select_slideInFromLeft__8tm7S","slideInFromBottom":"Select_slideInFromBottom__PsvX6","selectContentPopper":"Select_selectContentPopper__TU8Jn","selectViewport":"Select_selectViewport__OtOW7","selectViewportPopper":"Select_selectViewportPopper__dUoFi","selectLabel":"Select_selectLabel__rX9cj","selectItem":"Select_selectItem__JLg4D","selected":"Select_selected__tmqut","selectItemText":"Select_selectItemText__9JXv9","selectItemIndicatorContainer":"Select_selectItemIndicatorContainer__Vte2-","selectItemIndicator":"Select_selectItemIndicator__9HcxQ","selectSeparator":"Select_selectSeparator__OZw53","selectScrollButton":"Select_selectScrollButton__-z-iR","selectIcon":"Select_selectIcon__-TfP9","selectScrollIcon":"Select_selectScrollIcon__ZyTUI"};
5
5
  styleInject(css_248z);
6
6
 
@@ -1,3 +1,3 @@
1
- import { PropsWithChildren } from 'react';
2
1
  import type { ChatEmptyStateProps } from './ChatEmptyState.types';
3
- export declare function ChatEmptyState({ icon, title, description, additionalContent, children, }: PropsWithChildren<ChatEmptyStateProps>): import("react/jsx-runtime").JSX.Element;
2
+ import { PropsWithChildren } from 'react';
3
+ export declare function ChatEmptyState({ icon, title, description, additionalContent, children, className, }: PropsWithChildren<ChatEmptyStateProps>): import("react/jsx-runtime").JSX.Element;
@@ -5,6 +5,7 @@ export type ChatEmptyStateContext = {
5
5
  export interface ChatEmptyStateProps {
6
6
  icon?: React.ReactNode;
7
7
  title?: string;
8
+ className?: string;
8
9
  description?: string;
9
10
  /** Extra block below description (resolved before render in `ChatEmptyState`). */
10
11
  additionalContent?: React.ReactNode;
@@ -1,4 +1,5 @@
1
- export interface ChatSelectorProps {
1
+ import type { SelectProps, SelectTriggerProps } from '#uilib/components/ui/Select/Select.types.js';
2
+ export interface ChatSelectorProps extends SelectProps, Pick<SelectTriggerProps, 'size' | 'variant'> {
2
3
  id: string;
3
4
  wrapperClassName?: string;
4
5
  className?: string;
@@ -6,4 +7,4 @@ export interface ChatSelectorProps {
6
7
  /** When set, used for "+ New Chat" instead of the default empty `newChat()`. */
7
8
  onNewChat?: () => void;
8
9
  }
9
- export declare function ChatSelector({ id, wrapperClassName, className, onChatDeleted, onNewChat, }: ChatSelectorProps): import("react/jsx-runtime").JSX.Element;
10
+ export declare function ChatSelector({ id, size, variant, wrapperClassName, className, onChatDeleted, onNewChat, }: ChatSelectorProps): import("react/jsx-runtime").JSX.Element;
@@ -10,7 +10,7 @@ export interface ChatSheetProps extends Omit<UseChatPanelChromeModelInput, 'embe
10
10
  title?: string;
11
11
  /** Imperative open / new-chat for triggers outside `renderTrigger` (e.g. sidebar). */
12
12
  actionsRef?: React.MutableRefObject<ChatSheetActions | null>;
13
- renderTrigger?: (toggleOpen: () => void) => React.ReactNode;
13
+ renderTrigger?: (toggleOpen: () => void, isOpen: boolean) => React.ReactNode;
14
14
  triggerLabel?: React.ReactNode;
15
15
  /** aria-label for icon-only trigger (required when trigger has no visible text) */
16
16
  triggerAriaLabel?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sybilion/uilib",
3
- "version": "1.3.85",
3
+ "version": "1.3.87",
4
4
  "description": "Sybilion Design System — React UI components (Webpack + Stylus)",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -10,7 +10,6 @@ Host provides:
10
10
  - `chartData`, `forecastData` built from API
11
11
  - `timeRange` / `onTimeRangeChange` or brush-only range
12
12
  - Optional `mode`: pin | intervals | thresholds + overlay state
13
- - Analysis selector and fetch outside widget
14
13
 
15
14
  Report tile: `dataset_card` — host loads dataset + analysis; chart inside dashboard card.
16
15
 
@@ -1,8 +1,8 @@
1
+ import type { ChatEmptyStateProps } from './ChatEmptyState.types';
1
2
  import { PropsWithChildren } from 'react';
2
-
3
3
  import S from './ChatEmptyState.styl';
4
- import type { ChatEmptyStateProps } from './ChatEmptyState.types';
5
4
  import SparklesIcon from './icons/sparkles.svg';
5
+ import cn from 'classnames';
6
6
 
7
7
  export function ChatEmptyState({
8
8
  icon = <SparklesIcon />,
@@ -10,9 +10,10 @@ export function ChatEmptyState({
10
10
  description,
11
11
  additionalContent,
12
12
  children,
13
+ className,
13
14
  }: PropsWithChildren<ChatEmptyStateProps>) {
14
15
  return (
15
- <div className={S.root}>
16
+ <div className={cn(S.root, className)}>
16
17
  {icon && <div className={S.icon}>{icon}</div>}
17
18
  {title && <h2>{title}</h2>}
18
19
  {description && <p>{description}</p>}
@@ -7,6 +7,7 @@ export type ChatEmptyStateContext = {
7
7
  export interface ChatEmptyStateProps {
8
8
  icon?: React.ReactNode;
9
9
  title?: string;
10
+ className?: string;
10
11
  description?: string;
11
12
  /** Extra block below description (resolved before render in `ChatEmptyState`). */
12
13
  additionalContent?: React.ReactNode;
@@ -3,8 +3,8 @@
3
3
  .wrapper
4
4
  display flex
5
5
  align-items center
6
- gap var(--p-2)
7
- min-width 200px
6
+ gap var(--p-1)
7
+ min-width 160px
8
8
  z-index 1000
9
9
 
10
10
  .selectGrow
@@ -24,3 +24,19 @@
24
24
  .wrapper:hover .deleteBtn
25
25
  opacity 1
26
26
  pointer-events auto
27
+
28
+ // Variant styles
29
+ .variantClear .selectTrigger
30
+ border none
31
+ background-color transparent
32
+ box-shadow none
33
+
34
+ &:hover
35
+ box-shadow none
36
+ background-color transparent
37
+
38
+ .variantDefault .selectTrigger
39
+ background-color var(--background)
40
+
41
+ &:hover
42
+ box-shadow 0 0 0 2px var(--background)
@@ -4,6 +4,8 @@ interface CssExports {
4
4
  'deleteBtn': string;
5
5
  'selectGrow': string;
6
6
  'selectTrigger': string;
7
+ 'variantClear': string;
8
+ 'variantDefault': string;
7
9
  'wrapper': string;
8
10
  }
9
11
  export const cssExports: CssExports;
@@ -1,6 +1,10 @@
1
1
  import cn from 'classnames';
2
2
 
3
3
  import { Chat } from '#uilib/components/ui/Chat/Chat.types';
4
+ import type {
5
+ SelectProps,
6
+ SelectTriggerProps,
7
+ } from '#uilib/components/ui/Select/Select.types.js';
4
8
  import { useChatsForScopeId } from '#uilib/contexts/chat-context';
5
9
  import { Trash2Icon } from 'lucide-react';
6
10
 
@@ -14,7 +18,8 @@ import {
14
18
  } from '../../Select/Select';
15
19
  import S from './ChatSelector.styl';
16
20
 
17
- export interface ChatSelectorProps {
21
+ export interface ChatSelectorProps
22
+ extends SelectProps, Pick<SelectTriggerProps, 'size' | 'variant'> {
18
23
  id: string;
19
24
  wrapperClassName?: string;
20
25
  className?: string;
@@ -23,8 +28,13 @@ export interface ChatSelectorProps {
23
28
  onNewChat?: () => void;
24
29
  }
25
30
 
31
+ const deleteIconSize = (s: NonNullable<SelectTriggerProps['size']>) =>
32
+ s === 'sm' ? 16 : s === 'md' ? 18 : 20;
33
+
26
34
  export function ChatSelector({
27
35
  id,
36
+ size = 'sm',
37
+ variant = 'clear',
28
38
  wrapperClassName,
29
39
  className,
30
40
  onChatDeleted,
@@ -67,15 +77,22 @@ export function ChatSelector({
67
77
  };
68
78
 
69
79
  return (
70
- <div className={cn(S.wrapper, wrapperClassName)}>
80
+ <div
81
+ className={cn(
82
+ S.wrapper,
83
+ variant === 'clear' ? S.variantClear : S.variantDefault,
84
+ wrapperClassName,
85
+ )}
86
+ >
71
87
  <div className={S.selectGrow}>
72
88
  <Select
73
- variant="clear"
89
+ variant={variant}
74
90
  value={currentChatId?.toString() ?? ''}
75
91
  onValueChange={handleValueChange}
76
92
  >
77
93
  <SelectTrigger
78
- size="sm"
94
+ size={size}
95
+ variant={variant}
79
96
  className={
80
97
  className ? cn(S.selectTrigger, className) : S.selectTrigger
81
98
  }
@@ -100,12 +117,12 @@ export function ChatSelector({
100
117
  <Button
101
118
  type="button"
102
119
  variant="ghost"
103
- size="sm"
120
+ size={size}
104
121
  className={S.deleteBtn}
105
122
  aria-label="Delete chat"
106
123
  onClick={handleDeleteChat}
107
124
  >
108
- <Trash2Icon size={16} />
125
+ <Trash2Icon size={deleteIconSize(size)} />
109
126
  </Button>
110
127
  )}
111
128
  </div>
@@ -22,7 +22,7 @@ export interface ChatSheetProps extends Omit<
22
22
  title?: string;
23
23
  /** Imperative open / new-chat for triggers outside `renderTrigger` (e.g. sidebar). */
24
24
  actionsRef?: React.MutableRefObject<ChatSheetActions | null>;
25
- renderTrigger?: (toggleOpen: () => void) => React.ReactNode;
25
+ renderTrigger?: (toggleOpen: () => void, isOpen: boolean) => React.ReactNode;
26
26
  triggerLabel?: React.ReactNode;
27
27
  /** aria-label for icon-only trigger (required when trigger has no visible text) */
28
28
  triggerAriaLabel?: string;
@@ -88,7 +88,7 @@ export function ChatSheet({
88
88
 
89
89
  return (
90
90
  <>
91
- {renderTrigger?.(model.toggleOpen) ?? (
91
+ {renderTrigger?.(model.toggleOpen, model.isOpen) ?? (
92
92
  <Button
93
93
  variant="outline"
94
94
  aria-label={triggerAriaLabel}
@@ -46,15 +46,25 @@
46
46
  box-shadow 0 0 0 2px var(--background)
47
47
  // color var(--muted-foreground)
48
48
 
49
- &[data-size="md"]
50
- height 1.75rem
51
-
52
49
  &[data-size="sm"]
53
- height 1.75rem
50
+ height auto
51
+ min-height 28px
52
+ padding 0 var(--p-4)
53
+ border-radius var(--p-4)
54
54
  font-size var(--text-xs)
55
55
 
56
+ &[data-size="md"]
57
+ height auto
58
+ min-height 40px
59
+ padding var(--p-3) var(--p-4)
60
+ border-radius var(--p-4)
61
+ font-size var(--text-sm)
62
+
56
63
  &[data-size="lg"]
57
- height 2.25rem
64
+ height auto
65
+ min-height auto
66
+ padding var(--p-4) var(--p-6)
67
+ border-radius var(--p-4)
58
68
  font-size var(--text-sm)
59
69
 
60
70
  &[data-placeholder]
@@ -97,7 +107,6 @@
97
107
 
98
108
 
99
109
  .clear
100
- padding 0
101
110
  border none
102
111
  background-color transparent
103
112
  box-shadow none
@@ -11,7 +11,7 @@ Host provides:
11
11
  - Controlled `selectedDriver` + `setSelectedDriver`
12
12
  - `isLoading` while fetching drivers
13
13
 
14
- Report tile: `drivers_map` — tile resolves analysis id, fetches drivers, passes list + selection (see EmbeddedAnalysisSelector pattern).
14
+ Report tile: `drivers_map` — tile resolves analysis id, fetches drivers, passes list + selection.
15
15
 
16
16
  Requires: `drivers`; `isLoading`; `selectedDriver`; `setSelectedDriver`.
17
17
 
@@ -12,9 +12,9 @@ Host provides:
12
12
  - `seriesInitKey` when selected analysis changes
13
13
  - `viewTab` / `onViewTabChange`: `lagged` (calendar-aligned, raw dates) or `overlapped` (driver series shifted backward by parsed lag months)
14
14
 
15
- View tabs: host should render uilib `Tabs variant="button"` with **Lagged** / **Overlapped** in the toolbar (analysis selector left, tabs right). Chart applies `applyDriversComparisonViewToPayload` internally.
15
+ View tabs: host should render uilib `Tabs variant="button"` with **Lagged** / **Overlapped** in the toolbar. Chart applies `applyDriversComparisonViewToPayload` internally.
16
16
 
17
- Report tile: `drivers_comparison_chart` — host loads normalized backtests payload + dataset historical; built-in analysis selector.
17
+ Report tile: `drivers_comparison_chart` — host loads normalized backtests payload + dataset historical.
18
18
 
19
19
  Requires: `payload` — target + driver normalized_series; `loading` / `chartLoading` — spinners; `seriesInitKey` — reset visible series on analysis or view tab change; `runAnalysisHint` / `statusHint` — empty/error text.
20
20
 
@@ -8,10 +8,9 @@ Not when: simple forecast card or driver backtests — use ChartAreaInteractive
8
8
  Host provides:
9
9
 
10
10
  - `performanceData` (PerformanceChartPayload) and `historicalData` from performance API
11
- - Analysis selection and fetch outside widget
12
11
  - Optional `forecastData`, `customPerformanceMatrix`, `userSeries` for spaghetti
13
12
 
14
- Report tile: `performance_chart` — host loads performance payload + dataset series; built-in analysis selector.
13
+ Report tile: `performance_chart` — host loads performance payload + dataset series.
15
14
 
16
15
  Requires: `performanceData` — model/drift forecasts and metrics; `historicalData` — baseline series; `loading` / `chartLoading` / `performanceDataLoading` — spinners; `runAnalysisHint` / `statusHint` — empty states.
17
16
 
@@ -1,5 +1,3 @@
1
- import { useState } from 'react';
2
-
3
1
  import { PageContentSection } from '#uilib/components/ui/Page';
4
2
  import {
5
3
  Select,
@@ -12,28 +10,87 @@ import {
12
10
  import { AppPageHeader } from '../components/AppPageHeader/AppPageHeader';
13
11
  import { DocsHeaderActions } from '../docsHeaderActions';
14
12
 
15
- export default function SelectPage() {
16
- const [v, setV] = useState('apple');
13
+ const VARIANTS = ['default', 'clear'] as const;
14
+ const SIZES = ['sm', 'md', 'lg'] as const;
15
+
16
+ const FRUIT_OPTIONS = [
17
+ { value: 'apple', label: 'Apple' },
18
+ { value: 'orange', label: 'Orange' },
19
+ { value: 'banana', label: 'Banana' },
20
+ ] as const;
21
+
22
+ function DemoSelect({
23
+ variant,
24
+ size,
25
+ }: {
26
+ variant: (typeof VARIANTS)[number];
27
+ size: (typeof SIZES)[number];
28
+ }) {
29
+ return (
30
+ <Select defaultValue="apple">
31
+ <SelectTrigger variant={variant} size={size} style={{ width: 200 }}>
32
+ <SelectValue placeholder="Pick fruit" />
33
+ </SelectTrigger>
34
+ <SelectContent>
35
+ {FRUIT_OPTIONS.map(o => (
36
+ <SelectItem key={o.value} value={o.value}>
37
+ {o.label}
38
+ </SelectItem>
39
+ ))}
40
+ </SelectContent>
41
+ </Select>
42
+ );
43
+ }
17
44
 
45
+ export default function SelectPage() {
18
46
  return (
19
47
  <>
20
48
  <AppPageHeader
21
49
  breadcrumbs={[{ label: 'Select' }]}
22
50
  title="Select"
23
- subheader="Radix select."
51
+ subheader="Radix select — variants and sizes."
24
52
  actions={<DocsHeaderActions />}
25
53
  />
26
- <PageContentSection>
27
- <Select value={v} onValueChange={setV}>
28
- <SelectTrigger style={{ width: 200 }}>
29
- <SelectValue placeholder="Pick fruit" />
30
- </SelectTrigger>
31
- <SelectContent>
32
- <SelectItem value="apple">Apple</SelectItem>
33
- <SelectItem value="orange">Orange</SelectItem>
34
- <SelectItem value="banana">Banana</SelectItem>
35
- </SelectContent>
36
- </Select>
54
+ <PageContentSection
55
+ style={{ display: 'flex', flexDirection: 'column', gap: '2rem' }}
56
+ >
57
+ <section>
58
+ <h3 style={{ marginBottom: '1rem' }}>Variants × sizes</h3>
59
+ <div style={{ overflowX: 'auto' }}>
60
+ <table style={{ borderCollapse: 'collapse', width: '100%' }}>
61
+ <thead>
62
+ <tr>
63
+ <th style={{ textAlign: 'left', padding: '0.5rem' }} />
64
+ {SIZES.map(s => (
65
+ <th key={s} style={{ padding: '0.5rem' }}>
66
+ {s}
67
+ </th>
68
+ ))}
69
+ </tr>
70
+ </thead>
71
+ <tbody>
72
+ {VARIANTS.map(v => (
73
+ <tr key={v}>
74
+ <td
75
+ style={{
76
+ padding: '0.5rem',
77
+ fontWeight: 600,
78
+ whiteSpace: 'nowrap',
79
+ }}
80
+ >
81
+ {v}
82
+ </td>
83
+ {SIZES.map(s => (
84
+ <td key={s} style={{ padding: '0.5rem' }}>
85
+ <DemoSelect variant={v} size={s} />
86
+ </td>
87
+ ))}
88
+ </tr>
89
+ ))}
90
+ </tbody>
91
+ </table>
92
+ </div>
93
+ </section>
37
94
  </PageContentSection>
38
95
  </>
39
96
  );