@happyvertical/smrt-content 0.51.39 → 0.52.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 (72) hide show
  1. package/AGENTS.md +6 -0
  2. package/README.md +76 -0
  3. package/dist/body-format.d.ts +104 -0
  4. package/dist/body-format.d.ts.map +1 -1
  5. package/dist/body-format.js +439 -48
  6. package/dist/body-format.js.map +1 -1
  7. package/dist/chunks/content-query-BqLHbZYv.js +4131 -0
  8. package/dist/chunks/content-query-BqLHbZYv.js.map +1 -0
  9. package/dist/chunks/{content-versions-CvOoDLSK.js → content-versions-DatN0G28.js} +2 -2
  10. package/dist/chunks/{content-versions-CvOoDLSK.js.map → content-versions-DatN0G28.js.map} +1 -1
  11. package/dist/chunks/{contents-BB7RIBx2.js → contents-xas83N8M.js} +4 -6
  12. package/dist/chunks/contents-xas83N8M.js.map +1 -0
  13. package/dist/content-query.d.ts.map +1 -1
  14. package/dist/content.d.ts +13 -1
  15. package/dist/content.d.ts.map +1 -1
  16. package/dist/contents.d.ts.map +1 -1
  17. package/dist/index.d.ts +2 -2
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +6 -6
  20. package/dist/manifest.json +113 -23
  21. package/dist/server/content-list-data-surface.d.ts +1 -1
  22. package/dist/server/content-list-data-surface.d.ts.map +1 -1
  23. package/dist/server.js +3 -3
  24. package/dist/server.js.map +1 -1
  25. package/dist/smrt-knowledge.json +92 -10
  26. package/dist/svelte/components/ContentBodyEditor.svelte +898 -38
  27. package/dist/svelte/components/ContentBodyEditor.svelte.d.ts +67 -0
  28. package/dist/svelte/components/ContentBodyEditor.svelte.d.ts.map +1 -1
  29. package/dist/svelte/components/ContentBodyRenderer.svelte +36 -11
  30. package/dist/svelte/components/ContentBodyRenderer.svelte.d.ts +2 -0
  31. package/dist/svelte/components/ContentBodyRenderer.svelte.d.ts.map +1 -1
  32. package/dist/svelte/components/ContentClaimAuditTool.svelte +45 -2
  33. package/dist/svelte/components/ContentCorrectionsTool.svelte +24 -2
  34. package/dist/svelte/components/ContentEditor.svelte +67 -17
  35. package/dist/svelte/components/ContentEditor.svelte.d.ts +12 -0
  36. package/dist/svelte/components/ContentEditor.svelte.d.ts.map +1 -1
  37. package/dist/svelte/components/ContentGovernancePanel.svelte +4 -2
  38. package/dist/svelte/components/ContentMetadataFields.svelte +141 -51
  39. package/dist/svelte/components/ContentMetadataFields.svelte.d.ts +20 -0
  40. package/dist/svelte/components/ContentMetadataFields.svelte.d.ts.map +1 -1
  41. package/dist/svelte/components/ContentPictureDrawer.svelte +611 -0
  42. package/dist/svelte/components/ContentPictureDrawer.svelte.d.ts +68 -0
  43. package/dist/svelte/components/ContentPictureDrawer.svelte.d.ts.map +1 -0
  44. package/dist/svelte/components/ContentReviewStatusTray.svelte +2 -2
  45. package/dist/svelte/components/ContentStatusFields.svelte +85 -38
  46. package/dist/svelte/components/ContentStatusFields.svelte.d.ts +10 -0
  47. package/dist/svelte/components/ContentStatusFields.svelte.d.ts.map +1 -1
  48. package/dist/svelte/components/ContentTitleField.svelte +109 -12
  49. package/dist/svelte/components/ContentTitleField.svelte.d.ts +12 -0
  50. package/dist/svelte/components/ContentTitleField.svelte.d.ts.map +1 -1
  51. package/dist/svelte/components/ContentTransparencyReport.svelte +3 -1
  52. package/dist/svelte/components/ContentTransparencyTool.svelte +18 -3
  53. package/dist/svelte/components/ContentVersionsTool.svelte +26 -2
  54. package/dist/svelte/components/content-field-mode.d.ts +20 -0
  55. package/dist/svelte/components/content-field-mode.d.ts.map +1 -0
  56. package/dist/svelte/components/content-field-mode.js +26 -0
  57. package/dist/svelte/content-editor-media.d.ts +14 -0
  58. package/dist/svelte/content-editor-media.d.ts.map +1 -1
  59. package/dist/svelte/content-editor-media.js +41 -0
  60. package/dist/svelte/content-editor-state.svelte.d.ts +17 -0
  61. package/dist/svelte/content-editor-state.svelte.d.ts.map +1 -1
  62. package/dist/svelte/content-editor-state.svelte.js +46 -0
  63. package/dist/svelte/i18n.editor.d.ts +49 -0
  64. package/dist/svelte/i18n.editor.d.ts.map +1 -1
  65. package/dist/svelte/i18n.editor.js +53 -1
  66. package/dist/svelte/index.d.ts +10 -5
  67. package/dist/svelte/index.d.ts.map +1 -1
  68. package/dist/svelte/index.js +5 -3
  69. package/package.json +27 -25
  70. package/dist/chunks/content-query-DPJCcD1V.js +0 -4092
  71. package/dist/chunks/content-query-DPJCcD1V.js.map +0 -1
  72. package/dist/chunks/contents-BB7RIBx2.js.map +0 -1
