@universityofmaryland/web-feeds-library 1.3.0-beta.0 → 1.3.0-beta.1

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 (207) hide show
  1. package/dist/academic.js +4 -4
  2. package/dist/academic.js.map +1 -1
  3. package/dist/events.js +10 -10
  4. package/dist/events.js.map +1 -1
  5. package/dist/experts.js +8 -8
  6. package/dist/experts.js.map +1 -1
  7. package/dist/factory/core/createBaseFeed.d.ts.map +1 -1
  8. package/dist/factory/core/createBaseFeed.js +19 -17
  9. package/dist/factory/core/createBaseFeed.js.map +1 -1
  10. package/dist/factory/core/types.d.ts +1 -0
  11. package/dist/factory/core/types.d.ts.map +1 -1
  12. package/dist/factory/helpers/displayHandler.js +29 -47
  13. package/dist/factory/helpers/displayHandler.js.map +1 -1
  14. package/dist/factory/helpers/feedHelpers.js +3 -3
  15. package/dist/factory/helpers/feedHelpers.js.map +1 -1
  16. package/dist/factory/helpers/fetchHandler.js +16 -33
  17. package/dist/factory/helpers/fetchHandler.js.map +1 -1
  18. package/dist/feeds/academic/index.d.ts +1 -1
  19. package/dist/feeds/academic/index.d.ts.map +1 -1
  20. package/dist/feeds/academic/slider.d.ts +1 -2
  21. package/dist/feeds/academic/slider.d.ts.map +1 -1
  22. package/dist/feeds/academic/slider.js +7 -6
  23. package/dist/feeds/academic/slider.js.map +1 -1
  24. package/dist/feeds/events/grid.d.ts +1 -2
  25. package/dist/feeds/events/grid.d.ts.map +1 -1
  26. package/dist/feeds/events/grid.js +22 -21
  27. package/dist/feeds/events/grid.js.map +1 -1
  28. package/dist/feeds/events/grouped.d.ts +1 -2
  29. package/dist/feeds/events/grouped.d.ts.map +1 -1
  30. package/dist/feeds/events/grouped.js +62 -78
  31. package/dist/feeds/events/grouped.js.map +1 -1
  32. package/dist/feeds/events/index.d.ts +4 -4
  33. package/dist/feeds/events/index.d.ts.map +1 -1
  34. package/dist/feeds/events/list.d.ts +1 -2
  35. package/dist/feeds/events/list.d.ts.map +1 -1
  36. package/dist/feeds/events/list.js +22 -21
  37. package/dist/feeds/events/list.js.map +1 -1
  38. package/dist/feeds/events/slider.d.ts +1 -2
  39. package/dist/feeds/events/slider.d.ts.map +1 -1
  40. package/dist/feeds/events/slider.js +7 -6
  41. package/dist/feeds/events/slider.js.map +1 -1
  42. package/dist/feeds/experts/_types.d.ts +2 -1
  43. package/dist/feeds/experts/_types.d.ts.map +1 -1
  44. package/dist/feeds/experts/bio.d.ts +1 -2
  45. package/dist/feeds/experts/bio.d.ts.map +1 -1
  46. package/dist/feeds/experts/bio.js +32 -31
  47. package/dist/feeds/experts/bio.js.map +1 -1
  48. package/dist/feeds/experts/grid.d.ts +1 -2
  49. package/dist/feeds/experts/grid.d.ts.map +1 -1
  50. package/dist/feeds/experts/grid.js +24 -23
  51. package/dist/feeds/experts/grid.js.map +1 -1
  52. package/dist/feeds/experts/index.d.ts +3 -3
  53. package/dist/feeds/experts/index.d.ts.map +1 -1
  54. package/dist/feeds/experts/list.d.ts +1 -2
  55. package/dist/feeds/experts/list.d.ts.map +1 -1
  56. package/dist/feeds/experts/list.js +23 -22
  57. package/dist/feeds/experts/list.js.map +1 -1
  58. package/dist/feeds/news/featured.d.ts +1 -2
  59. package/dist/feeds/news/featured.d.ts.map +1 -1
  60. package/dist/feeds/news/featured.js +56 -55
  61. package/dist/feeds/news/featured.js.map +1 -1
  62. package/dist/feeds/news/grid.d.ts +1 -2
  63. package/dist/feeds/news/grid.d.ts.map +1 -1
  64. package/dist/feeds/news/grid.js +24 -23
  65. package/dist/feeds/news/grid.js.map +1 -1
  66. package/dist/feeds/news/index.d.ts +3 -3
  67. package/dist/feeds/news/index.d.ts.map +1 -1
  68. package/dist/feeds/news/list.d.ts +1 -2
  69. package/dist/feeds/news/list.d.ts.map +1 -1
  70. package/dist/feeds/news/list.js +23 -22
  71. package/dist/feeds/news/list.js.map +1 -1
  72. package/dist/helpers/events/index.js +4 -4
  73. package/dist/helpers/events/index.js.map +1 -1
  74. package/dist/helpers/grouping/events.js +10 -10
  75. package/dist/helpers/grouping/events.js.map +1 -1
  76. package/dist/helpers/styles/shadow.js +5 -22
  77. package/dist/helpers/styles/shadow.js.map +1 -1
  78. package/dist/index.js +10 -10
  79. package/dist/index.js.map +1 -1
  80. package/dist/news.js +8 -8
  81. package/dist/news.js.map +1 -1
  82. package/dist/states/_types.d.ts +0 -24
  83. package/dist/states/_types.d.ts.map +1 -1
  84. package/dist/states/_types.js +3 -3
  85. package/dist/states/_types.js.map +1 -1
  86. package/dist/states/announcer.d.ts +1 -3
  87. package/dist/states/announcer.d.ts.map +1 -1
  88. package/dist/states/announcer.js +5 -5
  89. package/dist/states/announcer.js.map +1 -1
  90. package/dist/states/empty.d.ts +0 -2
  91. package/dist/states/empty.d.ts.map +1 -1
  92. package/dist/states/empty.js +15 -32
  93. package/dist/states/empty.js.map +1 -1
  94. package/dist/states/index.d.ts +4 -8
  95. package/dist/states/index.d.ts.map +1 -1
  96. package/dist/states/loading.d.ts +1 -3
  97. package/dist/states/loading.d.ts.map +1 -1
  98. package/dist/states/loading.js +16 -16
  99. package/dist/states/loading.js.map +1 -1
  100. package/dist/states/pagination.d.ts +1 -3
  101. package/dist/states/pagination.d.ts.map +1 -1
  102. package/dist/states/pagination.js +11 -28
  103. package/dist/states/pagination.js.map +1 -1
  104. package/dist/strategies/display/events.js +13 -13
  105. package/dist/strategies/display/events.js.map +1 -1
  106. package/dist/strategies/display/experts.js +23 -23
  107. package/dist/strategies/display/experts.js.map +1 -1
  108. package/dist/strategies/display/news.js +13 -13
  109. package/dist/strategies/display/news.js.map +1 -1
  110. package/dist/strategies/fetch/academic.js +3 -3
  111. package/dist/strategies/fetch/academic.js.map +1 -1
  112. package/dist/strategies/fetch/events.js +13 -13
  113. package/dist/strategies/fetch/events.js.map +1 -1
  114. package/dist/strategies/fetch/experts.d.ts +1 -1
  115. package/dist/strategies/fetch/experts.d.ts.map +1 -1
  116. package/dist/strategies/fetch/experts.js +13 -8
  117. package/dist/strategies/fetch/experts.js.map +1 -1
  118. package/dist/strategies/fetch/graphql.d.ts.map +1 -1
  119. package/dist/strategies/fetch/graphql.js +11 -7
  120. package/dist/strategies/fetch/graphql.js.map +1 -1
  121. package/dist/strategies/fetch/news.js +6 -6
  122. package/dist/strategies/fetch/news.js.map +1 -1
  123. package/dist/strategies/layout/grid.js +11 -11
  124. package/dist/strategies/layout/grid.js.map +1 -1
  125. package/dist/widgets/index.d.ts +1 -1
  126. package/dist/widgets/index.d.ts.map +1 -1
  127. package/dist/widgets/slider.d.ts +1 -2
  128. package/dist/widgets/slider.d.ts.map +1 -1
  129. package/dist/widgets/slider.js +19 -35
  130. package/dist/widgets/slider.js.map +1 -1
  131. package/package.json +15 -14
  132. package/dist/academic.mjs +0 -5
  133. package/dist/academic.mjs.map +0 -1
  134. package/dist/events.mjs +0 -11
  135. package/dist/events.mjs.map +0 -1
  136. package/dist/experts.mjs +0 -9
  137. package/dist/experts.mjs.map +0 -1
  138. package/dist/factory/core/createBaseFeed.mjs +0 -114
  139. package/dist/factory/core/createBaseFeed.mjs.map +0 -1
  140. package/dist/factory/helpers/displayHandler.mjs +0 -169
  141. package/dist/factory/helpers/displayHandler.mjs.map +0 -1
  142. package/dist/factory/helpers/feedHelpers.mjs +0 -32
  143. package/dist/factory/helpers/feedHelpers.mjs.map +0 -1
  144. package/dist/factory/helpers/fetchHandler.mjs +0 -123
  145. package/dist/factory/helpers/fetchHandler.mjs.map +0 -1
  146. package/dist/feeds/academic/slider.mjs +0 -11
  147. package/dist/feeds/academic/slider.mjs.map +0 -1
  148. package/dist/feeds/events/grid.mjs +0 -32
  149. package/dist/feeds/events/grid.mjs.map +0 -1
  150. package/dist/feeds/events/grouped.mjs +0 -337
  151. package/dist/feeds/events/grouped.mjs.map +0 -1
  152. package/dist/feeds/events/list.mjs +0 -33
  153. package/dist/feeds/events/list.mjs.map +0 -1
  154. package/dist/feeds/events/slider.mjs +0 -11
  155. package/dist/feeds/events/slider.mjs.map +0 -1
  156. package/dist/feeds/experts/bio.mjs +0 -147
  157. package/dist/feeds/experts/bio.mjs.map +0 -1
  158. package/dist/feeds/experts/grid.mjs +0 -37
  159. package/dist/feeds/experts/grid.mjs.map +0 -1
  160. package/dist/feeds/experts/list.mjs +0 -26
  161. package/dist/feeds/experts/list.mjs.map +0 -1
  162. package/dist/feeds/news/featured.mjs +0 -379
  163. package/dist/feeds/news/featured.mjs.map +0 -1
  164. package/dist/feeds/news/grid.mjs +0 -37
  165. package/dist/feeds/news/grid.mjs.map +0 -1
  166. package/dist/feeds/news/list.mjs +0 -34
  167. package/dist/feeds/news/list.mjs.map +0 -1
  168. package/dist/helpers/events/index.mjs +0 -21
  169. package/dist/helpers/events/index.mjs.map +0 -1
  170. package/dist/helpers/grouping/events.mjs +0 -147
  171. package/dist/helpers/grouping/events.mjs.map +0 -1
  172. package/dist/helpers/styles/shadow.mjs +0 -16
  173. package/dist/helpers/styles/shadow.mjs.map +0 -1
  174. package/dist/index.mjs +0 -11
  175. package/dist/index.mjs.map +0 -1
  176. package/dist/news.mjs +0 -9
  177. package/dist/news.mjs.map +0 -1
  178. package/dist/states/_types.mjs +0 -12
  179. package/dist/states/_types.mjs.map +0 -1
  180. package/dist/states/announcer.mjs +0 -62
  181. package/dist/states/announcer.mjs.map +0 -1
  182. package/dist/states/empty.mjs +0 -104
  183. package/dist/states/empty.mjs.map +0 -1
  184. package/dist/states/loading.mjs +0 -155
  185. package/dist/states/loading.mjs.map +0 -1
  186. package/dist/states/pagination.mjs +0 -102
  187. package/dist/states/pagination.mjs.map +0 -1
  188. package/dist/strategies/display/events.mjs +0 -60
  189. package/dist/strategies/display/events.mjs.map +0 -1
  190. package/dist/strategies/display/experts.mjs +0 -266
  191. package/dist/strategies/display/experts.mjs.map +0 -1
  192. package/dist/strategies/display/news.mjs +0 -58
  193. package/dist/strategies/display/news.mjs.map +0 -1
  194. package/dist/strategies/fetch/academic.mjs +0 -30
  195. package/dist/strategies/fetch/academic.mjs.map +0 -1
  196. package/dist/strategies/fetch/events.mjs +0 -223
  197. package/dist/strategies/fetch/events.mjs.map +0 -1
  198. package/dist/strategies/fetch/experts.mjs +0 -189
  199. package/dist/strategies/fetch/experts.mjs.map +0 -1
  200. package/dist/strategies/fetch/graphql.mjs +0 -100
  201. package/dist/strategies/fetch/graphql.mjs.map +0 -1
  202. package/dist/strategies/fetch/news.mjs +0 -95
  203. package/dist/strategies/fetch/news.mjs.map +0 -1
  204. package/dist/strategies/layout/grid.mjs +0 -36
  205. package/dist/strategies/layout/grid.mjs.map +0 -1
  206. package/dist/widgets/slider.mjs +0 -87
  207. package/dist/widgets/slider.mjs.map +0 -1
