@invana/blocks 0.0.32 → 0.0.33

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.cts CHANGED
@@ -754,6 +754,13 @@ interface MultistepOptions {
754
754
  /** Show the answers for a last look, each with Edit, before they are sent. */
755
755
  review?: boolean;
756
756
  }
757
+ /** One choice of a form field's `select` or `radio`. */
758
+ interface FormOption {
759
+ value: string;
760
+ label: string;
761
+ description?: string;
762
+ disabled?: boolean;
763
+ }
757
764
  interface FormOptions extends AskText {
758
765
  /**
759
766
  * `side` sets each label in a column at the left; `top` sets it over its
@@ -764,9 +771,28 @@ interface FormOptions extends AskText {
764
771
  fields: {
765
772
  name: string;
766
773
  label: string;
767
- type: "number" | "text" | "date" | "select";
774
+ /**
775
+ * `textarea` is several lines of text; `checkbox` a yes/no with its label
776
+ * beside the box; `radio` one of `options` drawn as a list, `select` one
777
+ * of them in a menu.
778
+ */
779
+ type: "number" | "text" | "date" | "select" | "textarea" | "checkbox" | "radio";
768
780
  unit?: string;
769
- default?: string | number;
781
+ /** A `checkbox` takes `true`/`false`; `select` and `radio` an option's `value`. */
782
+ default?: string | number | boolean;
783
+ /**
784
+ * The choices of a `select` or `radio`. A `description` is a muted line
785
+ * under a radio's label; a `disabled` choice shows but can't be picked.
786
+ */
787
+ options?: FormOption[];
788
+ /** A `textarea`'s visible lines. */
789
+ rows?: number;
790
+ /** Text shown in an empty `text` or `textarea`. */
791
+ placeholder?: string;
792
+ /** Must be answered — for a `checkbox`, ticked. Holds the submit back until it is. */
793
+ required?: boolean;
794
+ /** Shown with its value but not changeable; the value is still sent. */
795
+ disabled?: boolean;
770
796
  /** Shown beside the value — `quoted 14 d`. */
771
797
  aside?: string;
772
798
  /** A line under the field — `From last year's promotions`. */
@@ -2043,7 +2069,9 @@ declare function FilesBlock({ spec, onAction }: BlockProps<"files">): React.JSX.
2043
2069
  * set — scenario inputs. The fields render through the form generator: with
2044
2070
  * `labels: "side"` in a column on the left, with `"top"` over each field, two
2045
2071
  * to a row where the card is wide enough; a field's `group` sets it under a
2046
- * small caps name. A number out of its `above`/`below` bounds says so under
2072
+ * small caps name. A `textarea` and a list of described `radio` choices take
2073
+ * the row; a `checkbox` sits beside its label. A number out of its
2074
+ * `above`/`below` bounds, or a `required` field left empty, says so under
2047
2075
  * itself and holds the submit back. The submit sends a `reply` keyed by field
2048
2076
  * name.
2049
2077
  *
@@ -2242,4 +2270,4 @@ declare function TimeseriesBlock({ spec }: BlockProps<"timeseries">): React.JSX.
2242
2270
  */
2243
2271
  declare function TraceBlock({ spec, onAction }: BlockProps<"trace">): React.JSX.Element;
2244
2272
 
2245
- export { ANSWER_KINDS, ASK_KINDS, type ActionOption, ActionRow, ActivityBlock, type ActivityLane, type ActivityOptions, type ActivityPin, type AnswerKind, type AnswerOptionsByKind, type ApprovalOptions, type AskKind, type AskOptionsByKind, type AskSpec, type AskState, type AskText, type AskValueByKind, BADGE_TONE, BLOCKS, BLOCK_RENDERERS, BarsBlock, Block, type BlockComponentProps, type BlockKind, type BlockOptionsByKind, type BlockPatch, BlockPatchError, type BlockPatchOp, type BlockProps, type BlockRenderers, type BlockSpec, CAPTION_TONE, CannotBlock, type CannotOptions, CaveatBlock, type CaveatNoteOptions, type CaveatOptions, type CaveatTone, type Cell, type ChoiceFigure, type ChoiceOption, type CitationSource, CitationsBlock, type CitationsBlockProps, type CitationsOptions, type Column, ConfirmAsk, ConfirmCard, type ConfirmCardProps, type ConfirmCost, type ConfirmOptions, type CostFigure, type EntityOptions, type EventSourceOptions, type Figure, type FileItem, FilesBlock, type ForkOptions, FormAsk, type FormOptions, GanttBlock, type GanttOptions, type GanttSpecBar, type GanttSpecRow, type GanttSpecSeam, type GanttSpecStatus, GridBlock, HeatStripBlock, type HeatStripCell, type HeatStripOptions, type HeatStripRowOptions, type HeatStripState, type HypothesisOptions, type InterpretationOptions, type LongOptions, MethodBlock, type MethodOptions, MetricBlock, type MetricOptions, type ModelSpecOptions, MultiAsk, type MultiOptions, MultistepAsk, type MultistepOptions, NarrativeBlock, type NarrativeBlockProps, type NarrativeOptions, type NumberOptions, Page, type PageProps, type PageSection, type PageSpec, type PatchChunk, type PatchPath, type PatchScript, type PatchSource, type PeriodOptions, Placeholder, type PlaceholderProps, type PlanOptions, type PlayOptions, ProposalBlock, type ProposalOptions, QuickAsk, type QuickOptions, type QuickPick, type RangeOptions, RankedBlock, RecordBlock, type RecordRow, type ScaleOptions, ScopeBlock, type ScopeBlockProps, type ScopeOptions, type ScopePart, type ScriptStep, type ShortOptions, SingleAsk, type SingleOptions, type SpecStream, type StreamOptions, SuggestionChips, type SuggestionChipsProps, SuggestionsAsk, type SuggestionsOptions, TableBlock, TimelineBlock, type TimelineEvent, TimeseriesBlock, type Tone, TraceBlock, type TraceIoRow, type TraceOptions, type TraceStep, type TypedValue, VALUE_TYPES, type ValueTypeId, type WeightsOptions, applyBlockPatch, applyBlockPatches, figureText, fromEventSource, fromNdjson, metricValue, offsetScript, patchesOf, playScript, prose, scriptFrames, scriptLength, strong, useBlockStream, useStreamedSpec };
2273
+ export { ANSWER_KINDS, ASK_KINDS, type ActionOption, ActionRow, ActivityBlock, type ActivityLane, type ActivityOptions, type ActivityPin, type AnswerKind, type AnswerOptionsByKind, type ApprovalOptions, type AskKind, type AskOptionsByKind, type AskSpec, type AskState, type AskText, type AskValueByKind, BADGE_TONE, BLOCKS, BLOCK_RENDERERS, BarsBlock, Block, type BlockComponentProps, type BlockKind, type BlockOptionsByKind, type BlockPatch, BlockPatchError, type BlockPatchOp, type BlockProps, type BlockRenderers, type BlockSpec, CAPTION_TONE, CannotBlock, type CannotOptions, CaveatBlock, type CaveatNoteOptions, type CaveatOptions, type CaveatTone, type Cell, type ChoiceFigure, type ChoiceOption, type CitationSource, CitationsBlock, type CitationsBlockProps, type CitationsOptions, type Column, ConfirmAsk, ConfirmCard, type ConfirmCardProps, type ConfirmCost, type ConfirmOptions, type CostFigure, type EntityOptions, type EventSourceOptions, type Figure, type FileItem, FilesBlock, type ForkOptions, FormAsk, type FormOption, type FormOptions, GanttBlock, type GanttOptions, type GanttSpecBar, type GanttSpecRow, type GanttSpecSeam, type GanttSpecStatus, GridBlock, HeatStripBlock, type HeatStripCell, type HeatStripOptions, type HeatStripRowOptions, type HeatStripState, type HypothesisOptions, type InterpretationOptions, type LongOptions, MethodBlock, type MethodOptions, MetricBlock, type MetricOptions, type ModelSpecOptions, MultiAsk, type MultiOptions, MultistepAsk, type MultistepOptions, NarrativeBlock, type NarrativeBlockProps, type NarrativeOptions, type NumberOptions, Page, type PageProps, type PageSection, type PageSpec, type PatchChunk, type PatchPath, type PatchScript, type PatchSource, type PeriodOptions, Placeholder, type PlaceholderProps, type PlanOptions, type PlayOptions, ProposalBlock, type ProposalOptions, QuickAsk, type QuickOptions, type QuickPick, type RangeOptions, RankedBlock, RecordBlock, type RecordRow, type ScaleOptions, ScopeBlock, type ScopeBlockProps, type ScopeOptions, type ScopePart, type ScriptStep, type ShortOptions, SingleAsk, type SingleOptions, type SpecStream, type StreamOptions, SuggestionChips, type SuggestionChipsProps, SuggestionsAsk, type SuggestionsOptions, TableBlock, TimelineBlock, type TimelineEvent, TimeseriesBlock, type Tone, TraceBlock, type TraceIoRow, type TraceOptions, type TraceStep, type TypedValue, VALUE_TYPES, type ValueTypeId, type WeightsOptions, applyBlockPatch, applyBlockPatches, figureText, fromEventSource, fromNdjson, metricValue, offsetScript, patchesOf, playScript, prose, scriptFrames, scriptLength, strong, useBlockStream, useStreamedSpec };
package/dist/index.d.ts CHANGED
@@ -754,6 +754,13 @@ interface MultistepOptions {
754
754
  /** Show the answers for a last look, each with Edit, before they are sent. */
755
755
  review?: boolean;
756
756
  }
757
+ /** One choice of a form field's `select` or `radio`. */
758
+ interface FormOption {
759
+ value: string;
760
+ label: string;
761
+ description?: string;
762
+ disabled?: boolean;
763
+ }
757
764
  interface FormOptions extends AskText {
758
765
  /**
759
766
  * `side` sets each label in a column at the left; `top` sets it over its
@@ -764,9 +771,28 @@ interface FormOptions extends AskText {
764
771
  fields: {
765
772
  name: string;
766
773
  label: string;
767
- type: "number" | "text" | "date" | "select";
774
+ /**
775
+ * `textarea` is several lines of text; `checkbox` a yes/no with its label
776
+ * beside the box; `radio` one of `options` drawn as a list, `select` one
777
+ * of them in a menu.
778
+ */
779
+ type: "number" | "text" | "date" | "select" | "textarea" | "checkbox" | "radio";
768
780
  unit?: string;
769
- default?: string | number;
781
+ /** A `checkbox` takes `true`/`false`; `select` and `radio` an option's `value`. */
782
+ default?: string | number | boolean;
783
+ /**
784
+ * The choices of a `select` or `radio`. A `description` is a muted line
785
+ * under a radio's label; a `disabled` choice shows but can't be picked.
786
+ */
787
+ options?: FormOption[];
788
+ /** A `textarea`'s visible lines. */
789
+ rows?: number;
790
+ /** Text shown in an empty `text` or `textarea`. */
791
+ placeholder?: string;
792
+ /** Must be answered — for a `checkbox`, ticked. Holds the submit back until it is. */
793
+ required?: boolean;
794
+ /** Shown with its value but not changeable; the value is still sent. */
795
+ disabled?: boolean;
770
796
  /** Shown beside the value — `quoted 14 d`. */
771
797
  aside?: string;
772
798
  /** A line under the field — `From last year's promotions`. */
@@ -2043,7 +2069,9 @@ declare function FilesBlock({ spec, onAction }: BlockProps<"files">): React.JSX.
2043
2069
  * set — scenario inputs. The fields render through the form generator: with
2044
2070
  * `labels: "side"` in a column on the left, with `"top"` over each field, two
2045
2071
  * to a row where the card is wide enough; a field's `group` sets it under a
2046
- * small caps name. A number out of its `above`/`below` bounds says so under
2072
+ * small caps name. A `textarea` and a list of described `radio` choices take
2073
+ * the row; a `checkbox` sits beside its label. A number out of its
2074
+ * `above`/`below` bounds, or a `required` field left empty, says so under
2047
2075
  * itself and holds the submit back. The submit sends a `reply` keyed by field
2048
2076
  * name.
2049
2077
  *
@@ -2242,4 +2270,4 @@ declare function TimeseriesBlock({ spec }: BlockProps<"timeseries">): React.JSX.
2242
2270
  */
2243
2271
  declare function TraceBlock({ spec, onAction }: BlockProps<"trace">): React.JSX.Element;
2244
2272
 
2245
- export { ANSWER_KINDS, ASK_KINDS, type ActionOption, ActionRow, ActivityBlock, type ActivityLane, type ActivityOptions, type ActivityPin, type AnswerKind, type AnswerOptionsByKind, type ApprovalOptions, type AskKind, type AskOptionsByKind, type AskSpec, type AskState, type AskText, type AskValueByKind, BADGE_TONE, BLOCKS, BLOCK_RENDERERS, BarsBlock, Block, type BlockComponentProps, type BlockKind, type BlockOptionsByKind, type BlockPatch, BlockPatchError, type BlockPatchOp, type BlockProps, type BlockRenderers, type BlockSpec, CAPTION_TONE, CannotBlock, type CannotOptions, CaveatBlock, type CaveatNoteOptions, type CaveatOptions, type CaveatTone, type Cell, type ChoiceFigure, type ChoiceOption, type CitationSource, CitationsBlock, type CitationsBlockProps, type CitationsOptions, type Column, ConfirmAsk, ConfirmCard, type ConfirmCardProps, type ConfirmCost, type ConfirmOptions, type CostFigure, type EntityOptions, type EventSourceOptions, type Figure, type FileItem, FilesBlock, type ForkOptions, FormAsk, type FormOptions, GanttBlock, type GanttOptions, type GanttSpecBar, type GanttSpecRow, type GanttSpecSeam, type GanttSpecStatus, GridBlock, HeatStripBlock, type HeatStripCell, type HeatStripOptions, type HeatStripRowOptions, type HeatStripState, type HypothesisOptions, type InterpretationOptions, type LongOptions, MethodBlock, type MethodOptions, MetricBlock, type MetricOptions, type ModelSpecOptions, MultiAsk, type MultiOptions, MultistepAsk, type MultistepOptions, NarrativeBlock, type NarrativeBlockProps, type NarrativeOptions, type NumberOptions, Page, type PageProps, type PageSection, type PageSpec, type PatchChunk, type PatchPath, type PatchScript, type PatchSource, type PeriodOptions, Placeholder, type PlaceholderProps, type PlanOptions, type PlayOptions, ProposalBlock, type ProposalOptions, QuickAsk, type QuickOptions, type QuickPick, type RangeOptions, RankedBlock, RecordBlock, type RecordRow, type ScaleOptions, ScopeBlock, type ScopeBlockProps, type ScopeOptions, type ScopePart, type ScriptStep, type ShortOptions, SingleAsk, type SingleOptions, type SpecStream, type StreamOptions, SuggestionChips, type SuggestionChipsProps, SuggestionsAsk, type SuggestionsOptions, TableBlock, TimelineBlock, type TimelineEvent, TimeseriesBlock, type Tone, TraceBlock, type TraceIoRow, type TraceOptions, type TraceStep, type TypedValue, VALUE_TYPES, type ValueTypeId, type WeightsOptions, applyBlockPatch, applyBlockPatches, figureText, fromEventSource, fromNdjson, metricValue, offsetScript, patchesOf, playScript, prose, scriptFrames, scriptLength, strong, useBlockStream, useStreamedSpec };
2273
+ export { ANSWER_KINDS, ASK_KINDS, type ActionOption, ActionRow, ActivityBlock, type ActivityLane, type ActivityOptions, type ActivityPin, type AnswerKind, type AnswerOptionsByKind, type ApprovalOptions, type AskKind, type AskOptionsByKind, type AskSpec, type AskState, type AskText, type AskValueByKind, BADGE_TONE, BLOCKS, BLOCK_RENDERERS, BarsBlock, Block, type BlockComponentProps, type BlockKind, type BlockOptionsByKind, type BlockPatch, BlockPatchError, type BlockPatchOp, type BlockProps, type BlockRenderers, type BlockSpec, CAPTION_TONE, CannotBlock, type CannotOptions, CaveatBlock, type CaveatNoteOptions, type CaveatOptions, type CaveatTone, type Cell, type ChoiceFigure, type ChoiceOption, type CitationSource, CitationsBlock, type CitationsBlockProps, type CitationsOptions, type Column, ConfirmAsk, ConfirmCard, type ConfirmCardProps, type ConfirmCost, type ConfirmOptions, type CostFigure, type EntityOptions, type EventSourceOptions, type Figure, type FileItem, FilesBlock, type ForkOptions, FormAsk, type FormOption, type FormOptions, GanttBlock, type GanttOptions, type GanttSpecBar, type GanttSpecRow, type GanttSpecSeam, type GanttSpecStatus, GridBlock, HeatStripBlock, type HeatStripCell, type HeatStripOptions, type HeatStripRowOptions, type HeatStripState, type HypothesisOptions, type InterpretationOptions, type LongOptions, MethodBlock, type MethodOptions, MetricBlock, type MetricOptions, type ModelSpecOptions, MultiAsk, type MultiOptions, MultistepAsk, type MultistepOptions, NarrativeBlock, type NarrativeBlockProps, type NarrativeOptions, type NumberOptions, Page, type PageProps, type PageSection, type PageSpec, type PatchChunk, type PatchPath, type PatchScript, type PatchSource, type PeriodOptions, Placeholder, type PlaceholderProps, type PlanOptions, type PlayOptions, ProposalBlock, type ProposalOptions, QuickAsk, type QuickOptions, type QuickPick, type RangeOptions, RankedBlock, RecordBlock, type RecordRow, type ScaleOptions, ScopeBlock, type ScopeBlockProps, type ScopeOptions, type ScopePart, type ScriptStep, type ShortOptions, SingleAsk, type SingleOptions, type SpecStream, type StreamOptions, SuggestionChips, type SuggestionChipsProps, SuggestionsAsk, type SuggestionsOptions, TableBlock, TimelineBlock, type TimelineEvent, TimeseriesBlock, type Tone, TraceBlock, type TraceIoRow, type TraceOptions, type TraceStep, type TypedValue, VALUE_TYPES, type ValueTypeId, type WeightsOptions, applyBlockPatch, applyBlockPatches, figureText, fromEventSource, fromNdjson, metricValue, offsetScript, patchesOf, playScript, prose, scriptFrames, scriptLength, strong, useBlockStream, useStreamedSpec };
package/dist/index.js CHANGED
@@ -737,12 +737,17 @@ var FIELD_TYPE = {
737
737
  number: "number",
738
738
  text: "text",
739
739
  date: "text",
740
- select: "select"
740
+ select: "select",
741
+ textarea: "textarea",
742
+ checkbox: "boolean",
743
+ radio: "radio"
741
744
  };
742
- function boundsRule(f) {
743
- if (f.above == null && f.below == null) return void 0;
745
+ var blank = (v) => v == null || typeof v === "string" && v.trim() === "";
746
+ function rules(f) {
747
+ if (!f.required && f.above == null && f.below == null) return void 0;
744
748
  return {
745
749
  validate: (v) => {
750
+ if (f.required && (f.type === "checkbox" ? v !== true : blank(v))) return "Required";
746
751
  const n = Number(v);
747
752
  if (f.above != null && !(n > f.above)) return `Must be above ${f.above}`;
748
753
  if (f.below != null && !(n < f.below)) return `Must be below ${f.below}`;
@@ -750,22 +755,41 @@ function boundsRule(f) {
750
755
  }
751
756
  };
752
757
  }
758
+ function optionsOf(f) {
759
+ if (f.options) return f.options;
760
+ if (f.type === "select" && f.default != null) {
761
+ return [{ value: String(f.default), label: String(f.default) }];
762
+ }
763
+ return void 0;
764
+ }
753
765
  var toField = (f) => ({
754
766
  name: f.name,
755
767
  type: FIELD_TYPE[f.type],
768
+ control: f.type === "checkbox" ? "checkbox" : void 0,
756
769
  label: f.label,
757
770
  unit: f.unit,
758
771
  aside: f.aside,
759
772
  description: f.hint,
760
773
  group: f.group,
761
- rules: boundsRule(f),
762
- placeholder: ""
774
+ options: optionsOf(f),
775
+ rows: f.rows,
776
+ disabled: f.disabled,
777
+ rules: rules(f),
778
+ placeholder: f.placeholder ?? "",
779
+ // A long answer takes the row; so does a list of described choices.
780
+ colSpan: f.type === "textarea" || f.type === "radio" && f.options?.some((o) => o.description) ? 2 : void 0
763
781
  });
782
+ var initial = (f) => f.type === "checkbox" ? f.default ?? false : f.default;
764
783
  function withUnit(value, unit) {
765
784
  if (value == null || value === "") return "\u2014";
766
785
  if (!unit) return String(value);
767
786
  return /^[A-Za-z]/.test(unit) ? `${value} ${unit}` : `${value}${unit}`;
768
787
  }
788
+ function answerOf(f, value) {
789
+ if (f.type === "checkbox") return value === true ? "Yes" : "No";
790
+ const picked = f.options?.find((o) => o.value === value);
791
+ return picked ? picked.label : withUnit(value, f.unit);
792
+ }
769
793
  function FormAsk({ spec, state = "pending", value: given, onAction }) {
770
794
  const auto = React18.useId();
771
795
  const pending = state === "pending";
@@ -773,14 +797,14 @@ function FormAsk({ spec, state = "pending", value: given, onAction }) {
773
797
  const current = given ?? {};
774
798
  const top = spec.labels === "top";
775
799
  const defaults = Object.fromEntries(
776
- spec.fields.map((f) => [f.name, pending ? f.default : current[f.name]])
800
+ spec.fields.map((f) => [f.name, pending ? initial(f) : current[f.name]])
777
801
  );
778
802
  const form = useForm({ defaultValues: { values: defaults }, mode: "onChange" });
779
803
  if (!pending && !editing) {
780
804
  return /* @__PURE__ */ jsx(
781
805
  AskSummary,
782
806
  {
783
- rows: spec.fields.map((f) => ({ label: f.label, value: withUnit(current[f.name], f.unit) })),
807
+ rows: spec.fields.map((f) => ({ label: f.label, value: answerOf(f, current[f.name]) })),
784
808
  change: state === "answered" ? "Change inputs" : void 0,
785
809
  onChange: () => setEditing(true)
786
810
  }
@@ -1215,7 +1239,7 @@ function MultistepAsk({ spec, state = "pending", value: given, onAction }) {
1215
1239
  setEditing(false);
1216
1240
  setReview(null);
1217
1241
  };
1218
- const initial = (step2) => editing ? current[step2.id] : "default" in step2 ? step2.default : void 0;
1242
+ const initial2 = (step2) => editing ? current[step2.id] : "default" in step2 ? step2.default : void 0;
1219
1243
  const index = Math.max(0, steps.findIndex((s) => s.id === item));
1220
1244
  const step = steps[index];
1221
1245
  const last = index === steps.length - 1;
@@ -1238,7 +1262,7 @@ function MultistepAsk({ spec, state = "pending", value: given, onAction }) {
1238
1262
  StepItem,
1239
1263
  {
1240
1264
  step: s,
1241
- value: initial(s),
1265
+ value: initial2(s),
1242
1266
  onStatusChange: (st) => setStatus((now) => ({ ...now, [s.id]: st }))
1243
1267
  },
1244
1268
  s.id