Skip to content

Commit 0ecf8a3

Browse files
committed
Ui fixes
1 parent 8c269d4 commit 0ecf8a3

5 files changed

Lines changed: 678 additions & 114 deletions

File tree

streamlit_pivot/frontend/src/config/DndFieldChip.tsx

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,3 +200,115 @@ export const DragOverlayChip: FC<FieldChipProps> = (props): ReactElement => {
200200
</span>
201201
);
202202
};
203+
204+
// ---------------------------------------------------------------------------
205+
// Synthetic (fx) measure chip — sortable within the Values zone.
206+
// ---------------------------------------------------------------------------
207+
208+
export interface SyntheticChipDisplayProps {
209+
syntheticId: string;
210+
label: string;
211+
testId: string;
212+
disabled?: boolean;
213+
onRemove?: (syntheticId: string) => void;
214+
showDragHandle?: boolean;
215+
}
216+
217+
function SyntheticChipContent({
218+
syntheticId,
219+
label,
220+
testId,
221+
disabled,
222+
onRemove,
223+
showDragHandle,
224+
}: SyntheticChipDisplayProps): ReactElement {
225+
return (
226+
<>
227+
{showDragHandle && <GripDotsIcon />}
228+
<span className={styles.aggChipIcon}>fx</span>
229+
<span
230+
className={styles.chipLabelText}
231+
data-testid={`${testId}-synthetic-label-${syntheticId}`}
232+
>
233+
<span className={styles.chipPrimaryText}>{label}</span>
234+
</span>
235+
{!disabled && onRemove && (
236+
<button
237+
type="button"
238+
className={styles.chipRemove}
239+
onMouseDown={(e) => e.stopPropagation()}
240+
onClick={(e) => {
241+
e.stopPropagation();
242+
onRemove(syntheticId);
243+
}}
244+
aria-label={`Remove ${label}`}
245+
data-testid={`${testId}-synthetic-remove-${syntheticId}`}
246+
>
247+
×
248+
</button>
249+
)}
250+
</>
251+
);
252+
}
253+
254+
export interface SortableSyntheticChipProps extends SyntheticChipDisplayProps {
255+
id: string;
256+
}
257+
258+
export const SortableSyntheticChip: FC<SortableSyntheticChipProps> = ({
259+
id,
260+
syntheticId,
261+
label,
262+
testId,
263+
disabled,
264+
onRemove,
265+
}): ReactElement => {
266+
const {
267+
attributes,
268+
listeners,
269+
setNodeRef,
270+
transform,
271+
transition,
272+
isDragging,
273+
} = useSortable({
274+
id,
275+
disabled,
276+
data: { type: "synthetic", syntheticId },
277+
});
278+
279+
const style: CSSProperties = {
280+
transform: CSS.Transform.toString(transform),
281+
transition,
282+
opacity: isDragging ? 0.3 : undefined,
283+
};
284+
285+
return (
286+
<span
287+
ref={setNodeRef}
288+
className={`${styles.chip} ${isDragging ? styles.chipDragging : ""}`}
289+
style={style}
290+
{...attributes}
291+
{...(disabled ? {} : listeners)}
292+
data-testid={`${testId}-synthetic-${syntheticId}`}
293+
>
294+
<SyntheticChipContent
295+
syntheticId={syntheticId}
296+
label={label}
297+
testId={testId}
298+
disabled={disabled}
299+
onRemove={onRemove}
300+
showDragHandle={!disabled}
301+
/>
302+
</span>
303+
);
304+
};
305+
306+
export const SyntheticDragOverlayChip: FC<SyntheticChipDisplayProps> = (
307+
props,
308+
): ReactElement => {
309+
return (
310+
<span className={`${styles.chip} ${styles.chipOverlay}`}>
311+
<SyntheticChipContent {...props} showDragHandle={true} />
312+
</span>
313+
);
314+
};

streamlit_pivot/frontend/src/config/SettingsPanel.module.css

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@
128128
box-sizing: border-box;
129129
max-height: 70px;
130130
overflow-y: auto;
131+
flex-shrink: 0;
131132
}
132133

133134
.availableChip {
@@ -232,6 +233,7 @@
232233
overflow-y: auto;
233234
scrollbar-gutter: stable;
234235
transition: border-color 0.15s, background 0.15s;
236+
flex-shrink: 0;
235237
}
236238

237239
.zoneAreaActive {
@@ -510,14 +512,23 @@
510512
align-items: center;
511513
gap: 3px;
512514
flex-shrink: 0;
513-
padding: 2px 6px;
515+
padding: 3px 7px 3px 9px;
516+
height: 24px;
517+
box-sizing: border-box;
514518
border: 1px solid color-mix(in srgb, var(--st-primary-color) 30%, transparent);
515519
border-radius: 12px;
516520
background: color-mix(in srgb, var(--st-primary-color) 5%, transparent);
517521
color: var(--st-text-color);
518522
font-family: var(--st-font);
519523
font-size: 0.75em;
520524
white-space: nowrap;
525+
position: relative;
526+
user-select: none;
527+
cursor: grab;
528+
}
529+
530+
.syntheticChip:active {
531+
cursor: grabbing;
521532
}
522533

523534
.syntheticIcon {
@@ -559,6 +570,7 @@
559570
display: flex;
560571
flex-direction: column;
561572
gap: 6px;
573+
flex-shrink: 0;
562574
}
563575

564576
.builderField {

0 commit comments

Comments
 (0)