@@ -1,15 +1,14 @@
1
- "use strict";
2
- const webBuilderLibrary = require("@universityofmaryland/web-builder-library");
3
- const composite = require("@universityofmaryland/web-elements-library/composite");
4
- const layout = require("@universityofmaryland/web-elements-library/layout");
5
- const loading = require("../../states/loading.js");
6
- const empty = require("../../states/empty.js");
7
- const pagination = require("../../states/pagination.js");
8
- const announcer = require("../../states/announcer.js");
9
- const news = require("../../strategies/fetch/news.js");
10
- const news$1 = require("../../strategies/display/news.js");
11
- const index = require("../../helpers/events/index.js");
12
- const shadow = require("../../helpers/styles/shadow.js");
1
+ import { ElementBuilder } from "@universityofmaryland/web-builder-library";
2
+ import { card } from "@universityofmaryland/web-elements-library/composite";
3
+ import { gridOffset, gridGap } from "@universityofmaryland/web-elements-library/layout";
4
+ import { LoadingState } from "../../states/loading.js";
5
+ import { EmptyState } from "../../states/empty.js";
6
+ import { PaginationState } from "../../states/pagination.js";
7
+ import { Announcer } from "../../states/announcer.js";
8
+ import { newsFetchStrategy } from "../../strategies/fetch/news.js";
9
+ import { newsDisplayStrategy } from "../../strategies/display/news.js";
10
+ import { dispatch, eventNames } from "../../helpers/events/index.js";
11
+ import { setShadowStyles } from "../../helpers/styles/shadow.js";
13
12
  const INITIAL_ITEMS = 3;
14
13
  const LOAD_MORE_ITEMS = 2;
