@vit-foundation/ui 0.10.0 → 0.11.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.
@@ -20,3 +20,24 @@ export function pageCopyEdit(page, sectionKey, locale, options) {
20
20
  export function entityEdit(entity, id, locale) {
21
21
  return (field, options) => ({ ref: { kind: 'entity', entity, id, field }, locale, ...options });
22
22
  }
23
+ /**
24
+ * Property-descriptor factory for one entity's scalar fields — the panel
25
+ * sibling of `entityEdit`, naming the row once:
26
+ *
27
+ * const property = entityProperty('milestones', milestone.id);
28
+ * occurredOn: property('occurred_on', { type: 'date', label: 'Data' })
29
+ */
30
+ export function entityProperty(entity, id) {
31
+ return (field, spec) => ({ ref: { kind: 'entity', entity, id, field }, ...spec });
32
+ }
33
+ /**
34
+ * A panel property over one interface-wording message — how strings that can
35
+ * never hold a caret (an `<option>` label, an input placeholder) still edit.
36
+ */
37
+ export function chromeProperty(key, spec) {
38
+ return { ref: { kind: 'chrome', key }, ...spec };
39
+ }
40
+ /** Names one entity collection at one render site. */
41
+ export function collectionOf(entity, scope) {
42
+ return scope === undefined ? { entity } : { entity, scope };
43
+ }
@@ -1,6 +1,12 @@
1
1
  export { getEditAdapter, setEditAdapter } from './context.js';
2
2
  export { default as ActionLabel } from './ActionLabel.svelte';
3
3
  export { default as Editable } from './Editable.svelte';
4
- export { chromeEdit, entityEdit, pageCopyEdit } from './helpers.js';
4
+ export { default as AddSlot } from './chrome/AddSlot.svelte';
5
+ export { default as ConfirmDialog } from './chrome/ConfirmDialog.svelte';
6
+ export { default as EditFrame } from './chrome/EditFrame.svelte';
7
+ export type { EditFrameSpec } from './chrome/EditFrame.svelte';
8
+ export { default as EditPanel } from './chrome/EditPanel.svelte';
9
+ export { default as EditPopover } from './chrome/EditPopover.svelte';
10
+ export { chromeEdit, chromeProperty, collectionOf, entityEdit, entityProperty, pageCopyEdit } from './helpers.js';
5
11
  export { localize } from './types.js';
6
- export type { ContentRef, EditableEntity, EditAdapter, EditDescriptor, LocalizedText } from './types.js';
12
+ export type { CollectionRef, ContentRef, EditableEntity, EditAdapter, EditDescriptor, EntityOp, LocalizedText, PropertyDescriptor, PropertyOption, PropertyType } from './types.js';
@@ -1,5 +1,10 @@
1
1
  export { getEditAdapter, setEditAdapter } from './context.js';
2
2
  export { default as ActionLabel } from './ActionLabel.svelte';
3
3
  export { default as Editable } from './Editable.svelte';
4
- export { chromeEdit, entityEdit, pageCopyEdit } from './helpers.js';
4
+ export { default as AddSlot } from './chrome/AddSlot.svelte';
5
+ export { default as ConfirmDialog } from './chrome/ConfirmDialog.svelte';
6
+ export { default as EditFrame } from './chrome/EditFrame.svelte';
7
+ export { default as EditPanel } from './chrome/EditPanel.svelte';
8
+ export { default as EditPopover } from './chrome/EditPopover.svelte';
9
+ export { chromeEdit, chromeProperty, collectionOf, entityEdit, entityProperty, pageCopyEdit } from './helpers.js';
5
10
  export { localize } from './types.js';
@@ -51,9 +51,75 @@ export interface EditDescriptor {
51
51
  /** Accessible name for the edit control, e.g. "Títol del weekly #12". */
52
52
  label?: string;
53
53
  }
54
+ /**
55
+ * The value kinds a property panel can edit. Everything in this content model
56
+ * serializes to a string on the wire — an ISO date, a URL, an enum member, a
57
+ * storage path — so there is no typed value union: the ADAPTER parses, and
58
+ * the host's schemas stay the sole validators.
59
+ */
60
+ export type PropertyType = 'text' | 'url' | 'date' | 'select' | 'image';
61
+ /** One choice of a `select` property. */
62
+ export interface PropertyOption {
63
+ value: string;
64
+ label: string;
65
+ }
66
+ /**
67
+ * Identity + shape of one panel-edited property. Unlike `EditDescriptor`,
68
+ * `locale` is optional: dates, urls, enum members and image paths are not
69
+ * localized, and its absence says so to the adapter.
70
+ */
71
+ export interface PropertyDescriptor {
72
+ ref: ContentRef;
73
+ /** Present only for localized text properties. */
74
+ locale?: Locale;
75
+ type: PropertyType;
76
+ /** Panel row label — required, the panel renders it. */
77
+ label: string;
78
+ /** Required when `type` is 'select'. */
79
+ options?: readonly PropertyOption[];
80
+ placeholder?: string;
81
+ /** Clearing the field saves null (linkUrl, externalUrl). */
82
+ nullable?: boolean;
83
+ }
84
+ /**
85
+ * Names one entity collection at one render site. `scope` disambiguates when
86
+ * the same entity renders in several lists (a board grid vs. a full roster).
87
+ */
88
+ export interface CollectionRef {
89
+ entity: EditableEntity;
90
+ scope?: string;
91
+ }
92
+ /**
93
+ * A structural collection operation. Deliberately WITHOUT an `update` verb:
94
+ * field values always travel through `save`/`saveProperty` — one save path
95
+ * per value — and ops stay purely about existence and order.
96
+ */
97
+ export type EntityOp = {
98
+ kind: 'create';
99
+ collection: CollectionRef;
100
+ anchor?: {
101
+ id: string | number;
102
+ placement: 'before' | 'after';
103
+ };
104
+ } | {
105
+ kind: 'remove';
106
+ collection: CollectionRef;
107
+ id: string | number;
108
+ } | {
109
+ kind: 'reorder';
110
+ collection: CollectionRef;
111
+ id: string | number;
112
+ anchor: {
113
+ id: string | number;
114
+ placement: 'before' | 'after';
115
+ };
116
+ };
54
117
  /**
55
118
  * What a consuming app plugs in to make the components writable. The package
56
- * never talks to a database: `save` is the whole persistence contract.
119
+ * never talks to a database: `save` is the whole persistence contract for
120
+ * inline text, and the three OPTIONAL members below are the property-panel
121
+ * and structural halves — leave them off and the components render no panel
122
+ * or collection affordance at all, byte-identical to a read-only build.
57
123
  *
58
124
  * Implementations must:
59
125
  * - back `isEditing` with reactive state (`$state`) — it gates every edit
@@ -68,4 +134,18 @@ export interface EditDescriptor {
68
134
  export interface EditAdapter {
69
135
  readonly isEditing: boolean;
70
136
  save(descriptor: EditDescriptor, value: string): Promise<void>;
137
+ /**
138
+ * Panel property save. The value stays a string on the wire (ISO date,
139
+ * url, enum member, image path); `null` clears a `nullable` property.
140
+ */
141
+ saveProperty?(descriptor: PropertyDescriptor, value: string | null): Promise<void>;
142
+ /**
143
+ * Structural collection ops. `create` may resolve the new row's id so the
144
+ * UI can point at it after the host's refresh.
145
+ */
146
+ applyOp?(op: EntityOp): Promise<{
147
+ id?: string | number;
148
+ } | void>;
149
+ /** Image upload; resolves to the stored path an `image` property saves. */
150
+ uploadImage?(descriptor: PropertyDescriptor, file: File): Promise<string>;
71
151
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vit-foundation/ui",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "scripts": {
5
5
  "dev": "vite dev",
6
6
  "build": "vite build && npm run prepack",