@photon-ai/pho-ui 4.8.0 → 4.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/chunks/bar-chart-ht70KKj3.js +19 -0
  2. package/dist/chunks/bar-chart-ht70KKj3.js.map +1 -0
  3. package/dist/chunks/{basic-page-BqfpJgAj.js → basic-page-DzT8yecB.js} +176 -175
  4. package/dist/chunks/basic-page-DzT8yecB.js.map +1 -0
  5. package/dist/chunks/chart-B5c8gmlj.js +1338 -0
  6. package/dist/chunks/chart-B5c8gmlj.js.map +1 -0
  7. package/dist/chunks/code-block-CbcE994O.js +516 -0
  8. package/dist/chunks/code-block-CbcE994O.js.map +1 -0
  9. package/dist/chunks/line-chart-Cm_Ac7f4.js +22 -0
  10. package/dist/chunks/line-chart-Cm_Ac7f4.js.map +1 -0
  11. package/dist/components/bar-chart.js +1 -1
  12. package/dist/components/chart.js +8 -5
  13. package/dist/components/code-block.js +12 -3
  14. package/dist/components/line-chart.js +1 -1
  15. package/dist/index.js +175 -162
  16. package/dist/motion.js +14 -13
  17. package/dist/motion.js.map +1 -1
  18. package/dist/primitives.js +1 -1
  19. package/dist/sections/basic-page.js +1 -1
  20. package/dist/src/components/bar-chart/bar-chart.d.ts +9 -1
  21. package/dist/src/components/chart/chart.d.ts +25 -0
  22. package/dist/src/components/chart/format.d.ts +9 -5
  23. package/dist/src/components/chart/index.d.ts +7 -4
  24. package/dist/src/components/chart/scale.d.ts +2 -2
  25. package/dist/src/components/chart/shell.d.ts +20 -13
  26. package/dist/src/components/chart/skeleton.d.ts +11 -0
  27. package/dist/src/components/chart/theme.d.ts +8 -0
  28. package/dist/src/components/chart/types.d.ts +39 -2
  29. package/dist/src/components/chart/use-measure.d.ts +2 -1
  30. package/dist/src/components/code-block/code-block.d.ts +23 -11
  31. package/dist/src/components/code-block/highlight.d.ts +24 -0
  32. package/dist/src/components/code-block/index.d.ts +4 -1
  33. package/dist/src/components/code-block/languages.d.ts +64 -0
  34. package/dist/src/components/code-block/pho-theme.d.ts +18 -0
  35. package/dist/src/components/code-block/tokens.d.ts +14 -0
  36. package/dist/src/components/line-chart/line-chart.d.ts +12 -3
  37. package/dist/src/motion/index.d.ts +6 -0
  38. package/dist/src/sections/basic-page/basic-page.d.ts +2 -0
  39. package/package.json +4 -1
  40. package/src/styles/theme.css +17 -4
  41. package/dist/chunks/IconArrowsMinimize-BfPUGuCB.js +0 -75
  42. package/dist/chunks/IconArrowsMinimize-BfPUGuCB.js.map +0 -1
  43. package/dist/chunks/bar-chart-DIALC2_z.js +0 -190
  44. package/dist/chunks/bar-chart-DIALC2_z.js.map +0 -1
  45. package/dist/chunks/basic-page-BqfpJgAj.js.map +0 -1
  46. package/dist/chunks/code-block-BuFfh0zH.js +0 -197
  47. package/dist/chunks/code-block-BuFfh0zH.js.map +0 -1
  48. package/dist/chunks/legend-C0mU7dqd.js +0 -60
  49. package/dist/chunks/legend-C0mU7dqd.js.map +0 -1
  50. package/dist/chunks/line-chart-VuMYKzW3.js +0 -453
  51. package/dist/chunks/line-chart-VuMYKzW3.js.map +0 -1
  52. package/dist/chunks/use-measure-C-i54AC6.js +0 -629
  53. package/dist/chunks/use-measure-C-i54AC6.js.map +0 -1
  54. package/dist/src/components/chart/axes.d.ts +0 -22
