refactor(opal): collect the input families into organizational directories (#14681)

This commit is contained in:
Raunak Bhagat authored and GitHub committed 2026-09-12 00:31:53 +00:00
1 parent 02234448f4
commit a0370f232b
82 files changed
+269 -277

No files matched your search

+2 -2
View File
@@ -155,9 +155,9 @@
"date-fns": "^4.0.0",
"formik": "^2.0.0",
"next": ">=14.0.0",
"react": "^18.0.0 || ^19.0.0",
"react": "^19.0.0",
"react-day-picker": "^9.0.0",
"react-dom": "^18.0.0 || ^19.0.0",
"react-dom": "^19.0.0",
"react-dropzone": "^14.0.0 || ^20.0.0",
"react-markdown": "^9.0.0",
"rehype-sanitize": "^6.0.0",
+2 -2
View File
@@ -107,9 +107,9 @@
"date-fns": "^4.0.0",
"formik": "^2.0.0",
"next": ">=14.0.0",
"react": "^18.0.0 || ^19.0.0",
"react": "^19.0.0",
"react-day-picker": "^9.0.0",
"react-dom": "^18.0.0 || ^19.0.0",
"react-dom": "^19.0.0",
"react-dropzone": "^14.0.0 || ^20.0.0",
"react-markdown": "^9.0.0",
"rehype-sanitize": "^6.0.0",
+6 -4
View File
@@ -21,14 +21,16 @@ The barrel file at `index.ts` re-exports each component and its prop types. Each
| [SelectButton](./buttons/select-button/) | Stateful toggle button with optional foldable content | [README](./buttons/select-button/README.md) |
| [OpenButton](./buttons/open-button/) | Trigger button with rotating chevron for popovers | [README](./buttons/open-button/README.md) |
| [Tag](./tag/) | Small colored label for status/category metadata | [README](./tag/README.md) |
| [DateRangePicker](./inputs/date-range-picker/) | Preset date-range strip with a custom-range calendar popover | [README](./inputs/date-range-picker/README.md) |
| [InputDateRangePicker](./inputs/chrono/input-date-range-picker/) | Preset date-range strip with a custom-range calendar popover | [README](./inputs/chrono/input-date-range-picker/README.md) |
| [InputFile](./inputs/input-file/) | Text field that doubles as a file picker | [README](./inputs/input-file/README.md) |
| [InputAvatar](./inputs/input-avatar/) | Avatar frame with primary input chrome | [README](./inputs/input-avatar/README.md) |
| [InputComboBox](./inputs/input-combo-box/) | Filterable input/select hybrid with create-new support | [README](./inputs/input-combo-box/README.md) |
| [InputComboBox](./inputs/selections/input-combo-box/) | Filterable input/select hybrid with create-new support | [README](./inputs/selections/input-combo-box/README.md) |
| [InputImage](./inputs/input-image/) | Circular image dropzone with edit overlay | [README](./inputs/input-image/README.md) |
| [InputKeyValue](./inputs/input-key-value/) | Key/value pair editor with validation | [README](./inputs/input-key-value/README.md) |
| [InputSingleSelect](./inputs/input-select/input-single-select/) | Styled dropdown on Radix Select, pick exactly one | [README](./inputs/input-select/input-single-select/README.md) |
| [InputMultiSelect](./inputs/input-select/input-multi-select/) | Chips-in-input multi selection (Figma Input/Tags) | [README](./inputs/input-select/input-multi-select/README.md) |
| [InputSingleSelect](./inputs/selections/input-single-select/) | Styled dropdown on Radix Select, pick exactly one | [README](./inputs/selections/input-single-select/README.md) |
| [InputMultiSelect](./inputs/selections/input-multi-select/) | Chips-in-input multi selection (Figma Input/Tags) | [README](./inputs/selections/input-multi-select/README.md) |
| [InputCheckbox](./inputs/booleans/input-checkbox/) | Checkbox with checked/indeterminate states | [README](./inputs/booleans/input-checkbox/README.md) |
| [InputSwitch](./inputs/booleans/input-switch/) | On/off toggle switch | [README](./inputs/booleans/input-switch/README.md) |
| [InputNumber](./inputs/input-number/) | Number field with steppers and reset | [README](./inputs/input-number/README.md) |
| [InputList](./inputs/input-list/) | Type-and-Enter list builder with removable chips below | [README](./inputs/input-list/README.md) |
@@ -12,7 +12,7 @@ rounding (`--radius-12`).
```
root Interactive.Stateful + Interactive.Container
├─ title tile + icon-less Content (main-ui / section, frozen)
│ ├─ tile icon on tint, or image cover-filling; Checkbox when selected
│ ├─ tile icon on tint, or image cover-filling; InputCheckbox when selected
│ └─ Content title, description, optional inline editing
├─ center centerChildren — flex-1, caller-aligned
└─ action rightChildren — min-width --spacing-block-36, always reserved
@@ -26,7 +26,7 @@ Exactly one of two arms, enforced at the type level:
- `imageSrc` + `imageAlt` — image fills the tile (`object-fit: cover`).
`imageAlt` is mandatory: the image is content, not chrome.
When `state="selected"`, the tile swaps its content for a checked `Checkbox`.
When `state="selected"`, the tile swaps its content for a checked `InputCheckbox`.
## Interactivity
@@ -6,7 +6,7 @@ import type {
IconFunctionComponent,
RichStr,
} from "@opal/types";
import { Checkbox, Tooltip, type TooltipSide } from "@opal/components";
import { InputCheckbox, Tooltip, type TooltipSide } from "@opal/components";
import {
composeKeyHandler,
guardNestedInteractiveClick,
@@ -253,7 +253,7 @@ function AttachmentItemButton({
the event flow — the row alone owns activation, and its
own selected styling carries the state for AT. */
<span inert aria-hidden className="contents">
<Checkbox checked readOnly />
<InputCheckbox checked readOnly />
</span>
) : imageSrc ? (
<img
+14 -14
View File
@@ -60,14 +60,14 @@ export {
type TextButtonProps,
} from "@opal/components/buttons/text-button/components";
/* DateRangePicker */
/* InputDateRangePicker */
export {
DateRangePicker,
InputDateRangePicker,
rangeForInclusiveDays,
THIRTY_DAYS,
type DateRange,
type DateRangePickerValue,
} from "@opal/components/inputs/date-range-picker/components";
type InputDateRangePickerValue,
} from "@opal/components/inputs/chrono/input-date-range-picker/components";
/* InputAvatar */
export { default as InputAvatar } from "@opal/components/inputs/input-avatar/components";
@@ -84,7 +84,7 @@ export {
default as InputComboBox,
type InputComboBoxProps,
type ComboBoxOption,
} from "@opal/components/inputs/input-combo-box/index";
} from "@opal/components/inputs/selections/input-combo-box/index";
/* InputImage */
export {
@@ -195,11 +195,11 @@ export {
type CalendarProps,
} from "@opal/components/calendar/components";
/* Checkbox */
/* InputCheckbox */
export {
Checkbox,
type CheckboxProps,
} from "@opal/components/checkbox/components";
InputCheckbox,
type InputCheckboxProps,
} from "@opal/components/inputs/booleans/input-checkbox/components";
/* Table */
export { Table } from "@opal/components/table/components";
@@ -249,7 +249,7 @@ export {
export {
InputDatePicker,
type InputDatePickerProps,
} from "@opal/components/inputs/input-date-picker/components";
} from "@opal/components/inputs/chrono/input-date-picker/components";
/* InputSingleSelect */
export {
@@ -258,14 +258,14 @@ export {
type InputSingleSelectTriggerProps,
type InputSingleSelectItemProps,
type InputSingleSelectSearchProps,
} from "@opal/components/inputs/input-select/input-single-select/components";
} from "@opal/components/inputs/selections/input-single-select/components";
/* InputMultiSelect */
export {
InputMultiSelect,
type InputMultiSelectProps,
type TagItem,
} from "@opal/components/inputs/input-select/input-multi-select/components";
} from "@opal/components/inputs/selections/input-multi-select/components";
/* InputPasswordTypeIn */
export {
@@ -284,7 +284,7 @@ export {
InputTime,
type InputTimeProps,
type TimeValue,
} from "@opal/components/inputs/input-time/components";
} from "@opal/components/inputs/chrono/input-time/components";
/* Spacer */
export { Spacer, type SpacerProps } from "@opal/components/spacer/components";
@@ -293,7 +293,7 @@ export { Spacer, type SpacerProps } from "@opal/components/spacer/components";
export {
InputSwitch,
type InputSwitchProps,
} from "@opal/components/inputs/input-switch/components";
} from "@opal/components/inputs/booleans/input-switch/components";
/* CopyButton */
export {
@@ -1,14 +1,14 @@
import type { Meta, StoryObj } from "@storybook/react-vite";
import { Checkbox, Text } from "@opal/components";
import { InputCheckbox, Text } from "@opal/components";
const meta = {
title: "Components/Checkbox",
component: Checkbox,
title: "opal/Inputs/InputCheckbox",
component: InputCheckbox,
tags: ["autodocs"],
parameters: {
layout: "centered",
},
} satisfies Meta<typeof Checkbox>;
} satisfies Meta<typeof InputCheckbox>;
export default meta;
@@ -54,7 +54,7 @@ export const DisabledChecked: Story = {
export const WithLabel: StoryObj = {
render: () => (
<div className="flex items-center gap-2">
<Checkbox id="terms" />
<InputCheckbox id="terms" />
<label htmlFor="terms" className="cursor-pointer">
<Text font="main-ui-body" color="text-04">
Accept terms and conditions
@@ -82,7 +82,7 @@ export const AllStates: StoryObj = {
] as const
).map(([label, props]) => (
<div key={label} className="flex items-center gap-3">
<Checkbox {...props} />
<InputCheckbox {...props} />
<Text font="secondary-body" color="text-03">
{label}
</Text>
@@ -1,6 +1,6 @@
# Checkbox
# InputCheckbox
**Import:** `import { Checkbox, type CheckboxProps } from "@opal/components";`
**Import:** `import { InputCheckbox, type InputCheckboxProps } from "@opal/components";`
A dual-element checkbox with custom styling. Uses a hidden native `<input>` for form state and a visible `<div>` for the visual surface. Supports controlled, uncontrolled, indeterminate, and disabled modes.
@@ -50,23 +50,23 @@ defined in `styles.css`:
## Usage Examples
```tsx
import { Checkbox } from "@opal/components";
import { InputCheckbox } from "@opal/components";
// Uncontrolled
<Checkbox onCheckedChange={(checked) => console.log(checked)} />
<InputCheckbox onCheckedChange={(checked) => console.log(checked)} />
// Controlled
<Checkbox checked={isChecked} onCheckedChange={setIsChecked} />
<InputCheckbox checked={isChecked} onCheckedChange={setIsChecked} />
// With label
<div className="flex items-center gap-2">
<Checkbox id="terms" />
<InputCheckbox id="terms" />
<label htmlFor="terms">Accept terms</label>
</div>
// Indeterminate (e.g. "select all" with partial selection)
<Checkbox indeterminate />
<InputCheckbox indeterminate />
// Disabled
<Checkbox disabled checked />
<InputCheckbox disabled checked />
```
@@ -1,8 +1,7 @@
"use client";
import "@opal/components/checkbox/styles.css";
import "@opal/components/inputs/booleans/input-checkbox/styles.css";
import React, { useEffect, useRef, useState } from "react";
import { cn } from "@opal/utils";
import { SvgCheck, SvgMinus } from "@opal/icons";
import type { WithoutStyles } from "@opal/types";
@@ -12,17 +11,8 @@ import type { WithoutStyles } from "@opal/types";
type CheckboxState = "unchecked" | "checked" | "indeterminate";
interface CheckboxProps extends WithoutStyles<
Omit<React.ComponentPropsWithoutRef<"input">, "type" | "size">
> {
checked?: boolean;
defaultChecked?: boolean;
onCheckedChange?: (checked: boolean) => void;
indeterminate?: boolean;
}
// ---------------------------------------------------------------------------
// Checkbox
// InputCheckbox
// ---------------------------------------------------------------------------
/**
@@ -35,23 +25,31 @@ interface CheckboxProps extends WithoutStyles<
*
* All visual states are driven by CSS in `styles.css`.
*/
function CheckboxInner(
{
checked: controlledChecked,
defaultChecked,
onCheckedChange,
indeterminate = false,
disabled,
onChange,
id,
name,
"aria-label": ariaLabel,
"aria-labelledby": ariaLabelledby,
"aria-describedby": ariaDescribedby,
...props
}: CheckboxProps,
ref: React.ForwardedRef<HTMLInputElement>
) {
type InputCheckboxProps = WithoutStyles<
Omit<React.ComponentPropsWithoutRef<"input">, "type" | "size">
> & {
checked?: boolean;
defaultChecked?: boolean;
onCheckedChange?: (checked: boolean) => void;
indeterminate?: boolean;
/** Ref to the hidden `<input>`. */
ref?: React.Ref<HTMLInputElement>;
};
function InputCheckbox({
checked: controlledChecked,
defaultChecked,
onCheckedChange,
indeterminate = false,
disabled,
onChange,
id,
name,
"aria-label": ariaLabel,
"aria-labelledby": ariaLabelledby,
"aria-describedby": ariaDescribedby,
ref,
...props
}: InputCheckboxProps) {
const [uncontrolledChecked, setUncontrolledChecked] = useState(
defaultChecked ?? false
);
@@ -161,7 +159,4 @@ function CheckboxInner(
);
}
const Checkbox = React.forwardRef(CheckboxInner);
Checkbox.displayName = "Checkbox";
export default Checkbox;
export { Checkbox, type CheckboxProps };
export { InputCheckbox, type InputCheckboxProps, type CheckboxState };
@@ -1,7 +1,7 @@
@reference "#reference.css";
/* ============================================================================
Checkbox — state x disabled color matrix
InputCheckbox — state x disabled color matrix
Visual styling is driven by two data attributes on the root element:
- `data-state`: "unchecked" | "checked" | "indeterminate"
@@ -28,7 +28,7 @@ import { InputSwitch } from "@opal/components";
| `onCheckedChange` | `(checked: boolean) => void` | `undefined` | Called with the new value when toggled. |
| `disabled` | `boolean` | `false` | Disables interaction and applies muted styles. |
All other `<button>` attributes (except `style`, `className`, and `onChange`) are forwarded.
All other `<button>` attributes (except `style`, `className`, `onChange`, and `type` — the switch is always `type="button"`) are forwarded.
## Visual States
@@ -0,0 +1,86 @@
"use client";
import "@opal/components/inputs/booleans/input-switch/styles.css";
import React, { useState } from "react";
import { cn } from "@opal/utils";
import type { WithoutStyles } from "@opal/types";
/**
* Accessible toggle switch. Supports controlled and uncontrolled modes.
*
* - Controlled: pass `checked` + `onCheckedChange`.
* - Uncontrolled: pass `defaultChecked` (defaults to `false`).
*/
type InputSwitchProps = WithoutStyles<
Omit<React.ComponentPropsWithoutRef<"button">, "onChange" | "type">
> & {
disabled?: boolean;
checked?: boolean;
defaultChecked?: boolean;
onCheckedChange?: (checked: boolean) => void;
/** Ref to the switch `<button>`. */
ref?: React.Ref<HTMLButtonElement>;
};
function InputSwitch({
ref,
disabled,
checked: controlledChecked,
defaultChecked,
onCheckedChange,
onClick,
...props
}: InputSwitchProps) {
const [uncontrolledChecked, setUncontrolledChecked] = useState(
defaultChecked ?? false
);
const isControlled = controlledChecked !== undefined;
const checked = isControlled ? controlledChecked : uncontrolledChecked;
function handleClick(event: React.MouseEvent<HTMLButtonElement>) {
if (disabled) return;
const newChecked = !checked;
if (!isControlled) setUncontrolledChecked(newChecked);
onClick?.(event);
onCheckedChange?.(newChecked);
}
return (
<button
// Spread first: type/role/aria-checked/disabled/onClick are this
// control's contract and must not be overridable through the spread.
{...props}
ref={ref}
type="button"
role="switch"
aria-checked={checked}
className={cn(
"peer inline-flex h-4.5 w-8 shrink-0 cursor-pointer items-center rounded-full transition-colors focus-visible:outline-hidden",
disabled
? checked
? "switch-disabled-checked"
: "switch-disabled"
: checked
? "switch-normal-checked"
: "switch-normal"
)}
disabled={disabled}
onClick={handleClick}
>
<span
className={cn(
"pointer-events-none block h-3.5 w-3.5 rounded-full ring-0 transition-transform",
// rtl: the knob travels toward the inline end, so RTL negates.
checked
? "translate-x-[15px] rtl:-translate-x-[15px]"
: "translate-x-px rtl:-translate-x-px",
disabled ? "switch-thumb-disabled" : "switch-thumb"
)}
/>
</button>
);
}
export { InputSwitch, type InputSwitchProps };
@@ -1,13 +1,13 @@
import { useState } from "react";
import type { Meta, StoryObj } from "@storybook/react-vite";
import {
DateRangePicker,
InputDateRangePicker,
type DateRange,
} from "@opal/components/inputs/date-range-picker/components";
} from "@opal/components/inputs/chrono/input-date-range-picker/components";
const meta: Meta<typeof DateRangePicker> = {
title: "components/DateRangePicker",
component: DateRangePicker,
const meta: Meta<typeof InputDateRangePicker> = {
title: "components/InputDateRangePicker",
component: InputDateRangePicker,
tags: ["autodocs"],
parameters: {
layout: "centered",
@@ -22,12 +22,12 @@ const meta: Meta<typeof DateRangePicker> = {
};
export default meta;
type Story = StoryObj<typeof DateRangePicker>;
type Story = StoryObj<typeof InputDateRangePicker>;
function ControlledRange({ initialValue }: { initialValue: DateRange }) {
const [value, setValue] = useState<DateRange>(initialValue);
return <DateRangePicker value={value} onValueChange={setValue} />;
return <InputDateRangePicker value={value} onValueChange={setValue} />;
}
export const Default: Story = {
@@ -1,8 +1,8 @@
import { render, screen } from "@tests/setup/test-utils";
import userEvent from "@testing-library/user-event";
import { DateRangePicker } from "@opal/components";
import { InputDateRangePicker } from "@opal/components";
describe("DateRangePicker", () => {
describe("InputDateRangePicker", () => {
beforeEach(() => {
jest.useFakeTimers();
jest.setSystemTime(new Date(2026, 7, 4, 12));
@@ -17,7 +17,7 @@ describe("DateRangePicker", () => {
const onValueChange = jest.fn();
render(
<DateRangePicker
<InputDateRangePicker
value={{
from: new Date(2026, 7, 1),
to: new Date(2026, 7, 4),
@@ -55,7 +55,7 @@ describe("DateRangePicker", () => {
const onValueChange = jest.fn();
render(
<DateRangePicker
<InputDateRangePicker
value={{
from: new Date(2026, 6, 5),
to: new Date(2026, 7, 4),
@@ -77,7 +77,7 @@ describe("DateRangePicker", () => {
const onValueChange = jest.fn();
render(
<DateRangePicker
<InputDateRangePicker
value={{
from: new Date(2026, 6, 6),
to: new Date(2026, 7, 4),
@@ -99,7 +99,7 @@ describe("DateRangePicker", () => {
const onValueChange = jest.fn();
render(
<DateRangePicker
<InputDateRangePicker
value={{
from: new Date(2026, 6, 6),
to: new Date(2026, 7, 4),
@@ -121,7 +121,7 @@ describe("DateRangePicker", () => {
const onValueChange = jest.fn();
render(
<DateRangePicker
<InputDateRangePicker
value={{
from: new Date(2026, 6, 6),
to: new Date(2026, 7, 4),
@@ -142,7 +142,7 @@ describe("DateRangePicker", () => {
const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime });
render(
<DateRangePicker
<InputDateRangePicker
value={{
from: new Date(2026, 6, 10),
to: new Date(2026, 6, 15),
@@ -1,6 +1,6 @@
# DateRangePicker
# InputDateRangePicker
**Import:** `import { DateRangePicker, rangeForInclusiveDays, type DateRange } from "@opal/components";`
**Import:** `import { InputDateRangePicker, rangeForInclusiveDays, type DateRange } from "@opal/components";`
A preset-strip date-range control: 1D / 7D / 1M / 3M buttons plus a "Custom" trigger that opens
the Opal `Calendar` in a popover for an arbitrary range. The active custom range renders as its
@@ -8,7 +8,7 @@ import { useOpalStrings, type OpalStrings } from "@opal/strings";
export const THIRTY_DAYS = "1M";
export type DateRangePickerValue = DateRange & {
export type InputDateRangePickerValue = DateRange & {
selectValue: string;
};
@@ -85,7 +85,7 @@ function presetDisplayLabel(strings: OpalStrings, preset: DatePreset): string {
}
}
export const DateRangePicker = memo(function DateRangePicker({
export const InputDateRangePicker = memo(function InputDateRangePicker({
value,
onValueChange,
size = "md",
@@ -1,97 +0,0 @@
"use client";
import "@opal/components/inputs/input-switch/styles.css";
import React, { useState } from "react";
import { cn } from "@opal/utils";
import type { WithoutStyles } from "@opal/types";
// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------
export interface InputSwitchProps extends WithoutStyles<
Omit<React.ComponentPropsWithoutRef<"button">, "onChange">
> {
disabled?: boolean;
checked?: boolean;
defaultChecked?: boolean;
onCheckedChange?: (checked: boolean) => void;
}
// ---------------------------------------------------------------------------
// Component
// ---------------------------------------------------------------------------
/**
* Accessible toggle switch. Supports controlled and uncontrolled modes.
*
* - Controlled: pass `checked` + `onCheckedChange`.
* - Uncontrolled: pass `defaultChecked` (defaults to `false`).
*/
const InputSwitch = React.forwardRef<HTMLButtonElement, InputSwitchProps>(
(
{
disabled,
checked: controlledChecked,
defaultChecked,
onCheckedChange,
onClick,
...props
},
ref
) => {
const [uncontrolledChecked, setUncontrolledChecked] = useState(
defaultChecked ?? false
);
const isControlled = controlledChecked !== undefined;
const checked = isControlled ? controlledChecked : uncontrolledChecked;
function handleClick(event: React.MouseEvent<HTMLButtonElement>) {
if (disabled) return;
const newChecked = !checked;
if (!isControlled) setUncontrolledChecked(newChecked);
onClick?.(event);
onCheckedChange?.(newChecked);
}
return (
<button
ref={ref}
type="button"
role="switch"
aria-checked={checked}
className={cn(
"peer inline-flex h-4.5 w-8 shrink-0 cursor-pointer items-center rounded-full transition-colors focus-visible:outline-hidden",
disabled
? checked
? "switch-disabled-checked"
: "switch-disabled"
: checked
? "switch-normal-checked"
: "switch-normal"
)}
disabled={disabled}
onClick={handleClick}
{...props}
>
<span
className={cn(
"pointer-events-none block h-3.5 w-3.5 rounded-full ring-0 transition-transform",
// rtl: the knob travels toward the inline end, so RTL negates.
checked
? "translate-x-[15px] rtl:-translate-x-[15px]"
: "translate-x-px rtl:-translate-x-px",
disabled ? "switch-thumb-disabled" : "switch-thumb"
)}
/>
</button>
);
}
);
InputSwitch.displayName = "InputSwitch";
export default InputSwitch;
export { InputSwitch };
@@ -3,7 +3,7 @@
import "@opal/components/inputs/shared.css";
// The inner field reuses InputTypeIn's .opal-input-field styling.
import "@opal/components/inputs/input-type-in/styles.css";
import "@opal/components/inputs/input-select/input-multi-select/styles.css";
import "@opal/components/inputs/selections/input-multi-select/styles.css";
import { useEffect, useRef } from "react";
import type { IconFunctionComponent } from "@opal/types";
import { Button, Tag, TAG_REMOVE_CLASS } from "@opal/components";
@@ -1,7 +1,7 @@
"use client";
import "@opal/components/inputs/shared.css";
import "@opal/components/inputs/input-select/input-single-select/styles.css";
import "@opal/components/inputs/selections/input-single-select/styles.css";
import React from "react";
import * as SelectPrimitive from "@radix-ui/react-select";
import { cn } from "@opal/utils";
+1 -1
View File
@@ -61,4 +61,4 @@ When a `[data-main-container]` element is present (the content area beside the s
## Deferred
The remaining Figma header/footer content variants (Search, Card, Panel, Checkbox, Message) are follow-ups.
The remaining Figma header/footer content variants (Search, Card, Panel, InputCheckbox, Message) are follow-ups.
@@ -5,7 +5,7 @@ import { cn } from "@opal/utils";
import { useTableSize } from "@opal/components/table/TableSizeContext";
import type { IconFunctionComponent } from "@opal/types";
import type { QualifierContentType } from "@opal/components/table/types";
import { Checkbox } from "@opal/components";
import { InputCheckbox } from "@opal/components";
interface TableQualifierProps {
/** Content type displayed in the qualifier */
@@ -118,7 +118,7 @@ function TableQualifier({
content === "simple" ? "flex" : overlayStyles
)}
>
<Checkbox
<InputCheckbox
checked={selected}
onCheckedChange={onSelectChange}
disabled={disabled}
@@ -21,7 +21,7 @@ import QualifierContainer from "@opal/components/table/QualifierContainer";
import ActionsContainer from "@opal/components/table/ActionsContainer";
import DragOverlayRow from "@opal/components/table/DragOverlayRow";
import Footer from "@opal/components/table/Footer";
import { Checkbox } from "@opal/components";
import { InputCheckbox } from "@opal/components";
import { TableSizeProvider } from "@opal/components/table/TableSizeContext";
import { ColumnVisibilityPopover } from "@opal/components/table/ColumnVisibilityPopover";
import { SortingPopover } from "@opal/components/table/ColumnSortabilityPopover";
@@ -387,7 +387,7 @@ export function Table<TData>(props: DataTableProps<TData>) {
return (
<QualifierContainer key={header.id} type="head">
{isMultiSelect && (
<Checkbox
<InputCheckbox
checked={isAllRowsSelected}
indeterminate={
!isAllRowsSelected && selectedCount > 0
@@ -15,7 +15,7 @@ import { Button } from "@opal/components";
import { cn } from "@opal/utils";
import { SvgChevronDownSmall, SvgTrash } from "@opal/icons";
function Checkbox({
function InputCheckbox({
label,
checked,
onChange,
@@ -142,7 +142,7 @@ export const ExistingSlackBotForm = ({
</div>
<div className="mt-2">
<div className="inline-block border rounded-lg border-background-200 p-2">
<Checkbox
<InputCheckbox
label={t("updateForm.enabledCheckbox.label")}
checked={formValues.enabled}
onChange={(e) => handleUpdateField("enabled", e.target.checked)}
@@ -11,7 +11,7 @@ import {
TableHeader,
TableRow,
} from "@/components/ui/table";
import { Checkbox } from "@opal/components";
import { InputCheckbox } from "@opal/components";
import {
updateConnectorFiles,
type ConnectorFileInfo,
@@ -246,7 +246,7 @@ export default function InlineFileManagement({
>
{isEditing && (
<TableCell>
<Checkbox
<InputCheckbox
checked={isMarkedForRemoval}
onCheckedChange={() =>
toggleFileForRemoval(file.file_id)
@@ -5,7 +5,7 @@ import { useState, useEffect, useCallback } from "react";
import { useTranslations } from "next-intl";
import { OnyxDocument } from "@/lib/search/interfaces";
import { buildDocumentSummaryDisplay } from "@/components/search/DocumentDisplay";
import { Checkbox } from "@opal/components";
import { InputCheckbox } from "@opal/components";
import { updateHiddenStatus } from "../lib";
import { toast } from "@opal/layouts";
import { getErrorMsg } from "@/lib/fetchUtils";
@@ -98,7 +98,7 @@ const DocumentDisplay = ({
)}
</div>
<div className="ms-1 my-auto">
<Checkbox checked={!document.hidden} />
<InputCheckbox checked={!document.hidden} />
</div>
</div>
</div>
@@ -16,7 +16,7 @@ import { numToDisplay } from "./constants";
import { FiEye, FiEyeOff } from "react-icons/fi";
import { getErrorMsg } from "@/lib/fetchUtils";
import { HoverPopup } from "@/components/HoverPopup";
import { Checkbox } from "@opal/components";
import { InputCheckbox } from "@opal/components";
import { ScoreSection } from "../ScoreEditor";
import { truncateString } from "@/lib/utils";
import { clickOnKeyDown } from "@opal/utils";
@@ -48,7 +48,7 @@ const IsVisibleSection = ({
>
<div className="select-none">{t("visibility.hidden.label")}</div>
<div className="ms-1 my-auto">
<Checkbox checked={false} />
<InputCheckbox checked={false} />
</div>
</div>
) : (
@@ -64,7 +64,7 @@ const IsVisibleSection = ({
{t("visibility.visible.label")}
</div>
<div className="ms-1 my-auto">
<Checkbox checked={true} />
<InputCheckbox checked={true} />
</div>
</div>
)
+2 -2
View File
@@ -5,7 +5,7 @@ import { useSettings } from "@/lib/settings/hooks";
import { Button } from "@opal/components";
import Text from "@/refresh-components/texts/Text";
import { FormField } from "@/refresh-components/form/FormField";
import { Checkbox } from "@opal/components";
import { InputCheckbox } from "@opal/components";
import { useEffect, useState } from "react";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
@@ -130,7 +130,7 @@ export function AppPopup() {
>
<div className="flex items-center gap-1">
<FormField.Control>
<Checkbox
<InputCheckbox
aria-label={t("consentCheckbox.label")}
checked={consentChecked}
onCheckedChange={(checked) => {
@@ -27,7 +27,7 @@ import {
type ModelPrice,
} from "@/app/app/settings/usage/lib";
import {
DateRangePicker,
InputDateRangePicker,
rangeForInclusiveDays,
type DateRange,
} from "@opal/components";
@@ -448,7 +448,7 @@ export default function UsageSettings() {
<Section gap={0.75} justifyContent="start">
<div className="flex w-full flex-wrap items-center justify-between gap-3">
<Text font="heading-h3">{t("header.title")}</Text>
<DateRangePicker
<InputDateRangePicker
value={dateRange}
onValueChange={setDateRange}
size="sm"
@@ -1,7 +1,7 @@
"use client";
import { useTranslations } from "next-intl";
import { Card, Checkbox, Text } from "@opal/components";
import { Card, InputCheckbox, Text } from "@opal/components";
import { SvgMcp } from "@opal/icons";
import type { IconFunctionComponent } from "@opal/types";
import { cn } from "@opal/utils";
@@ -213,7 +213,7 @@ function PreApprovalRow({ option, checked, onToggle }: PreApprovalRowProps) {
{option.status}
</Text>
</div>
<Checkbox
<InputCheckbox
id={checkboxId}
aria-label={option.name}
aria-describedby={statusId}
+1 -1
View File
@@ -114,7 +114,7 @@
display: none;
}
/* Checkbox Cell
/* InputCheckbox Cell
Figma specs:
- Width: 24px (1.5rem)
- Centered content
@@ -9,7 +9,7 @@ import {
import { ADMIN_ROUTES } from "@/lib/admin-routes";
import {
DateRange,
DateRangePicker,
InputDateRangePicker,
rangeForInclusiveDays,
} from "@opal/components";
import { useCallback, useState } from "react";
@@ -54,7 +54,7 @@ export default function QueryHistoryPage() {
title={adminRouteTitle(route)}
divider
rightChildren={
<DateRangePicker
<InputDateRangePicker
value={dateRange}
onValueChange={onTimeRangeChange}
/>
@@ -2,7 +2,7 @@
import { useAdminRouteTitle } from "@/lib/adminNavLabels";
import { useTranslations } from "next-intl";
import { DateRangePicker } from "@opal/components";
import { InputDateRangePicker } from "@opal/components";
import { useTimeRange } from "@/lib/usage/hooks";
import PerUserUsagePanel from "@/views/admin/PerUserUsagePanel";
import SystemUsagePanel from "@/views/admin/SystemUsagePanel";
@@ -26,7 +26,7 @@ export default function UsagePage() {
description={t("page.description")}
divider
rightChildren={
<DateRangePicker
<InputDateRangePicker
value={timeRange}
onValueChange={(value) => {
if (!value) return;
@@ -2,7 +2,7 @@
import { useEffect, useState, useMemo } from "react";
import { useLocale, useTranslations } from "next-intl";
import { Card, DateRange, DateRangePicker, Text } from "@opal/components";
import { Card, DateRange, InputDateRangePicker, Text } from "@opal/components";
import { Section } from "@opal/layouts";
import { useAgents } from "@/lib/agents/hooks";
import AgentAvatar from "@/refresh-components/avatars/AgentAvatar";
@@ -136,7 +136,7 @@ export function AgentStats({ agentId }: AgentStatsProps) {
{/* sm:flex-row / sm:items-center / sm:justify-between have no Section equivalent, kept as a raw div */}
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
<Text font="heading-h2">{t("analytics.agentChart.title")}</Text>
<DateRangePicker value={dateRange} onValueChange={setDateRange} />
<InputDateRangePicker value={dateRange} onValueChange={setDateRange} />
</div>
<Section
+2 -2
View File
@@ -28,7 +28,7 @@ import { useState, useEffect, memo, JSX } from "react";
import remarkGfm from "remark-gfm";
import {
Button,
Checkbox,
InputCheckbox,
InputDatePicker,
InputTextArea,
type InputTextAreaProps,
@@ -771,7 +771,7 @@ export const BooleanFormField = memo(function BooleanFormField({
removeIndent ? "me-2" : "mx-3"
)}
>
<Checkbox
<InputCheckbox
aria-label={`${label
.toLowerCase()
.replace(" ", "-")}-checkbox`}
@@ -2,7 +2,7 @@
import { useState, useEffect } from "react";
import { useTranslations } from "next-intl";
import { Button, Checkbox, Divider, Tooltip } from "@opal/components";
import { Button, InputCheckbox, Divider, Tooltip } from "@opal/components";
import {
ConfigurableSources,
CredentialFieldSpec,
@@ -662,7 +662,7 @@ export function FederatedConnectorForm({
<div key={fieldKey} className="space-y-2 w-full">
{isBoolType ? (
<div className="flex items-center gap-3 py-2">
<Checkbox
<InputCheckbox
checked={
formState.config[fieldKey] !== undefined
? Boolean(formState.config[fieldKey])
@@ -1,4 +1,4 @@
import { DateRangePickerValue } from "@opal/components";
import { InputDateRangePickerValue } from "@opal/components";
import { useTranslations } from "next-intl";
import { FiCalendar, FiChevronDown, FiXCircle } from "react-icons/fi";
import { CustomDropdown } from "../Dropdown";
@@ -12,8 +12,8 @@ export function SearchDateRangeSelector({
isHorizontal,
className,
}: {
value: DateRangePickerValue | null;
onValueChange: (value: DateRangePickerValue | null) => void;
value: InputDateRangePickerValue | null;
onValueChange: (value: InputDateRangePickerValue | null) => void;
isHorizontal?: boolean;
className?: string;
}) {
@@ -3,15 +3,15 @@ import { DocumentSetSummary, Tag, ValidSources } from "@/lib/types";
import { SourceMetadata } from "@/lib/search/interfaces";
import { FiBook, FiBookmark, FiMap, FiX } from "react-icons/fi";
import { SearchDateRangeSelector } from "@/components/dateRangeSelectors/SearchDateRangeSelector";
import { DateRangePickerValue } from "@opal/components";
import { InputDateRangePickerValue } from "@opal/components";
import { listSourceMetadata } from "@/lib/sources";
import { SourceIcon } from "@/components/SourceIcon";
import { FilterDropdown } from "@/components/search/filtering/FilterDropdown";
export interface SourceSelectorProps {
timeRange: DateRangePickerValue | null;
timeRange: InputDateRangePickerValue | null;
setTimeRange: React.Dispatch<
React.SetStateAction<DateRangePickerValue | null>
React.SetStateAction<InputDateRangePickerValue | null>
>;
showDocSidebar?: boolean;
selectedSources: SourceMetadata[];
@@ -4,7 +4,7 @@ import { useState } from "react";
import { useTranslations } from "next-intl";
import { ConfirmationModalLayout } from "@opal/layouts";
import { Button } from "@opal/components";
import { Checkbox } from "@opal/components";
import { InputCheckbox } from "@opal/components";
import Text from "@/refresh-components/texts/Text";
import { SvgAlertCircle } from "@opal/icons";
interface MoveCustomAgentChatModalProps {
@@ -37,7 +37,7 @@ export function MoveCustomAgentChatModal({
})}
</Text>
<div className="flex items-center gap-1">
<Checkbox
<InputCheckbox
id="move-custom-agent-do-not-show"
checked={doNotShowAgain}
onCheckedChange={(checked) => setDoNotShowAgain(Boolean(checked))}
+1 -1
View File
@@ -20,7 +20,7 @@ import {
useRef,
useState,
} from "react";
import { DateRangePickerValue } from "@opal/components";
import { InputDateRangePickerValue } from "@opal/components";
import { SourceMetadata } from "./search/interfaces";
import {
getProviderOverrideForAgent,
+2 -2
View File
@@ -1,4 +1,4 @@
import { DateRangePickerValue } from "@opal/components";
import { InputDateRangePickerValue } from "@opal/components";
import { Tag, ValidSources } from "../types";
import { Agent } from "@/lib/agents/types";
@@ -159,7 +159,7 @@ export interface SearchRequestArgs {
agentic?: boolean;
sources: SourceMetadata[];
documentSets: string[];
timeRange: DateRangePickerValue | null;
timeRange: InputDateRangePickerValue | null;
tags: Tag[];
persona: Agent;
updateDocumentRelevance: (relevance: any) => void;
+4 -2
View File
@@ -6,12 +6,14 @@ import { errorHandlingFetcher } from "@/lib/fetcher";
import { SWR_KEYS } from "@/lib/swr-keys";
import type { Tag, ValidSources } from "@/lib/types";
import type { SourceMetadata } from "@/lib/search/interfaces";
import type { DateRangePickerValue } from "@opal/components";
import type { InputDateRangePickerValue } from "@opal/components";
import { getConfiguredSources } from "@/lib/sources";
import type { SearchFilters } from "@/lib/searchFilters/types";
export function useSearchFilters(): SearchFilters {
const [timeRange, setTimeRange] = useState<DateRangePickerValue | null>(null);
const [timeRange, setTimeRange] = useState<InputDateRangePickerValue | null>(
null
);
const [selectedSources, setSelectedSources] = useState<SourceMetadata[]>([]);
const [selectedDocumentSets, setSelectedDocumentSets] = useState<string[]>(
[]
+3 -3
View File
@@ -1,10 +1,10 @@
import type { Tag } from "@/lib/types";
import type { SourceMetadata } from "@/lib/search/interfaces";
import type { DateRangePickerValue } from "@opal/components";
import type { InputDateRangePickerValue } from "@opal/components";
/** What is selected, without the means to change it. */
export interface SearchFiltersSelection {
timeRange: DateRangePickerValue | null;
timeRange: InputDateRangePickerValue | null;
selectedSources: SourceMetadata[];
selectedDocumentSets: string[];
selectedTags: Tag[];
@@ -13,7 +13,7 @@ export interface SearchFiltersSelection {
/** The live selection a user edits: which sources, sets, tags and dates to search. */
export interface SearchFilters extends SearchFiltersSelection {
setTimeRange: React.Dispatch<
React.SetStateAction<DateRangePickerValue | null>
React.SetStateAction<InputDateRangePickerValue | null>
>;
setSelectedSources: React.Dispatch<React.SetStateAction<SourceMetadata[]>>;
setSelectedDocumentSets: React.Dispatch<React.SetStateAction<string[]>>;
+2 -2
View File
@@ -1,13 +1,13 @@
import type { Tag } from "@/lib/types";
import type { SourceMetadata } from "@/lib/search/interfaces";
import type { DateRangePickerValue } from "@opal/components";
import type { InputDateRangePickerValue } from "@opal/components";
import type { SearchFiltersRequest } from "@/lib/searchFilters/types";
/** Freezes a live selection into the shape the backend receives. */
export function buildFilters(
sources: SourceMetadata[],
documentSets: string[],
timeRange: DateRangePickerValue | null,
timeRange: InputDateRangePickerValue | null,
tags: Tag[]
): SearchFiltersRequest {
return {
+8 -8
View File
@@ -21,12 +21,12 @@ import type { SystemUsageResponse } from "@/lib/usage/systemUsage";
import {
THIRTY_DAYS,
type DateRange,
type DateRangePickerValue,
type InputDateRangePickerValue,
rangeForInclusiveDays,
} from "@opal/components";
export function useTimeRange() {
return useState<DateRangePickerValue>({
return useState<InputDateRangePickerValue>({
...rangeForInclusiveDays(30),
selectValue: THIRTY_DAYS,
});
@@ -46,14 +46,14 @@ export function useSystemUsage(range?: DateRange) {
return { usage: data, isLoading, error, refetch: mutate };
}
function analyticsRange(timeRange: DateRangePickerValue) {
function analyticsRange(timeRange: InputDateRangePickerValue) {
return {
start: convertDateToStartOfDay(timeRange.from)?.toISOString(),
end: convertDateToEndOfDay(timeRange.to)?.toISOString(),
};
}
export function useQueryAnalytics(timeRange: DateRangePickerValue) {
export function useQueryAnalytics(timeRange: InputDateRangePickerValue) {
const url = buildApiPath(
"/api/analytics/admin/query",
analyticsRange(timeRange)
@@ -66,7 +66,7 @@ export function useQueryAnalytics(timeRange: DateRangePickerValue) {
};
}
export function useUserAnalytics(timeRange: DateRangePickerValue) {
export function useUserAnalytics(timeRange: InputDateRangePickerValue) {
const url = buildApiPath(
"/api/analytics/admin/user",
analyticsRange(timeRange)
@@ -79,7 +79,7 @@ export function useUserAnalytics(timeRange: DateRangePickerValue) {
};
}
export function useOnyxBotAnalytics(timeRange: DateRangePickerValue) {
export function useOnyxBotAnalytics(timeRange: InputDateRangePickerValue) {
const url = buildApiPath(
"/api/analytics/admin/onyxbot",
analyticsRange(timeRange)
@@ -94,7 +94,7 @@ export function useOnyxBotAnalytics(timeRange: DateRangePickerValue) {
export function usePersonaMessages(
personaId: number | undefined,
timeRange: DateRangePickerValue
timeRange: InputDateRangePickerValue
) {
const url = buildApiPath("/api/analytics/admin/persona/messages", {
persona_id: personaId?.toString(),
@@ -116,7 +116,7 @@ export function usePersonaMessages(
export function usePersonaUniqueUsers(
personaId: number | undefined,
timeRange: DateRangePickerValue
timeRange: InputDateRangePickerValue
) {
const url = buildApiPath("/api/analytics/admin/persona/unique-users", {
persona_id: personaId?.toString(),
@@ -1,10 +1,10 @@
"use client";
import { useField } from "formik";
import { Checkbox, type CheckboxProps } from "@opal/components";
import { InputCheckbox, type InputCheckboxProps } from "@opal/components";
import { useOnChangeValue } from "@/hooks/formHooks";
interface CheckboxFieldProps extends Omit<CheckboxProps, "checked"> {
interface CheckboxFieldProps extends Omit<InputCheckboxProps, "checked"> {
name: string;
}
@@ -17,6 +17,10 @@ export default function UnlabeledCheckboxField({
const onChange = useOnChangeValue(name, onCheckedChange);
return (
<Checkbox checked={field.value} onCheckedChange={onChange} {...props} />
<InputCheckbox
checked={field.value}
onCheckedChange={onChange}
{...props}
/>
);
}
@@ -74,7 +74,7 @@ type Story = StoryObj;
// CheckboxField (unlabeled)
// ---------------------------------------------------------------------------
export const Checkbox: Story = {
export const InputCheckbox: Story = {
name: "CheckboxField (unlabeled)",
render: () => (
<FormikWrapper initialValues={{ agree: false }}>
@@ -4,7 +4,7 @@ import React from "react";
import { useField } from "formik";
import { cn } from "@opal/utils";
import { Tooltip } from "@opal/components";
import { Checkbox } from "@opal/components";
import { InputCheckbox } from "@opal/components";
interface CheckboxFieldProps {
name: string;
@@ -40,7 +40,7 @@ export const CheckboxField: React.FC<CheckboxFieldProps> = ({
const checkboxContent = (
<div className="flex w-fit items-start space-x-2">
<Checkbox
<InputCheckbox
id={name}
aria-labelledby={labelId}
checked={field.value}
@@ -12,7 +12,7 @@ import * as GeneralLayouts from "@/layouts/general-layouts";
import * as TableLayouts from "@/layouts/table-layouts";
import {
Button,
Checkbox,
InputCheckbox,
CopyButton,
Divider as OpalDivider,
InputTypeIn,
@@ -721,7 +721,7 @@ export default function SourceHierarchyBrowser({
return <SvgFolder size={16} />;
}
if (isSelected) {
return <Checkbox checked={true} />;
return <InputCheckbox checked={true} />;
}
return <SvgFileText size={16} />;
};
@@ -803,7 +803,7 @@ export default function SourceHierarchyBrowser({
<TableLayouts.TableRow>
<TableLayouts.CheckboxCell>
{filteredItems.length > 0 && (
<Checkbox
<InputCheckbox
checked={allVisibleSelected}
indeterminate={someVisibleSelected}
onCheckedChange={handleHeaderCheckboxClick}
@@ -15,7 +15,7 @@ import type { SearchDocWithContent } from "@/lib/search/interfaces";
import type { ValidSources } from "@/lib/types";
import {
Button,
Checkbox,
InputCheckbox,
Divider,
InputTypeIn,
LineItemButton,
@@ -305,7 +305,7 @@ export function KnowledgeSearchResultsPanel({
aria-label={`search-node-${node.id}`}
>
<TableLayouts.CheckboxCell>
<Checkbox
<InputCheckbox
checked={isSelected}
onCheckedChange={() => onToggleFolder(node.id)}
/>
@@ -370,7 +370,7 @@ export function KnowledgeSearchResultsPanel({
aria-label={`search-doc-${doc.document_id}`}
>
<TableLayouts.CheckboxCell>
<Checkbox
<InputCheckbox
checked={isSelected}
onCheckedChange={() => onToggleDocument(doc.document_id)}
/>
@@ -5,7 +5,7 @@ import { useTranslations } from "next-intl";
import * as GeneralLayouts from "@/layouts/general-layouts";
import * as TableLayouts from "@/layouts/table-layouts";
import Text from "@/refresh-components/texts/Text";
import { Checkbox, Divider, InputTypeIn, Spacer } from "@opal/components";
import { InputCheckbox, Divider, InputTypeIn, Spacer } from "@opal/components";
import { SvgFilter } from "@opal/icons";
export interface KnowledgeTableColumn<T> {
@@ -117,7 +117,7 @@ export function KnowledgeTable<T>({
}
>
<TableLayouts.CheckboxCell>
<Checkbox
<InputCheckbox
checked={isSelected}
onCheckedChange={() => onToggleItem(id)}
/>
@@ -15,7 +15,7 @@ import type {
LLMProviderView,
ModelConfiguration,
} from "@/lib/languageModels/types";
import { Checkbox } from "@opal/components";
import { InputCheckbox } from "@opal/components";
import InputTypeInField from "@/refresh-components/form/InputTypeInField";
import { InputTypeIn } from "@opal/components";
import { InputComboBox } from "@opal/components";
@@ -641,7 +641,7 @@ function ModelRow({
variant="section"
sizePreset="main-ui"
center
icon={() => <Checkbox checked={isSelected} />}
icon={() => <InputCheckbox checked={isSelected} />}
title={displayName}
description={buildModelDescription(model)}
rightChildren={
@@ -6,7 +6,7 @@ import type { Route } from "next";
import {
Button,
Card,
Checkbox,
InputCheckbox,
InputTypeIn,
MessageCard,
Modal,
@@ -387,7 +387,7 @@ export function ImportSkillsFromGitHubModalView({
{preview && (
<div className="flex min-h-0 flex-col gap-2">
<div className="flex items-center gap-2">
<Checkbox
<InputCheckbox
checked={allImportableSelected}
indeterminate={
selectedPaths.length > 0 && !allImportableSelected
@@ -418,7 +418,7 @@ export function ImportSkillsFromGitHubModalView({
unavailable && "opacity-50"
)}
>
<Checkbox
<InputCheckbox
checked={checked}
disabled={loading || unavailable}
aria-label={t(
+2 -2
View File
@@ -56,7 +56,7 @@ import {
AttachmentItemButton,
Button,
Divider,
Checkbox,
InputCheckbox,
Text,
} from "@opal/components";
import useFederatedOAuthStatus from "@/hooks/useFederatedOAuthStatus";
@@ -204,7 +204,7 @@ function ScopeSelector({
const locked = lockReason !== undefined;
return (
<div key={option.scope} className="flex items-start gap-2 ps-2">
<Checkbox
<InputCheckbox
checked={selectedScopes.includes(option.scope) || locked}
disabled={disabled || locked}
onCheckedChange={() => toggleScope(option.scope)}
@@ -10,11 +10,11 @@ import {
resolveChartState,
useLoggedChartError,
} from "@/sections/usage/AnalyticsChart";
import { DateRangePickerValue } from "@opal/components";
import { InputDateRangePickerValue } from "@opal/components";
import { formatTokenCount } from "@/lib/format";
interface TimeRangeProps {
timeRange: DateRangePickerValue;
timeRange: InputDateRangePickerValue;
}
export function UsageChart({ timeRange }: TimeRangeProps) {
@@ -17,7 +17,7 @@ import {
chartSeries,
resolveChartState,
} from "@/sections/usage/AnalyticsChart";
import { DateRangePickerValue } from "@opal/components";
import { InputDateRangePickerValue } from "@opal/components";
import { Agent } from "@/lib/agents/types";
interface PersonaPickerProps {
@@ -107,7 +107,7 @@ function PersonaPicker({
}
interface PersonaMessagesChartProps {
timeRange: DateRangePickerValue;
timeRange: InputDateRangePickerValue;
}
export function PersonaMessagesChart({ timeRange }: PersonaMessagesChartProps) {
@@ -2,7 +2,7 @@
import { useAdminRouteTitle } from "@/lib/adminNavLabels";
import { useTranslations } from "next-intl";
import { DateRangePicker } from "@opal/components";
import { InputDateRangePicker } from "@opal/components";
import { useTimeRange } from "@/lib/usage/hooks";
import {
FeedbackChart,
@@ -30,7 +30,7 @@ export default function WorkspaceAnalyticsPage() {
description={t("page.description")}
divider
rightChildren={
<DateRangePicker
<InputDateRangePicker
value={timeRange}
onValueChange={(range) =>
setTimeRange((previous) =>