@ai-matrx/design-system 0.86.338 → 0.86.340
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/CHANGELOG.md +29 -1
- package/dist/carousel.js +1 -1
- package/dist/{chunk-T4IJELSS.js → chunk-KYH42WEX.js} +428 -370
- package/dist/chunk-KYH42WEX.js.map +1 -0
- package/dist/content-transfer.css +16 -6
- package/dist/controls.cjs +855 -797
- package/dist/controls.cjs.map +1 -1
- package/dist/controls.css +166 -0
- package/dist/controls.d.cts +49 -1
- package/dist/controls.d.ts +49 -1
- package/dist/controls.js +7 -1
- package/dist/index.cjs +137 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +46 -4
- package/dist/index.d.ts +46 -4
- package/dist/index.js +144 -15
- package/dist/index.js.map +1 -1
- package/dist/tokens.css +17 -0
- package/package.json +2 -2
- package/dist/chunk-T4IJELSS.js.map +0 -1
package/dist/controls.css
CHANGED
|
@@ -2463,3 +2463,169 @@
|
|
|
2463
2463
|
color: var(--mac-label-secondary) !important;
|
|
2464
2464
|
}
|
|
2465
2465
|
}
|
|
2466
|
+
|
|
2467
|
+
/* ── THE WINDOW CHROME (2026-10-23) ───────────────────────────────────────────────────────────
|
|
2468
|
+
`WindowLights` / `WindowLight` / `WindowChromeButton` (controls/window-controls.tsx): a floating
|
|
2469
|
+
window's title bar at macOS's own geometry, never the 28px control (a light drawn as a Button was a
|
|
2470
|
+
28px box with a 16px glyph in a 14px dot). Lights: 12px dots 8px apart, an 8px glyph revealed when
|
|
2471
|
+
the group is hovered or focused, each light's glyph in its own dark shade; disabled is a grey dot;
|
|
2472
|
+
an inactive window's lights are grey until the pointer reaches them. Chrome button: a 20px square,
|
|
2473
|
+
a 14px glyph, quiet until hovered. Colors are the --matrx-window-light-* tokens (tokens.css).
|
|
2474
|
+
Pinned by controls/window-controls-geometry.test.tsx. */
|
|
2475
|
+
@layer matrx-tap-lock {
|
|
2476
|
+
:root {
|
|
2477
|
+
--matrx-window-light-size: 0.75rem; /* 12px — the dot */
|
|
2478
|
+
--matrx-window-light-gap: 0.5rem; /* 8px between dots */
|
|
2479
|
+
--matrx-window-light-glyph-size: 0.5rem; /* 8px — the revealed glyph */
|
|
2480
|
+
--matrx-window-light-touch-size: 1.5rem; /* 24px — the phone header's dot */
|
|
2481
|
+
--matrx-window-light-touch-glyph-size: 0.625rem; /* 10px */
|
|
2482
|
+
--matrx-window-light-touch-gap: 0.75rem; /* 12px — the 44px hit areas barely meet */
|
|
2483
|
+
--matrx-window-chrome-button-size: 1.25rem; /* 20px — a title-bar action */
|
|
2484
|
+
--matrx-window-chrome-glyph: 0.875rem; /* 14px */
|
|
2485
|
+
}
|
|
2486
|
+
.matrx-window-lights {
|
|
2487
|
+
display: inline-flex !important;
|
|
2488
|
+
align-items: center !important;
|
|
2489
|
+
gap: var(--matrx-window-light-gap) !important;
|
|
2490
|
+
flex-shrink: 0 !important;
|
|
2491
|
+
cursor: default;
|
|
2492
|
+
}
|
|
2493
|
+
.matrx-window-light {
|
|
2494
|
+
position: relative;
|
|
2495
|
+
display: inline-flex !important;
|
|
2496
|
+
align-items: center !important;
|
|
2497
|
+
justify-content: center !important;
|
|
2498
|
+
flex-shrink: 0 !important;
|
|
2499
|
+
width: var(--matrx-window-light-size) !important;
|
|
2500
|
+
min-width: var(--matrx-window-light-size) !important;
|
|
2501
|
+
max-width: var(--matrx-window-light-size) !important;
|
|
2502
|
+
height: var(--matrx-window-light-size) !important;
|
|
2503
|
+
min-height: var(--matrx-window-light-size) !important;
|
|
2504
|
+
max-height: var(--matrx-window-light-size) !important;
|
|
2505
|
+
margin: 0 !important;
|
|
2506
|
+
padding: 0 !important;
|
|
2507
|
+
border: 0 !important;
|
|
2508
|
+
border-radius: 9999px !important;
|
|
2509
|
+
box-shadow: inset 0 0 0 0.5px hsl(var(--matrx-window-light-edge)) !important;
|
|
2510
|
+
cursor: pointer;
|
|
2511
|
+
-webkit-tap-highlight-color: transparent;
|
|
2512
|
+
transition: background-color 120ms ease, filter 120ms ease;
|
|
2513
|
+
}
|
|
2514
|
+
/* The hit area spans half the gap on every side, so the row of lights has no dead pixels between dots. */
|
|
2515
|
+
.matrx-window-light::after {
|
|
2516
|
+
content: "";
|
|
2517
|
+
position: absolute;
|
|
2518
|
+
inset: calc(var(--matrx-window-light-gap) / -2);
|
|
2519
|
+
border-radius: 9999px;
|
|
2520
|
+
}
|
|
2521
|
+
.matrx-window-light[data-matrx-window-light="close"] {
|
|
2522
|
+
background-color: hsl(var(--matrx-window-light-close)) !important;
|
|
2523
|
+
color: hsl(var(--matrx-window-light-close-glyph)) !important;
|
|
2524
|
+
}
|
|
2525
|
+
.matrx-window-light[data-matrx-window-light="minimize"] {
|
|
2526
|
+
background-color: hsl(var(--matrx-window-light-minimize)) !important;
|
|
2527
|
+
color: hsl(var(--matrx-window-light-minimize-glyph)) !important;
|
|
2528
|
+
}
|
|
2529
|
+
.matrx-window-light[data-matrx-window-light="maximize"] {
|
|
2530
|
+
background-color: hsl(var(--matrx-window-light-maximize)) !important;
|
|
2531
|
+
color: hsl(var(--matrx-window-light-maximize-glyph)) !important;
|
|
2532
|
+
}
|
|
2533
|
+
.matrx-window-light:active:not(:disabled) {
|
|
2534
|
+
filter: brightness(0.85);
|
|
2535
|
+
}
|
|
2536
|
+
.matrx-window-light svg {
|
|
2537
|
+
width: var(--matrx-window-light-glyph-size) !important;
|
|
2538
|
+
height: var(--matrx-window-light-glyph-size) !important;
|
|
2539
|
+
flex-shrink: 0 !important;
|
|
2540
|
+
stroke-width: 3.5 !important;
|
|
2541
|
+
opacity: 0;
|
|
2542
|
+
transition: opacity 100ms ease;
|
|
2543
|
+
pointer-events: none;
|
|
2544
|
+
}
|
|
2545
|
+
.matrx-window-lights:is(:hover, :focus-within) .matrx-window-light:not(:disabled) svg {
|
|
2546
|
+
opacity: 1;
|
|
2547
|
+
}
|
|
2548
|
+
/* Nothing hovers on touch: the glyphs are always shown. */
|
|
2549
|
+
@media (hover: none) {
|
|
2550
|
+
.matrx-window-light:not(:disabled) svg {
|
|
2551
|
+
opacity: 1;
|
|
2552
|
+
}
|
|
2553
|
+
}
|
|
2554
|
+
.matrx-window-light:focus-visible {
|
|
2555
|
+
outline: 2px solid hsl(var(--ring)) !important;
|
|
2556
|
+
outline-offset: 1px !important;
|
|
2557
|
+
}
|
|
2558
|
+
.matrx-window-light:disabled,
|
|
2559
|
+
.matrx-window-lights[data-inactive]:not(:hover):not(:focus-within) .matrx-window-light {
|
|
2560
|
+
background-color: hsl(var(--matrx-window-light-off)) !important;
|
|
2561
|
+
}
|
|
2562
|
+
.matrx-window-light:disabled {
|
|
2563
|
+
cursor: default;
|
|
2564
|
+
}
|
|
2565
|
+
.matrx-window-light:disabled svg {
|
|
2566
|
+
opacity: 0 !important;
|
|
2567
|
+
}
|
|
2568
|
+
/* The phone header's lights: bigger dots, glyphs always shown, a 44px hit area. */
|
|
2569
|
+
.matrx-window-lights[data-touch] {
|
|
2570
|
+
gap: var(--matrx-window-light-touch-gap) !important;
|
|
2571
|
+
}
|
|
2572
|
+
.matrx-window-lights[data-touch] .matrx-window-light {
|
|
2573
|
+
width: var(--matrx-window-light-touch-size) !important;
|
|
2574
|
+
min-width: var(--matrx-window-light-touch-size) !important;
|
|
2575
|
+
max-width: var(--matrx-window-light-touch-size) !important;
|
|
2576
|
+
height: var(--matrx-window-light-touch-size) !important;
|
|
2577
|
+
min-height: var(--matrx-window-light-touch-size) !important;
|
|
2578
|
+
max-height: var(--matrx-window-light-touch-size) !important;
|
|
2579
|
+
}
|
|
2580
|
+
.matrx-window-lights[data-touch] .matrx-window-light::after {
|
|
2581
|
+
inset: calc((var(--matrx-control-touch) - var(--matrx-window-light-touch-size)) / -2);
|
|
2582
|
+
}
|
|
2583
|
+
.matrx-window-lights[data-touch] .matrx-window-light svg {
|
|
2584
|
+
width: var(--matrx-window-light-touch-glyph-size) !important;
|
|
2585
|
+
height: var(--matrx-window-light-touch-glyph-size) !important;
|
|
2586
|
+
stroke-width: 3 !important;
|
|
2587
|
+
}
|
|
2588
|
+
.matrx-window-lights[data-touch] .matrx-window-light:not(:disabled) svg {
|
|
2589
|
+
opacity: 1;
|
|
2590
|
+
}
|
|
2591
|
+
|
|
2592
|
+
.matrx-window-chrome-button {
|
|
2593
|
+
position: relative;
|
|
2594
|
+
display: inline-flex !important;
|
|
2595
|
+
align-items: center !important;
|
|
2596
|
+
justify-content: center !important;
|
|
2597
|
+
flex-shrink: 0 !important;
|
|
2598
|
+
width: var(--matrx-window-chrome-button-size) !important;
|
|
2599
|
+
min-width: var(--matrx-window-chrome-button-size) !important;
|
|
2600
|
+
max-width: var(--matrx-window-chrome-button-size) !important;
|
|
2601
|
+
height: var(--matrx-window-chrome-button-size) !important;
|
|
2602
|
+
min-height: var(--matrx-window-chrome-button-size) !important;
|
|
2603
|
+
max-height: var(--matrx-window-chrome-button-size) !important;
|
|
2604
|
+
margin: 0 !important;
|
|
2605
|
+
padding: 0 !important;
|
|
2606
|
+
border: 0 !important;
|
|
2607
|
+
border-radius: 0.375rem !important;
|
|
2608
|
+
background-color: transparent !important;
|
|
2609
|
+
color: hsl(var(--muted-foreground)) !important;
|
|
2610
|
+
cursor: pointer;
|
|
2611
|
+
-webkit-tap-highlight-color: transparent;
|
|
2612
|
+
transition: background-color 120ms ease, color 120ms ease;
|
|
2613
|
+
}
|
|
2614
|
+
.matrx-window-chrome-button svg {
|
|
2615
|
+
width: var(--matrx-window-chrome-glyph) !important;
|
|
2616
|
+
height: var(--matrx-window-chrome-glyph) !important;
|
|
2617
|
+
flex-shrink: 0 !important;
|
|
2618
|
+
}
|
|
2619
|
+
.matrx-window-chrome-button:hover:not(:disabled) {
|
|
2620
|
+
background-color: hsl(var(--accent)) !important;
|
|
2621
|
+
color: hsl(var(--foreground)) !important;
|
|
2622
|
+
}
|
|
2623
|
+
.matrx-window-chrome-button:focus-visible {
|
|
2624
|
+
outline: 2px solid hsl(var(--ring)) !important;
|
|
2625
|
+
outline-offset: 1px !important;
|
|
2626
|
+
}
|
|
2627
|
+
.matrx-window-chrome-button:disabled {
|
|
2628
|
+
color: hsl(var(--disabled-foreground)) !important;
|
|
2629
|
+
cursor: default;
|
|
2630
|
+
}
|
|
2631
|
+
}
|
package/dist/controls.d.cts
CHANGED
|
@@ -326,6 +326,54 @@ interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement
|
|
|
326
326
|
*/
|
|
327
327
|
declare const Textarea: React.ForwardRefExoticComponent<TextareaProps & React.RefAttributes<HTMLTextAreaElement>>;
|
|
328
328
|
|
|
329
|
+
/**
|
|
330
|
+
* THE WINDOW CHROME CONTROLS (2026-10-23) — the title bar of a floating window (summon's
|
|
331
|
+
* WindowPanel) drawn at macOS's own geometry, never the 28px control:
|
|
332
|
+
*
|
|
333
|
+
* WindowLights the traffic-light group: 12px dots 8px apart; hovering (or focusing) the
|
|
334
|
+
* group reveals every light's 8px glyph, as macOS does. `inactive` greys the
|
|
335
|
+
* lights of a window that is not in front until the pointer reaches them.
|
|
336
|
+
* `touch` is the phone header's lights: 24px dots, 10px glyphs always shown.
|
|
337
|
+
* WindowLight one light: `kind` close / minimize / maximize picks its color and glyph;
|
|
338
|
+
* `restores` swaps in the restore glyph (a minimized window's yellow, a
|
|
339
|
+
* maximized window's green). Disabled is a grey dot with no glyph.
|
|
340
|
+
* WindowChromeButton a title-bar icon action (the sidebar toggle, pop out): a 20px square with
|
|
341
|
+
* a 14px glyph, quiet until hovered.
|
|
342
|
+
*
|
|
343
|
+
* Geometry and color live in `controls.css` (THE WINDOW CHROME), locked in
|
|
344
|
+
* `@layer matrx-tap-lock` like every control, so `className` places them and never restyles them.
|
|
345
|
+
* Colors are the `--matrx-window-light-*` tokens in `tokens.css` (both themes). The contract is
|
|
346
|
+
* pinned by `window-controls-geometry.test.tsx`: moving a light back onto the 28px Button fails it.
|
|
347
|
+
*/
|
|
348
|
+
|
|
349
|
+
type WindowLightKind = "close" | "minimize" | "maximize";
|
|
350
|
+
interface WindowLightsProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
351
|
+
/** The window is not the one in front: the lights are grey until the pointer reaches them. */
|
|
352
|
+
inactive?: boolean;
|
|
353
|
+
/** The phone header's lights: 24px dots with their glyphs always shown (no hover on touch). */
|
|
354
|
+
touch?: boolean;
|
|
355
|
+
}
|
|
356
|
+
/** The traffic-light group. Its hover (or keyboard focus) reveals every light's glyph. */
|
|
357
|
+
declare const WindowLights: React.ForwardRefExoticComponent<WindowLightsProps & React.RefAttributes<HTMLDivElement>>;
|
|
358
|
+
interface WindowLightProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "children"> {
|
|
359
|
+
/** Which light: close (red), minimize (yellow), maximize (green). */
|
|
360
|
+
kind: WindowLightKind;
|
|
361
|
+
/** The light undoes its window's state (restore a minimized or maximized window): the restore glyph. */
|
|
362
|
+
restores?: boolean;
|
|
363
|
+
/** A light must say what it does. */
|
|
364
|
+
"aria-label": string;
|
|
365
|
+
}
|
|
366
|
+
/** One traffic light. Place it inside `WindowLights`. */
|
|
367
|
+
declare const WindowLight: React.ForwardRefExoticComponent<WindowLightProps & React.RefAttributes<HTMLButtonElement>>;
|
|
368
|
+
interface WindowChromeButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "children"> {
|
|
369
|
+
/** The 14px glyph. */
|
|
370
|
+
icon: React.ReactNode;
|
|
371
|
+
/** A title-bar action must say what it does (also its tooltip unless `title` is given). */
|
|
372
|
+
"aria-label": string;
|
|
373
|
+
}
|
|
374
|
+
/** A title-bar icon action (sidebar toggle, pop out): 20px, quiet until hovered. */
|
|
375
|
+
declare const WindowChromeButton: React.ForwardRefExoticComponent<WindowChromeButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
376
|
+
|
|
329
377
|
/**
|
|
330
378
|
* DecisionControl — THE row decision: [Yes] [No] [Other] + the answer's value chip.
|
|
331
379
|
*
|
|
@@ -2078,4 +2126,4 @@ interface TileCardGridProps {
|
|
|
2078
2126
|
}
|
|
2079
2127
|
declare function TileCardGrid({ title, description, cards, columns, className }: TileCardGridProps): React.JSX.Element;
|
|
2080
2128
|
|
|
2081
|
-
export { ActionFeedbackButton, type ActionFeedbackButtonProps, AdvancedCollapsible, type AdvancedCollapsibleProps, type AnchorRect, AnchoredToolbar, type AnchoredToolbarProps, AspectRatioGlyph, AspectRatioSelect, type AspectRatioSelectProps, Badge, type BadgeProps, type BadgeTone, type BlockingCheck, Button, type ButtonProps$1 as ButtonProps, CHIP_TONES, CONFIGURATION_CHOICE_SIZE, CONTROLS_COLLAPSE_BELOW_REM, CONTROLS_CONTAINER_CLASS, CONTROLS_CONTAINER_NAME, CalloutBanner, type CalloutTone, type CardColor, type CardSize, Chip, type ChipHue, type ChipProps, ChipSet, type ChipSetProps, type ChipTone, CitationChip, type CitationChipProps, CitationPopoverBody, type CitationPopoverBodyProps, ClampedNumberInput, type ClampedNumberInputProps, CollapsibleText, CollapsibleTextGroupControls, type ColorSwatch, ColorSwatchRow, type ColorSwatchRowProps, type ConfigurationColumn, ConfigurationTable, ConfigurationTableRow, ConfigurationValueList, ConfirmDelete, type ConfirmDeleteProps, ControlRow, type ControlRowProps, ControlScope, type ControlVariant, type ControlWidth, DangerZone, DateField, type DateFieldMode, type DateFieldProps, DateTimeField, type DecisionAnswer, DecisionControl, type DecisionControlProps, DeleteButton, type DeleteButtonProps, DisclosureHeader, type DisclosureHeaderProps, type DisclosureHeaderVariant, EmptyState, EmptyStateCard, type EmptyStateCardProps, type EmptyStateProps, Field, FieldHelp, type FieldProps, GatedActionButton, type GatedActionButtonProps, type GlyphTone, HUE_TONE, HelpIcon, type HelpIconProps, HueCard, type HueCardProps, HueGrid, type HueGridProps, HueList, type HueListProps, HueRow, type HueRowProps, IconDropdownMenu, type IconDropdownMenuProps, type IconDropdownOption, IconSelect, type IconSelectItem, type IconSelectProps, type IndicatorItem, IndicatorStrip, type IndicatorStripProps, type IndicatorTone, InfoHint, type InfoHintProps, Input, type InputProps, IosWidget, type IosWidgetProps, KpiGrid, KpiTile, type KpiTileProps, type KpiTone, type KpiTrend, LabeledField, type LabeledFieldProps, LightSwitchToggle, type LightSwitchToggleProps, MiddleTruncate, MissingTag, NumberStepper, type NumberStepperProps, OpacitySlider, type OpacitySliderProps, OptionCombobox, type OptionComboboxGroup, type OptionComboboxProps, PageRangeInput, type PageRangeInputProps, type PageRangeIssue, type PageRangeIssueKind, type ParsedPageRanges, type ParsedRatio, PromoBanner, type PromoBannerProps, type PromoTone, PropertyRow, type PropertyRowProps, type RatioGroups, RegionSkeleton, type RegionSkeletonProps, RowGroup, type RowGroupProps, STATUS_TONES, SearchField, SearchInput, type SearchInputProps, type SegmentOption, SegmentedControl, type SegmentedControlProps, Select, type SelectOption, type SelectProps, SelectTrigger, type SelectTriggerProps, SettingRow, type SettingRowProps, Slider, type SliderProps, SplitButton, type StageState, type StageStep, StageSteps, type StageStepsProps, StatusBadge, type StatusBadgeProps, type StatusBadgeSize, StatusToken, type StatusTone, StructuredSectionCard, type StructuredSectionCardProps, type StructuredSectionCardTitleTone, Switch, type SwitchProps, Tabs, TabsList, type TabsListProps, type TabsProps, TabsTrigger, type TabsVariant, TextArrayInput, type TextArrayInputProps, Textarea, type TextareaProps, Tile, TileCard, TileCardGrid, type TileCardGridProps, type TileCardProps, type TileLayout, type TileProps, TimeField, ToolRail, type ToolRailItem, type ToolRailProps, type WayOutItem, clampDraft, cleanUrl, firstBlockingReason, formatDay, formatPageRanges, formatTime, groupRatioOptions, humanizeRatioWord, indicatorText, isAspectRatioOptionSet, isCollectedValue, parsePageRanges, parseRatio, parseTypedDate, parseTypedTime, ratioShapeName, shownDraft, spansOf, splitForMiddleTruncate, stageStates, valueSummary };
|
|
2129
|
+
export { ActionFeedbackButton, type ActionFeedbackButtonProps, AdvancedCollapsible, type AdvancedCollapsibleProps, type AnchorRect, AnchoredToolbar, type AnchoredToolbarProps, AspectRatioGlyph, AspectRatioSelect, type AspectRatioSelectProps, Badge, type BadgeProps, type BadgeTone, type BlockingCheck, Button, type ButtonProps$1 as ButtonProps, CHIP_TONES, CONFIGURATION_CHOICE_SIZE, CONTROLS_COLLAPSE_BELOW_REM, CONTROLS_CONTAINER_CLASS, CONTROLS_CONTAINER_NAME, CalloutBanner, type CalloutTone, type CardColor, type CardSize, Chip, type ChipHue, type ChipProps, ChipSet, type ChipSetProps, type ChipTone, CitationChip, type CitationChipProps, CitationPopoverBody, type CitationPopoverBodyProps, ClampedNumberInput, type ClampedNumberInputProps, CollapsibleText, CollapsibleTextGroupControls, type ColorSwatch, ColorSwatchRow, type ColorSwatchRowProps, type ConfigurationColumn, ConfigurationTable, ConfigurationTableRow, ConfigurationValueList, ConfirmDelete, type ConfirmDeleteProps, ControlRow, type ControlRowProps, ControlScope, type ControlVariant, type ControlWidth, DangerZone, DateField, type DateFieldMode, type DateFieldProps, DateTimeField, type DecisionAnswer, DecisionControl, type DecisionControlProps, DeleteButton, type DeleteButtonProps, DisclosureHeader, type DisclosureHeaderProps, type DisclosureHeaderVariant, EmptyState, EmptyStateCard, type EmptyStateCardProps, type EmptyStateProps, Field, FieldHelp, type FieldProps, GatedActionButton, type GatedActionButtonProps, type GlyphTone, HUE_TONE, HelpIcon, type HelpIconProps, HueCard, type HueCardProps, HueGrid, type HueGridProps, HueList, type HueListProps, HueRow, type HueRowProps, IconDropdownMenu, type IconDropdownMenuProps, type IconDropdownOption, IconSelect, type IconSelectItem, type IconSelectProps, type IndicatorItem, IndicatorStrip, type IndicatorStripProps, type IndicatorTone, InfoHint, type InfoHintProps, Input, type InputProps, IosWidget, type IosWidgetProps, KpiGrid, KpiTile, type KpiTileProps, type KpiTone, type KpiTrend, LabeledField, type LabeledFieldProps, LightSwitchToggle, type LightSwitchToggleProps, MiddleTruncate, MissingTag, NumberStepper, type NumberStepperProps, OpacitySlider, type OpacitySliderProps, OptionCombobox, type OptionComboboxGroup, type OptionComboboxProps, PageRangeInput, type PageRangeInputProps, type PageRangeIssue, type PageRangeIssueKind, type ParsedPageRanges, type ParsedRatio, PromoBanner, type PromoBannerProps, type PromoTone, PropertyRow, type PropertyRowProps, type RatioGroups, RegionSkeleton, type RegionSkeletonProps, RowGroup, type RowGroupProps, STATUS_TONES, SearchField, SearchInput, type SearchInputProps, type SegmentOption, SegmentedControl, type SegmentedControlProps, Select, type SelectOption, type SelectProps, SelectTrigger, type SelectTriggerProps, SettingRow, type SettingRowProps, Slider, type SliderProps, SplitButton, type StageState, type StageStep, StageSteps, type StageStepsProps, StatusBadge, type StatusBadgeProps, type StatusBadgeSize, StatusToken, type StatusTone, StructuredSectionCard, type StructuredSectionCardProps, type StructuredSectionCardTitleTone, Switch, type SwitchProps, Tabs, TabsList, type TabsListProps, type TabsProps, TabsTrigger, type TabsVariant, TextArrayInput, type TextArrayInputProps, Textarea, type TextareaProps, Tile, TileCard, TileCardGrid, type TileCardGridProps, type TileCardProps, type TileLayout, type TileProps, TimeField, ToolRail, type ToolRailItem, type ToolRailProps, type WayOutItem, WindowChromeButton, type WindowChromeButtonProps, WindowLight, type WindowLightKind, type WindowLightProps, WindowLights, type WindowLightsProps, clampDraft, cleanUrl, firstBlockingReason, formatDay, formatPageRanges, formatTime, groupRatioOptions, humanizeRatioWord, indicatorText, isAspectRatioOptionSet, isCollectedValue, parsePageRanges, parseRatio, parseTypedDate, parseTypedTime, ratioShapeName, shownDraft, spansOf, splitForMiddleTruncate, stageStates, valueSummary };
|
package/dist/controls.d.ts
CHANGED
|
@@ -326,6 +326,54 @@ interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement
|
|
|
326
326
|
*/
|
|
327
327
|
declare const Textarea: React.ForwardRefExoticComponent<TextareaProps & React.RefAttributes<HTMLTextAreaElement>>;
|
|
328
328
|
|
|
329
|
+
/**
|
|
330
|
+
* THE WINDOW CHROME CONTROLS (2026-10-23) — the title bar of a floating window (summon's
|
|
331
|
+
* WindowPanel) drawn at macOS's own geometry, never the 28px control:
|
|
332
|
+
*
|
|
333
|
+
* WindowLights the traffic-light group: 12px dots 8px apart; hovering (or focusing) the
|
|
334
|
+
* group reveals every light's 8px glyph, as macOS does. `inactive` greys the
|
|
335
|
+
* lights of a window that is not in front until the pointer reaches them.
|
|
336
|
+
* `touch` is the phone header's lights: 24px dots, 10px glyphs always shown.
|
|
337
|
+
* WindowLight one light: `kind` close / minimize / maximize picks its color and glyph;
|
|
338
|
+
* `restores` swaps in the restore glyph (a minimized window's yellow, a
|
|
339
|
+
* maximized window's green). Disabled is a grey dot with no glyph.
|
|
340
|
+
* WindowChromeButton a title-bar icon action (the sidebar toggle, pop out): a 20px square with
|
|
341
|
+
* a 14px glyph, quiet until hovered.
|
|
342
|
+
*
|
|
343
|
+
* Geometry and color live in `controls.css` (THE WINDOW CHROME), locked in
|
|
344
|
+
* `@layer matrx-tap-lock` like every control, so `className` places them and never restyles them.
|
|
345
|
+
* Colors are the `--matrx-window-light-*` tokens in `tokens.css` (both themes). The contract is
|
|
346
|
+
* pinned by `window-controls-geometry.test.tsx`: moving a light back onto the 28px Button fails it.
|
|
347
|
+
*/
|
|
348
|
+
|
|
349
|
+
type WindowLightKind = "close" | "minimize" | "maximize";
|
|
350
|
+
interface WindowLightsProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
351
|
+
/** The window is not the one in front: the lights are grey until the pointer reaches them. */
|
|
352
|
+
inactive?: boolean;
|
|
353
|
+
/** The phone header's lights: 24px dots with their glyphs always shown (no hover on touch). */
|
|
354
|
+
touch?: boolean;
|
|
355
|
+
}
|
|
356
|
+
/** The traffic-light group. Its hover (or keyboard focus) reveals every light's glyph. */
|
|
357
|
+
declare const WindowLights: React.ForwardRefExoticComponent<WindowLightsProps & React.RefAttributes<HTMLDivElement>>;
|
|
358
|
+
interface WindowLightProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "children"> {
|
|
359
|
+
/** Which light: close (red), minimize (yellow), maximize (green). */
|
|
360
|
+
kind: WindowLightKind;
|
|
361
|
+
/** The light undoes its window's state (restore a minimized or maximized window): the restore glyph. */
|
|
362
|
+
restores?: boolean;
|
|
363
|
+
/** A light must say what it does. */
|
|
364
|
+
"aria-label": string;
|
|
365
|
+
}
|
|
366
|
+
/** One traffic light. Place it inside `WindowLights`. */
|
|
367
|
+
declare const WindowLight: React.ForwardRefExoticComponent<WindowLightProps & React.RefAttributes<HTMLButtonElement>>;
|
|
368
|
+
interface WindowChromeButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "children"> {
|
|
369
|
+
/** The 14px glyph. */
|
|
370
|
+
icon: React.ReactNode;
|
|
371
|
+
/** A title-bar action must say what it does (also its tooltip unless `title` is given). */
|
|
372
|
+
"aria-label": string;
|
|
373
|
+
}
|
|
374
|
+
/** A title-bar icon action (sidebar toggle, pop out): 20px, quiet until hovered. */
|
|
375
|
+
declare const WindowChromeButton: React.ForwardRefExoticComponent<WindowChromeButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
376
|
+
|
|
329
377
|
/**
|
|
330
378
|
* DecisionControl — THE row decision: [Yes] [No] [Other] + the answer's value chip.
|
|
331
379
|
*
|
|
@@ -2078,4 +2126,4 @@ interface TileCardGridProps {
|
|
|
2078
2126
|
}
|
|
2079
2127
|
declare function TileCardGrid({ title, description, cards, columns, className }: TileCardGridProps): React.JSX.Element;
|
|
2080
2128
|
|
|
2081
|
-
export { ActionFeedbackButton, type ActionFeedbackButtonProps, AdvancedCollapsible, type AdvancedCollapsibleProps, type AnchorRect, AnchoredToolbar, type AnchoredToolbarProps, AspectRatioGlyph, AspectRatioSelect, type AspectRatioSelectProps, Badge, type BadgeProps, type BadgeTone, type BlockingCheck, Button, type ButtonProps$1 as ButtonProps, CHIP_TONES, CONFIGURATION_CHOICE_SIZE, CONTROLS_COLLAPSE_BELOW_REM, CONTROLS_CONTAINER_CLASS, CONTROLS_CONTAINER_NAME, CalloutBanner, type CalloutTone, type CardColor, type CardSize, Chip, type ChipHue, type ChipProps, ChipSet, type ChipSetProps, type ChipTone, CitationChip, type CitationChipProps, CitationPopoverBody, type CitationPopoverBodyProps, ClampedNumberInput, type ClampedNumberInputProps, CollapsibleText, CollapsibleTextGroupControls, type ColorSwatch, ColorSwatchRow, type ColorSwatchRowProps, type ConfigurationColumn, ConfigurationTable, ConfigurationTableRow, ConfigurationValueList, ConfirmDelete, type ConfirmDeleteProps, ControlRow, type ControlRowProps, ControlScope, type ControlVariant, type ControlWidth, DangerZone, DateField, type DateFieldMode, type DateFieldProps, DateTimeField, type DecisionAnswer, DecisionControl, type DecisionControlProps, DeleteButton, type DeleteButtonProps, DisclosureHeader, type DisclosureHeaderProps, type DisclosureHeaderVariant, EmptyState, EmptyStateCard, type EmptyStateCardProps, type EmptyStateProps, Field, FieldHelp, type FieldProps, GatedActionButton, type GatedActionButtonProps, type GlyphTone, HUE_TONE, HelpIcon, type HelpIconProps, HueCard, type HueCardProps, HueGrid, type HueGridProps, HueList, type HueListProps, HueRow, type HueRowProps, IconDropdownMenu, type IconDropdownMenuProps, type IconDropdownOption, IconSelect, type IconSelectItem, type IconSelectProps, type IndicatorItem, IndicatorStrip, type IndicatorStripProps, type IndicatorTone, InfoHint, type InfoHintProps, Input, type InputProps, IosWidget, type IosWidgetProps, KpiGrid, KpiTile, type KpiTileProps, type KpiTone, type KpiTrend, LabeledField, type LabeledFieldProps, LightSwitchToggle, type LightSwitchToggleProps, MiddleTruncate, MissingTag, NumberStepper, type NumberStepperProps, OpacitySlider, type OpacitySliderProps, OptionCombobox, type OptionComboboxGroup, type OptionComboboxProps, PageRangeInput, type PageRangeInputProps, type PageRangeIssue, type PageRangeIssueKind, type ParsedPageRanges, type ParsedRatio, PromoBanner, type PromoBannerProps, type PromoTone, PropertyRow, type PropertyRowProps, type RatioGroups, RegionSkeleton, type RegionSkeletonProps, RowGroup, type RowGroupProps, STATUS_TONES, SearchField, SearchInput, type SearchInputProps, type SegmentOption, SegmentedControl, type SegmentedControlProps, Select, type SelectOption, type SelectProps, SelectTrigger, type SelectTriggerProps, SettingRow, type SettingRowProps, Slider, type SliderProps, SplitButton, type StageState, type StageStep, StageSteps, type StageStepsProps, StatusBadge, type StatusBadgeProps, type StatusBadgeSize, StatusToken, type StatusTone, StructuredSectionCard, type StructuredSectionCardProps, type StructuredSectionCardTitleTone, Switch, type SwitchProps, Tabs, TabsList, type TabsListProps, type TabsProps, TabsTrigger, type TabsVariant, TextArrayInput, type TextArrayInputProps, Textarea, type TextareaProps, Tile, TileCard, TileCardGrid, type TileCardGridProps, type TileCardProps, type TileLayout, type TileProps, TimeField, ToolRail, type ToolRailItem, type ToolRailProps, type WayOutItem, clampDraft, cleanUrl, firstBlockingReason, formatDay, formatPageRanges, formatTime, groupRatioOptions, humanizeRatioWord, indicatorText, isAspectRatioOptionSet, isCollectedValue, parsePageRanges, parseRatio, parseTypedDate, parseTypedTime, ratioShapeName, shownDraft, spansOf, splitForMiddleTruncate, stageStates, valueSummary };
|
|
2129
|
+
export { ActionFeedbackButton, type ActionFeedbackButtonProps, AdvancedCollapsible, type AdvancedCollapsibleProps, type AnchorRect, AnchoredToolbar, type AnchoredToolbarProps, AspectRatioGlyph, AspectRatioSelect, type AspectRatioSelectProps, Badge, type BadgeProps, type BadgeTone, type BlockingCheck, Button, type ButtonProps$1 as ButtonProps, CHIP_TONES, CONFIGURATION_CHOICE_SIZE, CONTROLS_COLLAPSE_BELOW_REM, CONTROLS_CONTAINER_CLASS, CONTROLS_CONTAINER_NAME, CalloutBanner, type CalloutTone, type CardColor, type CardSize, Chip, type ChipHue, type ChipProps, ChipSet, type ChipSetProps, type ChipTone, CitationChip, type CitationChipProps, CitationPopoverBody, type CitationPopoverBodyProps, ClampedNumberInput, type ClampedNumberInputProps, CollapsibleText, CollapsibleTextGroupControls, type ColorSwatch, ColorSwatchRow, type ColorSwatchRowProps, type ConfigurationColumn, ConfigurationTable, ConfigurationTableRow, ConfigurationValueList, ConfirmDelete, type ConfirmDeleteProps, ControlRow, type ControlRowProps, ControlScope, type ControlVariant, type ControlWidth, DangerZone, DateField, type DateFieldMode, type DateFieldProps, DateTimeField, type DecisionAnswer, DecisionControl, type DecisionControlProps, DeleteButton, type DeleteButtonProps, DisclosureHeader, type DisclosureHeaderProps, type DisclosureHeaderVariant, EmptyState, EmptyStateCard, type EmptyStateCardProps, type EmptyStateProps, Field, FieldHelp, type FieldProps, GatedActionButton, type GatedActionButtonProps, type GlyphTone, HUE_TONE, HelpIcon, type HelpIconProps, HueCard, type HueCardProps, HueGrid, type HueGridProps, HueList, type HueListProps, HueRow, type HueRowProps, IconDropdownMenu, type IconDropdownMenuProps, type IconDropdownOption, IconSelect, type IconSelectItem, type IconSelectProps, type IndicatorItem, IndicatorStrip, type IndicatorStripProps, type IndicatorTone, InfoHint, type InfoHintProps, Input, type InputProps, IosWidget, type IosWidgetProps, KpiGrid, KpiTile, type KpiTileProps, type KpiTone, type KpiTrend, LabeledField, type LabeledFieldProps, LightSwitchToggle, type LightSwitchToggleProps, MiddleTruncate, MissingTag, NumberStepper, type NumberStepperProps, OpacitySlider, type OpacitySliderProps, OptionCombobox, type OptionComboboxGroup, type OptionComboboxProps, PageRangeInput, type PageRangeInputProps, type PageRangeIssue, type PageRangeIssueKind, type ParsedPageRanges, type ParsedRatio, PromoBanner, type PromoBannerProps, type PromoTone, PropertyRow, type PropertyRowProps, type RatioGroups, RegionSkeleton, type RegionSkeletonProps, RowGroup, type RowGroupProps, STATUS_TONES, SearchField, SearchInput, type SearchInputProps, type SegmentOption, SegmentedControl, type SegmentedControlProps, Select, type SelectOption, type SelectProps, SelectTrigger, type SelectTriggerProps, SettingRow, type SettingRowProps, Slider, type SliderProps, SplitButton, type StageState, type StageStep, StageSteps, type StageStepsProps, StatusBadge, type StatusBadgeProps, type StatusBadgeSize, StatusToken, type StatusTone, StructuredSectionCard, type StructuredSectionCardProps, type StructuredSectionCardTitleTone, Switch, type SwitchProps, Tabs, TabsList, type TabsListProps, type TabsProps, TabsTrigger, type TabsVariant, TextArrayInput, type TextArrayInputProps, Textarea, type TextareaProps, Tile, TileCard, TileCardGrid, type TileCardGridProps, type TileCardProps, type TileLayout, type TileProps, TimeField, ToolRail, type ToolRailItem, type ToolRailProps, type WayOutItem, WindowChromeButton, type WindowChromeButtonProps, WindowLight, type WindowLightKind, type WindowLightProps, WindowLights, type WindowLightsProps, clampDraft, cleanUrl, firstBlockingReason, formatDay, formatPageRanges, formatTime, groupRatioOptions, humanizeRatioWord, indicatorText, isAspectRatioOptionSet, isCollectedValue, parsePageRanges, parseRatio, parseTypedDate, parseTypedTime, ratioShapeName, shownDraft, spansOf, splitForMiddleTruncate, stageStates, valueSummary };
|
package/dist/controls.js
CHANGED
|
@@ -47,6 +47,9 @@ import {
|
|
|
47
47
|
TileCardGrid,
|
|
48
48
|
TimeField,
|
|
49
49
|
ToolRail,
|
|
50
|
+
WindowChromeButton,
|
|
51
|
+
WindowLight,
|
|
52
|
+
WindowLights,
|
|
50
53
|
clampDraft,
|
|
51
54
|
cleanUrl,
|
|
52
55
|
firstBlockingReason,
|
|
@@ -66,7 +69,7 @@ import {
|
|
|
66
69
|
spansOf,
|
|
67
70
|
splitForMiddleTruncate,
|
|
68
71
|
stageStates
|
|
69
|
-
} from "./chunk-
|
|
72
|
+
} from "./chunk-KYH42WEX.js";
|
|
70
73
|
import "./chunk-6NOLVA4E.js";
|
|
71
74
|
import {
|
|
72
75
|
Input,
|
|
@@ -239,6 +242,9 @@ export {
|
|
|
239
242
|
TileCardGrid,
|
|
240
243
|
TimeField,
|
|
241
244
|
ToolRail,
|
|
245
|
+
WindowChromeButton,
|
|
246
|
+
WindowLight,
|
|
247
|
+
WindowLights,
|
|
242
248
|
clampDraft,
|
|
243
249
|
cleanUrl,
|
|
244
250
|
firstBlockingReason,
|
package/dist/index.cjs
CHANGED
|
@@ -4272,6 +4272,7 @@ __export(src_exports, {
|
|
|
4272
4272
|
ArchivedDisclosure: () => ArchivedDisclosure,
|
|
4273
4273
|
AssistPeekCard: () => AssistPeekCard,
|
|
4274
4274
|
AssistPeekHover: () => AssistPeekHover,
|
|
4275
|
+
AssistTray: () => AssistTray,
|
|
4275
4276
|
AuthGateDialog: () => AuthGateDialog2,
|
|
4276
4277
|
Avatar: () => Avatar,
|
|
4277
4278
|
AvatarFallback: () => AvatarFallback,
|
|
@@ -13315,7 +13316,7 @@ function MenuDoor({ action, menu, disabled }) {
|
|
|
13315
13316
|
variant: "quiet",
|
|
13316
13317
|
"aria-label": action.label,
|
|
13317
13318
|
title: action.label,
|
|
13318
|
-
icon: action.busy ? /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Loader2Icon, { className: "
|
|
13319
|
+
icon: action.busy ? /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Loader2Icon, { className: "matrx-spin" }) : glyph,
|
|
13319
13320
|
className: "shrink-0",
|
|
13320
13321
|
disabled: disabled || action.busy,
|
|
13321
13322
|
onClick: (event) => event.stopPropagation()
|
|
@@ -13544,7 +13545,7 @@ function PeekCardFooter({ primary, primaryAt, onSettings, doors = [], copy, open
|
|
|
13544
13545
|
style: fills ? { minWidth: PEEK_PRIMARY_MIN_PX[sheet ? "sheet" : "card"] } : void 0,
|
|
13545
13546
|
disabled: loading || primary.disabled || primary.busy,
|
|
13546
13547
|
title: primary.title,
|
|
13547
|
-
icon: primary.busy ? /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Loader2Icon, { className: "
|
|
13548
|
+
icon: primary.busy ? /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(Loader2Icon, { className: "matrx-spin" }) : void 0,
|
|
13548
13549
|
onClick: primary.onClick,
|
|
13549
13550
|
children: primary.label
|
|
13550
13551
|
}
|
|
@@ -14447,7 +14448,7 @@ function ValueShell({ kind, glyph: Glyph, text, copy, state, record, peek, wrap
|
|
|
14447
14448
|
const off = state !== "ok";
|
|
14448
14449
|
const value = /* @__PURE__ */ (0, import_jsx_runtime92.jsx)("span", { className: cn("min-w-0", wrap ? "whitespace-pre-line break-words" : "truncate", off ? "text-muted-foreground line-through" : "text-foreground"), children: text });
|
|
14449
14450
|
const body = /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)(import_jsx_runtime92.Fragment, { children: [
|
|
14450
|
-
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)(Glyph, { className:
|
|
14451
|
+
Glyph ? /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(Glyph, { className: "size-[1em] shrink-0 text-muted-foreground" }) : null,
|
|
14451
14452
|
value,
|
|
14452
14453
|
off ? /* @__PURE__ */ (0, import_jsx_runtime92.jsx)("span", { className: "shrink-0 text-muted-foreground no-underline", children: `\xB7 ${CONTACT_STATE_LABEL[state]}` }) : null
|
|
14453
14454
|
] });
|
|
@@ -14648,7 +14649,7 @@ function SocialHandleValue(props) {
|
|
|
14648
14649
|
}
|
|
14649
14650
|
);
|
|
14650
14651
|
}
|
|
14651
|
-
function UrlValue({ url, title, owner, state = "ok", peek = true }) {
|
|
14652
|
+
function UrlValue({ url, title, owner, state = "ok", peek = true, icon = true }) {
|
|
14652
14653
|
const parsed = parseUrl(url);
|
|
14653
14654
|
const ok = state === "ok" && Boolean(parsed.href);
|
|
14654
14655
|
const record = {
|
|
@@ -14668,9 +14669,9 @@ function UrlValue({ url, title, owner, state = "ok", peek = true }) {
|
|
|
14668
14669
|
...ok ? { primary: { label: "Open", onSelect: () => (0, import_outbound2.openOutbound)(parsed.href) } } : {},
|
|
14669
14670
|
copyData: { url: parsed.href ?? url, domain: parsed.domain, ...title ? { title } : {} }
|
|
14670
14671
|
};
|
|
14671
|
-
return /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(ValueShell, { kind: "link", glyph: GlobeIcon, text: parsed.display, copy: parsed.href ?? url, state, record, peek });
|
|
14672
|
+
return /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(ValueShell, { kind: "link", ...icon ? { glyph: GlobeIcon } : {}, text: parsed.display, copy: parsed.href ?? url, state, record, peek });
|
|
14672
14673
|
}
|
|
14673
|
-
function ContactValue({ type, value, platform, followers, title, ...common }) {
|
|
14674
|
+
function ContactValue({ type, value, platform, followers, title, icon, ...common }) {
|
|
14674
14675
|
switch (type) {
|
|
14675
14676
|
case "email":
|
|
14676
14677
|
return /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(EmailValue, { email: value, ...common });
|
|
@@ -14681,7 +14682,7 @@ function ContactValue({ type, value, platform, followers, title, ...common }) {
|
|
|
14681
14682
|
case "social":
|
|
14682
14683
|
return /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(SocialHandleValue, { value, ...platform !== void 0 ? { platform } : {}, ...followers !== void 0 ? { followers } : {}, ...common });
|
|
14683
14684
|
case "url":
|
|
14684
|
-
return /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(UrlValue, { url: value, ...title !== void 0 ? { title } : {}, ...common });
|
|
14685
|
+
return /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(UrlValue, { url: value, ...title !== void 0 ? { title } : {}, ...icon !== void 0 ? { icon } : {}, ...common });
|
|
14685
14686
|
}
|
|
14686
14687
|
}
|
|
14687
14688
|
|
|
@@ -14871,6 +14872,7 @@ var React64 = __toESM(require("react"), 1);
|
|
|
14871
14872
|
var import_react_slot7 = require("@radix-ui/react-slot");
|
|
14872
14873
|
init_controls();
|
|
14873
14874
|
init_icons();
|
|
14875
|
+
init_dropdown_menu();
|
|
14874
14876
|
init_use_is_mobile();
|
|
14875
14877
|
var import_jsx_runtime95 = require("react/jsx-runtime");
|
|
14876
14878
|
function AssistPeekCard({
|
|
@@ -14887,8 +14889,10 @@ function AssistPeekCard({
|
|
|
14887
14889
|
stopShowing,
|
|
14888
14890
|
deciding = false,
|
|
14889
14891
|
onNotNow,
|
|
14892
|
+
closeAs = "not-now",
|
|
14890
14893
|
step
|
|
14891
14894
|
}) {
|
|
14895
|
+
const closeLabel = closeAs === "dismiss" ? "Dismiss" : "Not now";
|
|
14892
14896
|
const laterDoor = later?.length ? { kind: "action", id: "later", label: "Later", icon: ClockIcon, menu: later, busy: deciding } : null;
|
|
14893
14897
|
const stopDoor = stopShowing?.length ? { kind: "action", id: "stop", label: "Stop showing", icon: BellOffIcon, menu: stopShowing, busy: deciding } : null;
|
|
14894
14898
|
const doors = laterDoor && stopDoor ? [laterDoor, stopDoor] : laterDoor ? [laterDoor] : stopDoor ? [stopDoor] : [];
|
|
@@ -14899,7 +14903,7 @@ function AssistPeekCard({
|
|
|
14899
14903
|
title,
|
|
14900
14904
|
leading: Icon3 ? /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(Icon3, {}) : void 0,
|
|
14901
14905
|
subtitle,
|
|
14902
|
-
trailing: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(Button2, { type: "button", variant: "quiet", "aria-label":
|
|
14906
|
+
trailing: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(Button2, { type: "button", variant: "quiet", "aria-label": closeLabel, title: closeLabel, icon: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(XIcon, {}), disabled: Boolean(primary.busy) || deciding, onClick: onNotNow })
|
|
14903
14907
|
}
|
|
14904
14908
|
),
|
|
14905
14909
|
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)(PeekCardBody, { children: [
|
|
@@ -15000,6 +15004,131 @@ function AssistPeekHover({ trigger, label, side = "top", align = "end", presenta
|
|
|
15000
15004
|
}
|
|
15001
15005
|
);
|
|
15002
15006
|
}
|
|
15007
|
+
var TRAY_CLOSE_MS = 300;
|
|
15008
|
+
var TRAY_OPEN_MS = 500;
|
|
15009
|
+
function AssistTray({ count, children, quickQuiet, menu, allAssists, onHandlePointerDown, reminderAttributes, open: openProp, onOpenChange }) {
|
|
15010
|
+
const [hovered, setHovered] = React64.useState(false);
|
|
15011
|
+
const [keptOwn, setKept] = React64.useState(false);
|
|
15012
|
+
const kept = openProp ?? keptOwn;
|
|
15013
|
+
const open = kept || hovered;
|
|
15014
|
+
const box = React64.useRef(null);
|
|
15015
|
+
const timer = React64.useRef(null);
|
|
15016
|
+
const clear = () => {
|
|
15017
|
+
if (timer.current) clearTimeout(timer.current);
|
|
15018
|
+
timer.current = null;
|
|
15019
|
+
};
|
|
15020
|
+
React64.useEffect(() => clear, []);
|
|
15021
|
+
const setKeep = React64.useCallback(
|
|
15022
|
+
(next) => {
|
|
15023
|
+
setKept(next);
|
|
15024
|
+
onOpenChange?.(next);
|
|
15025
|
+
if (!next) setHovered(false);
|
|
15026
|
+
},
|
|
15027
|
+
[onOpenChange]
|
|
15028
|
+
);
|
|
15029
|
+
const enter = () => {
|
|
15030
|
+
clear();
|
|
15031
|
+
if (!open) timer.current = setTimeout(() => setHovered(true), TRAY_OPEN_MS);
|
|
15032
|
+
};
|
|
15033
|
+
const leave = () => {
|
|
15034
|
+
clear();
|
|
15035
|
+
timer.current = setTimeout(() => {
|
|
15036
|
+
if (document.querySelector("[data-radix-menu-content]")) return;
|
|
15037
|
+
setHovered(false);
|
|
15038
|
+
}, TRAY_CLOSE_MS);
|
|
15039
|
+
};
|
|
15040
|
+
React64.useEffect(() => {
|
|
15041
|
+
if (!kept) return;
|
|
15042
|
+
const onPress = (event) => {
|
|
15043
|
+
if (box.current?.contains(event.target) || inCardMenu(event.target)) return;
|
|
15044
|
+
setKeep(false);
|
|
15045
|
+
};
|
|
15046
|
+
const onKey = (event) => {
|
|
15047
|
+
if (event.key !== "Escape" || document.querySelector("[data-radix-menu-content]")) return;
|
|
15048
|
+
setKeep(false);
|
|
15049
|
+
};
|
|
15050
|
+
document.addEventListener("pointerdown", onPress, true);
|
|
15051
|
+
document.addEventListener("keydown", onKey);
|
|
15052
|
+
return () => {
|
|
15053
|
+
document.removeEventListener("pointerdown", onPress, true);
|
|
15054
|
+
document.removeEventListener("keydown", onKey);
|
|
15055
|
+
};
|
|
15056
|
+
}, [kept, setKeep]);
|
|
15057
|
+
if (count <= 0) return null;
|
|
15058
|
+
const label = `${count} assist${count === 1 ? "" : "s"}`;
|
|
15059
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)(
|
|
15060
|
+
"div",
|
|
15061
|
+
{
|
|
15062
|
+
ref: box,
|
|
15063
|
+
"data-matrx-assist-tray": "",
|
|
15064
|
+
"data-open": open ? "" : void 0,
|
|
15065
|
+
className: "pointer-events-none flex flex-col items-end gap-2 [:root[data-assist-dock-slot=header]_&]:flex-col-reverse",
|
|
15066
|
+
onMouseEnter: enter,
|
|
15067
|
+
onMouseLeave: leave,
|
|
15068
|
+
onPointerDownCapture: (event) => {
|
|
15069
|
+
if (event.target.closest("[data-matrx-assist-peek]")) setKeep(true);
|
|
15070
|
+
},
|
|
15071
|
+
children: [
|
|
15072
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("div", { "data-matrx-assist-tray-stack": "", className: "matrx-peek-scroll pointer-events-auto flex max-h-[min(70dvh,640px)] flex-col items-end gap-2 overflow-y-auto", children: [
|
|
15073
|
+
React64.Children.map(children, (child) => child ? /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("div", { className: "shrink-0", children: child }) : null),
|
|
15074
|
+
allAssists || menu?.length ? /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("div", { className: "flex shrink-0 items-center rounded-md border border-border bg-popover shadow-md", children: [
|
|
15075
|
+
allAssists,
|
|
15076
|
+
menu?.length ? /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(TrayMenu, { menu }) : null
|
|
15077
|
+
] }) : null
|
|
15078
|
+
] }) : null,
|
|
15079
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)(
|
|
15080
|
+
"div",
|
|
15081
|
+
{
|
|
15082
|
+
"data-matrx-assist-tray-reminder": "",
|
|
15083
|
+
...reminderAttributes,
|
|
15084
|
+
className: "group pointer-events-auto flex items-center rounded-md border border-border bg-popover shadow-md transition-opacity data-[assist-dock-pending]:invisible data-[assist-dock-yield]:pointer-events-none data-[assist-dock-yield]:opacity-30",
|
|
15085
|
+
onPointerDown: onHandlePointerDown,
|
|
15086
|
+
children: [
|
|
15087
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
15088
|
+
Button2,
|
|
15089
|
+
{
|
|
15090
|
+
type: "button",
|
|
15091
|
+
variant: "quiet",
|
|
15092
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(LightbulbIcon, {}),
|
|
15093
|
+
glyphTone: "primary",
|
|
15094
|
+
"aria-label": open ? `Hide ${label}` : `Show ${label}`,
|
|
15095
|
+
"aria-expanded": open,
|
|
15096
|
+
title: label,
|
|
15097
|
+
onClick: () => setKeep(!kept),
|
|
15098
|
+
children: String(count)
|
|
15099
|
+
}
|
|
15100
|
+
),
|
|
15101
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)(
|
|
15102
|
+
Button2,
|
|
15103
|
+
{
|
|
15104
|
+
type: "button",
|
|
15105
|
+
variant: "quiet",
|
|
15106
|
+
removes: true,
|
|
15107
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(XIcon, {}),
|
|
15108
|
+
"aria-label": quickQuiet.label,
|
|
15109
|
+
title: quickQuiet.label,
|
|
15110
|
+
onClick: () => {
|
|
15111
|
+
setKeep(false);
|
|
15112
|
+
quickQuiet.onQuiet();
|
|
15113
|
+
}
|
|
15114
|
+
}
|
|
15115
|
+
)
|
|
15116
|
+
]
|
|
15117
|
+
}
|
|
15118
|
+
)
|
|
15119
|
+
]
|
|
15120
|
+
}
|
|
15121
|
+
);
|
|
15122
|
+
}
|
|
15123
|
+
function TrayMenu({ menu }) {
|
|
15124
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)(DropdownMenu, { modal: false, children: [
|
|
15125
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(Button2, { type: "button", variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(BellOffIcon, {}), children: "Quiet" }) }),
|
|
15126
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)(DropdownMenuContent, { align: "end", children: menu.map((group, i) => /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)(React64.Fragment, { children: [
|
|
15127
|
+
group.label ? /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(DropdownMenuLabel, { children: group.label }) : null,
|
|
15128
|
+
group.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(DropdownMenuItem, { ...item.tone ? { tone: item.tone } : {}, onSelect: () => item.onSelect(), children: item.label }, item.key))
|
|
15129
|
+
] }, `${group.label ?? ""}-${i}`)) })
|
|
15130
|
+
] });
|
|
15131
|
+
}
|
|
15003
15132
|
|
|
15004
15133
|
// src/radio-group.tsx
|
|
15005
15134
|
var RadioGroupPrimitive = __toESM(require("@radix-ui/react-radio-group"), 1);
|