@@ -1,197 +0,0 @@
1
- "use client";
2
- import { t as v } from "./cn-ChIgwEl3.js";
3
- import { a as V } from "./button-C9VqBBIr.js";
4
- import { t as Y } from "./createReactComponent-BqCmnqfX.js";
5
- import { n as q, t as G } from "./IconArrowsMinimize-BfPUGuCB.js";
6
- import { t as Q } from "./IconChevronDown-CZilB71T.js";
7
- import { t as X } from "./IconChevronUp-CrpWSgIl.js";
8
- import { n as Z } from "./copy-button-D8XyP0oR.js";
9
- import { t as p } from "./scroll-area-DSwD9th7.js";
10
- import { t as u } from "./tooltip-BTF7GChl.js";
11
- import { n as ee } from "./toggle-o84tawXy.js";
12
- import { useMemo as M, useState as W } from "react";
13
- import { jsx as e, jsxs as m } from "react/jsx-runtime";
14
- var te = [
15
- ["path", {
16
- d: "M4 6l16 0",
17
- key: "svg-0"
18
- }],
19
- ["path", {
20
- d: "M4 18l5 0",
21
- key: "svg-1"
22
- }],
23
- ["path", {
24
- d: "M4 12h13a3 3 0 0 1 0 6h-4l2 -2m0 4l-2 -2",
25
- key: "svg-2"
26
- }]
27
- ], ne = Y("outline", "text-wrap", "TextWrap", te), b = /("(?:[^"\\]|\\.)*")(\s*:)?|(-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)|\b(true|false|null)\b|([{}[\]:,])/g;
28
- function oe(t) {
29
- const r = [];
30
- let n = 0;
31
- b.lastIndex = 0;
32
- for (let o = b.exec(t); o != null; o = b.exec(t)) {
33
- o.index > n && r.push({
34
- type: "plain",
35
- text: t.slice(n, o.index)
36
- });
37
- const [, l, a, c, s, d] = o;
38
- l != null ? (r.push({
39
- type: a != null ? "key" : "string",
40
- text: l
41
- }), a != null && r.push({
42
- type: "punctuation",
43
- text: a
44
- })) : c != null ? r.push({
45
- type: "number",
46
- text: c
47
- }) : s != null ? r.push({
48
- type: "keyword",
49
- text: s
50
- }) : d != null && r.push({
51
- type: "punctuation",
52
- text: d
53
- }), n = o.index + o[0].length;
54
- }
55
- return n < t.length && r.push({
56
- type: "plain",
57
- text: t.slice(n)
58
- }), r;
59
- }
60
- var re = {
61
- key: "text-pho-code-key",
62
- string: "text-pho-code-string",
63
- number: "text-pho-code-number",
64
- keyword: "text-pho-code-keyword",
65
- punctuation: "text-pho-code-punctuation",
66
- plain: void 0
67
- }, le = "rounded-base border border-pho-secondary bg-pho-code-bg text-pho-code-fg", ae = "1.25rem", se = "0.75rem";
68
- function ie(t) {
69
- if (t == null) return "";
70
- if (typeof t == "string") return t;
71
- try {
72
- return JSON.stringify(t, null, 2) ?? "";
73
- } catch {
74
- return String(t);
75
- }
76
- }
77
- function _({ label: t, pressed: r, onPressedChange: n, children: o }) {
78
- return /* @__PURE__ */ m(u.Root, { children: [/* @__PURE__ */ e(u.Trigger, { render: /* @__PURE__ */ e(ee, {
79
- size: "sm",
80
- pressed: r,
81
- onPressedChange: n,
82
- "aria-label": t,
83
- className: "rounded-sm",
84
- children: o
85
- }) }), /* @__PURE__ */ e(u.Portal, { children: /* @__PURE__ */ e(u.Positioner, { children: /* @__PURE__ */ e(u.Popup, { children: t }) }) })] });
86
- }
87
- function ce({ lines: t, language: r, lineNumbers: n, digits: o, wrap: l }) {
88
- return /* @__PURE__ */ e("code", { children: t.map((a, c) => /* @__PURE__ */ m("span", {
89
- "data-line": "",
90
- className: v("min-h-5", n ? "flex items-start" : "block", n && !l && "min-w-max"),
91
- children: [n ? /* @__PURE__ */ e("span", {
92
- "data-line-number": "",
93
- "aria-hidden": !0,
94
- className: "text-pho-placeholder bg-pho-code-bg sticky left-0 z-[1] box-content shrink-0 pr-3 pl-3 text-right font-mono text-xs leading-5 tabular-nums select-none",
95
- style: { width: `${o}ch` },
96
- children: c + 1
97
- }) : null, /* @__PURE__ */ e("span", {
98
- className: n ? "min-w-0 flex-1" : void 0,
99
- children: r === "json" ? oe(a).map((s, d) => s.type === "plain" ? s.text : /* @__PURE__ */ e("span", {
100
- className: re[s.type],
101
- children: s.text
102
- }, d)) : a
103
- })]
104
- }, c)) });
105
- }
106
- function pe({ code: t, language: r = "text", title: n, maxLines: o = 30, overflow: l = "scroll", wrap: a, defaultWrap: c = !1, onWrapChange: s, expandToggle: d = !0, wrapToggle: $ = !0, lineNumbers: C = !1, copy: A = !0, empty: O = "Nothing to show.", actions: N, className: P, ...B }) {
107
- const x = M(() => ie(t), [t]), h = M(() => x.split(`
108
- `), [x]), [L, D] = W(c), f = a ?? L, R = (w) => {
109
- a == null && D(w), s?.(w);
110
- }, [i, k] = W(!1), g = h.length > o, S = l === "scroll" && g && !i, j = l === "expand" && g && !i ? h.slice(0, o) : h, y = x === "", T = l === "scroll" && d && g && !y, E = $ && !y, z = A && !y, H = n != null || N != null || T || E || z, K = typeof n == "string" ? n.toLowerCase() : "code", J = typeof n == "string" ? n : "Code", U = i ? `Collapse to ${o} lines` : `Show all ${h.length} lines`, F = String(Math.max(h.length, 1)).length, I = /* @__PURE__ */ e("pre", {
111
- className: v("m-0 min-w-0 py-3 font-mono text-xs leading-5", C ? "pr-3 pl-0" : "px-3", f ? "[overflow-wrap:anywhere] whitespace-pre-wrap" : S ? "w-max min-w-full whitespace-pre" : "max-w-full overflow-x-auto whitespace-pre"),
112
- children: /* @__PURE__ */ e(ce, {
113
- lines: j,
114
- language: r,
115
- lineNumbers: C,
116
- digits: F,
117
- wrap: f
118
- })
119
- });
120
- return /* @__PURE__ */ m("div", {
121
- "data-code-block": "",
122
- "data-language": r,
123
- "data-overflow": l,
124
- className: v(le, "flex w-full min-w-0 flex-col overflow-hidden", P),
125
- ...B,
126
- children: [
127
- H ? /* @__PURE__ */ m("div", {
128
- className: "border-pho-secondary flex min-h-10 items-center gap-2 border-b py-1 pr-1.5 pl-3",
129
- children: [
130
- /* @__PURE__ */ e("div", {
131
- className: "text-pho-secondary min-w-0 flex-1 truncate text-xs font-medium",
132
- children: n
133
- }),
134
- N,
135
- /* @__PURE__ */ m(u.Provider, { children: [T ? /* @__PURE__ */ e(_, {
136
- label: U,
137
- pressed: i,
138
- onPressedChange: k,
139
- children: i ? /* @__PURE__ */ e(G, { "aria-hidden": !0 }) : /* @__PURE__ */ e(q, { "aria-hidden": !0 })
140
- }) : null, E ? /* @__PURE__ */ e(_, {
141
- label: "Wrap long lines",
142
- pressed: f,
143
- onPressedChange: R,
144
- children: /* @__PURE__ */ e(ne, { "aria-hidden": !0 })
145
- }) : null] }),
146
- z ? /* @__PURE__ */ e(Z, {
147
- value: x,
148
- label: K,
149
- size: "md"
150
- }) : null
151
- ]
152
- }) : null,
153
- y ? /* @__PURE__ */ e("p", {
154
- className: "text-pho-description m-0 px-3 py-3 text-base",
155
- children: O
156
- }) : S ? /* @__PURE__ */ e("section", {
157
- className: "min-w-0",
158
- children: /* @__PURE__ */ m(p.Root, {
159
- fade: !1,
160
- "data-code-scroll": "",
161
- className: "min-w-0 rounded-b-[inherit]",
162
- style: { height: `calc(${o} * ${ae} + ${se} * 2)` },
163
- children: [
164
- /* @__PURE__ */ e(p.Viewport, {
165
- tabIndex: 0,
166
- "aria-label": J,
167
- children: /* @__PURE__ */ e(p.Content, { children: I })
168
- }),
169
- /* @__PURE__ */ e(p.Scrollbar, { children: /* @__PURE__ */ e(p.Thumb, {}) }),
170
- f ? null : /* @__PURE__ */ e(p.Scrollbar, {
171
- orientation: "horizontal",
172
- children: /* @__PURE__ */ e(p.Thumb, {})
173
- })
174
- ]
175
- })
176
- }) : I,
177
- l === "expand" && g ? /* @__PURE__ */ e("div", {
178
- className: "border-pho-secondary flex items-center border-t px-1.5 py-1",
179
- children: /* @__PURE__ */ e(V, {
180
- variant: "ghost",
181
- size: "sm",
182
- "aria-expanded": i,
183
- prefix: i ? X : Q,
184
- onClick: () => k((w) => !w),
185
- children: i ? "Show less" : `Show all ${h.length} lines`
186
- })
187
- }) : null
188
- ]
189
- });
190
- }
191
- pe.displayName = "CodeBlock";
192
- export {
193
- oe as n,
194
- pe as t
195
- };
196
-
197
- //# sourceMappingURL=code-block-BuFfh0zH.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"code-block-BuFfh0zH.js","names":[],"sources":["../../../../node_modules/.pnpm/@tabler+icons-react@3.46.0_react@19.2.8/node_modules/@tabler/icons-react/dist/esm/icons/IconTextWrap.mjs","../../src/components/code-block/tokenize-json.ts","../../src/components/code-block/code-block.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\": \"M4 6l16 0\", \"key\": \"svg-0\" }], [\"path\", { \"d\": \"M4 18l5 0\", \"key\": \"svg-1\" }], [\"path\", { \"d\": \"M4 12h13a3 3 0 0 1 0 6h-4l2 -2m0 4l-2 -2\", \"key\": \"svg-2\" }]];\nconst IconTextWrap = createReactComponent(\"outline\", \"text-wrap\", \"TextWrap\", __iconNode);\n\nexport { __iconNode, IconTextWrap as default };\n//# sourceMappingURL=IconTextWrap.mjs.map\n","/**\n * A tokenizer for JSON, and nothing else: keys, strings, numbers, the\n * three keywords, and punctuation. Runs one line at a time (a JSON\n * string never spans lines) so a panel can show its first N lines and\n * stop. Text that isn't JSON comes back as it is, in plain tokens.\n */\n\nexport type JsonTokenType =\n \"key\" | \"string\" | \"number\" | \"keyword\" | \"punctuation\" | \"plain\";\n\nexport interface JsonToken {\n type: JsonTokenType;\n text: string;\n}\n\n// One pass, left to right: a string (a key when a colon follows), a\n// number, a keyword, a bracket or a comma. Anything between is plain.\nconst TOKEN =\n /(\"(?:[^\"\\\\]|\\\\.)*\")(\\s*:)?|(-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?)|\\b(true|false|null)\\b|([{}[\\]:,])/g;\n\nexport function tokenizeJson(line: string): JsonToken[] {\n const tokens: JsonToken[] = [];\n let last = 0;\n TOKEN.lastIndex = 0;\n for (let match = TOKEN.exec(line); match != null; match = TOKEN.exec(line)) {\n if (match.index > last) {\n tokens.push({ type: \"plain\", text: line.slice(last, match.index) });\n }\n const [, string, colon, number, keyword, punctuation] = match;\n if (string != null) {\n tokens.push({ type: colon != null ? \"key\" : \"string\", text: string });\n if (colon != null) tokens.push({ type: \"punctuation\", text: colon });\n } else if (number != null) {\n tokens.push({ type: \"number\", text: number });\n } else if (keyword != null) {\n tokens.push({ type: \"keyword\", text: keyword });\n } else if (punctuation != null) {\n tokens.push({ type: \"punctuation\", text: punctuation });\n }\n last = match.index + match[0].length;\n }\n if (last < line.length) {\n tokens.push({ type: \"plain\", text: line.slice(last) });\n }\n return tokens;\n}\n","import {\n useMemo,\n useState,\n type ComponentProps,\n type ReactNode,\n type Ref,\n} from \"react\";\nimport {\n IconArrowsMaximize,\n IconArrowsMinimize,\n IconChevronDown,\n IconChevronUp,\n IconTextWrap,\n} from \"@tabler/icons-react\";\nimport { Button } from \"../button\";\nimport { CopyButton } from \"../copy-button\";\nimport { ScrollArea } from \"../scroll-area\";\nimport { Toggle } from \"../toggle\";\nimport { Tooltip } from \"../tooltip\";\nimport { cn } from \"../../utils/cn\";\nimport { tokenizeJson, type JsonTokenType } from \"./tokenize-json\";\n\n/**\n * Code Block — a read-only panel for a request body, a response, an\n * event's JSON. Mono text on the code surface, a title row with expand,\n * wrap, and copy controls. Past `maxLines` the body either scrolls\n * inside that height (`overflow=\"scroll\"`, the default) or folds with a\n * footer button (`overflow=\"expand\"`).\n *\n * Design notes:\n * - Wide lines scroll sideways inside the panel; the page never does.\n * Wrapping is a toggle (`wrap` / `defaultWrap`), off by default so a\n * body reads the way it was sent.\n * - `language=\"json\"` colors keys, strings, numbers, and keywords with a\n * built-in tokenizer — no highlighter library at runtime — on the\n * `--color-pho-code-*` tokens, which carry light and dark.\n * - A body that isn't a string (an object) is pretty-printed as JSON.\n */\n\nexport type CodeBlockLanguage = \"json\" | \"text\";\n\nexport type CodeBlockOverflow = \"scroll\" | \"expand\";\n\nconst TOKEN_CLASS: Record<JsonTokenType, string | undefined> = {\n key: \"text-pho-code-key\",\n string: \"text-pho-code-string\",\n number: \"text-pho-code-number\",\n keyword: \"text-pho-code-keyword\",\n punctuation: \"text-pho-code-punctuation\",\n plain: undefined,\n};\n\n/** The panel's chrome — the card hairline around the code surface. */\nconst CODE_BLOCK_SURFACE =\n \"rounded-base border border-pho-secondary bg-pho-code-bg text-pho-code-fg\";\n\n/** One code line is `leading-5` / `min-h-5`; the pre pads `py-3`. */\nconst LINE_H = \"1.25rem\";\nconst PAD_Y = \"0.75rem\";\n\nexport interface CodeBlockProps extends Omit<\n ComponentProps<\"div\">,\n \"title\" | \"children\"\n> {\n /** The text. An object is pretty-printed as JSON (two-space indent). */\n code?: string | object | null;\n /** `json` colors the text; `text` leaves it plain. @default \"text\" */\n language?: CodeBlockLanguage;\n /** The title row's words — \"Request body\", \"Response\". */\n title?: ReactNode;\n /** Past this many lines the panel folds or clips. @default 30 */\n maxLines?: number;\n /**\n * How a long body is shown past `maxLines`. `scroll` clips to that\n * height and scrolls inside, with an expand toggle in the title row.\n * `expand` folds and shows a footer button.\n * @default \"scroll\"\n */\n overflow?: CodeBlockOverflow;\n /** Wrap long lines (controlled). */\n wrap?: boolean;\n /** Wrap long lines at first (uncontrolled). @default false */\n defaultWrap?: boolean;\n onWrapChange?: (wrap: boolean) => void;\n /** The expand toggle in the title row when `overflow` is `scroll`. @default true */\n expandToggle?: boolean;\n /** The wrap toggle in the title row. @default true */\n wrapToggle?: boolean;\n /**\n * A gutter of line numbers. Off by default; turn on for a long\n * payload (about twenty lines or more).\n * @default false\n */\n lineNumbers?: boolean;\n /** The copy control in the title row. @default true */\n copy?: boolean;\n /** What the panel says with no code. @default \"Nothing to show.\" */\n empty?: ReactNode;\n /** More controls in the title row, before the built-in ones. */\n actions?: ReactNode;\n ref?: Ref<HTMLDivElement>;\n}\n\nfunction toText(code: CodeBlockProps[\"code\"]): string {\n if (code == null) return \"\";\n if (typeof code === \"string\") return code;\n try {\n return JSON.stringify(code, null, 2) ?? \"\";\n } catch {\n return String(code);\n }\n}\n\nfunction HeaderToggle({\n label,\n pressed,\n onPressedChange,\n children,\n}: {\n label: string;\n pressed: boolean;\n onPressedChange: (next: boolean) => void;\n children: ReactNode;\n}) {\n return (\n <Tooltip.Root>\n <Tooltip.Trigger\n render={\n <Toggle\n size=\"sm\"\n pressed={pressed}\n onPressedChange={onPressedChange}\n aria-label={label}\n className=\"rounded-sm\"\n >\n {children}\n </Toggle>\n }\n />\n <Tooltip.Portal>\n <Tooltip.Positioner>\n <Tooltip.Popup>{label}</Tooltip.Popup>\n </Tooltip.Positioner>\n </Tooltip.Portal>\n </Tooltip.Root>\n );\n}\n\nfunction CodeLines({\n lines,\n language,\n lineNumbers,\n digits,\n wrap,\n}: {\n lines: string[];\n language: CodeBlockLanguage;\n lineNumbers: boolean;\n digits: number;\n wrap: boolean;\n}) {\n return (\n <code>\n {lines.map((line, index) => (\n <span\n key={index}\n data-line=\"\"\n className={cn(\n \"min-h-5\",\n lineNumbers ? \"flex items-start\" : \"block\",\n lineNumbers && !wrap && \"min-w-max\",\n )}\n >\n {lineNumbers ? (\n <span\n data-line-number=\"\"\n aria-hidden\n className=\"text-pho-placeholder bg-pho-code-bg sticky left-0 z-[1] box-content shrink-0 pr-3 pl-3 text-right font-mono text-xs leading-5 tabular-nums select-none\"\n style={{ width: `${digits}ch` }}\n >\n {index + 1}\n </span>\n ) : null}\n <span className={lineNumbers ? \"min-w-0 flex-1\" : undefined}>\n {language === \"json\"\n ? tokenizeJson(line).map((token, at) =>\n token.type === \"plain\" ? (\n token.text\n ) : (\n <span key={at} className={TOKEN_CLASS[token.type]}>\n {token.text}\n </span>\n ),\n )\n : line}\n </span>\n </span>\n ))}\n </code>\n );\n}\n\nexport function CodeBlock({\n code,\n language = \"text\",\n title,\n maxLines = 30,\n overflow = \"scroll\",\n wrap: wrapProp,\n defaultWrap = false,\n onWrapChange,\n expandToggle = true,\n wrapToggle = true,\n lineNumbers = false,\n copy = true,\n empty = \"Nothing to show.\",\n actions,\n className,\n ...props\n}: CodeBlockProps) {\n const text = useMemo(() => toText(code), [code]);\n const lines = useMemo(() => text.split(\"\\n\"), [text]);\n const [ownWrap, setOwnWrap] = useState(defaultWrap);\n const wrap = wrapProp ?? ownWrap;\n const setWrap = (next: boolean) => {\n if (wrapProp == null) setOwnWrap(next);\n onWrapChange?.(next);\n };\n const [expanded, setExpanded] = useState(false);\n const folds = lines.length > maxLines;\n const scrolling = overflow === \"scroll\" && folds && !expanded;\n const shown =\n overflow === \"expand\" && folds && !expanded\n ? lines.slice(0, maxLines)\n : lines;\n const isEmpty = text === \"\";\n const showExpandToggle =\n overflow === \"scroll\" && expandToggle && folds && !isEmpty;\n const showWrapToggle = wrapToggle && !isEmpty;\n const showCopy = copy && !isEmpty;\n const hasHeader =\n title != null ||\n actions != null ||\n showExpandToggle ||\n showWrapToggle ||\n showCopy;\n const copyLabel = typeof title === \"string\" ? title.toLowerCase() : \"code\";\n const scrollLabel = typeof title === \"string\" ? title : \"Code\";\n const expandLabel = expanded\n ? `Collapse to ${maxLines} lines`\n : `Show all ${lines.length} lines`;\n const lineNoDigits = String(Math.max(lines.length, 1)).length;\n const body = (\n <pre\n className={cn(\n \"m-0 min-w-0 py-3 font-mono text-xs leading-5\",\n lineNumbers ? \"pr-3 pl-0\" : \"px-3\",\n wrap\n ? \"[overflow-wrap:anywhere] whitespace-pre-wrap\"\n : scrolling\n ? \"w-max min-w-full whitespace-pre\"\n : \"max-w-full overflow-x-auto whitespace-pre\",\n )}\n >\n <CodeLines\n lines={shown}\n language={language}\n lineNumbers={lineNumbers}\n digits={lineNoDigits}\n wrap={wrap}\n />\n </pre>\n );\n return (\n <div\n data-code-block=\"\"\n data-language={language}\n data-overflow={overflow}\n className={cn(\n CODE_BLOCK_SURFACE,\n \"flex w-full min-w-0 flex-col overflow-hidden\",\n className,\n )}\n {...props}\n >\n {hasHeader ? (\n <div className=\"border-pho-secondary flex min-h-10 items-center gap-2 border-b py-1 pr-1.5 pl-3\">\n <div className=\"text-pho-secondary min-w-0 flex-1 truncate text-xs font-medium\">\n {title}\n </div>\n {actions}\n <Tooltip.Provider>\n {showExpandToggle ? (\n <HeaderToggle\n label={expandLabel}\n pressed={expanded}\n onPressedChange={setExpanded}\n >\n {expanded ? (\n <IconArrowsMinimize aria-hidden />\n ) : (\n <IconArrowsMaximize aria-hidden />\n )}\n </HeaderToggle>\n ) : null}\n {showWrapToggle ? (\n <HeaderToggle\n label=\"Wrap long lines\"\n pressed={wrap}\n onPressedChange={setWrap}\n >\n <IconTextWrap aria-hidden />\n </HeaderToggle>\n ) : null}\n </Tooltip.Provider>\n {showCopy ? (\n <CopyButton value={text} label={copyLabel} size=\"md\" />\n ) : null}\n </div>\n ) : null}\n {isEmpty ? (\n <p className=\"text-pho-description m-0 px-3 py-3 text-base\">{empty}</p>\n ) : scrolling ? (\n <section className=\"min-w-0\">\n <ScrollArea.Root\n fade={false}\n data-code-scroll=\"\"\n className=\"min-w-0 rounded-b-[inherit]\"\n style={{ height: `calc(${maxLines} * ${LINE_H} + ${PAD_Y} * 2)` }}\n >\n <ScrollArea.Viewport tabIndex={0} aria-label={scrollLabel}>\n <ScrollArea.Content>{body}</ScrollArea.Content>\n </ScrollArea.Viewport>\n <ScrollArea.Scrollbar>\n <ScrollArea.Thumb />\n </ScrollArea.Scrollbar>\n {wrap ? null : (\n <ScrollArea.Scrollbar orientation=\"horizontal\">\n <ScrollArea.Thumb />\n </ScrollArea.Scrollbar>\n )}\n </ScrollArea.Root>\n </section>\n ) : (\n body\n )}\n {overflow === \"expand\" && folds ? (\n <div className=\"border-pho-secondary flex items-center border-t px-1.5 py-1\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-expanded={expanded}\n prefix={expanded ? IconChevronUp : IconChevronDown}\n onClick={() => setExpanded((prev) => !prev)}\n >\n {expanded ? \"Show less\" : `Show all ${lines.length} lines`}\n </Button>\n </div>\n ) : null}\n </div>\n );\n}\n\nCodeBlock.displayName = \"CodeBlock\";\n"],"x_google_ignoreList":[0],"mappings":"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"}
@@ -1,60 +0,0 @@
1
- "use client";
2
- import { t as c } from "./cn-ChIgwEl3.js";
3
- import "react";
4
- import { jsx as n, jsxs as h } from "react/jsx-runtime";
5
- var s = [
6
- "chart-1",
7
- "chart-2",
8
- "chart-3",
9
- "chart-4",
10
- "chart-5",
11
- "chart-6"
12
- ];
13
- function p(a, e) {
14
- const r = a ?? s[e % s.length];
15
- return `var(--color-pho-${r.startsWith("chart-") ? r : `chart-${r}`})`;
16
- }
17
- function i({ color: a, kind: e = "rect", dashed: r }) {
18
- return e === "line" ? /* @__PURE__ */ n("svg", {
19
- "aria-hidden": !0,
20
- width: "14",
21
- height: "6",
22
- className: "shrink-0",
23
- children: /* @__PURE__ */ n("line", {
24
- x1: "1",
25
- x2: "13",
26
- y1: "3",
27
- y2: "3",
28
- stroke: a,
29
- strokeWidth: "2",
30
- strokeLinecap: "round",
31
- strokeDasharray: r ? "3 3" : void 0
32
- })
33
- }) : /* @__PURE__ */ n("span", {
34
- "aria-hidden": !0,
35
- className: "inline-block size-2 shrink-0 rounded-[2px]",
36
- style: { background: a }
37
- });
38
- }
39
- function u({ items: a, className: e, ...r }) {
40
- return /* @__PURE__ */ n("ul", {
41
- className: c("text-pho-secondary flex flex-wrap gap-x-4 gap-y-1 text-xs", e),
42
- ...r,
43
- children: a.map((t) => /* @__PURE__ */ h("li", {
44
- className: "flex items-center gap-1.5",
45
- children: [/* @__PURE__ */ n(i, {
46
- color: t.color,
47
- kind: t.kind,
48
- dashed: t.dashed
49
- }), t.label]
50
- }, t.label))
51
- });
52
- }
53
- export {
54
- p as i,
55
- i as n,
56
- s as r,
57
- u as t
58
- };
59
-
60
- //# sourceMappingURL=legend-C0mU7dqd.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"legend-C0mU7dqd.js","names":[],"sources":["../../src/components/chart/color.ts","../../src/components/chart/legend.tsx"],"sourcesContent":["import type { ChartColor } from \"./types\";\n\n/** The categorical slots, in the order series take them. */\nexport const CHART_SLOTS = [\n \"chart-1\",\n \"chart-2\",\n \"chart-3\",\n \"chart-4\",\n \"chart-5\",\n \"chart-6\",\n] as const satisfies ReadonlyArray<ChartColor>;\n\n/**\n * The CSS value for a series colour: the named colour, or the categorical\n * slot at `index` when the series names none. Slots are an ordered,\n * validated set — a seventh series wraps, so fold a long tail into\n * \"Other\" before it gets there.\n */\nexport function chartColor(\n color: ChartColor | undefined,\n index: number,\n): string {\n const name = color ?? CHART_SLOTS[index % CHART_SLOTS.length]!;\n const token = name.startsWith(\"chart-\") ? name : `chart-${name}`;\n return `var(--color-pho-${token})`;\n}\n","import { type ComponentProps } from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/** A legend or tooltip key mirrors its mark: a square for a bar, a stroke for a line. */\nexport type ChartSwatchKind = \"rect\" | \"line\";\n\nexport interface ChartSwatchProps {\n /** A CSS colour value — what `chartColor` returns. */\n color: string;\n kind?: ChartSwatchKind;\n dashed?: boolean;\n}\n\nexport function ChartSwatch({\n color,\n kind = \"rect\",\n dashed,\n}: ChartSwatchProps) {\n if (kind === \"line\") {\n return (\n <svg aria-hidden width=\"14\" height=\"6\" className=\"shrink-0\">\n <line\n x1=\"1\"\n x2=\"13\"\n y1=\"3\"\n y2=\"3\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeDasharray={dashed ? \"3 3\" : undefined}\n />\n </svg>\n );\n }\n return (\n <span\n aria-hidden\n className=\"inline-block size-2 shrink-0 rounded-[2px]\"\n style={{ background: color }}\n />\n );\n}\n\nexport interface ChartLegendItem {\n label: string;\n /** A CSS colour value — what `chartColor` returns. */\n color: string;\n kind?: ChartSwatchKind;\n dashed?: boolean;\n}\n\nexport interface ChartLegendProps extends Omit<\n ComponentProps<\"ul\">,\n \"children\"\n> {\n items: ReadonlyArray<ChartLegendItem>;\n}\n\n/**\n * The legend a chart of two or more series carries below the plot: a key\n * per series, in series order, wrapping when the row runs out. Text stays\n * in the UI ink; the swatch alone carries the colour.\n */\nexport function ChartLegend({ items, className, ...props }: ChartLegendProps) {\n return (\n <ul\n className={cn(\n \"text-pho-secondary flex flex-wrap gap-x-4 gap-y-1 text-xs\",\n className,\n )}\n {...props}\n >\n {items.map((item) => (\n <li key={item.label} className=\"flex items-center gap-1.5\">\n <ChartSwatch\n color={item.color}\n kind={item.kind}\n dashed={item.dashed}\n />\n {item.label}\n </li>\n ))}\n </ul>\n );\n}\n"],"mappings":";;;;AAGA,IAAa,IAAc;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAQA,SAAgB,EACd,GACA,GACQ;AACR,QAAM,IAAO,KAAS,EAAY,IAAQ,EAAY,MAAA;AAEtD,SAAO,mBADO,EAAK,WAAW,QAAQ,IAAI,IAAO,SAAS,CAAA,EAAA;AAE5D;ACZA,SAAgB,EAAY,EAC1B,OAAA,GACA,MAAA,IAAO,QACP,QAAA,EAAA,GACmB;AACnB,SAAI,MAAS,SAET,gBAAA,EAAC,OAAD;AAAA,IAAK,eAAA;AAAA,IAAY,OAAM;AAAA,IAAK,QAAO;AAAA,IAAI,WAAU;AAAA,IAC/C,UAAA,gBAAA,EAAC,QAAD;AAAA,MACE,IAAG;AAAA,MACH,IAAG;AAAA,MACH,IAAG;AAAA,MACH,IAAG;AAAA,MACH,QAAQ;AAAA,MACR,aAAY;AAAA,MACZ,eAAc;AAAA,MACd,iBAAiB,IAAS,QAAQ;AAAA,IACnC,CAAA;AAAA,EACE,CAAA,IAIP,gBAAA,EAAC,QAAD;AAAA,IACE,eAAA;AAAA,IACA,WAAU;AAAA,IACV,OAAO,EAAE,YAAY,EAAM;AAAA,EAC5B,CAAA;AAEL;AAsBA,SAAgB,EAAY,EAAE,OAAA,GAAO,WAAA,GAAW,GAAG,EAAA,GAA2B;AAC5E,SACE,gBAAA,EAAC,MAAD;AAAA,IACE,WAAW,EACT,6DACA,CACF;AAAA,IACA,GAAI;AAAA,IAEH,UAAA,EAAM,IAAA,CAAK,MACV,gBAAA,EAAC,MAAD;AAAA,MAAqB,WAAU;AAAA,MAA/B,UAAA,CACE,gBAAA,EAAC,GAAD;AAAA,QACE,OAAO,EAAK;AAAA,QACZ,MAAM,EAAK;AAAA,QACX,QAAQ,EAAK;AAAA,MACd,CAAA,GACA,EAAK,KACJ;AAAA,IAPK,GAAA,EAAK,KAOV,CACL;AAAA,EACC,CAAA;AAER"}