@dosgato/templating 0.0.70 → 0.0.72

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.
@@ -112,14 +112,9 @@ export declare abstract class Component<DataType extends ComponentData = any, Fe
112
112
  renderVariation(extension: string): string;
113
113
  /**
114
114
  * helper function to print an area's component list, but you can also override this if you
115
- * need to do something advanced like wrap each component in a div
115
+ * need to do something advanced
116
116
  */
117
- renderComponents(components?: RenderedComponent[] | string, opts?: {
118
- hideInheritBars?: boolean;
119
- skipBars?: boolean;
120
- skipContent?: boolean;
121
- editBarOpts?: RenderAreaEditBarOpts;
122
- }): string;
117
+ renderComponents(components?: RenderedComponent[] | string, opts?: RenderComponentsOpts): string;
123
118
  /**
124
119
  * helper function to print an area and set a minimum or maximum number of components
125
120
  *
@@ -131,17 +126,7 @@ export declare abstract class Component<DataType extends ComponentData = any, Fe
131
126
  * In that case you would call this.renderArea('areaname', { ..., skipEditBars: true }) first
132
127
  * and then this.renderArea('areaname', { ..., skipContent: true }) in another place.
133
128
  */
134
- renderArea(areaName: string, opts?: {
135
- min?: number;
136
- max?: number;
137
- hideMaxWarning?: boolean;
138
- maxWarning?: string;
139
- hideInheritBars?: boolean;
140
- skipBars?: boolean;
141
- skipContent?: boolean;
142
- newBarOpts?: NewBarOpts;
143
- editBarOpts?: RenderAreaEditBarOpts;
144
- }): string;
129
+ renderArea(areaName: string, opts?: RenderAreaOpts): string;
145
130
  /**
146
131
  * During rendering, each component should determine the CSS blocks that it needs. This may
147
132
  * change depending on the data. For instance, if you need some CSS to style up an image, but
@@ -285,12 +270,93 @@ export interface EditBarOpts extends BarOpts {
285
270
  hideEdit?: boolean;
286
271
  }
287
272
  export interface RenderAreaEditBarOpts extends Omit<Omit<EditBarOpts, 'label'>, 'extraClass'> {
273
+ /**
274
+ * Since renderArea and renderComponents render a whole list of components,
275
+ * they accept functions for editBarOpts.label and editBarOpts.extraClass
276
+ *
277
+ * This way you can have labels and classes depend on the data of the component.
278
+ */
288
279
  label?: string | ((c: Component) => string);
280
+ /**
281
+ * Since renderArea and renderComponents render a whole list of components,
282
+ * they accept functions for editBarOpts.label and editBarOpts.extraClass
283
+ *
284
+ * This way you can have labels and classes depend on the data of the component.
285
+ */
289
286
  extraClass?: string | ((c: Component) => string);
290
287
  }
291
288
  export interface NewBarOpts extends BarOpts {
292
289
  disabled?: boolean;
293
290
  }
