@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.
- package/README.md +36 -13
- package/dist/client/browser-reader-preferences.d.ts +8 -9
- package/dist/client/browser-reader-preferences.js +71 -63
- package/dist/client/browser-reader-preferences.js.map +1 -1
- package/dist/client/discovery.d.ts +3 -1
- package/dist/client/discovery.js +2 -2
- package/dist/client/discovery.js.map +1 -1
- package/dist/client/generated/routes.d.ts +2 -2
- package/dist/client/generated/routes.js +2 -1
- package/dist/client/generated/routes.js.map +1 -1
- package/dist/client/generated/wire.d.ts +5 -10
- package/dist/client/generated/wire.js.map +1 -1
- package/dist/client/http.d.ts +3 -4
- package/dist/client/http.js +7 -15
- package/dist/client/http.js.map +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/reader-preferences.d.ts +2 -2
- package/dist/client/reader-preferences.js +2 -6
- package/dist/client/reader-preferences.js.map +1 -1
- package/dist/components/content/daily-releases.js +39 -43
- package/dist/components/content/daily-releases.js.map +1 -1
- package/dist/components/content/filters.d.ts +2 -6
- package/dist/components/content/filters.js +57 -66
- package/dist/components/content/filters.js.map +1 -1
- package/dist/components/content/index.d.ts +1 -0
- package/dist/components/content/reader-settings.d.ts +0 -1
- package/dist/components/content/reader-settings.js +1 -2
- package/dist/components/content/reader-settings.js.map +1 -1
- package/dist/components/content/release-date-picker.d.ts +16 -0
- package/dist/components/content/release-date-picker.js +65 -0
- package/dist/components/content/release-date-picker.js.map +1 -0
- package/dist/index.js +22 -21
- package/dist/locales/discovery/de.js +3 -0
- package/dist/locales/discovery/de.js.map +1 -1
- package/dist/locales/discovery/en.d.ts +3 -0
- package/dist/locales/discovery/en.js +3 -0
- package/dist/locales/discovery/en.js.map +1 -1
- package/dist/locales/discovery/es.js +3 -0
- package/dist/locales/discovery/es.js.map +1 -1
- package/dist/locales/discovery/ja.js +3 -0
- package/dist/locales/discovery/ja.js.map +1 -1
- package/dist/locales/discovery/ko.js +3 -0
- package/dist/locales/discovery/ko.js.map +1 -1
- package/dist/locales/discovery/zh.js +3 -0
- package/dist/locales/discovery/zh.js.map +1 -1
- package/dist/locales/en.d.ts +3 -0
- package/dist/react/discovery.d.ts +3 -5
- package/dist/react/discovery.js +42 -71
- package/dist/react/discovery.js.map +1 -1
- package/dist/react/provider.js +1 -4
- package/dist/react/provider.js.map +1 -1
- package/dist/styles.css +1 -1
- 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
|
|
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: [
|
|
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 && !
|
|
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 && !
|
|
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(
|
|
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
|
-
|
|
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"
|
|
113
|
-
|
|
114
|
-
|
|
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
|
|
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
|
-
|
|
128
|
+
B,
|
|
132
129
|
o,
|
|
133
130
|
j
|
|
134
|
-
]),
|
|
131
|
+
]), W = b(() => v && !i ? U.filter((e) => !e.summary).map((e) => e.card) : [], [
|
|
135
132
|
v,
|
|
136
133
|
i,
|
|
137
|
-
|
|
138
|
-
]),
|
|
134
|
+
U
|
|
135
|
+
]), G = f(W, {
|
|
139
136
|
surface: a.surface ?? "releases",
|
|
140
137
|
render: e.date,
|
|
141
138
|
client: a.client
|
|
142
|
-
}),
|
|
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`)),
|
|
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
|
-
},
|
|
148
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
187
|
-
className: T(
|
|
188
|
-
style:
|
|
189
|
-
children: [
|
|
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?.(
|
|
197
|
-
onClick:
|
|
198
|
-
}, e.key) : /* @__PURE__ */ C(
|
|
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:
|
|
199
|
+
exposure: G,
|
|
203
200
|
cardProps: a
|
|
204
|
-
}, e.key)), e.filtered_count > 0 && /* @__PURE__ */ C(
|
|
201
|
+
}, e.key)), e.filtered_count > 0 && /* @__PURE__ */ C(P, {
|
|
205
202
|
tileKey: "filtered-summary",
|
|
206
|
-
contentKind:
|
|
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
|
-
|
|
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
|
-
|
|
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 &&
|
|
230
|
-
open:
|
|
231
|
-
onOpenChange:
|
|
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:
|
|
233
|
+
description: p.t("releases.filterContext", { date: J }),
|
|
238
234
|
appearance: a.appearance
|
|
239
235
|
})
|
|
240
236
|
]
|
|
241
237
|
});
|
|
242
238
|
}
|
|
243
|
-
function
|
|
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
|
|
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
|
-
|
|
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
|
-
/**
|
|
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 {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
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
|
|
16
|
-
let d = e(), { t:
|
|
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
|
-
}),
|
|
18
|
+
}), S = c("filters.save", r.onError), C = (e) => /* @__PURE__ */ h(t, {
|
|
20
19
|
appearance: r.appearance,
|
|
21
|
-
className:
|
|
20
|
+
className: _("grid gap-3 text-sm", r.className),
|
|
22
21
|
"data-ckui": "content-filters",
|
|
23
22
|
children: e
|
|
24
23
|
});
|
|
25
|
-
if (!
|
|
26
|
-
let
|
|
27
|
-
return !
|
|
28
|
-
|
|
29
|
-
className: "grid
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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
|
-
}
|
|
56
|
-
})
|
|
57
|
-
}
|
|
58
|
-
r.includeDeleted !== !1 &&
|
|
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__ */
|
|
61
|
-
id: `${
|
|
62
|
-
checked:
|
|
63
|
-
disabled:
|
|
64
|
-
onCheckedChange: (e) => void
|
|
65
|
-
}), /* @__PURE__ */
|
|
66
|
-
htmlFor: `${
|
|
67
|
-
children:
|
|
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__ */
|
|
61
|
+
/* @__PURE__ */ h(o, { error: S.error })
|
|
71
62
|
] }));
|
|
72
63
|
}
|
|
73
|
-
function
|
|
74
|
-
let f = e(), { t: p } = f, m = d(n, { client: c }),
|
|
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__ */
|
|
76
|
+
return /* @__PURE__ */ g(t, {
|
|
86
77
|
appearance: u,
|
|
87
|
-
className:
|
|
78
|
+
className: _("grid gap-2 text-sm", l),
|
|
88
79
|
"data-ckui": "release-dates",
|
|
89
|
-
children: [m.loading && !m.items.length ? /* @__PURE__ */
|
|
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__ */
|
|
83
|
+
children: [/* @__PURE__ */ h("p", {
|
|
93
84
|
className: "text-destructive",
|
|
94
85
|
children: s(f, m.error)
|
|
95
|
-
}), /* @__PURE__ */
|
|
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__ */
|
|
92
|
+
}) : m.items.length ? /* @__PURE__ */ h("ul", {
|
|
102
93
|
className: "grid gap-1",
|
|
103
|
-
children: m.items.map((e) => /* @__PURE__ */
|
|
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:
|
|
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__ */
|
|
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__ */
|
|
106
|
+
}) : /* @__PURE__ */ h("p", {
|
|
116
107
|
className: "text-muted-foreground",
|
|
117
108
|
children: p("contents.noDates")
|
|
118
|
-
}), m.hasMore && /* @__PURE__ */
|
|
109
|
+
}), m.hasMore && /* @__PURE__ */ g("div", {
|
|
119
110
|
className: "grid justify-items-center gap-2",
|
|
120
|
-
children: [m.error && /* @__PURE__ */
|
|
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__ */
|
|
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 {
|
|
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;
|