<EventTimeInput>— date/time companion bound to the surrounding Pryv event'sevent.time. Honoursmandatory/allowNullfrom the host item'sdateTimeblock.<EventDurationInput>— duration companion bound toevent.duration. Four modes (No / Ongoing / Length / End time); honoursmandatory/allowNull/maxSeconds. Drives the newtreatment-{basic,coded}items' span without mutating event payload schemas (Pryv-native fields).<DatasetSearch>generalised — handles{drug}/{regimen}/{procedure}payload shapes uniformly. Companion fields render inline alongside the search field. Pre-filled companions are read-only when bound to a coded selection.- Item context (D3 mechanic) —
HDSFormSection.itemCustomizations[itemKey].contextpins an itemDef to a descendant streamId (e.g.procedure-fertility). The walk-up resolution lives inhds-lib'sforEvent(); cross-subtree contexts are rejected.
- Test app refactor (
src-test-app/): unified Single Field / Datasets panels; removed bespoke Plan 46 (D3) and Medication tabs. Test app now exercisesEventTimeInput/EventDurationInputvia item-driven companion rendering.
- Public API additions only; existing
<HDSFormField>/<HDSFormSection>callers are unaffected. - All 61 unit tests pass.
- New optional props
customFieldKeys: string[]+customFields: CustomFieldDeclaration[]. For each declared key the section builds aVirtualItemDefviaappTemplates.customFieldDeclarationToVirtualItem(decl)and renders through the existing<HDSFormField>. Custom-field form values are stored under__cf::{templateId}::{key}so they don't collide with canonical itemKeys.
CUSTOM_FIELD_KEY_PREFIX— agreed sentinel__cf::.customFieldFormKey(decl)—__cf::{templateId}::{key}formatter.isCustomFieldKey(key)— predicate for downstream filters.buildCustomFieldEntries(customFieldKeys, customFields) → Array<{ key, itemDef }>— converts a section's custom-field declarations into entries structurally compatible withformDataToActions/prefillFromEvents. Mixed canonical- custom-field arrays work without modification: both expose
data.streamId,data.eventTypeandeventTemplate().
- custom-field arrays work without modification: both expose
- Exports the four bridge helpers.
- VirtualItemDef shape contract per
note/txt | note/html | count/generic | date/iso-8601 | activity/plain. - Options → select rendering with
{value, label: { en }}shape. customFieldFormKey/isCustomFieldKey/CUSTOM_FIELD_KEY_PREFIXsemantics.buildCustomFieldEntriesselection + skip-unknown behaviour.- Round-trip:
formDataToActionscreate / update / delete actions for custom-field values, plusprefillFromEventsmatching by(streamId, eventType)and picking the most recent matching event. - Mixed canonical + custom-field round-trip — entries don't interfere.
Net: 57 tests passing (21 new this version, 36 pre-existing).
FormBuilderitem browser andItemSearchPickernow load itemDefs viamodel.itemsDefs.getAllActive()(introduced inhds-lib0.7.2) — items flaggeddeprecated: truein pack.json are no longer offered when a doctor is designing a new form. Existing forms still resolve every item correctly (readers useforKey/forEvent, which are unchanged).ItemSearchPickernow accepts an optionalincludeDeprecatedprop (defaultfalse) for engineer-facing tools (e.g. the data-model browser) that need to inspect every item.
Requires hds-lib ≥ 0.7.2. Contract documented in data-model/AGENTS.md § "deprecated: true on items".
exports[.].importswitched from./js/hds-forms.mjs(pre-built ESM bundle) to./src/index.ts(TS source).- Added wildcard subpath exports:
./src/*and./js/*so deep imports keep working. - Added
srcto"files"so the published package includes the TS source. defaultexport still points at the compiled bundle for non-Vite/CJS consumers.
Why. Vite resolves the import condition in dev mode. With the previous pre-built bundle as import, require("hds-lib") inside that bundle was bundled by esbuild into the consumer's chunk separately from the consumer's own import 'hds-lib', creating two HDSModel singletons → duplicate-singleton bug that broke Plan 45's mcp-chrome smoke test. Pointing import at TS source lets Vite resolve hds-lib once through its normal module graph + dedup. Production builds and CJS consumers are unaffected (still hit default).
This brings hds-forms-js in line with _claude-memory/conventions.md § Package exports: TS source for bundlers. See _plans/49-local-dev-dependency-graph-study/PLAN.md for the full root-cause analysis.
HDSFormField.labelOverridesnow accepts either a singleFieldLabelOverridesobject or an array ofFieldLabelOverridesWithSource[]. With a single override the rendering is unchanged. With an array of length > 1 the field renders one stacked block per override, each prefixed by a small caption identifying its source contact + form, all bound to the same value. This lets the patient app surface multiple forms requesting the same item (e.g. EQ-5D-5L wording from one doctor + a custom form from another) without losing either wording.FieldLabelOverrides,FieldLabelOverridesWithSource,ItemCustomizationare now type aliases re-exported fromhds-lib(appTemplates.ItemLabels,appTemplates.ItemLabelsWithSource,appTemplates.ItemCustomization) — single source of truth across forms-js / lib / consumer apps.
- New
type: sliderfield type. Numeric input on a bounded scale with optional display-layer scaling. Items declaremin,max,step; optionalslider.{orientation, labels, display{multiplier, precision, suffix}}. Storage is the raw value in the item'seventType; display is UI-only. Enables VAS-style inputs (e.g. raw0..1stored, shown as0..100). Horizontal by default; vertical opt-in. Includes ARIA slider pattern, per-tick label rendering, and paired numeric readout. - Form-level label overrides on the existing
section.itemCustomizationsbag (piggybacks onhds-lib's persistedCollectorRequestshape — zero schema change). NewFieldLabelOverridesandItemCustomizationtypes exported from the package index.HDSFormFieldaccepts a newlabelOverridesprop;HDSFormSectionextracts per-itemKey overrides and forwards them. Enables questionnaire-specific wording (e.g. EuroQol first-person sentences) to live in templates while the underlyingdata-modelitems stay generic and reusable.
FormBuilderpreview now forwardssection.itemCustomizationstoHDSFormSectionso label overrides are visible during form-builder editing (previously only available on published / invited-patient renders).
- Preview passed a synthetic section object to
HDSFormSectionthat omitteditemCustomizations; overrides were silently invisible in the builder preview.
ItemSearchPickercomponent — reusable searchable item picker with collapsible groups, counts, auto-expand on search. Exported from lib for use across apps.Convertible.tsxrewritten: method picker → observation dropdowns (Option B)- Loads converter engine, lists methods from model
preferred-input-{itemKey}setting hides method selector, shows method label_rawmethod shows dimension stop dropdowns- All labels localized via method definitions
NumberInputnow shows unit label (Kg/Lbs) based onunitSystemsetting + per-item variation overrideHDSFormFieldacceptsitemKeyprop for preferred API resolution- Test app: settings panel wired to
HDSSettings._testInject, converter preferences UI, HDS logo + docs link, ItemSearchPicker in Single Field tab
- Settings renamed:
converter-auto-→preferred-display-,converter-default-→preferred-input- - Convertible field value uses
vectorskey (wasdata)
convertibleitem type withConvertible.tsxfield component (dimension sliders + source display)ConvertibleDatainterface withconverter-enginefield in schema types
- Removed CNAME: publish at
healthdatasafe.github.io/hds-forms-js/
- Added
resolve.dedupeto prevent duplicate hds-lib singletons
- Support for
canBeNullin composite sub-fields - Settings tab to test app (Plan 11 preview)
- Switched to Vite library build, point types to source TS
- Removed
js/from git (rebuilt byprepareon install) - Bumped Node engine to
>=24
- Shared FormBuilder component with slot-based architecture
- Item browser: group by key prefix, show description on hover
- ReminderEditor component integrated into FormBuilder
- Companion field schema utilities (
getCompanionSchema,extractCompanionDefaults) - DatasetSearch edit mode with readonly pre-filled companion fields
- Form Builder PoC tab in test app (Phase 1c)
- Native variation/eventType support in
formDataToActions - DatasetSearch field component
- Simplified medication intake UI: removed frequency/asNeeded, inline layout
- Improved DatasetSearch: source filter, source tags, clear button
- Renamed package to
hds-forms-js, added TS exports for bundlers
- TypeScript types and ratio/generic options bug
.nojekylladded to deploy script for GitHub Pages
- Initial release
- HDS form rendering library
- Dynamic form generation from HDS data model definitions
- Deploy script for gh-pages publishing