@tensor_1/react 2.30.0 → 2.32.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 (122) hide show
  1. package/README.md +430 -0
  2. package/dist/attachment-labels.d.ts +16 -0
  3. package/dist/attachment-labels.js +9 -0
  4. package/dist/calendar-model.d.ts +141 -1
  5. package/dist/calendar-model.js +200 -11
  6. package/dist/chart-preset.cjs +127 -7
  7. package/dist/chart-preset.d.cts +2 -2
  8. package/dist/chart-preset.d.ts +1 -0
  9. package/dist/chart-preset.js +6 -1
  10. package/dist/chart-theme-Cl0IrkKQ.d.cts +112 -0
  11. package/dist/chart-theme.d.ts +51 -0
  12. package/dist/chart-theme.js +99 -0
  13. package/dist/chart.cjs +127 -7
  14. package/dist/chart.d.cts +2 -2
  15. package/dist/chart.d.ts +1 -0
  16. package/dist/chart.js +6 -2
  17. package/dist/components/Alert.d.ts +17 -1
  18. package/dist/components/Alert.js +9 -4
  19. package/dist/components/AlertDismiss.d.ts +14 -0
  20. package/dist/components/AlertDismiss.js +11 -0
  21. package/dist/components/Attachment.d.ts +58 -0
  22. package/dist/components/Attachment.js +69 -0
  23. package/dist/components/AttachmentParts.d.ts +24 -0
  24. package/dist/components/AttachmentParts.js +20 -0
  25. package/dist/components/Chart.d.ts +1 -0
  26. package/dist/components/Chart.js +6 -1
  27. package/dist/components/ChartCore.d.ts +6 -1
  28. package/dist/components/ChartCore.js +23 -5
  29. package/dist/components/Chip.d.ts +17 -2
  30. package/dist/components/Chip.js +35 -11
  31. package/dist/components/ChipRemove.d.ts +17 -0
  32. package/dist/components/ChipRemove.js +13 -0
  33. package/dist/components/CollapsibleParts.d.ts +29 -0
  34. package/dist/components/CollapsibleParts.js +20 -0
  35. package/dist/components/CollapsibleSection.d.ts +30 -3
  36. package/dist/components/CollapsibleSection.js +7 -11
  37. package/dist/components/CollapsibleSectionState.d.ts +1 -1
  38. package/dist/components/CollapsibleSectionState.js +54 -27
  39. package/dist/components/DashboardGrid.d.ts +60 -0
  40. package/dist/components/DashboardGrid.js +40 -0
  41. package/dist/components/DateRangePicker.d.ts +7 -1
  42. package/dist/components/DateRangePicker.js +5 -1
  43. package/dist/components/DescriptionList.d.ts +12 -1
  44. package/dist/components/DescriptionList.js +5 -5
  45. package/dist/components/Dialogs.d.ts +24 -3
  46. package/dist/components/Dialogs.js +74 -16
  47. package/dist/components/EntityPicker.d.ts +56 -0
  48. package/dist/components/EntityPicker.js +168 -0
  49. package/dist/components/FileIcon.d.ts +9 -0
  50. package/dist/components/FileIcon.js +17 -0
  51. package/dist/components/FileUpload.d.ts +95 -0
  52. package/dist/components/FileUpload.js +145 -0
  53. package/dist/components/FilterEditor.d.ts +55 -0
  54. package/dist/components/FilterEditor.js +186 -0
  55. package/dist/components/Heartbeat.d.ts +31 -0
  56. package/dist/components/Heartbeat.js +28 -0
  57. package/dist/components/Lightbox.d.ts +45 -0
  58. package/dist/components/Lightbox.js +102 -0
  59. package/dist/components/Menu.d.ts +53 -5
  60. package/dist/components/Menu.js +104 -4
  61. package/dist/components/Meter.d.ts +7 -3
  62. package/dist/components/Meter.js +2 -1
  63. package/dist/components/Popover.d.ts +21 -2
  64. package/dist/components/Popover.js +94 -17
  65. package/dist/components/Prose.d.ts +6 -2
  66. package/dist/components/Prose.js +1 -1
  67. package/dist/components/RuleBuilder.d.ts +52 -4
  68. package/dist/components/RuleBuilder.js +109 -24
  69. package/dist/components/SchedulingCalendar.d.ts +142 -11
  70. package/dist/components/SchedulingCalendar.js +234 -57
  71. package/dist/components/SchedulingTimeline.d.ts +1 -0
  72. package/dist/components/SearchSuggest.d.ts +6 -2
  73. package/dist/components/SearchSuggest.js +4 -0
  74. package/dist/components/Segmented.d.ts +17 -3
  75. package/dist/components/Segmented.js +59 -5
  76. package/dist/components/Select.d.ts +66 -2
  77. package/dist/components/Select.js +800 -10
  78. package/dist/components/Spinner.d.ts +2 -1
  79. package/dist/components/Spinner.js +1 -1
  80. package/dist/components/StatusPill.d.ts +8 -2
  81. package/dist/components/StatusPill.js +2 -2
  82. package/dist/components/Steps.d.ts +28 -4
  83. package/dist/components/Steps.js +46 -16
  84. package/dist/components/TableControls.js +4 -3
  85. package/dist/components/Tabs.d.ts +7 -2
  86. package/dist/components/Tabs.js +14 -1
  87. package/dist/components/TextDiff.d.ts +49 -0
  88. package/dist/components/TextDiff.js +124 -0
  89. package/dist/{emoji-image-6mPZ15Zy.d.cts → emoji-image-DjCKpdwE.d.cts} +1 -1
  90. package/dist/emoji.cjs +169 -27
  91. package/dist/emoji.d.cts +3 -3
  92. package/dist/file-model.d.ts +56 -0
  93. package/dist/file-model.js +52 -0
  94. package/dist/filter-model.d.ts +112 -0
  95. package/dist/filter-model.js +103 -0
  96. package/dist/hooks/useAnchoredPosition.d.ts +24 -1
  97. package/dist/hooks/useAnchoredPosition.js +58 -8
  98. package/dist/hooks/useVirtualRows.d.ts +17 -2
  99. package/dist/hooks/useVirtualRows.js +6 -5
  100. package/dist/icons/Icon.d.ts +14 -14
  101. package/dist/index.cjs +4938 -1631
  102. package/dist/index.d.cts +1622 -178
  103. package/dist/index.d.ts +20 -6
  104. package/dist/index.js +88 -4
  105. package/dist/labels-context.d.ts +28 -0
  106. package/dist/{overlay-position-Cjv5E7mn.d.cts → overlay-position-2Afke51l.d.cts} +20 -0
  107. package/dist/overlay-position.d.ts +20 -0
  108. package/dist/overlay-position.js +17 -2
  109. package/dist/rich-text.cjs +169 -27
  110. package/dist/rich-text.d.cts +3 -3
  111. package/dist/rule-builder-model.d.ts +34 -2
  112. package/dist/rule-builder-model.js +48 -12
  113. package/dist/scheduling-calendar-model.d.ts +66 -0
  114. package/dist/scheduling-calendar-model.js +82 -0
  115. package/dist/select-model.d.ts +80 -0
  116. package/dist/select-model.js +109 -0
  117. package/dist/table-engine.d.ts +7 -0
  118. package/dist/table-engine.js +2 -1
  119. package/dist/text-diff-model.d.ts +71 -0
  120. package/dist/text-diff-model.js +261 -0
  121. package/package.json +1 -1
  122. package/dist/ChartCore-DzWe10bN.d.cts +0 -59
