@openrails/contentkit-ui 0.101.1 → 0.103.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 (53) hide show
  1. package/README.md +36 -13
  2. package/dist/client/browser-reader-preferences.d.ts +8 -9
  3. package/dist/client/browser-reader-preferences.js +71 -63
  4. package/dist/client/browser-reader-preferences.js.map +1 -1
  5. package/dist/client/discovery.d.ts +3 -1
  6. package/dist/client/discovery.js +2 -2
  7. package/dist/client/discovery.js.map +1 -1
  8. package/dist/client/generated/routes.d.ts +2 -2
  9. package/dist/client/generated/routes.js +2 -1
  10. package/dist/client/generated/routes.js.map +1 -1
  11. package/dist/client/generated/wire.d.ts +5 -10
  12. package/dist/client/generated/wire.js.map +1 -1
  13. package/dist/client/http.d.ts +3 -4
  14. package/dist/client/http.js +7 -15
  15. package/dist/client/http.js.map +1 -1
  16. package/dist/client/index.d.ts +1 -1
  17. package/dist/client/reader-preferences.d.ts +2 -2
  18. package/dist/client/reader-preferences.js +2 -6
  19. package/dist/client/reader-preferences.js.map +1 -1
  20. package/dist/components/content/daily-releases.js +39 -43
  21. package/dist/components/content/daily-releases.js.map +1 -1
  22. package/dist/components/content/filters.d.ts +2 -6
  23. package/dist/components/content/filters.js +57 -66
  24. package/dist/components/content/filters.js.map +1 -1
  25. package/dist/components/content/index.d.ts +1 -0
  26. package/dist/components/content/reader-settings.d.ts +0 -1
  27. package/dist/components/content/reader-settings.js +1 -2
  28. package/dist/components/content/reader-settings.js.map +1 -1
  29. package/dist/components/content/release-date-picker.d.ts +16 -0
  30. package/dist/components/content/release-date-picker.js +65 -0
  31. package/dist/components/content/release-date-picker.js.map +1 -0
  32. package/dist/index.js +22 -21
  33. package/dist/locales/discovery/de.js +3 -0
  34. package/dist/locales/discovery/de.js.map +1 -1
  35. package/dist/locales/discovery/en.d.ts +3 -0
  36. package/dist/locales/discovery/en.js +3 -0
  37. package/dist/locales/discovery/en.js.map +1 -1
  38. package/dist/locales/discovery/es.js +3 -0
  39. package/dist/locales/discovery/es.js.map +1 -1
  40. package/dist/locales/discovery/ja.js +3 -0
  41. package/dist/locales/discovery/ja.js.map +1 -1
  42. package/dist/locales/discovery/ko.js +3 -0
  43. package/dist/locales/discovery/ko.js.map +1 -1
  44. package/dist/locales/discovery/zh.js +3 -0
  45. package/dist/locales/discovery/zh.js.map +1 -1
  46. package/dist/locales/en.d.ts +3 -0
  47. package/dist/react/discovery.d.ts +3 -5
  48. package/dist/react/discovery.js +42 -71
  49. package/dist/react/discovery.js.map +1 -1
  50. package/dist/react/provider.js +1 -4
  51. package/dist/react/provider.js.map +1 -1
  52. package/dist/styles.css +1 -1
  53. package/package.json +1 -1
@@ -48,13 +48,13 @@ function j({ query: e, initialVisible: t = 30, revealStep: o = 30, collapsePremi
48
48
  data: E.data,
49
49
  revision: j.revision + (j.identity === k ? 0 : 1)
50
50
  });
