@photon-ai/pho-ui 2.17.0 → 3.0.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.
- package/dist/chunks/{basic-page-CogcwGx3.js → basic-page-CYDwfVjO.js} +2 -2
- package/dist/chunks/{basic-page-CogcwGx3.js.map → basic-page-CYDwfVjO.js.map} +1 -1
- package/dist/chunks/calendar-4OFiCLAv.js +292 -0
- package/dist/chunks/calendar-4OFiCLAv.js.map +1 -0
- package/dist/chunks/date-picker-Bwa6J4ik.js +381 -0
- package/dist/chunks/date-picker-Bwa6J4ik.js.map +1 -0
- package/dist/chunks/{error-D0yoFxCv.js → error-BAQgnde7.js} +2 -2
- package/dist/chunks/{error-D0yoFxCv.js.map → error-BAQgnde7.js.map} +1 -1
- package/dist/chunks/{filter-bar-BsvdXwzc.js → filter-bar-D9lBBr4z.js} +2 -2
- package/dist/chunks/{filter-bar-BsvdXwzc.js.map → filter-bar-D9lBBr4z.js.map} +1 -1
- package/dist/components/calendar.js +5 -0
- package/dist/components/date-picker.js +6 -0
- package/dist/components/error.js +1 -1
- package/dist/components/filter-bar.js +1 -1
- package/dist/index.js +114 -116
- package/dist/primitives.js +1 -1
- package/dist/sections/basic-page.js +1 -1
- package/dist/src/components/calendar/calendar.d.ts +36 -0
- package/dist/src/components/calendar/index.d.ts +2 -0
- package/dist/src/components/date-picker/date-picker.d.ts +97 -0
- package/dist/src/components/date-picker/index.d.ts +2 -0
- package/dist/src/index.d.ts +2 -1
- package/package.json +10 -5
- package/dist/chunks/date-range-picker-DwFDUNRL.js +0 -88
- package/dist/chunks/date-range-picker-DwFDUNRL.js.map +0 -1
- package/dist/components/date-range-picker.js +0 -10
- package/dist/src/components/date-range-picker/date-range-picker.d.ts +0 -31
- package/dist/src/components/date-range-picker/index.d.ts +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-D0yoFxCv.js","names":[],"sources":["../../../../node_modules/.pnpm/@tabler+icons-react@3.46.0_react@19.2.8/node_modules/@tabler/icons-react/dist/esm/icons/IconAlertTriangle.mjs","../../src/components/error/problem.ts","../../src/components/error/error.tsx"],"sourcesContent":["/**\n * @license @tabler/icons-react v3.46.0 - MIT\n *\n * This source code is licensed under the MIT license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createReactComponent from '../createReactComponent.mjs';\n\nconst __iconNode = [[\"path\", { \"d\": \"M12 9v4\", \"key\": \"svg-0\" }], [\"path\", { \"d\": \"M10.363 3.591l-8.106 13.534a1.914 1.914 0 0 0 1.636 2.871h16.214a1.914 1.914 0 0 0 1.636 -2.87l-8.106 -13.536a1.914 1.914 0 0 0 -3.274 0\", \"key\": \"svg-1\" }], [\"path\", { \"d\": \"M12 16h.01\", \"key\": \"svg-2\" }]];\nconst IconAlertTriangle = createReactComponent(\"outline\", \"alert-triangle\", \"AlertTriangle\", __iconNode);\n\nexport { __iconNode, IconAlertTriangle as default };\n//# sourceMappingURL=IconAlertTriangle.mjs.map\n","/**\n * Client-side mirror of the `@photon-hq/error` response contract — the\n * RFC 9457 Problem Details body every Photon service returns for 4xx / 5xx.\n * Machine logic branches on `code`; `title` / `detail` / `remediation` are\n * the human-readable copy, already reviewed server-side and safe to render.\n *\n * Fetch layers may also hand us a thin status-only shape when the response\n * was not ok but the body was not a contract problem — `title` + `status`\n * still count so the UI can disclose the HTTP code we already know.\n */\n\nexport interface ProblemRemediation {\n /** What the user can do about it — a full sentence. */\n action?: string;\n /** Docs URL explaining the problem. */\n documentation?: string;\n}\n\nexport interface Problem {\n /** Stable machine-readable key (`RATE_LIMITED`) — the field to branch on. */\n code?: string;\n /** Human summary of the problem type (\"Too Many Requests\"). */\n title: string;\n /** HTTP status (4xx / 5xx). */\n status: number;\n /** Problem type URI (`urn:photon:problem:*` or an https URL). */\n type?: string;\n /** Occurrence-specific human sentence. */\n detail?: string;\n /** Correlation id for support (`X-Request-ID`). */\n requestId?: string;\n remediation?: ProblemRemediation;\n /** RFC 9457 extensions (`issues`, `actualVersion`, …). */\n [extension: string]: unknown;\n}\n\n/** Structural check: `title` + a 4xx/5xx status. `code` is optional. */\nexport function isProblem(value: unknown): value is Problem {\n if (typeof value !== \"object\" || value === null) return false;\n const v = value as Record<string, unknown>;\n return (\n typeof v.title === \"string\" &&\n typeof v.status === \"number\" &&\n Number.isInteger(v.status) &&\n v.status >= 400 &&\n v.status <= 599 &&\n (v.code === undefined || typeof v.code === \"string\")\n );\n}\n\n/**\n * Find the problem a caught value carries — the value itself, one typed onto\n * an error as a `problem` field (dashboard's `ApiError` shape), or one\n * wrapped in an `Error` `cause` chain (how fetch layers usually rethrow a\n * parsed body). Returns `null` when there is none.\n */\nexport function parseProblem(error: unknown): Problem | null {\n let current: unknown = error;\n for (\n let depth = 0;\n depth < 8 && typeof current === \"object\" && current !== null;\n depth++\n ) {\n if (isProblem(current)) return current;\n const carried = (current as { problem?: unknown }).problem;\n if (isProblem(carried)) return carried;\n current = (current as { cause?: unknown }).cause;\n }\n return null;\n}\n\nexport interface ErrorDescription {\n /** Short name of the failure — the problem `title`, or a generic fallback. */\n title: string;\n /** Sentence(s) to show — `detail` and `remediation.action` joined. */\n description?: string;\n /** Docs URL from `remediation.documentation`. */\n documentation?: string;\n /** Correlation id for support. */\n requestId?: string;\n /** The matched problem, when the input carried one. */\n problem?: Problem;\n}\n\n/**\n * Anything that isn't a problem renders as this — raw `Error` messages are\n * not contract copy and never shown (the same fail-closed stance as the\n * server side of `@photon-hq/error`). Always a full sentence (trailing\n * period).\n */\nexport const GENERIC_ERROR_TITLE = \"Something went wrong.\";\n\n/** Standard reason phrases for statuses we commonly surface without a body. */\nconst HTTP_REASON_PHRASE: Record<number, string> = {\n 400: \"Bad Request\",\n 401: \"Unauthorized\",\n 403: \"Forbidden\",\n 404: \"Not Found\",\n 408: \"Request Timeout\",\n 409: \"Conflict\",\n 410: \"Gone\",\n 413: \"Payload Too Large\",\n 415: \"Unsupported Media Type\",\n 422: \"Unprocessable Entity\",\n 429: \"Too Many Requests\",\n 500: \"Internal Server Error\",\n 501: \"Not Implemented\",\n 502: \"Bad Gateway\",\n 503: \"Service Unavailable\",\n 504: \"Gateway Timeout\",\n};\n\n/** One-sentence explanations when the server gave a status but no problem copy. */\nconst HTTP_STATUS_EXPLANATION: Record<number, string> = {\n 400: \"The request was malformed or incomplete.\",\n 401: \"You need to sign in again.\",\n 403: \"You don't have permission to do that.\",\n 404: \"The requested resource was not found.\",\n 408: \"The request timed out before the server responded.\",\n 409: \"The request conflicts with the current state.\",\n 410: \"That resource is no longer available.\",\n 413: \"The request was too large for the server to accept.\",\n 415: \"That media type isn't supported.\",\n 422: \"The request was understood but couldn't be processed.\",\n 429: \"Request rate limit exceeded. Wait a moment before trying again.\",\n 500: \"The server hit an unexpected error.\",\n 501: \"The server doesn't support that operation.\",\n 502: \"The gateway got an invalid response from an upstream server.\",\n 503: \"The service is temporarily unavailable.\",\n 504: \"The gateway timed out waiting for an upstream server.\",\n};\n\nfunction hasContractCode(problem: Problem): boolean {\n return typeof problem.code === \"string\" && problem.code !== \"\";\n}\n\n/** Reason phrase for a status — map first, then a non-generic `problem.title`. */\nexport function httpReasonPhrase(\n status: number,\n fallbackTitle?: string,\n): string | undefined {\n if (HTTP_REASON_PHRASE[status]) return HTTP_REASON_PHRASE[status];\n if (\n fallbackTitle &&\n fallbackTitle !== GENERIC_ERROR_TITLE &&\n fallbackTitle !== \"Request failed\"\n ) {\n return fallbackTitle.replace(/\\.$/, \"\");\n }\n return undefined;\n}\n\n/** Human sentence for a bare HTTP status, when the body carried no copy. */\nexport function httpStatusExplanation(status: number): string {\n return (\n HTTP_STATUS_EXPLANATION[status] ??\n \"The request failed with an unexpected status.\"\n );\n}\n\n/**\n * Sentence-case the first character. Server `detail` / `title` sometimes\n * arrive fully lowercase; UI copy always leads with a capital.\n */\nexport function capitalizeFirst(text: string): string {\n if (!text) return text;\n const first = text.charAt(0);\n const upper = first.toUpperCase();\n if (first === upper) return text;\n return upper + text.slice(1);\n}\n\n/**\n * Turn a caught value into displayable copy. `Error` and `ErrorView` call\n * this internally; use it directly for other surfaces (a toast, a banner).\n *\n * Status-only failures (HTTP not ok, but no contract `code` / copy) still\n * keep `problem` so the details panel can show the status. Title becomes the\n * reason phrase (e.g. \"Bad Gateway\"); description is a short explanation —\n * not just the numeric code.\n */\nexport function describeError(error: unknown): ErrorDescription {\n const problem = parseProblem(error);\n if (problem == null) return { title: GENERIC_ERROR_TITLE };\n\n const description =\n [problem.detail, problem.remediation?.action]\n .filter((part): part is string => typeof part === \"string\" && part !== \"\")\n .join(\" \") || undefined;\n\n if (!hasContractCode(problem) && description == null) {\n const reason = httpReasonPhrase(problem.status, problem.title);\n return {\n title: capitalizeFirst(reason ?? GENERIC_ERROR_TITLE),\n description: httpStatusExplanation(problem.status),\n requestId: problem.requestId,\n problem,\n };\n }\n\n return {\n title: capitalizeFirst(problem.title || GENERIC_ERROR_TITLE),\n description: description ? capitalizeFirst(description) : undefined,\n documentation: problem.remediation?.documentation,\n requestId: problem.requestId,\n problem,\n };\n}\n","import {\n useEffect,\n useRef,\n useState,\n type ComponentProps,\n type ReactNode,\n} from \"react\";\nimport {\n IconAlertCircleFilled,\n IconAlertTriangle,\n IconInfoCircle,\n} from \"@tabler/icons-react\";\nimport { cn } from \"../../utils/cn\";\nimport { Button, ButtonLink } from \"../button/button\";\nimport { Popover } from \"../popover/popover\";\nimport { StatusView, type StatusViewSize } from \"../status-view/status-view\";\nimport {\n capitalizeFirst,\n describeError,\n httpReasonPhrase,\n type ErrorDescription,\n} from \"./problem\";\n\n/** Capitalize string copy; leave custom ReactNode overrides alone. */\nfunction displayCopy(value: ReactNode): ReactNode {\n return typeof value === \"string\" ? capitalizeFirst(value) : value;\n}\n\n/**\n * Design notes:\n * - ONE input: `error` is the caught value, whatever it is — a Problem\n * Details body from `@photon-hq/error`, an `Error` carrying one as\n * `cause`, or something unknown. The component derives its copy via\n * `describeError`; unknowns fall back to a generic line rather than\n * leaking raw messages.\n * - TWO presentations, one per altitude: `Error` is the inline line for\n * forms, cards, and action rows; `ErrorView` is the region / page state\n * built on StatusView (same `sm` / `base` size axis).\n * - Both render `null` when there is nothing to show, so they can sit\n * unconditionally in JSX (`<Error error={mutation.error} />`).\n * - Client-side *validation* is not this component's job — that belongs to\n * `Field.Error`, wired to control validity.\n */\n\nconst DOC_LINK_LABEL = \"Learn more\";\nconst RETRY_LABEL = \"Try again\";\n\ninterface ErrorBaseProps {\n /** The caught value — a problem body, an `Error` wrapping one, or unknown. */\n error?: unknown;\n /** Override the derived message. */\n children?: ReactNode;\n}\n\nexport interface ErrorProps\n extends ErrorBaseProps, Omit<ComponentProps<\"div\">, keyof ErrorBaseProps> {}\n\n/**\n * Error — one line of red ink naming a server failure (4xx / 5xx), placed\n * inline: under a form, in a card, beside the action that failed. Give it the\n * caught value and it renders the problem's `detail` (falling back to `title`,\n * then to a generic line), plus a docs link when the problem carries one.\n * Renders nothing while `error` is nullish, so it can stay mounted.\n *\n * For a region or page that failed to load, use {@link ErrorView}.\n */\nexport function Error({ error, children, className, ...props }: ErrorProps) {\n if (error == null && children == null) return null;\n const copy = describeError(error);\n return (\n <div\n role=\"alert\"\n className={cn(\n \"text-pho-error flex min-w-0 items-start gap-1.5 text-base\",\n className,\n )}\n {...props}\n >\n <span aria-hidden className=\"flex h-[1lh] shrink-0 items-center\">\n <IconAlertCircleFilled className=\"size-4\" />\n </span>\n <span className=\"min-w-0\">\n {displayCopy(children ?? copy.description ?? copy.title)}\n {copy.documentation != null && (\n <>\n {\" \"}\n <a\n href={copy.documentation}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"font-medium underline underline-offset-2\"\n >\n {DOC_LINK_LABEL}\n </a>\n </>\n )}\n {/* Trailing whitespace collapses when the details render null. */}{\" \"}\n <ErrorDetails copy={copy} />\n </span>\n </div>\n );\n}\n\nError.displayName = \"Error\";\n\n/**\n * Hover / focus disclosure on the inline line — the request's fuller story:\n * problem `title` (with the same alert icon + `text-pho-error` ink as the\n * inline line), the untruncated description, then `status` + `code` and the\n * copyable request id grouped below for a support handoff. Renders only when\n * the caught value actually carried a problem (or at least a request id); a\n * generic unknown has nothing more to disclose. Built on `Popover` rather\n * than `Tooltip` because the panel holds an interactive control (the copy\n * button) — `openOnHover` keeps the tooltip-like gesture.\n */\nfunction ErrorDetails({ copy }: { copy: ErrorDescription }) {\n const { problem, requestId } = copy;\n if (problem == null && requestId == null) return null;\n\n // Contract problems show `status CODE`; status-only shows `status Reason`.\n let statusLine: string | null = null;\n if (problem != null) {\n if (problem.code) {\n statusLine = `${problem.status} ${problem.code}`;\n } else {\n const reason = httpReasonPhrase(problem.status, problem.title);\n statusLine = reason\n ? `${problem.status} ${reason}`\n : String(problem.status);\n }\n }\n\n return (\n <Popover.Root>\n <Popover.Trigger\n openOnHover\n delay={150}\n aria-label=\"Error details\"\n className=\"outline-pho-brand inline-flex size-4 shrink-0 translate-y-[3px] cursor-help items-center justify-center rounded-full opacity-70 transition-opacity hover:opacity-100 focus-visible:opacity-100 focus-visible:outline-2\"\n >\n <IconInfoCircle className=\"size-3.5\" />\n </Popover.Trigger>\n <Popover.Portal>\n <Popover.Positioner align=\"start\">\n <Popover.Popup className=\"text-pho-error\">\n <Popover.Title className=\"text-pho-error flex items-start gap-1.5\">\n <span aria-hidden className=\"flex h-[1lh] shrink-0 items-center\">\n <IconAlertCircleFilled className=\"size-4\" />\n </span>\n {copy.title}\n </Popover.Title>\n {copy.description != null && (\n <Popover.Description className=\"text-pho-error\">\n {copy.description}\n </Popover.Description>\n )}\n {(statusLine != null || requestId != null) && (\n <div className=\"text-pho-error mt-1 font-mono text-[10px] leading-snug\">\n {statusLine != null && <p>{statusLine}</p>}\n {requestId != null && (\n <RequestId requestId={requestId} className=\"mt-0\" />\n )}\n </div>\n )}\n </Popover.Popup>\n </Popover.Positioner>\n </Popover.Portal>\n </Popover.Root>\n );\n}\n\n/** Request-id footnote — click copies the id for support handoff. */\nfunction RequestId({\n requestId,\n className,\n}: {\n requestId: string;\n className?: string;\n}) {\n const [copied, setCopied] = useState(false);\n const copiedTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(\n () => () => {\n if (copiedTimer.current) clearTimeout(copiedTimer.current);\n },\n [],\n );\n\n return (\n <span\n className={cn(\"mt-1 block font-mono text-[10px] leading-snug\", className)}\n >\n Request ID:{\" \"}\n <button\n type=\"button\"\n className=\"outline-pho-brand inline cursor-pointer underline-offset-2 select-all hover:underline focus-visible:underline focus-visible:outline-2 focus-visible:-outline-offset-1\"\n aria-label={\n copied ? \"Request ID copied\" : `Copy request ID ${requestId}`\n }\n onClick={async () => {\n try {\n await navigator.clipboard.writeText(requestId);\n } catch {\n return;\n }\n setCopied(true);\n if (copiedTimer.current) clearTimeout(copiedTimer.current);\n copiedTimer.current = setTimeout(() => setCopied(false), 1500);\n }}\n >\n {requestId}\n </button>\n <output className=\"sr-only\" aria-live=\"polite\">\n {copied ? \"Copied\" : \"\"}\n </output>\n </span>\n );\n}\n\ninterface ErrorViewBaseProps {\n /** The caught value — a problem body, an `Error` wrapping one, or unknown. */\n error?: unknown;\n /** Override the derived title. */\n title?: ReactNode;\n /** Override the derived description. */\n description?: ReactNode;\n /** Override the warning glyph. */\n icon?: ReactNode;\n /** Offer a retry — renders a \"Try again\" button. */\n onRetry?: () => void;\n /** Replace the built-in action row entirely. */\n actions?: ReactNode;\n /** Size variant — StatusView's axis. @default \"base\" */\n size?: StatusViewSize;\n}\n\nexport interface ErrorViewProps\n extends\n ErrorViewBaseProps,\n Omit<ComponentProps<\"div\">, keyof ErrorViewBaseProps | \"children\"> {}\n\n/**\n * ErrorView — the failed state of a region or page, built on StatusView:\n * warning icon over the problem's `title`, its `detail` and remediation\n * below, an action row (`onRetry` and the problem's docs link), and the\n * request id as a footnote for support. Announces via `role=\"alert\"`.\n *\n * Use `size=\"sm\"` inside cards and panels, the default `base` for whole\n * pages. Renders nothing while `error` is nullish (unless given a static\n * `title`), so it can sit unconditionally next to a query.\n */\nexport function ErrorView({\n error,\n title,\n description,\n icon,\n onRetry,\n actions,\n size = \"base\",\n ...props\n}: ErrorViewProps) {\n if (error == null && title == null) return null;\n const copy = describeError(error);\n\n const resolvedDescription = displayCopy(description ?? copy.description);\n const body =\n resolvedDescription != null || copy.requestId != null ? (\n <>\n {resolvedDescription}\n {copy.requestId != null && <RequestId requestId={copy.requestId} />}\n </>\n ) : undefined;\n\n const resolvedActions =\n actions ??\n (onRetry != null || copy.documentation != null ? (\n <>\n {onRetry != null && (\n <Button size=\"sm\" onClick={onRetry}>\n {RETRY_LABEL}\n </Button>\n )}\n {copy.documentation != null && (\n <ButtonLink\n size=\"sm\"\n variant=\"outlined\"\n href={copy.documentation}\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n {DOC_LINK_LABEL}\n </ButtonLink>\n )}\n </>\n ) : undefined);\n\n return (\n <StatusView\n role=\"alert\"\n size={size}\n icon={icon ?? <IconAlertTriangle />}\n title={displayCopy(title ?? copy.title)}\n description={body}\n actions={resolvedActions}\n {...props}\n />\n );\n}\n\nErrorView.displayName = \"ErrorView\";\n"],"x_google_ignoreList":[0],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"error-BAQgnde7.js","names":[],"sources":["../../../../node_modules/.pnpm/@tabler+icons-react@3.46.0_react@19.2.8/node_modules/@tabler/icons-react/dist/esm/icons/IconAlertTriangle.mjs","../../src/components/error/problem.ts","../../src/components/error/error.tsx"],"sourcesContent":["/**\n * @license @tabler/icons-react v3.46.0 - MIT\n *\n * This source code is licensed under the MIT license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createReactComponent from '../createReactComponent.mjs';\n\nconst __iconNode = [[\"path\", { \"d\": \"M12 9v4\", \"key\": \"svg-0\" }], [\"path\", { \"d\": \"M10.363 3.591l-8.106 13.534a1.914 1.914 0 0 0 1.636 2.871h16.214a1.914 1.914 0 0 0 1.636 -2.87l-8.106 -13.536a1.914 1.914 0 0 0 -3.274 0\", \"key\": \"svg-1\" }], [\"path\", { \"d\": \"M12 16h.01\", \"key\": \"svg-2\" }]];\nconst IconAlertTriangle = createReactComponent(\"outline\", \"alert-triangle\", \"AlertTriangle\", __iconNode);\n\nexport { __iconNode, IconAlertTriangle as default };\n//# sourceMappingURL=IconAlertTriangle.mjs.map\n","/**\n * Client-side mirror of the `@photon-hq/error` response contract — the\n * RFC 9457 Problem Details body every Photon service returns for 4xx / 5xx.\n * Machine logic branches on `code`; `title` / `detail` / `remediation` are\n * the human-readable copy, already reviewed server-side and safe to render.\n *\n * Fetch layers may also hand us a thin status-only shape when the response\n * was not ok but the body was not a contract problem — `title` + `status`\n * still count so the UI can disclose the HTTP code we already know.\n */\n\nexport interface ProblemRemediation {\n /** What the user can do about it — a full sentence. */\n action?: string;\n /** Docs URL explaining the problem. */\n documentation?: string;\n}\n\nexport interface Problem {\n /** Stable machine-readable key (`RATE_LIMITED`) — the field to branch on. */\n code?: string;\n /** Human summary of the problem type (\"Too Many Requests\"). */\n title: string;\n /** HTTP status (4xx / 5xx). */\n status: number;\n /** Problem type URI (`urn:photon:problem:*` or an https URL). */\n type?: string;\n /** Occurrence-specific human sentence. */\n detail?: string;\n /** Correlation id for support (`X-Request-ID`). */\n requestId?: string;\n remediation?: ProblemRemediation;\n /** RFC 9457 extensions (`issues`, `actualVersion`, …). */\n [extension: string]: unknown;\n}\n\n/** Structural check: `title` + a 4xx/5xx status. `code` is optional. */\nexport function isProblem(value: unknown): value is Problem {\n if (typeof value !== \"object\" || value === null) return false;\n const v = value as Record<string, unknown>;\n return (\n typeof v.title === \"string\" &&\n typeof v.status === \"number\" &&\n Number.isInteger(v.status) &&\n v.status >= 400 &&\n v.status <= 599 &&\n (v.code === undefined || typeof v.code === \"string\")\n );\n}\n\n/**\n * Find the problem a caught value carries — the value itself, one typed onto\n * an error as a `problem` field (dashboard's `ApiError` shape), or one\n * wrapped in an `Error` `cause` chain (how fetch layers usually rethrow a\n * parsed body). Returns `null` when there is none.\n */\nexport function parseProblem(error: unknown): Problem | null {\n let current: unknown = error;\n for (\n let depth = 0;\n depth < 8 && typeof current === \"object\" && current !== null;\n depth++\n ) {\n if (isProblem(current)) return current;\n const carried = (current as { problem?: unknown }).problem;\n if (isProblem(carried)) return carried;\n current = (current as { cause?: unknown }).cause;\n }\n return null;\n}\n\nexport interface ErrorDescription {\n /** Short name of the failure — the problem `title`, or a generic fallback. */\n title: string;\n /** Sentence(s) to show — `detail` and `remediation.action` joined. */\n description?: string;\n /** Docs URL from `remediation.documentation`. */\n documentation?: string;\n /** Correlation id for support. */\n requestId?: string;\n /** The matched problem, when the input carried one. */\n problem?: Problem;\n}\n\n/**\n * Anything that isn't a problem renders as this — raw `Error` messages are\n * not contract copy and never shown (the same fail-closed stance as the\n * server side of `@photon-hq/error`). Always a full sentence (trailing\n * period).\n */\nexport const GENERIC_ERROR_TITLE = \"Something went wrong.\";\n\n/** Standard reason phrases for statuses we commonly surface without a body. */\nconst HTTP_REASON_PHRASE: Record<number, string> = {\n 400: \"Bad Request\",\n 401: \"Unauthorized\",\n 403: \"Forbidden\",\n 404: \"Not Found\",\n 408: \"Request Timeout\",\n 409: \"Conflict\",\n 410: \"Gone\",\n 413: \"Payload Too Large\",\n 415: \"Unsupported Media Type\",\n 422: \"Unprocessable Entity\",\n 429: \"Too Many Requests\",\n 500: \"Internal Server Error\",\n 501: \"Not Implemented\",\n 502: \"Bad Gateway\",\n 503: \"Service Unavailable\",\n 504: \"Gateway Timeout\",\n};\n\n/** One-sentence explanations when the server gave a status but no problem copy. */\nconst HTTP_STATUS_EXPLANATION: Record<number, string> = {\n 400: \"The request was malformed or incomplete.\",\n 401: \"You need to sign in again.\",\n 403: \"You don't have permission to do that.\",\n 404: \"The requested resource was not found.\",\n 408: \"The request timed out before the server responded.\",\n 409: \"The request conflicts with the current state.\",\n 410: \"That resource is no longer available.\",\n 413: \"The request was too large for the server to accept.\",\n 415: \"That media type isn't supported.\",\n 422: \"The request was understood but couldn't be processed.\",\n 429: \"Request rate limit exceeded. Wait a moment before trying again.\",\n 500: \"The server hit an unexpected error.\",\n 501: \"The server doesn't support that operation.\",\n 502: \"The gateway got an invalid response from an upstream server.\",\n 503: \"The service is temporarily unavailable.\",\n 504: \"The gateway timed out waiting for an upstream server.\",\n};\n\nfunction hasContractCode(problem: Problem): boolean {\n return typeof problem.code === \"string\" && problem.code !== \"\";\n}\n\n/** Reason phrase for a status — map first, then a non-generic `problem.title`. */\nexport function httpReasonPhrase(\n status: number,\n fallbackTitle?: string,\n): string | undefined {\n if (HTTP_REASON_PHRASE[status]) return HTTP_REASON_PHRASE[status];\n if (\n fallbackTitle &&\n fallbackTitle !== GENERIC_ERROR_TITLE &&\n fallbackTitle !== \"Request failed\"\n ) {\n return fallbackTitle.replace(/\\.$/, \"\");\n }\n return undefined;\n}\n\n/** Human sentence for a bare HTTP status, when the body carried no copy. */\nexport function httpStatusExplanation(status: number): string {\n return (\n HTTP_STATUS_EXPLANATION[status] ??\n \"The request failed with an unexpected status.\"\n );\n}\n\n/**\n * Sentence-case the first character. Server `detail` / `title` sometimes\n * arrive fully lowercase; UI copy always leads with a capital.\n */\nexport function capitalizeFirst(text: string): string {\n if (!text) return text;\n const first = text.charAt(0);\n const upper = first.toUpperCase();\n if (first === upper) return text;\n return upper + text.slice(1);\n}\n\n/**\n * Turn a caught value into displayable copy. `Error` and `ErrorView` call\n * this internally; use it directly for other surfaces (a toast, a banner).\n *\n * Status-only failures (HTTP not ok, but no contract `code` / copy) still\n * keep `problem` so the details panel can show the status. Title becomes the\n * reason phrase (e.g. \"Bad Gateway\"); description is a short explanation —\n * not just the numeric code.\n */\nexport function describeError(error: unknown): ErrorDescription {\n const problem = parseProblem(error);\n if (problem == null) return { title: GENERIC_ERROR_TITLE };\n\n const description =\n [problem.detail, problem.remediation?.action]\n .filter((part): part is string => typeof part === \"string\" && part !== \"\")\n .join(\" \") || undefined;\n\n if (!hasContractCode(problem) && description == null) {\n const reason = httpReasonPhrase(problem.status, problem.title);\n return {\n title: capitalizeFirst(reason ?? GENERIC_ERROR_TITLE),\n description: httpStatusExplanation(problem.status),\n requestId: problem.requestId,\n problem,\n };\n }\n\n return {\n title: capitalizeFirst(problem.title || GENERIC_ERROR_TITLE),\n description: description ? capitalizeFirst(description) : undefined,\n documentation: problem.remediation?.documentation,\n requestId: problem.requestId,\n problem,\n };\n}\n","import {\n useEffect,\n useRef,\n useState,\n type ComponentProps,\n type ReactNode,\n} from \"react\";\nimport {\n IconAlertCircleFilled,\n IconAlertTriangle,\n IconInfoCircle,\n} from \"@tabler/icons-react\";\nimport { cn } from \"../../utils/cn\";\nimport { Button, ButtonLink } from \"../button/button\";\nimport { Popover } from \"../popover/popover\";\nimport { StatusView, type StatusViewSize } from \"../status-view/status-view\";\nimport {\n capitalizeFirst,\n describeError,\n httpReasonPhrase,\n type ErrorDescription,\n} from \"./problem\";\n\n/** Capitalize string copy; leave custom ReactNode overrides alone. */\nfunction displayCopy(value: ReactNode): ReactNode {\n return typeof value === \"string\" ? capitalizeFirst(value) : value;\n}\n\n/**\n * Design notes:\n * - ONE input: `error` is the caught value, whatever it is — a Problem\n * Details body from `@photon-hq/error`, an `Error` carrying one as\n * `cause`, or something unknown. The component derives its copy via\n * `describeError`; unknowns fall back to a generic line rather than\n * leaking raw messages.\n * - TWO presentations, one per altitude: `Error` is the inline line for\n * forms, cards, and action rows; `ErrorView` is the region / page state\n * built on StatusView (same `sm` / `base` size axis).\n * - Both render `null` when there is nothing to show, so they can sit\n * unconditionally in JSX (`<Error error={mutation.error} />`).\n * - Client-side *validation* is not this component's job — that belongs to\n * `Field.Error`, wired to control validity.\n */\n\nconst DOC_LINK_LABEL = \"Learn more\";\nconst RETRY_LABEL = \"Try again\";\n\ninterface ErrorBaseProps {\n /** The caught value — a problem body, an `Error` wrapping one, or unknown. */\n error?: unknown;\n /** Override the derived message. */\n children?: ReactNode;\n}\n\nexport interface ErrorProps\n extends ErrorBaseProps, Omit<ComponentProps<\"div\">, keyof ErrorBaseProps> {}\n\n/**\n * Error — one line of red ink naming a server failure (4xx / 5xx), placed\n * inline: under a form, in a card, beside the action that failed. Give it the\n * caught value and it renders the problem's `detail` (falling back to `title`,\n * then to a generic line), plus a docs link when the problem carries one.\n * Renders nothing while `error` is nullish, so it can stay mounted.\n *\n * For a region or page that failed to load, use {@link ErrorView}.\n */\nexport function Error({ error, children, className, ...props }: ErrorProps) {\n if (error == null && children == null) return null;\n const copy = describeError(error);\n return (\n <div\n role=\"alert\"\n className={cn(\n \"text-pho-error flex min-w-0 items-start gap-1.5 text-base\",\n className,\n )}\n {...props}\n >\n <span aria-hidden className=\"flex h-[1lh] shrink-0 items-center\">\n <IconAlertCircleFilled className=\"size-4\" />\n </span>\n <span className=\"min-w-0\">\n {displayCopy(children ?? copy.description ?? copy.title)}\n {copy.documentation != null && (\n <>\n {\" \"}\n <a\n href={copy.documentation}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"font-medium underline underline-offset-2\"\n >\n {DOC_LINK_LABEL}\n </a>\n </>\n )}\n {/* Trailing whitespace collapses when the details render null. */}{\" \"}\n <ErrorDetails copy={copy} />\n </span>\n </div>\n );\n}\n\nError.displayName = \"Error\";\n\n/**\n * Hover / focus disclosure on the inline line — the request's fuller story:\n * problem `title` (with the same alert icon + `text-pho-error` ink as the\n * inline line), the untruncated description, then `status` + `code` and the\n * copyable request id grouped below for a support handoff. Renders only when\n * the caught value actually carried a problem (or at least a request id); a\n * generic unknown has nothing more to disclose. Built on `Popover` rather\n * than `Tooltip` because the panel holds an interactive control (the copy\n * button) — `openOnHover` keeps the tooltip-like gesture.\n */\nfunction ErrorDetails({ copy }: { copy: ErrorDescription }) {\n const { problem, requestId } = copy;\n if (problem == null && requestId == null) return null;\n\n // Contract problems show `status CODE`; status-only shows `status Reason`.\n let statusLine: string | null = null;\n if (problem != null) {\n if (problem.code) {\n statusLine = `${problem.status} ${problem.code}`;\n } else {\n const reason = httpReasonPhrase(problem.status, problem.title);\n statusLine = reason\n ? `${problem.status} ${reason}`\n : String(problem.status);\n }\n }\n\n return (\n <Popover.Root>\n <Popover.Trigger\n openOnHover\n delay={150}\n aria-label=\"Error details\"\n className=\"outline-pho-brand inline-flex size-4 shrink-0 translate-y-[3px] cursor-help items-center justify-center rounded-full opacity-70 transition-opacity hover:opacity-100 focus-visible:opacity-100 focus-visible:outline-2\"\n >\n <IconInfoCircle className=\"size-3.5\" />\n </Popover.Trigger>\n <Popover.Portal>\n <Popover.Positioner align=\"start\">\n <Popover.Popup className=\"text-pho-error\">\n <Popover.Title className=\"text-pho-error flex items-start gap-1.5\">\n <span aria-hidden className=\"flex h-[1lh] shrink-0 items-center\">\n <IconAlertCircleFilled className=\"size-4\" />\n </span>\n {copy.title}\n </Popover.Title>\n {copy.description != null && (\n <Popover.Description className=\"text-pho-error\">\n {copy.description}\n </Popover.Description>\n )}\n {(statusLine != null || requestId != null) && (\n <div className=\"text-pho-error mt-1 font-mono text-[10px] leading-snug\">\n {statusLine != null && <p>{statusLine}</p>}\n {requestId != null && (\n <RequestId requestId={requestId} className=\"mt-0\" />\n )}\n </div>\n )}\n </Popover.Popup>\n </Popover.Positioner>\n </Popover.Portal>\n </Popover.Root>\n );\n}\n\n/** Request-id footnote — click copies the id for support handoff. */\nfunction RequestId({\n requestId,\n className,\n}: {\n requestId: string;\n className?: string;\n}) {\n const [copied, setCopied] = useState(false);\n const copiedTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(\n () => () => {\n if (copiedTimer.current) clearTimeout(copiedTimer.current);\n },\n [],\n );\n\n return (\n <span\n className={cn(\"mt-1 block font-mono text-[10px] leading-snug\", className)}\n >\n Request ID:{\" \"}\n <button\n type=\"button\"\n className=\"outline-pho-brand inline cursor-pointer underline-offset-2 select-all hover:underline focus-visible:underline focus-visible:outline-2 focus-visible:-outline-offset-1\"\n aria-label={\n copied ? \"Request ID copied\" : `Copy request ID ${requestId}`\n }\n onClick={async () => {\n try {\n await navigator.clipboard.writeText(requestId);\n } catch {\n return;\n }\n setCopied(true);\n if (copiedTimer.current) clearTimeout(copiedTimer.current);\n copiedTimer.current = setTimeout(() => setCopied(false), 1500);\n }}\n >\n {requestId}\n </button>\n <output className=\"sr-only\" aria-live=\"polite\">\n {copied ? \"Copied\" : \"\"}\n </output>\n </span>\n );\n}\n\ninterface ErrorViewBaseProps {\n /** The caught value — a problem body, an `Error` wrapping one, or unknown. */\n error?: unknown;\n /** Override the derived title. */\n title?: ReactNode;\n /** Override the derived description. */\n description?: ReactNode;\n /** Override the warning glyph. */\n icon?: ReactNode;\n /** Offer a retry — renders a \"Try again\" button. */\n onRetry?: () => void;\n /** Replace the built-in action row entirely. */\n actions?: ReactNode;\n /** Size variant — StatusView's axis. @default \"base\" */\n size?: StatusViewSize;\n}\n\nexport interface ErrorViewProps\n extends\n ErrorViewBaseProps,\n Omit<ComponentProps<\"div\">, keyof ErrorViewBaseProps | \"children\"> {}\n\n/**\n * ErrorView — the failed state of a region or page, built on StatusView:\n * warning icon over the problem's `title`, its `detail` and remediation\n * below, an action row (`onRetry` and the problem's docs link), and the\n * request id as a footnote for support. Announces via `role=\"alert\"`.\n *\n * Use `size=\"sm\"` inside cards and panels, the default `base` for whole\n * pages. Renders nothing while `error` is nullish (unless given a static\n * `title`), so it can sit unconditionally next to a query.\n */\nexport function ErrorView({\n error,\n title,\n description,\n icon,\n onRetry,\n actions,\n size = \"base\",\n ...props\n}: ErrorViewProps) {\n if (error == null && title == null) return null;\n const copy = describeError(error);\n\n const resolvedDescription = displayCopy(description ?? copy.description);\n const body =\n resolvedDescription != null || copy.requestId != null ? (\n <>\n {resolvedDescription}\n {copy.requestId != null && <RequestId requestId={copy.requestId} />}\n </>\n ) : undefined;\n\n const resolvedActions =\n actions ??\n (onRetry != null || copy.documentation != null ? (\n <>\n {onRetry != null && (\n <Button size=\"sm\" onClick={onRetry}>\n {RETRY_LABEL}\n </Button>\n )}\n {copy.documentation != null && (\n <ButtonLink\n size=\"sm\"\n variant=\"outlined\"\n href={copy.documentation}\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n {DOC_LINK_LABEL}\n </ButtonLink>\n )}\n </>\n ) : undefined);\n\n return (\n <StatusView\n role=\"alert\"\n size={size}\n icon={icon ?? <IconAlertTriangle />}\n title={displayCopy(title ?? copy.title)}\n description={body}\n actions={resolvedActions}\n {...props}\n />\n );\n}\n\nErrorView.displayName = \"ErrorView\";\n"],"x_google_ignoreList":[0],"mappings":"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"}
|
|
@@ -5,8 +5,8 @@ import { t as R } from "./createReactComponent-BqCmnqfX.js";
|
|
|
5
5
|
import { t as S } from "./IconCheck-D2WuculQ.js";
|
|
6
6
|
import { t as L } from "./IconSearch-BKAHkLyX.js";
|
|
7
7
|
import { t as $ } from "./IconX-pZ9vrtSr.js";
|
|
8
|
-
import { t as w } from "./input-group-fc9_jD4d.js";
|
|
9
8
|
import { t as g } from "./popover-BhBJO346.js";
|
|
9
|
+
import { t as w } from "./input-group-fc9_jD4d.js";
|
|
10
10
|
import { t as d } from "./command-CTYrSz9a.js";
|
|
11
11
|
import { useRef as D, useState as T } from "react";
|
|
12
12
|
import { jsx as a, jsxs as u } from "react/jsx-runtime";
|
|
@@ -256,4 +256,4 @@ export {
|
|
|
256
256
|
O as t
|
|
257
257
|
};
|
|
258
258
|
|
|
259
|
-
//# sourceMappingURL=filter-bar-
|
|
259
|
+
//# sourceMappingURL=filter-bar-D9lBBr4z.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter-bar-BsvdXwzc.js","names":[],"sources":["../../../../node_modules/.pnpm/@tabler+icons-react@3.46.0_react@19.2.8/node_modules/@tabler/icons-react/dist/esm/icons/IconPlus.mjs","../../src/components/filter-bar/filter-bar.tsx"],"sourcesContent":["/**\n * @license @tabler/icons-react v3.46.0 - MIT\n *\n * This source code is licensed under the MIT license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createReactComponent from '../createReactComponent.mjs';\n\nconst __iconNode = [[\"path\", { \"d\": \"M12 5l0 14\", \"key\": \"svg-0\" }], [\"path\", { \"d\": \"M5 12l14 0\", \"key\": \"svg-1\" }]];\nconst IconPlus = createReactComponent(\"outline\", \"plus\", \"Plus\", __iconNode);\n\nexport { __iconNode, IconPlus as default };\n//# sourceMappingURL=IconPlus.mjs.map\n","import {\n useRef,\n useState,\n type ComponentProps,\n type ReactNode,\n type Ref,\n type RefObject,\n} from \"react\";\nimport { IconCheck, IconPlus, IconSearch, IconX } from \"@tabler/icons-react\";\nimport { Button } from \"../button\";\nimport { Command } from \"../command\";\nimport { InputGroup } from \"../input-group\";\nimport { Popover } from \"../popover\";\nimport { cn } from \"../../utils/cn\";\n\n/**\n * Filter Bar — the row that pins above a log list: a search field for an\n * id, then one chip per filter. A chip with nothing chosen reads\n * `+ Status`; with a value it reads `Status: Failed` and carries its own\n * clear. Each chip opens a small popover: a keyboard-first list of\n * options (with a search field past eight of them), or presets and a\n * from / to pair for a date range.\n *\n * Design notes:\n * - Fully controlled. The page owns `filters` and `search` and hands\n * them back changed; the bar keeps no state but which popover is open.\n * That keeps the query in one place (the URL, a store) and lets the\n * list refetch from it.\n * - Chips are real buttons (the trigger, and the clear beside it), so\n * the bar is one tab stop per control and Escape closes a popover\n * back onto its chip.\n * - No scroll container of its own: chips wrap. `sticky` pins it to the\n * top of the nearest scroll pane on the surface it sits on.\n */\n\nexport interface FilterOption {\n value: string;\n label: string;\n}\n\ninterface FilterDefinitionBase {\n /** The key in `filters` this chip reads and writes. */\n key: string;\n /** The chip's word — \"Status\", \"Event type\". Sentence case. */\n label: string;\n}\n\nexport interface SelectFilterDefinition extends FilterDefinitionBase {\n type?: \"select\";\n options: readonly FilterOption[];\n /** Several values at once (`string[]`); one at a time by default. */\n multiple?: boolean;\n /**\n * A search field above the options. On by default past eight options,\n * off below; say so to override.\n */\n searchable?: boolean;\n /** The search field's placeholder. @default \"Search\" */\n searchPlaceholder?: string;\n}\n\n/** A relative preset for a date-range filter — \"Last 7 days\" is 168 hours. */\nexport interface DateRangePreset {\n label: string;\n hours: number;\n}\n\nexport interface DateRangeFilterDefinition extends FilterDefinitionBase {\n type: \"date-range\";\n /** The relative presets listed above the from / to pair. */\n presets?: readonly DateRangePreset[];\n}\n\nexport type FilterDefinition =\n SelectFilterDefinition | DateRangeFilterDefinition;\n\n/**\n * A date-range value. A preset stores an absolute ISO timestamp in `from`\n * (computed when chosen) and its label in `preset`; the from / to pair\n * stores plain `YYYY-MM-DD` dates. Either side may be open (`null`).\n */\nexport interface DateRangeValue {\n from: string | null;\n to: string | null;\n preset?: string;\n}\n\nexport type FilterValue = string | string[] | DateRangeValue;\n\n/** The page's filter state — one entry per definition key that is set. */\nexport type FilterValues = Record<string, FilterValue | undefined>;\n\n/** The relative presets a date-range chip lists when given none. */\nexport const FILTER_DATE_PRESETS: readonly DateRangePreset[] = [\n { label: \"Last hour\", hours: 1 },\n { label: \"Last 24 hours\", hours: 24 },\n { label: \"Last 7 days\", hours: 24 * 7 },\n { label: \"Last 30 days\", hours: 24 * 30 },\n];\n\n/** Past this many options a select chip shows a search field. */\nconst SEARCHABLE_PAST = 8;\n\n/** Whether a filter value counts as set — an empty string or list does not. */\nexport function isFilterSet(value: FilterValue | undefined): boolean {\n if (value == null) return false;\n if (typeof value === \"string\") return value !== \"\";\n if (Array.isArray(value)) return value.length > 0;\n return value.from != null || value.to != null;\n}\n\nconst DATE_ONLY = /^\\d{4}-\\d{2}-\\d{2}$/;\n\nfunction formatDay(value: string): string {\n // A plain date is a calendar day: format it in UTC so the day survives\n // every viewer timezone. A timestamp is a moment: format it locally.\n const dateOnly = DATE_ONLY.test(value);\n const date = new Date(dateOnly ? `${value}T00:00:00Z` : value);\n if (Number.isNaN(date.getTime())) return value;\n return new Intl.DateTimeFormat(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n ...(dateOnly ? { timeZone: \"UTC\" } : {}),\n }).format(date);\n}\n\n/** The words a set chip shows after its label. */\nexport function formatFilterValue(\n definition: FilterDefinition,\n value: FilterValue | undefined,\n): string {\n if (!isFilterSet(value) || value == null) return \"\";\n if (definition.type === \"date-range\") {\n const range = value as DateRangeValue;\n if (range.preset) return range.preset;\n if (range.from && range.to) {\n return `${formatDay(range.from)} to ${formatDay(range.to)}`;\n }\n if (range.from) return `From ${formatDay(range.from)}`;\n if (range.to) return `Until ${formatDay(range.to)}`;\n return \"\";\n }\n const labelOf = (item: string) =>\n definition.options.find((option) => option.value === item)?.label ?? item;\n if (Array.isArray(value)) return value.map(labelOf).join(\", \");\n return typeof value === \"string\" ? labelOf(value) : \"\";\n}\n\n/* --------------------------------- chips -------------------------------- */\n\nconst CHIP_TRIGGER =\n \"outline-pho-brand flex h-8 min-w-0 cursor-pointer items-center gap-1.5 rounded-full text-base transition-[color,background-color] duration-100 ease-linear focus-visible:outline-2 focus-visible:-outline-offset-2 [&>svg]:size-4 [&>svg]:shrink-0\";\n\nfunction FilterChip({\n definition,\n value,\n onChange,\n}: {\n definition: FilterDefinition;\n value: FilterValue | undefined;\n onChange: (next: FilterValue | undefined) => void;\n}) {\n const [open, setOpen] = useState(false);\n const focusRef = useRef<HTMLElement | null>(null);\n const set = isFilterSet(value);\n const display = formatFilterValue(definition, value);\n return (\n <Popover.Root open={open} onOpenChange={setOpen}>\n <span\n data-filter-chip={definition.key}\n data-set={set || undefined}\n className={cn(\n \"ring-pho-primary inline-flex max-w-full shrink-0 items-stretch rounded-full ring-1 ring-inset\",\n set ? \"bg-pho-secondary\" : \"bg-transparent\",\n )}\n >\n <Popover.Trigger\n aria-label={set ? undefined : `${definition.label} filter`}\n className={cn(\n CHIP_TRIGGER,\n \"hover:bg-pho-ghost-hover\",\n set ? \"pr-1.5 pl-3\" : \"pr-3 pl-2.5\",\n set ? \"rounded-r-none\" : \"\",\n )}\n >\n {set ? null : <IconPlus aria-hidden />}\n {set ? (\n <span className=\"flex min-w-0 items-baseline gap-1\">\n <span className=\"text-pho-description shrink-0\">\n {definition.label}:\n </span>\n <span className=\"text-pho-primary max-w-56 truncate font-medium\">\n {display}\n </span>\n </span>\n ) : (\n <span className=\"text-pho-secondary\">{definition.label}</span>\n )}\n </Popover.Trigger>\n {set ? (\n <button\n type=\"button\"\n aria-label={`Clear ${definition.label.toLowerCase()} filter`}\n onClick={() => onChange(undefined)}\n className={cn(\n CHIP_TRIGGER,\n \"text-pho-secondary hover:bg-pho-ghost-hover hover:text-pho-secondary-hover rounded-l-none pr-2.5 pl-1 [&>svg]:size-3.5\",\n )}\n >\n <IconX aria-hidden />\n </button>\n ) : null}\n </span>\n <Popover.Portal>\n <Popover.Positioner align=\"start\" sideOffset={6}>\n <Popover.Popup\n aria-label={`${definition.label} filter`}\n initialFocus={focusRef}\n className={cn(\n \"w-64 p-0\",\n definition.type === \"date-range\" && \"w-72\",\n )}\n >\n {definition.type === \"date-range\" ? (\n <DateRangePanel\n definition={definition}\n value={value as DateRangeValue | undefined}\n focusRef={focusRef}\n onChange={(next) => {\n onChange(next);\n if (next?.preset) setOpen(false);\n }}\n />\n ) : (\n <OptionsPanel\n definition={definition}\n value={value as string | string[] | undefined}\n focusRef={focusRef}\n onChange={(next) => {\n onChange(next);\n if (!definition.multiple) setOpen(false);\n }}\n />\n )}\n </Popover.Popup>\n </Popover.Positioner>\n </Popover.Portal>\n </Popover.Root>\n );\n}\n\nfunction OptionsPanel({\n definition,\n value,\n focusRef,\n onChange,\n}: {\n definition: SelectFilterDefinition;\n value: string | string[] | undefined;\n focusRef: RefObject<HTMLElement | null>;\n onChange: (next: string | string[] | undefined) => void;\n}) {\n const [query, setQuery] = useState(\"\");\n const searchable =\n definition.searchable ?? definition.options.length > SEARCHABLE_PAST;\n const chosen = new Set(\n value == null ? [] : Array.isArray(value) ? value : [value],\n );\n const needle = query.trim().toLowerCase();\n const options = needle\n ? definition.options.filter(\n (option) =>\n option.label.toLowerCase().includes(needle) ||\n option.value.toLowerCase().includes(needle),\n )\n : definition.options;\n const pick = (option: FilterOption) => {\n if (definition.multiple) {\n const next = new Set(chosen);\n if (next.has(option.value)) next.delete(option.value);\n else next.add(option.value);\n // Keep the definition's order, so the chip reads the same way\n // whatever order the values were chosen in.\n const ordered = definition.options\n .map((item) => item.value)\n .filter((item) => next.has(item));\n onChange(ordered.length > 0 ? ordered : undefined);\n return;\n }\n onChange(chosen.has(option.value) ? undefined : option.value);\n };\n return (\n <Command.Root\n label={`${definition.label} options`}\n // Without a search field the list itself takes focus, so the arrow\n // keys work from the first frame.\n ref={(node: HTMLDivElement | null) => {\n if (!searchable) focusRef.current = node;\n }}\n className=\"rounded-base\"\n >\n {searchable ? (\n <Command.InputGroup>\n <IconSearch\n aria-hidden\n className=\"text-pho-description pointer-events-none absolute left-3 size-4\"\n />\n <Command.Input\n ref={(node: HTMLInputElement | null) => {\n focusRef.current = node;\n }}\n value={query}\n onValueChange={setQuery}\n placeholder={definition.searchPlaceholder ?? \"Search\"}\n aria-label={`Search ${definition.label.toLowerCase()} options`}\n className=\"py-2 pr-3 pl-9 text-base\"\n />\n </Command.InputGroup>\n ) : null}\n <Command.List>\n <Command.Empty>Nothing matches.</Command.Empty>\n {options.map((option) => (\n <Command.Item\n key={option.value}\n value={option.value}\n title={option.label}\n aria-checked={chosen.has(option.value)}\n icon={chosen.has(option.value) ? <IconCheck aria-hidden /> : null}\n onSelect={() => pick(option)}\n />\n ))}\n </Command.List>\n </Command.Root>\n );\n}\n\nconst DATE_INPUT =\n \"bg-pho-primary ring-pho-primary text-pho-primary focus-visible:ring-pho-brand w-full min-w-0 rounded-sm px-2 py-1 text-base ring-1 transition-shadow duration-100 ease-linear outline-none ring-inset focus-visible:ring-2\";\n\nfunction DateRangePanel({\n definition,\n value,\n focusRef,\n onChange,\n}: {\n definition: DateRangeFilterDefinition;\n value: DateRangeValue | undefined;\n focusRef: RefObject<HTMLElement | null>;\n onChange: (next: DateRangeValue | undefined) => void;\n}) {\n const presets = definition.presets ?? FILTER_DATE_PRESETS;\n // A preset's `from` is a timestamp; the day field shows its date.\n const day = (side: string | null | undefined) =>\n side == null ? \"\" : DATE_ONLY.test(side) ? side : side.slice(0, 10);\n const setSide = (side: \"from\" | \"to\", next: string) => {\n // Editing either day leaves a preset behind: the pair is the value now,\n // and a preset's timestamp becomes the day it fell on.\n const range: DateRangeValue = {\n from: day(value?.from) || null,\n to: day(value?.to) || null,\n [side]: next || null,\n };\n onChange(range.from == null && range.to == null ? undefined : range);\n };\n return (\n <div className=\"flex flex-col\">\n <Command.Root\n label={`${definition.label} presets`}\n ref={(node: HTMLDivElement | null) => {\n focusRef.current = node;\n }}\n className=\"rounded-t-[inherit]\"\n >\n <Command.List>\n {presets.map((preset) => (\n <Command.Item\n key={preset.label}\n value={preset.label}\n title={preset.label}\n aria-checked={value?.preset === preset.label}\n icon={\n value?.preset === preset.label ? (\n <IconCheck aria-hidden />\n ) : null\n }\n onSelect={() =>\n onChange({\n from: new Date(\n Date.now() - preset.hours * 60 * 60 * 1000,\n ).toISOString(),\n to: null,\n preset: preset.label,\n })\n }\n />\n ))}\n </Command.List>\n </Command.Root>\n {/* The day fields stand outside the command list: its arrow-key\n handling would otherwise swallow the native date stepping. */}\n <div className=\"border-pho-secondary grid grid-cols-2 gap-2 border-t p-2\">\n <label className=\"text-pho-description flex min-w-0 flex-col gap-1 text-xs\">\n From\n <input\n type=\"date\"\n value={day(value?.from)}\n max={day(value?.to) || undefined}\n onChange={(event) => setSide(\"from\", event.target.value)}\n className={DATE_INPUT}\n />\n </label>\n <label className=\"text-pho-description flex min-w-0 flex-col gap-1 text-xs\">\n To\n <input\n type=\"date\"\n value={day(value?.to)}\n min={day(value?.from) || undefined}\n onChange={(event) => setSide(\"to\", event.target.value)}\n className={DATE_INPUT}\n />\n </label>\n </div>\n </div>\n );\n}\n\n/* ---------------------------------- bar --------------------------------- */\n\nexport interface FilterBarProps extends Omit<\n ComponentProps<\"div\">,\n \"children\"\n> {\n /** One chip per definition, in this order. */\n definitions: readonly FilterDefinition[];\n /** The values, keyed by definition key. Absent or empty means unset. */\n filters: FilterValues;\n /** The whole map, changed — set, cleared, or cleared all. */\n onFiltersChange: (next: FilterValues) => void;\n /** The search field's text. The field renders only with `onSearchChange`. */\n search?: string;\n onSearchChange?: (value: string) => void;\n /** A teaching phrase — \"Find an event by id\". @default \"Search\" */\n searchPlaceholder?: string;\n /** The field's accessible name when the placeholder is too short to be one. */\n searchLabel?: string;\n /**\n * Pin the bar to the top of the nearest scroll pane. It paints the\n * surface it sits on (`--pho-surface`) so rows scroll under it.\n */\n sticky?: boolean;\n /** Controls after the chips — a range picker, an export button. */\n children?: ReactNode;\n ref?: Ref<HTMLDivElement>;\n}\n\nexport function FilterBar({\n definitions,\n filters,\n onFiltersChange,\n search,\n onSearchChange,\n searchPlaceholder = \"Search\",\n searchLabel,\n sticky,\n className,\n children,\n ...props\n}: FilterBarProps) {\n const setCount = definitions.filter((definition) =>\n isFilterSet(filters[definition.key]),\n ).length;\n const change = (key: string, next: FilterValue | undefined) => {\n const rest = { ...filters };\n if (next === undefined) delete rest[key];\n else rest[key] = next;\n onFiltersChange(rest);\n };\n return (\n <div\n data-filter-bar=\"\"\n className={cn(\n \"flex min-w-0 flex-wrap items-center gap-2\",\n sticky &&\n \"sticky top-0 z-10 bg-[var(--pho-surface,var(--background-color-pho-page))] py-3\",\n className,\n )}\n {...props}\n >\n {onSearchChange != null ? (\n <InputGroup.Root size=\"sm\" className=\"w-64 max-w-full\">\n <InputGroup.Addon>\n <IconSearch />\n </InputGroup.Addon>\n <InputGroup.Input\n type=\"search\"\n value={search ?? \"\"}\n onChange={(event) => onSearchChange(event.target.value)}\n onKeyDown={(event) => {\n if (event.key !== \"Escape\") return;\n event.preventDefault();\n onSearchChange(\"\");\n }}\n placeholder={searchPlaceholder}\n aria-label={searchLabel ?? searchPlaceholder}\n />\n </InputGroup.Root>\n ) : null}\n {definitions.map((definition) => (\n <FilterChip\n key={definition.key}\n definition={definition}\n value={filters[definition.key]}\n onChange={(next) => change(definition.key, next)}\n />\n ))}\n {setCount > 1 ? (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => {\n const rest = { ...filters };\n for (const definition of definitions) delete rest[definition.key];\n onFiltersChange(rest);\n }}\n >\n Clear filters\n </Button>\n ) : null}\n {children}\n </div>\n );\n}\n\nFilterBar.displayName = \"FilterBar\";\n"],"x_google_ignoreList":[0],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"filter-bar-D9lBBr4z.js","names":[],"sources":["../../../../node_modules/.pnpm/@tabler+icons-react@3.46.0_react@19.2.8/node_modules/@tabler/icons-react/dist/esm/icons/IconPlus.mjs","../../src/components/filter-bar/filter-bar.tsx"],"sourcesContent":["/**\n * @license @tabler/icons-react v3.46.0 - MIT\n *\n * This source code is licensed under the MIT license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createReactComponent from '../createReactComponent.mjs';\n\nconst __iconNode = [[\"path\", { \"d\": \"M12 5l0 14\", \"key\": \"svg-0\" }], [\"path\", { \"d\": \"M5 12l14 0\", \"key\": \"svg-1\" }]];\nconst IconPlus = createReactComponent(\"outline\", \"plus\", \"Plus\", __iconNode);\n\nexport { __iconNode, IconPlus as default };\n//# sourceMappingURL=IconPlus.mjs.map\n","import {\n useRef,\n useState,\n type ComponentProps,\n type ReactNode,\n type Ref,\n type RefObject,\n} from \"react\";\nimport { IconCheck, IconPlus, IconSearch, IconX } from \"@tabler/icons-react\";\nimport { Button } from \"../button\";\nimport { Command } from \"../command\";\nimport { InputGroup } from \"../input-group\";\nimport { Popover } from \"../popover\";\nimport { cn } from \"../../utils/cn\";\n\n/**\n * Filter Bar — the row that pins above a log list: a search field for an\n * id, then one chip per filter. A chip with nothing chosen reads\n * `+ Status`; with a value it reads `Status: Failed` and carries its own\n * clear. Each chip opens a small popover: a keyboard-first list of\n * options (with a search field past eight of them), or presets and a\n * from / to pair for a date range.\n *\n * Design notes:\n * - Fully controlled. The page owns `filters` and `search` and hands\n * them back changed; the bar keeps no state but which popover is open.\n * That keeps the query in one place (the URL, a store) and lets the\n * list refetch from it.\n * - Chips are real buttons (the trigger, and the clear beside it), so\n * the bar is one tab stop per control and Escape closes a popover\n * back onto its chip.\n * - No scroll container of its own: chips wrap. `sticky` pins it to the\n * top of the nearest scroll pane on the surface it sits on.\n */\n\nexport interface FilterOption {\n value: string;\n label: string;\n}\n\ninterface FilterDefinitionBase {\n /** The key in `filters` this chip reads and writes. */\n key: string;\n /** The chip's word — \"Status\", \"Event type\". Sentence case. */\n label: string;\n}\n\nexport interface SelectFilterDefinition extends FilterDefinitionBase {\n type?: \"select\";\n options: readonly FilterOption[];\n /** Several values at once (`string[]`); one at a time by default. */\n multiple?: boolean;\n /**\n * A search field above the options. On by default past eight options,\n * off below; say so to override.\n */\n searchable?: boolean;\n /** The search field's placeholder. @default \"Search\" */\n searchPlaceholder?: string;\n}\n\n/** A relative preset for a date-range filter — \"Last 7 days\" is 168 hours. */\nexport interface DateRangePreset {\n label: string;\n hours: number;\n}\n\nexport interface DateRangeFilterDefinition extends FilterDefinitionBase {\n type: \"date-range\";\n /** The relative presets listed above the from / to pair. */\n presets?: readonly DateRangePreset[];\n}\n\nexport type FilterDefinition =\n SelectFilterDefinition | DateRangeFilterDefinition;\n\n/**\n * A date-range value. A preset stores an absolute ISO timestamp in `from`\n * (computed when chosen) and its label in `preset`; the from / to pair\n * stores plain `YYYY-MM-DD` dates. Either side may be open (`null`).\n */\nexport interface DateRangeValue {\n from: string | null;\n to: string | null;\n preset?: string;\n}\n\nexport type FilterValue = string | string[] | DateRangeValue;\n\n/** The page's filter state — one entry per definition key that is set. */\nexport type FilterValues = Record<string, FilterValue | undefined>;\n\n/** The relative presets a date-range chip lists when given none. */\nexport const FILTER_DATE_PRESETS: readonly DateRangePreset[] = [\n { label: \"Last hour\", hours: 1 },\n { label: \"Last 24 hours\", hours: 24 },\n { label: \"Last 7 days\", hours: 24 * 7 },\n { label: \"Last 30 days\", hours: 24 * 30 },\n];\n\n/** Past this many options a select chip shows a search field. */\nconst SEARCHABLE_PAST = 8;\n\n/** Whether a filter value counts as set — an empty string or list does not. */\nexport function isFilterSet(value: FilterValue | undefined): boolean {\n if (value == null) return false;\n if (typeof value === \"string\") return value !== \"\";\n if (Array.isArray(value)) return value.length > 0;\n return value.from != null || value.to != null;\n}\n\nconst DATE_ONLY = /^\\d{4}-\\d{2}-\\d{2}$/;\n\nfunction formatDay(value: string): string {\n // A plain date is a calendar day: format it in UTC so the day survives\n // every viewer timezone. A timestamp is a moment: format it locally.\n const dateOnly = DATE_ONLY.test(value);\n const date = new Date(dateOnly ? `${value}T00:00:00Z` : value);\n if (Number.isNaN(date.getTime())) return value;\n return new Intl.DateTimeFormat(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n ...(dateOnly ? { timeZone: \"UTC\" } : {}),\n }).format(date);\n}\n\n/** The words a set chip shows after its label. */\nexport function formatFilterValue(\n definition: FilterDefinition,\n value: FilterValue | undefined,\n): string {\n if (!isFilterSet(value) || value == null) return \"\";\n if (definition.type === \"date-range\") {\n const range = value as DateRangeValue;\n if (range.preset) return range.preset;\n if (range.from && range.to) {\n return `${formatDay(range.from)} to ${formatDay(range.to)}`;\n }\n if (range.from) return `From ${formatDay(range.from)}`;\n if (range.to) return `Until ${formatDay(range.to)}`;\n return \"\";\n }\n const labelOf = (item: string) =>\n definition.options.find((option) => option.value === item)?.label ?? item;\n if (Array.isArray(value)) return value.map(labelOf).join(\", \");\n return typeof value === \"string\" ? labelOf(value) : \"\";\n}\n\n/* --------------------------------- chips -------------------------------- */\n\nconst CHIP_TRIGGER =\n \"outline-pho-brand flex h-8 min-w-0 cursor-pointer items-center gap-1.5 rounded-full text-base transition-[color,background-color] duration-100 ease-linear focus-visible:outline-2 focus-visible:-outline-offset-2 [&>svg]:size-4 [&>svg]:shrink-0\";\n\nfunction FilterChip({\n definition,\n value,\n onChange,\n}: {\n definition: FilterDefinition;\n value: FilterValue | undefined;\n onChange: (next: FilterValue | undefined) => void;\n}) {\n const [open, setOpen] = useState(false);\n const focusRef = useRef<HTMLElement | null>(null);\n const set = isFilterSet(value);\n const display = formatFilterValue(definition, value);\n return (\n <Popover.Root open={open} onOpenChange={setOpen}>\n <span\n data-filter-chip={definition.key}\n data-set={set || undefined}\n className={cn(\n \"ring-pho-primary inline-flex max-w-full shrink-0 items-stretch rounded-full ring-1 ring-inset\",\n set ? \"bg-pho-secondary\" : \"bg-transparent\",\n )}\n >\n <Popover.Trigger\n aria-label={set ? undefined : `${definition.label} filter`}\n className={cn(\n CHIP_TRIGGER,\n \"hover:bg-pho-ghost-hover\",\n set ? \"pr-1.5 pl-3\" : \"pr-3 pl-2.5\",\n set ? \"rounded-r-none\" : \"\",\n )}\n >\n {set ? null : <IconPlus aria-hidden />}\n {set ? (\n <span className=\"flex min-w-0 items-baseline gap-1\">\n <span className=\"text-pho-description shrink-0\">\n {definition.label}:\n </span>\n <span className=\"text-pho-primary max-w-56 truncate font-medium\">\n {display}\n </span>\n </span>\n ) : (\n <span className=\"text-pho-secondary\">{definition.label}</span>\n )}\n </Popover.Trigger>\n {set ? (\n <button\n type=\"button\"\n aria-label={`Clear ${definition.label.toLowerCase()} filter`}\n onClick={() => onChange(undefined)}\n className={cn(\n CHIP_TRIGGER,\n \"text-pho-secondary hover:bg-pho-ghost-hover hover:text-pho-secondary-hover rounded-l-none pr-2.5 pl-1 [&>svg]:size-3.5\",\n )}\n >\n <IconX aria-hidden />\n </button>\n ) : null}\n </span>\n <Popover.Portal>\n <Popover.Positioner align=\"start\" sideOffset={6}>\n <Popover.Popup\n aria-label={`${definition.label} filter`}\n initialFocus={focusRef}\n className={cn(\n \"w-64 p-0\",\n definition.type === \"date-range\" && \"w-72\",\n )}\n >\n {definition.type === \"date-range\" ? (\n <DateRangePanel\n definition={definition}\n value={value as DateRangeValue | undefined}\n focusRef={focusRef}\n onChange={(next) => {\n onChange(next);\n if (next?.preset) setOpen(false);\n }}\n />\n ) : (\n <OptionsPanel\n definition={definition}\n value={value as string | string[] | undefined}\n focusRef={focusRef}\n onChange={(next) => {\n onChange(next);\n if (!definition.multiple) setOpen(false);\n }}\n />\n )}\n </Popover.Popup>\n </Popover.Positioner>\n </Popover.Portal>\n </Popover.Root>\n );\n}\n\nfunction OptionsPanel({\n definition,\n value,\n focusRef,\n onChange,\n}: {\n definition: SelectFilterDefinition;\n value: string | string[] | undefined;\n focusRef: RefObject<HTMLElement | null>;\n onChange: (next: string | string[] | undefined) => void;\n}) {\n const [query, setQuery] = useState(\"\");\n const searchable =\n definition.searchable ?? definition.options.length > SEARCHABLE_PAST;\n const chosen = new Set(\n value == null ? [] : Array.isArray(value) ? value : [value],\n );\n const needle = query.trim().toLowerCase();\n const options = needle\n ? definition.options.filter(\n (option) =>\n option.label.toLowerCase().includes(needle) ||\n option.value.toLowerCase().includes(needle),\n )\n : definition.options;\n const pick = (option: FilterOption) => {\n if (definition.multiple) {\n const next = new Set(chosen);\n if (next.has(option.value)) next.delete(option.value);\n else next.add(option.value);\n // Keep the definition's order, so the chip reads the same way\n // whatever order the values were chosen in.\n const ordered = definition.options\n .map((item) => item.value)\n .filter((item) => next.has(item));\n onChange(ordered.length > 0 ? ordered : undefined);\n return;\n }\n onChange(chosen.has(option.value) ? undefined : option.value);\n };\n return (\n <Command.Root\n label={`${definition.label} options`}\n // Without a search field the list itself takes focus, so the arrow\n // keys work from the first frame.\n ref={(node: HTMLDivElement | null) => {\n if (!searchable) focusRef.current = node;\n }}\n className=\"rounded-base\"\n >\n {searchable ? (\n <Command.InputGroup>\n <IconSearch\n aria-hidden\n className=\"text-pho-description pointer-events-none absolute left-3 size-4\"\n />\n <Command.Input\n ref={(node: HTMLInputElement | null) => {\n focusRef.current = node;\n }}\n value={query}\n onValueChange={setQuery}\n placeholder={definition.searchPlaceholder ?? \"Search\"}\n aria-label={`Search ${definition.label.toLowerCase()} options`}\n className=\"py-2 pr-3 pl-9 text-base\"\n />\n </Command.InputGroup>\n ) : null}\n <Command.List>\n <Command.Empty>Nothing matches.</Command.Empty>\n {options.map((option) => (\n <Command.Item\n key={option.value}\n value={option.value}\n title={option.label}\n aria-checked={chosen.has(option.value)}\n icon={chosen.has(option.value) ? <IconCheck aria-hidden /> : null}\n onSelect={() => pick(option)}\n />\n ))}\n </Command.List>\n </Command.Root>\n );\n}\n\nconst DATE_INPUT =\n \"bg-pho-primary ring-pho-primary text-pho-primary focus-visible:ring-pho-brand w-full min-w-0 rounded-sm px-2 py-1 text-base ring-1 transition-shadow duration-100 ease-linear outline-none ring-inset focus-visible:ring-2\";\n\nfunction DateRangePanel({\n definition,\n value,\n focusRef,\n onChange,\n}: {\n definition: DateRangeFilterDefinition;\n value: DateRangeValue | undefined;\n focusRef: RefObject<HTMLElement | null>;\n onChange: (next: DateRangeValue | undefined) => void;\n}) {\n const presets = definition.presets ?? FILTER_DATE_PRESETS;\n // A preset's `from` is a timestamp; the day field shows its date.\n const day = (side: string | null | undefined) =>\n side == null ? \"\" : DATE_ONLY.test(side) ? side : side.slice(0, 10);\n const setSide = (side: \"from\" | \"to\", next: string) => {\n // Editing either day leaves a preset behind: the pair is the value now,\n // and a preset's timestamp becomes the day it fell on.\n const range: DateRangeValue = {\n from: day(value?.from) || null,\n to: day(value?.to) || null,\n [side]: next || null,\n };\n onChange(range.from == null && range.to == null ? undefined : range);\n };\n return (\n <div className=\"flex flex-col\">\n <Command.Root\n label={`${definition.label} presets`}\n ref={(node: HTMLDivElement | null) => {\n focusRef.current = node;\n }}\n className=\"rounded-t-[inherit]\"\n >\n <Command.List>\n {presets.map((preset) => (\n <Command.Item\n key={preset.label}\n value={preset.label}\n title={preset.label}\n aria-checked={value?.preset === preset.label}\n icon={\n value?.preset === preset.label ? (\n <IconCheck aria-hidden />\n ) : null\n }\n onSelect={() =>\n onChange({\n from: new Date(\n Date.now() - preset.hours * 60 * 60 * 1000,\n ).toISOString(),\n to: null,\n preset: preset.label,\n })\n }\n />\n ))}\n </Command.List>\n </Command.Root>\n {/* The day fields stand outside the command list: its arrow-key\n handling would otherwise swallow the native date stepping. */}\n <div className=\"border-pho-secondary grid grid-cols-2 gap-2 border-t p-2\">\n <label className=\"text-pho-description flex min-w-0 flex-col gap-1 text-xs\">\n From\n <input\n type=\"date\"\n value={day(value?.from)}\n max={day(value?.to) || undefined}\n onChange={(event) => setSide(\"from\", event.target.value)}\n className={DATE_INPUT}\n />\n </label>\n <label className=\"text-pho-description flex min-w-0 flex-col gap-1 text-xs\">\n To\n <input\n type=\"date\"\n value={day(value?.to)}\n min={day(value?.from) || undefined}\n onChange={(event) => setSide(\"to\", event.target.value)}\n className={DATE_INPUT}\n />\n </label>\n </div>\n </div>\n );\n}\n\n/* ---------------------------------- bar --------------------------------- */\n\nexport interface FilterBarProps extends Omit<\n ComponentProps<\"div\">,\n \"children\"\n> {\n /** One chip per definition, in this order. */\n definitions: readonly FilterDefinition[];\n /** The values, keyed by definition key. Absent or empty means unset. */\n filters: FilterValues;\n /** The whole map, changed — set, cleared, or cleared all. */\n onFiltersChange: (next: FilterValues) => void;\n /** The search field's text. The field renders only with `onSearchChange`. */\n search?: string;\n onSearchChange?: (value: string) => void;\n /** A teaching phrase — \"Find an event by id\". @default \"Search\" */\n searchPlaceholder?: string;\n /** The field's accessible name when the placeholder is too short to be one. */\n searchLabel?: string;\n /**\n * Pin the bar to the top of the nearest scroll pane. It paints the\n * surface it sits on (`--pho-surface`) so rows scroll under it.\n */\n sticky?: boolean;\n /** Controls after the chips — a range picker, an export button. */\n children?: ReactNode;\n ref?: Ref<HTMLDivElement>;\n}\n\nexport function FilterBar({\n definitions,\n filters,\n onFiltersChange,\n search,\n onSearchChange,\n searchPlaceholder = \"Search\",\n searchLabel,\n sticky,\n className,\n children,\n ...props\n}: FilterBarProps) {\n const setCount = definitions.filter((definition) =>\n isFilterSet(filters[definition.key]),\n ).length;\n const change = (key: string, next: FilterValue | undefined) => {\n const rest = { ...filters };\n if (next === undefined) delete rest[key];\n else rest[key] = next;\n onFiltersChange(rest);\n };\n return (\n <div\n data-filter-bar=\"\"\n className={cn(\n \"flex min-w-0 flex-wrap items-center gap-2\",\n sticky &&\n \"sticky top-0 z-10 bg-[var(--pho-surface,var(--background-color-pho-page))] py-3\",\n className,\n )}\n {...props}\n >\n {onSearchChange != null ? (\n <InputGroup.Root size=\"sm\" className=\"w-64 max-w-full\">\n <InputGroup.Addon>\n <IconSearch />\n </InputGroup.Addon>\n <InputGroup.Input\n type=\"search\"\n value={search ?? \"\"}\n onChange={(event) => onSearchChange(event.target.value)}\n onKeyDown={(event) => {\n if (event.key !== \"Escape\") return;\n event.preventDefault();\n onSearchChange(\"\");\n }}\n placeholder={searchPlaceholder}\n aria-label={searchLabel ?? searchPlaceholder}\n />\n </InputGroup.Root>\n ) : null}\n {definitions.map((definition) => (\n <FilterChip\n key={definition.key}\n definition={definition}\n value={filters[definition.key]}\n onChange={(next) => change(definition.key, next)}\n />\n ))}\n {setCount > 1 ? (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => {\n const rest = { ...filters };\n for (const definition of definitions) delete rest[definition.key];\n onFiltersChange(rest);\n }}\n >\n Clear filters\n </Button>\n ) : null}\n {children}\n </div>\n );\n}\n\nFilterBar.displayName = \"FilterBar\";\n"],"x_google_ignoreList":[0],"mappings":"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"}
|
package/dist/components/error.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { a, c as s, i as t, l as e, n as o, o as i, r as E, s as p, t as l } from "../chunks/error-
|
|
2
|
+
import { a, c as s, i as t, l as e, n as o, o as i, r as E, s as p, t as l } from "../chunks/error-BAQgnde7.js";
|
|
3
3
|
export {
|
|
4
4
|
l as Error,
|
|
5
5
|
o as ErrorView,
|
package/dist/index.js
CHANGED
|
@@ -2,184 +2,182 @@
|
|
|
2
2
|
import { t as s } from "./chunks/cn-ChIgwEl3.js";
|
|
3
3
|
import { t as r } from "./chunks/is-react-component-DSnjtBmo.js";
|
|
4
4
|
import { t as e } from "./chunks/resolve-variant-CcD8iG5l.js";
|
|
5
|
-
import { n as
|
|
6
|
-
import { BAR_RISE_PX as n, BLUR_PX as m, EASE_POP as
|
|
5
|
+
import { n as E, t as S } from "./chunks/link-provider-DXzDQ08N.js";
|
|
6
|
+
import { BAR_RISE_PX as n, BLUR_PX as m, EASE_POP as I, EASE_STACK as T, FADE_ENTRANCE as p, FADE_SWAP as A, PRESS_SCALE as R, PRESS_SCALE_ROW as l, RISE_PX as C, SPRING_ENTRANCE as B, SPRING_PRESS as f, SPRING_PRESS_INLINE as N, SPRING_PRESS_QUICK as P, SPRING_SETTLE as u, TRAVEL_LINEAR as L, fadeThroughBlur as D, riseIn as c } from "./motion.js";
|
|
7
7
|
import { n as V, r as d, t as U } from "./chunks/use-press-pulse-IbNstUT0.js";
|
|
8
|
-
import { n as
|
|
8
|
+
import { n as F, t as b } from "./chunks/use-copy-D6JwKUll.js";
|
|
9
9
|
import "./utils.js";
|
|
10
|
-
import { a as h, c as v, d as k, i as w, l as W, n as x, o as H, r as z, s as K, t as
|
|
11
|
-
import { a as Z, c as j, i as J, l as Q, n as q, o as $, r as aa, s as sa, t as ta } from "./chunks/error-
|
|
12
|
-
import { A as oa, B as ea, C as
|
|
13
|
-
import { n as
|
|
14
|
-
import {
|
|
15
|
-
import { t as Es } from "./chunks/
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import { n as Cs, t as Bs } from "./chunks/
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import { t as
|
|
23
|
-
import {
|
|
24
|
-
import { n as
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import { i as
|
|
10
|
+
import { a as h, c as v, d as k, i as w, l as W, n as x, o as H, r as z, s as K, t as y, u as X } from "./chunks/button-CdqS_t5a.js";
|
|
11
|
+
import { a as Z, c as j, i as J, l as Q, n as q, o as $, r as aa, s as sa, t as ta } from "./chunks/error-BAQgnde7.js";
|
|
12
|
+
import { A as oa, B as ea, C as ia, D as Ea, E as Sa, F as _a, I as na, L as ma, M as Ia, N as Ta, O as pa, P as Aa, R as Ra, S as la, T as Ca, _ as Ba, a as fa, b as Na, c as Pa, d as ua, f as La, g as Da, h as ca, i as Oa, j as Va, k as da, l as Ua, m as Ga, n as Fa, o as ba, p as Ma, r as ga, s as ha, t as va, u as ka, v as wa, w as Wa, x as xa, y as Ha, z as za } from "./chunks/trace-Ba1RMBfk.js";
|
|
13
|
+
import { n as ya, t as Xa } from "./chunks/date-picker-Bwa6J4ik.js";
|
|
14
|
+
import { n as Za, t as ja } from "./chunks/copy-button-B_B15mEi.js";
|
|
15
|
+
import { a as Qa, c as qa, d as $a, i as as, l as ss, n as ts, o as rs, r as os, s as es, t as is, u as Es } from "./chunks/sidebar-DRPe5CAh.js";
|
|
16
|
+
import { t as _s } from "./chunks/input-DjvZoF8v.js";
|
|
17
|
+
import { i as ms, n as Is, r as Ts, t as ps } from "./chunks/filter-bar-D9lBBr4z.js";
|
|
18
|
+
import { a as Rs } from "./chunks/data-table-DcwCgXJU.js";
|
|
19
|
+
import { n as Cs, t as Bs } from "./chunks/code-block-BuDIo8Q0.js";
|
|
20
|
+
import { n as Ns, t as Ps } from "./chunks/stat-hnNqjWVG.js";
|
|
21
|
+
import { t as Ls } from "./chunks/calendar-4OFiCLAv.js";
|
|
22
|
+
import { t as cs } from "./chunks/close-button-GvqWbLl0.js";
|
|
23
|
+
import { t as Vs } from "./chunks/input-group-fc9_jD4d.js";
|
|
24
|
+
import { n as Us, t as Gs } from "./chunks/card-DhDwtSi9.js";
|
|
25
|
+
import { n as bs, t as Ms } from "./chunks/dialog-BwfUFn6B.js";
|
|
26
|
+
import { i as hs, n as vs, r as ks, t as ws } from "./chunks/status-view-C8tabjDu.js";
|
|
27
|
+
import { a as xs, c as Hs, d as zs, f as Ks, i as ys, l as Xs, m as Ys, n as Zs, o as js, p as Js, r as Qs, s as qs, t as $s, u as at } from "./chunks/basic-page-CYDwfVjO.js";
|
|
28
|
+
import { i as tt, n as rt, r as ot, t as et } from "./chunks/legend-C0mU7dqd.js";
|
|
28
29
|
import "./components/chart.js";
|
|
29
|
-
import { t as
|
|
30
|
-
import { t as
|
|
31
|
-
import { i as
|
|
32
|
-
import { t as
|
|
30
|
+
import { t as St } from "./chunks/bar-chart-DIALC2_z.js";
|
|
31
|
+
import { t as nt } from "./chunks/line-chart-VuMYKzW3.js";
|
|
32
|
+
import { i as It, n as Tt, r as pt, t as At } from "./chunks/log-list-BERiO4UJ.js";
|
|
33
|
+
import { t as lt } from "./chunks/description-list-C-mwe4ki.js";
|
|
33
34
|
export {
|
|
34
|
-
|
|
35
|
+
$s as AUTO_SAVE_DELAY_MS,
|
|
35
36
|
n as BAR_RISE_PX,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
Zs as BASIC_PAGE_CALLOUT,
|
|
38
|
+
Qs as BASIC_PAGE_CARD,
|
|
39
|
+
ys as BASIC_PAGE_ITEM,
|
|
40
|
+
xs as BASIC_PAGE_ITEM_PANEL,
|
|
41
|
+
js as BASIC_PAGE_ITEM_PANEL_DIVIDED,
|
|
42
|
+
qs as BASIC_PAGE_ROW,
|
|
42
43
|
m as BLUR_PX,
|
|
43
|
-
|
|
44
|
+
y as BUTTON_COLORS,
|
|
44
45
|
x as BUTTON_SHAPES,
|
|
45
46
|
z as BUTTON_SIZES,
|
|
46
47
|
w as BUTTON_VARIANTS,
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
St as BarChart,
|
|
49
|
+
Hs as BasicPage,
|
|
49
50
|
h as Button,
|
|
50
51
|
H as ButtonLink,
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
Gs as CARD_SURFACE,
|
|
53
|
+
ot as CHART_SLOTS,
|
|
54
|
+
Xs as CONDENSE_BAR_ENTER,
|
|
55
|
+
at as CONDENSE_BAR_RISE_PX,
|
|
56
|
+
zs as CONDENSE_BAR_TRAVEL,
|
|
56
57
|
U as CONTROL_PRESS_SCALE,
|
|
57
58
|
V as CONTROL_PRESS_SPRING,
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
et as
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
I as
|
|
59
|
+
ja as COPY_BUTTON_SIZES,
|
|
60
|
+
b as COPY_FEEDBACK_MS,
|
|
61
|
+
Ls as Calendar,
|
|
62
|
+
Us as Card,
|
|
63
|
+
et as ChartLegend,
|
|
64
|
+
rt as ChartSwatch,
|
|
65
|
+
cs as CloseButton,
|
|
66
|
+
Bs as CodeBlock,
|
|
67
|
+
Za as CopyButton,
|
|
68
|
+
Xa as DatePicker,
|
|
69
|
+
lt as DescriptionList,
|
|
70
|
+
Ms as Dialog,
|
|
71
|
+
I as EASE_POP,
|
|
72
|
+
T as EASE_STACK,
|
|
71
73
|
K as EFFECT_BUTTON_SIZES,
|
|
72
74
|
v as EffectButton,
|
|
73
75
|
W as EffectButtonLink,
|
|
74
76
|
ta as Error,
|
|
75
77
|
q as ErrorView,
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
78
|
+
p as FADE_ENTRANCE,
|
|
79
|
+
A as FADE_SWAP,
|
|
80
|
+
ps as FILTER_DATE_PRESETS,
|
|
79
81
|
la as FULL_VIEW,
|
|
80
|
-
|
|
82
|
+
Is as FilterBar,
|
|
81
83
|
aa as GENERIC_ERROR_TITLE,
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
La as GEN_AI_KINDS,
|
|
85
|
+
_s as Input,
|
|
86
|
+
Vs as InputGroup,
|
|
87
|
+
nt as LineChart,
|
|
86
88
|
S as LinkProvider,
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
p as PRESS_SCALE,
|
|
89
|
+
At as LogList,
|
|
90
|
+
ia as MIN_VIEW_WIDTH,
|
|
91
|
+
R as PRESS_SCALE,
|
|
91
92
|
l as PRESS_SCALE_ROW,
|
|
92
93
|
C as RISE_PX,
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
94
|
+
is as SIDEBAR_HEADER_INSET,
|
|
95
|
+
ts as SIDEBAR_ITEM,
|
|
96
|
+
os as SIDEBAR_ITEM_ACTIVE,
|
|
97
|
+
as as SIDEBAR_ITEM_INACTIVE,
|
|
98
|
+
Qa as SIDEBAR_ROOT,
|
|
99
|
+
rs as SIDEBAR_ROOT_BASE,
|
|
100
|
+
es as SIDEBAR_ROOT_INSET,
|
|
101
|
+
qa as SIDEBAR_SUBMENU_CHEVRON,
|
|
102
|
+
ss as SIDEBAR_SUBMENU_LIST_INDENT,
|
|
103
|
+
Es as SIDEBAR_SUBMENU_TRIGGER_CHILD_ACTIVE,
|
|
103
104
|
B as SPRING_ENTRANCE,
|
|
104
105
|
f as SPRING_PRESS,
|
|
105
106
|
N as SPRING_PRESS_INLINE,
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
107
|
+
P as SPRING_PRESS_QUICK,
|
|
108
|
+
u as SPRING_SETTLE,
|
|
109
|
+
ws as STATUS_VIEW,
|
|
110
|
+
vs as STATUS_VIEW_COPY,
|
|
111
|
+
ks as STATUS_VIEW_SIZES,
|
|
112
|
+
$a as Sidebar,
|
|
112
113
|
Ha as SpanPrimitive,
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
114
|
+
Ps as Stat,
|
|
115
|
+
Ns as StatGroup,
|
|
116
|
+
hs as StatusView,
|
|
117
|
+
L as TRAVEL_LINEAR,
|
|
117
118
|
va as Trace,
|
|
118
119
|
Wa as allCollapsed,
|
|
119
120
|
Ca as ancestorIds,
|
|
120
|
-
|
|
121
|
+
Ma as attribute,
|
|
121
122
|
Ga as attributeText,
|
|
122
123
|
Oa as axisTicks,
|
|
123
124
|
fa as barGeometry,
|
|
124
125
|
Sa as buildSpanTree,
|
|
125
|
-
|
|
126
|
+
X as buttonVariants,
|
|
126
127
|
J as capitalizeFirst,
|
|
127
|
-
|
|
128
|
-
|
|
128
|
+
tt as chartColor,
|
|
129
|
+
Ea as clampView,
|
|
129
130
|
s as cn,
|
|
130
|
-
|
|
131
|
+
pa as collapseAllIds,
|
|
131
132
|
da as collapseOneLevel,
|
|
132
|
-
|
|
133
|
-
Os as dateRangeError,
|
|
133
|
+
Rs as createColumns,
|
|
134
134
|
oa as deriveSpanTree,
|
|
135
135
|
Z as describeError,
|
|
136
136
|
k as effectButtonVariants,
|
|
137
137
|
Va as expandOneLevel,
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
138
|
+
D as fadeThroughBlur,
|
|
139
|
+
Ia as filterSpans,
|
|
140
|
+
Fa as footerTotals,
|
|
141
|
+
Ks as formToasts,
|
|
142
|
+
ya as formatDateLabel,
|
|
143
|
+
ba as formatDuration,
|
|
144
|
+
Ts as formatFilterValue,
|
|
145
145
|
ha as formatTick,
|
|
146
|
-
Ps as fromDateTimeLocalValue,
|
|
147
146
|
ca as genAIKind,
|
|
148
147
|
$ as httpReasonPhrase,
|
|
149
148
|
sa as httpStatusExplanation,
|
|
150
|
-
|
|
151
|
-
|
|
149
|
+
ms as isFilterSet,
|
|
150
|
+
Ta as isFullView,
|
|
152
151
|
j as isProblem,
|
|
153
152
|
r as isReactComponent,
|
|
154
|
-
|
|
155
|
-
|
|
153
|
+
Pa as labeledTicks,
|
|
154
|
+
Tt as logStatusColor,
|
|
156
155
|
pt as logStatusLabel,
|
|
157
156
|
Ua as niceStep,
|
|
158
157
|
ka as normalizeSpans,
|
|
159
|
-
|
|
158
|
+
Aa as panView,
|
|
160
159
|
Q as parseProblem,
|
|
161
|
-
|
|
160
|
+
Da as peerService,
|
|
162
161
|
e as resolveVariant,
|
|
163
162
|
c as riseIn,
|
|
164
163
|
Ba as spanDecorationIcon,
|
|
165
|
-
|
|
164
|
+
ua as spanDuration,
|
|
166
165
|
wa as spanPills,
|
|
167
166
|
_a as spanTimelineBarVars,
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
ba as traceBulletInset,
|
|
167
|
+
Cs as tokenizeJson,
|
|
168
|
+
ga as traceBulletInset,
|
|
171
169
|
na as traceRange,
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
170
|
+
It as truncateMiddle,
|
|
171
|
+
Js as useAutoSave,
|
|
172
|
+
Ys as useCondense,
|
|
173
|
+
F as useCopy,
|
|
176
174
|
bs as useDialogPending,
|
|
177
|
-
|
|
175
|
+
E as useLinkComponent,
|
|
178
176
|
d as usePressPulse,
|
|
179
177
|
Na as useSpan,
|
|
180
178
|
xa as useSpanTree,
|
|
181
179
|
ma as viewFraction,
|
|
182
|
-
|
|
180
|
+
Ra as viewToRange,
|
|
183
181
|
za as visibleSpans,
|
|
184
182
|
ea as zoomView
|
|
185
183
|
};
|