15
14
  const createFetchProps = (props, offset) => ({
@@ -57,8 +56,8 @@ class FeaturedFeedState {
57
56
  *
58
57
  * @param shadow - Shadow root element
59
58
  */
60
- setShadowRoot(shadow2) {
61
- this.shadowRoot = shadow2;
59
+ setShadowRoot(shadow) {
60
+ this.shadowRoot = shadow;
62
61
  }
63
62
  /**
64
63
  * Update shadow DOM styles
@@ -67,7 +66,7 @@ class FeaturedFeedState {
67
66
  */
68
67
  async updateShadowStyles() {
69
68
  if (!this.shadowRoot) return;
70
- await shadow.setShadowStyles({
69
+ await setShadowStyles({
71
70
  shadowRoot: this.shadowRoot,
72
71
  styles: this.getStyles()
73
72
  });
@@ -86,7 +85,7 @@ class FeaturedFeedState {
86
85
  * @returns Callback function for shadow root
87
86
  */
88
87
  getShadowCallback() {
89
- return (shadow2) => this.setShadowRoot(shadow2);
88
+ return (shadow) => this.setShadowRoot(shadow);
90
89
  }
91
90
  /**
92
91
  * Get current offset
@@ -155,12 +154,12 @@ class FeaturedFeedState {
155
154
  *
156
155
  * @param pagination - Pagination state
157
156
  */
158
- setPagination(pagination2) {
159
- this.pagination = pagination2;
157
+ setPagination(pagination) {
158
+ this.pagination = pagination;
160
159
  }
161
160
  }
162
161
  const createOverlayCard = (entry, state, isThemeDark) => {
163
- const overlayCard = news$1.newsDisplayStrategy.mapEntryToCard(entry, {
162
+ const overlayCard = newsDisplayStrategy.mapEntryToCard(entry, {
164
163
  isOverlay: true,
165
164
  isThemeDark,
166
165
  imageConfig: () => createImageConfig(entry)
@@ -168,11 +167,11 @@ const createOverlayCard = (entry, state, isThemeDark) => {
168
167
  state.addStyles(`
169
168
  ${overlayCard.styles}
170
169
 
171
- .${composite.card.overlay.imageClassRef} {
170
+ .${card.overlay.imageClassRef} {
172
171
  height: inherit;
173
172
  }
174
173
 
175
- .${composite.card.overlay.imageClassRef} .umd-asset-image-wrapper-scaled {
174
+ .${card.overlay.imageClassRef} .umd-asset-image-wrapper-scaled {
176
175
  position: absolute;
177
176
  }
178
177
  `);
@@ -180,7 +179,7 @@ const createOverlayCard = (entry, state, isThemeDark) => {
180
179
  };
181
180
  const createBlockCards = (entries, state, options) => {
182
181
  return entries.map((entry) => {
183
- const blockCard = news$1.newsDisplayStrategy.mapEntryToCard(entry, {
182
+ const blockCard = newsDisplayStrategy.mapEntryToCard(entry, {
184
183
  isThemeDark: options.isThemeDark,
185
184
  isTransparent: options.isTransparent,
186
185
  isAligned: true,
@@ -205,12 +204,12 @@ const renderFeaturedLayout = async (container, entries, state, props, loadMore)
205
204
  });
206
205
  }
207
206
  state.markOffsetRendered();
208
- const offsetLayout = layout.gridOffset({
207
+ const offsetLayout = gridOffset({
209
208
  columns: 2,
210
209
  isLayoutReversed,
211
210
  stickyTopPosition: overwriteStickyPosition
212
211
  });
213
- const gridLayout = layout.gridGap({ columns: 2 });
212
+ const gridLayout = gridGap({ columns: 2 });
214
213
  gridLayout.element.setAttribute("id", "umd-featured-news-grid-container");
215
214
  const overlayCard = createOverlayCard(entries[0], state, isThemeDark);
216
215
  const blockCards = createBlockCards(entries.slice(1, 3), state, {
@@ -227,23 +226,23 @@ const renderFeaturedLayout = async (container, entries, state, props, loadMore)
227
226
  state.addStyles(gridLayout.styles);
228
227
  state.setOffset(3);
229
228
  if (isLazyLoad && state.getTotalEntries() > state.getOffset()) {
230
- const pagination$1 = new pagination.PaginationState({
229
+ const pagination = new PaginationState({
231
230
  totalEntries: state.getTotalEntries(),
232
231
  offset: state.getOffset(),
233
232
  isLazyLoad: true,
234
233
  callback: loadMore
235
234
  });
236
- const paginationElement = pagination$1.render(container);
235
+ const paginationElement = pagination.render(container);
237
236
  if (paginationElement) state.addStyles(paginationElement.styles);
238
- state.setPagination(pagination$1);
237
+ state.setPagination(pagination);
239
238
  }
240
239
  const message = createAnnouncerMessage(
241
240
  INITIAL_ITEMS,
242
241
  state.getTotalEntries(),
243
242
  isLazyLoad
244
243
  );
245
- const announcer$1 = new announcer.Announcer({ message });
246
- container.appendChild(announcer$1.getElement());
244
+ const announcer = new Announcer({ message });
245
+ container.appendChild(announcer.getElement());
247
246
  await state.updateShadowStyles();
248
247
  };
249
248
  const renderStandardGrid = async (container, entries, state, options) => {
@@ -251,7 +250,7 @@ const renderStandardGrid = async (container, entries, state, options) => {
251
250
  "#umd-featured-news-grid-container"
252
251
  );
253
252
  if (!gridContainer) {
254
- const gridLayout = layout.gridGap({ columns: 2 });
253
+ const gridLayout = gridGap({ columns: 2 });
255
254
  gridLayout.element.setAttribute("id", "umd-featured-news-grid-container");
256
255
  container.appendChild(gridLayout.element);
257
256
  state.addStyles(gridLayout.styles);
@@ -265,12 +264,12 @@ const renderStandardGrid = async (container, entries, state, options) => {
265
264
  await state.updateShadowStyles();
266
265
  };
267
266
  const renderError = async (container, message, state, isThemeDark) => {
268
- const emptyState = new empty.EmptyState({ message, isThemeDark });
267
+ const emptyState = new EmptyState({ message, isThemeDark });
269
268
  emptyState.render(container);
270
269
  state.addStyles(emptyState.styles);
271
270
  await state.updateShadowStyles();
272
271
  };
273
- const featured = (props) => {
272
+ const newsFeatured = (props) => {
274
273
  const {
275
274
  token,
276
275
  categories,
@@ -279,33 +278,33 @@ const featured = (props) => {
279
278
  isLazyLoad = false,
280
279
  isTransparent = false
281
280
  } = props;
282
- const containerBuilder = new webBuilderLibrary.ElementBuilder("div").withClassName(
281
+ const containerBuilder = new ElementBuilder("div").withClassName(
283
282
  "featured-news-feed"
284
283
  );
285
284
  const container = containerBuilder.getElement();
286
- const loading$1 = new loading.LoadingState({ isThemeDark });
287
- const state = new FeaturedFeedState(loading$1.styles);
285
+ const loading = new LoadingState({ isThemeDark });
286
+ const state = new FeaturedFeedState(loading.styles);
288
287
  const loadMore = async () => {
289
- const pagination2 = state.getPagination();
290
- if (pagination2) {
291
- pagination2.remove();
288
+ const pagination = state.getPagination();
289
+ if (pagination) {
290
+ pagination.remove();
292
291
  }
293
- loading$1.show(container);
292
+ loading.show(container);
294
293
  const fetchProps = createFetchProps(
295
294
  { token, categories, isUnion },
296
295
  state.getOffset()
297
296
  );
298
- const variables = news.newsFetchStrategy.composeApiVariables(fetchProps);
299
- const entries = await news.newsFetchStrategy.fetchEntries(variables);
300
- loading$1.hide();
297
+ const variables = newsFetchStrategy.composeApiVariables(fetchProps);
298
+ const entries = await newsFetchStrategy.fetchEntries(variables);
299
+ loading.hide();
301
300
  if (!entries || entries.length === 0) return;
302
301
  await renderStandardGrid(container, entries, state, {
303
302
  isThemeDark,
304
303
  isTransparent
305
304
  });
306
- if (pagination2) {
307
- pagination2.updateState(state.getOffset(), state.getTotalEntries());
308
- if (pagination2.styles) state.addStyles(pagination2.styles);
305
+ if (pagination) {
306
+ pagination.updateState(state.getOffset(), state.getTotalEntries());
307
+ if (pagination.styles) state.addStyles(pagination.styles);
309
308
  await state.updateShadowStyles();
310
309
  }
311
310
  const existingAnnouncer = container.querySelector(
@@ -318,9 +317,9 @@ const featured = (props) => {
318
317
  isLazyLoad
319
318
  );
320
319
  }
321
- index.dispatch(
320
+ dispatch(
322
321
  container,
323
- index.eventNames.FEED_LOADED_MORE,
322
+ eventNames.FEED_LOADED_MORE,
324
323
  {
325
324
  items: entries,
326
325
  count: entries.length,
@@ -329,14 +328,14 @@ const featured = (props) => {
329
328
  );
330
329
  };
331
330
  const initialize = async () => {
332
- loading$1.show(container);
331
+ loading.show(container);
333
332
  const fetchProps = createFetchProps({ token, categories, isUnion }, 0);
334
- const variables = news.newsFetchStrategy.composeApiVariables(fetchProps);
333
+ const variables = newsFetchStrategy.composeApiVariables(fetchProps);
335
334
  const [count, entries] = await Promise.all([
336
- news.newsFetchStrategy.fetchCount(variables),
337
- news.newsFetchStrategy.fetchEntries(variables)
335
+ newsFetchStrategy.fetchCount(variables),
336
+ newsFetchStrategy.fetchEntries(variables)
338
337
  ]);
339
- loading$1.hide();
338
+ loading.hide();
340
339
  if (!entries || entries.length === 0) {
341
340
  await renderError(
342
341
  container,
@@ -347,7 +346,7 @@ const featured = (props) => {
347
346
  return;
348
347
  }
349
348
  state.setTotalEntries(count || entries.length);
350
- index.dispatch(container, index.eventNames.FEED_LOADED, {
349
+ dispatch(container, eventNames.FEED_LOADED, {
351
350
  items: entries,
352
351
  count: entries.length,
353
352
  total: state.getTotalEntries()
@@ -358,7 +357,7 @@ const featured = (props) => {
358
357
  const model = containerBuilder.build();
359
358
  const setPosition = (position) => {
360
359
  const overlayElement = container.querySelector(
361
- `.${composite.card.overlay.imageClassRef}`
360
+ `.${card.overlay.imageClassRef}`
362
361
  );
363
362
  if (overlayElement) overlayElement.style.top = `${position}px`;
364
363
  };
@@ -374,5 +373,7 @@ const featured = (props) => {
374
373
  }
375
374
  };
376
375
  };
377
- module.exports = featured;
376
+ export {
377
+ newsFeatured
378
+ };
378
379
  //# sourceMappingURL=featured.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"featured.js","sources":["../../../source/feeds/news/featured.ts"],"sourcesContent":["/**\n * News Featured Feed (Refactored with Element Builder)\n *\n * Displays news articles with a featured layout:\n * - First article: Large overlay card with sticky positioning\n * - Next 2 articles: Block cards in grid layout\n * - Additional articles: Lazy-loaded block cards\n *\n * Uses Element Builder pattern for clean, declarative construction.\n *\n * @module feeds/news/featured\n */\n\nimport { ElementBuilder } from '@universityofmaryland/web-builder-library';\nimport { card } from '@universityofmaryland/web-elements-library/composite';\nimport {\n gridGap,\n gridOffset,\n} from '@universityofmaryland/web-elements-library/layout';\nimport {\n LoadingState,\n PaginationState,\n EmptyState,\n Announcer,\n} from '../../states';\nimport { newsFetchStrategy } from '../../strategies/fetch/news';\nimport { newsDisplayStrategy } from '../../strategies/display/news';\nimport {\n events as eventUtilities,\n styles as styleUtilities,\n} from '../../helpers';\nimport { type FeaturedProps } from './_types';\nimport { type ElementModel } from '../../_types';\nimport { type NewsEntry } from 'types/data';\n\n// ============================================================================\n// CONSTANTS\n// ============================================================================\n\n/** Featured layout displays 3 items initially: 1 overlay + 2 block cards */\nconst INITIAL_ITEMS = 3;\n\n/** Lazy loading adds 2 items at a time to fill a row in the 2-column grid */\nconst LOAD_MORE_ITEMS = 2;\n\n// ============================================================================\n// PURE HELPER FUNCTIONS\n// ============================================================================\n\n/**\n * Create base props for fetch strategy\n *\n * @param props - Feed props\n * @param offset - Current offset\n * @returns Base props object for strategy's composeApiVariables\n */\nconst createFetchProps = (\n props: Pick<FeaturedProps, 'token' | 'categories' | 'isUnion'>,\n offset: number,\n) => ({\n token: props.token,\n categories: props.categories,\n isUnion: props.isUnion,\n numberOfRowsToStart: offset === 0 ? INITIAL_ITEMS : LOAD_MORE_ITEMS,\n numberOfColumnsToShow: 1,\n getOffset: () => offset,\n});\n\n/**\n * Create image configuration for news entry\n *\n * @param entry - News entry\n * @returns Image config object\n */\nconst createImageConfig = (entry: NewsEntry) => ({\n imageUrl: entry.image[0]?.url,\n altText: entry.image[0]?.altText || 'News Article Image',\n linkUrl: entry.url,\n linkLabel: 'Maryland Today Article with image',\n});\n\n/**\n * Create announcer message\n *\n * @param offset - Current offset\n * @param total - Total entries\n * @param isLazyLoad - Lazy load enabled\n * @returns Announcer message\n */\nconst createAnnouncerMessage = (\n offset: number,\n total: number,\n isLazyLoad: boolean,\n): string => {\n return isLazyLoad\n ? `Showing ${offset} of ${total} articles`\n : `Showing ${offset} articles`;\n};\n\n// ============================================================================\n// STATE MANAGER CLASS\n// ============================================================================\n\n/**\n * Manages featured feed state and shadow DOM synchronization\n *\n * Encapsulates all mutable state including pagination, offset,\n * and shadow DOM management.\n */\nclass FeaturedFeedState {\n private stylesArray: string[] = [];\n private shadowRoot: ShadowRoot | null = null;\n private totalEntries: number = 0;\n private offset: number = 0;\n private hasRenderedOffset: boolean = false;\n private pagination: PaginationState | null = null;\n\n /**\n * Initialize state with initial styles\n *\n * @param initialStyles - Initial CSS styles\n */\n constructor(initialStyles: string) {\n this.stylesArray.push(initialStyles);\n }\n\n /**\n * Add styles to the accumulated styles\n *\n * @param styles - CSS styles to add\n */\n addStyles(styles: string): void {\n this.stylesArray.push(styles);\n }\n\n /**\n * Set shadow root reference for style updates\n *\n * @param shadow - Shadow root element\n */\n setShadowRoot(shadow: ShadowRoot): void {\n this.shadowRoot = shadow;\n }\n\n /**\n * Update shadow DOM styles\n *\n * @returns Promise that resolves when styles are updated\n */\n async updateShadowStyles(): Promise<void> {\n if (!this.shadowRoot) return;\n await styleUtilities.setShadowStyles({\n shadowRoot: this.shadowRoot,\n styles: this.getStyles(),\n });\n }\n\n /**\n * Get accumulated styles as single string\n *\n * @returns Combined CSS styles\n */\n getStyles(): string {\n return this.stylesArray.join('\\n');\n }\n\n /**\n * Get shadow root callback for events\n *\n * @returns Callback function for shadow root\n */\n getShadowCallback(): (shadow: ShadowRoot) => void {\n return (shadow) => this.setShadowRoot(shadow);\n }\n\n /**\n * Get current offset\n *\n * @returns Current offset\n */\n getOffset(): number {\n return this.offset;\n }\n\n /**\n * Set offset to specific value\n *\n * @param value - New offset value\n */\n setOffset(value: number): void {\n this.offset = value;\n }\n\n /**\n * Increment offset by count\n *\n * @param count - Number to increment by\n */\n incrementOffset(count: number): void {\n this.offset += count;\n }\n\n /**\n * Get total entries\n *\n * @returns Total entries\n */\n getTotalEntries(): number {\n return this.totalEntries;\n }\n\n /**\n * Set total entries\n *\n * @param total - Total entries\n */\n setTotalEntries(total: number): void {\n this.totalEntries = total;\n }\n\n /**\n * Check if offset layout has been rendered\n *\n * @returns True if offset layout rendered\n */\n hasOffset(): boolean {\n return this.hasRenderedOffset;\n }\n\n /**\n * Mark offset layout as rendered\n */\n markOffsetRendered(): void {\n this.hasRenderedOffset = true;\n }\n\n /**\n * Get pagination state\n *\n * @returns Pagination state or null\n */\n getPagination(): PaginationState | null {\n return this.pagination;\n }\n\n /**\n * Set pagination state\n *\n * @param pagination - Pagination state\n */\n setPagination(pagination: PaginationState | null): void {\n this.pagination = pagination;\n }\n}\n\n// ============================================================================\n// RENDERING FUNCTIONS\n// ============================================================================\n\n/**\n * Create overlay card for featured entry\n *\n * @param entry - News entry\n * @param state - State manager\n * @param isThemeDark - Dark theme flag\n * @returns Overlay card element model\n */\nconst createOverlayCard = (\n entry: NewsEntry,\n state: FeaturedFeedState,\n isThemeDark: boolean,\n): ElementModel => {\n const overlayCard = newsDisplayStrategy.mapEntryToCard(entry, {\n isOverlay: true,\n isThemeDark,\n imageConfig: () => createImageConfig(entry),\n });\n\n // Add custom overlay styles\n state.addStyles(`\n ${overlayCard.styles}\n\n .${card.overlay.imageClassRef} {\n height: inherit;\n }\n\n .${card.overlay.imageClassRef} .umd-asset-image-wrapper-scaled {\n position: absolute;\n }\n `);\n\n return overlayCard;\n};\n\n/**\n * Create block cards for entries\n *\n * @param entries - News entries\n * @param state - State manager\n * @param options - Card options\n * @returns Array of block card element models\n */\nconst createBlockCards = (\n entries: NewsEntry[],\n state: FeaturedFeedState,\n options: { isThemeDark: boolean; isTransparent: boolean },\n): ElementModel[] => {\n return entries.map((entry) => {\n const blockCard = newsDisplayStrategy.mapEntryToCard(entry, {\n isThemeDark: options.isThemeDark,\n isTransparent: options.isTransparent,\n isAligned: true,\n imageConfig: () => createImageConfig(entry),\n });\n\n state.addStyles(blockCard.styles);\n return blockCard;\n });\n};\n\n/**\n * Render featured layout (initial load only)\n *\n * @param container - Container element\n * @param entries - News entries\n * @param state - State manager\n * @param props - Feed props\n * @param loadMore - Load more callback\n * @returns Promise that resolves when rendering is complete\n */\nconst renderFeaturedLayout = async (\n container: HTMLElement,\n entries: NewsEntry[],\n state: FeaturedFeedState,\n props: FeaturedProps,\n loadMore: () => Promise<void>,\n): Promise<void> => {\n const {\n isThemeDark = false,\n isTransparent = false,\n isLayoutReversed = false,\n overwriteStickyPosition,\n isLazyLoad = false,\n } = props;\n\n // Fall back to standard grid if not enough entries or already rendered\n if (entries.length < 2 || state.hasOffset()) {\n return renderStandardGrid(container, entries, state, {\n isThemeDark,\n isTransparent,\n });\n }\n\n state.markOffsetRendered();\n\n // Create offset layout\n const offsetLayout = gridOffset({\n columns: 2,\n isLayoutReversed,\n stickyTopPosition: overwriteStickyPosition,\n });\n\n // Create grid for remaining items\n const gridLayout = gridGap({ columns: 2 });\n gridLayout.element.setAttribute('id', 'umd-featured-news-grid-container');\n\n // First item: overlay card\n const overlayCard = createOverlayCard(entries[0], state, isThemeDark);\n\n // Next 2 items: block cards\n const blockCards = createBlockCards(entries.slice(1, 3), state, {\n isThemeDark,\n isTransparent,\n });\n\n // Append block cards to grid\n blockCards.forEach((card) => {\n gridLayout.element.appendChild(card.element);\n });\n\n // Assemble offset layout\n offsetLayout.element.appendChild(overlayCard.element);\n offsetLayout.element.appendChild(gridLayout.element);\n container.appendChild(offsetLayout.element);\n\n state.addStyles(offsetLayout.styles);\n state.addStyles(gridLayout.styles);\n state.setOffset(3); // We've shown 3 items\n\n // Add pagination if needed\n if (isLazyLoad && state.getTotalEntries() > state.getOffset()) {\n const pagination = new PaginationState({\n totalEntries: state.getTotalEntries(),\n offset: state.getOffset(),\n isLazyLoad: true,\n callback: loadMore,\n });\n\n const paginationElement = pagination.render(container);\n if (paginationElement) state.addStyles(paginationElement.styles);\n state.setPagination(pagination);\n }\n\n // Announcer\n const message = createAnnouncerMessage(\n INITIAL_ITEMS,\n state.getTotalEntries(),\n isLazyLoad,\n );\n const announcer = new Announcer({ message });\n container.appendChild(announcer.getElement());\n\n await state.updateShadowStyles();\n};\n\n/**\n * Render standard grid (for lazy-loaded items or fallback)\n *\n * @param container - Container element\n * @param entries - News entries\n * @param state - State manager\n * @param options - Rendering options\n * @returns Promise that resolves when rendering is complete\n */\nconst renderStandardGrid = async (\n container: HTMLElement,\n entries: NewsEntry[],\n state: FeaturedFeedState,\n options: { isThemeDark: boolean; isTransparent: boolean },\n): Promise<void> => {\n let gridContainer = container.querySelector(\n '#umd-featured-news-grid-container',\n ) as HTMLElement;\n\n // Create grid if it doesn't exist\n if (!gridContainer) {\n const gridLayout = gridGap({ columns: 2 });\n gridLayout.element.setAttribute('id', 'umd-featured-news-grid-container');\n container.appendChild(gridLayout.element);\n state.addStyles(gridLayout.styles);\n gridContainer = gridLayout.element;\n }\n\n // Create and append block cards\n const blockCards = createBlockCards(entries, state, options);\n blockCards.forEach((card) => {\n gridContainer.appendChild(card.element);\n });\n\n state.incrementOffset(entries.length);\n\n await state.updateShadowStyles();\n};\n\n/**\n * Render error state\n *\n * @param container - Container element\n * @param message - Error message\n * @param state - State manager\n * @param isThemeDark - Dark theme flag\n * @returns Promise that resolves when rendering is complete\n */\nconst renderError = async (\n container: HTMLElement,\n message: string,\n state: FeaturedFeedState,\n isThemeDark: boolean,\n): Promise<void> => {\n const emptyState = new EmptyState({ message, isThemeDark });\n emptyState.render(container);\n state.addStyles(emptyState.styles);\n await state.updateShadowStyles();\n};\n\n// ============================================================================\n// MAIN EXPORT\n// ============================================================================\n\n/**\n * Create a featured news feed\n *\n * Displays news with featured layout: overlay card + grid.\n * Uses Element Builder pattern for clean construction.\n *\n * @param props - Feed configuration\n * @returns ElementModel with feed element, styles, and events\n *\n * @example\n * ```typescript\n * const feed = newsFeatured({\n * token: 'my-token',\n * isLazyLoad: true,\n * });\n * ```\n *\n * @example\n * ```typescript\n * // With custom sticky position\n * const feed = newsFeatured({\n * token: 'my-token',\n * overwriteStickyPosition: 100,\n * isLayoutReversed: true,\n * });\n * ```\n */\nexport default (props: FeaturedProps): ElementModel => {\n const {\n token,\n categories,\n isUnion,\n isThemeDark = false,\n isLazyLoad = false,\n isTransparent = false,\n } = props;\n\n // Create container using ElementBuilder\n const containerBuilder = new ElementBuilder('div').withClassName(\n 'featured-news-feed',\n );\n\n // Get element for manipulation (non-destructive)\n const container = containerBuilder.getElement();\n\n // Initialize state management\n const loading = new LoadingState({ isThemeDark });\n const state = new FeaturedFeedState(loading.styles);\n\n /**\n * Load more articles (for lazy loading)\n */\n const loadMore = async (): Promise<void> => {\n // Remove pagination button\n const pagination = state.getPagination();\n if (pagination) {\n pagination.remove();\n }\n\n // Show loading indicator\n loading.show(container);\n\n // Load more items\n const fetchProps = createFetchProps(\n { token, categories, isUnion },\n state.getOffset(),\n );\n const variables = newsFetchStrategy.composeApiVariables(fetchProps);\n\n const entries = await newsFetchStrategy.fetchEntries(variables);\n\n // Hide loading indicator\n loading.hide();\n\n if (!entries || entries.length === 0) return;\n\n await renderStandardGrid(container, entries, state, {\n isThemeDark,\n isTransparent,\n });\n\n // Update pagination state\n if (pagination) {\n pagination.updateState(state.getOffset(), state.getTotalEntries());\n if (pagination.styles) state.addStyles(pagination.styles);\n await state.updateShadowStyles();\n }\n\n // Update announcer\n const existingAnnouncer = container.querySelector(\n '[role=\"status\"]',\n ) as HTMLElement;\n if (existingAnnouncer) {\n existingAnnouncer.textContent = createAnnouncerMessage(\n state.getOffset(),\n state.getTotalEntries(),\n isLazyLoad,\n );\n }\n\n // Dispatch update event\n eventUtilities.dispatch(\n container,\n eventUtilities.eventNames.FEED_LOADED_MORE,\n {\n items: entries,\n count: entries.length,\n total: state.getTotalEntries(),\n },\n );\n };\n\n /**\n * Initialize feed\n */\n const initialize = async (): Promise<void> => {\n loading.show(container);\n\n // Fetch initial items\n const fetchProps = createFetchProps({ token, categories, isUnion }, 0);\n const variables = newsFetchStrategy.composeApiVariables(fetchProps);\n\n const [count, entries] = await Promise.all([\n newsFetchStrategy.fetchCount(variables),\n newsFetchStrategy.fetchEntries(variables),\n ]);\n\n loading.hide();\n\n // Handle no results\n if (!entries || entries.length === 0) {\n await renderError(\n container,\n 'No news articles found',\n state,\n isThemeDark,\n );\n return;\n }\n\n state.setTotalEntries(count || entries.length);\n\n // Dispatch loaded event\n eventUtilities.dispatch(container, eventUtilities.eventNames.FEED_LOADED, {\n items: entries,\n count: entries.length,\n total: state.getTotalEntries(),\n });\n\n // Render featured layout\n await renderFeaturedLayout(container, entries, state, props, loadMore);\n };\n\n // Start initialization\n initialize();\n\n // Build and return element model\n const model = containerBuilder.build();\n\n // Custom event: allow external control of sticky position\n const setPosition = (position: number) => {\n const overlayElement = container.querySelector(\n `.${card.overlay.imageClassRef}`,\n ) as HTMLElement;\n if (overlayElement) overlayElement.style.top = `${position}px`;\n };\n\n return {\n element: model.element,\n get styles() {\n return state.getStyles();\n },\n events: {\n callback: state.getShadowCallback(),\n setPosition, // Custom event for sticky position control\n },\n };\n};\n"],"names":["shadow","styleUtilities.setShadowStyles","pagination","newsDisplayStrategy","card","gridOffset","gridGap","PaginationState","announcer","Announcer","EmptyState","ElementBuilder","loading","LoadingState","newsFetchStrategy","eventUtilities.dispatch","eventUtilities.eventNames"],"mappings":"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"}
1
+ {"version":3,"file":"featured.js","sources":["../../../source/feeds/news/featured.ts"],"sourcesContent":["/**\n * News Featured Feed (Refactored with Element Builder)\n *\n * Displays news articles with a featured layout:\n * - First article: Large overlay card with sticky positioning\n * - Next 2 articles: Block cards in grid layout\n * - Additional articles: Lazy-loaded block cards\n *\n * Uses Element Builder pattern for clean, declarative construction.\n *\n * @module feeds/news/featured\n */\n\nimport { ElementBuilder } from '@universityofmaryland/web-builder-library';\nimport { card } from '@universityofmaryland/web-elements-library/composite';\nimport {\n gridGap,\n gridOffset,\n} from '@universityofmaryland/web-elements-library/layout';\nimport {\n LoadingState,\n PaginationState,\n EmptyState,\n Announcer,\n} from '../../states';\nimport { newsFetchStrategy } from '../../strategies/fetch/news';\nimport { newsDisplayStrategy } from '../../strategies/display/news';\nimport {\n events as eventUtilities,\n styles as styleUtilities,\n} from '../../helpers';\nimport { type FeaturedProps } from './_types';\nimport { type ElementModel } from '../../_types';\nimport { type NewsEntry } from 'types/data';\n\n// ============================================================================\n// CONSTANTS\n// ============================================================================\n\n/** Featured layout displays 3 items initially: 1 overlay + 2 block cards */\nconst INITIAL_ITEMS = 3;\n\n/** Lazy loading adds 2 items at a time to fill a row in the 2-column grid */\nconst LOAD_MORE_ITEMS = 2;\n\n// ============================================================================\n// PURE HELPER FUNCTIONS\n// ============================================================================\n\n/**\n * Create base props for fetch strategy\n *\n * @param props - Feed props\n * @param offset - Current offset\n * @returns Base props object for strategy's composeApiVariables\n */\nconst createFetchProps = (\n props: Pick<FeaturedProps, 'token' | 'categories' | 'isUnion'>,\n offset: number,\n) => ({\n token: props.token,\n categories: props.categories,\n isUnion: props.isUnion,\n numberOfRowsToStart: offset === 0 ? INITIAL_ITEMS : LOAD_MORE_ITEMS,\n numberOfColumnsToShow: 1,\n getOffset: () => offset,\n});\n\n/**\n * Create image configuration for news entry\n *\n * @param entry - News entry\n * @returns Image config object\n */\nconst createImageConfig = (entry: NewsEntry) => ({\n imageUrl: entry.image[0]?.url,\n altText: entry.image[0]?.altText || 'News Article Image',\n linkUrl: entry.url,\n linkLabel: 'Maryland Today Article with image',\n});\n\n/**\n * Create announcer message\n *\n * @param offset - Current offset\n * @param total - Total entries\n * @param isLazyLoad - Lazy load enabled\n * @returns Announcer message\n */\nconst createAnnouncerMessage = (\n offset: number,\n total: number,\n isLazyLoad: boolean,\n): string => {\n return isLazyLoad\n ? `Showing ${offset} of ${total} articles`\n : `Showing ${offset} articles`;\n};\n\n// ============================================================================\n// STATE MANAGER CLASS\n// ============================================================================\n\n/**\n * Manages featured feed state and shadow DOM synchronization\n *\n * Encapsulates all mutable state including pagination, offset,\n * and shadow DOM management.\n */\nclass FeaturedFeedState {\n private stylesArray: string[] = [];\n private shadowRoot: ShadowRoot | null = null;\n private totalEntries: number = 0;\n private offset: number = 0;\n private hasRenderedOffset: boolean = false;\n private pagination: PaginationState | null = null;\n\n /**\n * Initialize state with initial styles\n *\n * @param initialStyles - Initial CSS styles\n */\n constructor(initialStyles: string) {\n this.stylesArray.push(initialStyles);\n }\n\n /**\n * Add styles to the accumulated styles\n *\n * @param styles - CSS styles to add\n */\n addStyles(styles: string): void {\n this.stylesArray.push(styles);\n }\n\n /**\n * Set shadow root reference for style updates\n *\n * @param shadow - Shadow root element\n */\n setShadowRoot(shadow: ShadowRoot): void {\n this.shadowRoot = shadow;\n }\n\n /**\n * Update shadow DOM styles\n *\n * @returns Promise that resolves when styles are updated\n */\n async updateShadowStyles(): Promise<void> {\n if (!this.shadowRoot) return;\n await styleUtilities.setShadowStyles({\n shadowRoot: this.shadowRoot,\n styles: this.getStyles(),\n });\n }\n\n /**\n * Get accumulated styles as single string\n *\n * @returns Combined CSS styles\n */\n getStyles(): string {\n return this.stylesArray.join('\\n');\n }\n\n /**\n * Get shadow root callback for events\n *\n * @returns Callback function for shadow root\n */\n getShadowCallback(): (shadow: ShadowRoot) => void {\n return (shadow) => this.setShadowRoot(shadow);\n }\n\n /**\n * Get current offset\n *\n * @returns Current offset\n */\n getOffset(): number {\n return this.offset;\n }\n\n /**\n * Set offset to specific value\n *\n * @param value - New offset value\n */\n setOffset(value: number): void {\n this.offset = value;\n }\n\n /**\n * Increment offset by count\n *\n * @param count - Number to increment by\n */\n incrementOffset(count: number): void {\n this.offset += count;\n }\n\n /**\n * Get total entries\n *\n * @returns Total entries\n */\n getTotalEntries(): number {\n return this.totalEntries;\n }\n\n /**\n * Set total entries\n *\n * @param total - Total entries\n */\n setTotalEntries(total: number): void {\n this.totalEntries = total;\n }\n\n /**\n * Check if offset layout has been rendered\n *\n * @returns True if offset layout rendered\n */\n hasOffset(): boolean {\n return this.hasRenderedOffset;\n }\n\n /**\n * Mark offset layout as rendered\n */\n markOffsetRendered(): void {\n this.hasRenderedOffset = true;\n }\n\n /**\n * Get pagination state\n *\n * @returns Pagination state or null\n */\n getPagination(): PaginationState | null {\n return this.pagination;\n }\n\n /**\n * Set pagination state\n *\n * @param pagination - Pagination state\n */\n setPagination(pagination: PaginationState | null): void {\n this.pagination = pagination;\n }\n}\n\n// ============================================================================\n// RENDERING FUNCTIONS\n// ============================================================================\n\n/**\n * Create overlay card for featured entry\n *\n * @param entry - News entry\n * @param state - State manager\n * @param isThemeDark - Dark theme flag\n * @returns Overlay card element model\n */\nconst createOverlayCard = (\n entry: NewsEntry,\n state: FeaturedFeedState,\n isThemeDark: boolean,\n): ElementModel => {\n const overlayCard = newsDisplayStrategy.mapEntryToCard(entry, {\n isOverlay: true,\n isThemeDark,\n imageConfig: () => createImageConfig(entry),\n });\n\n // Add custom overlay styles\n state.addStyles(`\n ${overlayCard.styles}\n\n .${card.overlay.imageClassRef} {\n height: inherit;\n }\n\n .${card.overlay.imageClassRef} .umd-asset-image-wrapper-scaled {\n position: absolute;\n }\n `);\n\n return overlayCard;\n};\n\n/**\n * Create block cards for entries\n *\n * @param entries - News entries\n * @param state - State manager\n * @param options - Card options\n * @returns Array of block card element models\n */\nconst createBlockCards = (\n entries: NewsEntry[],\n state: FeaturedFeedState,\n options: { isThemeDark: boolean; isTransparent: boolean },\n): ElementModel[] => {\n return entries.map((entry) => {\n const blockCard = newsDisplayStrategy.mapEntryToCard(entry, {\n isThemeDark: options.isThemeDark,\n isTransparent: options.isTransparent,\n isAligned: true,\n imageConfig: () => createImageConfig(entry),\n });\n\n state.addStyles(blockCard.styles);\n return blockCard;\n });\n};\n\n/**\n * Render featured layout (initial load only)\n *\n * @param container - Container element\n * @param entries - News entries\n * @param state - State manager\n * @param props - Feed props\n * @param loadMore - Load more callback\n * @returns Promise that resolves when rendering is complete\n */\nconst renderFeaturedLayout = async (\n container: HTMLElement,\n entries: NewsEntry[],\n state: FeaturedFeedState,\n props: FeaturedProps,\n loadMore: () => Promise<void>,\n): Promise<void> => {\n const {\n isThemeDark = false,\n isTransparent = false,\n isLayoutReversed = false,\n overwriteStickyPosition,\n isLazyLoad = false,\n } = props;\n\n // Fall back to standard grid if not enough entries or already rendered\n if (entries.length < 2 || state.hasOffset()) {\n return renderStandardGrid(container, entries, state, {\n isThemeDark,\n isTransparent,\n });\n }\n\n state.markOffsetRendered();\n\n // Create offset layout\n const offsetLayout = gridOffset({\n columns: 2,\n isLayoutReversed,\n stickyTopPosition: overwriteStickyPosition,\n });\n\n // Create grid for remaining items\n const gridLayout = gridGap({ columns: 2 });\n gridLayout.element.setAttribute('id', 'umd-featured-news-grid-container');\n\n // First item: overlay card\n const overlayCard = createOverlayCard(entries[0], state, isThemeDark);\n\n // Next 2 items: block cards\n const blockCards = createBlockCards(entries.slice(1, 3), state, {\n isThemeDark,\n isTransparent,\n });\n\n // Append block cards to grid\n blockCards.forEach((card) => {\n gridLayout.element.appendChild(card.element);\n });\n\n // Assemble offset layout\n offsetLayout.element.appendChild(overlayCard.element);\n offsetLayout.element.appendChild(gridLayout.element);\n container.appendChild(offsetLayout.element);\n\n state.addStyles(offsetLayout.styles);\n state.addStyles(gridLayout.styles);\n state.setOffset(3); // We've shown 3 items\n\n // Add pagination if needed\n if (isLazyLoad && state.getTotalEntries() > state.getOffset()) {\n const pagination = new PaginationState({\n totalEntries: state.getTotalEntries(),\n offset: state.getOffset(),\n isLazyLoad: true,\n callback: loadMore,\n });\n\n const paginationElement = pagination.render(container);\n if (paginationElement) state.addStyles(paginationElement.styles);\n state.setPagination(pagination);\n }\n\n // Announcer\n const message = createAnnouncerMessage(\n INITIAL_ITEMS,\n state.getTotalEntries(),\n isLazyLoad,\n );\n const announcer = new Announcer({ message });\n container.appendChild(announcer.getElement());\n\n await state.updateShadowStyles();\n};\n\n/**\n * Render standard grid (for lazy-loaded items or fallback)\n *\n * @param container - Container element\n * @param entries - News entries\n * @param state - State manager\n * @param options - Rendering options\n * @returns Promise that resolves when rendering is complete\n */\nconst renderStandardGrid = async (\n container: HTMLElement,\n entries: NewsEntry[],\n state: FeaturedFeedState,\n options: { isThemeDark: boolean; isTransparent: boolean },\n): Promise<void> => {\n let gridContainer = container.querySelector(\n '#umd-featured-news-grid-container',\n ) as HTMLElement;\n\n // Create grid if it doesn't exist\n if (!gridContainer) {\n const gridLayout = gridGap({ columns: 2 });\n gridLayout.element.setAttribute('id', 'umd-featured-news-grid-container');\n container.appendChild(gridLayout.element);\n state.addStyles(gridLayout.styles);\n gridContainer = gridLayout.element;\n }\n\n // Create and append block cards\n const blockCards = createBlockCards(entries, state, options);\n blockCards.forEach((card) => {\n gridContainer.appendChild(card.element);\n });\n\n state.incrementOffset(entries.length);\n\n await state.updateShadowStyles();\n};\n\n/**\n * Render error state\n *\n * @param container - Container element\n * @param message - Error message\n * @param state - State manager\n * @param isThemeDark - Dark theme flag\n * @returns Promise that resolves when rendering is complete\n */\nconst renderError = async (\n container: HTMLElement,\n message: string,\n state: FeaturedFeedState,\n isThemeDark: boolean,\n): Promise<void> => {\n const emptyState = new EmptyState({ message, isThemeDark });\n emptyState.render(container);\n state.addStyles(emptyState.styles);\n await state.updateShadowStyles();\n};\n\n// ============================================================================\n// MAIN EXPORT\n// ============================================================================\n\n/**\n * Create a featured news feed\n *\n * Displays news with featured layout: overlay card + grid.\n * Uses Element Builder pattern for clean construction.\n *\n * @param props - Feed configuration\n * @returns ElementModel with feed element, styles, and events\n *\n * @example\n * ```typescript\n * const feed = newsFeatured({\n * token: 'my-token',\n * isLazyLoad: true,\n * });\n * ```\n *\n * @example\n * ```typescript\n * // With custom sticky position\n * const feed = newsFeatured({\n * token: 'my-token',\n * overwriteStickyPosition: 100,\n * isLayoutReversed: true,\n * });\n * ```\n */\nexport const newsFeatured = (props: FeaturedProps): ElementModel => {\n const {\n token,\n categories,\n isUnion,\n isThemeDark = false,\n isLazyLoad = false,\n isTransparent = false,\n } = props;\n\n // Create container using ElementBuilder\n const containerBuilder = new ElementBuilder('div').withClassName(\n 'featured-news-feed',\n );\n\n // Get element for manipulation (non-destructive)\n const container = containerBuilder.getElement();\n\n // Initialize state management\n const loading = new LoadingState({ isThemeDark });\n const state = new FeaturedFeedState(loading.styles);\n\n /**\n * Load more articles (for lazy loading)\n */\n const loadMore = async (): Promise<void> => {\n // Remove pagination button\n const pagination = state.getPagination();\n if (pagination) {\n pagination.remove();\n }\n\n // Show loading indicator\n loading.show(container);\n\n // Load more items\n const fetchProps = createFetchProps(\n { token, categories, isUnion },\n state.getOffset(),\n );\n const variables = newsFetchStrategy.composeApiVariables(fetchProps);\n\n const entries = await newsFetchStrategy.fetchEntries(variables);\n\n // Hide loading indicator\n loading.hide();\n\n if (!entries || entries.length === 0) return;\n\n await renderStandardGrid(container, entries, state, {\n isThemeDark,\n isTransparent,\n });\n\n // Update pagination state\n if (pagination) {\n pagination.updateState(state.getOffset(), state.getTotalEntries());\n if (pagination.styles) state.addStyles(pagination.styles);\n await state.updateShadowStyles();\n }\n\n // Update announcer\n const existingAnnouncer = container.querySelector(\n '[role=\"status\"]',\n ) as HTMLElement;\n if (existingAnnouncer) {\n existingAnnouncer.textContent = createAnnouncerMessage(\n state.getOffset(),\n state.getTotalEntries(),\n isLazyLoad,\n );\n }\n\n // Dispatch update event\n eventUtilities.dispatch(\n container,\n eventUtilities.eventNames.FEED_LOADED_MORE,\n {\n items: entries,\n count: entries.length,\n total: state.getTotalEntries(),\n },\n );\n };\n\n /**\n * Initialize feed\n */\n const initialize = async (): Promise<void> => {\n loading.show(container);\n\n // Fetch initial items\n const fetchProps = createFetchProps({ token, categories, isUnion }, 0);\n const variables = newsFetchStrategy.composeApiVariables(fetchProps);\n\n const [count, entries] = await Promise.all([\n newsFetchStrategy.fetchCount(variables),\n newsFetchStrategy.fetchEntries(variables),\n ]);\n\n loading.hide();\n\n // Handle no results\n if (!entries || entries.length === 0) {\n await renderError(\n container,\n 'No news articles found',\n state,\n isThemeDark,\n );\n return;\n }\n\n state.setTotalEntries(count || entries.length);\n\n // Dispatch loaded event\n eventUtilities.dispatch(container, eventUtilities.eventNames.FEED_LOADED, {\n items: entries,\n count: entries.length,\n total: state.getTotalEntries(),\n });\n\n // Render featured layout\n await renderFeaturedLayout(container, entries, state, props, loadMore);\n };\n\n // Start initialization\n initialize();\n\n // Build and return element model\n const model = containerBuilder.build();\n\n // Custom event: allow external control of sticky position\n const setPosition = (position: number) => {\n const overlayElement = container.querySelector(\n `.${card.overlay.imageClassRef}`,\n ) as HTMLElement;\n if (overlayElement) overlayElement.style.top = `${position}px`;\n };\n\n return {\n element: model.element,\n get styles() {\n return state.getStyles();\n },\n events: {\n callback: state.getShadowCallback(),\n setPosition, // Custom event for sticky position control\n },\n };\n};\n"],"names":["styleUtilities.setShadowStyles","card","eventUtilities.dispatch","eventUtilities.eventNames"],"mappings":"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"}
@@ -1,5 +1,4 @@
1
1
  import { BlockProps } from './_types';
2
2
  import { ElementModel } from '../../_types';
3
- declare const _default: (props: BlockProps) => ElementModel;
4
- export default _default;
3
+ export declare const newsGrid: (props: BlockProps) => ElementModel;
5
4
  //# sourceMappingURL=grid.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"grid.d.ts","sourceRoot":"","sources":["../../../source/feeds/news/grid.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;yBA6BjC,OAAO,UAAU,KAAG,YAAY;AAAhD,wBAiBE"}
1
+ {"version":3,"file":"grid.d.ts","sourceRoot":"","sources":["../../../source/feeds/news/grid.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AA6BjD,eAAO,MAAM,QAAQ,GAAI,OAAO,UAAU,KAAG,YAiB5C,CAAC"}
@@ -1,29 +1,28 @@
1
- "use strict";
2
- const createBaseFeed = require("../../factory/core/createBaseFeed.js");
3
- require("@universityofmaryland/web-builder-library");
4
- require("@universityofmaryland/web-styles-library");
5
- require("@universityofmaryland/web-styles-library/typography");
6
- require("@universityofmaryland/web-utilities-library/theme");
7
- require("@universityofmaryland/web-elements-library");
8
- require("@universityofmaryland/web-elements-library/composite");
9
- require("@universityofmaryland/web-elements-library/atomic");
10
- require("@universityofmaryland/web-utilities-library/elements");
11
- const news$1 = require("../../strategies/display/news.js");
12
- require("@universityofmaryland/web-utilities-library/network");
13
- require("../../strategies/fetch/events.js");
14
- const news = require("../../strategies/fetch/news.js");
15
- require("../../strategies/fetch/experts.js");
16
- const grid$1 = require("../../strategies/layout/grid.js");
17
- require("@universityofmaryland/web-elements-library/layout");
18
- const grid = (props) => {
1
+ import { createBaseFeed } from "../../factory/core/createBaseFeed.js";
2
+ import "@universityofmaryland/web-builder-library";
3
+ import "@universityofmaryland/web-styles-library";
4
+ import "@universityofmaryland/web-styles-library/typography";
5
+ import "@universityofmaryland/web-utilities-library/theme";
6
+ import "@universityofmaryland/web-elements-library";
7
+ import "@universityofmaryland/web-elements-library/composite";
8
+ import "@universityofmaryland/web-elements-library/atomic";
9
+ import "@universityofmaryland/web-utilities-library/elements";
10
+ import { newsDisplayStrategy } from "../../strategies/display/news.js";
11
+ import "@universityofmaryland/web-utilities-library/network";
12
+ import "../../strategies/fetch/events.js";
13
+ import { newsFetchStrategy } from "../../strategies/fetch/news.js";
14
+ import "../../strategies/fetch/experts.js";
15
+ import { gridLayout, gridGapLayout } from "../../strategies/layout/grid.js";
16
+ import "@universityofmaryland/web-elements-library/layout";
17
+ const newsGrid = (props) => {
19
18
  const { isTypeOverlay = false } = props;
20
- return createBaseFeed.createBaseFeed({
19
+ return createBaseFeed({
21
20
  ...props,
22
21
  isOverlay: isTypeOverlay,
23
22
  isAligned: !isTypeOverlay,
24
- fetchStrategy: news.newsFetchStrategy,
25
- displayStrategy: news$1.newsDisplayStrategy,
26
- layoutStrategy: isTypeOverlay ? grid$1.gridLayout : grid$1.gridGapLayout,
23
+ fetchStrategy: newsFetchStrategy,
24
+ displayStrategy: newsDisplayStrategy,
25
+ layoutStrategy: isTypeOverlay ? gridLayout : gridGapLayout,
27
26
  imageConfig: (entry) => ({
28
27
  imageUrl: entry.image[0].url,
29
28
  altText: entry.image[0].altText || "News Article Image",
@@ -32,5 +31,7 @@ const grid = (props) => {
32
31
  })
33
32
  });
34
33
  };
35
- module.exports = grid;
34
+ export {
35
+ newsGrid
36
+ };
36
37
  //# sourceMappingURL=grid.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"grid.js","sources":["../../../source/feeds/news/grid.ts"],"sourcesContent":["/**\n * News Grid Feed (Factory Pattern)\n *\n * Grid layout for news article entries using the feed factory pattern.\n * This is the NEW implementation using factory + strategies.\n *\n * @module composite/news/grid-new\n */\n\nimport { createBaseFeed } from 'factory';\nimport {\n newsFetchStrategy,\n newsDisplayStrategy,\n gridLayout,\n gridGapLayout,\n} from 'strategies';\nimport { type BlockProps } from './_types';\nimport { type ElementModel } from '../../_types';\n\n/**\n * Create a news grid feed\n *\n * @param props - Feed configuration\n * @returns ElementModel with feed element and styles\n *\n * @example\n * ```typescript\n * // Standard grid with gap\n * const feed = newsGrid({\n * token: 'my-token',\n * numberOfColumnsToShow: 3,\n * numberOfRowsToStart: 2,\n * isLazyLoad: true,\n * });\n *\n * // Overlay grid\n * const overlayFeed = newsGrid({\n * token: 'my-token',\n * numberOfColumnsToShow: 3,\n * numberOfRowsToStart: 2,\n * isTypeOverlay: true,\n * });\n *\n * document.body.appendChild(feed.element);\n * ```\n */\nexport default (props: BlockProps): ElementModel => {\n const { isTypeOverlay = false } = props;\n\n return createBaseFeed({\n ...props,\n isOverlay: isTypeOverlay,\n isAligned: !isTypeOverlay,\n fetchStrategy: newsFetchStrategy,\n displayStrategy: newsDisplayStrategy,\n layoutStrategy: isTypeOverlay ? gridLayout : gridGapLayout,\n imageConfig: (entry) => ({\n imageUrl: entry.image[0].url,\n altText: entry.image[0].altText || 'News Article Image',\n linkUrl: entry.url,\n linkLabel: 'Maryland Today Article with image',\n }),\n });\n};\n"],"names":["createBaseFeed","newsFetchStrategy","newsDisplayStrategy","gridLayout","gridGapLayout"],"mappings":";;;;;;;;;;;;;;;;;AA8CA,MAAA,OAAe,CAAC,UAAoC;AAClD,QAAM,EAAE,gBAAgB,MAAA,IAAU;AAElC,SAAOA,8BAAe;AAAA,IACpB,GAAG;AAAA,IACH,WAAW;AAAA,IACX,WAAW,CAAC;AAAA,IACZ,eAAeC,KAAAA;AAAAA,IACf,iBAAiBC,OAAAA;AAAAA,IACjB,gBAAgB,gBAAgBC,OAAAA,aAAaC,OAAAA;AAAAA,IAC7C,aAAa,CAAC,WAAW;AAAA,MACvB,UAAU,MAAM,MAAM,CAAC,EAAE;AAAA,MACzB,SAAS,MAAM,MAAM,CAAC,EAAE,WAAW;AAAA,MACnC,SAAS,MAAM;AAAA,MACf,WAAW;AAAA,IAAA;AAAA,EACb,CACD;AACH;;"}
1
+ {"version":3,"file":"grid.js","sources":["../../../source/feeds/news/grid.ts"],"sourcesContent":["/**\n * News Grid Feed (Factory Pattern)\n *\n * Grid layout for news article entries using the feed factory pattern.\n * This is the NEW implementation using factory + strategies.\n *\n * @module composite/news/grid-new\n */\n\nimport { createBaseFeed } from 'factory';\nimport {\n newsFetchStrategy,\n newsDisplayStrategy,\n gridLayout,\n gridGapLayout,\n} from 'strategies';\nimport { type BlockProps } from './_types';\nimport { type ElementModel } from '../../_types';\n\n/**\n * Create a news grid feed\n *\n * @param props - Feed configuration\n * @returns ElementModel with feed element and styles\n *\n * @example\n * ```typescript\n * // Standard grid with gap\n * const feed = newsGrid({\n * token: 'my-token',\n * numberOfColumnsToShow: 3,\n * numberOfRowsToStart: 2,\n * isLazyLoad: true,\n * });\n *\n * // Overlay grid\n * const overlayFeed = newsGrid({\n * token: 'my-token',\n * numberOfColumnsToShow: 3,\n * numberOfRowsToStart: 2,\n * isTypeOverlay: true,\n * });\n *\n * document.body.appendChild(feed.element);\n * ```\n */\nexport const newsGrid = (props: BlockProps): ElementModel => {\n const { isTypeOverlay = false } = props;\n\n return createBaseFeed({\n ...props,\n isOverlay: isTypeOverlay,\n isAligned: !isTypeOverlay,\n fetchStrategy: newsFetchStrategy,\n displayStrategy: newsDisplayStrategy,\n layoutStrategy: isTypeOverlay ? gridLayout : gridGapLayout,\n imageConfig: (entry) => ({\n imageUrl: entry.image[0].url,\n altText: entry.image[0].altText || 'News Article Image',\n linkUrl: entry.url,\n linkLabel: 'Maryland Today Article with image',\n }),\n });\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AA8CO,MAAM,WAAW,CAAC,UAAoC;AAC3D,QAAM,EAAE,gBAAgB,MAAA,IAAU;AAElC,SAAO,eAAe;AAAA,IACpB,GAAG;AAAA,IACH,WAAW;AAAA,IACX,WAAW,CAAC;AAAA,IACZ,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,gBAAgB,gBAAgB,aAAa;AAAA,IAC7C,aAAa,CAAC,WAAW;AAAA,MACvB,UAAU,MAAM,MAAM,CAAC,EAAE;AAAA,MACzB,SAAS,MAAM,MAAM,CAAC,EAAE,WAAW;AAAA,MACnC,SAAS,MAAM;AAAA,MACf,WAAW;AAAA,IAAA;AAAA,EACb,CACD;AACH;"}
@@ -1,4 +1,4 @@
1
- export { default as featured } from './featured';
2
- export { default as grid } from './grid';
3
- export { default as list } from './list';
1
+ export { newsFeatured as featured } from './featured';
2
+ export { newsGrid as grid } from './grid';
3
+ export { newsList as list } from './list';
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../source/feeds/news/index.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,YAAY,CAAC;AAqBjD,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAC;AAoBzC,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../source/feeds/news/index.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,YAAY,IAAI,QAAQ,EAAE,MAAM,YAAY,CAAC;AAqBtD,OAAO,EAAE,QAAQ,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAC;AAoB1C,OAAO,EAAE,QAAQ,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAC"}
@@ -1,5 +1,4 @@
1
1
  import { ListProps } from './_types';
2
2
  import { ElementModel } from '../../_types';
3
- declare const _default: (props: ListProps) => ElementModel;
4
- export default _default;
3
+ export declare const newsList: (props: ListProps) => ElementModel;
5
4
  //# sourceMappingURL=list.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../source/feeds/news/list.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;yBAoBjC,OAAO,SAAS,KAAG,YAAY;AAA/C,wBAcK"}
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../source/feeds/news/list.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAoBjD,eAAO,MAAM,QAAQ,GAAI,OAAO,SAAS,KAAG,YAcxC,CAAC"}
@@ -1,27 +1,26 @@
1
- "use strict";
2
- const createBaseFeed = require("../../factory/core/createBaseFeed.js");
3
- require("@universityofmaryland/web-builder-library");
4
- require("@universityofmaryland/web-styles-library");
5
- require("@universityofmaryland/web-styles-library/typography");
6
- require("@universityofmaryland/web-utilities-library/theme");
7
- require("@universityofmaryland/web-elements-library");
8
- require("@universityofmaryland/web-elements-library/composite");
9
- require("@universityofmaryland/web-elements-library/atomic");
10
- require("@universityofmaryland/web-utilities-library/elements");
11
- const news$1 = require("../../strategies/display/news.js");
12
- require("@universityofmaryland/web-utilities-library/network");
13
- require("../../strategies/fetch/events.js");
14
- const news = require("../../strategies/fetch/news.js");
15
- require("../../strategies/fetch/experts.js");
16
- const grid = require("../../strategies/layout/grid.js");
17
- require("@universityofmaryland/web-elements-library/layout");
18
- const list = (props) => createBaseFeed.createBaseFeed({
1
+ import { createBaseFeed } from "../../factory/core/createBaseFeed.js";
2
+ import "@universityofmaryland/web-builder-library";
3
+ import "@universityofmaryland/web-styles-library";
4
+ import "@universityofmaryland/web-styles-library/typography";
5
+ import "@universityofmaryland/web-utilities-library/theme";
6
+ import "@universityofmaryland/web-elements-library";
7
+ import "@universityofmaryland/web-elements-library/composite";
8
+ import "@universityofmaryland/web-elements-library/atomic";
9
+ import "@universityofmaryland/web-utilities-library/elements";
10
+ import { newsDisplayStrategy } from "../../strategies/display/news.js";
11
+ import "@universityofmaryland/web-utilities-library/network";
12
+ import "../../strategies/fetch/events.js";
13
+ import { newsFetchStrategy } from "../../strategies/fetch/news.js";
14
+ import "../../strategies/fetch/experts.js";
15
+ import { stackedLayout } from "../../strategies/layout/grid.js";
16
+ import "@universityofmaryland/web-elements-library/layout";
17
+ const newsList = (props) => createBaseFeed({
19
18
  ...props,
20
19
  cardType: "list",
21
20
  isAligned: false,
22
- fetchStrategy: news.newsFetchStrategy,
23
- displayStrategy: news$1.newsDisplayStrategy,
24
- layoutStrategy: grid.stackedLayout,
21
+ fetchStrategy: newsFetchStrategy,
22
+ displayStrategy: newsDisplayStrategy,
23
+ layoutStrategy: stackedLayout,
25
24
  imageConfig: (entry) => ({
26
25
  imageUrl: entry.image[0].url,
27
26
  altText: entry.image[0].altText || "News Article Image",
@@ -29,5 +28,7 @@ const list = (props) => createBaseFeed.createBaseFeed({
29
28
  linkLabel: "Maryland Today Article with image"
30
29
  })
31
30
  });
32
- module.exports = list;
31
+ export {
32
+ newsList
33
+ };
33
34
  //# sourceMappingURL=list.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"list.js","sources":["../../../source/feeds/news/list.ts"],"sourcesContent":["/**\n * News List Feed (Factory Pattern)\n *\n * List layout for news article entries using the feed factory pattern.\n * This is the NEW implementation using factory + strategies.\n *\n * @module composite/news/list-new\n */\n\nimport { createBaseFeed } from 'factory';\nimport {\n newsFetchStrategy,\n newsDisplayStrategy,\n stackedLayout,\n} from 'strategies';\nimport { type ListProps } from './_types';\nimport { type ElementModel } from '../../_types';\n\n/**\n * Create a news list feed\n *\n * @param props - Feed configuration\n * @returns ElementModel with feed element and styles\n *\n * @example\n * ```typescript\n * const feed = newsList({\n * token: 'my-token',\n * numberOfRowsToStart: 5,\n * isLazyLoad: true,\n * categories: ['research', 'campus-life'],\n * });\n *\n * document.body.appendChild(feed.element);\n * ```\n */\nexport default (props: ListProps): ElementModel =>\n createBaseFeed({\n ...props,\n cardType: 'list',\n isAligned: false,\n fetchStrategy: newsFetchStrategy,\n displayStrategy: newsDisplayStrategy,\n layoutStrategy: stackedLayout,\n imageConfig: (entry) => ({\n imageUrl: entry.image[0].url,\n altText: entry.image[0].altText || 'News Article Image',\n linkUrl: entry.url,\n linkLabel: 'Maryland Today Article with image',\n }),\n });\n"],"names":["createBaseFeed","newsFetchStrategy","newsDisplayStrategy","stackedLayout"],"mappings":";;;;;;;;;;;;;;;;;AAoCA,MAAA,OAAe,CAAC,UACdA,eAAAA,eAAe;AAAA,EACb,GAAG;AAAA,EACH,UAAU;AAAA,EACV,WAAW;AAAA,EACX,eAAeC,KAAAA;AAAAA,EACf,iBAAiBC,OAAAA;AAAAA,EACjB,gBAAgBC,KAAAA;AAAAA,EAChB,aAAa,CAAC,WAAW;AAAA,IACvB,UAAU,MAAM,MAAM,CAAC,EAAE;AAAA,IACzB,SAAS,MAAM,MAAM,CAAC,EAAE,WAAW;AAAA,IACnC,SAAS,MAAM;AAAA,IACf,WAAW;AAAA,EAAA;AAEf,CAAC;;"}
1
+ {"version":3,"file":"list.js","sources":["../../../source/feeds/news/list.ts"],"sourcesContent":["/**\n * News List Feed (Factory Pattern)\n *\n * List layout for news article entries using the feed factory pattern.\n * This is the NEW implementation using factory + strategies.\n *\n * @module composite/news/list-new\n */\n\nimport { createBaseFeed } from 'factory';\nimport {\n newsFetchStrategy,\n newsDisplayStrategy,\n stackedLayout,\n} from 'strategies';\nimport { type ListProps } from './_types';\nimport { type ElementModel } from '../../_types';\n\n/**\n * Create a news list feed\n *\n * @param props - Feed configuration\n * @returns ElementModel with feed element and styles\n *\n * @example\n * ```typescript\n * const feed = newsList({\n * token: 'my-token',\n * numberOfRowsToStart: 5,\n * isLazyLoad: true,\n * categories: ['research', 'campus-life'],\n * });\n *\n * document.body.appendChild(feed.element);\n * ```\n */\nexport const newsList = (props: ListProps): ElementModel =>\n createBaseFeed({\n ...props,\n cardType: 'list',\n isAligned: false,\n fetchStrategy: newsFetchStrategy,\n displayStrategy: newsDisplayStrategy,\n layoutStrategy: stackedLayout,\n imageConfig: (entry) => ({\n imageUrl: entry.image[0].url,\n altText: entry.image[0].altText || 'News Article Image',\n linkUrl: entry.url,\n linkLabel: 'Maryland Today Article with image',\n }),\n });\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAoCO,MAAM,WAAW,CAAC,UACvB,eAAe;AAAA,EACb,GAAG;AAAA,EACH,UAAU;AAAA,EACV,WAAW;AAAA,EACX,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,aAAa,CAAC,WAAW;AAAA,IACvB,UAAU,MAAM,MAAM,CAAC,EAAE;AAAA,IACzB,SAAS,MAAM,MAAM,CAAC,EAAE,WAAW;AAAA,IACnC,SAAS,MAAM;AAAA,IACf,WAAW;AAAA,EAAA;AAEf,CAAC;"}
@@ -1,5 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
1
  const eventNames = {
4
2
  /** Triggered when a feed has finished loading its content */
5
3
  FEED_LOADED: "feed:loaded",
@@ -16,6 +14,8 @@ const dispatch = (element, eventName, detail) => {
16
14
  });
17
15
  return element.dispatchEvent(event);
18
16
  };
19
- exports.dispatch = dispatch;
20
- exports.eventNames = eventNames;
17
+ export {
18
+ dispatch,
19
+ eventNames
20
+ };
21
21
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../source/helpers/events/index.ts"],"sourcesContent":["/**\n * Event names supported by the feeds library.\n * These can be used for consistent event handling across implementations.\n */\nexport const eventNames = {\n /** Triggered when a feed has finished loading its content */\n FEED_LOADED: 'feed:loaded',\n\n /** Triggered when a feed loads more content (lazy loading/pagination) */\n FEED_LOADED_MORE: 'feed:loaded:more',\n\n /** Triggered when an error occurs during feed loading or processing */\n FEED_ERROR: 'feed:error',\n};\n\n/**\n * Custom event details for different feed events.\n */\nexport interface FeedEventDetails {\n /** Items in the feed that have been loaded */\n items?: any[];\n\n /** Error information if a feed failed to load */\n error?: Error | string;\n\n /** Information about a specific item that was clicked */\n item?: any;\n\n /** Additional custom data that may be included with any event */\n [key: string]: any;\n}\n\n/**\n * Dispatches a custom feed event on the specified element.\n *\n * @param element - The element to dispatch the event on\n * @param eventName - Name of the event to dispatch (use eventNames constants for consistency)\n * @param detail - Event details to include\n * @returns True if the event was dispatched successfully and not cancelled\n *\n * @example\n * ```typescript\n * import { events } from '@universityofmaryland/web-feeds-library/utilities';\n *\n * // Dispatch a feed loaded event\n * events.dispatch(feedContainer, events.eventNames.FEED_LOADED, { items: loadedItems });\n *\n * // Listen for feed loaded events\n * feedContainer.addEventListener(events.eventNames.FEED_LOADED, (event) => {\n * console.log('Feed loaded with', event.detail.items.length, 'items');\n * });\n * ```\n */\nexport const dispatch = (\n element: HTMLElement,\n eventName: string,\n detail: FeedEventDetails,\n): boolean => {\n const event = new CustomEvent(eventName, {\n detail,\n bubbles: true,\n cancelable: true,\n });\n\n return element.dispatchEvent(event);\n};\n\n/**\n * Adds an event listener for a specific feed event with proper TypeScript typings for the event detail.\n *\n * @param element - The element to attach the event listener to\n * @param eventName - Name of the event to listen for (use eventNames constants for consistency)\n * @param callback - Function to call when the event is triggered\n * @param options - Standard addEventListener options (capture, once, passive, etc.)\n * @returns A function that removes the event listener when called\n *\n * @example\n * ```typescript\n * import { events } from '@universityofmaryland/web-feeds-library/utilities';\n *\n * // Add a typed event listener\n * const removeListener = events.listen(\n * feedContainer,\n * events.eventNames.FEED_LOADED,\n * (detail) => console.log('Feed loaded with', detail.items.length, 'items')\n * );\n *\n * // Later, if needed:\n * removeListener();\n * ```\n */\nexport const listen = (\n element: HTMLElement,\n eventName: string,\n callback: (detail: FeedEventDetails) => void,\n options?: AddEventListenerOptions,\n): (() => void) => {\n const eventListener = (event: Event) => {\n const customEvent = event as CustomEvent<FeedEventDetails>;\n callback(customEvent.detail);\n };\n\n element.addEventListener(eventName, eventListener, options);\n\n return () => {\n element.removeEventListener(eventName, eventListener, options);\n };\n};\n"],"names":[],"mappings":";;AAIO,MAAM,aAAa;AAAA;AAAA,EAExB,aAAa;AAAA;AAAA,EAGb,kBAAkB;AAAA;AAAA,EAGlB,YAAY;AACd;AAwCO,MAAM,WAAW,CACtB,SACA,WACA,WACY;AACZ,QAAM,QAAQ,IAAI,YAAY,WAAW;AAAA,IACvC;AAAA,IACA,SAAS;AAAA,IACT,YAAY;AAAA,EAAA,CACb;AAED,SAAO,QAAQ,cAAc,KAAK;AACpC;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../source/helpers/events/index.ts"],"sourcesContent":["/**\n * Event names supported by the feeds library.\n * These can be used for consistent event handling across implementations.\n */\nexport const eventNames = {\n /** Triggered when a feed has finished loading its content */\n FEED_LOADED: 'feed:loaded',\n\n /** Triggered when a feed loads more content (lazy loading/pagination) */\n FEED_LOADED_MORE: 'feed:loaded:more',\n\n /** Triggered when an error occurs during feed loading or processing */\n FEED_ERROR: 'feed:error',\n};\n\n/**\n * Custom event details for different feed events.\n */\nexport interface FeedEventDetails {\n /** Items in the feed that have been loaded */\n items?: any[];\n\n /** Error information if a feed failed to load */\n error?: Error | string;\n\n /** Information about a specific item that was clicked */\n item?: any;\n\n /** Additional custom data that may be included with any event */\n [key: string]: any;\n}\n\n/**\n * Dispatches a custom feed event on the specified element.\n *\n * @param element - The element to dispatch the event on\n * @param eventName - Name of the event to dispatch (use eventNames constants for consistency)\n * @param detail - Event details to include\n * @returns True if the event was dispatched successfully and not cancelled\n *\n * @example\n * ```typescript\n * import { events } from '@universityofmaryland/web-feeds-library/utilities';\n *\n * // Dispatch a feed loaded event\n * events.dispatch(feedContainer, events.eventNames.FEED_LOADED, { items: loadedItems });\n *\n * // Listen for feed loaded events\n * feedContainer.addEventListener(events.eventNames.FEED_LOADED, (event) => {\n * console.log('Feed loaded with', event.detail.items.length, 'items');\n * });\n * ```\n */\nexport const dispatch = (\n element: HTMLElement,\n eventName: string,\n detail: FeedEventDetails,\n): boolean => {\n const event = new CustomEvent(eventName, {\n detail,\n bubbles: true,\n cancelable: true,\n });\n\n return element.dispatchEvent(event);\n};\n\n/**\n * Adds an event listener for a specific feed event with proper TypeScript typings for the event detail.\n *\n * @param element - The element to attach the event listener to\n * @param eventName - Name of the event to listen for (use eventNames constants for consistency)\n * @param callback - Function to call when the event is triggered\n * @param options - Standard addEventListener options (capture, once, passive, etc.)\n * @returns A function that removes the event listener when called\n *\n * @example\n * ```typescript\n * import { events } from '@universityofmaryland/web-feeds-library/utilities';\n *\n * // Add a typed event listener\n * const removeListener = events.listen(\n * feedContainer,\n * events.eventNames.FEED_LOADED,\n * (detail) => console.log('Feed loaded with', detail.items.length, 'items')\n * );\n *\n * // Later, if needed:\n * removeListener();\n * ```\n */\nexport const listen = (\n element: HTMLElement,\n eventName: string,\n callback: (detail: FeedEventDetails) => void,\n options?: AddEventListenerOptions,\n): (() => void) => {\n const eventListener = (event: Event) => {\n const customEvent = event as CustomEvent<FeedEventDetails>;\n callback(customEvent.detail);\n };\n\n element.addEventListener(eventName, eventListener, options);\n\n return () => {\n element.removeEventListener(eventName, eventListener, options);\n };\n};\n"],"names":[],"mappings":"AAIO,MAAM,aAAa;AAAA;AAAA,EAExB,aAAa;AAAA;AAAA,EAGb,kBAAkB;AAAA;AAAA,EAGlB,YAAY;AACd;AAwCO,MAAM,WAAW,CACtB,SACA,WACA,WACY;AACZ,QAAM,QAAQ,IAAI,YAAY,WAAW;AAAA,IACvC;AAAA,IACA,SAAS;AAAA,IACT,YAAY;AAAA,EAAA,CACb;AAED,SAAO,QAAQ,cAAc,KAAK;AACpC;"}