51
- let N = E.data ?? (j.identity === k ? j.data : void 0), F = !E.data && !!N, I = b(() => N?.days.filter((e) => e.contents.length || e.filtered_count > 0).sort((e, t) => t.date.localeCompare(e.date)) ?? [], [N]), L = A(t, 30);
51
+ let P = E.data ?? (j.identity === k ? j.data : void 0), F = !E.data && !!P, I = b(() => P?.days.filter((e) => e.contents.length || e.filtered_count > 0).sort((e, t) => t.date.localeCompare(e.date)) ?? [], [P]), L = A(t, 30);
52
52
  return /* @__PURE__ */ w(r, {
53
53
  appearance: p.appearance,
54
54
  className: T("grid gap-6 text-sm", p.className),
55
55
  "data-ckui": "daily-releases",
56
56
  "aria-busy": E.loading,
57
- children: [N && E.error && /* @__PURE__ */ w("div", {
57
+ children: [P && E.error && /* @__PURE__ */ w("div", {
58
58
  role: "alert",
59
59
  className: "grid justify-items-start gap-2",
60
60
  children: [/* @__PURE__ */ C("p", {
@@ -66,14 +66,14 @@ function j({ query: e, initialVisible: t = 30, revealStep: o = 30, collapsePremi
66
66
  onClick: E.reload,
67
67
  children: h.t("common.retry")
68
68
  })]
69
- }), E.loading && !N ? /* @__PURE__ */ C("div", {
69
+ }), E.loading && !P ? /* @__PURE__ */ C("div", {
70
70
  className: D.className,
71
71
  style: D.style,
72
72
  children: Array.from({ length: 6 }, (e, t) => /* @__PURE__ */ C(l, {
73
73
  className: p.aspectRatio === void 0 ? p.shape === "landscape" ? "aspect-video" : "aspect-[3/4]" : void 0,
74
74
  style: p.aspectRatio === void 0 ? void 0 : { aspectRatio: p.aspectRatio }
75
75
  }, t))
76
- }) : E.error && !N ? /* @__PURE__ */ w("div", {
76
+ }) : E.error && !P ? /* @__PURE__ */ w("div", {
77
77
  role: "alert",
78
78
  className: "grid justify-items-start gap-2",
79
79
  children: [/* @__PURE__ */ C("p", {
@@ -87,7 +87,7 @@ function j({ query: e, initialVisible: t = 30, revealStep: o = 30, collapsePremi
87
87
  })]
88
88
  }) : I.length ? I.map((e) => {
89
89
  let t = Math.min(L, e.contents.length);
90
- return L -= t, /* @__PURE__ */ C(P, {
90
+ return L -= t, /* @__PURE__ */ C(N, {
91
91
  day: e,
92
92
  pending: F,
93
93
  collapsePremium: c,
@@ -99,7 +99,7 @@ function j({ query: e, initialVisible: t = 30, revealStep: o = 30, collapsePremi
99
99
  cardProps: p
100
100
  }, JSON.stringify([
101
101
  O,
102
- N?.from_date,
102
+ P?.from_date,
103
103
  e.date
104
104
  ]));
105
105
  }) : /* @__PURE__ */ C("p", {
@@ -109,14 +109,11 @@ function j({ query: e, initialVisible: t = 30, revealStep: o = 30, collapsePremi
109
109
  })]
110
110
  }, j.revision);
111
111
  }
112
- var M = (e) => !e.access.allowed && e.access.level === "tier", N = (e) => {
113
- let t = /* @__PURE__ */ new Set([...e.contents.map((e) => e.kind), ...(e.filtered_entities ?? []).map((e) => e.content_kind)]);
114
- return t.size === 1 ? t.values().next().value : void 0;
115
- };
116
- function P({ day: e, initial: t, step: r, pending: i, cardProps: a, collapsePremium: o, summaryLabels: c, language: u, kinds: d }) {
117
- let p = n(), _ = y(), [v, D] = S(t > 0 || !e.contents.length && e.filtered_count > 0), [O, A] = S(t), [j, P] = S(!1), [L, R] = S(!1), z = x(null), B = x(null), V = b(() => e.contents.slice(0, O), [e.contents, O]), H = b(() => e.contents.filter(M).length, [e.contents]), U = d?.[0] ?? N(e), W = b(() => {
112
+ var M = (e) => !e.access.allowed && e.access.level === "tier";
113
+ function N({ day: e, initial: t, step: r, pending: i, cardProps: a, collapsePremium: o, summaryLabels: c, language: u, kinds: d }) {
114
+ let p = n(), _ = y(), [v, D] = S(t > 0 || !e.contents.length && e.filtered_count > 0), [O, A] = S(t), [j, N] = S(!1), [I, L] = S(!1), R = x(null), z = x(null), B = b(() => e.contents.slice(0, O), [e.contents, O]), V = b(() => e.contents.filter(M).length, [e.contents]), H = d?.[0], U = b(() => {
118
115
  let e = !1;
119
- return V.flatMap((t, n) => !o || j || !M(t) ? [{
116
+ return B.flatMap((t, n) => !o || j || !M(t) ? [{
120
117
  key: t.id,
121
118
  card: t,
122
119
  summary: !1,
@@ -128,38 +125,38 @@ function P({ day: e, initial: t, step: r, pending: i, cardProps: a, collapsePrem
128
125
  position: n + 1
129
126
  }]));
130
127
  }, [
131
- V,
128
+ B,
132
129
  o,
133
130
  j
134
- ]), G = b(() => v && !i ? W.filter((e) => !e.summary).map((e) => e.card) : [], [
131
+ ]), W = b(() => v && !i ? U.filter((e) => !e.summary).map((e) => e.card) : [], [
135
132
  v,
136
133
  i,
137
- W
138
- ]), K = f(G, {
134
+ U
135
+ ]), G = f(W, {
139
136
  surface: a.surface ?? "releases",
140
137
  render: e.date,
141
138
  client: a.client
142
- }), q = m(a.grid), J = g(`${O}|${W.map((e) => e.key).join("\0")}`), Y = new Intl.DateTimeFormat(p.language, {
139
+ }), K = m(a.grid), q = g(`${O}|${U.map((e) => e.key).join("\0")}`), J = new Intl.DateTimeFormat(p.language, {
143
140
  dateStyle: "full",
144
141
  timeZone: "UTC"
145
- }).format(/* @__PURE__ */ new Date(`${e.date}T12:00:00Z`)), X = () => {
142
+ }).format(/* @__PURE__ */ new Date(`${e.date}T12:00:00Z`)), Y = () => {
146
143
  !v && !O && A(Math.min(r, e.contents.length)), D(!v);
147
- }, Z = (e) => {
148
- J.prepare(e.detail === 0), P(!0);
144
+ }, X = (e) => {
145
+ q.prepare(e.detail === 0), N(!0);
149
146
  };
150
147
  return /* @__PURE__ */ w("section", {
151
148
  "data-ckui": "release-day",
152
149
  "data-date": e.date,
153
150
  children: [
154
151
  /* @__PURE__ */ C("h2", { children: /* @__PURE__ */ w(s, {
155
- ref: B,
152
+ ref: z,
156
153
  id: `${_}-heading`,
157
154
  type: "button",
158
155
  variant: "ghost",
159
156
  className: "h-auto w-full justify-start gap-3 px-0 py-3 text-start text-lg font-semibold",
160
157
  "aria-expanded": v,
161
158
  "aria-controls": `${_}-contents`,
162
- onClick: X,
159
+ onClick: Y,
163
160
  children: [/* @__PURE__ */ C(k, {
164
161
  icon: E,
165
162
  strokeWidth: 2,
@@ -167,7 +164,7 @@ function P({ day: e, initial: t, step: r, pending: i, cardProps: a, collapsePrem
167
164
  "aria-hidden": !0
168
165
  }), /* @__PURE__ */ C("time", {
169
166
  dateTime: e.date,
170
- children: Y
167
+ children: J
171
168
  })]
172
169
  }) }),
173
170
  v && i && /* @__PURE__ */ C(l, { className: "h-24 w-full" }),
@@ -183,33 +180,33 @@ function P({ day: e, initial: t, step: r, pending: i, cardProps: a, collapsePrem
183
180
  children: /* @__PURE__ */ w("div", {
184
181
  className: "min-h-0 overflow-hidden",
185
182
  children: [/* @__PURE__ */ w("ol", {
186
- ref: J.grid,
187
- className: T(q.className, "pt-2"),
188
- style: q.style,
189
- children: [W.map((e) => e.summary ? /* @__PURE__ */ C(F, {
183
+ ref: q.grid,
184
+ className: T(K.className, "pt-2"),
185
+ style: K.style,
186
+ children: [U.map((e) => e.summary ? /* @__PURE__ */ C(P, {
190
187
  tileKey: e.key,
191
188
  contentKind: d?.[0] ?? e.card.kind,
192
189
  open: v && !i,
193
190
  preview: e.card,
194
191
  cardProps: a,
195
192
  kind: "premium",
196
- label: c?.premium?.(H) ?? p.plural("releases.premiumMore", H),
197
- onClick: Z
198
- }, e.key) : /* @__PURE__ */ C(I, {
193
+ label: c?.premium?.(V) ?? p.plural("releases.premiumMore", V),
194
+ onClick: X
195
+ }, e.key) : /* @__PURE__ */ C(F, {
199
196
  card: e.card,
200
197
  open: v && !i,
201
198
  position: e.position,
202
- exposure: K,
199
+ exposure: G,
203
200
  cardProps: a
204
- }, e.key)), e.filtered_count > 0 && /* @__PURE__ */ C(F, {
201
+ }, e.key)), e.filtered_count > 0 && /* @__PURE__ */ C(P, {
205
202
  tileKey: "filtered-summary",
206
- contentKind: U,
203
+ contentKind: H,
207
204
  open: v && !i,
208
205
  cardProps: a,
209
206
  kind: "filtered",
210
207
  label: c?.filtered?.(e.filtered_count) ?? p.plural("releases.filteredMore", e.filtered_count),
211
208
  onClick: (e) => {
212
- z.current = e.currentTarget, R(!0);
209
+ R.current = e.currentTarget, L(!0);
213
210
  }
214
211
  })]
215
212
  }), O < e.contents.length && /* @__PURE__ */ C("div", {
@@ -218,7 +215,7 @@ function P({ day: e, initial: t, step: r, pending: i, cardProps: a, collapsePrem
218
215
  type: "button",
219
216
  variant: "outline",
220
217
  onClick: (t) => {
221
- J.prepare(t.detail === 0), A((t) => Math.min(t + r, e.contents.length));
218
+ q.prepare(t.detail === 0), A((t) => Math.min(t + r, e.contents.length));
222
219
  },
223
220
  children: p.t("contents.showMore")
224
221
  })
@@ -226,21 +223,20 @@ function P({ day: e, initial: t, step: r, pending: i, cardProps: a, collapsePrem
226
223
  })
227
224
  }),
228
225
  /* @__PURE__ */ C(h, {
229
- returnFocus: () => !i && z.current?.isConnected ? z.current : B.current,
230
- open: L,
231
- onOpenChange: R,
226
+ returnFocus: () => !i && R.current?.isConnected ? R.current : z.current,
227
+ open: I,
228
+ onOpenChange: L,
232
229
  client: a.client,
233
230
  kinds: d,
234
- labels: a.labels,
235
231
  language: u,
236
232
  counts: e.filtered_entities ?? [],
237
- description: p.t("releases.filterContext", { date: Y }),
233
+ description: p.t("releases.filterContext", { date: J }),
238
234
  appearance: a.appearance
239
235
  })
240
236
  ]
241
237
  });
242
238
  }
243
- function F({ tileKey: r, kind: i, contentKind: a, preview: l, open: u, label: d, onClick: f, cardProps: p }) {
239
+ function P({ tileKey: r, kind: i, contentKind: a, preview: l, open: u, label: d, onClick: f, cardProps: p }) {
244
240
  let { t: m } = n(), [h, g] = c({
245
241
  margin: "0px",
246
242
  leaveMargin: "1200px 0px"
@@ -289,7 +285,7 @@ function F({ tileKey: r, kind: i, contentKind: a, preview: l, open: u, label: d,
289
285
  })]
290
286
  });
291
287
  }
292
- function I({ card: e, open: t, position: n, exposure: r, cardProps: i }) {
288
+ function F({ card: e, open: t, position: n, exposure: r, cardProps: i }) {
293
289
  let [a, o] = c({
294
290
  margin: "0px",
295
291
  leaveMargin: "1200px 0px"
@@ -1 +1 @@
1
- {"version":3,"file":"daily-releases.js","names":[],"sources":["../../../src/components/content/daily-releases.tsx"],"sourcesContent":["import { ArrowDown01Icon, LockIcon, Settings01Icon } from \"@hugeicons/core-free-icons\";\nimport { HugeiconsIcon } from \"@hugeicons/react\";\nimport { cn } from \"cn\";\nimport { useCallback, useContext, useId, useMemo, useState, useRef, type CSSProperties, type MouseEvent } from \"react\";\nimport type { DailyReleasesQuery } from \"../../client/discovery.js\";\nimport type { Card, ReleaseDay } from \"../../client/generated/wire.js\";\nimport { useMessages } from \"../../i18n/context.js\";\nimport { useDailyReleases, useExposure } from \"../../react/discovery.js\";\nimport { ContentKitContext } from \"../../react/context.js\";\nimport { useContentScope } from \"../../react/use-resource.js\";\nimport { usePresets } from \"../../react/public.js\";\nimport { ratio } from \"../../client/aspect.js\";\nimport { RenditionImg } from \"../rendition-img.js\";\nimport { useNearViewport } from \"../../react/viewport.js\";\nimport { ContentKitUiRoot } from \"../../scope.js\";\nimport { Button } from \"#ckui/ui/button\";\nimport { Skeleton } from \"#ckui/ui/skeleton\";\nimport { contentError } from \"../social/parts.js\";\nimport { ContentFilterDialog } from \"./filter-dialog.js\";\nimport { useReleaseReveal } from \"./release-reveal.js\";\nimport { ContentCard } from \"./card.js\";\nimport { cardGridLayout, type CardListProps } from \"./grid.js\";\n\nexport interface DailyReleasesProps extends Omit<CardListProps, \"infinite\" | \"pageSize\" | \"renderCard\" | \"loadMedia\"> {\n /** One complete calendar window. Defaults to 10 days in the browser's time zone. */\n query?: DailyReleasesQuery;\n /** Cards initially revealed across the whole window, allocated newest first. Default 30. */\n initialVisible?: number;\n /** Collapse locked tier previews per day; expansion never grants access. Default false. */\n collapsePremium?: boolean;\n /** Host-specific nouns; defaults use localized generic item labels. */\n summaryLabels?: { premium?: (count: number) => string; filtered?: (count: number) => string };\n /** Additional cached cards revealed by a day's Show more button. Default 30. */\n revealStep?: number;\n}\n\nconst count = (value: number, fallback: number) => Number.isFinite(value) ? Math.max(0, Math.floor(value)) : fallback;\n\n/**\n * One metadata request for a calendar window, with no requests when a day is\n * opened or expanded. Only revealed, visible cards mount images and previews.\n */\nexport function DailyReleases({ query, initialVisible = 30, revealStep = 30, collapsePremium = false, summaryLabels, ...p }: DailyReleasesProps) {\n const m = useMessages();\n const { client, viewer } = useContentScope(p.client);\n const context = useContext(ContentKitContext);\n const request = useMemo(() => ({ days: 10, time_zone: Intl.DateTimeFormat().resolvedOptions().timeZone, ...query }), [query]);\n const releases = useDailyReleases(request, { client: p.client });\n const layout = cardGridLayout(p.grid);\n const requestKey = JSON.stringify(request);\n // Guest preference changes create a fresh read scope. Keep the open day/dialog\n // while it loads, but never show the old cards or carry data across accounts.\n const identity = useMemo(() => ({ client, viewer, language: context?.language, accessRevision: context?.accessRevision, requestKey }), [client, viewer, context?.language, context?.accessRevision, requestKey]);\n const [previous, setPrevious] = useState({ identity, data: releases.data, revision: 0 });\n if (previous.identity !== identity || (releases.data && previous.data !== releases.data)) setPrevious({ identity, data: releases.data, revision: previous.revision + (previous.identity === identity ? 0 : 1) });\n const data = releases.data ?? (previous.identity === identity ? previous.data : undefined);\n const pending = !releases.data && Boolean(data);\n const days = useMemo(() => data?.days.filter((day) => (day.contents.length || day.filtered_count > 0)).sort((a, b) => b.date.localeCompare(a.date)) ?? [], [data]);\n let remaining = count(initialVisible, 30);\n return (\n <ContentKitUiRoot key={previous.revision} appearance={p.appearance} className={cn(\"grid gap-6 text-sm\", p.className)} data-ckui=\"daily-releases\" aria-busy={releases.loading}>\n {data && releases.error && <div role=\"alert\" className=\"grid justify-items-start gap-2\"><p className=\"text-destructive\">{contentError(m, releases.error)}</p><Button type=\"button\" variant=\"outline\" onClick={releases.reload}>{m.t(\"common.retry\")}</Button></div>}\n {releases.loading && !data ? <div className={layout.className} style={layout.style}>{Array.from({ length: 6 }, (_, i) => <Skeleton key={i} className={p.aspectRatio === undefined ? p.shape === \"landscape\" ? \"aspect-video\" : \"aspect-[3/4]\" : undefined} style={p.aspectRatio === undefined ? undefined : { aspectRatio: p.aspectRatio }} />)}</div> : releases.error && !data ? (\n <div role=\"alert\" className=\"grid justify-items-start gap-2\">\n <p className=\"text-destructive\">{contentError(m, releases.error)}</p>\n <Button size=\"sm\" variant=\"outline\" onClick={releases.reload}>{m.t(\"common.retry\")}</Button>\n </div>\n ) : !days.length ? <p role=\"status\" className=\"text-muted-foreground\">{p.empty ?? m.t(\"contents.empty\")}</p> : days.map((day) => {\n const initial = Math.min(remaining, day.contents.length);\n remaining -= initial;\n return <ReleaseDaySection key={JSON.stringify([requestKey, data?.from_date, day.date])} day={day} pending={pending} collapsePremium={collapsePremium} summaryLabels={summaryLabels} language={request.display_language ?? request.language} kinds={request.kind ? [request.kind] : undefined} initial={initial} step={Math.max(1, count(revealStep, 30))} cardProps={p} />;\n })}\n </ContentKitUiRoot>\n );\n}\n\ntype ReleaseCardProps = Omit<DailyReleasesProps, \"query\" | \"initialVisible\" | \"revealStep\" | \"collapsePremium\" | \"summaryLabels\">;\nconst lockedPremium = (card: Card) => !card.access.allowed && card.access.level === \"tier\";\nconst singleReleaseKind = (day: ReleaseDay): string | undefined => {\n const kinds = new Set([...day.contents.map((card) => card.kind), ...(day.filtered_entities ?? []).map((entry) => entry.content_kind)]);\n return kinds.size === 1 ? kinds.values().next().value : undefined;\n};\n\nfunction ReleaseDaySection({ day, initial, step, pending, cardProps: p, collapsePremium, summaryLabels, language, kinds }: {\n day: ReleaseDay; initial: number; step: number; pending: boolean; cardProps: ReleaseCardProps;\n collapsePremium: boolean; summaryLabels?: DailyReleasesProps[\"summaryLabels\"]; language?: string; kinds?: string[];\n}) {\n const m = useMessages();\n const id = useId();\n const [open, setOpen] = useState(initial > 0 || (!day.contents.length && day.filtered_count > 0));\n const [visible, setVisible] = useState(initial);\n const [premiumExpanded, setPremiumExpanded] = useState(false);\n const [filtersOpen, setFiltersOpen] = useState(false);\n const filterTrigger = useRef<HTMLElement | null>(null);\n const dayHeading = useRef<HTMLButtonElement>(null);\n const cards = useMemo(() => day.contents.slice(0, visible), [day.contents, visible]);\n const premiumCount = useMemo(() => day.contents.filter(lockedPremium).length, [day.contents]);\n const summaryContentKind = kinds?.[0] ?? singleReleaseKind(day);\n const entries = useMemo(() => {\n let inserted = false;\n return cards.flatMap((card, i): { key: string; card: Card; summary: boolean; position: number }[] => {\n if (!collapsePremium || premiumExpanded || !lockedPremium(card)) return [{ key: card.id, card, summary: false, position: i + 1 }];\n if (inserted) return [];\n inserted = true;\n return [{ key: \"premium-summary\", card, summary: true, position: i + 1 }];\n });\n }, [cards, collapsePremium, premiumExpanded]);\n const exposed = useMemo(() => open && !pending ? entries.filter((entry) => !entry.summary).map((entry) => entry.card) : [], [open, pending, entries]);\n const exposure = useExposure(exposed, { surface: p.surface ?? \"releases\", render: day.date, client: p.client });\n const layout = cardGridLayout(p.grid);\n const reveal = useReleaseReveal(`${visible}|${entries.map((entry) => entry.key).join(\"\\0\")}`);\n const label = new Intl.DateTimeFormat(m.language, { dateStyle: \"full\", timeZone: \"UTC\" }).format(new Date(`${day.date}T12:00:00Z`));\n const toggle = () => {\n if (!open && !visible) setVisible(Math.min(step, day.contents.length));\n setOpen(!open);\n };\n const expandPremium = (event: MouseEvent<HTMLButtonElement>) => {\n reveal.prepare(event.detail === 0);\n setPremiumExpanded(true);\n };\n return (\n <section data-ckui=\"release-day\" data-date={day.date}>\n <h2>\n <Button ref={dayHeading} id={`${id}-heading`} type=\"button\" variant=\"ghost\" className=\"h-auto w-full justify-start gap-3 px-0 py-3 text-start text-lg font-semibold\" aria-expanded={open} aria-controls={`${id}-contents`} onClick={toggle}>\n <HugeiconsIcon icon={ArrowDown01Icon} strokeWidth={2} className={cn(\"size-5 shrink-0 transition-transform duration-200 motion-reduce:transition-none\", !open && \"-rotate-90\")} aria-hidden />\n <time dateTime={day.date}>{label}</time>\n </Button>\n </h2>\n {open && pending && <Skeleton className=\"h-24 w-full\" />}\n <div hidden={pending} style={pending ? { display: \"none\" } : undefined} id={`${id}-contents`} role=\"region\" aria-labelledby={`${id}-heading`} aria-hidden={!open || pending} inert={!open || pending} className={cn(\"grid transition-[grid-template-rows,opacity] duration-250 ease-out motion-reduce:transition-none\", open ? \"grid-rows-[1fr] opacity-100\" : \"grid-rows-[0fr] opacity-0\")}>\n <div className=\"min-h-0 overflow-hidden\">\n <ol ref={reveal.grid} className={cn(layout.className, \"pt-2\")} style={layout.style}>\n {entries.map((entry) => entry.summary ?\n <ReleaseSummaryTile key={entry.key} tileKey={entry.key} contentKind={kinds?.[0] ?? entry.card.kind} open={open && !pending} preview={entry.card} cardProps={p} kind=\"premium\" label={summaryLabels?.premium?.(premiumCount) ?? m.plural(\"releases.premiumMore\", premiumCount)} onClick={expandPremium} /> :\n <ReleaseCard key={entry.key} card={entry.card} open={open && !pending} position={entry.position} exposure={exposure} cardProps={p} />)}\n {day.filtered_count > 0 && <ReleaseSummaryTile tileKey=\"filtered-summary\" contentKind={summaryContentKind} open={open && !pending} cardProps={p} kind=\"filtered\" label={summaryLabels?.filtered?.(day.filtered_count) ?? m.plural(\"releases.filteredMore\", day.filtered_count)} onClick={(event) => { filterTrigger.current = event.currentTarget; setFiltersOpen(true); }} />}\n </ol>\n {visible < day.contents.length && <div className=\"flex justify-center pt-5 pb-1\"><Button type=\"button\" variant=\"outline\" onClick={(event) => { reveal.prepare(event.detail === 0); setVisible((n) => Math.min(n + step, day.contents.length)); }}>{m.t(\"contents.showMore\")}</Button></div>}\n </div>\n </div>\n <ContentFilterDialog returnFocus={() => !pending && filterTrigger.current?.isConnected ? filterTrigger.current : dayHeading.current} open={filtersOpen} onOpenChange={setFiltersOpen} client={p.client} kinds={kinds} labels={p.labels} language={language} counts={day.filtered_entities ?? []} description={m.t(\"releases.filterContext\", { date: label })} appearance={p.appearance} />\n </section>\n );\n}\n\nfunction ReleaseSummaryTile({ tileKey, kind, contentKind, preview, open, label, onClick, cardProps: p }: {\n tileKey: string; kind: \"premium\" | \"filtered\"; contentKind?: string; preview?: Card; open: boolean; label: string; onClick: (event: MouseEvent<HTMLButtonElement>) => void; cardProps: ReleaseCardProps;\n}) {\n const { t } = useMessages();\n const [ref, near] = useNearViewport({ margin: \"0px\", leaveMargin: \"1200px 0px\" });\n const { presets } = usePresets({ client: p.client });\n const aspect: CSSProperties[\"aspectRatio\"] = p.aspectRatio ?? ratio(presets.find((preset) => preset.kind === contentKind && preset.name === \"cover\")?.aspect) ?? (p.shape === \"landscape\" ? \"16 / 9\" : \"3 / 4\");\n return <li ref={ref} data-release-key={tileKey}>\n <Button type=\"button\" variant=\"outline\" data-ckui={`${kind}-release-tile`} aria-label={label} aria-expanded={kind === \"premium\" ? false : undefined} aria-haspopup={kind === \"filtered\" ? \"dialog\" : undefined} className=\"relative flex h-auto w-full flex-col justify-center overflow-hidden rounded-lg p-0 text-center whitespace-normal\" style={{ aspectRatio: aspect }} onClick={onClick}>\n {preview && open && near && <RenditionImg outputs={preview.cover} alt=\"\" fit=\"cover\" loading=\"lazy\" className=\"absolute inset-0 size-full opacity-20\" />}\n <span className=\"relative grid justify-items-center gap-3 p-4\">\n <HugeiconsIcon icon={kind === \"premium\" ? LockIcon : Settings01Icon} strokeWidth={2} className=\"size-8\" aria-hidden />\n <span className=\"text-xl font-semibold\">{label}</span>\n <span className=\"text-sm text-muted-foreground\">{t(kind === \"premium\" ? \"releases.premiumHint\" : \"releases.manageFilters\")}</span>\n </span>\n </Button>\n {preview && <p className=\"mt-2 line-clamp-2 text-lg leading-snug text-muted-foreground\">{preview.title}</p>}\n </li>;\n}\n\nfunction ReleaseCard({ card, open, position, exposure, cardProps: p }: { card: Card; open: boolean; position: number; exposure: ReturnType<typeof useExposure>; cardProps: ReleaseCardProps }) {\n const [viewport, visible] = useNearViewport({ margin: \"0px\", leaveMargin: \"1200px 0px\" });\n const tracked = useMemo(() => exposure.track(card.id, position), [exposure, card.id, position]);\n const ref = useCallback((element: HTMLLIElement | null) => { viewport(element); tracked(element); }, [viewport, tracked]);\n return <li ref={ref} data-release-key={card.id}>\n <ContentCard card={card} client={p.client} href={p.href} shape={p.shape} aspectRatio={p.aspectRatio} titlePosition={p.titlePosition} loadMedia={open && visible} groupKinds={p.groupKinds} chips={p.chips} filterEntity={p.filterEntity} entityStyle={p.entityStyle} entityLayout={p.entityLayout} metadata={p.metadata} showCounts={p.showCounts} tiers={p.tiers} labels={p.labels} owner={p.owner} ownerHref={p.ownerHref} decorate={p.decorate} onOpen={() => exposure.click(card.id, position)} />\n </li>;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"daily-releases.js","names":[],"sources":["../../../src/components/content/daily-releases.tsx"],"sourcesContent":["import { ArrowDown01Icon, LockIcon, Settings01Icon } from \"@hugeicons/core-free-icons\";\nimport { HugeiconsIcon } from \"@hugeicons/react\";\nimport { cn } from \"cn\";\nimport { useCallback, useContext, useId, useMemo, useState, useRef, type CSSProperties, type MouseEvent } from \"react\";\nimport type { DailyReleasesQuery } from \"../../client/discovery.js\";\nimport type { Card, ReleaseDay } from \"../../client/generated/wire.js\";\nimport { useMessages } from \"../../i18n/context.js\";\nimport { useDailyReleases, useExposure } from \"../../react/discovery.js\";\nimport { ContentKitContext } from \"../../react/context.js\";\nimport { useContentScope } from \"../../react/use-resource.js\";\nimport { usePresets } from \"../../react/public.js\";\nimport { ratio } from \"../../client/aspect.js\";\nimport { RenditionImg } from \"../rendition-img.js\";\nimport { useNearViewport } from \"../../react/viewport.js\";\nimport { ContentKitUiRoot } from \"../../scope.js\";\nimport { Button } from \"#ckui/ui/button\";\nimport { Skeleton } from \"#ckui/ui/skeleton\";\nimport { contentError } from \"../social/parts.js\";\nimport { ContentFilterDialog } from \"./filter-dialog.js\";\nimport { useReleaseReveal } from \"./release-reveal.js\";\nimport { ContentCard } from \"./card.js\";\nimport { cardGridLayout, type CardListProps } from \"./grid.js\";\n\nexport interface DailyReleasesProps extends Omit<CardListProps, \"infinite\" | \"pageSize\" | \"renderCard\" | \"loadMedia\"> {\n /** One complete calendar window. Defaults to 10 days in the browser's time zone. */\n query?: DailyReleasesQuery;\n /** Cards initially revealed across the whole window, allocated newest first. Default 30. */\n initialVisible?: number;\n /** Collapse locked tier previews per day; expansion never grants access. Default false. */\n collapsePremium?: boolean;\n /** Host-specific nouns; defaults use localized generic item labels. */\n summaryLabels?: { premium?: (count: number) => string; filtered?: (count: number) => string };\n /** Additional cached cards revealed by a day's Show more button. Default 30. */\n revealStep?: number;\n}\n\nconst count = (value: number, fallback: number) => Number.isFinite(value) ? Math.max(0, Math.floor(value)) : fallback;\n\n/**\n * One metadata request for a calendar window, with no requests when a day is\n * opened or expanded. Only revealed, visible cards mount images and previews.\n */\nexport function DailyReleases({ query, initialVisible = 30, revealStep = 30, collapsePremium = false, summaryLabels, ...p }: DailyReleasesProps) {\n const m = useMessages();\n const { client, viewer } = useContentScope(p.client);\n const context = useContext(ContentKitContext);\n const request = useMemo(() => ({ days: 10, time_zone: Intl.DateTimeFormat().resolvedOptions().timeZone, ...query }), [query]);\n const releases = useDailyReleases(request, { client: p.client });\n const layout = cardGridLayout(p.grid);\n const requestKey = JSON.stringify(request);\n // Guest preference changes create a fresh read scope. Keep the open day/dialog\n // while it loads, but never show the old cards or carry data across accounts.\n const identity = useMemo(() => ({ client, viewer, language: context?.language, accessRevision: context?.accessRevision, requestKey }), [client, viewer, context?.language, context?.accessRevision, requestKey]);\n const [previous, setPrevious] = useState({ identity, data: releases.data, revision: 0 });\n if (previous.identity !== identity || (releases.data && previous.data !== releases.data)) setPrevious({ identity, data: releases.data, revision: previous.revision + (previous.identity === identity ? 0 : 1) });\n const data = releases.data ?? (previous.identity === identity ? previous.data : undefined);\n const pending = !releases.data && Boolean(data);\n const days = useMemo(() => data?.days.filter((day) => (day.contents.length || day.filtered_count > 0)).sort((a, b) => b.date.localeCompare(a.date)) ?? [], [data]);\n let remaining = count(initialVisible, 30);\n return (\n <ContentKitUiRoot key={previous.revision} appearance={p.appearance} className={cn(\"grid gap-6 text-sm\", p.className)} data-ckui=\"daily-releases\" aria-busy={releases.loading}>\n {data && releases.error && <div role=\"alert\" className=\"grid justify-items-start gap-2\"><p className=\"text-destructive\">{contentError(m, releases.error)}</p><Button type=\"button\" variant=\"outline\" onClick={releases.reload}>{m.t(\"common.retry\")}</Button></div>}\n {releases.loading && !data ? <div className={layout.className} style={layout.style}>{Array.from({ length: 6 }, (_, i) => <Skeleton key={i} className={p.aspectRatio === undefined ? p.shape === \"landscape\" ? \"aspect-video\" : \"aspect-[3/4]\" : undefined} style={p.aspectRatio === undefined ? undefined : { aspectRatio: p.aspectRatio }} />)}</div> : releases.error && !data ? (\n <div role=\"alert\" className=\"grid justify-items-start gap-2\">\n <p className=\"text-destructive\">{contentError(m, releases.error)}</p>\n <Button size=\"sm\" variant=\"outline\" onClick={releases.reload}>{m.t(\"common.retry\")}</Button>\n </div>\n ) : !days.length ? <p role=\"status\" className=\"text-muted-foreground\">{p.empty ?? m.t(\"contents.empty\")}</p> : days.map((day) => {\n const initial = Math.min(remaining, day.contents.length);\n remaining -= initial;\n return <ReleaseDaySection key={JSON.stringify([requestKey, data?.from_date, day.date])} day={day} pending={pending} collapsePremium={collapsePremium} summaryLabels={summaryLabels} language={request.display_language ?? request.language} kinds={request.kind ? [request.kind] : undefined} initial={initial} step={Math.max(1, count(revealStep, 30))} cardProps={p} />;\n })}\n </ContentKitUiRoot>\n );\n}\n\ntype ReleaseCardProps = Omit<DailyReleasesProps, \"query\" | \"initialVisible\" | \"revealStep\" | \"collapsePremium\" | \"summaryLabels\">;\nconst lockedPremium = (card: Card) => !card.access.allowed && card.access.level === \"tier\";\n\nfunction ReleaseDaySection({ day, initial, step, pending, cardProps: p, collapsePremium, summaryLabels, language, kinds }: {\n day: ReleaseDay; initial: number; step: number; pending: boolean; cardProps: ReleaseCardProps;\n collapsePremium: boolean; summaryLabels?: DailyReleasesProps[\"summaryLabels\"]; language?: string; kinds?: string[];\n}) {\n const m = useMessages();\n const id = useId();\n const [open, setOpen] = useState(initial > 0 || (!day.contents.length && day.filtered_count > 0));\n const [visible, setVisible] = useState(initial);\n const [premiumExpanded, setPremiumExpanded] = useState(false);\n const [filtersOpen, setFiltersOpen] = useState(false);\n const filterTrigger = useRef<HTMLElement | null>(null);\n const dayHeading = useRef<HTMLButtonElement>(null);\n const cards = useMemo(() => day.contents.slice(0, visible), [day.contents, visible]);\n const premiumCount = useMemo(() => day.contents.filter(lockedPremium).length, [day.contents]);\n const summaryContentKind = kinds?.[0];\n const entries = useMemo(() => {\n let inserted = false;\n return cards.flatMap((card, i): { key: string; card: Card; summary: boolean; position: number }[] => {\n if (!collapsePremium || premiumExpanded || !lockedPremium(card)) return [{ key: card.id, card, summary: false, position: i + 1 }];\n if (inserted) return [];\n inserted = true;\n return [{ key: \"premium-summary\", card, summary: true, position: i + 1 }];\n });\n }, [cards, collapsePremium, premiumExpanded]);\n const exposed = useMemo(() => open && !pending ? entries.filter((entry) => !entry.summary).map((entry) => entry.card) : [], [open, pending, entries]);\n const exposure = useExposure(exposed, { surface: p.surface ?? \"releases\", render: day.date, client: p.client });\n const layout = cardGridLayout(p.grid);\n const reveal = useReleaseReveal(`${visible}|${entries.map((entry) => entry.key).join(\"\\0\")}`);\n const label = new Intl.DateTimeFormat(m.language, { dateStyle: \"full\", timeZone: \"UTC\" }).format(new Date(`${day.date}T12:00:00Z`));\n const toggle = () => {\n if (!open && !visible) setVisible(Math.min(step, day.contents.length));\n setOpen(!open);\n };\n const expandPremium = (event: MouseEvent<HTMLButtonElement>) => {\n reveal.prepare(event.detail === 0);\n setPremiumExpanded(true);\n };\n return (\n <section data-ckui=\"release-day\" data-date={day.date}>\n <h2>\n <Button ref={dayHeading} id={`${id}-heading`} type=\"button\" variant=\"ghost\" className=\"h-auto w-full justify-start gap-3 px-0 py-3 text-start text-lg font-semibold\" aria-expanded={open} aria-controls={`${id}-contents`} onClick={toggle}>\n <HugeiconsIcon icon={ArrowDown01Icon} strokeWidth={2} className={cn(\"size-5 shrink-0 transition-transform duration-200 motion-reduce:transition-none\", !open && \"-rotate-90\")} aria-hidden />\n <time dateTime={day.date}>{label}</time>\n </Button>\n </h2>\n {open && pending && <Skeleton className=\"h-24 w-full\" />}\n <div hidden={pending} style={pending ? { display: \"none\" } : undefined} id={`${id}-contents`} role=\"region\" aria-labelledby={`${id}-heading`} aria-hidden={!open || pending} inert={!open || pending} className={cn(\"grid transition-[grid-template-rows,opacity] duration-250 ease-out motion-reduce:transition-none\", open ? \"grid-rows-[1fr] opacity-100\" : \"grid-rows-[0fr] opacity-0\")}>\n <div className=\"min-h-0 overflow-hidden\">\n <ol ref={reveal.grid} className={cn(layout.className, \"pt-2\")} style={layout.style}>\n {entries.map((entry) => entry.summary ?\n <ReleaseSummaryTile key={entry.key} tileKey={entry.key} contentKind={kinds?.[0] ?? entry.card.kind} open={open && !pending} preview={entry.card} cardProps={p} kind=\"premium\" label={summaryLabels?.premium?.(premiumCount) ?? m.plural(\"releases.premiumMore\", premiumCount)} onClick={expandPremium} /> :\n <ReleaseCard key={entry.key} card={entry.card} open={open && !pending} position={entry.position} exposure={exposure} cardProps={p} />)}\n {day.filtered_count > 0 && <ReleaseSummaryTile tileKey=\"filtered-summary\" contentKind={summaryContentKind} open={open && !pending} cardProps={p} kind=\"filtered\" label={summaryLabels?.filtered?.(day.filtered_count) ?? m.plural(\"releases.filteredMore\", day.filtered_count)} onClick={(event) => { filterTrigger.current = event.currentTarget; setFiltersOpen(true); }} />}\n </ol>\n {visible < day.contents.length && <div className=\"flex justify-center pt-5 pb-1\"><Button type=\"button\" variant=\"outline\" onClick={(event) => { reveal.prepare(event.detail === 0); setVisible((n) => Math.min(n + step, day.contents.length)); }}>{m.t(\"contents.showMore\")}</Button></div>}\n </div>\n </div>\n <ContentFilterDialog returnFocus={() => !pending && filterTrigger.current?.isConnected ? filterTrigger.current : dayHeading.current} open={filtersOpen} onOpenChange={setFiltersOpen} client={p.client} kinds={kinds} language={language} counts={day.filtered_entities ?? []} description={m.t(\"releases.filterContext\", { date: label })} appearance={p.appearance} />\n </section>\n );\n}\n\nfunction ReleaseSummaryTile({ tileKey, kind, contentKind, preview, open, label, onClick, cardProps: p }: {\n tileKey: string; kind: \"premium\" | \"filtered\"; contentKind?: string; preview?: Card; open: boolean; label: string; onClick: (event: MouseEvent<HTMLButtonElement>) => void; cardProps: ReleaseCardProps;\n}) {\n const { t } = useMessages();\n const [ref, near] = useNearViewport({ margin: \"0px\", leaveMargin: \"1200px 0px\" });\n const { presets } = usePresets({ client: p.client });\n const aspect: CSSProperties[\"aspectRatio\"] = p.aspectRatio ?? ratio(presets.find((preset) => preset.kind === contentKind && preset.name === \"cover\")?.aspect) ?? (p.shape === \"landscape\" ? \"16 / 9\" : \"3 / 4\");\n return <li ref={ref} data-release-key={tileKey}>\n <Button type=\"button\" variant=\"outline\" data-ckui={`${kind}-release-tile`} aria-label={label} aria-expanded={kind === \"premium\" ? false : undefined} aria-haspopup={kind === \"filtered\" ? \"dialog\" : undefined} className=\"relative flex h-auto w-full flex-col justify-center overflow-hidden rounded-lg p-0 text-center whitespace-normal\" style={{ aspectRatio: aspect }} onClick={onClick}>\n {preview && open && near && <RenditionImg outputs={preview.cover} alt=\"\" fit=\"cover\" loading=\"lazy\" className=\"absolute inset-0 size-full opacity-20\" />}\n <span className=\"relative grid justify-items-center gap-3 p-4\">\n <HugeiconsIcon icon={kind === \"premium\" ? LockIcon : Settings01Icon} strokeWidth={2} className=\"size-8\" aria-hidden />\n <span className=\"text-xl font-semibold\">{label}</span>\n <span className=\"text-sm text-muted-foreground\">{t(kind === \"premium\" ? \"releases.premiumHint\" : \"releases.manageFilters\")}</span>\n </span>\n </Button>\n {preview && <p className=\"mt-2 line-clamp-2 text-lg leading-snug text-muted-foreground\">{preview.title}</p>}\n </li>;\n}\n\nfunction ReleaseCard({ card, open, position, exposure, cardProps: p }: { card: Card; open: boolean; position: number; exposure: ReturnType<typeof useExposure>; cardProps: ReleaseCardProps }) {\n const [viewport, visible] = useNearViewport({ margin: \"0px\", leaveMargin: \"1200px 0px\" });\n const tracked = useMemo(() => exposure.track(card.id, position), [exposure, card.id, position]);\n const ref = useCallback((element: HTMLLIElement | null) => { viewport(element); tracked(element); }, [viewport, tracked]);\n return <li ref={ref} data-release-key={card.id}>\n <ContentCard card={card} client={p.client} href={p.href} shape={p.shape} aspectRatio={p.aspectRatio} titlePosition={p.titlePosition} loadMedia={open && visible} groupKinds={p.groupKinds} chips={p.chips} filterEntity={p.filterEntity} entityStyle={p.entityStyle} entityLayout={p.entityLayout} metadata={p.metadata} showCounts={p.showCounts} tiers={p.tiers} labels={p.labels} owner={p.owner} ownerHref={p.ownerHref} decorate={p.decorate} onOpen={() => exposure.click(card.id, position)} />\n </li>;\n}\n"],"mappings":"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"}
@@ -3,19 +3,15 @@ import { ContentKitClient } from '../../client/client.js';
3
3
  import { GroupCard } from '../../client/generated/wire.js';
4
4
  import { ReleaseDatesQuery } from '../../client/discovery.js';
5
5
  import { ContentKitErrorHandler } from '../../react/context.js';
6
- import { Labels } from '../groups/parts.js';
7
- /** Counts for one concrete listing selection, keyed by content kind and entity.
6
+ /** Counts for one concrete listing selection, aggregated by entity.
8
7
  * Only rows offered by the current domain's filter inventory are displayed. */
9
8
  export interface ContentFilterCount {
10
- content_kind: string;
11
9
  entity: Pick<GroupCard, "id">;
12
10
  count: number;
13
11
  }
14
12
  export interface ContentFilterSettingsProps {
15
- /** Content kinds to show. Omitted displays every configured kind. */
13
+ /** Listing context; shows shared controls when any kind is in applies_to. */
16
14
  kinds?: readonly string[];
17
- /** Display labels for content-kind sections, when more than one is shown. */
18
- labels?: Labels;
19
15
  /** Entity names in this language; default the provider's. */
20
16
  language?: string;
21
17
  /** Currently excluded matches in this listing/day; omitted shows no counts. */
@@ -7,71 +7,62 @@ import { Skeleton as a } from "../../ui/skeleton.js";
7
7
  import { ErrorLine as o, contentError as s, useAction as c } from "../social/parts.js";
8
8
  import { Switch as l } from "../../ui/switch.js";
9
9
  import { useContentFilters as u, useReleaseDates as d } from "../../react/discovery.js";
10
- import { labelOf as f } from "../groups/parts.js";
11
- import { useContext as p, useId as m } from "react";
12
- import { Fragment as h, jsx as g, jsxs as _ } from "react/jsx-runtime";
13
- import { cn as v } from "cn";
10
+ import { useContext as f, useId as p } from "react";
11
+ import { Fragment as m, jsx as h, jsxs as g } from "react/jsx-runtime";
12
+ import { cn as _ } from "cn";
14
13
  //#region src/components/content/filters.tsx
15
- function y(r) {
16
- let d = e(), { t: y } = d, b = m(), x = p(n), S = u({
14
+ function v(r) {
15
+ let d = e(), { t: v } = d, y = p(), b = f(n), x = u({
17
16
  language: r.language,
18
17
  client: r.client
19
- }), C = c("filters.save", r.onError), w = (e) => /* @__PURE__ */ g(t, {
18
+ }), S = c("filters.save", r.onError), C = (e) => /* @__PURE__ */ h(t, {
20
19
  appearance: r.appearance,
21
- className: v("grid gap-3 text-sm", r.className),
20
+ className: _("grid gap-3 text-sm", r.className),
22
21
  "data-ckui": "content-filters",
23
22
  children: e
24
23
  });
25
- if (!S.filters) return S.error ? w(/* @__PURE__ */ g(o, { children: s(d, S.error) })) : w(/* @__PURE__ */ g(a, { className: "h-24 w-full" }));
26
- let T = S.filters, E = Object.entries(T.kinds).filter(([e, t]) => t.length && (!r.kinds || r.kinds.includes(e)));
27
- return !E.length && r.includeDeleted === !1 ? null : w(/* @__PURE__ */ _(h, { children: [
28
- E.map(([e, t]) => /* @__PURE__ */ _("section", {
29
- className: "grid gap-2",
30
- "data-content-kind": e,
31
- children: [E.length > 1 && /* @__PURE__ */ g("h4", {
32
- className: "font-medium",
33
- children: f(r.labels, e)
34
- }), /* @__PURE__ */ g("ul", {
35
- className: "grid divide-y divide-border rounded-lg border border-border",
36
- children: t.map((t) => /* @__PURE__ */ _("li", {
37
- className: "flex flex-wrap items-center gap-3 p-3",
38
- "data-ckui": "content-filter",
39
- "data-kind": e,
40
- "data-slug": t.entity.slug,
41
- "data-visible": t.visible,
42
- children: [/* @__PURE__ */ g(l, {
43
- id: `${b}-${e}-${t.entity.id}`,
44
- checked: t.visible,
45
- disabled: C.pending,
46
- onCheckedChange: (n) => void C.run(() => S.setVisible(e, t.entity.id, n))
47
- }), /* @__PURE__ */ _(i, {
48
- htmlFor: `${b}-${e}-${t.entity.id}`,
49
- className: "min-w-0 flex-1",
50
- children: [t.entity.name || t.entity.slug, r.counts !== void 0 && /* @__PURE__ */ _("span", {
51
- className: "tabular-nums",
52
- children: [": ", new Intl.NumberFormat(d.language).format(r.counts.find((n) => n.content_kind === e && n.entity.id === t.entity.id)?.count ?? 0)]
53
- })]
24
+ if (!x.filters) return x.error ? C(/* @__PURE__ */ h(o, { children: s(d, x.error) })) : C(/* @__PURE__ */ h(a, { className: "h-24 w-full" }));
25
+ let w = x.filters, T = !r.kinds || r.kinds.some((e) => w.applies_to.includes(e)) ? w.filters : [];
26
+ return !T.length && r.includeDeleted === !1 ? null : C(/* @__PURE__ */ g(m, { children: [
27
+ T.length > 0 && /* @__PURE__ */ h("ul", {
28
+ className: "grid divide-y divide-border rounded-lg border border-border",
29
+ children: T.map((e) => /* @__PURE__ */ g("li", {
30
+ className: "flex flex-wrap items-center gap-3 p-3",
31
+ "data-ckui": "content-filter",
32
+ "data-slug": e.entity.slug,
33
+ "data-visible": e.visible,
34
+ children: [/* @__PURE__ */ h(l, {
35
+ id: `${y}-${e.entity.id}`,
36
+ checked: e.visible,
37
+ disabled: S.pending,
38
+ onCheckedChange: (t) => void S.run(() => x.setVisible(e.entity.id, t))
39
+ }), /* @__PURE__ */ g(i, {
40
+ htmlFor: `${y}-${e.entity.id}`,
41
+ className: "min-w-0 flex-1",
42
+ children: [e.entity.name || e.entity.slug, r.counts !== void 0 && /* @__PURE__ */ g("span", {
43
+ className: "tabular-nums",
44
+ children: [": ", new Intl.NumberFormat(d.language).format(r.counts.filter((t) => t.entity.id === e.entity.id).reduce((e, t) => e + t.count, 0))]
54
45
  })]
55
- }, t.entity.id))
56
- })]
57
- }, e)),
58
- r.includeDeleted !== !1 && x?.viewer !== null && /* @__PURE__ */ _("div", {
46
+ })]
47
+ }, e.entity.id))
48
+ }),
49
+ r.includeDeleted !== !1 && b?.viewer !== null && /* @__PURE__ */ g("div", {
59
50
  className: "flex items-center gap-3",
60
- children: [/* @__PURE__ */ g(l, {
61
- id: `${b}-deleted`,
62
- checked: T.include_deleted,
63
- disabled: C.pending,
64
- onCheckedChange: (e) => void C.run(() => S.setIncludeDeleted(e))
65
- }), /* @__PURE__ */ g(i, {
66
- htmlFor: `${b}-deleted`,
67
- children: y("contents.includeDeleted")
51
+ children: [/* @__PURE__ */ h(l, {
52
+ id: `${y}-deleted`,
53
+ checked: w.include_deleted,
54
+ disabled: S.pending,
55
+ onCheckedChange: (e) => void S.run(() => x.setIncludeDeleted(e))
56
+ }), /* @__PURE__ */ h(i, {
57
+ htmlFor: `${y}-deleted`,
58
+ children: v("contents.includeDeleted")
68
59
  })]
69
60
  }),
70
- /* @__PURE__ */ g(o, { error: C.error })
61
+ /* @__PURE__ */ h(o, { error: S.error })
71
62
  ] }));
72
63
  }
73
- function b({ query: n = {}, selected: i, onSelect: o, client: c, className: l, appearance: u }) {
74
- let f = e(), { t: p } = f, m = d(n, { client: c }), h = (e) => {
64
+ function y({ query: n = {}, selected: i, onSelect: o, client: c, className: l, appearance: u }) {
65
+ let f = e(), { t: p } = f, m = d(n, { client: c }), v = (e) => {
75
66
  let [t, n, r] = e.split("-").map(Number), i = new Date(Date.UTC(t, (n ?? 1) - 1, r ?? 1));
76
67
  return new Intl.DateTimeFormat(f.language, r ? {
77
68
  dateStyle: "medium",
@@ -82,46 +73,46 @@ function b({ query: n = {}, selected: i, onSelect: o, client: c, className: l, a
82
73
  timeZone: "UTC"
83
74
  }).format(i);
84
75
  };
85
- return /* @__PURE__ */ _(t, {
76
+ return /* @__PURE__ */ g(t, {
86
77
  appearance: u,
87
- className: v("grid gap-2 text-sm", l),
78
+ className: _("grid gap-2 text-sm", l),
88
79
  "data-ckui": "release-dates",
89
- children: [m.loading && !m.items.length ? /* @__PURE__ */ g(a, { className: "h-24 w-full" }) : m.error && !m.items.length ? /* @__PURE__ */ _("div", {
80
+ children: [m.loading && !m.items.length ? /* @__PURE__ */ h(a, { className: "h-24 w-full" }) : m.error && !m.items.length ? /* @__PURE__ */ g("div", {
90
81
  role: "alert",
91
82
  className: "grid justify-items-start gap-2",
92
- children: [/* @__PURE__ */ g("p", {
83
+ children: [/* @__PURE__ */ h("p", {
93
84
  className: "text-destructive",
94
85
  children: s(f, m.error)
95
- }), /* @__PURE__ */ g(r, {
86
+ }), /* @__PURE__ */ h(r, {
96
87
  size: "sm",
97
88
  variant: "outline",
98
89
  onClick: m.reload,
99
90
  children: p("common.retry")
100
91
  })]
101
- }) : m.items.length ? /* @__PURE__ */ g("ul", {
92
+ }) : m.items.length ? /* @__PURE__ */ h("ul", {
102
93
  className: "grid gap-1",
103
- children: m.items.map((e) => /* @__PURE__ */ g("li", { children: /* @__PURE__ */ _("button", {
94
+ children: m.items.map((e) => /* @__PURE__ */ h("li", { children: /* @__PURE__ */ g("button", {
104
95
  type: "button",
105
96
  "aria-pressed": i === e.date,
106
- className: v("flex w-full items-center justify-between gap-3 rounded-md px-2 py-1.5 text-start hover:bg-muted", i === e.date && "bg-muted font-medium"),
97
+ className: _("flex w-full items-center justify-between gap-3 rounded-md px-2 py-1.5 text-start hover:bg-muted", i === e.date && "bg-muted font-medium"),
107
98
  onClick: () => o?.(e.date),
108
99
  "data-ckui": "release-date",
109
100
  "data-date": e.date,
110
- children: [/* @__PURE__ */ g("span", { children: h(e.date) }), /* @__PURE__ */ _("span", {
101
+ children: [/* @__PURE__ */ h("span", { children: v(e.date) }), /* @__PURE__ */ g("span", {
111
102
  className: "text-xs text-muted-foreground tabular-nums",
112
103
  children: [f.plural("contents.items", e.count), e.free < e.count && ` · ${f.plural("contents.free", e.free)}`]
113
104
  })]
114
105
  }) }, e.date))
115
- }) : /* @__PURE__ */ g("p", {
106
+ }) : /* @__PURE__ */ h("p", {
116
107
  className: "text-muted-foreground",
117
108
  children: p("contents.noDates")
118
- }), m.hasMore && /* @__PURE__ */ _("div", {
109
+ }), m.hasMore && /* @__PURE__ */ g("div", {
119
110
  className: "grid justify-items-center gap-2",
120
- children: [m.error && /* @__PURE__ */ g("p", {
111
+ children: [m.error && /* @__PURE__ */ h("p", {
121
112
  role: "alert",
122
113
  className: "text-destructive",
123
114
  children: s(f, m.error)
124
- }), /* @__PURE__ */ g(r, {
115
+ }), /* @__PURE__ */ h(r, {
125
116
  variant: "outline",
126
117
  size: "sm",
127
118
  disabled: m.loadingMore,
@@ -132,6 +123,6 @@ function b({ query: n = {}, selected: i, onSelect: o, client: c, className: l, a
132
123
  });
133
124
  }
134
125
  //#endregion
135
- export { y as ContentFilterSettings, b as ReleaseDateIndex };
126
+ export { v as ContentFilterSettings, y as ReleaseDateIndex };
136
127
 
137
128
  //# sourceMappingURL=filters.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"filters.js","names":[],"sources":["../../../src/components/content/filters.tsx"],"sourcesContent":["import { cn } from \"cn\";\nimport { useContext, useId } from \"react\";\nimport type { ContentKitUiAppearance } from \"../../appearance.js\";\nimport type { ContentKitClient } from \"../../client/client.js\";\nimport type { GroupCard } from \"../../client/generated/wire.js\";\nimport type { ReleaseDatesQuery } from \"../../client/discovery.js\";\nimport { useMessages } from \"../../i18n/context.js\";\nimport { ContentKitContext, type ContentKitErrorHandler } from \"../../react/context.js\";\nimport { useContentFilters, useReleaseDates } from \"../../react/discovery.js\";\nimport { ContentKitUiRoot } from \"../../scope.js\";\nimport { Button } from \"#ckui/ui/button\";\nimport { Label } from \"#ckui/ui/label\";\nimport { Skeleton } from \"#ckui/ui/skeleton\";\nimport { Switch } from \"#ckui/ui/switch\";\nimport { labelOf, type Labels } from \"../groups/parts.js\";\nimport { contentError, ErrorLine, useAction } from \"../social/parts.js\";\n\n/** Counts for one concrete listing selection, keyed by content kind and entity.\n * Only rows offered by the current domain's filter inventory are displayed. */\nexport interface ContentFilterCount {\n content_kind: string;\n entity: Pick<GroupCard, \"id\">;\n count: number;\n}\n\nexport interface ContentFilterSettingsProps {\n /** Content kinds to show. Omitted displays every configured kind. */\n kinds?: readonly string[];\n /** Display labels for content-kind sections, when more than one is shown. */\n labels?: Labels;\n /** Entity names in this language; default the provider's. */\n language?: string;\n /** Currently excluded matches in this listing/day; omitted shows no counts. */\n counts?: readonly ContentFilterCount[];\n /** Offer listing deleted content the reader holds. Default true. */\n includeDeleted?: boolean;\n client?: ContentKitClient;\n onError?: ContentKitErrorHandler;\n className?: string;\n appearance?: ContentKitUiAppearance;\n}\n\n/** Show or hide configured content for this browser or signed-in account. */\nexport function ContentFilterSettings(p: ContentFilterSettingsProps) {\n const m = useMessages();\n const { t } = m;\n const id = useId();\n const ctx = useContext(ContentKitContext);\n const f = useContentFilters({ language: p.language, client: p.client });\n const save = useAction(\"filters.save\", p.onError);\n const root = (children: React.ReactNode) => (\n <ContentKitUiRoot appearance={p.appearance} className={cn(\"grid gap-3 text-sm\", p.className)} data-ckui=\"content-filters\">\n {children}\n </ContentKitUiRoot>\n );\n if (!f.filters) {\n if (f.error) return root(<ErrorLine>{contentError(m, f.error)}</ErrorLine>);\n return root(<Skeleton className=\"h-24 w-full\" />);\n }\n const filters = f.filters;\n const groups = Object.entries(filters.kinds).filter(([kind, rows]) => rows.length && (!p.kinds || p.kinds.includes(kind)));\n if (!groups.length && p.includeDeleted === false) return null;\n return root(\n <>\n {groups.map(([kind, rows]) => (\n <section key={kind} className=\"grid gap-2\" data-content-kind={kind}>\n {groups.length > 1 && <h4 className=\"font-medium\">{labelOf(p.labels, kind)}</h4>}\n <ul className=\"grid divide-y divide-border rounded-lg border border-border\">\n {rows.map((x) => (\n <li key={x.entity.id} className=\"flex flex-wrap items-center gap-3 p-3\" data-ckui=\"content-filter\" data-kind={kind} data-slug={x.entity.slug} data-visible={x.visible}>\n <Switch id={`${id}-${kind}-${x.entity.id}`} checked={x.visible} disabled={save.pending} onCheckedChange={(v) => void save.run(() => f.setVisible(kind, x.entity.id, v))} />\n <Label htmlFor={`${id}-${kind}-${x.entity.id}`} className=\"min-w-0 flex-1\">\n {x.entity.name || x.entity.slug}\n {p.counts !== undefined && <span className=\"tabular-nums\">: {new Intl.NumberFormat(m.language).format(p.counts.find((entry) => entry.content_kind === kind && entry.entity.id === x.entity.id)?.count ?? 0)}</span>}\n </Label>\n </li>\n ))}\n </ul>\n </section>\n ))}\n {p.includeDeleted !== false && ctx?.viewer !== null && (\n <div className=\"flex items-center gap-3\">\n <Switch id={`${id}-deleted`} checked={filters.include_deleted} disabled={save.pending} onCheckedChange={(v) => void save.run(() => f.setIncludeDeleted(v))} />\n <Label htmlFor={`${id}-deleted`}>{t(\"contents.includeDeleted\")}</Label>\n </div>\n )}\n <ErrorLine error={save.error} />\n </>,\n );\n}\n\nexport interface ReleaseDateIndexProps {\n /** Which contents count: the listing's filters. */\n query?: ReleaseDatesQuery;\n /** The bucket chosen (a day YYYY-MM-DD or month YYYY-MM): list with released_on set to it. */\n selected?: string;\n onSelect?: (date: string) => void;\n client?: ContentKitClient;\n className?: string;\n appearance?: ContentKitUiAppearance;\n}\n\n/** The release date index: per month or day, newest first, how many contents and how many free. */\nexport function ReleaseDateIndex({ query = {}, selected, onSelect, client, className, appearance }: ReleaseDateIndexProps) {\n const m = useMessages();\n const { t } = m;\n const dates = useReleaseDates(query, { client });\n const label = (date: string) => {\n const [y, mo, d] = date.split(\"-\").map(Number);\n const at = new Date(Date.UTC(y!, (mo ?? 1) - 1, d ?? 1));\n return new Intl.DateTimeFormat(m.language, d ? { dateStyle: \"medium\", timeZone: \"UTC\" } : { year: \"numeric\", month: \"long\", timeZone: \"UTC\" }).format(at);\n };\n return (\n <ContentKitUiRoot appearance={appearance} className={cn(\"grid gap-2 text-sm\", className)} data-ckui=\"release-dates\">\n {dates.loading && !dates.items.length ? (\n <Skeleton className=\"h-24 w-full\" />\n ) : dates.error && !dates.items.length ? (\n <div role=\"alert\" className=\"grid justify-items-start gap-2\">\n <p className=\"text-destructive\">{contentError(m, dates.error)}</p>\n <Button size=\"sm\" variant=\"outline\" onClick={dates.reload}>\n {t(\"common.retry\")}\n </Button>\n </div>\n ) : !dates.items.length ? (\n <p className=\"text-muted-foreground\">{t(\"contents.noDates\")}</p>\n ) : (\n <ul className=\"grid gap-1\">\n {dates.items.map((d) => (\n <li key={d.date}>\n <button\n type=\"button\"\n aria-pressed={selected === d.date}\n className={cn(\"flex w-full items-center justify-between gap-3 rounded-md px-2 py-1.5 text-start hover:bg-muted\", selected === d.date && \"bg-muted font-medium\")}\n onClick={() => onSelect?.(d.date)}\n data-ckui=\"release-date\"\n data-date={d.date}\n >\n <span>{label(d.date)}</span>\n <span className=\"text-xs text-muted-foreground tabular-nums\">\n {m.plural(\"contents.items\", d.count)}\n {d.free < d.count && ` · ${m.plural(\"contents.free\", d.free)}`}\n </span>\n </button>\n </li>\n ))}\n </ul>\n )}\n {dates.hasMore && (\n <div className=\"grid justify-items-center gap-2\">\n {dates.error && <p role=\"alert\" className=\"text-destructive\">{contentError(m, dates.error)}</p>}\n <Button variant=\"outline\" size=\"sm\" disabled={dates.loadingMore} onClick={() => void dates.loadMore()}>\n {dates.loadingMore ? t(\"contents.loading\") : dates.error ? t(\"common.retry\") : t(\"contents.loadMore\")}\n </Button>\n </div>\n )}\n </ContentKitUiRoot>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"filters.js","names":[],"sources":["../../../src/components/content/filters.tsx"],"sourcesContent":["import { cn } from \"cn\";\nimport { useContext, useId } from \"react\";\nimport type { ContentKitUiAppearance } from \"../../appearance.js\";\nimport type { ContentKitClient } from \"../../client/client.js\";\nimport type { GroupCard } from \"../../client/generated/wire.js\";\nimport type { ReleaseDatesQuery } from \"../../client/discovery.js\";\nimport { useMessages } from \"../../i18n/context.js\";\nimport { ContentKitContext, type ContentKitErrorHandler } from \"../../react/context.js\";\nimport { useContentFilters, useReleaseDates } from \"../../react/discovery.js\";\nimport { ContentKitUiRoot } from \"../../scope.js\";\nimport { Button } from \"#ckui/ui/button\";\nimport { Label } from \"#ckui/ui/label\";\nimport { Skeleton } from \"#ckui/ui/skeleton\";\nimport { Switch } from \"#ckui/ui/switch\";\nimport { contentError, ErrorLine, useAction } from \"../social/parts.js\";\n\n/** Counts for one concrete listing selection, aggregated by entity.\n * Only rows offered by the current domain's filter inventory are displayed. */\nexport interface ContentFilterCount {\n entity: Pick<GroupCard, \"id\">;\n count: number;\n}\n\nexport interface ContentFilterSettingsProps {\n /** Listing context; shows shared controls when any kind is in applies_to. */\n kinds?: readonly string[];\n /** Entity names in this language; default the provider's. */\n language?: string;\n /** Currently excluded matches in this listing/day; omitted shows no counts. */\n counts?: readonly ContentFilterCount[];\n /** Offer listing deleted content the reader holds. Default true. */\n includeDeleted?: boolean;\n client?: ContentKitClient;\n onError?: ContentKitErrorHandler;\n className?: string;\n appearance?: ContentKitUiAppearance;\n}\n\n/** Show or hide configured content for this browser or signed-in account. */\nexport function ContentFilterSettings(p: ContentFilterSettingsProps) {\n const m = useMessages();\n const { t } = m;\n const id = useId();\n const ctx = useContext(ContentKitContext);\n const f = useContentFilters({ language: p.language, client: p.client });\n const save = useAction(\"filters.save\", p.onError);\n const root = (children: React.ReactNode) => (\n <ContentKitUiRoot appearance={p.appearance} className={cn(\"grid gap-3 text-sm\", p.className)} data-ckui=\"content-filters\">\n {children}\n </ContentKitUiRoot>\n );\n if (!f.filters) {\n if (f.error) return root(<ErrorLine>{contentError(m, f.error)}</ErrorLine>);\n return root(<Skeleton className=\"h-24 w-full\" />);\n }\n const filters = f.filters;\n const rows = !p.kinds || p.kinds.some((kind) => filters.applies_to.includes(kind)) ? filters.filters : [];\n if (!rows.length && p.includeDeleted === false) return null;\n return root(\n <>\n {rows.length > 0 && (\n <ul className=\"grid divide-y divide-border rounded-lg border border-border\">\n {rows.map((x) => (\n <li key={x.entity.id} className=\"flex flex-wrap items-center gap-3 p-3\" data-ckui=\"content-filter\" data-slug={x.entity.slug} data-visible={x.visible}>\n <Switch id={`${id}-${x.entity.id}`} checked={x.visible} disabled={save.pending} onCheckedChange={(v) => void save.run(() => f.setVisible(x.entity.id, v))} />\n <Label htmlFor={`${id}-${x.entity.id}`} className=\"min-w-0 flex-1\">\n {x.entity.name || x.entity.slug}\n {p.counts !== undefined && (\n <span className=\"tabular-nums\">: {new Intl.NumberFormat(m.language).format(p.counts.filter((entry) => entry.entity.id === x.entity.id).reduce((n, entry) => n + entry.count, 0))}</span>\n )}\n </Label>\n </li>\n ))}\n </ul>\n )}\n {p.includeDeleted !== false && ctx?.viewer !== null && (\n <div className=\"flex items-center gap-3\">\n <Switch id={`${id}-deleted`} checked={filters.include_deleted} disabled={save.pending} onCheckedChange={(v) => void save.run(() => f.setIncludeDeleted(v))} />\n <Label htmlFor={`${id}-deleted`}>{t(\"contents.includeDeleted\")}</Label>\n </div>\n )}\n <ErrorLine error={save.error} />\n </>,\n );\n}\n\nexport interface ReleaseDateIndexProps {\n /** Which contents count: the listing's filters. */\n query?: ReleaseDatesQuery;\n /** The bucket chosen (a day YYYY-MM-DD or month YYYY-MM): list with released_on set to it. */\n selected?: string;\n onSelect?: (date: string) => void;\n client?: ContentKitClient;\n className?: string;\n appearance?: ContentKitUiAppearance;\n}\n\n/** The release date index: per month or day, newest first, how many contents and how many free. */\nexport function ReleaseDateIndex({ query = {}, selected, onSelect, client, className, appearance }: ReleaseDateIndexProps) {\n const m = useMessages();\n const { t } = m;\n const dates = useReleaseDates(query, { client });\n const label = (date: string) => {\n const [y, mo, d] = date.split(\"-\").map(Number);\n const at = new Date(Date.UTC(y!, (mo ?? 1) - 1, d ?? 1));\n return new Intl.DateTimeFormat(m.language, d ? { dateStyle: \"medium\", timeZone: \"UTC\" } : { year: \"numeric\", month: \"long\", timeZone: \"UTC\" }).format(at);\n };\n return (\n <ContentKitUiRoot appearance={appearance} className={cn(\"grid gap-2 text-sm\", className)} data-ckui=\"release-dates\">\n {dates.loading && !dates.items.length ? (\n <Skeleton className=\"h-24 w-full\" />\n ) : dates.error && !dates.items.length ? (\n <div role=\"alert\" className=\"grid justify-items-start gap-2\">\n <p className=\"text-destructive\">{contentError(m, dates.error)}</p>\n <Button size=\"sm\" variant=\"outline\" onClick={dates.reload}>\n {t(\"common.retry\")}\n </Button>\n </div>\n ) : !dates.items.length ? (\n <p className=\"text-muted-foreground\">{t(\"contents.noDates\")}</p>\n ) : (\n <ul className=\"grid gap-1\">\n {dates.items.map((d) => (\n <li key={d.date}>\n <button\n type=\"button\"\n aria-pressed={selected === d.date}\n className={cn(\"flex w-full items-center justify-between gap-3 rounded-md px-2 py-1.5 text-start hover:bg-muted\", selected === d.date && \"bg-muted font-medium\")}\n onClick={() => onSelect?.(d.date)}\n data-ckui=\"release-date\"\n data-date={d.date}\n >\n <span>{label(d.date)}</span>\n <span className=\"text-xs text-muted-foreground tabular-nums\">\n {m.plural(\"contents.items\", d.count)}\n {d.free < d.count && ` · ${m.plural(\"contents.free\", d.free)}`}\n </span>\n </button>\n </li>\n ))}\n </ul>\n )}\n {dates.hasMore && (\n <div className=\"grid justify-items-center gap-2\">\n {dates.error && <p role=\"alert\" className=\"text-destructive\">{contentError(m, dates.error)}</p>}\n <Button variant=\"outline\" size=\"sm\" disabled={dates.loadingMore} onClick={() => void dates.loadMore()}>\n {dates.loadingMore ? t(\"contents.loading\") : dates.error ? t(\"common.retry\") : t(\"contents.loadMore\")}\n </Button>\n </div>\n )}\n </ContentKitUiRoot>\n );\n}\n"],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  export { ContentCard, OwnerChip, PostCard, lockLabel, type CardMetadata, type ContentCardProps, type PostCardProps } from './card.js';
2
2
  export { cardGridLayout, CardGrid, ContentGrid, ContentHistory, ContentRail, SearchResults, type CardGridLayout, type CardListProps, type ContentRailProps, type LockedCards } from './grid.js';
3
3
  export { DailyReleases, type DailyReleasesProps } from './daily-releases.js';
4
+ export { ReleaseDatePicker, isReleaseDate, localReleaseDate, type ReleaseDatePickerProps } from './release-date-picker.js';
4
5
  export { PopularContentGrid, type PopularContentGridProps } from './popular.js';
5
6
  export { SearchBox, type SearchBoxProps } from './search.js';
6
7
  export { ReaderSettings, type ReaderSettingsProps } from './reader-settings.js';
@@ -5,7 +5,6 @@ import { ContentFilterSettingsProps } from './filters.js';
5
5
  export interface ReaderSettingsProps {
6
6
  /** Content kinds offered in this dialog; omitted shows all configured kinds. */
7
7
  kinds?: ContentFilterSettingsProps["kinds"];
8
- labels?: ContentFilterSettingsProps["labels"];
9
8
  languages: readonly {
10
9
  value: string;
11
10
  label: string;