@jarenjs/app 0.72.3 → 0.75.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.
@@ -69,15 +69,20 @@ export type FormViewOptions = {
69
69
  * - Remove-item button text (default `'×'`).
70
70
  */
71
71
  removeLabel?: string;
72
+ /**
73
+ * - Decorative required marker (default `'*'`).
74
+ */
75
+ requiredMarker?: string;
72
76
  /**
73
77
  * - Accessible
74
- * names for the two symbol buttons. `@jarenjs/forms`'
78
+ * names for the symbol buttons and the JSON editor's hint. `@jarenjs/forms`'
75
79
  * `formChromeLabels(catalog)` resolves them from a message catalog;
76
80
  * the English defaults apply when absent.
77
81
  */
78
82
  labels?: {
79
83
  addItem?: string;
80
84
  removeItem?: string;
85
+ jsonPlaceholder?: string;
81
86
  };
82
87
  /**
83
88
  * - (actions) JSON Pointer to the form
@@ -95,8 +100,9 @@ export type FormViewOptions = {
95
100
  * standard action names (`input`/`check`/`number`/`add`/`remove`).
96
101
  * @property {string} [addLabel] - Add-item button text (default `'+'`).
97
102
  * @property {string} [removeLabel] - Remove-item button text (default `'×'`).
98
- * @property {{addItem?: string, removeItem?: string}} [labels] - Accessible
99
- * names for the two symbol buttons. `@jarenjs/forms`'
103
+ * @property {string} [requiredMarker] - Decorative required marker (default `'*'`).
104
+ * @property {{addItem?: string, removeItem?: string, jsonPlaceholder?: string}} [labels] - Accessible
105
+ * names for the symbol buttons and the JSON editor's hint. `@jarenjs/forms`'
100
106
  * `formChromeLabels(catalog)` resolves them from a message catalog;
101
107
  * the English defaults apply when absent.
102
108
  * @property {string} [dataPointer] - (actions) JSON Pointer to the form
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@jarenjs/app",
3
3
  "private": false,
4
- "version": "0.72.3",
4
+ "version": "0.75.0",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
7
7
  "types": "./dist/types/index.d.ts",
@@ -50,8 +50,8 @@
50
50
  "prepack": "npm run build:types"
51
51
  },
52
52
  "dependencies": {
53
- "@jarenjs/core": "^0.72.3",
54
- "@jarenjs/json": "^0.72.3",
55
- "@jarenjs/view": "^0.72.3"
53
+ "@jarenjs/core": "^0.75.0",
54
+ "@jarenjs/json": "^0.75.0",
55
+ "@jarenjs/view": "^0.75.0"
56
56
  }
57
57
  }
package/src/forms.js CHANGED
@@ -88,8 +88,9 @@ export function formEventFields() {
88
88
  * standard action names (`input`/`check`/`number`/`add`/`remove`).
89
89
  * @property {string} [addLabel] - Add-item button text (default `'+'`).
90
90
  * @property {string} [removeLabel] - Remove-item button text (default `'×'`).
91
- * @property {{addItem?: string, removeItem?: string}} [labels] - Accessible
92
- * names for the two symbol buttons. `@jarenjs/forms`'
91
+ * @property {string} [requiredMarker] - Decorative required marker (default `'*'`).
92
+ * @property {{addItem?: string, removeItem?: string, jsonPlaceholder?: string}} [labels] - Accessible
93
+ * names for the symbol buttons and the JSON editor's hint. `@jarenjs/forms`'
93
94
  * `formChromeLabels(catalog)` resolves them from a message catalog;
94
95
  * the English defaults apply when absent.
95
96
  * @property {string} [dataPointer] - (actions) JSON Pointer to the form
@@ -108,7 +109,7 @@ export function createFormView(options = {}) {
108
109
  const root = options.root ?? '$.form';
109
110
  const cls = options.classPrefix ?? 'jaren-form';
110
111
  const act = { ...DEFAULT_ACTIONS, ...options.actions };
111
- const labels = { addItem: 'Add item', removeItem: 'Remove item', ...options.labels };
112
+ const labels = { addItem: 'Add item', removeItem: 'Remove item', jsonPlaceholder: 'Enter a JSON value', ...options.labels };
112
113
  /** Match any view-model node under `root` with the given control. */
113
114
  const ctl = (control) => `${root}..[?@.control == '${control}']`;
114
115
 
@@ -123,17 +124,17 @@ export function createFormView(options = {}) {
123
124
  type: 'button',
124
125
  class: `${cls}-remove`,
125
126
  // the glyph is decoration; the accessible name is the label
126
- 'aria-label': labels.removeItem,
127
- title: labels.removeItem,
127
+ 'aria-label': { $const: labels.removeItem },
128
+ title: { $const: labels.removeItem },
128
129
  disabled: writeDisabled,
129
130
  on: { click: { action: act.remove, with: { pointer: '$.pointer' } } },
130
- }, options.removeLabel ?? '×']] };
131
+ }, { $const: options.removeLabel ?? '×' }]] };
131
132
 
