@datum-cloud/datum-ui 3.7.1 → 3.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/dist/app-navigation/index.mjs +1 -1
  2. package/dist/{app-navigation-Bcx7hr9L.mjs → app-navigation-DyNZwlSG.mjs} +4 -4
  3. package/dist/assistant/index.mjs +9 -8
  4. package/dist/autocomplete/index.mjs +1 -1
  5. package/dist/{autocomplete-fSSmRLYK.mjs → autocomplete-CrCbO2VS.mjs} +12 -6
  6. package/dist/autosearch/index.mjs +3 -3
  7. package/dist/badge/index.mjs +182 -1
  8. package/dist/button/index.mjs +2 -2
  9. package/dist/{button-Dj6cKrWj.mjs → button-Cn4KagBO.mjs} +1 -1
  10. package/dist/{button-BU8TEbJ5.mjs → button-IK-Lnu_9.mjs} +1 -1
  11. package/dist/button-group/index.mjs +1 -1
  12. package/dist/{button-group-C3GKo-0p.mjs → button-group-DJ6X1SSj.mjs} +2 -2
  13. package/dist/{calendar-date-picker-BUwgVaI1.mjs → calendar-date-picker-BRKs56gR.mjs} +1 -1
  14. package/dist/card/index.mjs +1 -1
  15. package/dist/{card-save-bar-0XDpAJo_.mjs → card-save-bar-Te8jf-ie.mjs} +1 -1
  16. package/dist/checkbox/index.mjs +1 -1
  17. package/dist/checkbox-BAo5sbHk.mjs +84 -0
  18. package/dist/collapsible/index.mjs +1 -6
  19. package/dist/collapsible-B-KP3JZ-.mjs +104 -0
  20. package/dist/components/base/checkbox/checkbox.d.ts +11 -3
  21. package/dist/components/base/collapsible/collapsible.d.ts +28 -0
  22. package/dist/components/base/collapsible/index.d.ts +1 -1
  23. package/dist/components/base/radio-group/radio-group.d.ts +11 -5
  24. package/dist/components/base/spinner/index.d.ts +1 -1
  25. package/dist/components/base/spinner/spinner.d.ts +11 -0
  26. package/dist/components/base/switch/switch.d.ts +6 -1
  27. package/dist/components/base/typography/typography.d.ts +1 -1
  28. package/dist/components/features/_shared/copy-state-icon.d.ts +12 -0
  29. package/dist/components/features/_shared/index.d.ts +2 -0
  30. package/dist/components/features/_shared/motion-chip.d.ts +293 -0
  31. package/dist/components/features/logs/hooks/use-logs-url-state.d.ts +59 -0
  32. package/dist/components/features/logs/index.d.ts +4 -1
  33. package/dist/components/features/logs/utils/facet-counts.d.ts +50 -0
  34. package/dist/components/features/logs/utils/facets.d.ts +2 -0
  35. package/dist/components/features/logs/utils/index.d.ts +4 -0
  36. package/dist/components/features/logs/utils/url-state.d.ts +61 -0
  37. package/dist/components/icons/spinner.icon.d.ts +17 -3
  38. package/dist/copy-state-icon-DMvXXsZm.mjs +61 -0
  39. package/dist/data-table/index.mjs +1 -1
  40. package/dist/{data-table-s2YrE79S.mjs → data-table-DFUnUydN.mjs} +8 -8
  41. package/dist/date-picker/index.mjs +3 -3
  42. package/dist/date-time-picker/index.mjs +1 -1
  43. package/dist/{date-time-picker-CLdaGiGC.mjs → date-time-picker-BRMm2QSz.mjs} +1 -1
  44. package/dist/{date-time-range-picker-RZX4CS4b.mjs → date-time-range-picker-CqGGJTLS.mjs} +20 -9
  45. package/dist/dropzone/index.mjs +1 -1
  46. package/dist/{dropzone-Cer9E-VH.mjs → dropzone-qKYfSe7o.mjs} +1 -1
  47. package/dist/empty-content/index.mjs +1 -1
  48. package/dist/{empty-content-B2FZ9cyt.mjs → empty-content-CTMHak36.mjs} +1 -1
  49. package/dist/field-styles-D-FJatHt.mjs +31 -0
  50. package/dist/form/index.mjs +1 -1
  51. package/dist/form/stepper/index.mjs +1 -1
  52. package/dist/{form-C4XcxxjK.mjs → form-VdbSqDjL.mjs} +20 -13
  53. package/dist/grouped-table/index.mjs +1 -1
  54. package/dist/{grouped-table-32RO2v7U.mjs → grouped-table-B4HzLXq6.mjs} +3 -3
  55. package/dist/hooks/index.mjs +1 -1
  56. package/dist/hooks/use-breakpoint.d.ts +7 -2
  57. package/dist/icons/index.mjs +1 -1
  58. package/dist/index.mjs +37 -37
  59. package/dist/{layers-XEND2WKv.mjs → layers-BC1Ny49w.mjs} +11 -3
  60. package/dist/loader-overlay/index.mjs +1 -1
  61. package/dist/{loader-overlay-JvB8IQo3.mjs → loader-overlay-DP0pvHuG.mjs} +1 -1
  62. package/dist/logs/index.mjs +412 -115
  63. package/dist/map/index.mjs +1 -1
  64. package/dist/more-actions/index.mjs +1 -1
  65. package/dist/{more-actions-D9k1ILzT.mjs → more-actions-DXQiV-bN.mjs} +2 -2
  66. package/dist/motion-chip-BczV7spP.mjs +52 -0
  67. package/dist/multi-select/index.mjs +1 -1
  68. package/dist/{multi-select-BUgx6VZF.mjs → multi-select-DwcsJdHt.mjs} +82 -66
  69. package/dist/picker/index.mjs +2 -2
  70. package/dist/{picker-C0h30DHf.mjs → picker-BHPtncpv.mjs} +2 -2
  71. package/dist/radio-group/index.mjs +1 -1
  72. package/dist/radio-group-Boxi2hm0.mjs +83 -0
  73. package/dist/responsive-dropdown/index.mjs +1 -1
  74. package/dist/{responsive-dropdown-DsWgpE_i.mjs → responsive-dropdown-B9cDUeHt.mjs} +1 -1
  75. package/dist/responsive-popover/index.mjs +1 -1
  76. package/dist/{responsive-popover-DJYd8lOK.mjs → responsive-popover-B_pUxrZ1.mjs} +1 -1
  77. package/dist/rich-text-editor/index.mjs +1 -1
  78. package/dist/{rich-text-editor-ibngjhQV.mjs → rich-text-editor-CPd_6vdZ.mjs} +2 -2
  79. package/dist/select/index.mjs +1 -1
  80. package/dist/{select-DemYhwnG.mjs → select-B0Xlz-wD.mjs} +3 -2
  81. package/dist/{select-jgK6wyXj.mjs → select-CGsHf70u.mjs} +7 -2
  82. package/dist/spinner/index.mjs +1 -1
  83. package/dist/spinner-DSlDJdWl.mjs +23 -0
  84. package/dist/spinner.icon-BiUnMAxw.mjs +104 -0
  85. package/dist/switch/index.mjs +1 -1
  86. package/dist/switch-IduVwiPZ.mjs +114 -0
  87. package/dist/tabs/index.mjs +1 -1
  88. package/dist/tag-input/index.mjs +1 -1
  89. package/dist/{tag-input-DAMY703F.mjs → tag-input-a3ktkGrH.mjs} +39 -32
  90. package/dist/task-queue/index.mjs +1 -1
  91. package/dist/{task-queue-dropdown-BgQSGDwg.mjs → task-queue-dropdown-BflEFiMi.mjs} +4 -4
  92. package/dist/time-picker/index.mjs +1 -1
  93. package/dist/{time-picker-DgHjdcMZ.mjs → time-picker-BFwH-Vd3.mjs} +1 -1
  94. package/dist/{to-api-format-EZInfj0_.mjs → to-api-format-BiWOTFha.mjs} +4 -4
  95. package/dist/transfer/index.mjs +1 -1
  96. package/dist/{transfer-91lwTOhX.mjs → transfer-DGUeAQUL.mjs} +1 -1
  97. package/dist/{use-breakpoint-zY_JYINK.mjs → use-breakpoint-Ce5tS4cU.mjs} +11 -5
  98. package/dist/{use-option-picker-CBMU72LU.mjs → use-option-picker-DXY2SNnT.mjs} +2 -2
  99. package/dist/utils/field-styles.d.ts +21 -0
  100. package/package.json +1 -4
  101. package/dist/badge-D7A6GfWn.mjs +0 -182
  102. package/dist/checkbox-CNljVnKj.mjs +0 -28
  103. package/dist/radio-group-0RxTmRnF.mjs +0 -43
  104. package/dist/spinner-DjEpx6Q3.mjs +0 -13
  105. package/dist/spinner.icon-D0SKuGFG.mjs +0 -47
  106. package/dist/switch-CWvVN9ea.mjs +0 -33