@@ -7,10 +7,12 @@ import {
7
7
  mapRuleGroup,
8
8
  moveRuleNode,
9
9
  removeRuleNode,
10
+ setRuleCombinator,
10
11
  summarizeRule,
11
12
  validateRuleDefinition
12
13
  } from "../rule-builder-model.js";
13
14
  import { fillLabel } from "../fill-label.js";
15
+ import { useUixLabels } from "../labels-context.js";
14
16
  const DEFAULT_RULE_BUILDER_LABELS = {
15
17
  region: "Rule builder",
16
18
  summary: "Rule summary",
@@ -40,7 +42,20 @@ const DEFAULT_RULE_BUILDER_LABELS = {
40
42
  summaryIssuesMany: "Rule has {count} validation issues.",
41
43
  addCondition: "Add condition",
42
44
  addGroup: "Add group",
43
- addAction: "Add action"
45
+ addAction: "Add action",
46
+ issueDuplicateId: "Duplicate id \u201C{id}\u201D.",
47
+ issueMaxDepth: "Nesting exceeds {max} levels.",
48
+ issueEmptyGroup: "Add at least one condition.",
49
+ issueMissingField: "Choose a field.",
50
+ issueMissingOperator: "Choose an operator.",
51
+ issueNoActions: "Add at least one action.",
52
+ issueMissingActionType: "Choose an action.",
53
+ summarySentence: "When {conditions}, then {actions}.",
54
+ summarySentenceConditionsOnly: "When {conditions}.",
55
+ summaryNoConditions: "no conditions",
56
+ summaryNoActions: "no actions",
57
+ and: "AND",
58
+ or: "OR"
44
59
  };
45
60
  let ruleId = 0;
46
61
  const nextId = (prefix) => `${prefix}-${Date.now().toString(36)}-${(++ruleId).toString(36)}`;
@@ -49,28 +64,45 @@ function defaultCondition(fields, operators) {
49
64
  const operator = operators.find((item) => field?.operators?.includes(item.id)) ?? operators[0];
50
65
  return { id: nextId("condition"), field: field?.id ?? "", operator: operator?.id ?? "", value: "" };
51
66
  }
52
- function RuleGroupEditor({ group, depth, root, fields, operators, maxDepth, disabled, onRootChange, labels }) {
67
+ function RuleGroupEditor({ group, depth, root, fields, operators, maxDepth, disabled, onRootChange, labels, combinator, hideCombinator, allowGroups }) {
53
68
  const updateNode = (id, update) => onRootChange(mapRuleGroup(root, id, update));
54
69
  const addCondition = () => onRootChange(appendRuleNode(root, group.id, defaultCondition(fields, operators), maxDepth));
55
70
  const addGroup = () => onRootChange(appendRuleNode(root, group.id, {
56
71
  id: nextId("group"),
57
- combinator: "and",
72
+ combinator: combinator ?? "and",
58
73
  conditions: [defaultCondition(fields, operators)]
59
74
  }, maxDepth));
75
+ const rowControls = (node, index, label) => disabled ? null : /* @__PURE__ */ jsx(
76
+ RowControls,
77
+ {
78
+ labels,
79
+ label,
80
+ first: index === 0,
81
+ last: index === group.conditions.length - 1,
82
+ disabled: false,
83
+ onUp: () => onRootChange(moveRuleNode(root, node.id, -1)),
84
+ onDown: () => onRootChange(moveRuleNode(root, node.id, 1)),
85
+ onRemove: () => onRootChange(removeRuleNode(root, node.id))
86
+ }
87
+ );
60
88
  return /* @__PURE__ */ jsxs("fieldset", { className: "uix-rule-builder__group", "data-depth": depth, children: [
61
89
  /* @__PURE__ */ jsxs("legend", { className: "uix-rule-builder__group-heading", children: [
62
90
  /* @__PURE__ */ jsx("span", { children: depth === 1 ? labels.when : labels.group }),
63
- /* @__PURE__ */ jsxs("label", { children: [
91
+ !hideCombinator && (combinator ? /* @__PURE__ */ jsxs("span", { className: "uix-rule-builder__match", children: [
92
+ labels.match,
93
+ " ",
94
+ combinator === "or" ? labels.any : labels.all
95
+ ] }) : /* @__PURE__ */ jsxs("label", { children: [
64
96
  labels.match,
65
97
  /* @__PURE__ */ jsxs("select", { className: "uix-select uix-select--sm", value: group.combinator, disabled, onChange: (event) => updateNode(group.id, (node) => ({ ...node, combinator: event.currentTarget.value })), children: [
66
98
  /* @__PURE__ */ jsx("option", { value: "and", children: labels.all }),
67
99
  /* @__PURE__ */ jsx("option", { value: "or", children: labels.any })
68
100
  ] })
69
- ] })
101
+ ] }))
70
102
  ] }),
71
103
  /* @__PURE__ */ jsx("div", { className: "uix-rule-builder__rows", children: group.conditions.map((node, index) => isRuleGroup(node) ? /* @__PURE__ */ jsxs("div", { className: "uix-rule-builder__nested", children: [
72
- /* @__PURE__ */ jsx(RuleGroupEditor, { ...{ group: node, depth: depth + 1, root, fields, operators, maxDepth, disabled, onRootChange, labels } }),
73
- /* @__PURE__ */ jsx(RowControls, { labels, label: labels.itemGroup, first: index === 0, last: index === group.conditions.length - 1, disabled, onUp: () => onRootChange(moveRuleNode(root, node.id, -1)), onDown: () => onRootChange(moveRuleNode(root, node.id, 1)), onRemove: () => onRootChange(removeRuleNode(root, node.id)) })
104
+ /* @__PURE__ */ jsx(RuleGroupEditor, { ...{ group: node, depth: depth + 1, root, fields, operators, maxDepth, disabled, onRootChange, labels, combinator, hideCombinator, allowGroups } }),
105
+ rowControls(node, index, labels.itemGroup)
74
106
  ] }, node.id) : /* @__PURE__ */ jsx(
75
107
  ConditionRow,
76
108
  {
@@ -80,13 +112,13 @@ function RuleGroupEditor({ group, depth, root, fields, operators, maxDepth, disa
80
112
  operators,
81
113
  disabled,
82
114
  onChange: (condition) => updateNode(node.id, () => condition),
83
- controls: /* @__PURE__ */ jsx(RowControls, { labels, label: labels.itemCondition, first: index === 0, last: index === group.conditions.length - 1, disabled, onUp: () => onRootChange(moveRuleNode(root, node.id, -1)), onDown: () => onRootChange(moveRuleNode(root, node.id, 1)), onRemove: () => onRootChange(removeRuleNode(root, node.id)) })
115
+ controls: rowControls(node, index, labels.itemCondition)
84
116
  },
85
117
  node.id
86
118
  )) }),
87
- /* @__PURE__ */ jsxs("div", { className: "uix-rule-builder__add", children: [
88
- /* @__PURE__ */ jsx("button", { type: "button", className: "uix-btn uix-btn--secondary uix-btn--sm", onClick: addCondition, disabled: disabled || fields.length === 0 || operators.length === 0, children: labels.addCondition }),
89
- /* @__PURE__ */ jsx("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", onClick: addGroup, disabled: disabled || depth >= maxDepth, children: labels.addGroup })
119
+ !disabled && /* @__PURE__ */ jsxs("div", { className: "uix-rule-builder__add", children: [
120
+ /* @__PURE__ */ jsx("button", { type: "button", className: "uix-btn uix-btn--secondary uix-btn--sm", onClick: addCondition, disabled: fields.length === 0 || operators.length === 0, children: labels.addCondition }),
121
+ allowGroups && /* @__PURE__ */ jsx("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", onClick: addGroup, disabled: depth >= maxDepth, children: labels.addGroup })
90
122
  ] })
91
123
  ] });
92
124
  }
@@ -124,9 +156,14 @@ function RuleBuilder({
124
156
  onChange,
125
157
  fields,
126
158
  operators,
127
- actions,
159
+ actions = [],
128
160
  maxDepth = 3,
129
161
  readOnly = false,
162
+ conditionsOnly = false,
163
+ combinator,
164
+ hideCombinator = false,
165
+ allowGroups = true,
166
+ checks,
130
167
  validate,
131
168
  className,
132
169
  addConditionLabel,
@@ -134,33 +171,81 @@ function RuleBuilder({
134
171
  addActionLabel,
135
172
  labels: labelOverrides
136
173
  }) {
174
+ const provided = useUixLabels().ruleBuilder;
137
175
  const labels = {
138
176
  ...DEFAULT_RULE_BUILDER_LABELS,
177
+ ...provided,
139
178
  ...addConditionLabel != null ? { addCondition: addConditionLabel } : {},
140
179
  ...addGroupLabel != null ? { addGroup: addGroupLabel } : {},
141
180
  ...addActionLabel != null ? { addAction: addActionLabel } : {},
142
181
  ...labelOverrides
143
182
  };
144
183
  const issuesText = (template1, templateN) => fillLabel(issues.length === 1 ? template1 : templateN, { count: issues.length });
145
- const issues = [...validateRuleDefinition(value, maxDepth), ...validate?.(value) ?? []];
184
+ const builtIn = validateRuleDefinition(value, maxDepth, {
185
+ messages: {
186
+ duplicateId: labels.issueDuplicateId,
187
+ maxDepth: labels.issueMaxDepth,
188
+ emptyGroup: labels.issueEmptyGroup,
189
+ missingField: labels.issueMissingField,
190
+ missingOperator: labels.issueMissingOperator,
191
+ noActions: labels.issueNoActions,
192
+ missingActionType: labels.issueMissingActionType
193
+ },
194
+ checks: conditionsOnly ? { noActions: false, missingActionType: false, ...checks } : checks
195
+ });
196
+ const issues = [...builtIn, ...validate?.(value) ?? []];
146
197
  const fieldLabels = Object.fromEntries(fields.map((field) => [field.id, field.label]));
147
198
  const operatorLabels = Object.fromEntries(operators.map((operator) => [operator.id, operator.label]));
148
199
  const actionLabels = Object.fromEntries(actions.map((action) => [action.id, action.label]));
149
- if (readOnly) return /* @__PURE__ */ jsxs("section", { className: cx("uix-rule-builder uix-rule-builder--summary", className), "aria-label": labels.summary, children: [
150
- /* @__PURE__ */ jsx("p", { children: summarizeRule(value, { fields: fieldLabels, operators: operatorLabels, actions: actionLabels }) }),
151
- issues.length > 0 && /* @__PURE__ */ jsx("p", { className: "uix-rule-builder__invalid", children: issuesText(labels.summaryIssuesOne, labels.summaryIssuesMany) })
152
- ] });
200
+ if (readOnly === "summary") {
201
+ const sentence = summarizeRule(value, {
202
+ fields: fieldLabels,
203
+ operators: operatorLabels,
204
+ actions: actionLabels,
205
+ conditionsOnly,
206
+ words: {
207
+ sentence: labels.summarySentence,
208
+ sentenceConditionsOnly: labels.summarySentenceConditionsOnly,
209
+ noConditions: labels.summaryNoConditions,
210
+ noActions: labels.summaryNoActions,
211
+ and: labels.and,
212
+ or: labels.or
213
+ }
214
+ });
215
+ return /* @__PURE__ */ jsxs("section", { className: cx("uix-rule-builder uix-rule-builder--summary", className), "aria-label": labels.summary, children: [
216
+ /* @__PURE__ */ jsx("p", { children: sentence }),
217
+ issues.length > 0 && /* @__PURE__ */ jsx("p", { className: "uix-rule-builder__invalid", children: issuesText(labels.summaryIssuesOne, labels.summaryIssuesMany) })
218
+ ] });
219
+ }
220
+ const disabled = readOnly === true;
221
+ const emitWhen = (when) => onChange({ ...value, when: combinator ? setRuleCombinator(when, combinator) : when });
153
222
  const updateActions = (next) => onChange({ ...value, then: next });
154
- return /* @__PURE__ */ jsxs("section", { className: cx("uix-rule-builder", className), "aria-label": labels.region, children: [
155
- /* @__PURE__ */ jsx(RuleGroupEditor, { group: value.when, depth: 1, root: value.when, fields, operators, maxDepth, disabled: readOnly, onRootChange: (when) => onChange({ ...value, when }), labels }),
156
- /* @__PURE__ */ jsxs("fieldset", { className: "uix-rule-builder__actions", children: [
223
+ return /* @__PURE__ */ jsxs("section", { className: cx("uix-rule-builder", disabled && "uix-rule-builder--readonly", className), "aria-label": labels.region, children: [
224
+ /* @__PURE__ */ jsx(
225
+ RuleGroupEditor,
226
+ {
227
+ group: value.when,
228
+ depth: 1,
229
+ root: value.when,
230
+ fields,
231
+ operators,
232
+ maxDepth,
233
+ disabled,
234
+ onRootChange: emitWhen,
235
+ labels,
236
+ combinator,
237
+ hideCombinator,
238
+ allowGroups: allowGroups && maxDepth > 1
239
+ }
240
+ ),
241
+ !conditionsOnly && /* @__PURE__ */ jsxs("fieldset", { className: "uix-rule-builder__actions", children: [
157
242
  /* @__PURE__ */ jsx("legend", { children: labels.then }),
158
243
  value.then.map((action, index) => {
159
244
  const definition = actions.find((item) => item.id === action.type);
160
245
  return /* @__PURE__ */ jsxs("div", { className: "uix-rule-builder__action", children: [
161
- /* @__PURE__ */ jsx("select", { className: "uix-select", value: action.type, onChange: (event) => updateActions(value.then.map((item) => item.id === action.id ? { ...item, type: event.currentTarget.value } : item)), "aria-label": labels.actionType, children: actions.map((item) => /* @__PURE__ */ jsx("option", { value: item.id, children: item.label }, item.id)) }),
162
- definition?.renderParameters?.(action, (parameters) => updateActions(value.then.map((item) => item.id === action.id ? { ...item, parameters } : item)), false),
163
- /* @__PURE__ */ jsx(
246
+ /* @__PURE__ */ jsx("select", { className: "uix-select", value: action.type, disabled, onChange: (event) => updateActions(value.then.map((item) => item.id === action.id ? { ...item, type: event.currentTarget.value } : item)), "aria-label": labels.actionType, children: actions.map((item) => /* @__PURE__ */ jsx("option", { value: item.id, children: item.label }, item.id)) }),
247
+ definition?.renderParameters?.(action, (parameters) => updateActions(value.then.map((item) => item.id === action.id ? { ...item, parameters } : item)), disabled),
248
+ !disabled && /* @__PURE__ */ jsx(
164
249
  RowControls,
165
250
  {
166
251
  labels,
@@ -183,7 +268,7 @@ function RuleBuilder({
183
268
  )
184
269
  ] }, action.id);
185
270
  }),
186
- /* @__PURE__ */ jsx("button", { type: "button", className: "uix-btn uix-btn--secondary uix-btn--sm", disabled: actions.length === 0, onClick: () => updateActions([...value.then, { id: nextId("action"), type: actions[0]?.id ?? "", parameters: {} }]), children: labels.addAction })
271
+ !disabled && /* @__PURE__ */ jsx("button", { type: "button", className: "uix-btn uix-btn--secondary uix-btn--sm", disabled: actions.length === 0, onClick: () => updateActions([...value.then, { id: nextId("action"), type: actions[0]?.id ?? "", parameters: {} }]), children: labels.addAction })
187
272
  ] }),
188
273
  /* @__PURE__ */ jsx("div", { className: "uix-rule-builder__validation", "aria-live": "polite", children: issues.length === 0 ? /* @__PURE__ */ jsx("span", { children: labels.valid }) : /* @__PURE__ */ jsxs(Fragment, { children: [
189
274
  /* @__PURE__ */ jsx("strong", { children: issuesText(labels.issuesOne, labels.issuesMany) }),
@@ -1,10 +1,29 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
3
  import { CalendarWeekday } from '../calendar-model.js';
4
+ import { MonthSpanLayout } from '../scheduling-calendar-model.js';
4
5
 
5
6
  type SchedulingCalendarView = 'month' | 'week' | 'agenda';
7
+ /**
8
+ * @deprecated Use `band`, `status` and `markers` on the entry: they carry no product
9
+ * vocabulary and the consumer supplies every word. The values keep working in 2.x.
10
+ */
6
11
  type SchedulingEntryState = 'scheduled' | 'conflicted' | 'in-progress' | 'blackout-violation';
12
+ /** @deprecated Use `pattern` and `kindLabel` on the overlay. The values keep working in 2.x. */
7
13
  type SchedulingOverlayKind = 'maintenance' | 'blackout';
14
+ /**
15
+ * The one dimension that takes a hue. `none` and `low` are untinted, `medium` gets a
16
+ * heavier edge, and only `high` is filled. The consumer decides what a band means.
17
+ */
18
+ type SchedulingBand = 'none' | 'low' | 'medium' | 'high';
19
+ /**
20
+ * The state channel, drawn without hue: `tentative` is dashed, `committed` is the plain
21
+ * item, `live` carries a leading dot, `done` is dimmed and `dead` is struck through.
22
+ */
23
+ type SchedulingStatus = 'tentative' | 'committed' | 'live' | 'done' | 'dead';
24
+ type SchedulingMarkerEmphasis = 'refused' | 'warning' | 'neutral';
25
+ /** How a window is hatched. Windows are neutral: the pattern and the visible label tell them apart. */
26
+ type SchedulingOverlayPattern = 'diagonal' | 'cross' | 'dotted' | 'solid';
8
27
  /**
9
28
  * Which date text a `formatDate` call is for (TENSOR B1/C9, HAR-1347):
10
29
  * `day` names one day (each day cell's accessible name, the week-range title);
@@ -12,20 +31,66 @@ type SchedulingOverlayKind = 'maintenance' | 'blackout';
12
31
  * `month` is the month-view title (the date is the first of the month).
13
32
  */
14
33
  type SchedulingDatePart = 'day' | 'weekday' | 'month';
34
+ /** A shape or icon with text. The text is always in the accessible name; a marker never relies on colour. */
35
+ interface SchedulingMarker {
36
+ id: string;
37
+ /** An icon from `@tensor_1/react/icons`. Without one the marker draws a shape for its `emphasis`. */
38
+ icon?: ReactNode;
39
+ label: string;
40
+ emphasis?: SchedulingMarkerEmphasis;
41
+ }
15
42
  interface SchedulingCalendarEntry {
16
43
  id: string;
17
44
  title: string;
18
45
  start: string;
19
46
  end: string;
47
+ /** @deprecated Use `band`, `status` and `markers`. */
20
48
  state?: SchedulingEntryState;
21
49
  meta?: string;
50
+ band?: SchedulingBand;
51
+ status?: SchedulingStatus;
52
+ markers?: SchedulingMarker[];
53
+ /** The complete accessible name, built by the consumer from its own words. Replaces `labels.entry`. */
54
+ accessibleName?: string;
22
55
  }
23
56
  interface SchedulingCalendarOverlay {
24
57
  id: string;
58
+ /** The window's name, shown as text. */
25
59
  label: string;
26
60
  start: string;
27
61
  end: string;
28
- kind: SchedulingOverlayKind;
62
+ /** @deprecated Use `pattern` and `kindLabel`. */
63
+ kind?: SchedulingOverlayKind;
64
+ /** Defaults to `'solid'`. */
65
+ pattern?: SchedulingOverlayPattern;
66
+ /** What kind of window this is, in the consumer's words. Shown before the name. */
67
+ kindLabel?: string;
68
+ /** What the window applies to. Shown after the name. */
69
+ scopeLabel?: string;
70
+ /** The window applies to everything. A window that is not global never gets the global treatment. */
71
+ global?: boolean;
72
+ /** The complete accessible name. Replaces `labels.overlay`. */
73
+ accessibleName?: string;
74
+ }
75
+ /** What the consumer knows about one day (`YYYY-MM-DD`). The calendar shows these numbers and never derives them. */
76
+ interface SchedulingCalendarDay {
77
+ /** Every item on the day, shown in the cell even when no chip fits. */
78
+ count: number;
79
+ /** The "+N" of the cell. 0 shows none. */
80
+ overflowCount: number;
81
+ /** The accessible text of the count, e.g. "7 items, 2 need review". */
82
+ label?: string;
83
+ markers?: SchedulingMarker[];
84
+ }
85
+ interface SchedulingLegendItem {
86
+ id: string;
87
+ label: string;
88
+ swatch: {
89
+ band?: SchedulingBand;
90
+ status?: SchedulingStatus;
91
+ pattern?: SchedulingOverlayPattern;
92
+ icon?: ReactNode;
93
+ };
29
94
  }
30
95
  /**
31
96
  * Every word the calendar renders (TENSOR RX-125, UIX-12). `{timeZone}`, `{view}`,
@@ -33,8 +98,15 @@ interface SchedulingCalendarOverlay {
33
98
  */
34
99
  interface SchedulingCalendarLabels {
35
100
  region: string;
101
+ /** @deprecated Use `previousMonth` and `previousWeek`. Still used when those are not set. */
36
102
  previous: string;
103
+ /** @deprecated Use `nextMonth` and `nextWeek`. Still used when those are not set. */
37
104
  next: string;
105
+ previousMonth?: string;
106
+ nextMonth?: string;
107
+ /** Also names the agenda's step, which moves by a week. */
108
+ previousWeek?: string;
109
+ nextWeek?: string;
38
110
  viewGroup: string;
39
111
  viewMonth: string;
40
112
  viewWeek: string;
@@ -44,7 +116,10 @@ interface SchedulingCalendarLabels {
44
116
  agenda: string;
45
117
  agendaEmpty: string;
46
118
  grid: string;
119
+ /** An entry's accessible name unless it sets `accessibleName`. Its marker labels are appended. */
47
120
  entry: string;
121
+ /** A window's accessible name unless it sets `accessibleName`. `{title}` is its kind, name and scope. */
122
+ overlay?: string;
48
123
  legend: string;
49
124
  /** The "+N more" toggle on a day with more entries than `maxEntriesPerDay`. `{count}` placeholder. */
50
125
  moreEntries: string;
@@ -52,19 +127,36 @@ interface SchedulingCalendarLabels {
52
127
  moreEntriesLabel: string;
53
128
  /** The toggle once the day is expanded in place. */
54
129
  fewerEntries: string;
130
+ /** The "+N" at the end of a week row whose spans did not all get a lane. `{count}` placeholder. */
131
+ moreSpans?: string;
132
+ /** Accessible name of that control. `{count}` and `{date}` (the first day with a hidden span). */
133
+ moreSpansLabel?: string;
134
+ /** The accessible text of a day's count when `days[date].label` is not given. `{count}` placeholder. */
135
+ dayCount?: string;
55
136
  states: Record<SchedulingEntryState, string>;
137
+ /** The words for `status`, used in the default accessible name and the agenda. */
138
+ statuses?: Partial<Record<SchedulingStatus, string>>;
56
139
  }
57
140
  declare const DEFAULT_SCHEDULING_CALENDAR_LABELS: SchedulingCalendarLabels;
58
141
  interface SchedulingCalendarProps {
142
+ /**
143
+ * The entries. Without `dayEntries` the calendar places each on its day in the order
144
+ * given; with `dayEntries` only the entries that cover more than one day are read from
145
+ * here (they are drawn as spans).
146
+ */
59
147
  entries: SchedulingCalendarEntry[];
60
148
  anchorDate: string;
61
149
  timeZone: string;
62
150
  view?: SchedulingCalendarView;
63
151
  onViewChange?: (view: SchedulingCalendarView) => void;
64
152
  onAnchorDateChange?: (date: string) => void;
153
+ /** Called by a click or Enter on a chip, a span or an agenda row. */
65
154
  onSelectEntry?: (entry: SchedulingCalendarEntry) => void;
66
155
  overlays?: SchedulingCalendarOverlay[];
156
+ /** Called by a click or Enter on a window span. */
157
+ onSelectOverlay?: (overlay: SchedulingCalendarOverlay) => void;
67
158
  filter?: (entry: SchedulingCalendarEntry) => boolean;
159
+ /** Replaces a chip's content. The default is the start time in `timeZone` (24 h) and the title. */
68
160
  renderEntry?: (entry: SchedulingCalendarEntry) => ReactNode;
69
161
  locale?: string;
70
162
  /** First column of the month and week grids: 0 = Sunday … 6 = Saturday. Defaults to 1 (Monday). */
@@ -75,20 +167,23 @@ interface SchedulingCalendarProps {
75
167
  */
76
168
  formatDate?: (date: string, part: SchedulingDatePart) => string;
77
169
  /**
78
- * Formats an entry's start or end instant (ISO 8601) for the agenda and the entry names.
79
- * The component does not shift it: render it in `timeZone` yourself. Defaults to `Intl`
80
- * medium date + short time in `timeZone`.
170
+ * Formats a start or end instant (ISO 8601) for the agenda and the accessible names.
171
+ * The component does not shift it: render it in `timeZone` yourself. Defaults to the
172
+ * `day` date text followed by the 24-hour time in `timeZone`.
81
173
  */
82
174
  formatInstant?: (instant: string) => string;
83
175
  /**
84
- * Show at most this many entries in a month or week day; the rest collapse behind a
85
- * "+N more" toggle. Unset shows every entry.
176
+ * How many chips a day shows. Without `dayEntries` the rest collapse behind "+N more";
177
+ * with `dayEntries` it only sizes the cell (the consumer already cut the list, and a longer
178
+ * list makes the cells taller, never clipped). Unset shows every entry where the cells
179
+ * grow, and sizes a fixed cell for three chips.
86
180
  */
87
181
  maxEntriesPerDay?: number;
88
182
  /**
89
- * Called by the "+N more" toggle with the day and every entry on it. When set, the
90
- * consumer shows them (a popover, a drawer, the day view) and the day stays collapsed;
91
- * otherwise the day expands in place.
183
+ * Called by a day's "+N more" and by a week row's "+N" with the day (and, without
184
+ * `dayEntries`, every entry on it). When set, the consumer shows them (a popover, a
185
+ * drawer, the day view) and the day stays collapsed. Required with `days` or `dayEntries`:
186
+ * a controlled day never expands in place.
92
187
  */
93
188
  onShowMore?: (date: string, entries: SchedulingCalendarEntry[]) => void;
94
189
  /**
@@ -98,6 +193,42 @@ interface SchedulingCalendarProps {
98
193
  * to the number). Return null for no badge.
99
194
  */
100
195
  renderDayBadge?: (date: string, entries: SchedulingCalendarEntry[]) => ReactNode;
196
+ /**
197
+ * Consumer-owned numbers per day (`YYYY-MM-DD`). When set, each listed day shows its
198
+ * `count` and markers even with no chip, and its "+N" is `overflowCount`, never a number
199
+ * derived from the entries given. Without `dayEntries` the chips are still this day's
200
+ * `entries`, cut to `maxEntriesPerDay`; the day never expands in place.
201
+ */
202
+ days?: Record<string, SchedulingCalendarDay>;
203
+ /**
204
+ * The single-day chips of each day, already ranked and cut by the consumer. When set, the
205
+ * calendar renders exactly these in the order given: it does not place, rank, cut or count.
206
+ */
207
+ dayEntries?: Record<string, SchedulingCalendarEntry[]>;
208
+ /**
209
+ * The result of `layoutMonthSpans` for this grid. When set, the calendar draws exactly
210
+ * these spans and never packs lanes itself. Compute it with `schedulingGridDays`.
211
+ */
212
+ spanLayout?: MonthSpanLayout;
213
+ /**
214
+ * Lanes kept for windows above the chips. Windows never take a chip slot. Default 2 where
215
+ * the cells have a fixed height; where they grow with their content every window gets a lane.
216
+ */
217
+ windowLaneCap?: number;
218
+ /** Lanes kept for entries that cover more than one day. Default as for `windowLaneCap`. */
219
+ spanLaneCap?: number;
220
+ /** When set, the legend is exactly these items (an empty list draws no legend). Unset keeps the built-in state legend. */
221
+ legend?: SchedulingLegendItem[];
222
+ /** A line under the legend, e.g. the display zone. */
223
+ legendCaption?: ReactNode;
224
+ /** `false` hides the previous/next buttons, the title and the view switch (the page has its own toolbar). */
225
+ showHeader?: boolean;
226
+ /** Shown above the grid, e.g. "Showing the first 2,000 items". */
227
+ notice?: ReactNode;
228
+ /** Shown inside the grid, below the day cells, when there is nothing to show. */
229
+ emptyNote?: ReactNode;
230
+ /** Called by a click or Enter on a day number. */
231
+ onSelectDate?: (date: string) => void;
101
232
  loading?: boolean;
102
233
  error?: string;
103
234
  onRetry?: () => void;
@@ -105,6 +236,6 @@ interface SchedulingCalendarProps {
105
236
  labels?: Partial<SchedulingCalendarLabels>;
106
237
  }
107
238
  /** Month/week/agenda calendar for UTC ranges rendered in an explicit IANA time zone. */
108
- declare function SchedulingCalendar({ entries, anchorDate, timeZone, view: controlledView, onViewChange, onAnchorDateChange, onSelectEntry, overlays, filter, renderEntry, locale, weekStartsOn, formatDate, formatInstant: formatInstantProp, maxEntriesPerDay, onShowMore, renderDayBadge, loading, error, onRetry, className, labels: labelOverrides, }: SchedulingCalendarProps): react.JSX.Element;
239
+ declare function SchedulingCalendar({ entries, anchorDate, timeZone, view: controlledView, onViewChange, onAnchorDateChange, onSelectEntry, overlays, onSelectOverlay, filter, renderEntry, locale, weekStartsOn, formatDate, formatInstant: formatInstantProp, maxEntriesPerDay, onShowMore, renderDayBadge, days: dayInfo, dayEntries, spanLayout, windowLaneCap, spanLaneCap, legend, legendCaption, showHeader, notice, emptyNote, onSelectDate, loading, error, onRetry, className, labels: labelOverrides, }: SchedulingCalendarProps): react.JSX.Element;
109
240
 
110
- export { DEFAULT_SCHEDULING_CALENDAR_LABELS, SchedulingCalendar, type SchedulingCalendarEntry, type SchedulingCalendarLabels, type SchedulingCalendarOverlay, type SchedulingCalendarProps, type SchedulingCalendarView, type SchedulingDatePart, type SchedulingEntryState, type SchedulingOverlayKind };
241
+ export { DEFAULT_SCHEDULING_CALENDAR_LABELS, type SchedulingBand, SchedulingCalendar, type SchedulingCalendarDay, type SchedulingCalendarEntry, type SchedulingCalendarLabels, type SchedulingCalendarOverlay, type SchedulingCalendarProps, type SchedulingCalendarView, type SchedulingDatePart, type SchedulingEntryState, type SchedulingLegendItem, type SchedulingMarker, type SchedulingMarkerEmphasis, type SchedulingOverlayKind, type SchedulingOverlayPattern, type SchedulingStatus };