132
133
  /** The shared field chrome around one control vnode. */
133
134
  const field = (control) => ['div', { class: `${cls}-field`, 'data-pointer': '$.pointer' },
134
135
  ['label', {},
135
136
  '$.label',
136
- { $if: ['$.required', ['span', { class: `${cls}-required`, 'aria-hidden': 'true' }, ' *']] },
137
+ { $if: ['$.required', ['span', { class: `${cls}-required`, 'aria-hidden': 'true' }, { $const: ` ${options.requiredMarker ?? '*'}` }]] },
137
138
  control,
138
139
  ],
139
140
  { $if: ['$.description', ['p', { class: `${cls}-description` }, '$.description']] },
@@ -153,6 +154,7 @@ export function createFormView(options = {}) {
153
154
  placeholder: '$.placeholder',
154
155
  readonly: '$.readOnly',
155
156
  disabled,
157
+ 'aria-required': { $if: ['$.required', 'true'] },
156
158
  on: { input: { action, with: writeWith } },
157
159
  }];
158
160
 
@@ -170,6 +172,7 @@ export function createFormView(options = {}) {
170
172
  placeholder: '$.placeholder',
171
173
  readonly: '$.readOnly',
172
174
  disabled,
175
+ 'aria-required': { $if: ['$.required', 'true'] },
173
176
  min: '$.constraints.formatMinimum',
174
177
  max: '$.constraints.formatMaximum',
175
178
  on: { input: { action, with: writeWith } },
@@ -205,11 +208,11 @@ export function createFormView(options = {}) {
205
208
  ['button', {
206
209
  type: 'button',
207
210
  class: `${cls}-add`,
208
- 'aria-label': labels.addItem,
209
- title: labels.addItem,
211
+ 'aria-label': { $const: labels.addItem },
212
+ title: { $const: labels.addItem },
210
213
  disabled: writeDisabled,
211
214
  on: { click: { action: act.add, with: { pointer: '$.pointer', value: '$.addValue' } } },
212
- }, options.addLabel ?? '+']] },
215
+ }, { $const: options.addLabel ?? '+' }]] },
213
216
  [{ $apply: '$.errors[*]' }],
214
217
  remove,
215
218
  ],
@@ -229,6 +232,7 @@ export function createFormView(options = {}) {
229
232
  match: ctl('select'),
230
233
  body: field(['select', {
231
234
  disabled: writeDisabled,
235
+ 'aria-required': { $if: ['$.required', 'true'] },
232
236
  on: {
233
237
  change: { action: act.json, with: writeWith, event: [JSON_FIELD] },
234
238
  },
@@ -241,6 +245,7 @@ export function createFormView(options = {}) {
241
245
  type: 'checkbox',
242
246
  checked: '$.value',
243
247
  disabled: writeDisabled,
248
+ 'aria-required': { $if: ['$.required', 'true'] },
244
249
  on: { change: { action: act.check, with: writeWith } },
245
250
  }]),
246
251
  },
@@ -249,6 +254,7 @@ export function createFormView(options = {}) {
249
254
  match: ctl('textarea'),
250
255
  body: field(['textarea', {
251
256
  placeholder: '$.placeholder',
257
+ 'aria-required': { $if: ['$.required', 'true'] },
252
258
  readonly: '$.readOnly',
253
259
  disabled,
254
260
  on: { input: { action: act.input, with: writeWith } },
@@ -266,6 +272,9 @@ export function createFormView(options = {}) {
266
272
  class: `${cls}-json`,
267
273
  rows: 4,
268
274
  spellcheck: 'false',
275
+ placeholder: { $const: labels.jsonPlaceholder },
276
+ 'aria-description': { $const: labels.jsonPlaceholder },
277
+ 'aria-required': { $if: ['$.required', 'true'] },
269
278
  readonly: '$.readOnly',
270
279
  disabled,
271
280
  on: { change: { action: act.json, with: writeWith, event: [JSON_FIELD] } },