291
+ export interface RenderComponentsOpts {
292
+ /**
293
+ * Hide bars entiredly for inherited items instead of allowing the user
294
+ * to link back to the creating page. Useful for headers and footers where it's
295
+ * obvious the entire site shares the data from the root page.
296
+ */
297
+ hideInheritBars?: boolean;
298
+ /**
299
+ * Do not print edit or new bars. Useful for components that have view-one-at-a-time
300
+ * subcomponents. If you don't move your editbars somewhere else, you'll be unable to
301
+ * re-order them easily.
302
+ */
303
+ skipBars?: boolean;
304
+ /**
305
+ * Do not print the content, only print edit and new bars. This is the other half
306
+ * of skipBars. You'd print bars in one place and content in another.
307
+ */
308
+ skipContent?: boolean;
309
+ /**
310
+ * Provide a function that wraps each component, e.g.
311
+ * (output: string) => `<li>${output}</li>`
312
+ *
313
+ * Note that the wrap will also go around the edit bar.
314
+ *
315
+ * If you need it (unlikely), the full component object is provided as a second parameter.
316
+ */
317
+ wrap?: (output: string, c: Component) => string;
318
+ /**
319
+ * Options for each edit bar; also accepts functions for label and extraClass
320
+ */
321
+ editBarOpts?: RenderAreaEditBarOpts;
322
+ }
323
+ export interface RenderAreaOpts extends RenderComponentsOpts {
324
+ /**
325
+ * Set a minimum number of components for the area.
326
+ *
327
+ * Enforcement of the minimum components is UI-only. It's possible for a
328
+ * page to be imported or updated via API with less than the minimum.
329
+ */
330
+ min?: number;
331
+ /**
332
+ * Set a maximum number of components for the area.
333
+ *
334
+ * Enforcement of the maximum components is UI-only. It's possible for a
335
+ * page to be imported or updated via API with more than the maximum.
336
+ */
337
+ max?: number;
338
+ /**
339
+ * Remove new bar when max is reached
340
+ *
341
+ * If you've set a max, the new bar will change to disabled and change its
342
+ * label when the max has been reached or exceeded. Set this true to completely
343
+ * remove the new bar instead.
344
+ */
345
+ hideMaxWarning?: boolean;
346
+ /**
347
+ * Set the maximum reached warning label
348
+ *
349
+ * If you've set a max, the new bar will change to disabled and change its
350
+ * label when the max has been reached or exceeded. Set this to adjust the
351
+ * wording of the maximum reached warning, when applicable.
352
+ */
353
+ maxWarning?: string;
354
+ /**
355
+ * Options to pass into the new bar. Note that some like 'disabled' will
356
+ * be overridden if you have set a max.
357
+ */
358
+ newBarOpts?: NewBarOpts;
359
+ }
294
360
  export interface RenderedComponent<C extends Component = Component> {
295
361
  component: C;
296
362
  output: string;
package/dist/component.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { isNotBlank } from 'txstate-utils';
2
2
  import { ResourceProvider } from './provider.js';
3
+ function defaultWrap(output) { return output; }
3
4
  /**
4
5
  * This is the primary templating class to build your templates. Subclass it and provide
5
6
  * at least a render function.
@@ -90,21 +91,22 @@ export class Component extends ResourceProvider {
90
91
  }
91
92
  /**
92
93
  * helper function to print an area's component list, but you can also override this if you
93
- * need to do something advanced like wrap each component in a div
94
+ * need to do something advanced
94
95
  */
95
96
  renderComponents(components = [], opts) {
96
97
  if (!Array.isArray(components))
97
98
  components = this.renderedAreas.get(components) ?? [];
99
+ const wrap = opts?.wrap ?? defaultWrap;
98
100
  if (opts?.skipBars)
99
- return components.map(c => c.output).join('');
101
+ return components.map(c => wrap(c.output, c.component)).join('');
100
102
  return components
101
- .flatMap(c => c.component.inheritedFrom && opts?.hideInheritBars
102
- ? [opts.skipContent ? '' : c.output]
103
- : [c.component.editBar({
103
+ .map(c => c.component.inheritedFrom && opts?.hideInheritBars
104
+ ? (opts.skipContent ? '' : wrap(c.output, c.component))
105
+ : wrap([c.component.editBar({
104
106
  ...opts?.editBarOpts,
105
107
  label: typeof opts?.editBarOpts?.label === 'function' ? opts.editBarOpts.label(c.component) : opts?.editBarOpts?.label,
106
108
  extraClass: typeof opts?.editBarOpts?.extraClass === 'function' ? opts.editBarOpts.extraClass(c.component) : opts?.editBarOpts?.extraClass
107
- }), opts?.skipContent ? '' : c.output]).join('');
109
+ }), opts?.skipContent ? '' : c.output].join(''), c.component)).join('');
108
110
  }
109
111
  /**
110
112
  * helper function to print an area and set a minimum or maximum number of components
@@ -121,7 +123,7 @@ export class Component extends ResourceProvider {
121
123
  const components = this.renderedAreas.get(areaName) ?? [];
122
124
  const ownedComponentCount = components.filter(c => !c.component.inheritedFrom).length;
123
125
  const full = !!(opts?.max && ownedComponentCount >= opts.max);
124
- let output = this.renderComponents(components, { hideInheritBars: opts?.hideInheritBars, skipBars: opts?.skipBars, skipContent: opts?.skipContent, editBarOpts: { ...opts?.editBarOpts, disableDelete: ownedComponentCount <= (opts?.min ?? 0), disableDrop: full } });
126
+ let output = this.renderComponents(components, { ...opts, editBarOpts: { ...opts?.editBarOpts, disableDelete: ownedComponentCount <= (opts?.min ?? 0), disableDrop: full } });
125
127
  if (!opts?.skipBars) {
126
128
  if (full) {
127
129
  if (!opts.hideMaxWarning)
@@ -186,7 +188,7 @@ export class Component extends ResourceProvider {
186
188
  editBar(opts = {}) {
187
189
  const options = { ...opts };
188
190
  options.label ?? (options.label = this.editLabel() ?? this.autoLabel);
189
- options.extraClass ?? (options.extraClass = this.editClass());
191
+ options.extraClass = [options.extraClass, this.editClass()].filter(isNotBlank).join(' ');
190
192
  options.editMode ?? (options.editMode = this.editMode);
191
193
  options.inheritedFrom ?? (options.inheritedFrom = this.inheritedFrom);
192
194
  options.hideEdit = this.noData || options.hideEdit;
@@ -200,7 +202,7 @@ export class Component extends ResourceProvider {
200
202
  newBar(areaName, opts = {}) {
201
203
  const options = { ...opts };
202
204
  options.label ?? (options.label = this.newLabel(areaName) ?? (this.areas.size > 1 ? `Add ${areaName} Content` : `Add ${this.autoLabel} Content`));
203
- options.extraClass ?? (options.extraClass = this.newClass(areaName));
205
+ options.extraClass = [options.extraClass, this.newClass(areaName)].filter(isNotBlank).join(' ');
204
206
  options.editMode ?? (options.editMode = this.editMode);
205
207
  return Component.newBar([this.path, 'areas', areaName].filter(isNotBlank).join('.'), options);
206
208
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dosgato/templating",
3
- "version": "0.0.70",
3
+ "version": "0.0.72",
4
4
  "description": "A library to support building templates for dosgato CMS.",
5
5
  "type": "module",
6
6
  "exports": {