@skyvexsoftware/stratos-sdk 0.16.2 → 0.16.5
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/dist/hooks/useTrackingSession.d.ts +7 -0
- package/dist/hooks/useTrackingSession.js +2 -0
- package/dist/shared-types/flight-manager.d.ts +7 -0
- package/dist/ui/card.d.ts +4 -1
- package/dist/ui/card.js +2 -2
- package/dist/ui/combobox.d.ts +13 -1
- package/dist/ui/combobox.js +23 -5
- package/dist/ui/slider.js +16 -1
- package/dist/ui/switch.d.ts +5 -6
- package/dist/ui/switch.js +1 -1
- package/package.json +1 -1
|
@@ -27,6 +27,13 @@ type UseTrackingSessionReturn = {
|
|
|
27
27
|
reconnecting: boolean;
|
|
28
28
|
/** Reason tracking is suspended; null when not suspended. */
|
|
29
29
|
suspendReason: string | null;
|
|
30
|
+
/**
|
|
31
|
+
* Why auto-start has not started a flight yet, as a sentence fragment
|
|
32
|
+
* ("the aircraft is 260 nm from CYUL, the nearest booked departure"); null
|
|
33
|
+
* when auto-start is off, not polling, a flight is active, or the shell
|
|
34
|
+
* predates core 2.32.17.
|
|
35
|
+
*/
|
|
36
|
+
autoStartWaitReason: string | null;
|
|
30
37
|
currentFlight: CurrentFlight | null;
|
|
31
38
|
pendingRecovery: RecoverableFlight | null;
|
|
32
39
|
elapsedTime: number;
|
|
@@ -75,6 +75,7 @@ export function useTrackingSession() {
|
|
|
75
75
|
const simDisconnected = stateData?.simDisconnected ?? false;
|
|
76
76
|
const reconnecting = stateData?.reconnecting ?? false;
|
|
77
77
|
const suspendReason = stateData?.suspendReason ?? null;
|
|
78
|
+
const autoStartWaitReason = stateData?.autoStartWaitReason ?? null;
|
|
78
79
|
const startFlight = useCallback(async (plan, options) => {
|
|
79
80
|
const result = await api("/start", "POST", { flightPlan: plan, options });
|
|
80
81
|
return result.data;
|
|
@@ -158,6 +159,7 @@ export function useTrackingSession() {
|
|
|
158
159
|
simDisconnected,
|
|
159
160
|
reconnecting,
|
|
160
161
|
suspendReason,
|
|
162
|
+
autoStartWaitReason,
|
|
161
163
|
currentFlight: flight,
|
|
162
164
|
pendingRecovery,
|
|
163
165
|
elapsedTime,
|
|
@@ -134,6 +134,13 @@ export type FlightManagerPayload = {
|
|
|
134
134
|
reconnecting: boolean;
|
|
135
135
|
/** Why tracking is suspended (continuity gate asserted a discontinuity), or null. Present whenever `simDisconnected` is true. */
|
|
136
136
|
suspendReason?: string | null;
|
|
137
|
+
/**
|
|
138
|
+
* Why auto-start has not started a flight yet, as a sentence fragment
|
|
139
|
+
* ("the aircraft is 260 nm from CYUL, the nearest booked departure"), or
|
|
140
|
+
* null when auto-start is off, not polling, or a flight is active. Absent
|
|
141
|
+
* on shells before core 2.32.17.
|
|
142
|
+
*/
|
|
143
|
+
autoStartWaitReason?: string | null;
|
|
137
144
|
timestamp: number;
|
|
138
145
|
};
|
|
139
146
|
/** Result returned from startFlight */
|
package/dist/ui/card.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
declare function Card({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
3
3
|
declare function CardHeader({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
4
|
-
|
|
4
|
+
type CardTitleProps = React.ComponentProps<"h3"> & {
|
|
5
|
+
as?: React.ElementType;
|
|
6
|
+
};
|
|
7
|
+
declare function CardTitle({ as: Comp, className, ...props }: CardTitleProps): React.JSX.Element;
|
|
5
8
|
declare function CardDescription({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
6
9
|
declare function CardAction({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
7
10
|
declare function CardContent({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
package/dist/ui/card.js
CHANGED
|
@@ -6,8 +6,8 @@ function Card({ className, ...props }) {
|
|
|
6
6
|
function CardHeader({ className, ...props }) {
|
|
7
7
|
return (_jsx("div", { "data-slot": "card-header", className: cn("@container/card-header has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6 grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6", className), ...props }));
|
|
8
8
|
}
|
|
9
|
-
function CardTitle({ className, ...props }) {
|
|
10
|
-
return (_jsx(
|
|
9
|
+
function CardTitle({ as: Comp = "h3", className, ...props }) {
|
|
10
|
+
return (_jsx(Comp, { "data-slot": "card-title", className: cn("font-semibold leading-none", className), ...props }));
|
|
11
11
|
}
|
|
12
12
|
function CardDescription({ className, ...props }) {
|
|
13
13
|
return (_jsx("div", { "data-slot": "card-description", className: cn("text-muted-foreground text-sm", className), ...props }));
|
package/dist/ui/combobox.d.ts
CHANGED
|
@@ -4,6 +4,12 @@ import * as React from "react";
|
|
|
4
4
|
export type ComboboxOption = {
|
|
5
5
|
value: string;
|
|
6
6
|
label: string;
|
|
7
|
+
/**
|
|
8
|
+
* Optional heading to list this option under. Groups render in the order
|
|
9
|
+
* they are first seen; options without a group render first, ungrouped.
|
|
10
|
+
* Omit on every option for a flat list.
|
|
11
|
+
*/
|
|
12
|
+
group?: string;
|
|
7
13
|
};
|
|
8
14
|
/** Props for the searchable single-select `Combobox` component. */
|
|
9
15
|
export type ComboboxProps = {
|
|
@@ -24,6 +30,12 @@ export type ComboboxProps = {
|
|
|
24
30
|
contentClassName?: string;
|
|
25
31
|
align?: "start" | "center" | "end";
|
|
26
32
|
onOpenChange?: (open: boolean) => void;
|
|
33
|
+
/** Element id applied to the trigger button. */
|
|
34
|
+
id?: string;
|
|
35
|
+
/** Accessible name for the trigger button (and the search field inside the popover). */
|
|
36
|
+
"aria-label"?: string;
|
|
37
|
+
/** Id of an element that labels the trigger button. */
|
|
38
|
+
"aria-labelledby"?: string;
|
|
27
39
|
};
|
|
28
40
|
/**
|
|
29
41
|
* Searchable single-select built on Popover + cmdk. The list scrolls
|
|
@@ -31,5 +43,5 @@ export type ComboboxProps = {
|
|
|
31
43
|
* selected option with a check. Pass `loading` while options are being
|
|
32
44
|
* fetched to keep the trigger usable without a flickering empty state.
|
|
33
45
|
*/
|
|
34
|
-
export declare function Combobox({ options, value, onValueChange, placeholder, searchPlaceholder, emptyText, loading, loadingText, disabled, triggerClassName, contentClassName, align, onOpenChange, }: ComboboxProps): React.JSX.Element;
|
|
46
|
+
export declare function Combobox({ options, value, onValueChange, placeholder, searchPlaceholder, emptyText, loading, loadingText, disabled, triggerClassName, contentClassName, align, onOpenChange, id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, }: ComboboxProps): React.JSX.Element;
|
|
35
47
|
//# sourceMappingURL=combobox.d.ts.map
|
package/dist/ui/combobox.js
CHANGED
|
@@ -11,15 +11,33 @@ import { Popover, PopoverContent, PopoverTrigger } from "./popover";
|
|
|
11
11
|
* selected option with a check. Pass `loading` while options are being
|
|
12
12
|
* fetched to keep the trigger usable without a flickering empty state.
|
|
13
13
|
*/
|
|
14
|
-
export function Combobox({ options, value, onValueChange, placeholder = "Select…", searchPlaceholder = "Search…", emptyText = "No results.", loading = false, loadingText = "Loading…", disabled = false, triggerClassName, contentClassName, align = "start", onOpenChange, }) {
|
|
14
|
+
export function Combobox({ options, value, onValueChange, placeholder = "Select…", searchPlaceholder = "Search…", emptyText = "No results.", loading = false, loadingText = "Loading…", disabled = false, triggerClassName, contentClassName, align = "start", onOpenChange, id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, }) {
|
|
15
15
|
const [open, setOpen] = React.useState(false);
|
|
16
16
|
const selected = options.find((option) => option.value === value);
|
|
17
|
+
const inputAriaLabel = ariaLabel ?? selected?.label ?? placeholder;
|
|
17
18
|
const handleOpenChange = (next) => {
|
|
18
19
|
setOpen(next);
|
|
19
20
|
onOpenChange?.(next);
|
|
20
21
|
};
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
// Ungrouped options stay flat at the top; grouped ones render under a
|
|
23
|
+
// heading per group, in first-seen order.
|
|
24
|
+
const ungrouped = options.filter((option) => !option.group);
|
|
25
|
+
const groups = React.useMemo(() => {
|
|
26
|
+
const byGroup = new Map();
|
|
27
|
+
for (const option of options) {
|
|
28
|
+
if (!option.group)
|
|
29
|
+
continue;
|
|
30
|
+
const bucket = byGroup.get(option.group);
|
|
31
|
+
if (bucket)
|
|
32
|
+
bucket.push(option);
|
|
33
|
+
else
|
|
34
|
+
byGroup.set(option.group, [option]);
|
|
35
|
+
}
|
|
36
|
+
return Array.from(byGroup.entries());
|
|
37
|
+
}, [options]);
|
|
38
|
+
const renderItem = (option) => (_jsxs(Command.Item, { value: `${option.label} ${option.value}`, onSelect: () => {
|
|
39
|
+
onValueChange?.(option.value);
|
|
40
|
+
handleOpenChange(false);
|
|
41
|
+
}, className: "aria-selected:bg-accent aria-selected:text-accent-foreground flex cursor-pointer items-center rounded-sm px-2 py-1.5 text-sm outline-none", children: [_jsx(Check, { className: cn("mr-2 h-4 w-4 shrink-0", value === option.value ? "opacity-100" : "opacity-0") }), _jsx("span", { className: "truncate", children: option.label })] }, option.value));
|
|
42
|
+
return (_jsxs(Popover, { open: open, onOpenChange: handleOpenChange, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs("button", { type: "button", id: id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, disabled: disabled, className: cn("border-input bg-background ring-offset-background focus:ring-ring flex h-9 w-full items-center justify-between rounded-md border px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50", triggerClassName), children: [_jsx("span", { className: cn("truncate", !selected && "text-muted-foreground"), children: selected ? selected.label : placeholder }), _jsx(ChevronsUpDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })] }) }), _jsx(PopoverContent, { align: align, className: cn("w-[var(--radix-popover-trigger-width)] p-0", contentClassName), children: _jsxs(Command, { className: "text-popover-foreground flex w-full flex-col overflow-hidden", children: [_jsxs("div", { className: "border-border flex items-center border-b px-2.5", children: [_jsx(Search, { className: "text-muted-foreground mr-2 h-4 w-4 shrink-0" }), _jsx(Command.Input, { placeholder: searchPlaceholder, "aria-label": inputAriaLabel, className: "placeholder:text-muted-foreground h-9 w-full bg-transparent py-2 text-sm outline-none" })] }), _jsx(Command.List, { className: "max-h-60 overflow-y-auto p-1", children: loading ? (_jsx("div", { className: "text-muted-foreground py-3 text-center text-sm", children: loadingText })) : (_jsxs(_Fragment, { children: [_jsx(Command.Empty, { className: "text-muted-foreground py-3 text-center text-sm", children: emptyText }), ungrouped.map(renderItem), groups.map(([heading, items]) => (_jsx(Command.Group, { heading: heading, className: "[&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium", children: items.map(renderItem) }, heading)))] })) })] }) })] }));
|
|
25
43
|
}
|
package/dist/ui/slider.js
CHANGED
|
@@ -2,6 +2,21 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import * as SliderPrimitive from "@radix-ui/react-slider";
|
|
4
4
|
import { cn } from "../utils/cn";
|
|
5
|
-
const Slider = React.forwardRef(({ className,
|
|
5
|
+
const Slider = React.forwardRef(({ className, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, ...props }, ref) => {
|
|
6
|
+
// Only include the aria attributes when they're actually set. For a
|
|
7
|
+
// multi-value slider, Radix's Thumb falls back to a computed positional
|
|
8
|
+
// label ("Minimum"/"Maximum"/"Value N of M") when no aria-label is
|
|
9
|
+
// supplied; spreading an explicit `aria-label: undefined` key would
|
|
10
|
+
// overwrite that fallback (Radix's internal spread order puts the
|
|
11
|
+
// caller's props last), leaving the thumb with no accessible name at
|
|
12
|
+
// all. Omitting the key entirely preserves whatever fallback Radix
|
|
13
|
+
// computes.
|
|
14
|
+
const thumbAriaProps = {};
|
|
15
|
+
if (ariaLabel !== undefined)
|
|
16
|
+
thumbAriaProps["aria-label"] = ariaLabel;
|
|
17
|
+
if (ariaLabelledBy !== undefined)
|
|
18
|
+
thumbAriaProps["aria-labelledby"] = ariaLabelledBy;
|
|
19
|
+
return (_jsxs(SliderPrimitive.Root, { ref: ref, className: cn("relative flex w-full touch-none select-none items-center", className), ...props, children: [_jsx(SliderPrimitive.Track, { className: "bg-primary/20 relative h-1.5 w-full grow overflow-hidden rounded-full", children: _jsx(SliderPrimitive.Range, { className: "bg-primary absolute h-full" }) }), _jsx(SliderPrimitive.Thumb, { ...thumbAriaProps, className: "border-primary/50 bg-background focus-visible:ring-ring focus-visible:outline-hidden block h-4 w-4 rounded-full border shadow-sm transition-colors focus-visible:ring-1 disabled:pointer-events-none disabled:opacity-50" })] }));
|
|
20
|
+
});
|
|
6
21
|
Slider.displayName = SliderPrimitive.Root.displayName;
|
|
7
22
|
export { Slider };
|
package/dist/ui/switch.d.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
type SwitchProps = {
|
|
2
|
+
type SwitchProps = Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "checked" | "onClick" | "type" | "role"> & {
|
|
3
3
|
checked?: boolean;
|
|
4
4
|
onCheckedChange?: (checked: boolean) => void;
|
|
5
|
-
disabled?: boolean;
|
|
6
|
-
className?: string;
|
|
7
|
-
id?: string;
|
|
8
|
-
name?: string;
|
|
9
5
|
};
|
|
10
|
-
declare const Switch: React.ForwardRefExoticComponent<
|
|
6
|
+
declare const Switch: React.ForwardRefExoticComponent<Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "type" | "role" | "onClick" | "checked"> & {
|
|
7
|
+
checked?: boolean;
|
|
8
|
+
onCheckedChange?: (checked: boolean) => void;
|
|
9
|
+
} & React.RefAttributes<HTMLButtonElement>>;
|
|
11
10
|
export { Switch };
|
|
12
11
|
export type { SwitchProps };
|
|
13
12
|
//# sourceMappingURL=switch.d.ts.map
|
package/dist/ui/switch.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { cn } from "../utils/cn";
|
|
4
|
-
const Switch = React.forwardRef(({ checked = false, onCheckedChange, disabled, className, ...props }, ref) => (_jsx("button", { type: "button", role: "switch", "aria-checked": checked, ref: ref, disabled: disabled, onClick: () => onCheckedChange?.(!checked), className: cn("relative inline-flex shrink-0 cursor-pointer rounded-md transition-all duration-150", "h-[18px] w-[32px]", checked
|
|
4
|
+
const Switch = React.forwardRef(({ checked = false, onCheckedChange, disabled, className, ...props }, ref) => (_jsx("button", { type: "button", role: "switch", "aria-checked": checked, ref: ref, disabled: disabled, onClick: () => onCheckedChange?.(!checked), className: cn("relative inline-flex shrink-0 cursor-pointer rounded-md transition-all duration-150", "h-[18px] w-[32px]", "focus-visible:outline-hidden focus-visible:ring-ring focus-visible:ring-2", checked
|
|
5
5
|
? "border-primary bg-primary border"
|
|
6
6
|
: "border-border-interactive bg-muted border", disabled && "cursor-not-allowed opacity-50", className), ...props, children: _jsx("span", { className: cn("pointer-events-none absolute top-[2px] h-[12px] w-[12px] rounded-sm transition-[left] duration-150", checked ? "bg-primary-foreground left-[16px]" : "left-[2px] bg-white") }) })));
|
|
7
7
|
Switch.displayName = "Switch";
|