@stonecrop/aform 0.31.0 → 0.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/aform.js +3024 -2256
- package/dist/aform.js.map +1 -1
- package/dist/assets/index.css +1170 -1
- package/dist/src/components/AForm.vue.d.ts +20 -0
- package/dist/src/components/AForm.vue.d.ts.map +1 -0
- package/dist/src/components/AFormLoading.vue.d.ts +14 -0
- package/dist/src/components/AFormLoading.vue.d.ts.map +1 -0
- package/dist/src/components/base/CollapseButton.vue.d.ts +7 -0
- package/dist/src/components/base/CollapseButton.vue.d.ts.map +1 -0
- package/dist/src/components/base/ExpandButton.vue.d.ts +7 -0
- package/dist/src/components/base/ExpandButton.vue.d.ts.map +1 -0
- package/dist/src/components/form/ABadge.vue.d.ts +14 -0
- package/dist/src/components/form/ABadge.vue.d.ts.map +1 -0
- package/dist/src/components/form/ACheckbox.vue.d.ts +15 -0
- package/dist/src/components/form/ACheckbox.vue.d.ts.map +1 -0
- package/dist/src/components/form/ACurrencyInput.vue.d.ts +20 -0
- package/dist/src/components/form/ACurrencyInput.vue.d.ts.map +1 -0
- package/dist/src/components/form/ADate.vue.d.ts +14 -0
- package/dist/src/components/form/ADate.vue.d.ts.map +1 -0
- package/dist/src/components/form/ADatePicker.vue.d.ts +28 -0
- package/dist/src/components/form/ADatePicker.vue.d.ts.map +1 -0
- package/dist/src/components/form/ADateRange.vue.d.ts +18 -0
- package/dist/src/components/form/ADateRange.vue.d.ts.map +1 -0
- package/dist/src/components/form/ADateSelection.vue.d.ts +52 -0
- package/dist/src/components/form/ADateSelection.vue.d.ts.map +1 -0
- package/dist/src/components/form/ADateTime.vue.d.ts +17 -0
- package/dist/src/components/form/ADateTime.vue.d.ts.map +1 -0
- package/dist/src/components/form/ADateTimeInput.vue.d.ts +30 -0
- package/dist/src/components/form/ADateTimeInput.vue.d.ts.map +1 -0
- package/dist/src/components/form/ADropdown.vue.d.ts +20 -0
- package/dist/src/components/form/ADropdown.vue.d.ts.map +1 -0
- package/dist/src/components/form/ADuration.vue.d.ts +18 -0
- package/dist/src/components/form/ADuration.vue.d.ts.map +1 -0
- package/dist/src/components/form/AFieldset.vue.d.ts +28 -0
- package/dist/src/components/form/AFieldset.vue.d.ts.map +1 -0
- package/dist/src/components/form/AFileAttach.vue.d.ts +5 -0
- package/dist/src/components/form/AFileAttach.vue.d.ts.map +1 -0
- package/dist/src/components/form/AFormLink.vue.d.ts +40 -0
- package/dist/src/components/form/AFormLink.vue.d.ts.map +1 -0
- package/dist/src/components/form/ANumericInput.vue.d.ts +14 -0
- package/dist/src/components/form/ANumericInput.vue.d.ts.map +1 -0
- package/dist/src/components/form/AQuantityInput.vue.d.ts +20 -0
- package/dist/src/components/form/AQuantityInput.vue.d.ts.map +1 -0
- package/dist/src/components/form/ASegmentedControl.vue.d.ts +23 -0
- package/dist/src/components/form/ASegmentedControl.vue.d.ts.map +1 -0
- package/dist/src/components/form/ATextInput.vue.d.ts +14 -0
- package/dist/src/components/form/ATextInput.vue.d.ts.map +1 -0
- package/dist/src/components/form/ATextboxInput.vue.d.ts +21 -0
- package/dist/src/components/form/ATextboxInput.vue.d.ts.map +1 -0
- package/dist/src/components/utilities/Login.vue.d.ts +14 -0
- package/dist/src/components/utilities/Login.vue.d.ts.map +1 -0
- package/dist/{tsdoc-metadata.json → src/tsdoc-metadata.json} +1 -1
- package/package.json +35 -30
- package/dist/aform.d.ts +0 -441
- package/dist/aform.tsbuildinfo +0 -1
- package/dist/src/directives/mask.js +0 -107
- package/dist/src/index.js +0 -58
- package/dist/src/types/index.js +0 -0
- package/dist/src/utils/badge.js +0 -71
- package/dist/src/utils/columns.js +0 -33
- package/dist/src/utils/deserialize.js +0 -20
- package/src/components/AForm.vue +0 -314
- package/src/components/AFormLoading.vue +0 -76
- package/src/components/base/CollapseButton.vue +0 -36
- package/src/components/base/ExpandButton.vue +0 -34
- package/src/components/form/ABadge.vue +0 -135
- package/src/components/form/ACheckbox.vue +0 -62
- package/src/components/form/ACurrencyInput.vue +0 -357
- package/src/components/form/ADate.vue +0 -93
- package/src/components/form/ADatePicker.vue +0 -470
- package/src/components/form/ADateRange.vue +0 -133
- package/src/components/form/ADateSelection.vue +0 -174
- package/src/components/form/ADateTime.vue +0 -149
- package/src/components/form/ADateTimeInput.vue +0 -299
- package/src/components/form/ADropdown.vue +0 -222
- package/src/components/form/ADuration.vue +0 -124
- package/src/components/form/AFieldset.vue +0 -72
- package/src/components/form/AFileAttach.vue +0 -97
- package/src/components/form/AFormLink.vue +0 -368
- package/src/components/form/ANumericInput.vue +0 -32
- package/src/components/form/AQuantityInput.vue +0 -349
- package/src/components/form/ASegmentedControl.vue +0 -342
- package/src/components/form/ATextInput.vue +0 -40
- package/src/components/form/ATextboxInput.vue +0 -66
- package/src/components/utilities/Login.vue +0 -189
- package/src/directives/mask.ts +0 -122
- package/src/index.ts +0 -92
- package/src/shims-vue.d.ts +0 -5
- package/src/types/index.ts +0 -333
- package/src/utils/badge.ts +0 -94
- package/src/utils/columns.ts +0 -38
- package/src/utils/deserialize.ts +0 -20
package/src/types/index.ts
DELETED
|
@@ -1,333 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
ColumnSchema,
|
|
3
|
-
FieldValidation,
|
|
4
|
-
GetRecordsOptions,
|
|
5
|
-
GetRecordsResult,
|
|
6
|
-
TableViewConfig,
|
|
7
|
-
ValueField,
|
|
8
|
-
} from '@stonecrop/schema'
|
|
9
|
-
|
|
10
|
-
// ---------------------------------------------------------------------------
|
|
11
|
-
// InteractionMode — canonical home is @stonecrop/schema
|
|
12
|
-
// ---------------------------------------------------------------------------
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Controls the level of user interaction for a field, container, or table.
|
|
16
|
-
* `'edit'` — interactive; `'read'` — non-interactive with form chrome;
|
|
17
|
-
* `'display'` — non-interactive plain-text rendering.
|
|
18
|
-
* @public
|
|
19
|
-
*/
|
|
20
|
-
export type { InteractionMode } from '@stonecrop/schema'
|
|
21
|
-
|
|
22
|
-
// ---------------------------------------------------------------------------
|
|
23
|
-
// ResolvedField — the output-space type that AForm consumes
|
|
24
|
-
//
|
|
25
|
-
// Usually produced by resolveSchema() from an authoring-space DoctypeField[].
|
|
26
|
-
// It may also be hand-authored, for view chrome that has no backing doctype
|
|
27
|
-
// (see Desktop.vue's doctype list) — annotate such literals with `satisfies
|
|
28
|
-
// ResolvedTable`/`satisfies ResolvedField` so they stay checked.
|
|
29
|
-
//
|
|
30
|
-
// Authoring space and output space are NOT interchangeable. The trap is tables:
|
|
31
|
-
// an authoring TableField carries its columns under `columns`, while resolveSchema
|
|
32
|
-
// renames that key to `schema` (registry.ts) because `schema` is the ATable prop
|
|
33
|
-
// that runs schemaToColumns(). Hand-authoring `columns` here — or feeding an
|
|
34
|
-
// authoring-space field straight to AForm — produces a field AForm does not
|
|
35
|
-
// recognise as a table.
|
|
36
|
-
// ---------------------------------------------------------------------------
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* A resolved scalar field. Derived from ValueField with `cardinality` omitted
|
|
40
|
-
* (consumed by resolveSchema) and an optional `doctype` added for unresolved Link fields.
|
|
41
|
-
* @public
|
|
42
|
-
*/
|
|
43
|
-
export type ResolvedScalar = Omit<ValueField, 'cardinality'> & {
|
|
44
|
-
/** Doctype slug for unresolved Link fields — added by resolveSchema when AFormLink is available */
|
|
45
|
-
doctype?: string
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* A resolved Link field with cardinality `one` or `atMostOne` — embedded as a nested form.
|
|
50
|
-
* @public
|
|
51
|
-
*/
|
|
52
|
-
export interface ResolvedLink {
|
|
53
|
-
/** Discriminator */
|
|
54
|
-
kind: 'link'
|
|
55
|
-
/** Field identifier */
|
|
56
|
-
fieldname: string
|
|
57
|
-
/** Component to render; defaults to `'AForm'` */
|
|
58
|
-
component: string
|
|
59
|
-
/** Human-readable label */
|
|
60
|
-
label?: string
|
|
61
|
-
/** Interaction mode */
|
|
62
|
-
mode?: import('@stonecrop/schema').InteractionMode
|
|
63
|
-
/** Resolved child fields */
|
|
64
|
-
schema: ResolvedField[]
|
|
65
|
-
/** Preserved from the original ValueField */
|
|
66
|
-
required?: boolean
|
|
67
|
-
/** Preserved from the original ValueField */
|
|
68
|
-
readOnly?: boolean
|
|
69
|
-
/** Preserved from the original ValueField */
|
|
70
|
-
hidden?: boolean
|
|
71
|
-
/** Preserved from the original ValueField */
|
|
72
|
-
default?: unknown
|
|
73
|
-
/** Preserved from the original ValueField */
|
|
74
|
-
validation?: FieldValidation
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* A resolved table — either from a Link with `noneOrMany`/`atLeastOne` cardinality,
|
|
79
|
-
* or from an inline TableField. ATable receives columns via `:schema` (ColumnSchema[])
|
|
80
|
-
* and row data via `:rows` from formData at render time.
|
|
81
|
-
*
|
|
82
|
-
* Note the key rename: an authoring `TableField` declares its columns under `columns`;
|
|
83
|
-
* `resolveSchema` moves them to `schema` here, because `schema` is the ATable prop that
|
|
84
|
-
* runs `schemaToColumns()` (ATable's own `columns` prop means already-converted
|
|
85
|
-
* `TableColumn[]`). A hand-authored table must therefore use `schema`, not `columns`.
|
|
86
|
-
*
|
|
87
|
-
* Rows are never part of the schema. AForm sources them from the data model at
|
|
88
|
-
* `dataModel[fieldname]`, so a `rows` key placed on this object is ignored.
|
|
89
|
-
* @public
|
|
90
|
-
*/
|
|
91
|
-
export interface ResolvedTable {
|
|
92
|
-
/** Discriminator */
|
|
93
|
-
kind: 'table'
|
|
94
|
-
/** Field identifier */
|
|
95
|
-
fieldname: string
|
|
96
|
-
/** Component to render; defaults to `'ATable'` */
|
|
97
|
-
component: string
|
|
98
|
-
/** Human-readable label */
|
|
99
|
-
label?: string
|
|
100
|
-
/** Interaction mode for all cells */
|
|
101
|
-
mode?: import('@stonecrop/schema').InteractionMode
|
|
102
|
-
/** Column definitions — passed to ATable's `:schema` prop */
|
|
103
|
-
schema: ColumnSchema[]
|
|
104
|
-
/** View configuration — always present; defaults to `{ view: 'list' }` */
|
|
105
|
-
config: TableViewConfig
|
|
106
|
-
/** Preserved from the original ValueField or TableField */
|
|
107
|
-
required?: boolean
|
|
108
|
-
/** Preserved from the original ValueField or TableField */
|
|
109
|
-
readOnly?: boolean
|
|
110
|
-
/** Preserved from the original ValueField or TableField */
|
|
111
|
-
hidden?: boolean
|
|
112
|
-
/** Preserved from the original ValueField or TableField */
|
|
113
|
-
default?: unknown
|
|
114
|
-
/** Preserved from the original ValueField or TableField */
|
|
115
|
-
validation?: FieldValidation
|
|
116
|
-
/** When set, ATable fetches list pages through this callback (server paging). */
|
|
117
|
-
getRecords?: (options?: GetRecordsOptions) => Promise<GetRecordsResult>
|
|
118
|
-
/** When this changes, ATable refetches from offset 0. */
|
|
119
|
-
sourceKey?: string
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* A resolved fieldset — groups child fields inside an AFieldset component.
|
|
124
|
-
* @public
|
|
125
|
-
*/
|
|
126
|
-
export interface ResolvedFieldset {
|
|
127
|
-
/** Discriminator */
|
|
128
|
-
kind: 'fieldset'
|
|
129
|
-
/** Field identifier */
|
|
130
|
-
fieldname: string
|
|
131
|
-
/** Component to render; defaults to `'AFieldset'` */
|
|
132
|
-
component?: string
|
|
133
|
-
/** Human-readable label for the legend */
|
|
134
|
-
label?: string
|
|
135
|
-
/** Whether the fieldset can be collapsed */
|
|
136
|
-
collapsible?: boolean
|
|
137
|
-
/** Interaction mode for all children */
|
|
138
|
-
mode?: import('@stonecrop/schema').InteractionMode
|
|
139
|
-
/** Resolved child fields */
|
|
140
|
-
schema: ResolvedField[]
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* The discriminated union of all resolved field types — what AForm consumes,
|
|
145
|
-
* usually after `resolveSchema()` has transformed the authoring `DoctypeField[]`,
|
|
146
|
-
* but also valid hand-authored for view chrome with no backing doctype.
|
|
147
|
-
* Narrowed by `kind`: `'field'` | `'link'` | `'table'` | `'fieldset'`.
|
|
148
|
-
*
|
|
149
|
-
* `kind` is required — AForm dispatches on it alone and does not infer a field's
|
|
150
|
-
* type from its structure.
|
|
151
|
-
* @public
|
|
152
|
-
*/
|
|
153
|
-
export type ResolvedField = ResolvedScalar | ResolvedLink | ResolvedTable | ResolvedFieldset
|
|
154
|
-
|
|
155
|
-
// ---------------------------------------------------------------------------
|
|
156
|
-
// Utility types
|
|
157
|
-
// ---------------------------------------------------------------------------
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Defined props for AForm components
|
|
161
|
-
* @public
|
|
162
|
-
*/
|
|
163
|
-
export type ComponentProps = {
|
|
164
|
-
/**
|
|
165
|
-
* The schema object to pass to the component
|
|
166
|
-
* @public
|
|
167
|
-
*/
|
|
168
|
-
schema?: ResolvedField
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* The label to display in the component
|
|
172
|
-
* @public
|
|
173
|
-
*/
|
|
174
|
-
label?: string
|
|
175
|
-
|
|
176
|
-
// TODO: add docstring
|
|
177
|
-
selectRange?: boolean
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* The mask to apply to inputs inside the component. Accepts either a plain
|
|
181
|
-
* mask string (e.g. `"(###) ###-####"`) or a stringified arrow function that
|
|
182
|
-
* receives `locale` and returns a mask string
|
|
183
|
-
* (e.g. `"(locale) => locale === 'en-US' ? '(###) ###-####' : '####-######'"`).
|
|
184
|
-
* @public
|
|
185
|
-
*/
|
|
186
|
-
mask?: string
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Indicate whether input is required for text and/or select elements inside the component
|
|
190
|
-
* @public
|
|
191
|
-
*/
|
|
192
|
-
required?: boolean
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* The rendering mode for the component
|
|
196
|
-
* @public
|
|
197
|
-
*/
|
|
198
|
-
mode?: import('@stonecrop/schema').InteractionMode
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Set a unique identifier for elements inside the component
|
|
202
|
-
* @public
|
|
203
|
-
*/
|
|
204
|
-
uuid?: string
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Validation options for elements inside the component
|
|
208
|
-
* @public
|
|
209
|
-
*/
|
|
210
|
-
validation?: {
|
|
211
|
-
/**
|
|
212
|
-
* The error message to display when validation fails
|
|
213
|
-
* @public
|
|
214
|
-
*/
|
|
215
|
-
errorMessage: string
|
|
216
|
-
|
|
217
|
-
[key: string]: any
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Inline validation error messages to display on this field. Fed by the host
|
|
222
|
-
* (e.g. mapped from the core validation store) — the renderer stays dumb and just
|
|
223
|
-
* shows what it is given. Takes precedence over the static `validation.errorMessage`.
|
|
224
|
-
* @public
|
|
225
|
-
*/
|
|
226
|
-
errors?: string[]
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* The value shape for AFormLink — a linked document reference with optional display text
|
|
231
|
-
* @public
|
|
232
|
-
*/
|
|
233
|
-
export interface AFormLinkValue {
|
|
234
|
-
/** The FK/linked document ID. `id: 0` is a valid ID. */
|
|
235
|
-
id: string | number
|
|
236
|
-
/** Display text shown in the input. Falls back to `String(id)` if omitted. */
|
|
237
|
-
displayText?: string
|
|
238
|
-
/** Additional properties passed through to the underlying input component */
|
|
239
|
-
[extra: string]: any
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* What AFormLink accepts as its `v-model`.
|
|
244
|
-
*
|
|
245
|
-
* Wider than {@link AFormLinkValue} because a link is as often bound straight to its FK column as
|
|
246
|
-
* to a resolved reference: a record loaded from the DB carries the raw scalar, and a parent bound
|
|
247
|
-
* to that column coerces every update it receives back to a scalar. The component reads through
|
|
248
|
-
* `linkId`/`linkDisplayText`/`asLinkValue`, so all three shapes render and resolve identically.
|
|
249
|
-
*
|
|
250
|
-
* Emitting is narrower — AFormLink always writes back an {@link AFormLinkValue}.
|
|
251
|
-
* @public
|
|
252
|
-
*/
|
|
253
|
-
export type AFormLinkModelValue = AFormLinkValue | string | number
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* Navigation contract for AFormLink. Provide via `provide('aformLinkNavigator', ...)` in the app plugin.
|
|
257
|
-
* @public
|
|
258
|
-
*/
|
|
259
|
-
export interface AFormLinkNavigator {
|
|
260
|
-
/** Navigate to the linked document. Implementation is app-defined. */
|
|
261
|
-
navigate(doctype: string, id: string | number): void
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
/**
|
|
265
|
-
* The value shape for AQuantityInput — a quantity paired with its unit of measure, plus the
|
|
266
|
-
* derived stock-equivalent quantity/UOM. `conversionFactor` is carried on the value so it
|
|
267
|
-
* round-trips with the record even though it is never shown in the UI.
|
|
268
|
-
* @public
|
|
269
|
-
*/
|
|
270
|
-
export interface QuantityValue {
|
|
271
|
-
/** The entered quantity, in `uom` units */
|
|
272
|
-
qty: number
|
|
273
|
-
/** Unit of measure the user entered `qty` in */
|
|
274
|
-
uom: string
|
|
275
|
-
/** `qty` converted into `stockUom` units — `qty * conversionFactor` */
|
|
276
|
-
stockQty: number
|
|
277
|
-
/** The item's base/stock unit of measure — fixed, not user-editable */
|
|
278
|
-
stockUom: string
|
|
279
|
-
/** Multiplier from `uom` to `stockUom` — hidden from the UI, drives `stockQty` */
|
|
280
|
-
conversionFactor: number
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* Type-specific configuration for AQuantityInput, passed via the field's `options` property.
|
|
285
|
-
* @public
|
|
286
|
-
*/
|
|
287
|
-
export interface QuantityOptions {
|
|
288
|
-
/** Dropdown choices for the `uom` field */
|
|
289
|
-
uoms?: string[]
|
|
290
|
-
/** The item's base/stock unit of measure — fixed, not user-editable */
|
|
291
|
-
stockUom?: string
|
|
292
|
-
/** Conversion factor lookup for each non-stock UOM, relative to `stockUom` (which is implicitly `1`) */
|
|
293
|
-
conversionFactors?: Record<string, number>
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
/**
|
|
297
|
-
* The value shape for ACurrencyInput — an amount paired with its currency (an
|
|
298
|
-
* {@link AFormLinkValue} FK reference), plus the derived base-currency-equivalent amount.
|
|
299
|
-
* `exchangeRate` is carried on the value so it round-trips with the record even though it is
|
|
300
|
-
* never directly edited by the user.
|
|
301
|
-
* @public
|
|
302
|
-
*/
|
|
303
|
-
export interface CurrencyValue {
|
|
304
|
-
/** The entered amount, in `currency` units */
|
|
305
|
-
amount: number
|
|
306
|
-
/** FK reference to the Currency doctype the user entered `amount` in */
|
|
307
|
-
currency: AFormLinkValue
|
|
308
|
-
/** `amount` converted into `baseCurrency` units — `amount * exchangeRate` */
|
|
309
|
-
baseAmount: number
|
|
310
|
-
/** The record's base currency — fixed, not user-editable */
|
|
311
|
-
baseCurrency: AFormLinkValue
|
|
312
|
-
/** Multiplier from `currency` to `baseCurrency` — hidden from the UI, drives `baseAmount` */
|
|
313
|
-
exchangeRate: number
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
/**
|
|
317
|
-
* Type-specific configuration for ACurrencyInput, passed via the field's `options` property.
|
|
318
|
-
* @public
|
|
319
|
-
*/
|
|
320
|
-
export interface CurrencyOptions {
|
|
321
|
-
/** Currency doctype name, used for FK resolution via `aformLinkResolver`. The currency picker is embedded, so it renders no navigate button. */
|
|
322
|
-
doctype?: string
|
|
323
|
-
/** The record's base currency — fixed, not user-editable. A bare id resolves to displayText via `aformLinkResolver`. */
|
|
324
|
-
baseCurrency?: AFormLinkValue | string
|
|
325
|
-
/** Exchange rate lookup for each non-base currency id, relative to `baseCurrency` (which is implicitly `1`) */
|
|
326
|
-
exchangeRates?: Record<string, number>
|
|
327
|
-
/** Decimal places to round the derived `baseAmount` to — the base currency's scale (JPY carries 0, most carry 2, KWD 3). Applies only to `baseAmount`; the entered `amount` is left as typed. Omit to round only enough to shed binary floating-point noise, which never discards a digit the rate actually produced. A non-integer or out-of-range value falls back to that default. */
|
|
328
|
-
precision?: number
|
|
329
|
-
/** Search function backing the `currency` autocomplete dropdown — see AFormLink's `filterFunction` */
|
|
330
|
-
filterFunction?: string | ((search: string) => AFormLinkValue[] | Promise<AFormLinkValue[]>)
|
|
331
|
-
/** Whether `filterFunction` results should show a loading state — see AFormLink's `isAsync` */
|
|
332
|
-
isAsync?: boolean
|
|
333
|
-
}
|
package/src/utils/badge.ts
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import type { BadgeDescriptor, FieldOptions } from '@stonecrop/schema'
|
|
2
|
-
import { isBadgeDescriptor, lookupBadge } from '@stonecrop/schema'
|
|
3
|
-
|
|
4
|
-
import { deserializeFunction } from './deserialize'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Row context passed to badge `format` functions in form fields.
|
|
8
|
-
* @public
|
|
9
|
-
*/
|
|
10
|
-
export type BadgeFormatContext = {
|
|
11
|
-
record?: Record<string, unknown>
|
|
12
|
-
row?: Record<string, unknown>
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Badge-aware field `format` function signature.
|
|
17
|
-
* @public
|
|
18
|
-
*/
|
|
19
|
-
export type BadgeFormatFn = (value: unknown, context: BadgeFormatContext) => string | BadgeDescriptor
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Resolve a field value to a badge descriptor using format (if present) then options map.
|
|
23
|
-
* @public
|
|
24
|
-
*/
|
|
25
|
-
export function resolveFieldBadge(
|
|
26
|
-
value: unknown,
|
|
27
|
-
options: FieldOptions | undefined,
|
|
28
|
-
format: string | BadgeFormatFn | undefined,
|
|
29
|
-
context: BadgeFormatContext = {}
|
|
30
|
-
): BadgeDescriptor | undefined {
|
|
31
|
-
if (format) {
|
|
32
|
-
let formatted: unknown
|
|
33
|
-
if (typeof format === 'function') {
|
|
34
|
-
formatted = format(value, context)
|
|
35
|
-
} else {
|
|
36
|
-
const formatFn = deserializeFunction<BadgeFormatFn>(format)
|
|
37
|
-
formatted = formatFn(value, context)
|
|
38
|
-
}
|
|
39
|
-
if (isBadgeDescriptor(formatted)) {
|
|
40
|
-
const label = formatted.label.trim()
|
|
41
|
-
return label ? formatted : undefined
|
|
42
|
-
}
|
|
43
|
-
if (typeof formatted === 'string' && formatted !== '') {
|
|
44
|
-
return lookupBadge(options, formatted) ?? { label: formatted, variant: 'neutral' }
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const key = badgeLookupKey(value)
|
|
49
|
-
if (key === undefined) return undefined
|
|
50
|
-
return lookupBadge(options, key)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Stored choice value as an options-map key. Only primitives can match a declared choice, so
|
|
55
|
-
* anything else yields undefined rather than the '[object Object]' that String() would produce.
|
|
56
|
-
*/
|
|
57
|
-
function badgeLookupKey(value: unknown): string | undefined {
|
|
58
|
-
switch (typeof value) {
|
|
59
|
-
case 'string':
|
|
60
|
-
return value === '' ? undefined : value
|
|
61
|
-
case 'number':
|
|
62
|
-
case 'boolean':
|
|
63
|
-
case 'bigint':
|
|
64
|
-
return String(value)
|
|
65
|
-
default:
|
|
66
|
-
return undefined
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const BADGE_VARIANTS = new Set<string>(['neutral', 'success', 'warning', 'danger', 'brand'])
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* CSS custom properties for input-accent styling on a native input.
|
|
74
|
-
* @public
|
|
75
|
-
*/
|
|
76
|
-
export function badgeInputAccentStyle(descriptor: BadgeDescriptor | undefined): Record<string, string> | undefined {
|
|
77
|
-
if (!descriptor?.label?.trim()) return undefined
|
|
78
|
-
const variant = descriptor.variant ?? 'neutral'
|
|
79
|
-
if (descriptor.color) {
|
|
80
|
-
return {
|
|
81
|
-
borderLeftWidth: '4px',
|
|
82
|
-
borderLeftStyle: 'solid',
|
|
83
|
-
borderLeftColor: descriptor.color,
|
|
84
|
-
paddingLeft: 'calc(1ch - 4px)',
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
if (!BADGE_VARIANTS.has(variant)) return undefined
|
|
88
|
-
return {
|
|
89
|
-
borderLeftWidth: '4px',
|
|
90
|
-
borderLeftStyle: 'solid',
|
|
91
|
-
borderLeftColor: `var(--sc-badge-${variant}-accent)`,
|
|
92
|
-
paddingLeft: 'calc(1ch - 4px)',
|
|
93
|
-
}
|
|
94
|
-
}
|
package/src/utils/columns.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import type { ColumnSchema } from '@stonecrop/schema'
|
|
2
|
-
|
|
3
|
-
import type { ResolvedField } from '../types'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* The resolved fields that can be columns in a list or table view, in declaration order.
|
|
7
|
-
*
|
|
8
|
-
* A cell renders one value, so only `kind: 'field'` qualifies. The other three kinds are
|
|
9
|
-
* containers: a `fieldset` groups fields for layout and has no value of its own, while a `link`
|
|
10
|
-
* and a `table` hold a nested record and an array of them. Neither has a `cellComponent`, so a
|
|
11
|
-
* container reaching `ACell` falls through to plain-text rendering and stringifies its children —
|
|
12
|
-
* no error and no log, just a wrong column.
|
|
13
|
-
*
|
|
14
|
-
* A fieldset's *children* are real columns, so it is flattened rather than dropped; losing them is
|
|
15
|
-
* the same silent defect in the other direction.
|
|
16
|
-
*
|
|
17
|
-
* One definition, called by both consumers: `Registry.buildTableConfig` (a child table's columns,
|
|
18
|
-
* from its target's resolved schema) and Desktop's records list. Re-deriving it at either call
|
|
19
|
-
* site produced exactly one of the two failures above at each.
|
|
20
|
-
*
|
|
21
|
-
* @param fields - resolved fields, as produced by `resolveSchema`
|
|
22
|
-
* @returns column definitions, with the `kind` discriminator stripped
|
|
23
|
-
* @public
|
|
24
|
-
*/
|
|
25
|
-
export function resolvedFieldsToColumns(fields: readonly ResolvedField[]): ColumnSchema[] {
|
|
26
|
-
const columns: ColumnSchema[] = []
|
|
27
|
-
|
|
28
|
-
for (const field of fields) {
|
|
29
|
-
if (field.kind === 'fieldset') {
|
|
30
|
-
columns.push(...resolvedFieldsToColumns(field.schema))
|
|
31
|
-
} else if (field.kind === 'field') {
|
|
32
|
-
const { kind: _kind, ...column } = field
|
|
33
|
-
columns.push(column)
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return columns
|
|
38
|
-
}
|
package/src/utils/deserialize.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Deserializes a stringified function expression into a typed callable.
|
|
3
|
-
*
|
|
4
|
-
* Throws if the string cannot be parsed as a function (SyntaxError) or if the
|
|
5
|
-
* resulting expression is not callable (TypeError), or if the expression references
|
|
6
|
-
* an undefined variable (ReferenceError). Callers are responsible for try/catch.
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* ```ts
|
|
10
|
-
* const fn = deserializeFunction<(x: number) => number>('(x) => x * 2')
|
|
11
|
-
* fn(5) // 10
|
|
12
|
-
* ```
|
|
13
|
-
* @public
|
|
14
|
-
*/
|
|
15
|
-
// T is intentionally a caller-supplied return type — this utility is unsafe by design (Function constructor).
|
|
16
|
-
// oxlint-disable-next-line typescript/no-unnecessary-type-parameters
|
|
17
|
-
export function deserializeFunction<T extends (...args: any[]) => any>(source: string): T {
|
|
18
|
-
// oxlint-disable-next-line typescript/no-unsafe-type-assertion, typescript/no-implied-eval
|
|
19
|
-
return Function(`"use strict"; return (${source})`)() as T
|
|
20
|
-
}
|