@bwlng/blocks 0.1.0-fork.2e294b1
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/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +971 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +3 -0
- package/dist/validation-BG2u9jAE.d.ts +450 -0
- package/dist/validation-BG2u9jAE.d.ts.map +1 -0
- package/dist/validation-DAttVLF0.js +1051 -0
- package/dist/validation-DAttVLF0.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["KumoCodeBlock"],"sources":["../src/elements/button.tsx","../src/elements/checkbox.tsx","../src/elements/combobox.tsx","../src/elements/date-input.tsx","../src/elements/number-input.tsx","../src/elements/radio.tsx","../src/elements/secret-input.tsx","../src/elements/select.tsx","../src/elements/text-input.tsx","../src/elements/toggle.tsx","../src/render-element.tsx","../src/blocks/actions.tsx","../src/blocks/banner.tsx","../src/utils.ts","../src/blocks/chart.tsx","../src/blocks/code.tsx","../src/blocks/columns.tsx","../src/blocks/context.tsx","../src/blocks/divider.tsx","../src/blocks/fields.tsx","../src/blocks/form.tsx","../src/blocks/header.tsx","../src/blocks/image.tsx","../src/blocks/meter.tsx","../src/blocks/section.tsx","../src/blocks/stats.tsx","../src/blocks/table.tsx","../src/renderer.tsx"],"sourcesContent":["import { Button, Dialog, DialogRoot } from \"@cloudflare/kumo\";\nimport { useCallback, useState } from \"react\";\n\nimport type { BlockInteraction, ButtonElement } from \"../types.js\";\n\nexport function ButtonElementComponent({\n\telement,\n\tonAction,\n}: {\n\telement: ButtonElement;\n\tonAction: (interaction: BlockInteraction) => void;\n}) {\n\tconst [confirmOpen, setConfirmOpen] = useState(false);\n\n\tconst fireAction = useCallback(() => {\n\t\tonAction({\n\t\t\ttype: \"block_action\",\n\t\t\taction_id: element.action_id,\n\t\t\tvalue: element.value,\n\t\t});\n\t}, [onAction, element.action_id, element.value]);\n\n\tconst handleClick = useCallback(() => {\n\t\tif (element.confirm) {\n\t\t\tsetConfirmOpen(true);\n\t\t} else {\n\t\t\tfireAction();\n\t\t}\n\t}, [element.confirm, fireAction]);\n\n\tconst handleConfirm = useCallback(() => {\n\t\tsetConfirmOpen(false);\n\t\tfireAction();\n\t}, [fireAction]);\n\n\tconst variant =\n\t\telement.style === \"primary\"\n\t\t\t? (\"primary\" as const)\n\t\t\t: element.style === \"danger\"\n\t\t\t\t? (\"destructive\" as const)\n\t\t\t\t: (\"secondary\" as const);\n\n\treturn (\n\t\t<>\n\t\t\t<Button variant={variant} onClick={handleClick}>\n\t\t\t\t{element.label}\n\t\t\t</Button>\n\t\t\t{element.confirm && (\n\t\t\t\t<DialogRoot open={confirmOpen} onOpenChange={setConfirmOpen}>\n\t\t\t\t\t<Dialog>\n\t\t\t\t\t\t<h3 className=\"text-lg font-semibold text-kumo-default\">{element.confirm.title}</h3>\n\t\t\t\t\t\t<p className=\"mt-1 text-sm text-kumo-subtle\">{element.confirm.text}</p>\n\t\t\t\t\t\t<div className=\"flex justify-end gap-2 pt-4\">\n\t\t\t\t\t\t\t<Button variant=\"secondary\" onClick={() => setConfirmOpen(false)}>\n\t\t\t\t\t\t\t\t{element.confirm.deny}\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\tvariant={element.confirm.style === \"danger\" ? \"destructive\" : \"primary\"}\n\t\t\t\t\t\t\t\tonClick={handleConfirm}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{element.confirm.confirm}\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</Dialog>\n\t\t\t\t</DialogRoot>\n\t\t\t)}\n\t\t</>\n\t);\n}\n","import { Checkbox } from \"@cloudflare/kumo\";\nimport { useCallback, useEffect, useState } from \"react\";\n\nimport type { BlockInteraction, CheckboxElement } from \"../types.js\";\n\nexport function CheckboxElementComponent({\n\telement,\n\tonAction,\n\tonChange,\n}: {\n\telement: CheckboxElement;\n\tonAction: (interaction: BlockInteraction) => void;\n\tonChange?: (actionId: string, value: unknown) => void;\n}) {\n\tconst [values, setValues] = useState<string[]>(element.initial_value ?? []);\n\n\tuseEffect(() => {\n\t\tsetValues(element.initial_value ?? []);\n\t}, [element.initial_value]);\n\n\tconst handleChange = useCallback(\n\t\t(newValues: string[]) => {\n\t\t\tsetValues(newValues);\n\t\t\tif (onChange) {\n\t\t\t\tonChange(element.action_id, newValues);\n\t\t\t} else {\n\t\t\t\tonAction({\n\t\t\t\t\ttype: \"block_action\",\n\t\t\t\t\taction_id: element.action_id,\n\t\t\t\t\tvalue: newValues,\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\t[onChange, onAction, element.action_id],\n\t);\n\n\treturn (\n\t\t<Checkbox.Group legend={element.label} value={values} onValueChange={handleChange}>\n\t\t\t{element.options.map((opt) => (\n\t\t\t\t<Checkbox.Item key={opt.value} value={opt.value} label={opt.label} />\n\t\t\t))}\n\t\t</Checkbox.Group>\n\t);\n}\n","import { Combobox } from \"@cloudflare/kumo\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\n\nimport type { BlockInteraction, ComboboxElement } from \"../types.js\";\n\nexport function ComboboxElementComponent({\n\telement,\n\tonAction,\n\tonChange,\n}: {\n\telement: ComboboxElement;\n\tonAction: (interaction: BlockInteraction) => void;\n\tonChange?: (actionId: string, value: unknown) => void;\n}) {\n\tconst initialOption = useMemo(\n\t\t() => element.options.find((o) => o.value === element.initial_value) ?? null,\n\t\t[element.options, element.initial_value],\n\t);\n\n\tconst [selected, setSelected] = useState<{ label: string; value: string } | null>(initialOption);\n\n\tuseEffect(() => {\n\t\tsetSelected(initialOption);\n\t}, [initialOption]);\n\n\tconst handleChange = useCallback(\n\t\t(newValue: unknown) => {\n\t\t\tconst opt = newValue as { label: string; value: string } | null;\n\t\t\tsetSelected(opt);\n\t\t\tconst val = opt?.value ?? null;\n\t\t\tif (onChange) {\n\t\t\t\tonChange(element.action_id, val);\n\t\t\t} else {\n\t\t\t\tonAction({\n\t\t\t\t\ttype: \"block_action\",\n\t\t\t\t\taction_id: element.action_id,\n\t\t\t\t\tvalue: val,\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\t[onChange, onAction, element.action_id],\n\t);\n\n\treturn (\n\t\t<Combobox\n\t\t\tlabel={element.label}\n\t\t\titems={element.options}\n\t\t\tvalue={selected}\n\t\t\tonValueChange={handleChange}\n\t\t>\n\t\t\t<Combobox.TriggerInput placeholder={element.placeholder ?? \"Search...\"} />\n\t\t\t<Combobox.Content>\n\t\t\t\t<Combobox.List>\n\t\t\t\t\t{(item: { label: string; value: string }) => (\n\t\t\t\t\t\t<Combobox.Item value={item}>{item.label}</Combobox.Item>\n\t\t\t\t\t)}\n\t\t\t\t</Combobox.List>\n\t\t\t\t<Combobox.Empty>No results</Combobox.Empty>\n\t\t\t</Combobox.Content>\n\t\t</Combobox>\n\t);\n}\n","import { useCallback, useEffect, useState } from \"react\";\n\nimport type { BlockInteraction, DateInputElement } from \"../types.js\";\n\nexport function DateInputElementComponent({\n\telement,\n\tonAction,\n\tonChange,\n}: {\n\telement: DateInputElement;\n\tonAction: (interaction: BlockInteraction) => void;\n\tonChange?: (actionId: string, value: unknown) => void;\n}) {\n\tconst [value, setValue] = useState(element.initial_value ?? \"\");\n\n\tuseEffect(() => {\n\t\tsetValue(element.initial_value ?? \"\");\n\t}, [element.initial_value]);\n\n\tconst handleChange = useCallback(\n\t\t(e: React.ChangeEvent<HTMLInputElement>) => {\n\t\t\tconst newValue = e.target.value;\n\t\t\tsetValue(newValue);\n\t\t\tif (onChange) {\n\t\t\t\tonChange(element.action_id, newValue);\n\t\t\t}\n\t\t},\n\t\t[onChange, element.action_id],\n\t);\n\n\tconst handleBlur = useCallback(\n\t\t(e: React.FocusEvent<HTMLInputElement>) => {\n\t\t\tif (!onChange) {\n\t\t\t\tonAction({\n\t\t\t\t\ttype: \"block_action\",\n\t\t\t\t\taction_id: element.action_id,\n\t\t\t\t\tvalue: e.target.value,\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\t[onChange, onAction, element.action_id],\n\t);\n\n\treturn (\n\t\t<div className=\"flex flex-col gap-1\">\n\t\t\t<label className=\"text-sm font-medium text-kumo-text\">{element.label}</label>\n\t\t\t<input\n\t\t\t\ttype=\"date\"\n\t\t\t\tvalue={value}\n\t\t\t\tonChange={handleChange}\n\t\t\t\tonBlur={handleBlur}\n\t\t\t\tplaceholder={element.placeholder}\n\t\t\t\tclassName=\"h-9 rounded-lg border border-kumo-line bg-kumo-bg px-3 text-sm text-kumo-text outline-none focus:ring-2 focus:ring-kumo-ring\"\n\t\t\t/>\n\t\t</div>\n\t);\n}\n","import { Input } from \"@cloudflare/kumo\";\nimport { useCallback } from \"react\";\n\nimport type { BlockInteraction, NumberInputElement } from \"../types.js\";\n\nexport function NumberInputElementComponent({\n\telement,\n\tonAction,\n\tonChange,\n}: {\n\telement: NumberInputElement;\n\tonAction: (interaction: BlockInteraction) => void;\n\tonChange?: (actionId: string, value: unknown) => void;\n}) {\n\tconst handleChange = useCallback(\n\t\t(e: React.ChangeEvent<HTMLInputElement>) => {\n\t\t\tconst val = e.target.value === \"\" ? undefined : Number(e.target.value);\n\t\t\tif (onChange) {\n\t\t\t\tonChange(element.action_id, val);\n\t\t\t}\n\t\t},\n\t\t[onChange, element.action_id],\n\t);\n\n\tconst handleBlur = useCallback(\n\t\t(e: React.FocusEvent<HTMLInputElement>) => {\n\t\t\tif (!onChange) {\n\t\t\t\tconst val = e.target.value === \"\" ? undefined : Number(e.target.value);\n\t\t\t\tonAction({\n\t\t\t\t\ttype: \"block_action\",\n\t\t\t\t\taction_id: element.action_id,\n\t\t\t\t\tvalue: val,\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\t[onChange, onAction, element.action_id],\n\t);\n\n\treturn (\n\t\t<Input\n\t\t\tlabel={element.label}\n\t\t\ttype=\"number\"\n\t\t\tmin={element.min}\n\t\t\tmax={element.max}\n\t\t\tdefaultValue={element.initial_value}\n\t\t\tonChange={handleChange}\n\t\t\tonBlur={handleBlur}\n\t\t/>\n\t);\n}\n","import { Radio } from \"@cloudflare/kumo\";\nimport { useCallback, useEffect, useState } from \"react\";\n\nimport type { BlockInteraction, RadioElement } from \"../types.js\";\n\nexport function RadioElementComponent({\n\telement,\n\tonAction,\n\tonChange,\n}: {\n\telement: RadioElement;\n\tonAction: (interaction: BlockInteraction) => void;\n\tonChange?: (actionId: string, value: unknown) => void;\n}) {\n\tconst [value, setValue] = useState(element.initial_value ?? \"\");\n\n\tuseEffect(() => {\n\t\tsetValue(element.initial_value ?? \"\");\n\t}, [element.initial_value]);\n\n\tconst handleChange = useCallback(\n\t\t(newValue: string) => {\n\t\t\tsetValue(newValue);\n\t\t\tif (onChange) {\n\t\t\t\tonChange(element.action_id, newValue);\n\t\t\t} else {\n\t\t\t\tonAction({\n\t\t\t\t\ttype: \"block_action\",\n\t\t\t\t\taction_id: element.action_id,\n\t\t\t\t\tvalue: newValue,\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\t[onChange, onAction, element.action_id],\n\t);\n\n\treturn (\n\t\t<Radio.Group legend={element.label} value={value} onValueChange={handleChange}>\n\t\t\t{element.options.map((opt) => (\n\t\t\t\t<Radio.Item key={opt.value} value={opt.value} label={opt.label} />\n\t\t\t))}\n\t\t</Radio.Group>\n\t);\n}\n","import { SensitiveInput } from \"@cloudflare/kumo\";\nimport { useCallback, useState } from \"react\";\n\nimport type { BlockInteraction, SecretInputElement } from \"../types.js\";\n\nexport function SecretInputElementComponent({\n\telement,\n\tonAction,\n\tonChange,\n}: {\n\telement: SecretInputElement;\n\tonAction: (interaction: BlockInteraction) => void;\n\tonChange?: (actionId: string, value: unknown) => void;\n}) {\n\tconst [value, setValue] = useState(\"\");\n\tconst [editing, setEditing] = useState(!element.has_value);\n\n\tconst handleValueChange = useCallback(\n\t\t(v: string) => {\n\t\t\tsetValue(v);\n\t\t\tif (onChange) {\n\t\t\t\tonChange(element.action_id, v);\n\t\t\t}\n\t\t},\n\t\t[onChange, element.action_id],\n\t);\n\n\tconst handleFocus = useCallback(() => {\n\t\tif (!editing) {\n\t\t\tsetEditing(true);\n\t\t\tsetValue(\"\");\n\t\t}\n\t}, [editing]);\n\n\tconst handleBlur = useCallback(() => {\n\t\tif (!onChange && value) {\n\t\t\tonAction({\n\t\t\t\ttype: \"block_action\",\n\t\t\t\taction_id: element.action_id,\n\t\t\t\tvalue,\n\t\t\t});\n\t\t}\n\t\tif (!value && element.has_value) {\n\t\t\tsetEditing(false);\n\t\t}\n\t}, [onChange, onAction, element.action_id, value, element.has_value]);\n\n\tif (!editing) {\n\t\treturn (\n\t\t\t<SensitiveInput\n\t\t\t\tlabel={element.label}\n\t\t\t\tvalue={\"••••••••\"}\n\t\t\t\treadOnly\n\t\t\t\tonFocus={handleFocus}\n\t\t\t\tplaceholder={element.placeholder}\n\t\t\t/>\n\t\t);\n\t}\n\n\treturn (\n\t\t<SensitiveInput\n\t\t\tlabel={element.label}\n\t\t\tvalue={value}\n\t\t\tonValueChange={handleValueChange}\n\t\t\tonFocus={handleFocus}\n\t\t\tonBlur={handleBlur}\n\t\t\tplaceholder={element.placeholder}\n\t\t/>\n\t);\n}\n","import { Select } from \"@cloudflare/kumo\";\nimport { useCallback } from \"react\";\n\nimport type { BlockInteraction, SelectElement } from \"../types.js\";\n\nexport function SelectElementComponent({\n\telement,\n\tonAction,\n\tonChange,\n}: {\n\telement: SelectElement;\n\tonAction: (interaction: BlockInteraction) => void;\n\tonChange?: (actionId: string, value: unknown) => void;\n}) {\n\tconst handleValueChange = useCallback(\n\t\t(value: unknown) => {\n\t\t\tif (onChange) {\n\t\t\t\tonChange(element.action_id, value);\n\t\t\t} else {\n\t\t\t\tonAction({\n\t\t\t\t\ttype: \"block_action\",\n\t\t\t\t\taction_id: element.action_id,\n\t\t\t\t\tvalue,\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\t[onChange, onAction, element.action_id],\n\t);\n\n\treturn (\n\t\t<Select\n\t\t\tlabel={element.label}\n\t\t\tdefaultValue={element.initial_value}\n\t\t\tonValueChange={handleValueChange}\n\t\t>\n\t\t\t{element.options.map((opt) => (\n\t\t\t\t<Select.Option key={opt.value} value={opt.value}>\n\t\t\t\t\t{opt.label}\n\t\t\t\t</Select.Option>\n\t\t\t))}\n\t\t</Select>\n\t);\n}\n","import { Input, InputArea } from \"@cloudflare/kumo\";\nimport { useCallback } from \"react\";\n\nimport type { BlockInteraction, TextInputElement } from \"../types.js\";\n\nexport function TextInputElementComponent({\n\telement,\n\tonAction,\n\tonChange,\n}: {\n\telement: TextInputElement;\n\tonAction: (interaction: BlockInteraction) => void;\n\tonChange?: (actionId: string, value: unknown) => void;\n}) {\n\tconst handleChange = useCallback(\n\t\t(e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n\t\t\tif (onChange) {\n\t\t\t\tonChange(element.action_id, e.target.value);\n\t\t\t}\n\t\t},\n\t\t[onChange, element.action_id],\n\t);\n\n\tconst handleBlur = useCallback(\n\t\t(e: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n\t\t\tif (!onChange) {\n\t\t\t\tonAction({\n\t\t\t\t\ttype: \"block_action\",\n\t\t\t\t\taction_id: element.action_id,\n\t\t\t\t\tvalue: e.target.value,\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\t[onChange, onAction, element.action_id],\n\t);\n\n\tif (element.multiline) {\n\t\treturn (\n\t\t\t<InputArea\n\t\t\t\tlabel={element.label}\n\t\t\t\tplaceholder={element.placeholder}\n\t\t\t\tdefaultValue={element.initial_value}\n\t\t\t\tonChange={handleChange}\n\t\t\t\tonBlur={handleBlur}\n\t\t\t/>\n\t\t);\n\t}\n\n\treturn (\n\t\t<Input\n\t\t\tlabel={element.label}\n\t\t\tplaceholder={element.placeholder}\n\t\t\tdefaultValue={element.initial_value}\n\t\t\tonChange={handleChange}\n\t\t\tonBlur={handleBlur}\n\t\t/>\n\t);\n}\n","import { Switch } from \"@cloudflare/kumo\";\nimport { useCallback, useState } from \"react\";\n\nimport type { BlockInteraction, ToggleElement } from \"../types.js\";\n\nexport function ToggleElementComponent({\n\telement,\n\tonAction,\n\tonChange,\n}: {\n\telement: ToggleElement;\n\tonAction: (interaction: BlockInteraction) => void;\n\tonChange?: (actionId: string, value: unknown) => void;\n}) {\n\tconst [checked, setChecked] = useState(element.initial_value ?? false);\n\n\tconst handleChange = useCallback(\n\t\t(value: boolean) => {\n\t\t\tsetChecked(value);\n\t\t\tif (onChange) {\n\t\t\t\tonChange(element.action_id, value);\n\t\t\t} else {\n\t\t\t\tonAction({\n\t\t\t\t\ttype: \"block_action\",\n\t\t\t\t\taction_id: element.action_id,\n\t\t\t\t\tvalue,\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\t[onChange, onAction, element.action_id],\n\t);\n\n\treturn <Switch label={element.label} checked={checked} onCheckedChange={handleChange} />;\n}\n","import { ButtonElementComponent } from \"./elements/button.js\";\nimport { CheckboxElementComponent } from \"./elements/checkbox.js\";\nimport { ComboboxElementComponent } from \"./elements/combobox.js\";\nimport { DateInputElementComponent } from \"./elements/date-input.js\";\nimport { NumberInputElementComponent } from \"./elements/number-input.js\";\nimport { RadioElementComponent } from \"./elements/radio.js\";\nimport { SecretInputElementComponent } from \"./elements/secret-input.js\";\nimport { SelectElementComponent } from \"./elements/select.js\";\nimport { TextInputElementComponent } from \"./elements/text-input.js\";\nimport { ToggleElementComponent } from \"./elements/toggle.js\";\nimport type { BlockInteraction, Element } from \"./types.js\";\n\nexport function renderElement(\n\telement: Element,\n\tonAction: (interaction: BlockInteraction) => void,\n\tonChange?: (actionId: string, value: unknown) => void,\n): React.ReactNode {\n\tswitch (element.type) {\n\t\tcase \"button\":\n\t\t\treturn <ButtonElementComponent element={element} onAction={onAction} />;\n\t\tcase \"text_input\":\n\t\t\treturn (\n\t\t\t\t<TextInputElementComponent element={element} onAction={onAction} onChange={onChange} />\n\t\t\t);\n\t\tcase \"number_input\":\n\t\t\treturn (\n\t\t\t\t<NumberInputElementComponent element={element} onAction={onAction} onChange={onChange} />\n\t\t\t);\n\t\tcase \"select\":\n\t\t\treturn <SelectElementComponent element={element} onAction={onAction} onChange={onChange} />;\n\t\tcase \"toggle\":\n\t\t\treturn <ToggleElementComponent element={element} onAction={onAction} onChange={onChange} />;\n\t\tcase \"secret_input\":\n\t\t\treturn (\n\t\t\t\t<SecretInputElementComponent element={element} onAction={onAction} onChange={onChange} />\n\t\t\t);\n\t\tcase \"checkbox\":\n\t\t\treturn <CheckboxElementComponent element={element} onAction={onAction} onChange={onChange} />;\n\t\tcase \"radio\":\n\t\t\treturn <RadioElementComponent element={element} onAction={onAction} onChange={onChange} />;\n\t\tcase \"date_input\":\n\t\t\treturn (\n\t\t\t\t<DateInputElementComponent element={element} onAction={onAction} onChange={onChange} />\n\t\t\t);\n\t\tcase \"combobox\":\n\t\t\treturn <ComboboxElementComponent element={element} onAction={onAction} onChange={onChange} />;\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = element;\n\t\t\treturn null;\n\t\t}\n\t}\n}\n","import { renderElement } from \"../render-element.js\";\nimport type { ActionsBlock, BlockInteraction } from \"../types.js\";\n\nexport function ActionsBlockComponent({\n\tblock,\n\tonAction,\n}: {\n\tblock: ActionsBlock;\n\tonAction: (interaction: BlockInteraction) => void;\n}) {\n\treturn (\n\t\t<div className=\"flex flex-wrap gap-2\">\n\t\t\t{block.elements.map((el, i) => (\n\t\t\t\t<div key={el.action_id ?? i}>{renderElement(el, onAction)}</div>\n\t\t\t))}\n\t\t</div>\n\t);\n}\n","import { Banner } from \"@cloudflare/kumo\";\nimport { Info, Warning, WarningCircle } from \"@phosphor-icons/react\";\nimport { useMemo } from \"react\";\n\nimport type { BannerBlock } from \"../types.js\";\n\nfunction useVariantIcon(variant: \"default\" | \"alert\" | \"error\") {\n\treturn useMemo(() => {\n\t\tswitch (variant) {\n\t\t\tcase \"alert\":\n\t\t\t\treturn <Warning weight=\"fill\" size={20} />;\n\t\t\tcase \"error\":\n\t\t\t\treturn <WarningCircle weight=\"fill\" size={20} />;\n\t\t\tdefault:\n\t\t\t\treturn <Info weight=\"fill\" size={20} />;\n\t\t}\n\t}, [variant]);\n}\n\nexport function BannerBlockComponent({ block }: { block: BannerBlock }) {\n\tconst variant = block.variant ?? \"default\";\n\tconst icon = useVariantIcon(variant);\n\treturn (\n\t\t<Banner variant={variant} icon={icon} title={block.title} description={block.description} />\n\t);\n}\n","import { clsx } from \"clsx\";\nimport { useEffect, useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: Parameters<typeof clsx>) {\n\treturn twMerge(clsx(inputs));\n}\n\n/**\n * Detects dark mode from `<html data-theme=\"dark\">` or the system\n * `prefers-color-scheme` media query and stays in sync reactively.\n */\nexport function useIsDarkMode(): boolean {\n\tconst [dark, setDark] = useState(() => {\n\t\tif (typeof document === \"undefined\") return false;\n\t\tconst attr = document.documentElement.getAttribute(\"data-theme\");\n\t\tif (attr === \"dark\") return true;\n\t\tif (attr === \"light\") return false;\n\t\treturn window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n\t});\n\n\tuseEffect(() => {\n\t\t// Watch for data-theme attribute changes on <html>\n\t\tconst observer = new MutationObserver(() => {\n\t\t\tconst attr = document.documentElement.getAttribute(\"data-theme\");\n\t\t\tif (attr === \"dark\") return setDark(true);\n\t\t\tif (attr === \"light\") return setDark(false);\n\t\t\tsetDark(window.matchMedia(\"(prefers-color-scheme: dark)\").matches);\n\t\t});\n\t\tobserver.observe(document.documentElement, {\n\t\t\tattributes: true,\n\t\t\tattributeFilter: [\"data-theme\"],\n\t\t});\n\n\t\t// Also watch the system media query\n\t\tconst mq = window.matchMedia(\"(prefers-color-scheme: dark)\");\n\t\tconst handler = (e: MediaQueryListEvent) => {\n\t\t\tif (!document.documentElement.hasAttribute(\"data-theme\")) {\n\t\t\t\tsetDark(e.matches);\n\t\t\t}\n\t\t};\n\t\tmq.addEventListener(\"change\", handler);\n\n\t\treturn () => {\n\t\t\tobserver.disconnect();\n\t\t\tmq.removeEventListener(\"change\", handler);\n\t\t};\n\t}, []);\n\n\treturn dark;\n}\n\nconst MINUTE = 60;\nconst HOUR = 60 * MINUTE;\nconst DAY = 24 * HOUR;\nconst WEEK = 7 * DAY;\nconst MONTH = 30 * DAY;\nconst YEAR = 365 * DAY;\n\nexport function formatRelativeTime(iso: string): string {\n\tconst date = new Date(iso);\n\tconst now = Date.now();\n\tconst diff = Math.floor((now - date.getTime()) / 1000);\n\n\tif (diff < 0) {\n\t\treturn \"just now\";\n\t}\n\tif (diff < MINUTE) {\n\t\treturn \"just now\";\n\t}\n\tif (diff < HOUR) {\n\t\tconst mins = Math.floor(diff / MINUTE);\n\t\treturn mins === 1 ? \"1 minute ago\" : `${mins} minutes ago`;\n\t}\n\tif (diff < DAY) {\n\t\tconst hours = Math.floor(diff / HOUR);\n\t\treturn hours === 1 ? \"1 hour ago\" : `${hours} hours ago`;\n\t}\n\tif (diff < WEEK) {\n\t\tconst days = Math.floor(diff / DAY);\n\t\treturn days === 1 ? \"1 day ago\" : `${days} days ago`;\n\t}\n\tif (diff < MONTH) {\n\t\tconst weeks = Math.floor(diff / WEEK);\n\t\treturn weeks === 1 ? \"1 week ago\" : `${weeks} weeks ago`;\n\t}\n\tif (diff < YEAR) {\n\t\tconst months = Math.floor(diff / MONTH);\n\t\treturn months === 1 ? \"1 month ago\" : `${months} months ago`;\n\t}\n\tconst years = Math.floor(diff / YEAR);\n\treturn years === 1 ? \"1 year ago\" : `${years} years ago`;\n}\n","import { Chart, ChartPalette, TimeseriesChart } from \"@cloudflare/kumo/components/chart\";\nimport type { EChartsOption } from \"echarts\";\nimport { BarChart, LineChart, PieChart } from \"echarts/charts\";\nimport {\n\tAriaComponent,\n\tAxisPointerComponent,\n\tGridComponent,\n\tTooltipComponent,\n} from \"echarts/components\";\nimport * as echarts from \"echarts/core\";\nimport { CanvasRenderer } from \"echarts/renderers\";\nimport { useMemo } from \"react\";\n\nimport type { ChartBlock } from \"../types.js\";\nimport { useIsDarkMode } from \"../utils.js\";\n\necharts.use([\n\tBarChart,\n\tLineChart,\n\tPieChart,\n\tAriaComponent,\n\tAxisPointerComponent,\n\tGridComponent,\n\tTooltipComponent,\n\tCanvasRenderer,\n]);\n\n// ── Security: HTML-escape untrusted strings before they reach ECharts ────────\n// ECharts tooltip renders via innerHTML. Plugin-supplied names/labels must be\n// escaped to prevent stored XSS in the admin dashboard.\n\nconst RE_AMP = /&/g;\nconst RE_LT = /</g;\nconst RE_GT = />/g;\nconst RE_QUOT = /\"/g;\nconst RE_APOS = /'/g;\n\nfunction escapeHtml(str: string): string {\n\treturn str\n\t\t.replace(RE_AMP, \"&\")\n\t\t.replace(RE_LT, \"<\")\n\t\t.replace(RE_GT, \">\")\n\t\t.replace(RE_QUOT, \""\")\n\t\t.replace(RE_APOS, \"'\");\n}\n\n// ── Security: Sanitize custom ECharts options ────────────────────────────────\n// Plugin-supplied options are passed to chart.setOption(). ECharts accepts\n// formatter strings rendered via innerHTML, tooltip HTML, and graphic elements\n// that can execute arbitrary code. We strip dangerous properties and force\n// richText tooltip mode to eliminate HTML injection vectors.\n\n/** Keys that accept HTML strings or executable content in ECharts options */\nconst DANGEROUS_KEYS = new Set([\"formatter\", \"rich\", \"graphic\", \"axisPointer\"]);\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n\treturn typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\nconst RE_HTML_TAG = /<[a-z/!]/i;\n\nfunction containsHtml(v: unknown): boolean {\n\treturn typeof v === \"string\" && RE_HTML_TAG.test(v);\n}\n\n/**\n * Deep-clone an ECharts options object, stripping properties that could\n * inject HTML or executable content. Strings containing HTML tags are\n * replaced with escaped versions.\n */\nfunction sanitizeOptions(obj: Record<string, unknown>): Record<string, unknown> {\n\tconst result: Record<string, unknown> = {};\n\tfor (const [key, value] of Object.entries(obj)) {\n\t\tif (DANGEROUS_KEYS.has(key)) continue;\n\t\tif (containsHtml(value)) {\n\t\t\tresult[key] = escapeHtml(value as string);\n\t\t} else if (Array.isArray(value)) {\n\t\t\tresult[key] = value.map((item) =>\n\t\t\t\tisRecord(item)\n\t\t\t\t\t? sanitizeOptions(item)\n\t\t\t\t\t: containsHtml(item)\n\t\t\t\t\t\t? escapeHtml(item as string)\n\t\t\t\t\t\t: item,\n\t\t\t);\n\t\t} else if (isRecord(value)) {\n\t\t\tresult[key] = sanitizeOptions(value);\n\t\t} else {\n\t\t\tresult[key] = value;\n\t\t}\n\t}\n\treturn result;\n}\n\nfunction TimeseriesChartBlock({ block, isDarkMode }: { block: ChartBlock; isDarkMode: boolean }) {\n\tconst config = block.config;\n\tif (config.chart_type !== \"timeseries\") return null;\n\n\tconst data = useMemo(\n\t\t() =>\n\t\t\tconfig.series.map((s, i) => ({\n\t\t\t\tname: escapeHtml(s.name),\n\t\t\t\tdata: s.data,\n\t\t\t\tcolor: s.color ?? ChartPalette.color(i, isDarkMode),\n\t\t\t})),\n\t\t[config.series, isDarkMode],\n\t);\n\n\treturn (\n\t\t<TimeseriesChart\n\t\t\techarts={echarts}\n\t\t\tisDarkMode={isDarkMode}\n\t\t\ttype={config.style}\n\t\t\tdata={data}\n\t\t\txAxisName={config.x_axis_name ? escapeHtml(config.x_axis_name) : undefined}\n\t\t\tyAxisName={config.y_axis_name ? escapeHtml(config.y_axis_name) : undefined}\n\t\t\theight={config.height}\n\t\t\tgradient={config.gradient}\n\t\t/>\n\t);\n}\n\nfunction CustomChartBlock({ block, isDarkMode }: { block: ChartBlock; isDarkMode: boolean }) {\n\tconst config = block.config;\n\tif (config.chart_type !== \"custom\") return null;\n\n\tconst safeOptions = useMemo(() => {\n\t\tconst sanitized = sanitizeOptions(config.options);\n\t\t// Force richText tooltip mode — renders via canvas, not innerHTML\n\t\tif (isRecord(sanitized.tooltip)) {\n\t\t\tsanitized.tooltip.renderMode = \"richText\";\n\t\t} else {\n\t\t\tsanitized.tooltip = { renderMode: \"richText\" };\n\t\t}\n\t\treturn sanitized;\n\t}, [config.options]);\n\n\treturn (\n\t\t<Chart\n\t\t\techarts={echarts}\n\t\t\tisDarkMode={isDarkMode}\n\t\t\toptions={safeOptions as EChartsOption}\n\t\t\theight={config.height}\n\t\t/>\n\t);\n}\n\nexport function ChartBlockComponent({ block }: { block: ChartBlock }) {\n\tconst isDarkMode = useIsDarkMode();\n\n\treturn (\n\t\t<div className=\"rounded-lg border border-kumo-line p-4\">\n\t\t\t{block.config.chart_type === \"timeseries\" ? (\n\t\t\t\t<TimeseriesChartBlock block={block} isDarkMode={isDarkMode} />\n\t\t\t) : (\n\t\t\t\t<CustomChartBlock block={block} isDarkMode={isDarkMode} />\n\t\t\t)}\n\t\t</div>\n\t);\n}\n","import { CodeBlock as KumoCodeBlock } from \"@cloudflare/kumo\";\n\nimport type { CodeBlock } from \"../types.js\";\n\nexport function CodeBlockComponent({ block }: { block: CodeBlock }) {\n\treturn <KumoCodeBlock code={block.code} lang={block.language} />;\n}\n","import { BlockRenderer } from \"../renderer.js\";\nimport type { BlockInteraction, ColumnsBlock } from \"../types.js\";\n\nexport function ColumnsBlockComponent({\n\tblock,\n\tonAction,\n}: {\n\tblock: ColumnsBlock;\n\tonAction: (interaction: BlockInteraction) => void;\n}) {\n\tconst colCount = Math.min(block.columns.length, 3);\n\tconst gridClass = colCount === 2 ? \"grid grid-cols-2 gap-4\" : \"grid grid-cols-3 gap-4\";\n\n\treturn (\n\t\t<div className={gridClass}>\n\t\t\t{block.columns.map((col, i) => (\n\t\t\t\t<div key={i}>\n\t\t\t\t\t<BlockRenderer blocks={col} onAction={onAction} />\n\t\t\t\t</div>\n\t\t\t))}\n\t\t</div>\n\t);\n}\n","import type { ContextBlock } from \"../types.js\";\n\nexport function ContextBlockComponent({ block }: { block: ContextBlock }) {\n\treturn <p className=\"text-sm text-kumo-subtle\">{block.text}</p>;\n}\n","export function DividerBlockComponent() {\n\treturn <hr className=\"my-4 border-kumo-line\" />;\n}\n","import type { FieldsBlock } from \"../types.js\";\n\nexport function FieldsBlockComponent({ block }: { block: FieldsBlock }) {\n\treturn (\n\t\t<div className=\"grid grid-cols-2 gap-x-6 gap-y-3\">\n\t\t\t{block.fields.map((field, i) => (\n\t\t\t\t<div key={i}>\n\t\t\t\t\t<div className=\"text-sm text-kumo-subtle\">{field.label}</div>\n\t\t\t\t\t<div className=\"text-kumo-default\">{field.value}</div>\n\t\t\t\t</div>\n\t\t\t))}\n\t\t</div>\n\t);\n}\n","import { Button } from \"@cloudflare/kumo\";\nimport { useCallback, useState } from \"react\";\n\nimport { renderElement } from \"../render-element.js\";\nimport type { BlockInteraction, FieldCondition, FormBlock, FormField } from \"../types.js\";\n\nfunction deepEqual(a: unknown, b: unknown): boolean {\n\tif (a === b) return true;\n\tif (Array.isArray(a) && Array.isArray(b)) {\n\t\tif (a.length !== b.length) return false;\n\t\treturn a.every((v, i) => deepEqual(v, b[i]));\n\t}\n\treturn false;\n}\n\nfunction evaluateCondition(condition: FieldCondition, values: Record<string, unknown>): boolean {\n\tconst fieldValue = values[condition.field];\n\tif (\"eq\" in condition && condition.eq !== undefined) {\n\t\treturn deepEqual(fieldValue, condition.eq);\n\t}\n\tif (\"neq\" in condition && condition.neq !== undefined) {\n\t\treturn !deepEqual(fieldValue, condition.neq);\n\t}\n\treturn true;\n}\n\nfunction getInitialValues(fields: FormField[]): Record<string, unknown> {\n\tconst values: Record<string, unknown> = {};\n\tfor (const field of fields) {\n\t\tif (\"initial_value\" in field && field.initial_value !== undefined) {\n\t\t\tvalues[field.action_id] = field.initial_value;\n\t\t}\n\t}\n\treturn values;\n}\n\nexport function FormBlockComponent({\n\tblock,\n\tonAction,\n}: {\n\tblock: FormBlock;\n\tonAction: (interaction: BlockInteraction) => void;\n}) {\n\tconst [values, setValues] = useState<Record<string, unknown>>(() =>\n\t\tgetInitialValues(block.fields),\n\t);\n\n\tconst handleChange = useCallback((actionId: string, value: unknown) => {\n\t\tsetValues((prev) => ({ ...prev, [actionId]: value }));\n\t}, []);\n\n\tfunction handleSubmit(e: React.FormEvent) {\n\t\te.preventDefault();\n\t\tonAction({\n\t\t\ttype: \"form_submit\",\n\t\t\taction_id: block.submit.action_id,\n\t\t\tblock_id: block.block_id,\n\t\t\tvalues,\n\t\t});\n\t}\n\n\treturn (\n\t\t<form onSubmit={handleSubmit} className=\"flex flex-col gap-4\">\n\t\t\t{block.fields.map((field) => {\n\t\t\t\tif (field.condition && !evaluateCondition(field.condition, values)) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\treturn <div key={field.action_id}>{renderElement(field, onAction, handleChange)}</div>;\n\t\t\t})}\n\t\t\t<div>\n\t\t\t\t<Button type=\"submit\">{block.submit.label}</Button>\n\t\t\t</div>\n\t\t</form>\n\t);\n}\n","import type { HeaderBlock } from \"../types.js\";\n\nexport function HeaderBlockComponent({ block }: { block: HeaderBlock }) {\n\treturn <h2 className=\"text-xl font-bold text-kumo-default\">{block.text}</h2>;\n}\n","import type { ImageBlock } from \"../types.js\";\n\nexport function ImageBlockComponent({ block }: { block: ImageBlock }) {\n\treturn (\n\t\t<figure>\n\t\t\t<img src={block.url} alt={block.alt} className=\"max-w-full rounded\" />\n\t\t\t{block.title && (\n\t\t\t\t<figcaption className=\"mt-1 text-sm text-kumo-subtle\">{block.title}</figcaption>\n\t\t\t)}\n\t\t</figure>\n\t);\n}\n","import { Meter } from \"@cloudflare/kumo\";\n\nimport type { MeterBlock } from \"../types.js\";\n\nexport function MeterBlockComponent({ block }: { block: MeterBlock }) {\n\treturn (\n\t\t<Meter\n\t\t\tlabel={block.label}\n\t\t\tvalue={block.value}\n\t\t\tmax={block.max}\n\t\t\tmin={block.min}\n\t\t\tcustomValue={block.custom_value}\n\t\t/>\n\t);\n}\n","import { renderElement } from \"../render-element.js\";\nimport type { BlockInteraction, SectionBlock } from \"../types.js\";\n\nexport function SectionBlockComponent({\n\tblock,\n\tonAction,\n}: {\n\tblock: SectionBlock;\n\tonAction: (interaction: BlockInteraction) => void;\n}) {\n\treturn (\n\t\t<div className=\"flex items-start justify-between gap-4\">\n\t\t\t<div className=\"flex-1 text-kumo-default\">{block.text}</div>\n\t\t\t{block.accessory && (\n\t\t\t\t<div className=\"flex-shrink-0\">{renderElement(block.accessory, onAction)}</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n","import { ArrowDown, ArrowUp, Minus } from \"@phosphor-icons/react\";\n\nimport type { StatItem, StatsBlock } from \"../types.js\";\nimport { cn } from \"../utils.js\";\n\nconst trendConfig = {\n\tup: { icon: ArrowUp, color: \"text-green-600\" },\n\tdown: { icon: ArrowDown, color: \"text-red-600\" },\n\tneutral: { icon: Minus, color: \"text-kumo-subtle\" },\n} as const;\n\nfunction StatCard({ item }: { item: StatItem }) {\n\tconst trend = item.trend ? trendConfig[item.trend] : null;\n\tconst TrendIcon = trend?.icon;\n\n\treturn (\n\t\t<div className=\"flex-1 rounded-lg border border-kumo-line p-4\">\n\t\t\t<div className=\"text-sm text-kumo-subtle\">{item.label}</div>\n\t\t\t<div className=\"mt-1 flex items-baseline gap-2\">\n\t\t\t\t<span className=\"text-2xl font-bold text-kumo-default\">{item.value}</span>\n\t\t\t\t{TrendIcon && (\n\t\t\t\t\t<span className={cn(\"flex items-center\", trend.color)}>\n\t\t\t\t\t\t<TrendIcon size={16} />\n\t\t\t\t\t</span>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t\t{item.description && <div className=\"mt-1 text-sm text-kumo-subtle\">{item.description}</div>}\n\t\t</div>\n\t);\n}\n\nexport function StatsBlockComponent({ block }: { block: StatsBlock }) {\n\treturn (\n\t\t<div className=\"flex gap-4\">\n\t\t\t{block.items.map((item, i) => (\n\t\t\t\t<StatCard key={i} item={item} />\n\t\t\t))}\n\t\t</div>\n\t);\n}\n","import { Badge } from \"@cloudflare/kumo\";\nimport { ArrowDown, ArrowUp } from \"@phosphor-icons/react\";\nimport { useState } from \"react\";\n\nimport type { BlockInteraction, TableBlock, TableColumn } from \"../types.js\";\nimport { cn, formatRelativeTime } from \"../utils.js\";\n\nfunction formatCell(value: unknown, format: TableColumn[\"format\"]): React.ReactNode {\n\tlet str: string;\n\tif (value == null) {\n\t\tstr = \"\";\n\t} else if (typeof value === \"string\") {\n\t\tstr = value;\n\t} else if (typeof value === \"number\" || typeof value === \"boolean\") {\n\t\tstr = String(value);\n\t} else if (typeof value === \"object\") {\n\t\tstr = JSON.stringify(value);\n\t} else {\n\t\tstr = \"\";\n\t}\n\tswitch (format) {\n\t\tcase \"badge\":\n\t\t\treturn <Badge>{str}</Badge>;\n\t\tcase \"relative_time\":\n\t\t\treturn str ? formatRelativeTime(str) : \"\";\n\t\tcase \"number\": {\n\t\t\tconst num = Number(value);\n\t\t\treturn Number.isNaN(num) ? str : num.toLocaleString();\n\t\t}\n\t\tcase \"code\":\n\t\t\treturn <code className=\"rounded bg-kumo-tint px-1.5 py-0.5 font-mono text-sm\">{str}</code>;\n\t\tdefault:\n\t\t\treturn str;\n\t}\n}\n\nexport function TableBlockComponent({\n\tblock,\n\tonAction,\n}: {\n\tblock: TableBlock;\n\tonAction: (interaction: BlockInteraction) => void;\n}) {\n\tconst [sort, setSort] = useState<{ key: string; dir: \"asc\" | \"desc\" } | null>(null);\n\n\tfunction handleSort(key: string) {\n\t\tconst next =\n\t\t\tsort?.key === key && sort.dir === \"asc\"\n\t\t\t\t? { key, dir: \"desc\" as const }\n\t\t\t\t: { key, dir: \"asc\" as const };\n\t\tsetSort(next);\n\t\tonAction({\n\t\t\ttype: \"block_action\",\n\t\t\taction_id: block.page_action_id,\n\t\t\tblock_id: block.block_id,\n\t\t\tvalue: { sort: next },\n\t\t});\n\t}\n\n\tfunction handleLoadMore() {\n\t\tonAction({\n\t\t\ttype: \"block_action\",\n\t\t\taction_id: block.page_action_id,\n\t\t\tblock_id: block.block_id,\n\t\t\tvalue: { cursor: block.next_cursor, sort },\n\t\t});\n\t}\n\n\tif (block.rows.length === 0 && block.empty_text) {\n\t\treturn <p className=\"py-4 text-center text-sm text-kumo-subtle\">{block.empty_text}</p>;\n\t}\n\n\treturn (\n\t\t<div className=\"overflow-x-auto\">\n\t\t\t<table className=\"w-full text-left text-sm\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr className=\"border-b border-kumo-line\">\n\t\t\t\t\t\t{block.columns.map((col) => (\n\t\t\t\t\t\t\t<th\n\t\t\t\t\t\t\t\tkey={col.key}\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\"px-3 py-2 text-sm font-medium text-kumo-subtle\",\n\t\t\t\t\t\t\t\t\tcol.sortable && \"cursor-pointer select-none\",\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\tonClick={col.sortable ? () => handleSort(col.key) : undefined}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span className=\"inline-flex items-center gap-1\">\n\t\t\t\t\t\t\t\t\t{col.label}\n\t\t\t\t\t\t\t\t\t{col.sortable &&\n\t\t\t\t\t\t\t\t\t\tsort?.key === col.key &&\n\t\t\t\t\t\t\t\t\t\t(sort.dir === \"asc\" ? <ArrowUp size={14} /> : <ArrowDown size={14} />)}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\t\t\t\t<tbody>\n\t\t\t\t\t{block.rows.map((row, i) => (\n\t\t\t\t\t\t<tr key={i} className=\"border-b border-kumo-line last:border-0\">\n\t\t\t\t\t\t\t{block.columns.map((col) => (\n\t\t\t\t\t\t\t\t<td key={col.key} className=\"px-3 py-2 text-kumo-default\">\n\t\t\t\t\t\t\t\t\t{formatCell(row[col.key], col.format)}\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t))}\n\t\t\t\t</tbody>\n\t\t\t</table>\n\t\t\t{block.next_cursor && (\n\t\t\t\t<div className=\"mt-2 flex justify-center\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={handleLoadMore}\n\t\t\t\t\t\tclassName=\"text-sm text-kumo-link hover:underline\"\n\t\t\t\t\t>\n\t\t\t\t\t\tLoad more\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n","import { ActionsBlockComponent } from \"./blocks/actions.js\";\nimport { BannerBlockComponent } from \"./blocks/banner.js\";\nimport { ChartBlockComponent } from \"./blocks/chart.js\";\nimport { CodeBlockComponent } from \"./blocks/code.js\";\nimport { ColumnsBlockComponent } from \"./blocks/columns.js\";\nimport { ContextBlockComponent } from \"./blocks/context.js\";\nimport { DividerBlockComponent } from \"./blocks/divider.js\";\nimport { FieldsBlockComponent } from \"./blocks/fields.js\";\nimport { FormBlockComponent } from \"./blocks/form.js\";\nimport { HeaderBlockComponent } from \"./blocks/header.js\";\nimport { ImageBlockComponent } from \"./blocks/image.js\";\nimport { MeterBlockComponent } from \"./blocks/meter.js\";\nimport { SectionBlockComponent } from \"./blocks/section.js\";\nimport { StatsBlockComponent } from \"./blocks/stats.js\";\nimport { TableBlockComponent } from \"./blocks/table.js\";\nimport type { Block, BlockInteraction } from \"./types.js\";\n\nfunction renderBlock(\n\tblock: Block,\n\tonAction: (interaction: BlockInteraction) => void,\n): React.ReactNode {\n\tswitch (block.type) {\n\t\tcase \"header\":\n\t\t\treturn <HeaderBlockComponent block={block} />;\n\t\tcase \"section\":\n\t\t\treturn <SectionBlockComponent block={block} onAction={onAction} />;\n\t\tcase \"divider\":\n\t\t\treturn <DividerBlockComponent />;\n\t\tcase \"fields\":\n\t\t\treturn <FieldsBlockComponent block={block} />;\n\t\tcase \"table\":\n\t\t\treturn <TableBlockComponent block={block} onAction={onAction} />;\n\t\tcase \"actions\":\n\t\t\treturn <ActionsBlockComponent block={block} onAction={onAction} />;\n\t\tcase \"stats\":\n\t\t\treturn <StatsBlockComponent block={block} />;\n\t\tcase \"form\":\n\t\t\treturn <FormBlockComponent block={block} onAction={onAction} />;\n\t\tcase \"image\":\n\t\t\treturn <ImageBlockComponent block={block} />;\n\t\tcase \"context\":\n\t\t\treturn <ContextBlockComponent block={block} />;\n\t\tcase \"columns\":\n\t\t\treturn <ColumnsBlockComponent block={block} onAction={onAction} />;\n\t\tcase \"chart\":\n\t\t\treturn <ChartBlockComponent block={block} />;\n\t\tcase \"meter\":\n\t\t\treturn <MeterBlockComponent block={block} />;\n\t\tcase \"banner\":\n\t\t\treturn <BannerBlockComponent block={block} />;\n\t\tcase \"code\":\n\t\t\treturn <CodeBlockComponent block={block} />;\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = block;\n\t\t\treturn null;\n\t\t}\n\t}\n}\n\nexport interface BlockRendererProps {\n\tblocks: Block[];\n\tonAction: (interaction: BlockInteraction) => void;\n}\n\nexport function BlockRenderer({ blocks, onAction }: BlockRendererProps) {\n\treturn (\n\t\t<div className=\"flex flex-col gap-4\">\n\t\t\t{blocks.map((block, i) => (\n\t\t\t\t<div key={block.block_id ?? i}>{renderBlock(block, onAction)}</div>\n\t\t\t))}\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { A as ImageBlock, B as TableBlock, C as Element, D as FormField, E as FormBlock, F as SecretInputElement, H as TextInputElement, I as SectionBlock, L as SelectElement, M as NumberInputElement, N as PageLoad, O as FormSubmit, R as StatItem, S as DividerBlock, T as FieldsBlock, V as TableColumn, W as ToggleElement, c as BlockInteraction, g as ColumnsBlock, i as ActionsBlock, k as HeaderBlock, l as BlockResponse, n as blocks, o as Block, r as elements, s as BlockAction, t as validateBlocks, u as ButtonElement, v as ConfirmDialog, w as FieldCondition, y as ContextBlock, z as StatsBlock } from "./validation-BG2u9jAE.js";
|
|
2
|
+
export { type ActionsBlock, type Block, type BlockAction, type BlockInteraction, type BlockResponse, type ButtonElement, type ColumnsBlock, type ConfirmDialog, type ContextBlock, type DividerBlock, type Element, type FieldCondition, type FieldsBlock, type FormBlock, type FormField, type FormSubmit, type HeaderBlock, type ImageBlock, type NumberInputElement, type PageLoad, type SecretInputElement, type SectionBlock, type SelectElement, type StatItem, type StatsBlock, type TableBlock, type TableColumn, type TextInputElement, type ToggleElement, blocks, elements, validateBlocks };
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
//#region src/types.d.ts
|
|
2
|
+
interface ConfirmDialog {
|
|
3
|
+
title: string;
|
|
4
|
+
text: string;
|
|
5
|
+
confirm: string;
|
|
6
|
+
deny: string;
|
|
7
|
+
style?: "danger";
|
|
8
|
+
}
|
|
9
|
+
interface ButtonElement {
|
|
10
|
+
type: "button";
|
|
11
|
+
action_id: string;
|
|
12
|
+
label: string;
|
|
13
|
+
style?: "primary" | "danger" | "secondary";
|
|
14
|
+
value?: unknown;
|
|
15
|
+
confirm?: ConfirmDialog;
|
|
16
|
+
}
|
|
17
|
+
interface TextInputElement {
|
|
18
|
+
type: "text_input";
|
|
19
|
+
action_id: string;
|
|
20
|
+
label: string;
|
|
21
|
+
placeholder?: string;
|
|
22
|
+
initial_value?: string;
|
|
23
|
+
multiline?: boolean;
|
|
24
|
+
}
|
|
25
|
+
interface NumberInputElement {
|
|
26
|
+
type: "number_input";
|
|
27
|
+
action_id: string;
|
|
28
|
+
label: string;
|
|
29
|
+
initial_value?: number;
|
|
30
|
+
min?: number;
|
|
31
|
+
max?: number;
|
|
32
|
+
}
|
|
33
|
+
interface SelectElement {
|
|
34
|
+
type: "select";
|
|
35
|
+
action_id: string;
|
|
36
|
+
label: string;
|
|
37
|
+
options: Array<{
|
|
38
|
+
label: string;
|
|
39
|
+
value: string;
|
|
40
|
+
}>;
|
|
41
|
+
initial_value?: string;
|
|
42
|
+
/** Plugin route that returns `{ items: Array<{ id, name }> }` to populate options dynamically */
|
|
43
|
+
optionsRoute?: string;
|
|
44
|
+
}
|
|
45
|
+
interface ToggleElement {
|
|
46
|
+
type: "toggle";
|
|
47
|
+
action_id: string;
|
|
48
|
+
label: string;
|
|
49
|
+
description?: string;
|
|
50
|
+
initial_value?: boolean;
|
|
51
|
+
}
|
|
52
|
+
interface SecretInputElement {
|
|
53
|
+
type: "secret_input";
|
|
54
|
+
action_id: string;
|
|
55
|
+
label: string;
|
|
56
|
+
placeholder?: string;
|
|
57
|
+
has_value?: boolean;
|
|
58
|
+
}
|
|
59
|
+
interface CheckboxElement {
|
|
60
|
+
type: "checkbox";
|
|
61
|
+
action_id: string;
|
|
62
|
+
label: string;
|
|
63
|
+
options: Array<{
|
|
64
|
+
label: string;
|
|
65
|
+
value: string;
|
|
66
|
+
}>;
|
|
67
|
+
initial_value?: string[];
|
|
68
|
+
}
|
|
69
|
+
interface DateInputElement {
|
|
70
|
+
type: "date_input";
|
|
71
|
+
action_id: string;
|
|
72
|
+
label: string;
|
|
73
|
+
initial_value?: string;
|
|
74
|
+
placeholder?: string;
|
|
75
|
+
}
|
|
76
|
+
interface ComboboxElement {
|
|
77
|
+
type: "combobox";
|
|
78
|
+
action_id: string;
|
|
79
|
+
label: string;
|
|
80
|
+
options: Array<{
|
|
81
|
+
label: string;
|
|
82
|
+
value: string;
|
|
83
|
+
}>;
|
|
84
|
+
initial_value?: string;
|
|
85
|
+
placeholder?: string;
|
|
86
|
+
}
|
|
87
|
+
interface RadioElement {
|
|
88
|
+
type: "radio";
|
|
89
|
+
action_id: string;
|
|
90
|
+
label: string;
|
|
91
|
+
options: Array<{
|
|
92
|
+
label: string;
|
|
93
|
+
value: string;
|
|
94
|
+
}>;
|
|
95
|
+
initial_value?: string;
|
|
96
|
+
}
|
|
97
|
+
type Element = ButtonElement | TextInputElement | NumberInputElement | SelectElement | ToggleElement | SecretInputElement | CheckboxElement | DateInputElement | ComboboxElement | RadioElement;
|
|
98
|
+
type FieldCondition = {
|
|
99
|
+
field: string;
|
|
100
|
+
eq?: unknown;
|
|
101
|
+
neq?: never;
|
|
102
|
+
} | {
|
|
103
|
+
field: string;
|
|
104
|
+
neq?: unknown;
|
|
105
|
+
eq?: never;
|
|
106
|
+
};
|
|
107
|
+
type FormField = (ButtonElement | TextInputElement | NumberInputElement | SelectElement | ToggleElement | SecretInputElement | CheckboxElement | DateInputElement | ComboboxElement | RadioElement) & {
|
|
108
|
+
condition?: FieldCondition;
|
|
109
|
+
};
|
|
110
|
+
interface TableColumn {
|
|
111
|
+
key: string;
|
|
112
|
+
label: string;
|
|
113
|
+
format?: "text" | "badge" | "relative_time" | "number" | "code";
|
|
114
|
+
sortable?: boolean;
|
|
115
|
+
}
|
|
116
|
+
interface StatItem {
|
|
117
|
+
label: string;
|
|
118
|
+
value: string | number;
|
|
119
|
+
description?: string;
|
|
120
|
+
trend?: "up" | "down" | "neutral";
|
|
121
|
+
}
|
|
122
|
+
/** A single data series for a timeseries chart. */
|
|
123
|
+
interface ChartSeries {
|
|
124
|
+
/** Display name shown in tooltips and legends */
|
|
125
|
+
name: string;
|
|
126
|
+
/** Array of `[timestamp_ms, value]` tuples ordered by time */
|
|
127
|
+
data: [number, number][];
|
|
128
|
+
/**
|
|
129
|
+
* Hex color for this series. If omitted, an automatic categorical color
|
|
130
|
+
* from the Kumo palette is assigned based on the series index.
|
|
131
|
+
*/
|
|
132
|
+
color?: string;
|
|
133
|
+
}
|
|
134
|
+
/** Timeseries-specific chart configuration */
|
|
135
|
+
interface TimeseriesChartConfig {
|
|
136
|
+
chart_type: "timeseries";
|
|
137
|
+
/** Visual style of each series. Defaults to `"line"`. */
|
|
138
|
+
style?: "line" | "bar";
|
|
139
|
+
/** Array of time series to display */
|
|
140
|
+
series: ChartSeries[];
|
|
141
|
+
/** Label for the x-axis */
|
|
142
|
+
x_axis_name?: string;
|
|
143
|
+
/** Label for the y-axis */
|
|
144
|
+
y_axis_name?: string;
|
|
145
|
+
/** Height of the chart in pixels. Defaults to 350. */
|
|
146
|
+
height?: number;
|
|
147
|
+
/** Render a gradient fill beneath line series */
|
|
148
|
+
gradient?: boolean;
|
|
149
|
+
}
|
|
150
|
+
/** Custom chart configuration using raw ECharts options (pie, etc.) */
|
|
151
|
+
interface CustomChartConfig {
|
|
152
|
+
chart_type: "custom";
|
|
153
|
+
/** Raw ECharts option object — passed through to `chart.setOption()` */
|
|
154
|
+
options: Record<string, unknown>;
|
|
155
|
+
/** Height of the chart in pixels. Defaults to 350. */
|
|
156
|
+
height?: number;
|
|
157
|
+
}
|
|
158
|
+
type ChartConfig = TimeseriesChartConfig | CustomChartConfig;
|
|
159
|
+
interface BlockBase {
|
|
160
|
+
block_id?: string;
|
|
161
|
+
}
|
|
162
|
+
interface HeaderBlock extends BlockBase {
|
|
163
|
+
type: "header";
|
|
164
|
+
text: string;
|
|
165
|
+
}
|
|
166
|
+
interface SectionBlock extends BlockBase {
|
|
167
|
+
type: "section";
|
|
168
|
+
text: string;
|
|
169
|
+
accessory?: Element;
|
|
170
|
+
}
|
|
171
|
+
interface DividerBlock extends BlockBase {
|
|
172
|
+
type: "divider";
|
|
173
|
+
}
|
|
174
|
+
interface FieldsBlock extends BlockBase {
|
|
175
|
+
type: "fields";
|
|
176
|
+
fields: Array<{
|
|
177
|
+
label: string;
|
|
178
|
+
value: string;
|
|
179
|
+
}>;
|
|
180
|
+
}
|
|
181
|
+
interface TableBlock extends BlockBase {
|
|
182
|
+
type: "table";
|
|
183
|
+
columns: TableColumn[];
|
|
184
|
+
rows: Array<Record<string, unknown>>;
|
|
185
|
+
next_cursor?: string;
|
|
186
|
+
page_action_id: string;
|
|
187
|
+
empty_text?: string;
|
|
188
|
+
}
|
|
189
|
+
interface ActionsBlock extends BlockBase {
|
|
190
|
+
type: "actions";
|
|
191
|
+
elements: Element[];
|
|
192
|
+
}
|
|
193
|
+
interface StatsBlock extends BlockBase {
|
|
194
|
+
type: "stats";
|
|
195
|
+
items: StatItem[];
|
|
196
|
+
}
|
|
197
|
+
interface FormBlock extends BlockBase {
|
|
198
|
+
type: "form";
|
|
199
|
+
fields: FormField[];
|
|
200
|
+
submit: {
|
|
201
|
+
label: string;
|
|
202
|
+
action_id: string;
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
interface ImageBlock extends BlockBase {
|
|
206
|
+
type: "image";
|
|
207
|
+
url: string;
|
|
208
|
+
alt: string;
|
|
209
|
+
title?: string;
|
|
210
|
+
}
|
|
211
|
+
interface ContextBlock extends BlockBase {
|
|
212
|
+
type: "context";
|
|
213
|
+
text: string;
|
|
214
|
+
}
|
|
215
|
+
interface ColumnsBlock extends BlockBase {
|
|
216
|
+
type: "columns";
|
|
217
|
+
columns: Block[][];
|
|
218
|
+
}
|
|
219
|
+
interface ChartBlock extends BlockBase {
|
|
220
|
+
type: "chart";
|
|
221
|
+
config: ChartConfig;
|
|
222
|
+
}
|
|
223
|
+
interface BannerBlock extends BlockBase {
|
|
224
|
+
type: "banner";
|
|
225
|
+
title?: string;
|
|
226
|
+
description?: string;
|
|
227
|
+
variant?: "default" | "alert" | "error";
|
|
228
|
+
}
|
|
229
|
+
interface MeterBlock extends BlockBase {
|
|
230
|
+
type: "meter";
|
|
231
|
+
label: string;
|
|
232
|
+
value: number;
|
|
233
|
+
max?: number;
|
|
234
|
+
min?: number;
|
|
235
|
+
custom_value?: string;
|
|
236
|
+
}
|
|
237
|
+
interface CodeBlock extends BlockBase {
|
|
238
|
+
type: "code";
|
|
239
|
+
code: string;
|
|
240
|
+
language?: "ts" | "tsx" | "jsonc" | "bash" | "css";
|
|
241
|
+
}
|
|
242
|
+
type Block = HeaderBlock | SectionBlock | DividerBlock | FieldsBlock | TableBlock | ActionsBlock | StatsBlock | FormBlock | ImageBlock | ContextBlock | ColumnsBlock | ChartBlock | BannerBlock | MeterBlock | CodeBlock;
|
|
243
|
+
interface BlockAction {
|
|
244
|
+
type: "block_action";
|
|
245
|
+
action_id: string;
|
|
246
|
+
block_id?: string;
|
|
247
|
+
value?: unknown;
|
|
248
|
+
}
|
|
249
|
+
interface FormSubmit {
|
|
250
|
+
type: "form_submit";
|
|
251
|
+
action_id: string;
|
|
252
|
+
block_id?: string;
|
|
253
|
+
values: Record<string, unknown>;
|
|
254
|
+
}
|
|
255
|
+
interface PageLoad {
|
|
256
|
+
type: "page_load";
|
|
257
|
+
page: string;
|
|
258
|
+
}
|
|
259
|
+
type BlockInteraction = BlockAction | FormSubmit | PageLoad;
|
|
260
|
+
interface BlockResponse {
|
|
261
|
+
blocks: Block[];
|
|
262
|
+
toast?: {
|
|
263
|
+
message: string;
|
|
264
|
+
type: "success" | "error" | "info";
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
//#endregion
|
|
268
|
+
//#region src/builders.d.ts
|
|
269
|
+
declare function header(text: string, opts?: {
|
|
270
|
+
blockId?: string;
|
|
271
|
+
}): HeaderBlock;
|
|
272
|
+
declare function section(text: string, opts?: {
|
|
273
|
+
accessory?: Element;
|
|
274
|
+
blockId?: string;
|
|
275
|
+
}): SectionBlock;
|
|
276
|
+
declare function divider(opts?: {
|
|
277
|
+
blockId?: string;
|
|
278
|
+
}): DividerBlock;
|
|
279
|
+
declare function fieldsBlock(fields: Array<{
|
|
280
|
+
label: string;
|
|
281
|
+
value: string;
|
|
282
|
+
}>, opts?: {
|
|
283
|
+
blockId?: string;
|
|
284
|
+
}): FieldsBlock;
|
|
285
|
+
declare function table(opts: {
|
|
286
|
+
blockId?: string;
|
|
287
|
+
columns: TableColumn[];
|
|
288
|
+
rows: Array<Record<string, unknown>>;
|
|
289
|
+
nextCursor?: string;
|
|
290
|
+
pageActionId: string;
|
|
291
|
+
emptyText?: string;
|
|
292
|
+
}): TableBlock;
|
|
293
|
+
declare function actionsBlock(elements: Element[], opts?: {
|
|
294
|
+
blockId?: string;
|
|
295
|
+
}): ActionsBlock;
|
|
296
|
+
declare function stats(items: StatItem[], opts?: {
|
|
297
|
+
blockId?: string;
|
|
298
|
+
}): StatsBlock;
|
|
299
|
+
declare function form(opts: {
|
|
300
|
+
blockId?: string;
|
|
301
|
+
fields: FormField[];
|
|
302
|
+
submit: {
|
|
303
|
+
label: string;
|
|
304
|
+
actionId: string;
|
|
305
|
+
};
|
|
306
|
+
}): FormBlock;
|
|
307
|
+
declare function image(opts: {
|
|
308
|
+
url: string;
|
|
309
|
+
alt: string;
|
|
310
|
+
title?: string;
|
|
311
|
+
blockId?: string;
|
|
312
|
+
}): ImageBlock;
|
|
313
|
+
declare function context(text: string, opts?: {
|
|
314
|
+
blockId?: string;
|
|
315
|
+
}): ContextBlock;
|
|
316
|
+
declare function columnsBlock(columns: Block[][], opts?: {
|
|
317
|
+
blockId?: string;
|
|
318
|
+
}): ColumnsBlock;
|
|
319
|
+
declare function bannerBlock(opts: {
|
|
320
|
+
blockId?: string;
|
|
321
|
+
variant?: "default" | "alert" | "error";
|
|
322
|
+
} & ({
|
|
323
|
+
title: string;
|
|
324
|
+
description?: string;
|
|
325
|
+
} | {
|
|
326
|
+
title?: string;
|
|
327
|
+
description: string;
|
|
328
|
+
})): BannerBlock;
|
|
329
|
+
declare function textInput(actionId: string, label: string, opts?: {
|
|
330
|
+
placeholder?: string;
|
|
331
|
+
initialValue?: string;
|
|
332
|
+
multiline?: boolean;
|
|
333
|
+
}): TextInputElement;
|
|
334
|
+
declare function numberInput(actionId: string, label: string, opts?: {
|
|
335
|
+
initialValue?: number;
|
|
336
|
+
min?: number;
|
|
337
|
+
max?: number;
|
|
338
|
+
}): NumberInputElement;
|
|
339
|
+
declare function select(actionId: string, label: string, options: Array<{
|
|
340
|
+
label: string;
|
|
341
|
+
value: string;
|
|
342
|
+
}>, opts?: {
|
|
343
|
+
initialValue?: string;
|
|
344
|
+
}): SelectElement;
|
|
345
|
+
declare function toggle(actionId: string, label: string, opts?: {
|
|
346
|
+
description?: string;
|
|
347
|
+
initialValue?: boolean;
|
|
348
|
+
}): ToggleElement;
|
|
349
|
+
declare function button(actionId: string, label: string, opts?: {
|
|
350
|
+
style?: "primary" | "danger" | "secondary";
|
|
351
|
+
value?: unknown;
|
|
352
|
+
confirm?: ConfirmDialog;
|
|
353
|
+
}): ButtonElement;
|
|
354
|
+
declare function secretInput(actionId: string, label: string, opts?: {
|
|
355
|
+
placeholder?: string;
|
|
356
|
+
hasValue?: boolean;
|
|
357
|
+
}): SecretInputElement;
|
|
358
|
+
declare function checkbox(actionId: string, label: string, options: Array<{
|
|
359
|
+
label: string;
|
|
360
|
+
value: string;
|
|
361
|
+
}>, opts?: {
|
|
362
|
+
initialValue?: string[];
|
|
363
|
+
}): CheckboxElement;
|
|
364
|
+
declare function dateInput(actionId: string, label: string, opts?: {
|
|
365
|
+
initialValue?: string;
|
|
366
|
+
placeholder?: string;
|
|
367
|
+
}): DateInputElement;
|
|
368
|
+
declare function combobox(actionId: string, label: string, options: Array<{
|
|
369
|
+
label: string;
|
|
370
|
+
value: string;
|
|
371
|
+
}>, opts?: {
|
|
372
|
+
initialValue?: string;
|
|
373
|
+
placeholder?: string;
|
|
374
|
+
}): ComboboxElement;
|
|
375
|
+
declare function radio(actionId: string, label: string, options: Array<{
|
|
376
|
+
label: string;
|
|
377
|
+
value: string;
|
|
378
|
+
}>, opts?: {
|
|
379
|
+
initialValue?: string;
|
|
380
|
+
}): RadioElement;
|
|
381
|
+
declare function timeseriesChart(opts: {
|
|
382
|
+
blockId?: string;
|
|
383
|
+
series: ChartSeries[];
|
|
384
|
+
style?: "line" | "bar";
|
|
385
|
+
xAxisName?: string;
|
|
386
|
+
yAxisName?: string;
|
|
387
|
+
height?: number;
|
|
388
|
+
gradient?: boolean;
|
|
389
|
+
}): ChartBlock;
|
|
390
|
+
declare function customChart(opts: {
|
|
391
|
+
blockId?: string;
|
|
392
|
+
options: Record<string, unknown>;
|
|
393
|
+
height?: number;
|
|
394
|
+
}): ChartBlock;
|
|
395
|
+
declare function meter(opts: {
|
|
396
|
+
blockId?: string;
|
|
397
|
+
label: string;
|
|
398
|
+
value: number;
|
|
399
|
+
max?: number;
|
|
400
|
+
min?: number;
|
|
401
|
+
customValue?: string;
|
|
402
|
+
}): MeterBlock;
|
|
403
|
+
declare function codeBlock(opts: {
|
|
404
|
+
blockId?: string;
|
|
405
|
+
code: string;
|
|
406
|
+
language?: "ts" | "tsx" | "jsonc" | "bash" | "css";
|
|
407
|
+
}): CodeBlock;
|
|
408
|
+
declare const blocks: {
|
|
409
|
+
header: typeof header;
|
|
410
|
+
section: typeof section;
|
|
411
|
+
divider: typeof divider;
|
|
412
|
+
fields: typeof fieldsBlock;
|
|
413
|
+
table: typeof table;
|
|
414
|
+
actions: typeof actionsBlock;
|
|
415
|
+
stats: typeof stats;
|
|
416
|
+
form: typeof form;
|
|
417
|
+
image: typeof image;
|
|
418
|
+
context: typeof context;
|
|
419
|
+
columns: typeof columnsBlock;
|
|
420
|
+
timeseriesChart: typeof timeseriesChart;
|
|
421
|
+
customChart: typeof customChart;
|
|
422
|
+
banner: typeof bannerBlock;
|
|
423
|
+
meter: typeof meter;
|
|
424
|
+
code: typeof codeBlock;
|
|
425
|
+
};
|
|
426
|
+
declare const elements: {
|
|
427
|
+
textInput: typeof textInput;
|
|
428
|
+
numberInput: typeof numberInput;
|
|
429
|
+
select: typeof select;
|
|
430
|
+
toggle: typeof toggle;
|
|
431
|
+
button: typeof button;
|
|
432
|
+
secretInput: typeof secretInput;
|
|
433
|
+
checkbox: typeof checkbox;
|
|
434
|
+
combobox: typeof combobox;
|
|
435
|
+
dateInput: typeof dateInput;
|
|
436
|
+
radio: typeof radio;
|
|
437
|
+
};
|
|
438
|
+
//#endregion
|
|
439
|
+
//#region src/validation.d.ts
|
|
440
|
+
interface ValidationError {
|
|
441
|
+
path: string;
|
|
442
|
+
message: string;
|
|
443
|
+
}
|
|
444
|
+
declare function validateBlocks(blocks: unknown): {
|
|
445
|
+
valid: boolean;
|
|
446
|
+
errors: ValidationError[];
|
|
447
|
+
};
|
|
448
|
+
//#endregion
|
|
449
|
+
export { ImageBlock as A, TableBlock as B, Element as C, FormField as D, FormBlock as E, SecretInputElement as F, TextInputElement as H, SectionBlock as I, SelectElement as L, NumberInputElement as M, PageLoad as N, FormSubmit as O, RadioElement as P, StatItem as R, DividerBlock as S, FieldsBlock as T, TimeseriesChartConfig as U, TableColumn as V, ToggleElement as W, ComboboxElement as _, BannerBlock as a, CustomChartConfig as b, BlockInteraction as c, ChartBlock as d, ChartConfig as f, ColumnsBlock as g, CodeBlock as h, ActionsBlock as i, MeterBlock as j, HeaderBlock as k, BlockResponse as l, CheckboxElement as m, blocks as n, Block as o, ChartSeries as p, elements as r, BlockAction as s, validateBlocks as t, ButtonElement as u, ConfirmDialog as v, FieldCondition as w, DateInputElement as x, ContextBlock as y, StatsBlock as z };
|
|
450
|
+
//# sourceMappingURL=validation-BG2u9jAE.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation-BG2u9jAE.d.ts","names":[],"sources":["../src/types.ts","../src/builders.ts","../src/validation.ts"],"mappings":"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"}
|