@@ -1,13 +1,19 @@
1
- import { RadioGroup as ShadcnRadioGroup, RadioGroupItem as ShadcnRadioGroupItem } from '../../../_shadcn/ui/radio-group';
1
+ import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
2
2
  import * as React from 'react';
3
- declare function RadioGroup({ ref, className, ...props }: React.ComponentProps<typeof ShadcnRadioGroup> & {
4
- ref?: React.RefObject<React.ElementRef<typeof ShadcnRadioGroup> | null>;
3
+ declare function RadioGroup({ ref, className, value: valueProp, defaultValue, onValueChange, ...props }: React.ComponentProps<typeof RadioGroupPrimitive.Root> & {
4
+ ref?: React.RefObject<React.ElementRef<typeof RadioGroupPrimitive.Root> | null>;
5
5
  }): React.JSX.Element;
6
6
  declare namespace RadioGroup {
7
7
  var displayName: string;
8
8
  }
9
- declare function RadioGroupItem({ ref, className, ...props }: React.ComponentProps<typeof ShadcnRadioGroupItem> & {
10
- ref?: React.RefObject<React.ElementRef<typeof ShadcnRadioGroupItem> | null>;
9
+ /**
10
+ * RadioGroupItem renders the Radix primitive directly (not the shadcn wrapper)
11
+ * so the dot can stay mounted and animate out as well as in. The dot pops in
12
+ * from half size with a small spring and fades out quickly when another option
13
+ * takes the selection. Under reduced motion it only fades.
14
+ */
15
+ declare function RadioGroupItem({ ref, className, value, ...props }: React.ComponentProps<typeof RadioGroupPrimitive.Item> & {
16
+ ref?: React.RefObject<React.ElementRef<typeof RadioGroupPrimitive.Item> | null>;
11
17
  }): React.JSX.Element;
12
18
  declare namespace RadioGroupItem {
13
19
  var displayName: string;
@@ -1 +1 @@
1
- export * from '../../../_shadcn/ui/spinner';
1
+ export { Spinner } from './spinner';
@@ -0,0 +1,11 @@
1
+ import type * as React from 'react';
2
+ /**
3
+ * Standalone loading indicator, announced to assistive tech as a status.
4
+ *
5
+ * Built on `SpinnerIcon`. It differs in three ways: it is `size-4` unless a
6
+ * size class is passed, it carries `role="status"`, and its colour comes from
7
+ * `className` (default `text-primary`), so `<Spinner className="text-white" />`
8
+ * recolours the arc and its track together.
9
+ */
10
+ declare function Spinner({ className, ...props }: React.ComponentProps<'svg'>): React.JSX.Element;
11
+ export { Spinner };
@@ -5,8 +5,13 @@ import * as React from 'react';
5
5
  * one, because its state glyphs go inside the thumb. Building it here keeps the
6
6
  * shadcn base untouched, so that base can be regenerated from upstream without
7
7
  * losing anything of ours.
8
+ *
9
+ * Motion drives the thumb: it slides on a light spring, stretches while the
10
+ * pointer is held down (so the press registers before the release toggles it),
11
+ * and the on/off glyphs cross-fade. Under reduced motion the thumb moves
12
+ * instantly and only the glyphs fade.
8
13
  */
9
- declare function Switch({ ref, className, ...props }: React.ComponentProps<typeof SwitchPrimitive.Root> & {
14
+ declare function Switch({ ref, className, checked: checkedProp, defaultChecked, onCheckedChange, onPointerDown, onPointerUp, onPointerLeave, onPointerCancel, ...props }: React.ComponentProps<typeof SwitchPrimitive.Root> & {
10
15
  ref?: React.RefObject<React.ElementRef<typeof SwitchPrimitive.Root> | null>;
11
16
  }): React.JSX.Element;
12
17
  declare namespace Switch {
@@ -1,7 +1,7 @@
1
1
  import type { VariantProps } from 'class-variance-authority';
2
2
  import * as React from 'react';
3
3
  declare const titleVariants: (props?: ({
4
- level?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | null | undefined;
4
+ level?: 1 | 2 | 4 | 3 | 5 | 6 | 7 | null | undefined;
5
5
  weight?: "bold" | "normal" | "medium" | "semibold" | "extrabold" | null | undefined;
6
6
  textColor?: "default" | "secondary" | "destructive" | "success" | "info" | "warning" | "primary" | "muted" | null | undefined;
7
7
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
@@ -0,0 +1,12 @@
1
+ import type { LucideProps } from 'lucide-react';
2
+ /**
3
+ * Copy glyph that turns into a check once the copy has happened, and back again
4
+ * when `copied` resets. The two glyphs are stacked and cross-fade with a scale
5
+ * and a light blur, so the swap reads as one icon changing rather than two
6
+ * swapping places. Under reduced motion it only fades.
7
+ *
8
+ * Decorative: the owning button carries the accessible label.
9
+ */
10
+ export declare function CopyStateIcon({ copied, ...iconProps }: LucideProps & {
11
+ copied: boolean;
12
+ }): import("react").JSX.Element;
@@ -1,2 +1,4 @@
1
+ export { CopyStateIcon } from './copy-state-icon';
2
+ export { MotionBadge, useChipMotion } from './motion-chip';
1
3
  export { endOfDayInTz, startOfDayInTz } from './timezone';
2
4
  export { useDeprecationWarning } from './use-deprecation-warning';
@@ -0,0 +1,293 @@
1
+ import type { HTMLMotionProps } from 'motion/react';
2
+ /** `Badge` as a Motion component, so chips can enter, exit and reflow. */
3
+ export declare const MotionBadge: import("react").ComponentType<Omit<{
4
+ slot?: string | undefined;
5
+ title?: string | undefined;
6
+ className?: string | undefined;
7
+ defaultChecked?: boolean | undefined;
8
+ defaultValue?: string | number | readonly string[] | undefined;
9
+ suppressContentEditableWarning?: boolean | undefined;
10
+ suppressHydrationWarning?: boolean | undefined;
11
+ accessKey?: string | undefined;
12
+ autoCapitalize?: "none" | (string & {}) | "off" | "on" | "sentences" | "words" | "characters" | undefined;
13
+ autoFocus?: boolean | undefined;
14
+ contentEditable?: (boolean | "true" | "false") | "inherit" | "plaintext-only" | undefined;
15
+ contextMenu?: string | undefined;
16
+ dir?: string | undefined;
17
+ draggable?: (boolean | "true" | "false") | undefined;
18
+ enterKeyHint?: "search" | "enter" | "done" | "go" | "next" | "previous" | "send" | undefined;
19
+ hidden?: boolean | undefined;
20
+ id?: string | undefined;
21
+ lang?: string | undefined;
22
+ nonce?: string | undefined;
23
+ spellCheck?: (boolean | "true" | "false") | undefined;
24
+ tabIndex?: number | undefined;
25
+ translate?: "yes" | "no" | undefined;
26
+ radioGroup?: string | undefined;
27
+ role?: import("react").AriaRole | undefined;
28
+ about?: string | undefined;
29
+ content?: string | undefined;
30
+ datatype?: string | undefined;
31
+ inlist?: any;
32
+ prefix?: string | undefined;
33
+ property?: string | undefined;
34
+ rel?: string | undefined;
35
+ resource?: string | undefined;
36
+ rev?: string | undefined;
37
+ typeof?: string | undefined;
38
+ vocab?: string | undefined;
39
+ autoCorrect?: string | undefined;
40
+ autoSave?: string | undefined;
41
+ color?: string | undefined;
42
+ itemProp?: string | undefined;
43
+ itemScope?: boolean | undefined;
44
+ itemType?: string | undefined;
45
+ itemID?: string | undefined;
46
+ itemRef?: string | undefined;
47
+ results?: number | undefined;
48
+ security?: string | undefined;
49
+ unselectable?: "off" | "on" | undefined;
50
+ popover?: "" | "auto" | "manual" | "hint" | undefined;
51
+ popoverTargetAction?: "toggle" | "show" | "hide" | undefined;
52
+ popoverTarget?: string | undefined;
53
+ inert?: boolean | undefined;
54
+ inputMode?: "search" | "text" | "none" | "tel" | "url" | "email" | "numeric" | "decimal" | undefined;
55
+ is?: string | undefined;
56
+ exportparts?: string | undefined;
57
+ part?: string | undefined;
58
+ "aria-activedescendant"?: string | undefined;
59
+ "aria-atomic"?: (boolean | "true" | "false") | undefined;
60
+ "aria-autocomplete"?: "list" | "none" | "inline" | "both" | undefined;
61
+ "aria-braillelabel"?: string | undefined;
62
+ "aria-brailleroledescription"?: string | undefined;
63
+ "aria-busy"?: (boolean | "true" | "false") | undefined;
64
+ "aria-checked"?: boolean | "true" | "false" | "mixed" | undefined;
65
+ "aria-colcount"?: number | undefined;
66
+ "aria-colindex"?: number | undefined;
67
+ "aria-colindextext"?: string | undefined;
68
+ "aria-colspan"?: number | undefined;
69
+ "aria-controls"?: string | undefined;
70
+ "aria-current"?: boolean | "true" | "false" | "time" | "page" | "step" | "location" | "date" | undefined;
71
+ "aria-describedby"?: string | undefined;
72
+ "aria-description"?: string | undefined;
73
+ "aria-details"?: string | undefined;
74
+ "aria-disabled"?: (boolean | "true" | "false") | undefined;
75
+ "aria-dropeffect"?: "link" | "none" | "copy" | "execute" | "move" | "popup" | undefined;
76
+ "aria-errormessage"?: string | undefined;
77
+ "aria-expanded"?: (boolean | "true" | "false") | undefined;
78
+ "aria-flowto"?: string | undefined;
79
+ "aria-grabbed"?: (boolean | "true" | "false") | undefined;
80
+ "aria-haspopup"?: boolean | "true" | "false" | "dialog" | "menu" | "grid" | "listbox" | "tree" | undefined;
81
+ "aria-hidden"?: (boolean | "true" | "false") | undefined;
82
+ "aria-invalid"?: boolean | "true" | "false" | "grammar" | "spelling" | undefined;
83
+ "aria-keyshortcuts"?: string | undefined;
84
+ "aria-label"?: string | undefined;
85
+ "aria-labelledby"?: string | undefined;
86
+ "aria-level"?: number | undefined;
87
+ "aria-live"?: "off" | "assertive" | "polite" | undefined;
88
+ "aria-modal"?: (boolean | "true" | "false") | undefined;
89
+ "aria-multiline"?: (boolean | "true" | "false") | undefined;
90
+ "aria-multiselectable"?: (boolean | "true" | "false") | undefined;
91
+ "aria-orientation"?: "horizontal" | "vertical" | undefined;
92
+ "aria-owns"?: string | undefined;
93
+ "aria-placeholder"?: string | undefined;
94
+ "aria-posinset"?: number | undefined;
95
+ "aria-pressed"?: boolean | "true" | "false" | "mixed" | undefined;
96
+ "aria-readonly"?: (boolean | "true" | "false") | undefined;
97
+ "aria-relevant"?: "text" | "all" | "additions" | "additions removals" | "additions text" | "removals" | "removals additions" | "removals text" | "text additions" | "text removals" | undefined;
98
+ "aria-required"?: (boolean | "true" | "false") | undefined;
99
+ "aria-roledescription"?: string | undefined;
100
+ "aria-rowcount"?: number | undefined;
101
+ "aria-rowindex"?: number | undefined;
102
+ "aria-rowindextext"?: string | undefined;
103
+ "aria-rowspan"?: number | undefined;
104
+ "aria-selected"?: (boolean | "true" | "false") | undefined;
105
+ "aria-setsize"?: number | undefined;
106
+ "aria-sort"?: "none" | "ascending" | "descending" | "other" | undefined;
107
+ "aria-valuemax"?: number | undefined;
108
+ "aria-valuemin"?: number | undefined;
109
+ "aria-valuenow"?: number | undefined;
110
+ "aria-valuetext"?: string | undefined;
111
+ dangerouslySetInnerHTML?: {
112
+ __html: string | TrustedHTML;
113
+ } | undefined;
114
+ onCopy?: import("react").ClipboardEventHandler<HTMLDivElement> | undefined;
115
+ onCopyCapture?: import("react").ClipboardEventHandler<HTMLDivElement> | undefined;
116
+ onCut?: import("react").ClipboardEventHandler<HTMLDivElement> | undefined;
117
+ onCutCapture?: import("react").ClipboardEventHandler<HTMLDivElement> | undefined;
118
+ onPaste?: import("react").ClipboardEventHandler<HTMLDivElement> | undefined;
119
+ onPasteCapture?: import("react").ClipboardEventHandler<HTMLDivElement> | undefined;
120
+ onCompositionEnd?: import("react").CompositionEventHandler<HTMLDivElement> | undefined;
121
+ onCompositionEndCapture?: import("react").CompositionEventHandler<HTMLDivElement> | undefined;
122
+ onCompositionStart?: import("react").CompositionEventHandler<HTMLDivElement> | undefined;
123
+ onCompositionStartCapture?: import("react").CompositionEventHandler<HTMLDivElement> | undefined;
124
+ onCompositionUpdate?: import("react").CompositionEventHandler<HTMLDivElement> | undefined;
125
+ onCompositionUpdateCapture?: import("react").CompositionEventHandler<HTMLDivElement> | undefined;
126
+ onFocus?: import("react").FocusEventHandler<HTMLDivElement> | undefined;
127
+ onFocusCapture?: import("react").FocusEventHandler<HTMLDivElement> | undefined;
128
+ onBlur?: import("react").FocusEventHandler<HTMLDivElement> | undefined;
129
+ onBlurCapture?: import("react").FocusEventHandler<HTMLDivElement> | undefined;
130
+ onChange?: import("react").ChangeEventHandler<HTMLDivElement, Element> | undefined;
131
+ onChangeCapture?: import("react").ChangeEventHandler<HTMLDivElement, Element> | undefined;
132
+ onBeforeInput?: import("react").InputEventHandler<HTMLDivElement> | undefined;
133
+ onBeforeInputCapture?: import("react").InputEventHandler<HTMLDivElement> | undefined;
134
+ onInput?: import("react").InputEventHandler<HTMLDivElement> | undefined;
135
+ onInputCapture?: import("react").InputEventHandler<HTMLDivElement> | undefined;
136
+ onReset?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
137
+ onResetCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
138
+ onSubmit?: import("react").SubmitEventHandler<HTMLDivElement> | undefined;
139
+ onSubmitCapture?: import("react").SubmitEventHandler<HTMLDivElement> | undefined;
140
+ onInvalid?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
141
+ onInvalidCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
142
+ onLoad?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
143
+ onLoadCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
144
+ onError?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
145
+ onErrorCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
146
+ onKeyDown?: import("react").KeyboardEventHandler<HTMLDivElement> | undefined;
147
+ onKeyDownCapture?: import("react").KeyboardEventHandler<HTMLDivElement> | undefined;
148
+ onKeyPress?: import("react").KeyboardEventHandler<HTMLDivElement> | undefined;
149
+ onKeyPressCapture?: import("react").KeyboardEventHandler<HTMLDivElement> | undefined;
150
+ onKeyUp?: import("react").KeyboardEventHandler<HTMLDivElement> | undefined;
151
+ onKeyUpCapture?: import("react").KeyboardEventHandler<HTMLDivElement> | undefined;
152
+ onAbort?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
153
+ onAbortCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
154
+ onCanPlay?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
155
+ onCanPlayCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
156
+ onCanPlayThrough?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
157
+ onCanPlayThroughCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
158
+ onDurationChange?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
159
+ onDurationChangeCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
160
+ onEmptied?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
161
+ onEmptiedCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
162
+ onEncrypted?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
163
+ onEncryptedCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
164
+ onEnded?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
165
+ onEndedCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
166
+ onLoadedData?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
167
+ onLoadedDataCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
168
+ onLoadedMetadata?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
169
+ onLoadedMetadataCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
170
+ onLoadStart?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
171
+ onLoadStartCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
172
+ onPause?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
173
+ onPauseCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
174
+ onPlay?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
175
+ onPlayCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
176
+ onPlaying?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
177
+ onPlayingCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
178
+ onProgress?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
179
+ onProgressCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
180
+ onRateChange?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
181
+ onRateChangeCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
182
+ onSeeked?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
183
+ onSeekedCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
184
+ onSeeking?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
185
+ onSeekingCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
186
+ onStalled?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
187
+ onStalledCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
188
+ onSuspend?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
189
+ onSuspendCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
190
+ onTimeUpdate?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
191
+ onTimeUpdateCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
192
+ onVolumeChange?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
193
+ onVolumeChangeCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
194
+ onWaiting?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
195
+ onWaitingCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
196
+ onAuxClick?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
197
+ onAuxClickCapture?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
198
+ onClick?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
199
+ onClickCapture?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
200
+ onContextMenu?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
201
+ onContextMenuCapture?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
202
+ onDoubleClick?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
203
+ onDoubleClickCapture?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
204
+ onDragCapture?: import("react").DragEventHandler<HTMLDivElement> | undefined;
205
+ onDragEndCapture?: import("react").DragEventHandler<HTMLDivElement> | undefined;
206
+ onDragEnter?: import("react").DragEventHandler<HTMLDivElement> | undefined;
207
+ onDragEnterCapture?: import("react").DragEventHandler<HTMLDivElement> | undefined;
208
+ onDragExit?: import("react").DragEventHandler<HTMLDivElement> | undefined;
209
+ onDragExitCapture?: import("react").DragEventHandler<HTMLDivElement> | undefined;
210
+ onDragLeave?: import("react").DragEventHandler<HTMLDivElement> | undefined;
211
+ onDragLeaveCapture?: import("react").DragEventHandler<HTMLDivElement> | undefined;
212
+ onDragOver?: import("react").DragEventHandler<HTMLDivElement> | undefined;
213
+ onDragOverCapture?: import("react").DragEventHandler<HTMLDivElement> | undefined;
214
+ onDragStartCapture?: import("react").DragEventHandler<HTMLDivElement> | undefined;
215
+ onDrop?: import("react").DragEventHandler<HTMLDivElement> | undefined;
216
+ onDropCapture?: import("react").DragEventHandler<HTMLDivElement> | undefined;
217
+ onMouseDown?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
218
+ onMouseDownCapture?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
219
+ onMouseEnter?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
220
+ onMouseLeave?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
221
+ onMouseMove?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
222
+ onMouseMoveCapture?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
223
+ onMouseOut?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
224
+ onMouseOutCapture?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
225
+ onMouseOver?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
226
+ onMouseOverCapture?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
227
+ onMouseUp?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
228
+ onMouseUpCapture?: import("react").MouseEventHandler<HTMLDivElement> | undefined;
229
+ onSelect?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
230
+ onSelectCapture?: import("react").ReactEventHandler<HTMLDivElement> | undefined;
231
+ onTouchCancel?: import("react").TouchEventHandler<HTMLDivElement> | undefined;
232
+ onTouchCancelCapture?: import("react").TouchEventHandler<HTMLDivElement> | undefined;
233
+ onTouchEnd?: import("react").TouchEventHandler<HTMLDivElement> | undefined;
234
+ onTouchEndCapture?: import("react").TouchEventHandler<HTMLDivElement> | undefined;
235
+ onTouchMove?: import("react").TouchEventHandler<HTMLDivElement> | undefined;
236
+ onTouchMoveCapture?: import("react").TouchEventHandler<HTMLDivElement> | undefined;
237
+ onTouchStart?: import("react").TouchEventHandler<HTMLDivElement> | undefined;
238
+ onTouchStartCapture?: import("react").TouchEventHandler<HTMLDivElement> | undefined;
239
+ onPointerDown?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
240
+ onPointerDownCapture?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
241
+ onPointerMove?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
242
+ onPointerMoveCapture?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
243
+ onPointerUp?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
244
+ onPointerUpCapture?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
245
+ onPointerCancel?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
246
+ onPointerCancelCapture?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
247
+ onPointerEnter?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
248
+ onPointerLeave?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
249
+ onPointerOver?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
250
+ onPointerOverCapture?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
251
+ onPointerOut?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
252
+ onPointerOutCapture?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
253
+ onGotPointerCapture?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
254
+ onGotPointerCaptureCapture?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
255
+ onLostPointerCapture?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
256
+ onLostPointerCaptureCapture?: import("react").PointerEventHandler<HTMLDivElement> | undefined;
257
+ onScroll?: import("react").UIEventHandler<HTMLDivElement> | undefined;
258
+ onScrollCapture?: import("react").UIEventHandler<HTMLDivElement> | undefined;
259
+ onScrollEnd?: import("react").UIEventHandler<HTMLDivElement> | undefined;
260
+ onScrollEndCapture?: import("react").UIEventHandler<HTMLDivElement> | undefined;
261
+ onWheel?: import("react").WheelEventHandler<HTMLDivElement> | undefined;
262
+ onWheelCapture?: import("react").WheelEventHandler<HTMLDivElement> | undefined;
263
+ onAnimationStartCapture?: import("react").AnimationEventHandler<HTMLDivElement> | undefined;
264
+ onAnimationEnd?: import("react").AnimationEventHandler<HTMLDivElement> | undefined;
265
+ onAnimationEndCapture?: import("react").AnimationEventHandler<HTMLDivElement> | undefined;
266
+ onAnimationIteration?: import("react").AnimationEventHandler<HTMLDivElement> | undefined;
267
+ onAnimationIterationCapture?: import("react").AnimationEventHandler<HTMLDivElement> | undefined;
268
+ onToggle?: import("react").ToggleEventHandler<HTMLDivElement> | undefined;
269
+ onBeforeToggle?: import("react").ToggleEventHandler<HTMLDivElement> | undefined;
270
+ onTransitionCancel?: import("react").TransitionEventHandler<HTMLDivElement> | undefined;
271
+ onTransitionCancelCapture?: import("react").TransitionEventHandler<HTMLDivElement> | undefined;
272
+ onTransitionEnd?: import("react").TransitionEventHandler<HTMLDivElement> | undefined;
273
+ onTransitionEndCapture?: import("react").TransitionEventHandler<HTMLDivElement> | undefined;
274
+ onTransitionRun?: import("react").TransitionEventHandler<HTMLDivElement> | undefined;
275
+ onTransitionRunCapture?: import("react").TransitionEventHandler<HTMLDivElement> | undefined;
276
+ onTransitionStart?: import("react").TransitionEventHandler<HTMLDivElement> | undefined;
277
+ onTransitionStartCapture?: import("react").TransitionEventHandler<HTMLDivElement> | undefined;
278
+ type?: "secondary" | "success" | "info" | "warning" | "primary" | "tertiary" | "quaternary" | "danger" | "muted" | null | undefined;
279
+ theme?: "outline" | "solid" | "light" | null | undefined;
280
+ } & import("motion/react").MotionProps, "children"> & {
281
+ children?: import("react").ReactNode | import("motion/react").MotionValue<number> | import("motion/react").MotionValue<string>;
282
+ }>;
283
+ /**
284
+ * Motion props for a chip in a wrapping list, for use with `MotionBadge`
285
+ * inside `<AnimatePresence initial={false} mode="popLayout">`.
286
+ *
287
+ * A chip scales up slightly as it fades in, and fades out a little faster
288
+ * when removed. `popLayout` takes the leaving chip out of flow straight away,
289
+ * and `layout="position"` slides the chips after it into the gap rather than
290
+ * snapping. The list needs `position: relative` for `popLayout` to place the
291
+ * leaving chip. Under reduced motion chips only fade and nothing slides.
292
+ */
293
+ export declare function useChipMotion(): Pick<HTMLMotionProps<'div'>, 'initial' | 'animate' | 'exit' | 'transition' | 'layout'>;
@@ -0,0 +1,59 @@
1
+ import type { LogFilters, LogTimeRange } from '../types';
2
+ import type { LogsUrlState, LogsUrlStateOptions } from '../utils/url-state';
3
+ type SearchParamsUpdate = (prev: URLSearchParams) => URLSearchParams;
4
+ /**
5
+ * Updates the query string. Shaped like React Router's `setSearchParams`, so
6
+ * `useSearchParams()` from `react-router` plugs straight in.
7
+ */
8
+ export type SetLogsSearchParams = (update: SearchParamsUpdate, options?: {
9
+ replace?: boolean;
10
+ }) => void;
11
+ export interface UseLogsUrlStateOptions extends LogsUrlStateOptions {
12
+ /**
13
+ * Current query string, from the app's router. Pass it together with
14
+ * `setSearchParams` whenever the app has a client router that owns the URL
15
+ * (React Router, TanStack Router): writing `window.history` behind its back
16
+ * leaves the router's location stale, and its next navigation can drop these
17
+ * params. Leave both out only for plain pages or Next.js App Router, which
18
+ * follows History API calls itself.
19
+ */
20
+ searchParams?: URLSearchParams;
21
+ setSearchParams?: SetLogsSearchParams;
22
+ /**
23
+ * `replace` (default) rewrites the current history entry, so the back button
24
+ * leaves the page instead of stepping through every filter click. `push`
25
+ * adds an entry per change.
26
+ */
27
+ history?: 'replace' | 'push';
28
+ }
29
+ /** Values and change handlers to spread onto `Logs.Root`. */
30
+ export interface LogsUrlStateProps extends LogsUrlState {
31
+ onTimeRangeChange: (range: LogTimeRange) => void;
32
+ onFiltersChange: (filters: LogFilters) => void;
33
+ onSearchChange: (search: string) => void;
34
+ onLiveChange: (live: boolean) => void;
35
+ onSelectedIdChange: (id: string | null) => void;
36
+ }
37
+ /**
38
+ * Keep `Logs.Root`'s time range, filters, search, live toggle and open row in
39
+ * the address bar, so a refresh or a shared link reopens the same view.
40
+ *
41
+ * ```tsx
42
+ * const logsState = useLogsUrlState()
43
+ * const query = buildLogQL({ matchers: logsState.filters, lineContains: logsState.search })
44
+ * // fetch with query + resolveLogTimeRange(logsState.timeRange)
45
+ *
46
+ * <Logs.Root {...logsState} entries={entries} onRefresh={refetch}>
47
+ * <Logs.Explorer />
48
+ * </Logs.Root>
49
+ * ```
50
+ *
51
+ * With React Router, hand it the router's search params instead:
52
+ *
53
+ * ```tsx
54
+ * const [searchParams, setSearchParams] = useSearchParams()
55
+ * const logsState = useLogsUrlState({ searchParams, setSearchParams })
56
+ * ```
57
+ */
58
+ export declare function useLogsUrlState(options?: UseLogsUrlStateOptions): LogsUrlStateProps;
59
+ export {};
@@ -1,5 +1,8 @@
1
1
  export { resolveLogColumns } from './components/columns';
2
2
  export { useLogs } from './hooks/use-logs';
3
+ export { useLogsUrlState } from './hooks/use-logs-url-state';
4
+ export type { LogsUrlStateProps, SetLogsSearchParams, UseLogsUrlStateOptions } from './hooks/use-logs-url-state';
3
5
  export { Logs } from './logs';
4
6
  export type { BuildLogQLOptions, LogColumn, LogColumnCellContext, LogColumnId, LogColumnSize, LogColumnSkeletonContext, LogColumnSpec, LogEntry, LogFacet, LogFacetOption, LogFilters, LogHistogramBucket, LogsContextValue, LogsRootProps, LogTimeRange, LokiQueryRangeResponse, LokiStream, ParsedHttpLogLine, ParsedLogLine, ParsedTextLogLine, } from './types';
5
- export { buildLogQL, facetsFromEntries, filterEntries, flattenLokiStreams, formatHttpLogLine, histogramFromEntries, httpStatusBadgeType, httpStatusTextClass, lastThirtyMinutes, LOG_TIME_PRESETS, logLineDisplay, logRequestHost, logTimeRangeLabel, logUserAgent, nsToDate, parseLogLine, parseUserAgent, resolveLogTimeRange, searchableLogText, severityBadgeType, splitPathQuery, } from './utils';
7
+ export { buildLogFacetCountQuery, buildLogQL, facetFromLokiCounts, facetsFromEntries, filterEntries, flattenLokiStreams, formatHttpLogLine, histogramFromEntries, httpStatusBadgeType, httpStatusTextClass, lastThirtyMinutes, LOG_TIME_PRESETS, logLineDisplay, logRequestHost, LOGS_URL_KEYS, logTimeRangeLabel, logUserAgent, nsToDate, parseLogLine, parseLogsUrlState, parseUserAgent, resolveLogTimeRange, searchableLogText, severityBadgeType, splitPathQuery, writeLogsUrlState, } from './utils';
8
+ export type { BuildLogFacetCountQueryOptions, LogsUrlState, LogsUrlStateOptions, LokiVectorResponse, LokiVectorSample } from './utils';
@@ -0,0 +1,50 @@
1
+ import type { LogFacet, LogFilters, LogTimeRange } from '../types';
2
+ export interface BuildLogFacetCountQueryOptions {
3
+ /** Label to count values of, e.g. `response_code`. */
4
+ label: string;
5
+ /**
6
+ * Matchers that scope the page, e.g. `{ route_name: ['my-alb'] }`. Leave the
7
+ * user's facet selections and search out: counting against the scope alone
8
+ * keeps every option listed, with its total for the window, no matter what
9
+ * is ticked.
10
+ */
11
+ matchers?: LogFilters;
12
+ /** Window to count over. Its length becomes the range selector. */
13
+ timeRange: LogTimeRange;
14
+ }
15
+ /**
16
+ * LogQL that counts log lines per value of one label across a time range:
17
+ *
18
+ * ```
19
+ * sum by (response_code) (count_over_time({route_name="my-alb"}[1800s]))
20
+ * ```
21
+ *
22
+ * Run it as an instant query (`/loki/api/v1/query`) with `time` set to the
23
+ * range's `to`, then pass the response to `facetFromLokiCounts`. Returns
24
+ * `null` for a label name LogQL can't express. Works for indexed stream labels
25
+ * and for structured metadata, which Loki can also group by.
26
+ */
27
+ export declare function buildLogFacetCountQuery({ label, matchers, timeRange }: BuildLogFacetCountQueryOptions): string | null;
28
+ /** One series of a Loki instant-query (`resultType: 'vector'`) response. */
29
+ export interface LokiVectorSample {
30
+ metric: Record<string, string>;
31
+ value: [timestamp: number | string, value: string];
32
+ }
33
+ export interface LokiVectorResponse {
34
+ status: 'success' | 'error';
35
+ data?: {
36
+ resultType: string;
37
+ result: LokiVectorSample[];
38
+ };
39
+ errorType?: string;
40
+ error?: string;
41
+ }
42
+ /**
43
+ * Turn the response to a `buildLogFacetCountQuery` query into a facet for
44
+ * `Logs.Root`. Series without the label (lines that don't carry it) and zero
45
+ * counts are skipped. Options are ordered the same way as `facetsFromEntries`.
46
+ * Pass `label` to override the display name.
47
+ */
48
+ export declare function facetFromLokiCounts(name: string, response: LokiVectorResponse | null | undefined, options?: {
49
+ label?: string;
50
+ }): LogFacet;
@@ -1,4 +1,6 @@
1
1
  import type { LogEntry, LogFacet, LogFilters } from '../types';
2
+ export declare function facetLabel(name: string): string;
3
+ export declare function compareFacetValues(name: string, a: string, b: string): number;
2
4
  export declare function facetsFromEntries(entries: readonly LogEntry[], names?: readonly string[]): LogFacet[];
3
5
  export declare function filterEntries(entries: readonly LogEntry[], filters: LogFilters, search?: string): LogEntry[];
4
6
  /**
@@ -1,5 +1,7 @@
1
1
  export { buildLogQL } from './build-logql';
2
2
  export { CANONICAL_FACET_NAMES, DEFAULT_LOG_COLUMNS, DEFAULT_LOGQL_MATCHER, FACET_LABELS, SEVERITY_ORDER, } from './constants';
3
+ export { buildLogFacetCountQuery, facetFromLokiCounts } from './facet-counts';
4
+ export type { BuildLogFacetCountQueryOptions, LokiVectorResponse, LokiVectorSample } from './facet-counts';
3
5
  export { facetsFromEntries, filterEntries, searchableLogText } from './facets';
4
6
  export { flattenLokiStreams, nsToDate } from './flatten-loki';
5
7
  export { formatLocalTimestamp, formatLogTimestamp, formatLogTimestampParts, formatRelativeTimestamp, formatUtcTimestamp, } from './format-timestamp';
@@ -8,5 +10,7 @@ export { logRequestHost } from './host';
8
10
  export { formatHttpLogLine, logLineDisplay, parseLogLine, splitPathQuery } from './parse-log-line';
9
11
  export { httpStatusBadgeType, httpStatusTextClass, severityBadgeType } from './severity';
10
12
  export { filtersAreActive, lastThirtyMinutes, LOG_TIME_PRESETS, logTimeRangeLabel, resolveLogTimeRange, } from './time-range';
13
+ export { LOGS_URL_KEYS, logsUrlStateKey, parseLogsUrlState, writeLogsUrlState } from './url-state';
14
+ export type { LogsUrlState, LogsUrlStateOptions } from './url-state';
11
15
  export { logUserAgent, parseUserAgent } from './user-agent';
12
16
  export type { ParsedUserAgent, UserAgentDevice } from './user-agent';
@@ -0,0 +1,61 @@
1
+ import type { LogFilters, LogTimeRange } from '../types';
2
+ /**
3
+ * The parts of `Logs.Root` state that belong in the address bar: everything
4
+ * that decides which logs the host fetches, plus the open row.
5
+ */
6
+ export interface LogsUrlState {
7
+ timeRange: LogTimeRange;
8
+ filters: LogFilters;
9
+ search: string;
10
+ live: boolean;
11
+ selectedId: string | null;
12
+ }
13
+ export interface LogsUrlStateOptions {
14
+ /**
15
+ * Prepended to every key, e.g. `logs.` gives `logs.q`, `logs.range`. Use it
16
+ * when two explorers share a page, or a key clashes with one the app owns.
17
+ */
18
+ prefix?: string;
19
+ /**
20
+ * Range used when the URL has none, and left out of the URL when chosen.
21
+ * Defaults to the last 30 minutes.
22
+ */
23
+ defaultTimeRange?: LogTimeRange;
24
+ }
25
+ /**
26
+ * Query-string keys, before `prefix`. A preset range is written as
27
+ * `range=last-1h`; a hand-picked one as `from` and `to` ISO timestamps. Each
28
+ * selected facet value is its own `filter=<label>:<value>` entry.
29
+ */
30
+ export declare const LOGS_URL_KEYS: {
31
+ readonly search: "q";
32
+ readonly range: "range";
33
+ readonly from: "from";
34
+ readonly to: "to";
35
+ readonly filter: "filter";
36
+ readonly live: "live";
37
+ readonly selected: "log";
38
+ };
39
+ /**
40
+ * Read logs state from a query string. Missing or malformed values fall back
41
+ * to the defaults (`Logs.Root`'s own defaults), so a hand-edited or stale link
42
+ * still opens. A preset range is resolved against `now`.
43
+ */
44
+ export declare function parseLogsUrlState(input: URLSearchParams | string, options?: LogsUrlStateOptions & {
45
+ now?: Date;
46
+ }): LogsUrlState;
47
+ /**
48
+ * Return a copy of `input` with the given parts of logs state written in.
49
+ * Only the parts present in `state` are touched, and params the app owns are
50
+ * kept. Defaults (no search, no filters, not live, the default range) are
51
+ * left out so a fresh explorer has a clean URL.
52
+ */
53
+ export declare function writeLogsUrlState(input: URLSearchParams | string, state: Partial<LogsUrlState>, options?: LogsUrlStateOptions): URLSearchParams;
54
+ /**
55
+ * Just this explorer's params, as a query string in a fixed key order. It
56
+ * parses to the same state as the full query string, and only changes when
57
+ * one of these params does, so it works as a memo key: an unrelated app param
58
+ * changing won't re-resolve a preset range (which would hand the host a new
59
+ * `timeRange` and trigger a refetch).
60
+ */
61
+ export declare function logsUrlStateKey(input: URLSearchParams | string, options?: Pick<LogsUrlStateOptions, 'prefix'>): string;
@@ -1,12 +1,26 @@
1
1
  import type { VariantProps } from 'class-variance-authority';
2
+ import * as React from 'react';
2
3
  declare const spinnerVariants: (props?: ({
3
4
  size?: "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "6xl" | "7xl" | "8xl" | "9xl" | null | undefined;
4
5
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
5
6
  export interface SpinnerIconProps extends React.SVGProps<SVGSVGElement>, VariantProps<typeof spinnerVariants> {
6
- /** Color of the track (background circle) */
7
+ /**
8
+ * Colour of the track (background circle). By default the track is the
9
+ * indicator colour at low opacity, so recolouring the indicator recolours both.
10
+ */
7
11
  trackClassName?: string;
8
- /** Color of the spinning indicator */
12
+ /** Colour of the spinning indicator */
9
13
  indicatorClassName?: string;
10
14
  }
11
- export declare function SpinnerIcon({ size, className, trackClassName, indicatorClassName, ...props }: SpinnerIconProps): import("react").JSX.Element;
15
+ /**
16
+ * A loading spinner: a faint full-circle track with an arc that fades from a
17
+ * transparent tail to a solid, rounded head, turning clockwise.
18
+ *
19
+ * The rotation runs through Motion as a full `transform` keyframe animation,
20
+ * which Motion hands to the Web Animations API. That keeps it on the
21
+ * compositor, so the spinner stays smooth while the main thread is busy doing
22
+ * whatever the user is waiting for. It keeps spinning under reduced motion:
23
+ * it is essential loading feedback, not decoration.
24
+ */
25
+ export declare function SpinnerIcon({ size, className, trackClassName, indicatorClassName, ...props }: SpinnerIconProps): React.JSX.Element;
12
26
  export {};