@mirror-physics/fractal-ui 0.2.0-next.78 → 0.2.0-next.80
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/README.md +30 -1
- package/dist/{chunk-QZX655IA.js → chunk-UNMOINWV.js} +12 -17
- package/dist/chunk-UNMOINWV.js.map +1 -0
- package/dist/column-editor.cjs +11 -16
- package/dist/column-editor.cjs.map +1 -1
- package/dist/column-editor.css.map +1 -1
- package/dist/column-editor.js +1 -1
- package/dist/index.cjs +160 -87
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +164 -14
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +20 -5
- package/dist/index.d.ts +20 -5
- package/dist/index.js +252 -174
- package/dist/index.js.map +1 -1
- package/dist/tokens.css +9 -5
- package/package.json +2 -2
- package/dist/chunk-QZX655IA.js.map +0 -1
package/README.md
CHANGED
|
@@ -46,7 +46,7 @@ npm run build
|
|
|
46
46
|
|
|
47
47
|
### Shared control sizes
|
|
48
48
|
|
|
49
|
-
Use `controlSize="
|
|
49
|
+
Use `controlSize="sm" | "md" | "lg" | "xl"` on Button, Dropdown, Input, NumberInput, TableSearch, PasswordInput, and Label. The default is `lg`. `xs` is no longer supported; migrate existing `xs` controls to `sm`. Matching sizes share typography and padding; their block size derives from the line box, padding, and borders. Existing `Button.buttonSize` and `Dropdown.size` remain aliases; `controlSize` wins if both are supplied. Native numeric `Input.size` retains its HTML meaning.
|
|
50
50
|
|
|
51
51
|
Compose a persistent label and control in `className="fractal-field"` to use the shared label gap. For dropdowns, connect `Label.htmlFor` to `Dropdown.triggerId` and provide a meaningful `triggerLabel`. Use matching sizes across a row. Icons add a shared leading slot; centered action labels remain centered.
|
|
52
52
|
|
|
@@ -82,3 +82,32 @@ No size prop is needed. If more room is required, override the token once on the
|
|
|
82
82
|
### Dropdown placement and scrolling
|
|
83
83
|
|
|
84
84
|
Dropdown menus default to a 320px maximum height and scroll internally. Set `maxHeight` (pixels) to change the cap. Available space can reduce the height further. `direction` and `align` express preferred placement; the menu flips and shifts within the viewport and ancestor scroll containers, with an 8px inset configurable through `collisionPadding`. Placement updates while scrolling or resizing, and long option text wraps to fit narrow viewports. Use Arrow keys, Home/End, and Escape to navigate or dismiss an open menu.
|
|
85
|
+
|
|
86
|
+
### Floating field titles
|
|
87
|
+
|
|
88
|
+
Use `fieldLabel="Company"` on Input, NumberInput, PasswordInput, TableSearch, Textarea, or Dropdown. The title occupies the empty field until focus, then floats into the border; filled inactive titles use `fg-secondary`, and active titles use `fg-primary`. `placeholder` stays a separate entry hint. Labels are associated with the underlying control and IDs are generated when omitted. Existing `controlSize` heights are unchanged, and reduced motion disables the transition. Textarea retains its multiline height. Native date/time and other controls that display their own empty UI keep the title floated to avoid overlap.
|
|
89
|
+
|
|
90
|
+
For Dropdown, `selectedValue=""` is the empty state; keep the existing `label` prop for menu section headings. Supply `fieldLabel` for the trigger title. Existing externally labeled and icon-only usages remain supported. Stories under **Input / Floating Labels** cover states, variants, and all five control sizes.
|
|
91
|
+
|
|
92
|
+
Use `Dropdown multiple selectedValues={values} onSelectionChange={setValues}` for checkbox-style multiselect menus. Add `searchable` for a labeled search field; `searchPlaceholder` and `emptyMessage` customize its text. Options stay open while toggling. Header items group options and participate in search. Arrow keys navigate options, Space/Enter toggle, and Escape closes and restores trigger focus.
|
|
93
|
+
|
|
94
|
+
Search fields are exempt from floating titles: use the search icon and placeholder. `Input type="search"` and `TableSearch` keep `fieldLabel` as an accessible name only; explicit ARIA naming takes precedence.
|
|
95
|
+
|
|
96
|
+
### Primary button theme
|
|
97
|
+
|
|
98
|
+
Primary text and icon-only buttons inherit the same neutral theme by default.
|
|
99
|
+
Set these custom properties on your app root (or any subtree) to theme both:
|
|
100
|
+
|
|
101
|
+
```css
|
|
102
|
+
.axon {
|
|
103
|
+
--button-primary-bg: var(--blue-600);
|
|
104
|
+
--button-primary-hover: var(--blue-500);
|
|
105
|
+
--button-primary-active: var(--blue-700);
|
|
106
|
+
--button-primary-fg: var(--grey-0);
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
A user preference can update these properties at runtime without remounting
|
|
111
|
+
components. Supply a contrasting foreground (at least 4.5:1 against every
|
|
112
|
+
state). An explicit `color="pink"` preset takes precedence over the inherited
|
|
113
|
+
theme. Disabled and danger styles remain independent.
|
|
@@ -46,9 +46,9 @@ var colorPalette = {
|
|
|
46
46
|
}
|
|
47
47
|
};
|
|
48
48
|
function getButtonStyles(buttonType, isHovered, isActive, disabled, color, hasIconOnly) {
|
|
49
|
-
const palette = colorPalette[color];
|
|
49
|
+
const palette = color ? colorPalette[color] : void 0;
|
|
50
50
|
const base = {
|
|
51
|
-
borderRadius:
|
|
51
|
+
borderRadius: "var(--radius-sm, 4px)",
|
|
52
52
|
cursor: disabled ? "not-allowed" : "pointer",
|
|
53
53
|
transition: "background-color 0.15s ease, border-color 0.15s ease, opacity 0.15s ease"
|
|
54
54
|
};
|
|
@@ -62,22 +62,17 @@ function getButtonStyles(buttonType, isHovered, isActive, disabled, color, hasIc
|
|
|
62
62
|
return { ...base, backgroundColor: "transparent", border: "1px solid var(--fg-disabled)", color: "var(--fg-disabled)" };
|
|
63
63
|
}
|
|
64
64
|
switch (buttonType) {
|
|
65
|
-
//
|
|
65
|
+
// Text and icon-only primary actions inherit the same scoped theme.
|
|
66
66
|
case "primary":
|
|
67
|
-
if (hasIconOnly) {
|
|
68
|
-
return {
|
|
69
|
-
...base,
|
|
70
|
-
backgroundColor: isActive ? palette[700] : isHovered ? palette[500] : palette[600],
|
|
71
|
-
border: "1px solid transparent",
|
|
72
|
-
color: "var(--fg-inverse)"
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
67
|
return {
|
|
76
68
|
...base,
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
69
|
+
border: "1px solid transparent",
|
|
70
|
+
...palette ? {
|
|
71
|
+
"--button-primary-bg": palette[600],
|
|
72
|
+
"--button-primary-hover": palette[500],
|
|
73
|
+
"--button-primary-active": palette[700],
|
|
74
|
+
"--button-primary-fg": "var(--grey-0)"
|
|
75
|
+
} : {}
|
|
81
76
|
};
|
|
82
77
|
// Secondary: neutral. Rest=canvas, hover=surface-1 (darken), pressed=surface-2. Subtle border, dark text.
|
|
83
78
|
case "secondary":
|
|
@@ -108,7 +103,7 @@ function getButtonStyles(buttonType, isHovered, isActive, disabled, color, hasIc
|
|
|
108
103
|
}
|
|
109
104
|
}
|
|
110
105
|
var Button = React.forwardRef(
|
|
111
|
-
({ className, buttonType = "primary", buttonSize = "
|
|
106
|
+
({ className, buttonType = "primary", buttonSize = "lg", controlSize, color, icon, hasIconOnly, iconPosition = "left", style, disabled, children, ...props }, ref) => {
|
|
112
107
|
const [isHovered, setIsHovered] = React.useState(false);
|
|
113
108
|
const [isActive, setIsActive] = React.useState(false);
|
|
114
109
|
const typeStyles = getButtonStyles(buttonType, isHovered, isActive, !!disabled, color, hasIconOnly);
|
|
@@ -341,4 +336,4 @@ export {
|
|
|
341
336
|
Button,
|
|
342
337
|
ColumnEditor
|
|
343
338
|
};
|
|
344
|
-
//# sourceMappingURL=chunk-
|
|
339
|
+
//# sourceMappingURL=chunk-UNMOINWV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/cn.ts","../src/components/Button/Button.tsx","../src/components/ColumnEditor/ColumnEditor.tsx"],"sourcesContent":["import { clsx, type ClassValue } from 'clsx'\n\nexport function cn(...inputs: ClassValue[]) {\n return clsx(inputs)\n}\n","import * as React from 'react'\nimport { cn } from '../../utils/cn'\nimport type { ControlSize } from '../../utils/control-size'\nimport '../../styles/control.css'\nimport './Button.css'\n\nexport type ButtonType = 'primary' | 'secondary' | 'ghost' | 'danger'\nexport type ButtonSize = ControlSize\nexport type ButtonColor = 'blue' | 'pink' | 'orange' | 'green'\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Visual hierarchy. Primary = strongest action, Secondary = neutral bordered, Ghost = minimal, Danger = destructive. */\n buttonType?: ButtonType\n /** Shared visual density; takes precedence over the buttonSize alias. */\n controlSize?: ControlSize\n /** Backward-compatible alias for controlSize. */\n buttonSize?: ButtonSize\n /** Explicit primary color preset. Omit to inherit the application's primary tokens. */\n color?: ButtonColor\n /** Icon element. */\n icon?: React.ReactNode\n /** Whether the button displays only an icon (no text). Must include aria-label. */\n hasIconOnly?: boolean\n /** Position of the icon relative to the label. */\n iconPosition?: 'left' | 'right'\n}\n\n/*\n * Color palette mapping per the color guide's semantic stop roles:\n * 0 = bg (non-interactive reading surfaces)\n * 50 = surface (tertiary button fill — interactive)\n * 100 = surface-hover (tertiary button hover — darken)\n * 200 = surface-stroke (tertiary pressed, borders)\n * 500 = md-stroke (strong chromatic hover — lighten from 600)\n * 600 = strong (strong chromatic fill — rest)\n * 700 = strong-pressed (strong chromatic pressed — darken)\n */\nconst colorPalette = {\n blue: {\n 0: 'var(--blue-0)',\n 50: 'var(--blue-50)',\n 100: 'var(--blue-100)',\n 200: 'var(--blue-200)',\n 500: 'var(--blue-500)',\n 600: 'var(--blue-600)',\n 700: 'var(--blue-700)',\n },\n pink: {\n 0: 'var(--pink-0)',\n 50: 'var(--pink-50)',\n 100: 'var(--pink-100)',\n 200: 'var(--pink-200)',\n 500: 'var(--pink-500)',\n 600: 'var(--pink-600)',\n 700: 'var(--pink-700)',\n },\n orange: {\n 0: 'var(--orange-0)',\n 50: 'var(--orange-50)',\n 100: 'var(--orange-100)',\n 200: 'var(--orange-200)',\n 500: 'var(--orange-500)',\n 600: 'var(--orange-600)',\n 700: 'var(--orange-700)',\n },\n green: {\n 0: 'var(--green-0)',\n 50: 'var(--green-50)',\n 100: 'var(--green-100)',\n 200: 'var(--green-200)',\n 500: 'var(--green-500)',\n 600: 'var(--green-600)',\n 700: 'var(--green-700)',\n },\n}\n\nfunction getButtonStyles(\n buttonType: ButtonType,\n isHovered: boolean,\n isActive: boolean,\n disabled: boolean,\n color: ButtonColor | undefined,\n hasIconOnly: boolean | undefined,\n): React.CSSProperties {\n const palette = color ? colorPalette[color] : undefined\n\n const base: React.CSSProperties = {\n borderRadius: 'var(--radius-sm, 4px)',\n cursor: disabled ? 'not-allowed' : 'pointer',\n transition: 'background-color 0.15s ease, border-color 0.15s ease, opacity 0.15s ease',\n }\n\n if (hasIconOnly) {\n base.justifyContent = 'center'\n }\n\n // Disabled: bordered buttons get transparent bg + disabled border + disabled text.\n // Others just get opacity: 0.5 (handled by CSS).\n // Per principles.md Interaction States > Disabled\n if (disabled) {\n if (buttonType === 'ghost') {\n return { ...base, backgroundColor: 'transparent', border: '1px solid transparent', color: 'var(--fg-disabled)' }\n }\n return { ...base, backgroundColor: 'transparent', border: '1px solid var(--fg-disabled)', color: 'var(--fg-disabled)' }\n }\n\n switch (buttonType) {\n // Text and icon-only primary actions inherit the same scoped theme.\n case 'primary':\n return {\n ...base,\n border: '1px solid transparent',\n ...(palette ? {\n '--button-primary-bg': palette[600],\n '--button-primary-hover': palette[500],\n '--button-primary-active': palette[700],\n '--button-primary-fg': 'var(--grey-0)',\n } : {}),\n } as React.CSSProperties\n\n // Secondary: neutral. Rest=canvas, hover=surface-1 (darken), pressed=surface-2. Subtle border, dark text.\n case 'secondary':\n return {\n ...base,\n backgroundColor: isActive ? 'var(--bg-surface-2)' : isHovered ? 'var(--bg-surface-1)' : 'var(--bg-canvas)',\n border: '1px solid var(--border-subtle)',\n color: 'var(--fg-primary)',\n }\n\n // Ghost: no border. Rest=transparent, hover/press=surface-1.\n case 'ghost':\n return {\n ...base,\n backgroundColor: isHovered || isActive ? 'var(--bg-surface-1)' : 'transparent',\n border: '1px solid transparent',\n color: 'var(--fg-primary)',\n }\n\n // Danger: low-intensity destructive action. Text stays steady; hover deepens the light red surface.\n case 'danger':\n return {\n ...base,\n backgroundColor: isHovered || isActive ? 'var(--danger-button-surface-hover)' : 'var(--danger-button-surface)',\n border: '1px solid transparent',\n color: 'var(--danger-button-fg)',\n }\n\n default:\n return base\n }\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, buttonType = 'primary', buttonSize = 'lg', controlSize, color, icon, hasIconOnly, iconPosition = 'left', style, disabled, children, ...props }, ref) => {\n const [isHovered, setIsHovered] = React.useState(false)\n const [isActive, setIsActive] = React.useState(false)\n\n const typeStyles = getButtonStyles(buttonType, isHovered, isActive, !!disabled, color, hasIconOnly)\n const hasIconAndText = icon && children && !hasIconOnly\n const finalStyles = hasIconAndText\n ? { ...typeStyles, gap: 'var(--space-2, 8px)', ...style }\n : { ...typeStyles, ...style }\n\n return (\n <button\n ref={ref}\n type=\"button\"\n data-control-size={controlSize ?? buttonSize}\n data-icon-only={hasIconOnly || undefined}\n className={cn('fractal-control', 'fractal-button', `fractal-button--${buttonType}`, className)}\n style={finalStyles}\n disabled={disabled}\n onMouseEnter={(e) => { setIsHovered(true); props.onMouseEnter?.(e) }}\n onMouseLeave={(e) => { setIsHovered(false); setIsActive(false); props.onMouseLeave?.(e) }}\n onMouseDown={(e) => { setIsActive(true); props.onMouseDown?.(e) }}\n onMouseUp={(e) => { setIsActive(false); props.onMouseUp?.(e) }}\n {...props}\n >\n {iconPosition !== 'right' && icon}\n {!hasIconOnly && children}\n {iconPosition === 'right' && icon}\n </button>\n )\n }\n)\nButton.displayName = 'Button'\n\nexport { Button }\n","import * as React from 'react'\nimport { ArrowUp, ArrowDown, DotsSixVertical, Eye, EyeSlash, Gear } from '@mirror-physics/fractal-icons'\nimport { Button } from '../Button'\nimport { cn } from '../../utils/cn'\nimport './ColumnEditor.css'\n\nexport interface ColumnEditorItem { id: string; label: string; required?: boolean }\nexport interface ColumnEditorProps {\n items: ColumnEditorItem[]\n /** Visible column IDs in display order. Required items cannot be hidden. */\n value: string[]\n onChange: (value: string[]) => void\n label?: string\n hiddenLabel?: string\n className?: string\n}\ninterface DragState {\n id: string; pointerId: number; x: number; y: number; active: boolean\n visible: string[]; hidden: string[]\n}\nconst equal = (a: string[], b: string[]) => a.length === b.length && a.every((id, index) => id === b[index])\n\n/** Reorderable visible/hidden columns, with pointer preview and keyboard actions. */\nexport function ColumnEditor({ items, value, onChange, label = 'Edit columns', hiddenLabel = 'Hidden columns', className }: ColumnEditorProps) {\n const [open, setOpen] = React.useState(false)\n const [preview, setPreview] = React.useState<{ visible: string[]; hidden: string[]; active: string } | null>(null)\n const [announcement, setAnnouncement] = React.useState('')\n const root = React.useRef<HTMLDivElement>(null)\n const trigger = React.useRef<HTMLButtonElement>(null)\n const panel = React.useRef<HTMLDivElement>(null)\n const drag = React.useRef<DragState | null>(null)\n const positions = React.useRef<Map<string, DOMRect> | null>(null)\n const id = React.useId()\n function capturePositions() {\n positions.current = new Map(Array.from(panel.current?.querySelectorAll<HTMLElement>('[data-column-editor-item]') ?? []).map(row => [row.dataset.columnEditorItem!, row.getBoundingClientRect()]))\n }\n // FLIP from each row's current visual position, including interrupted animations.\n React.useLayoutEffect(() => {\n const before = positions.current\n positions.current = null\n if (!before || !panel.current || window.matchMedia('(prefers-reduced-motion: reduce)').matches) return\n const styles = getComputedStyle(panel.current)\n const token = styles.getPropertyValue('--duration-normal').trim()\n const duration = parseFloat(token) * (token.endsWith('ms') ? 1 : 1000)\n const easing = styles.getPropertyValue('--ease-out').trim()\n for (const row of panel.current.querySelectorAll<HTMLElement>('[data-column-editor-item]')) {\n const previous = before.get(row.dataset.columnEditorItem!)\n row.getAnimations().filter(animation => animation.id === 'fractal-column-position').forEach(animation => animation.cancel())\n if (!previous) continue\n const next = row.getBoundingClientRect()\n const x = previous.left - next.left, y = previous.top - next.top\n if (Math.abs(x) < 1 && Math.abs(y) < 1) continue\n row.animate([{ transform: `translate(${x}px, ${y}px)` }, { transform: 'translate(0, 0)' }], { duration, easing, id: 'fractal-column-position' })\n }\n })\n const valid = [...new Set(value)].filter(key => items.some(item => item.id === key))\n const committed = [...valid, ...items.filter(item => item.required && !valid.includes(item.id)).map(item => item.id)]\n const visible = preview?.visible ?? committed\n const hidden = preview?.hidden ?? items.filter(item => !committed.includes(item.id)).map(item => item.id)\n\n function cancel() { capturePositions(); drag.current = null; setPreview(null) }\n React.useEffect(() => {\n if (!open) return\n panel.current?.focus()\n function outside(event: PointerEvent) { if (!drag.current && !root.current?.contains(event.target as Node)) setOpen(false) }\n function escape(event: KeyboardEvent) {\n if (event.key !== 'Escape') return\n event.preventDefault()\n if (drag.current) { capturePositions(); drag.current = null; setPreview(null); setAnnouncement('Reordering cancelled') }\n else { setOpen(false); trigger.current?.focus() }\n }\n function blur(event: FocusEvent) { if (event.relatedTarget instanceof Node && !root.current?.contains(event.relatedTarget)) setOpen(false) }\n const element = root.current\n document.addEventListener('pointerdown', outside); document.addEventListener('keydown', escape); element?.addEventListener('focusout', blur)\n return () => { document.removeEventListener('pointerdown', outside); document.removeEventListener('keydown', escape); element?.removeEventListener('focusout', blur) }\n }, [open])\n\n function commit(next: string[], message: string) { capturePositions(); onChange(next); setAnnouncement(message) }\n function move(key: string, offset: number) {\n const index = committed.indexOf(key)\n const next = committed.filter(item => item !== key)\n if (offset > 0 && index === committed.length - 1 && !items.find(item => item.id === key)?.required) {\n commit(next, `${items.find(item => item.id === key)?.label} hidden`); return\n }\n next.splice(Math.max(0, Math.min(next.length, index + offset)), 0, key)\n commit(next, `${items.find(item => item.id === key)?.label} moved ${offset < 0 ? 'up' : 'down'}`)\n }\n function start(event: React.PointerEvent<HTMLLIElement>, key: string) {\n if (event.button !== 0 || (event.target as Element).closest('button')) return\n drag.current = { id: key, pointerId: event.pointerId, x: event.clientX, y: event.clientY, active: false, visible: [...committed], hidden: [...hidden] }\n panel.current?.setPointerCapture(event.pointerId)\n event.preventDefault()\n }\n function update(event: React.PointerEvent<HTMLDivElement>) {\n const current = drag.current\n if (!current || event.pointerId !== current.pointerId) return\n if (!current.active && Math.hypot(event.clientX - current.x, event.clientY - current.y) < 4) return\n current.active = true\n const container = panel.current\n if (!container) return\n const bounds = container.getBoundingClientRect()\n const hiddenGroup = container.querySelector<HTMLElement>('[data-column-editor-group=\"hidden\"]')!\n const inside = event.clientX >= bounds.left && event.clientX <= bounds.right && event.clientY >= bounds.top && event.clientY <= bounds.bottom\n if (!inside) return\n const destination = event.clientY >= hiddenGroup.getBoundingClientRect().top ? 'hidden' : 'visible'\n if (destination === 'hidden' && items.find(item => item.id === current.id)?.required) return\n // Hit-test layout slots, not animated row positions, so moving rows cannot flicker back and forth.\n const slots = Array.from(container.querySelectorAll<HTMLElement>(`[data-column-editor-group=\"${destination}\"] [data-column-editor-item]`))\n const localY = event.clientY - bounds.top + container.scrollTop - container.clientTop\n const ownSlot = slots.find(row => row.dataset.columnEditorItem === current.id)\n if (ownSlot && localY >= ownSlot.offsetTop && localY <= ownSlot.offsetTop + ownSlot.offsetHeight) return\n const nextVisible = current.visible.filter(key => key !== current.id)\n let nextHidden = current.hidden.filter(key => key !== current.id)\n if (destination === 'visible') {\n const index = slots.filter(row => row.dataset.columnEditorItem !== current.id && localY > row.offsetTop + row.offsetHeight / 2).length\n nextVisible.splice(index, 0, current.id)\n } else {\n nextHidden.push(current.id)\n nextHidden = items.filter(item => nextHidden.includes(item.id)).map(item => item.id)\n }\n if (!equal(nextVisible, current.visible) || !equal(nextHidden, current.hidden)) {\n capturePositions()\n current.visible = nextVisible; current.hidden = nextHidden\n }\n setPreview({ visible: current.visible, hidden: current.hidden, active: current.id })\n // Scroll the popover when dragging near its visible edges.\n if (event.clientY < bounds.top + 32) container.scrollTop -= 12\n else if (event.clientY > bounds.bottom - 32) container.scrollTop += 12\n }\n function finish(event: React.PointerEvent<HTMLDivElement>) {\n const current = drag.current\n if (!current || current.pointerId !== event.pointerId) return\n const hit = document.elementFromPoint(event.clientX, event.clientY)\n if (current.active && hit && panel.current?.contains(hit)) commit(current.visible, 'Column order updated')\n cancel()\n if (panel.current?.hasPointerCapture(event.pointerId)) panel.current.releasePointerCapture(event.pointerId)\n }\n function row(key: string, isHidden: boolean, index: number) {\n const item = items.find(item => item.id === key)!\n return <li key={key} className=\"fractal-column-editor__row\" data-column-editor-item={key} data-hidden={isHidden || undefined} data-dragging={preview?.active === key || undefined}\n onPointerDown={event => start(event, key)}>\n <DotsSixVertical className=\"fractal-column-editor__grip\" aria-hidden=\"true\" />\n <span className=\"fractal-column-editor__name\">{item.label}</span>\n <div className=\"fractal-column-editor__actions\" onPointerDown={event => event.stopPropagation()}>\n {isHidden ? <Button buttonType=\"ghost\" controlSize=\"sm\" hasIconOnly icon={<Eye aria-hidden=\"true\" />} aria-label={`Show ${item.label} column`} onClick={() => commit([...committed, key], `${item.label} shown`)} /> : <>\n <Button buttonType=\"ghost\" controlSize=\"sm\" hasIconOnly icon={<ArrowUp aria-hidden=\"true\" />} aria-label={`Move ${item.label} up`} disabled={index === 0} onClick={() => move(key, -1)} />\n <Button buttonType=\"ghost\" controlSize=\"sm\" hasIconOnly icon={index === visible.length - 1 && !item.required ? <EyeSlash aria-hidden=\"true\" /> : <ArrowDown aria-hidden=\"true\" />} aria-label={index === visible.length - 1 && !item.required ? `Hide ${item.label} column` : `Move ${item.label} down`} disabled={index === visible.length - 1 && item.required} onClick={() => move(key, 1)} />\n </>}\n </div>\n </li>\n }\n return <div className={cn('fractal-column-editor', className)} ref={root}>\n <Button ref={trigger} controlSize=\"lg\" buttonType=\"secondary\" icon={<Gear aria-hidden=\"true\" />} iconPosition=\"right\" aria-haspopup=\"dialog\" aria-expanded={open} aria-controls={id} onClick={() => { cancel(); setOpen(current => !current) }}>{label}</Button>\n {open ? <div id={id} className=\"fractal-column-editor__panel\" ref={panel} role=\"dialog\" data-dragging={Boolean(preview) || undefined} aria-label={label} tabIndex={-1} onPointerMove={update} onPointerUp={finish} onPointerCancel={cancel} onLostPointerCapture={cancel}>\n <ol className=\"fractal-column-editor__list\" data-column-editor-group=\"visible\" aria-label=\"Visible columns\">{visible.map((key, index) => row(key, false, index))}</ol>\n <section data-column-editor-group=\"hidden\" className=\"fractal-column-editor__hidden\" aria-label={hiddenLabel}>\n <div className=\"fractal-column-editor__divider\"><span>{hiddenLabel}<EyeSlash aria-hidden=\"true\" /></span></div>\n <ol className=\"fractal-column-editor__list\">{hidden.map((key, index) => row(key, true, index))}</ol>\n {!hidden.length ? <p className=\"fractal-column-editor__empty\">Drag columns here to hide them.</p> : null}\n </section>\n <span className=\"fractal-column-editor__announcement\" role=\"status\" aria-live=\"polite\">{announcement}</span>\n </div> : null}\n </div>\n}\n"],"mappings":"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","names":["React","jsxs","row","item"]}
|
package/dist/column-editor.cjs
CHANGED
|
@@ -88,9 +88,9 @@ var colorPalette = {
|
|
|
88
88
|
}
|
|
89
89
|
};
|
|
90
90
|
function getButtonStyles(buttonType, isHovered, isActive, disabled, color, hasIconOnly) {
|
|
91
|
-
const palette = colorPalette[color];
|
|
91
|
+
const palette = color ? colorPalette[color] : void 0;
|
|
92
92
|
const base = {
|
|
93
|
-
borderRadius:
|
|
93
|
+
borderRadius: "var(--radius-sm, 4px)",
|
|
94
94
|
cursor: disabled ? "not-allowed" : "pointer",
|
|
95
95
|
transition: "background-color 0.15s ease, border-color 0.15s ease, opacity 0.15s ease"
|
|
96
96
|
};
|
|
@@ -104,22 +104,17 @@ function getButtonStyles(buttonType, isHovered, isActive, disabled, color, hasIc
|
|
|
104
104
|
return { ...base, backgroundColor: "transparent", border: "1px solid var(--fg-disabled)", color: "var(--fg-disabled)" };
|
|
105
105
|
}
|
|
106
106
|
switch (buttonType) {
|
|
107
|
-
//
|
|
107
|
+
// Text and icon-only primary actions inherit the same scoped theme.
|
|
108
108
|
case "primary":
|
|
109
|
-
if (hasIconOnly) {
|
|
110
|
-
return {
|
|
111
|
-
...base,
|
|
112
|
-
backgroundColor: isActive ? palette[700] : isHovered ? palette[500] : palette[600],
|
|
113
|
-
border: "1px solid transparent",
|
|
114
|
-
color: "var(--fg-inverse)"
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
109
|
return {
|
|
118
110
|
...base,
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
111
|
+
border: "1px solid transparent",
|
|
112
|
+
...palette ? {
|
|
113
|
+
"--button-primary-bg": palette[600],
|
|
114
|
+
"--button-primary-hover": palette[500],
|
|
115
|
+
"--button-primary-active": palette[700],
|
|
116
|
+
"--button-primary-fg": "var(--grey-0)"
|
|
117
|
+
} : {}
|
|
123
118
|
};
|
|
124
119
|
// Secondary: neutral. Rest=canvas, hover=surface-1 (darken), pressed=surface-2. Subtle border, dark text.
|
|
125
120
|
case "secondary":
|
|
@@ -150,7 +145,7 @@ function getButtonStyles(buttonType, isHovered, isActive, disabled, color, hasIc
|
|
|
150
145
|
}
|
|
151
146
|
}
|
|
152
147
|
var Button = React.forwardRef(
|
|
153
|
-
({ className, buttonType = "primary", buttonSize = "
|
|
148
|
+
({ className, buttonType = "primary", buttonSize = "lg", controlSize, color, icon, hasIconOnly, iconPosition = "left", style, disabled, children, ...props }, ref) => {
|
|
154
149
|
const [isHovered, setIsHovered] = React.useState(false);
|
|
155
150
|
const [isActive, setIsActive] = React.useState(false);
|
|
156
151
|
const typeStyles = getButtonStyles(buttonType, isHovered, isActive, !!disabled, color, hasIconOnly);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/ColumnEditor/entry.ts","../src/components/ColumnEditor/ColumnEditor.tsx","../src/components/Button/Button.tsx","../src/utils/cn.ts"],"sourcesContent":["export { ColumnEditor } from './ColumnEditor'\nexport type { ColumnEditorItem, ColumnEditorProps } from './ColumnEditor'\n","import * as React from 'react'\nimport { ArrowUp, ArrowDown, DotsSixVertical, Eye, EyeSlash, Gear } from '@mirror-physics/fractal-icons'\nimport { Button } from '../Button'\nimport { cn } from '../../utils/cn'\nimport './ColumnEditor.css'\n\nexport interface ColumnEditorItem { id: string; label: string; required?: boolean }\nexport interface ColumnEditorProps {\n items: ColumnEditorItem[]\n /** Visible column IDs in display order. Required items cannot be hidden. */\n value: string[]\n onChange: (value: string[]) => void\n label?: string\n hiddenLabel?: string\n className?: string\n}\ninterface DragState {\n id: string; pointerId: number; x: number; y: number; active: boolean\n visible: string[]; hidden: string[]\n}\nconst equal = (a: string[], b: string[]) => a.length === b.length && a.every((id, index) => id === b[index])\n\n/** Reorderable visible/hidden columns, with pointer preview and keyboard actions. */\nexport function ColumnEditor({ items, value, onChange, label = 'Edit columns', hiddenLabel = 'Hidden columns', className }: ColumnEditorProps) {\n const [open, setOpen] = React.useState(false)\n const [preview, setPreview] = React.useState<{ visible: string[]; hidden: string[]; active: string } | null>(null)\n const [announcement, setAnnouncement] = React.useState('')\n const root = React.useRef<HTMLDivElement>(null)\n const trigger = React.useRef<HTMLButtonElement>(null)\n const panel = React.useRef<HTMLDivElement>(null)\n const drag = React.useRef<DragState | null>(null)\n const positions = React.useRef<Map<string, DOMRect> | null>(null)\n const id = React.useId()\n function capturePositions() {\n positions.current = new Map(Array.from(panel.current?.querySelectorAll<HTMLElement>('[data-column-editor-item]') ?? []).map(row => [row.dataset.columnEditorItem!, row.getBoundingClientRect()]))\n }\n // FLIP from each row's current visual position, including interrupted animations.\n React.useLayoutEffect(() => {\n const before = positions.current\n positions.current = null\n if (!before || !panel.current || window.matchMedia('(prefers-reduced-motion: reduce)').matches) return\n const styles = getComputedStyle(panel.current)\n const token = styles.getPropertyValue('--duration-normal').trim()\n const duration = parseFloat(token) * (token.endsWith('ms') ? 1 : 1000)\n const easing = styles.getPropertyValue('--ease-out').trim()\n for (const row of panel.current.querySelectorAll<HTMLElement>('[data-column-editor-item]')) {\n const previous = before.get(row.dataset.columnEditorItem!)\n row.getAnimations().filter(animation => animation.id === 'fractal-column-position').forEach(animation => animation.cancel())\n if (!previous) continue\n const next = row.getBoundingClientRect()\n const x = previous.left - next.left, y = previous.top - next.top\n if (Math.abs(x) < 1 && Math.abs(y) < 1) continue\n row.animate([{ transform: `translate(${x}px, ${y}px)` }, { transform: 'translate(0, 0)' }], { duration, easing, id: 'fractal-column-position' })\n }\n })\n const valid = [...new Set(value)].filter(key => items.some(item => item.id === key))\n const committed = [...valid, ...items.filter(item => item.required && !valid.includes(item.id)).map(item => item.id)]\n const visible = preview?.visible ?? committed\n const hidden = preview?.hidden ?? items.filter(item => !committed.includes(item.id)).map(item => item.id)\n\n function cancel() { capturePositions(); drag.current = null; setPreview(null) }\n React.useEffect(() => {\n if (!open) return\n panel.current?.focus()\n function outside(event: PointerEvent) { if (!drag.current && !root.current?.contains(event.target as Node)) setOpen(false) }\n function escape(event: KeyboardEvent) {\n if (event.key !== 'Escape') return\n event.preventDefault()\n if (drag.current) { capturePositions(); drag.current = null; setPreview(null); setAnnouncement('Reordering cancelled') }\n else { setOpen(false); trigger.current?.focus() }\n }\n function blur(event: FocusEvent) { if (event.relatedTarget instanceof Node && !root.current?.contains(event.relatedTarget)) setOpen(false) }\n const element = root.current\n document.addEventListener('pointerdown', outside); document.addEventListener('keydown', escape); element?.addEventListener('focusout', blur)\n return () => { document.removeEventListener('pointerdown', outside); document.removeEventListener('keydown', escape); element?.removeEventListener('focusout', blur) }\n }, [open])\n\n function commit(next: string[], message: string) { capturePositions(); onChange(next); setAnnouncement(message) }\n function move(key: string, offset: number) {\n const index = committed.indexOf(key)\n const next = committed.filter(item => item !== key)\n if (offset > 0 && index === committed.length - 1 && !items.find(item => item.id === key)?.required) {\n commit(next, `${items.find(item => item.id === key)?.label} hidden`); return\n }\n next.splice(Math.max(0, Math.min(next.length, index + offset)), 0, key)\n commit(next, `${items.find(item => item.id === key)?.label} moved ${offset < 0 ? 'up' : 'down'}`)\n }\n function start(event: React.PointerEvent<HTMLLIElement>, key: string) {\n if (event.button !== 0 || (event.target as Element).closest('button')) return\n drag.current = { id: key, pointerId: event.pointerId, x: event.clientX, y: event.clientY, active: false, visible: [...committed], hidden: [...hidden] }\n panel.current?.setPointerCapture(event.pointerId)\n event.preventDefault()\n }\n function update(event: React.PointerEvent<HTMLDivElement>) {\n const current = drag.current\n if (!current || event.pointerId !== current.pointerId) return\n if (!current.active && Math.hypot(event.clientX - current.x, event.clientY - current.y) < 4) return\n current.active = true\n const container = panel.current\n if (!container) return\n const bounds = container.getBoundingClientRect()\n const hiddenGroup = container.querySelector<HTMLElement>('[data-column-editor-group=\"hidden\"]')!\n const inside = event.clientX >= bounds.left && event.clientX <= bounds.right && event.clientY >= bounds.top && event.clientY <= bounds.bottom\n if (!inside) return\n const destination = event.clientY >= hiddenGroup.getBoundingClientRect().top ? 'hidden' : 'visible'\n if (destination === 'hidden' && items.find(item => item.id === current.id)?.required) return\n // Hit-test layout slots, not animated row positions, so moving rows cannot flicker back and forth.\n const slots = Array.from(container.querySelectorAll<HTMLElement>(`[data-column-editor-group=\"${destination}\"] [data-column-editor-item]`))\n const localY = event.clientY - bounds.top + container.scrollTop - container.clientTop\n const ownSlot = slots.find(row => row.dataset.columnEditorItem === current.id)\n if (ownSlot && localY >= ownSlot.offsetTop && localY <= ownSlot.offsetTop + ownSlot.offsetHeight) return\n const nextVisible = current.visible.filter(key => key !== current.id)\n let nextHidden = current.hidden.filter(key => key !== current.id)\n if (destination === 'visible') {\n const index = slots.filter(row => row.dataset.columnEditorItem !== current.id && localY > row.offsetTop + row.offsetHeight / 2).length\n nextVisible.splice(index, 0, current.id)\n } else {\n nextHidden.push(current.id)\n nextHidden = items.filter(item => nextHidden.includes(item.id)).map(item => item.id)\n }\n if (!equal(nextVisible, current.visible) || !equal(nextHidden, current.hidden)) {\n capturePositions()\n current.visible = nextVisible; current.hidden = nextHidden\n }\n setPreview({ visible: current.visible, hidden: current.hidden, active: current.id })\n // Scroll the popover when dragging near its visible edges.\n if (event.clientY < bounds.top + 32) container.scrollTop -= 12\n else if (event.clientY > bounds.bottom - 32) container.scrollTop += 12\n }\n function finish(event: React.PointerEvent<HTMLDivElement>) {\n const current = drag.current\n if (!current || current.pointerId !== event.pointerId) return\n const hit = document.elementFromPoint(event.clientX, event.clientY)\n if (current.active && hit && panel.current?.contains(hit)) commit(current.visible, 'Column order updated')\n cancel()\n if (panel.current?.hasPointerCapture(event.pointerId)) panel.current.releasePointerCapture(event.pointerId)\n }\n function row(key: string, isHidden: boolean, index: number) {\n const item = items.find(item => item.id === key)!\n return <li key={key} className=\"fractal-column-editor__row\" data-column-editor-item={key} data-hidden={isHidden || undefined} data-dragging={preview?.active === key || undefined}\n onPointerDown={event => start(event, key)}>\n <DotsSixVertical className=\"fractal-column-editor__grip\" aria-hidden=\"true\" />\n <span className=\"fractal-column-editor__name\">{item.label}</span>\n <div className=\"fractal-column-editor__actions\" onPointerDown={event => event.stopPropagation()}>\n {isHidden ? <Button buttonType=\"ghost\" controlSize=\"sm\" hasIconOnly icon={<Eye aria-hidden=\"true\" />} aria-label={`Show ${item.label} column`} onClick={() => commit([...committed, key], `${item.label} shown`)} /> : <>\n <Button buttonType=\"ghost\" controlSize=\"sm\" hasIconOnly icon={<ArrowUp aria-hidden=\"true\" />} aria-label={`Move ${item.label} up`} disabled={index === 0} onClick={() => move(key, -1)} />\n <Button buttonType=\"ghost\" controlSize=\"sm\" hasIconOnly icon={index === visible.length - 1 && !item.required ? <EyeSlash aria-hidden=\"true\" /> : <ArrowDown aria-hidden=\"true\" />} aria-label={index === visible.length - 1 && !item.required ? `Hide ${item.label} column` : `Move ${item.label} down`} disabled={index === visible.length - 1 && item.required} onClick={() => move(key, 1)} />\n </>}\n </div>\n </li>\n }\n return <div className={cn('fractal-column-editor', className)} ref={root}>\n <Button ref={trigger} controlSize=\"lg\" buttonType=\"secondary\" icon={<Gear aria-hidden=\"true\" />} iconPosition=\"right\" aria-haspopup=\"dialog\" aria-expanded={open} aria-controls={id} onClick={() => { cancel(); setOpen(current => !current) }}>{label}</Button>\n {open ? <div id={id} className=\"fractal-column-editor__panel\" ref={panel} role=\"dialog\" data-dragging={Boolean(preview) || undefined} aria-label={label} tabIndex={-1} onPointerMove={update} onPointerUp={finish} onPointerCancel={cancel} onLostPointerCapture={cancel}>\n <ol className=\"fractal-column-editor__list\" data-column-editor-group=\"visible\" aria-label=\"Visible columns\">{visible.map((key, index) => row(key, false, index))}</ol>\n <section data-column-editor-group=\"hidden\" className=\"fractal-column-editor__hidden\" aria-label={hiddenLabel}>\n <div className=\"fractal-column-editor__divider\"><span>{hiddenLabel}<EyeSlash aria-hidden=\"true\" /></span></div>\n <ol className=\"fractal-column-editor__list\">{hidden.map((key, index) => row(key, true, index))}</ol>\n {!hidden.length ? <p className=\"fractal-column-editor__empty\">Drag columns here to hide them.</p> : null}\n </section>\n <span className=\"fractal-column-editor__announcement\" role=\"status\" aria-live=\"polite\">{announcement}</span>\n </div> : null}\n </div>\n}\n","import * as React from 'react'\nimport { cn } from '../../utils/cn'\nimport type { ControlSize } from '../../utils/control-size'\nimport '../../styles/control.css'\nimport './Button.css'\n\nexport type ButtonType = 'primary' | 'secondary' | 'ghost' | 'danger'\nexport type ButtonSize = ControlSize\nexport type ButtonColor = 'blue' | 'pink' | 'orange' | 'green'\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Visual hierarchy. Primary = strongest action, Secondary = neutral bordered, Ghost = minimal, Danger = destructive. */\n buttonType?: ButtonType\n /** Shared visual density; takes precedence over the buttonSize alias. */\n controlSize?: ControlSize\n /** Backward-compatible alias for controlSize. */\n buttonSize?: ButtonSize\n /** Color theme — maps to the design system's color scales. */\n color?: ButtonColor\n /** Icon element. */\n icon?: React.ReactNode\n /** Whether the button displays only an icon (no text). Must include aria-label. */\n hasIconOnly?: boolean\n /** Position of the icon relative to the label. */\n iconPosition?: 'left' | 'right'\n}\n\n/*\n * Color palette mapping per the color guide's semantic stop roles:\n * 0 = bg (non-interactive reading surfaces)\n * 50 = surface (tertiary button fill — interactive)\n * 100 = surface-hover (tertiary button hover — darken)\n * 200 = surface-stroke (tertiary pressed, borders)\n * 500 = md-stroke (strong chromatic hover — lighten from 600)\n * 600 = strong (strong chromatic fill — rest)\n * 700 = strong-pressed (strong chromatic pressed — darken)\n */\nconst colorPalette = {\n blue: {\n 0: 'var(--blue-0)',\n 50: 'var(--blue-50)',\n 100: 'var(--blue-100)',\n 200: 'var(--blue-200)',\n 500: 'var(--blue-500)',\n 600: 'var(--blue-600)',\n 700: 'var(--blue-700)',\n },\n pink: {\n 0: 'var(--pink-0)',\n 50: 'var(--pink-50)',\n 100: 'var(--pink-100)',\n 200: 'var(--pink-200)',\n 500: 'var(--pink-500)',\n 600: 'var(--pink-600)',\n 700: 'var(--pink-700)',\n },\n orange: {\n 0: 'var(--orange-0)',\n 50: 'var(--orange-50)',\n 100: 'var(--orange-100)',\n 200: 'var(--orange-200)',\n 500: 'var(--orange-500)',\n 600: 'var(--orange-600)',\n 700: 'var(--orange-700)',\n },\n green: {\n 0: 'var(--green-0)',\n 50: 'var(--green-50)',\n 100: 'var(--green-100)',\n 200: 'var(--green-200)',\n 500: 'var(--green-500)',\n 600: 'var(--green-600)',\n 700: 'var(--green-700)',\n },\n}\n\nfunction getButtonStyles(\n buttonType: ButtonType,\n isHovered: boolean,\n isActive: boolean,\n disabled: boolean,\n color: ButtonColor,\n hasIconOnly: boolean | undefined,\n): React.CSSProperties {\n const palette = colorPalette[color]\n\n const base: React.CSSProperties = {\n borderRadius: hasIconOnly ? 'var(--radius-lg, 8px)' : 'var(--radius-full, 9999px)',\n cursor: disabled ? 'not-allowed' : 'pointer',\n transition: 'background-color 0.15s ease, border-color 0.15s ease, opacity 0.15s ease',\n }\n\n if (hasIconOnly) {\n base.justifyContent = 'center'\n }\n\n // Disabled: bordered buttons get transparent bg + disabled border + disabled text.\n // Others just get opacity: 0.5 (handled by CSS).\n // Per principles.md Interaction States > Disabled\n if (disabled) {\n if (buttonType === 'ghost') {\n return { ...base, backgroundColor: 'transparent', border: '1px solid transparent', color: 'var(--fg-disabled)' }\n }\n return { ...base, backgroundColor: 'transparent', border: '1px solid var(--fg-disabled)', color: 'var(--fg-disabled)' }\n }\n\n switch (buttonType) {\n // Primary with text: dark pill. Icon-only: color palette (Synapse style).\n case 'primary':\n if (hasIconOnly) {\n return {\n ...base,\n backgroundColor: isActive ? palette[700] : isHovered ? palette[500] : palette[600],\n border: '1px solid transparent',\n color: 'var(--fg-inverse)',\n }\n }\n return {\n ...base,\n backgroundColor: 'var(--fg-primary)',\n border: '1px solid var(--fg-primary)',\n color: 'var(--fg-inverse)',\n ...(isHovered || isActive ? { opacity: 0.85 } : {}),\n }\n\n // Secondary: neutral. Rest=canvas, hover=surface-1 (darken), pressed=surface-2. Subtle border, dark text.\n case 'secondary':\n return {\n ...base,\n backgroundColor: isActive ? 'var(--bg-surface-2)' : isHovered ? 'var(--bg-surface-1)' : 'var(--bg-canvas)',\n border: '1px solid var(--border-subtle)',\n color: 'var(--fg-primary)',\n }\n\n // Ghost: no border. Rest=transparent, hover/press=surface-1.\n case 'ghost':\n return {\n ...base,\n backgroundColor: isHovered || isActive ? 'var(--bg-surface-1)' : 'transparent',\n border: '1px solid transparent',\n color: 'var(--fg-primary)',\n }\n\n // Danger: low-intensity destructive action. Text stays steady; hover deepens the light red surface.\n case 'danger':\n return {\n ...base,\n backgroundColor: isHovered || isActive ? 'var(--danger-button-surface-hover)' : 'var(--danger-button-surface)',\n border: '1px solid transparent',\n color: 'var(--danger-button-fg)',\n }\n\n default:\n return base\n }\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, buttonType = 'primary', buttonSize = 'md', controlSize, color = 'blue', icon, hasIconOnly, iconPosition = 'left', style, disabled, children, ...props }, ref) => {\n const [isHovered, setIsHovered] = React.useState(false)\n const [isActive, setIsActive] = React.useState(false)\n\n const typeStyles = getButtonStyles(buttonType, isHovered, isActive, !!disabled, color, hasIconOnly)\n const hasIconAndText = icon && children && !hasIconOnly\n const finalStyles = hasIconAndText\n ? { ...typeStyles, gap: 'var(--space-2, 8px)', ...style }\n : { ...typeStyles, ...style }\n\n return (\n <button\n ref={ref}\n type=\"button\"\n data-control-size={controlSize ?? buttonSize}\n data-icon-only={hasIconOnly || undefined}\n className={cn('fractal-control', 'fractal-button', `fractal-button--${buttonType}`, className)}\n style={finalStyles}\n disabled={disabled}\n onMouseEnter={(e) => { setIsHovered(true); props.onMouseEnter?.(e) }}\n onMouseLeave={(e) => { setIsHovered(false); setIsActive(false); props.onMouseLeave?.(e) }}\n onMouseDown={(e) => { setIsActive(true); props.onMouseDown?.(e) }}\n onMouseUp={(e) => { setIsActive(false); props.onMouseUp?.(e) }}\n {...props}\n >\n {iconPosition !== 'right' && icon}\n {!hasIconOnly && children}\n {iconPosition === 'right' && icon}\n </button>\n )\n }\n)\nButton.displayName = 'Button'\n\nexport { Button }\n","import { clsx, type ClassValue } from 'clsx'\n\nexport function cn(...inputs: ClassValue[]) {\n return clsx(inputs)\n}\n"],"mappings":"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","names":["React","import_jsx_runtime","row","item"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/ColumnEditor/entry.ts","../src/components/ColumnEditor/ColumnEditor.tsx","../src/components/Button/Button.tsx","../src/utils/cn.ts"],"sourcesContent":["export { ColumnEditor } from './ColumnEditor'\nexport type { ColumnEditorItem, ColumnEditorProps } from './ColumnEditor'\n","import * as React from 'react'\nimport { ArrowUp, ArrowDown, DotsSixVertical, Eye, EyeSlash, Gear } from '@mirror-physics/fractal-icons'\nimport { Button } from '../Button'\nimport { cn } from '../../utils/cn'\nimport './ColumnEditor.css'\n\nexport interface ColumnEditorItem { id: string; label: string; required?: boolean }\nexport interface ColumnEditorProps {\n items: ColumnEditorItem[]\n /** Visible column IDs in display order. Required items cannot be hidden. */\n value: string[]\n onChange: (value: string[]) => void\n label?: string\n hiddenLabel?: string\n className?: string\n}\ninterface DragState {\n id: string; pointerId: number; x: number; y: number; active: boolean\n visible: string[]; hidden: string[]\n}\nconst equal = (a: string[], b: string[]) => a.length === b.length && a.every((id, index) => id === b[index])\n\n/** Reorderable visible/hidden columns, with pointer preview and keyboard actions. */\nexport function ColumnEditor({ items, value, onChange, label = 'Edit columns', hiddenLabel = 'Hidden columns', className }: ColumnEditorProps) {\n const [open, setOpen] = React.useState(false)\n const [preview, setPreview] = React.useState<{ visible: string[]; hidden: string[]; active: string } | null>(null)\n const [announcement, setAnnouncement] = React.useState('')\n const root = React.useRef<HTMLDivElement>(null)\n const trigger = React.useRef<HTMLButtonElement>(null)\n const panel = React.useRef<HTMLDivElement>(null)\n const drag = React.useRef<DragState | null>(null)\n const positions = React.useRef<Map<string, DOMRect> | null>(null)\n const id = React.useId()\n function capturePositions() {\n positions.current = new Map(Array.from(panel.current?.querySelectorAll<HTMLElement>('[data-column-editor-item]') ?? []).map(row => [row.dataset.columnEditorItem!, row.getBoundingClientRect()]))\n }\n // FLIP from each row's current visual position, including interrupted animations.\n React.useLayoutEffect(() => {\n const before = positions.current\n positions.current = null\n if (!before || !panel.current || window.matchMedia('(prefers-reduced-motion: reduce)').matches) return\n const styles = getComputedStyle(panel.current)\n const token = styles.getPropertyValue('--duration-normal').trim()\n const duration = parseFloat(token) * (token.endsWith('ms') ? 1 : 1000)\n const easing = styles.getPropertyValue('--ease-out').trim()\n for (const row of panel.current.querySelectorAll<HTMLElement>('[data-column-editor-item]')) {\n const previous = before.get(row.dataset.columnEditorItem!)\n row.getAnimations().filter(animation => animation.id === 'fractal-column-position').forEach(animation => animation.cancel())\n if (!previous) continue\n const next = row.getBoundingClientRect()\n const x = previous.left - next.left, y = previous.top - next.top\n if (Math.abs(x) < 1 && Math.abs(y) < 1) continue\n row.animate([{ transform: `translate(${x}px, ${y}px)` }, { transform: 'translate(0, 0)' }], { duration, easing, id: 'fractal-column-position' })\n }\n })\n const valid = [...new Set(value)].filter(key => items.some(item => item.id === key))\n const committed = [...valid, ...items.filter(item => item.required && !valid.includes(item.id)).map(item => item.id)]\n const visible = preview?.visible ?? committed\n const hidden = preview?.hidden ?? items.filter(item => !committed.includes(item.id)).map(item => item.id)\n\n function cancel() { capturePositions(); drag.current = null; setPreview(null) }\n React.useEffect(() => {\n if (!open) return\n panel.current?.focus()\n function outside(event: PointerEvent) { if (!drag.current && !root.current?.contains(event.target as Node)) setOpen(false) }\n function escape(event: KeyboardEvent) {\n if (event.key !== 'Escape') return\n event.preventDefault()\n if (drag.current) { capturePositions(); drag.current = null; setPreview(null); setAnnouncement('Reordering cancelled') }\n else { setOpen(false); trigger.current?.focus() }\n }\n function blur(event: FocusEvent) { if (event.relatedTarget instanceof Node && !root.current?.contains(event.relatedTarget)) setOpen(false) }\n const element = root.current\n document.addEventListener('pointerdown', outside); document.addEventListener('keydown', escape); element?.addEventListener('focusout', blur)\n return () => { document.removeEventListener('pointerdown', outside); document.removeEventListener('keydown', escape); element?.removeEventListener('focusout', blur) }\n }, [open])\n\n function commit(next: string[], message: string) { capturePositions(); onChange(next); setAnnouncement(message) }\n function move(key: string, offset: number) {\n const index = committed.indexOf(key)\n const next = committed.filter(item => item !== key)\n if (offset > 0 && index === committed.length - 1 && !items.find(item => item.id === key)?.required) {\n commit(next, `${items.find(item => item.id === key)?.label} hidden`); return\n }\n next.splice(Math.max(0, Math.min(next.length, index + offset)), 0, key)\n commit(next, `${items.find(item => item.id === key)?.label} moved ${offset < 0 ? 'up' : 'down'}`)\n }\n function start(event: React.PointerEvent<HTMLLIElement>, key: string) {\n if (event.button !== 0 || (event.target as Element).closest('button')) return\n drag.current = { id: key, pointerId: event.pointerId, x: event.clientX, y: event.clientY, active: false, visible: [...committed], hidden: [...hidden] }\n panel.current?.setPointerCapture(event.pointerId)\n event.preventDefault()\n }\n function update(event: React.PointerEvent<HTMLDivElement>) {\n const current = drag.current\n if (!current || event.pointerId !== current.pointerId) return\n if (!current.active && Math.hypot(event.clientX - current.x, event.clientY - current.y) < 4) return\n current.active = true\n const container = panel.current\n if (!container) return\n const bounds = container.getBoundingClientRect()\n const hiddenGroup = container.querySelector<HTMLElement>('[data-column-editor-group=\"hidden\"]')!\n const inside = event.clientX >= bounds.left && event.clientX <= bounds.right && event.clientY >= bounds.top && event.clientY <= bounds.bottom\n if (!inside) return\n const destination = event.clientY >= hiddenGroup.getBoundingClientRect().top ? 'hidden' : 'visible'\n if (destination === 'hidden' && items.find(item => item.id === current.id)?.required) return\n // Hit-test layout slots, not animated row positions, so moving rows cannot flicker back and forth.\n const slots = Array.from(container.querySelectorAll<HTMLElement>(`[data-column-editor-group=\"${destination}\"] [data-column-editor-item]`))\n const localY = event.clientY - bounds.top + container.scrollTop - container.clientTop\n const ownSlot = slots.find(row => row.dataset.columnEditorItem === current.id)\n if (ownSlot && localY >= ownSlot.offsetTop && localY <= ownSlot.offsetTop + ownSlot.offsetHeight) return\n const nextVisible = current.visible.filter(key => key !== current.id)\n let nextHidden = current.hidden.filter(key => key !== current.id)\n if (destination === 'visible') {\n const index = slots.filter(row => row.dataset.columnEditorItem !== current.id && localY > row.offsetTop + row.offsetHeight / 2).length\n nextVisible.splice(index, 0, current.id)\n } else {\n nextHidden.push(current.id)\n nextHidden = items.filter(item => nextHidden.includes(item.id)).map(item => item.id)\n }\n if (!equal(nextVisible, current.visible) || !equal(nextHidden, current.hidden)) {\n capturePositions()\n current.visible = nextVisible; current.hidden = nextHidden\n }\n setPreview({ visible: current.visible, hidden: current.hidden, active: current.id })\n // Scroll the popover when dragging near its visible edges.\n if (event.clientY < bounds.top + 32) container.scrollTop -= 12\n else if (event.clientY > bounds.bottom - 32) container.scrollTop += 12\n }\n function finish(event: React.PointerEvent<HTMLDivElement>) {\n const current = drag.current\n if (!current || current.pointerId !== event.pointerId) return\n const hit = document.elementFromPoint(event.clientX, event.clientY)\n if (current.active && hit && panel.current?.contains(hit)) commit(current.visible, 'Column order updated')\n cancel()\n if (panel.current?.hasPointerCapture(event.pointerId)) panel.current.releasePointerCapture(event.pointerId)\n }\n function row(key: string, isHidden: boolean, index: number) {\n const item = items.find(item => item.id === key)!\n return <li key={key} className=\"fractal-column-editor__row\" data-column-editor-item={key} data-hidden={isHidden || undefined} data-dragging={preview?.active === key || undefined}\n onPointerDown={event => start(event, key)}>\n <DotsSixVertical className=\"fractal-column-editor__grip\" aria-hidden=\"true\" />\n <span className=\"fractal-column-editor__name\">{item.label}</span>\n <div className=\"fractal-column-editor__actions\" onPointerDown={event => event.stopPropagation()}>\n {isHidden ? <Button buttonType=\"ghost\" controlSize=\"sm\" hasIconOnly icon={<Eye aria-hidden=\"true\" />} aria-label={`Show ${item.label} column`} onClick={() => commit([...committed, key], `${item.label} shown`)} /> : <>\n <Button buttonType=\"ghost\" controlSize=\"sm\" hasIconOnly icon={<ArrowUp aria-hidden=\"true\" />} aria-label={`Move ${item.label} up`} disabled={index === 0} onClick={() => move(key, -1)} />\n <Button buttonType=\"ghost\" controlSize=\"sm\" hasIconOnly icon={index === visible.length - 1 && !item.required ? <EyeSlash aria-hidden=\"true\" /> : <ArrowDown aria-hidden=\"true\" />} aria-label={index === visible.length - 1 && !item.required ? `Hide ${item.label} column` : `Move ${item.label} down`} disabled={index === visible.length - 1 && item.required} onClick={() => move(key, 1)} />\n </>}\n </div>\n </li>\n }\n return <div className={cn('fractal-column-editor', className)} ref={root}>\n <Button ref={trigger} controlSize=\"lg\" buttonType=\"secondary\" icon={<Gear aria-hidden=\"true\" />} iconPosition=\"right\" aria-haspopup=\"dialog\" aria-expanded={open} aria-controls={id} onClick={() => { cancel(); setOpen(current => !current) }}>{label}</Button>\n {open ? <div id={id} className=\"fractal-column-editor__panel\" ref={panel} role=\"dialog\" data-dragging={Boolean(preview) || undefined} aria-label={label} tabIndex={-1} onPointerMove={update} onPointerUp={finish} onPointerCancel={cancel} onLostPointerCapture={cancel}>\n <ol className=\"fractal-column-editor__list\" data-column-editor-group=\"visible\" aria-label=\"Visible columns\">{visible.map((key, index) => row(key, false, index))}</ol>\n <section data-column-editor-group=\"hidden\" className=\"fractal-column-editor__hidden\" aria-label={hiddenLabel}>\n <div className=\"fractal-column-editor__divider\"><span>{hiddenLabel}<EyeSlash aria-hidden=\"true\" /></span></div>\n <ol className=\"fractal-column-editor__list\">{hidden.map((key, index) => row(key, true, index))}</ol>\n {!hidden.length ? <p className=\"fractal-column-editor__empty\">Drag columns here to hide them.</p> : null}\n </section>\n <span className=\"fractal-column-editor__announcement\" role=\"status\" aria-live=\"polite\">{announcement}</span>\n </div> : null}\n </div>\n}\n","import * as React from 'react'\nimport { cn } from '../../utils/cn'\nimport type { ControlSize } from '../../utils/control-size'\nimport '../../styles/control.css'\nimport './Button.css'\n\nexport type ButtonType = 'primary' | 'secondary' | 'ghost' | 'danger'\nexport type ButtonSize = ControlSize\nexport type ButtonColor = 'blue' | 'pink' | 'orange' | 'green'\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Visual hierarchy. Primary = strongest action, Secondary = neutral bordered, Ghost = minimal, Danger = destructive. */\n buttonType?: ButtonType\n /** Shared visual density; takes precedence over the buttonSize alias. */\n controlSize?: ControlSize\n /** Backward-compatible alias for controlSize. */\n buttonSize?: ButtonSize\n /** Explicit primary color preset. Omit to inherit the application's primary tokens. */\n color?: ButtonColor\n /** Icon element. */\n icon?: React.ReactNode\n /** Whether the button displays only an icon (no text). Must include aria-label. */\n hasIconOnly?: boolean\n /** Position of the icon relative to the label. */\n iconPosition?: 'left' | 'right'\n}\n\n/*\n * Color palette mapping per the color guide's semantic stop roles:\n * 0 = bg (non-interactive reading surfaces)\n * 50 = surface (tertiary button fill — interactive)\n * 100 = surface-hover (tertiary button hover — darken)\n * 200 = surface-stroke (tertiary pressed, borders)\n * 500 = md-stroke (strong chromatic hover — lighten from 600)\n * 600 = strong (strong chromatic fill — rest)\n * 700 = strong-pressed (strong chromatic pressed — darken)\n */\nconst colorPalette = {\n blue: {\n 0: 'var(--blue-0)',\n 50: 'var(--blue-50)',\n 100: 'var(--blue-100)',\n 200: 'var(--blue-200)',\n 500: 'var(--blue-500)',\n 600: 'var(--blue-600)',\n 700: 'var(--blue-700)',\n },\n pink: {\n 0: 'var(--pink-0)',\n 50: 'var(--pink-50)',\n 100: 'var(--pink-100)',\n 200: 'var(--pink-200)',\n 500: 'var(--pink-500)',\n 600: 'var(--pink-600)',\n 700: 'var(--pink-700)',\n },\n orange: {\n 0: 'var(--orange-0)',\n 50: 'var(--orange-50)',\n 100: 'var(--orange-100)',\n 200: 'var(--orange-200)',\n 500: 'var(--orange-500)',\n 600: 'var(--orange-600)',\n 700: 'var(--orange-700)',\n },\n green: {\n 0: 'var(--green-0)',\n 50: 'var(--green-50)',\n 100: 'var(--green-100)',\n 200: 'var(--green-200)',\n 500: 'var(--green-500)',\n 600: 'var(--green-600)',\n 700: 'var(--green-700)',\n },\n}\n\nfunction getButtonStyles(\n buttonType: ButtonType,\n isHovered: boolean,\n isActive: boolean,\n disabled: boolean,\n color: ButtonColor | undefined,\n hasIconOnly: boolean | undefined,\n): React.CSSProperties {\n const palette = color ? colorPalette[color] : undefined\n\n const base: React.CSSProperties = {\n borderRadius: 'var(--radius-sm, 4px)',\n cursor: disabled ? 'not-allowed' : 'pointer',\n transition: 'background-color 0.15s ease, border-color 0.15s ease, opacity 0.15s ease',\n }\n\n if (hasIconOnly) {\n base.justifyContent = 'center'\n }\n\n // Disabled: bordered buttons get transparent bg + disabled border + disabled text.\n // Others just get opacity: 0.5 (handled by CSS).\n // Per principles.md Interaction States > Disabled\n if (disabled) {\n if (buttonType === 'ghost') {\n return { ...base, backgroundColor: 'transparent', border: '1px solid transparent', color: 'var(--fg-disabled)' }\n }\n return { ...base, backgroundColor: 'transparent', border: '1px solid var(--fg-disabled)', color: 'var(--fg-disabled)' }\n }\n\n switch (buttonType) {\n // Text and icon-only primary actions inherit the same scoped theme.\n case 'primary':\n return {\n ...base,\n border: '1px solid transparent',\n ...(palette ? {\n '--button-primary-bg': palette[600],\n '--button-primary-hover': palette[500],\n '--button-primary-active': palette[700],\n '--button-primary-fg': 'var(--grey-0)',\n } : {}),\n } as React.CSSProperties\n\n // Secondary: neutral. Rest=canvas, hover=surface-1 (darken), pressed=surface-2. Subtle border, dark text.\n case 'secondary':\n return {\n ...base,\n backgroundColor: isActive ? 'var(--bg-surface-2)' : isHovered ? 'var(--bg-surface-1)' : 'var(--bg-canvas)',\n border: '1px solid var(--border-subtle)',\n color: 'var(--fg-primary)',\n }\n\n // Ghost: no border. Rest=transparent, hover/press=surface-1.\n case 'ghost':\n return {\n ...base,\n backgroundColor: isHovered || isActive ? 'var(--bg-surface-1)' : 'transparent',\n border: '1px solid transparent',\n color: 'var(--fg-primary)',\n }\n\n // Danger: low-intensity destructive action. Text stays steady; hover deepens the light red surface.\n case 'danger':\n return {\n ...base,\n backgroundColor: isHovered || isActive ? 'var(--danger-button-surface-hover)' : 'var(--danger-button-surface)',\n border: '1px solid transparent',\n color: 'var(--danger-button-fg)',\n }\n\n default:\n return base\n }\n}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, buttonType = 'primary', buttonSize = 'lg', controlSize, color, icon, hasIconOnly, iconPosition = 'left', style, disabled, children, ...props }, ref) => {\n const [isHovered, setIsHovered] = React.useState(false)\n const [isActive, setIsActive] = React.useState(false)\n\n const typeStyles = getButtonStyles(buttonType, isHovered, isActive, !!disabled, color, hasIconOnly)\n const hasIconAndText = icon && children && !hasIconOnly\n const finalStyles = hasIconAndText\n ? { ...typeStyles, gap: 'var(--space-2, 8px)', ...style }\n : { ...typeStyles, ...style }\n\n return (\n <button\n ref={ref}\n type=\"button\"\n data-control-size={controlSize ?? buttonSize}\n data-icon-only={hasIconOnly || undefined}\n className={cn('fractal-control', 'fractal-button', `fractal-button--${buttonType}`, className)}\n style={finalStyles}\n disabled={disabled}\n onMouseEnter={(e) => { setIsHovered(true); props.onMouseEnter?.(e) }}\n onMouseLeave={(e) => { setIsHovered(false); setIsActive(false); props.onMouseLeave?.(e) }}\n onMouseDown={(e) => { setIsActive(true); props.onMouseDown?.(e) }}\n onMouseUp={(e) => { setIsActive(false); props.onMouseUp?.(e) }}\n {...props}\n >\n {iconPosition !== 'right' && icon}\n {!hasIconOnly && children}\n {iconPosition === 'right' && icon}\n </button>\n )\n }\n)\nButton.displayName = 'Button'\n\nexport { Button }\n","import { clsx, type ClassValue } from 'clsx'\n\nexport function cn(...inputs: ClassValue[]) {\n return clsx(inputs)\n}\n"],"mappings":"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","names":["React","import_jsx_runtime","row","item"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/styles/control.css","../src/components/Button/Button.css","../src/components/ColumnEditor/ColumnEditor.css"],"sourcesContent":["/* Shared metrics are canonical Fractal tokens; choose them per control. */\n[data-control-size=\"xs\"] {\n --control-font-size: var(--control-xs-font-size);\n --control-line-height: var(--control-xs-line-height);\n --control-padding-block: var(--control-xs-padding-block);\n --control-padding-inline: var(--control-xs-padding-inline);\n --control-icon-size: var(--control-xs-icon-size);\n}\n[data-control-size=\"sm\"] {\n --control-font-size: var(--control-sm-font-size);\n --control-line-height: var(--control-sm-line-height);\n --control-padding-block: var(--control-sm-padding-block);\n --control-padding-inline: var(--control-sm-padding-inline);\n --control-icon-size: var(--control-sm-icon-size);\n}\n[data-control-size=\"md\"] {\n --control-font-size: var(--control-md-font-size);\n --control-line-height: var(--control-md-line-height);\n --control-padding-block: var(--control-md-padding-block);\n --control-padding-inline: var(--control-md-padding-inline);\n --control-icon-size: var(--control-md-icon-size);\n}\n[data-control-size=\"lg\"] {\n --control-font-size: var(--control-lg-font-size);\n --control-line-height: var(--control-lg-line-height);\n --control-padding-block: var(--control-lg-padding-block);\n --control-padding-inline: var(--control-lg-padding-inline);\n --control-icon-size: var(--control-lg-icon-size);\n}\n[data-control-size=\"xl\"] {\n --control-font-size: var(--control-xl-font-size);\n --control-line-height: var(--control-xl-line-height);\n --control-padding-block: var(--control-xl-padding-block);\n --control-padding-inline: var(--control-xl-padding-inline);\n --control-icon-size: var(--control-xl-icon-size);\n}\n\n[data-control-size] {\n --control-min-block-size: calc(var(--control-line-height) + 2 * var(--control-padding-block) + 2 * var(--control-border-width));\n}\n\n.fractal-control {\n box-sizing: border-box;\n height: auto;\n min-block-size: var(--control-min-block-size);\n margin: 0;\n padding: var(--control-padding-block) var(--control-padding-inline);\n font-family: var(--font-sans);\n font-size: var(--control-font-size);\n font-weight: 400;\n line-height: var(--control-line-height);\n letter-spacing: normal;\n}\n\n.fractal-field {\n display: grid;\n align-content: start;\n gap: var(--control-label-gap);\n min-inline-size: 0;\n}\n",".fractal-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n white-space: nowrap;\n font-weight: 400;\n font-family: var(--font-sans);\n text-decoration: none;\n box-sizing: border-box;\n transform: scale(1);\n transition: transform 120ms cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n/* Press: subtle shrink, then expand on release. 120ms / ease-out per motion guide. */\n.fractal-button--primary:active:not(:disabled),\n.fractal-button--secondary:active:not(:disabled),\n.fractal-button--ghost:active:not(:disabled),\n.fractal-button--danger:active:not(:disabled) {\n transform: scale(0.97);\n}\n\n/* Focus ring: 2px --border-focus, 2px offset. Per principles.md Focus section. */\n.fractal-button:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--bg-canvas, #fff), 0 0 0 4px var(--border-focus, var(--blue-500));\n}\n\n.fractal-button:disabled {\n opacity: 0.5;\n pointer-events: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .fractal-button {\n transition-duration: 0.01ms;\n }\n}\n\n.fractal-button { gap: var(--control-icon-gap); }\n.fractal-button svg { inline-size: var(--control-icon-size); block-size: var(--control-icon-size); flex-shrink: 0; }\n.fractal-button[data-icon-only] {\n inline-size: var(--control-min-block-size);\n padding-inline: 0;\n}\n",".fractal-column-editor { position: relative; }\n.fractal-column-editor__panel {\n position: absolute; z-index: 60; top: calc(100% + var(--space-2)); right: 0;\n width: min(440px, calc(100vw - var(--space-7))); box-sizing: border-box;\n padding: var(--space-4); border: 1px solid var(--border-subtle); border-radius: var(--radius-lg);\n background: var(--bg-canvas); box-shadow: var(--shadow-md); max-height: 72dvh; overflow-y: auto;\n font-family: var(--font-sans); font-size: .875rem;\n}\n.fractal-column-editor__panel:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 2px; }\n.fractal-column-editor__list { display: grid; gap: var(--space-2); padding: 0; margin: 0; list-style: none; min-height: var(--space-4); }\n.fractal-column-editor__row {\n display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2);\n border: 1px solid var(--border-subtle); border-radius: var(--radius-md);\n color: var(--fg-primary); background: var(--bg-canvas); cursor: grab;\n user-select: none; touch-action: none;\n transition: background-color var(--duration-fast) var(--ease-out), border-color var(--duration-fast) var(--ease-out);\n}\n.fractal-column-editor__row[data-hidden] { color: var(--fg-disabled); background: var(--bg-surface-1); }\n.fractal-column-editor__row:hover { background: var(--hover-surface); }\n.fractal-column-editor__row[data-dragging] { cursor: grabbing; background: var(--nav-selected); border-color: var(--border-focus); }\n.fractal-column-editor__grip { width: 20px; height: 20px; flex-shrink: 0; color: inherit; pointer-events: none; }\n.fractal-column-editor__name { min-width: 0; pointer-events: none; }\n.fractal-column-editor__actions { display: flex; flex-shrink: 0; margin-left: auto; cursor: default; }\n/* An arrow has its own stronger hover against the hovered row. */\n.fractal-column-editor__actions .fractal-button { cursor: pointer !important; color: var(--fg-secondary); }\n.fractal-column-editor__actions .fractal-button:hover:not(:disabled) { background: var(--bg-surface-2) !important; }\n.fractal-column-editor__actions .fractal-button:disabled { pointer-events: auto; cursor: pointer !important; }\n.fractal-column-editor__divider { display: flex; align-items: center; gap: var(--space-3); margin-block: var(--space-6); color: var(--fg-tertiary); }\n.fractal-column-editor__divider::before, .fractal-column-editor__divider::after { content: ''; flex: 1; border-top: 1px solid var(--border-subtle); }\n.fractal-column-editor__divider > span { display: flex; gap: var(--space-2); align-items: center; white-space: nowrap; }\n.fractal-column-editor__divider svg { width: 20px; height: 20px; }\n.fractal-column-editor__empty { margin: 0; padding-block: var(--space-4); color: var(--fg-tertiary); }\n.fractal-column-editor__announcement { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }\n@media (prefers-reduced-motion: reduce) { .fractal-column-editor__row { transition: none; } }\n\n.fractal-column-editor__panel[data-dragging], .fractal-column-editor__panel[data-dragging] .fractal-column-editor__row { cursor: grabbing; }\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/styles/control.css","../src/components/Button/Button.css","../src/components/ColumnEditor/ColumnEditor.css"],"sourcesContent":["/* Shared metrics are canonical Fractal tokens; choose them per control. */\n[data-control-size=\"sm\"] {\n --control-font-size: var(--control-sm-font-size);\n --control-line-height: var(--control-sm-line-height);\n --control-padding-block: var(--control-sm-padding-block);\n --control-padding-inline: var(--control-sm-padding-inline);\n --control-icon-size: var(--control-sm-icon-size);\n}\n[data-control-size=\"md\"] {\n --control-font-size: var(--control-md-font-size);\n --control-line-height: var(--control-md-line-height);\n --control-padding-block: var(--control-md-padding-block);\n --control-padding-inline: var(--control-md-padding-inline);\n --control-icon-size: var(--control-md-icon-size);\n}\n[data-control-size=\"lg\"] {\n --control-font-size: var(--control-lg-font-size);\n --control-line-height: var(--control-lg-line-height);\n --control-padding-block: var(--control-lg-padding-block);\n --control-padding-inline: var(--control-lg-padding-inline);\n --control-icon-size: var(--control-lg-icon-size);\n}\n[data-control-size=\"xl\"] {\n --control-font-size: var(--control-xl-font-size);\n --control-line-height: var(--control-xl-line-height);\n --control-padding-block: var(--control-xl-padding-block);\n --control-padding-inline: var(--control-xl-padding-inline);\n --control-icon-size: var(--control-xl-icon-size);\n}\n\n[data-control-size] {\n --control-min-block-size: calc(var(--control-line-height) + 2 * var(--control-padding-block) + 2 * var(--control-border-width));\n}\n\n.fractal-control {\n box-sizing: border-box;\n height: auto;\n min-block-size: var(--control-min-block-size);\n margin: 0;\n padding: var(--control-padding-block) var(--control-padding-inline);\n font-family: var(--font-sans);\n font-size: var(--control-font-size);\n font-weight: 400;\n line-height: var(--control-line-height);\n letter-spacing: normal;\n}\n\n.fractal-field {\n display: grid;\n align-content: start;\n gap: var(--control-label-gap);\n min-inline-size: 0;\n}\n",".fractal-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n white-space: nowrap;\n font-weight: 400;\n font-family: var(--font-sans);\n text-decoration: none;\n box-sizing: border-box;\n transform: scale(1);\n transition: transform 120ms cubic-bezier(0.16, 1, 0.3, 1);\n}\n\n/* Press: subtle shrink, then expand on release. 120ms / ease-out per motion guide. */\n.fractal-button--primary:active:not(:disabled),\n.fractal-button--secondary:active:not(:disabled),\n.fractal-button--ghost:active:not(:disabled),\n.fractal-button--danger:active:not(:disabled) {\n transform: scale(0.97);\n}\n\n/* Focus ring: 2px --border-focus, 2px offset. Per principles.md Focus section. */\n.fractal-button:focus-visible {\n outline: none;\n box-shadow: 0 0 0 2px var(--bg-canvas, #fff), 0 0 0 4px var(--border-focus, var(--blue-500));\n}\n\n.fractal-button:disabled {\n opacity: 0.5;\n pointer-events: none;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .fractal-button {\n transition-duration: 0.01ms;\n }\n}\n\n.fractal-button { gap: var(--control-icon-gap); }\n.fractal-button svg { inline-size: var(--control-icon-size); block-size: var(--control-icon-size); flex-shrink: 0; }\n.fractal-button[data-icon-only] {\n inline-size: var(--control-min-block-size);\n padding-inline: 0;\n}\n\n.fractal-button--primary:not(:disabled) {\n background-color: var(--button-primary-bg, var(--fg-primary));\n color: var(--button-primary-fg, var(--fg-inverse));\n}\n.fractal-button--primary:not(:disabled):hover {\n background-color: var(--button-primary-hover, var(--fg-secondary));\n}\n.fractal-button--primary:not(:disabled):active {\n background-color: var(--button-primary-active, var(--fg-primary));\n}\n",".fractal-column-editor { position: relative; }\n.fractal-column-editor__panel {\n position: absolute; z-index: 60; top: calc(100% + var(--space-2)); right: 0;\n width: min(440px, calc(100vw - var(--space-7))); box-sizing: border-box;\n padding: var(--space-4); border: 1px solid var(--border-subtle); border-radius: var(--radius-lg);\n background: var(--bg-canvas); box-shadow: var(--shadow-md); max-height: 72dvh; overflow-y: auto;\n font-family: var(--font-sans); font-size: .875rem;\n}\n.fractal-column-editor__panel:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 2px; }\n.fractal-column-editor__list { display: grid; gap: var(--space-2); padding: 0; margin: 0; list-style: none; min-height: var(--space-4); }\n.fractal-column-editor__row {\n display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2);\n border: 1px solid var(--border-subtle); border-radius: var(--radius-md);\n color: var(--fg-primary); background: var(--bg-canvas); cursor: grab;\n user-select: none; touch-action: none;\n transition: background-color var(--duration-fast) var(--ease-out), border-color var(--duration-fast) var(--ease-out);\n}\n.fractal-column-editor__row[data-hidden] { color: var(--fg-disabled); background: var(--bg-surface-1); }\n.fractal-column-editor__row:hover { background: var(--hover-surface); }\n.fractal-column-editor__row[data-dragging] { cursor: grabbing; background: var(--nav-selected); border-color: var(--border-focus); }\n.fractal-column-editor__grip { width: 20px; height: 20px; flex-shrink: 0; color: inherit; pointer-events: none; }\n.fractal-column-editor__name { min-width: 0; pointer-events: none; }\n.fractal-column-editor__actions { display: flex; flex-shrink: 0; margin-left: auto; cursor: default; }\n/* An arrow has its own stronger hover against the hovered row. */\n.fractal-column-editor__actions .fractal-button { cursor: pointer !important; color: var(--fg-secondary); }\n.fractal-column-editor__actions .fractal-button:hover:not(:disabled) { background: var(--bg-surface-2) !important; }\n.fractal-column-editor__actions .fractal-button:disabled { pointer-events: auto; cursor: pointer !important; }\n.fractal-column-editor__divider { display: flex; align-items: center; gap: var(--space-3); margin-block: var(--space-6); color: var(--fg-tertiary); }\n.fractal-column-editor__divider::before, .fractal-column-editor__divider::after { content: ''; flex: 1; border-top: 1px solid var(--border-subtle); }\n.fractal-column-editor__divider > span { display: flex; gap: var(--space-2); align-items: center; white-space: nowrap; }\n.fractal-column-editor__divider svg { width: 20px; height: 20px; }\n.fractal-column-editor__empty { margin: 0; padding-block: var(--space-4); color: var(--fg-tertiary); }\n.fractal-column-editor__announcement { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }\n@media (prefers-reduced-motion: reduce) { .fractal-column-editor__row { transition: none; } }\n\n.fractal-column-editor__panel[data-dragging], .fractal-column-editor__panel[data-dragging] .fractal-column-editor__row { cursor: grabbing; }\n"],"mappings":"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","names":[]}
|