@@ -1,7 +1,14 @@
1
1
  <script lang="ts">
2
- import { Input, Textarea } from '@happyvertical/smrt-ui/forms';
2
+ import { FormGroup, Input, Textarea } from '@happyvertical/smrt-ui/forms';
3
3
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
4
4
  import { M } from '../i18n.editor.js';
5
+ import {
6
+ type ContentFieldMode,
7
+ type ContentMetadataFieldName,
8
+ FULL_METADATA_FIELDS,
9
+ resolveContentFields,
10
+ SIMPLE_METADATA_FIELDS,
11
+ } from './content-field-mode.js';
5
12
 
6
13
  const { t } = useI18n();
7
14
 
@@ -17,16 +24,62 @@ export interface ContentMetadataFieldData {
17
24
  export interface Props {
18
25
  /** Current metadata field values. */
19
26
  data: ContentMetadataFieldData;
27
+ /**
28
+ * `full` (default) shows Author, Description, Tags, URL and File key;
29
+ * `simple` shows Author, Summary and Tags — each marked "(optional)" —
30
+ * inside a collapsed "Details" section.
31
+ */
32
+ mode?: ContentFieldMode;
33
+ /** Explicit allow-list of fields; overrides the mode's choice. */
34
+ fields?: readonly ContentMetadataFieldName[];
35
+ /**
36
+ * Wrap the fields in a "Details" disclosure. Defaults to collapsed in
37
+ * simple mode and off in full mode. Pass `{ open: true }` to start open,
38
+ * or `false` when the page supplies its own section.
39
+ */
40
+ details?: boolean | { open?: boolean; label?: string };
41
+ /** Prefix for field DOM ids, unique per editor on the page (default `content`). */
42
+ idPrefix?: string;
20
43
  /** Invoked when the user modifies any metadata field. */
21
44
  onChange?: (change: Record<string, unknown>) => void;
22
45
  }
23
46
 
24
- let { data, onChange = undefined }: Props = $props();
47
+ let {
48
+ data,
49
+ mode = 'full',
50
+ fields = undefined,
51
+ details = undefined,
52
+ idPrefix = 'content',
53
+ onChange = undefined,
54
+ }: Props = $props();
55
+
56
+ const simple = $derived(mode === 'simple');
57
+ const shown = $derived(
58
+ resolveContentFields(
59
+ mode,
60
+ fields,
61
+ SIMPLE_METADATA_FIELDS,
62
+ FULL_METADATA_FIELDS,
63
+ ),
64
+ );
65
+ const disclosure = $derived.by(() => {
66
+ const setting = details ?? simple;
67
+ if (setting === false) return null;
68
+ const options = typeof setting === 'object' ? setting : {};
69
+ return {
70
+ open: options.open ?? false,
71
+ label: options.label ?? t(M['content.content_fields.details']),
72
+ };
73
+ });
25
74
 
26
75
  const tagsValue = $derived(
27
76
  Array.isArray(data.tags) ? data.tags.join(', ') : String(data.tags || ''),
28
77
  );
29
78
 
79
+ function fieldLabel(label: string): string {
80
+ return simple ? t(M['content.content_fields.optional'], { label }) : label;
81
+ }
82
+
30
83
  function updateField(key: string, value: unknown) {
31
84
  onChange?.({ [key]: value });
32
85
  }
@@ -42,49 +95,80 @@ function updateTags(value: string) {
42
95
  }
43
96
  </script>
44
97
 
45
- <div class="content-metadata-fields">
46
- <label>
47
- <span>Author</span>
48
- <Input
49
- type="text"
50
- value={data.author || ''}
51
- oninput={(event) => updateField('author', event.currentTarget.value)}
52
- />
53
- </label>
54
- <label>
55
- <span>Description</span>
56
- <Textarea
57
- rows={4}
58
- value={data.description || ''}
59
- oninput={(event) => updateField('description', event.currentTarget.value)}
60
- ></Textarea>
61
- </label>
62
- <label>
63
- <span>Tags</span>
64
- <Input
65
- type="text"
66
- value={tagsValue}
67
- placeholder={t(M['content.content_metadata_fields.tags_placeholder'])}
68
- oninput={(event) => updateTags(event.currentTarget.value)}
69
- />
70
- </label>
71
- <label>
72
- <span>URL</span>
73
- <Input
74
- type="url"
75
- value={data.url || ''}
76
- oninput={(event) => updateField('url', event.currentTarget.value)}
77
- />
78
- </label>
79
- <label>
80
- <span>{t(M['content.content_metadata_fields.file_key'])}</span>
81
- <Input
82
- type="text"
83
- value={data.fileKey || ''}
84
- oninput={(event) => updateField('fileKey', event.currentTarget.value)}
85
- />
86
- </label>
87
- </div>
98
+ {#snippet metadataFields()}
99
+ <div class="content-metadata-fields">
100
+ {#if shown.has('author')}
101
+ <FormGroup label={fieldLabel(t(M['content.content_fields.author']))} id="{idPrefix}-author">
102
+ <Input
103
+ name="author"
104
+ type="text"
105
+ value={data.author || ''}
106
+ oninput={(event) => updateField('author', event.currentTarget.value)}
107
+ />
108
+ </FormGroup>
109
+ {/if}
110
+ {#if shown.has('description')}
111
+ <FormGroup
112
+ label={simple
113
+ ? fieldLabel(t(M['content.content_fields.summary']))
114
+ : t(M['content.content_fields.description'])}
115
+ hint={simple ? t(M['content.content_fields.summary_hint']) : undefined}
116
+ id="{idPrefix}-description"
117
+ >
118
+ <Textarea
119
+ name="description"
120
+ rows={simple ? 3 : 4}
121
+ value={data.description || ''}
122
+ oninput={(event) => updateField('description', event.currentTarget.value)}
123
+ ></Textarea>
124
+ </FormGroup>
125
+ {/if}
126
+ {#if shown.has('tags')}
127
+ <FormGroup
128
+ label={fieldLabel(t(M['content.content_fields.tags']))}
129
+ hint={simple ? t(M['content.content_fields.tags_hint']) : undefined}
130
+ id="{idPrefix}-tags"
131
+ >
132
+ <Input
133
+ name="tags"
134
+ type="text"
135
+ value={tagsValue}
136
+ placeholder={t(M['content.content_metadata_fields.tags_placeholder'])}
137
+ oninput={(event) => updateTags(event.currentTarget.value)}
138
+ />
139
+ </FormGroup>
140
+ {/if}
141
+ {#if shown.has('url')}
142
+ <FormGroup label={fieldLabel(t(M['content.content_fields.url']))} id="{idPrefix}-url">
143
+ <Input
144
+ name="url"
145
+ type="url"
146
+ value={data.url || ''}
147
+ oninput={(event) => updateField('url', event.currentTarget.value)}
148
+ />
149
+ </FormGroup>
150
+ {/if}
151
+ {#if shown.has('fileKey')}
152
+ <FormGroup label={fieldLabel(t(M['content.content_metadata_fields.file_key']))} id="{idPrefix}-file-key">
153
+ <Input
154
+ name="fileKey"
155
+ type="text"
156
+ value={data.fileKey || ''}
157
+ oninput={(event) => updateField('fileKey', event.currentTarget.value)}
158
+ />
159
+ </FormGroup>
160
+ {/if}
161
+ </div>
162
+ {/snippet}
163
+
164
+ {#if disclosure}
165
+ <details class="content-metadata-details" open={disclosure.open}>
166
+ <summary>{disclosure.label}</summary>
167
+ {@render metadataFields()}
168
+ </details>
169
+ {:else}
170
+ {@render metadataFields()}
171
+ {/if}
88
172
 
89
173
  <style>
90
174
  .content-metadata-fields {
@@ -92,12 +176,18 @@ function updateTags(value: string) {
92
176
  gap: 1rem;
93
177
  }
94
178
 
95
- label {
96
- display: grid;
97
- gap: 0.45rem;
98
- color: var(--smrt-color-on-surface-variant);
99
- font-size: var(--smrt-typography-label-large-size, 0.875rem);
100
- font-weight: var(--smrt-typography-weight-medium, 500);
179
+ .content-metadata-fields :global(.form-group) {
180
+ margin: 0;
181
+ }
182
+
183
+ .content-metadata-details > summary {
184
+ cursor: pointer;
185
+ padding-block: 0.5rem;
186
+ color: var(--smrt-color-on-surface);
187
+ font-weight: var(--smrt-typography-weight-semibold, 600);
101
188
  }
102
189
 
190
+ .content-metadata-details[open] > summary {
191
+ margin-bottom: 0.75rem;
192
+ }
103
193
  </style>
@@ -1,3 +1,4 @@
1
+ import { type ContentFieldMode, type ContentMetadataFieldName } from './content-field-mode.js';
1
2
  export interface ContentMetadataFieldData {
2
3
  author?: string;
3
4
  description?: string;
@@ -9,6 +10,25 @@ export interface ContentMetadataFieldData {
9
10
  export interface Props {
10
11
  /** Current metadata field values. */
11
12
  data: ContentMetadataFieldData;
13
+ /**
14
+ * `full` (default) shows Author, Description, Tags, URL and File key;
15
+ * `simple` shows Author, Summary and Tags — each marked "(optional)" —
16
+ * inside a collapsed "Details" section.
17
+ */
18
+ mode?: ContentFieldMode;
19
+ /** Explicit allow-list of fields; overrides the mode's choice. */
20
+ fields?: readonly ContentMetadataFieldName[];
21
+ /**
22
+ * Wrap the fields in a "Details" disclosure. Defaults to collapsed in
23
+ * simple mode and off in full mode. Pass `{ open: true }` to start open,
24
+ * or `false` when the page supplies its own section.
25
+ */
26
+ details?: boolean | {
27
+ open?: boolean;
28
+ label?: string;
29
+ };
30
+ /** Prefix for field DOM ids, unique per editor on the page (default `content`). */
31
+ idPrefix?: string;
12
32
  /** Invoked when the user modifies any metadata field. */
13
33
  onChange?: (change: Record<string, unknown>) => void;
14
34
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ContentMetadataFields.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/ContentMetadataFields.svelte.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,wBAAwB;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,KAAK;IACpB,qCAAqC;IACrC,IAAI,EAAE,wBAAwB,CAAC;IAC/B,yDAAyD;IACzD,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;CACtD;AA0DD,QAAA,MAAM,qBAAqB,2CAAwC,CAAC;AACpE,KAAK,qBAAqB,GAAG,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACtE,eAAe,qBAAqB,CAAC"}
1
+ {"version":3,"file":"ContentMetadataFields.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/ContentMetadataFields.svelte.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,wBAAwB,EAI9B,MAAM,yBAAyB,CAAC;AAGjC,MAAM,WAAW,wBAAwB;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,KAAK;IACpB,qCAAqC;IACrC,IAAI,EAAE,wBAAwB,CAAC;IAC/B;;;;OAIG;IACH,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,kEAAkE;IAClE,MAAM,CAAC,EAAE,SAAS,wBAAwB,EAAE,CAAC;IAC7C;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACvD,mFAAmF;IACnF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;CACtD;AA2GD,QAAA,MAAM,qBAAqB,2CAAwC,CAAC;AACpE,KAAK,qBAAqB,GAAG,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACtE,eAAe,qBAAqB,CAAC"}