@openrails/contentkit-ui 0.93.1 → 0.95.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 (74) hide show
  1. package/README.md +77 -5
  2. package/dist/client/browser-reader-preferences.d.ts +38 -0
  3. package/dist/client/browser-reader-preferences.js +172 -0
  4. package/dist/client/browser-reader-preferences.js.map +1 -0
  5. package/dist/client/client.d.ts +3 -0
  6. package/dist/client/client.js +27 -25
  7. package/dist/client/client.js.map +1 -1
  8. package/dist/client/discovery.d.ts +14 -1
  9. package/dist/client/discovery.js +36 -22
  10. package/dist/client/discovery.js.map +1 -1
  11. package/dist/client/generated/routes.d.ts +33 -7
  12. package/dist/client/generated/routes.js +57 -2
  13. package/dist/client/generated/routes.js.map +1 -1
  14. package/dist/client/generated/wire.d.ts +15 -0
  15. package/dist/client/generated/wire.js.map +1 -1
  16. package/dist/client/http.d.ts +18 -1
  17. package/dist/client/http.js +67 -26
  18. package/dist/client/http.js.map +1 -1
  19. package/dist/client/index.d.ts +3 -1
  20. package/dist/client/reader-preferences.d.ts +46 -0
  21. package/dist/client/reader-preferences.js +147 -0
  22. package/dist/client/reader-preferences.js.map +1 -0
  23. package/dist/client.js +17 -15
  24. package/dist/components/content/card.d.ts +21 -5
  25. package/dist/components/content/card.js +80 -67
  26. package/dist/components/content/card.js.map +1 -1
  27. package/dist/components/content/daily-releases.d.ts +15 -0
  28. package/dist/components/content/daily-releases.js +167 -0
  29. package/dist/components/content/daily-releases.js.map +1 -0
  30. package/dist/components/content/filters.d.ts +1 -1
  31. package/dist/components/content/filters.js +1 -5
  32. package/dist/components/content/filters.js.map +1 -1
  33. package/dist/components/content/grid.d.ts +14 -1
  34. package/dist/components/content/grid.js +58 -32
  35. package/dist/components/content/grid.js.map +1 -1
  36. package/dist/components/content/index.d.ts +4 -2
  37. package/dist/components/content/popular.d.ts +11 -0
  38. package/dist/components/content/popular.js +49 -0
  39. package/dist/components/content/popular.js.map +1 -0
  40. package/dist/components/content/reader-settings.d.ts +1 -1
  41. package/dist/components/content/reader-settings.js +67 -44
  42. package/dist/components/content/reader-settings.js.map +1 -1
  43. package/dist/index.js +22 -20
  44. package/dist/locales/discovery/de.js +6 -0
  45. package/dist/locales/discovery/de.js.map +1 -1
  46. package/dist/locales/discovery/en.d.ts +6 -0
  47. package/dist/locales/discovery/en.js +6 -0
  48. package/dist/locales/discovery/en.js.map +1 -1
  49. package/dist/locales/discovery/es.js +6 -0
  50. package/dist/locales/discovery/es.js.map +1 -1
  51. package/dist/locales/discovery/ja.js +6 -0
  52. package/dist/locales/discovery/ja.js.map +1 -1
  53. package/dist/locales/discovery/ko.js +6 -0
  54. package/dist/locales/discovery/ko.js.map +1 -1
  55. package/dist/locales/discovery/zh.js +6 -0
  56. package/dist/locales/discovery/zh.js.map +1 -1
  57. package/dist/locales/en.d.ts +6 -0
  58. package/dist/react/context.d.ts +1 -1
  59. package/dist/react/context.js.map +1 -1
  60. package/dist/react/discovery.d.ts +14 -4
  61. package/dist/react/discovery.js +196 -149
  62. package/dist/react/discovery.js.map +1 -1
  63. package/dist/react/index.d.ts +2 -1
  64. package/dist/react/provider.d.ts +4 -1
  65. package/dist/react/provider.js +38 -31
  66. package/dist/react/provider.js.map +1 -1
  67. package/dist/react/reader-preferences.d.ts +13 -0
  68. package/dist/react/reader-preferences.js +15 -0
  69. package/dist/react/reader-preferences.js.map +1 -0
  70. package/dist/react/resources.js +11 -11
  71. package/dist/react/resources.js.map +1 -1
  72. package/dist/react.js +10 -9
  73. package/dist/styles.css +1 -1
  74. package/package.json +1 -1
@@ -0,0 +1,167 @@
1
+ import { useMessages as e } from "../../i18n/context.js";
2
+ import { ContentKitUiRoot as t } from "../../scope.js";
3
+ import { useContentScope as n } from "../../react/use-resource.js";
4
+ import { Button as r } from "../../ui/button.js";
5
+ import { useNearViewport as i } from "../../react/viewport.js";
6
+ import { Skeleton as a } from "../../ui/skeleton.js";
7
+ import { contentError as o } from "../social/parts.js";
8
+ import { useDailyReleases as s, useExposure as c } from "../../react/discovery.js";
9
+ import { ContentCard as l } from "./card.js";
10
+ import { cardGridLayout as u } from "./grid.js";
11
+ import { useCallback as d, useId as f, useMemo as p, useState as m } from "react";
12
+ import { jsx as h, jsxs as g } from "react/jsx-runtime";
13
+ import { cn as _ } from "cn";
14
+ import { ArrowDown01Icon as v } from "@hugeicons/core-free-icons";
15
+ import { HugeiconsIcon as y } from "@hugeicons/react";
16
+ //#region src/components/content/daily-releases.tsx
17
+ var b = (e, t) => Number.isFinite(e) ? Math.max(0, Math.floor(e)) : t;
18
+ function x({ query: i, initialVisible: c = 30, revealStep: l = 30, ...d }) {
19
+ let f = e(), { scope: m } = n(d.client), v = p(() => ({
20
+ days: 10,
21
+ time_zone: Intl.DateTimeFormat().resolvedOptions().timeZone,
22
+ ...i
23
+ }), [i]), y = s(v, { client: d.client }), x = u(d.grid), C = p(() => y.data?.days.filter((e) => e.contents.length).sort((e, t) => t.date.localeCompare(e.date)) ?? [], [y.data]), w = b(c, 30);
24
+ return /* @__PURE__ */ h(t, {
25
+ appearance: d.appearance,
26
+ className: _("grid gap-6 text-sm", d.className),
27
+ "data-ckui": "daily-releases",
28
+ "aria-busy": y.loading,
29
+ children: y.loading && !y.data ? /* @__PURE__ */ h("div", {
30
+ className: x.className,
31
+ style: x.style,
32
+ children: Array.from({ length: 6 }, (e, t) => /* @__PURE__ */ h(a, { className: "aspect-[3/4]" }, t))
33
+ }) : y.error && !y.data ? /* @__PURE__ */ g("div", {
34
+ role: "alert",
35
+ className: "grid justify-items-start gap-2",
36
+ children: [/* @__PURE__ */ h("p", {
37
+ className: "text-destructive",
38
+ children: o(f, y.error)
39
+ }), /* @__PURE__ */ h(r, {
40
+ size: "sm",
41
+ variant: "outline",
42
+ onClick: y.reload,
43
+ children: f.t("common.retry")
44
+ })]
45
+ }) : C.length ? C.map((e) => {
46
+ let t = Math.min(w, e.contents.length);
47
+ return w -= t, /* @__PURE__ */ h(S, {
48
+ day: e,
49
+ initial: t,
50
+ step: Math.max(1, b(l, 30)),
51
+ cardProps: d
52
+ }, JSON.stringify([
53
+ m,
54
+ v,
55
+ y.data?.from_date,
56
+ e.date
57
+ ]));
58
+ }) : /* @__PURE__ */ h("p", {
59
+ role: "status",
60
+ className: "text-muted-foreground",
61
+ children: d.empty ?? f.t("contents.empty")
62
+ })
63
+ });
64
+ }
65
+ function S({ day: t, initial: n, step: i, cardProps: a }) {
66
+ let o = e(), s = f(), [l, d] = m(n > 0), [b, x] = m(n), S = p(() => t.contents.slice(0, b), [t.contents, b]), w = p(() => l ? S : [], [l, S]), T = c(w, {
67
+ surface: a.surface ?? "releases",
68
+ render: t.date,
69
+ client: a.client
70
+ }), E = u(a.grid), D = new Intl.DateTimeFormat(o.language, {
71
+ dateStyle: "full",
72
+ timeZone: "UTC"
73
+ }).format(/* @__PURE__ */ new Date(`${t.date}T12:00:00Z`));
74
+ return /* @__PURE__ */ g("section", {
75
+ "data-ckui": "release-day",
76
+ "data-date": t.date,
77
+ children: [/* @__PURE__ */ h("h2", { children: /* @__PURE__ */ g(r, {
78
+ id: `${s}-heading`,
79
+ type: "button",
80
+ variant: "ghost",
81
+ className: "h-auto w-full justify-start gap-3 px-0 py-3 text-start text-lg font-semibold",
82
+ "aria-expanded": l,
83
+ "aria-controls": `${s}-contents`,
84
+ onClick: () => {
85
+ !l && !b && x(Math.min(i, t.contents.length)), d(!l);
86
+ },
87
+ children: [
88
+ /* @__PURE__ */ h(y, {
89
+ icon: v,
90
+ strokeWidth: 2,
91
+ className: _("size-5 shrink-0 transition-transform duration-200 motion-reduce:transition-none", !l && "-rotate-90"),
92
+ "aria-hidden": !0
93
+ }),
94
+ /* @__PURE__ */ h("time", {
95
+ dateTime: t.date,
96
+ children: D
97
+ }),
98
+ /* @__PURE__ */ h("span", {
99
+ className: "ml-auto shrink-0 text-sm font-normal text-muted-foreground",
100
+ children: o.plural("contents.items", t.contents.length)
101
+ })
102
+ ]
103
+ }) }), /* @__PURE__ */ h("div", {
104
+ id: `${s}-contents`,
105
+ role: "region",
106
+ "aria-labelledby": `${s}-heading`,
107
+ "aria-hidden": !l,
108
+ inert: !l,
109
+ className: _("grid transition-[grid-template-rows,opacity] duration-250 ease-out motion-reduce:transition-none", l ? "grid-rows-[1fr] opacity-100" : "grid-rows-[0fr] opacity-0"),
110
+ children: /* @__PURE__ */ g("div", {
111
+ className: "min-h-0 overflow-hidden",
112
+ children: [/* @__PURE__ */ h("ol", {
113
+ className: _(E.className, "pt-2"),
114
+ style: E.style,
115
+ children: S.map((e, t) => /* @__PURE__ */ h(C, {
116
+ card: e,
117
+ open: l,
118
+ position: t + 1,
119
+ exposure: T,
120
+ cardProps: a
121
+ }, e.id))
122
+ }), b < t.contents.length && /* @__PURE__ */ h("div", {
123
+ className: "flex justify-center pt-5 pb-1",
124
+ children: /* @__PURE__ */ h(r, {
125
+ type: "button",
126
+ variant: "outline",
127
+ onClick: () => x((e) => Math.min(e + i, t.contents.length)),
128
+ children: o.t("contents.showMore")
129
+ })
130
+ })]
131
+ })
132
+ })]
133
+ });
134
+ }
135
+ function C({ card: e, open: t, position: n, exposure: r, cardProps: a }) {
136
+ let [o, s] = i({ margin: "0px" }), c = p(() => r.track(e.id, n), [
137
+ r,
138
+ e.id,
139
+ n
140
+ ]), u = d((e) => {
141
+ o(e), c(e);
142
+ }, [o, c]);
143
+ return /* @__PURE__ */ h("li", {
144
+ ref: u,
145
+ children: /* @__PURE__ */ h(l, {
146
+ card: e,
147
+ href: a.href,
148
+ shape: a.shape,
149
+ loadMedia: t && s,
150
+ groupKinds: a.groupKinds,
151
+ chips: a.chips,
152
+ filterEntity: a.filterEntity,
153
+ metadata: a.metadata,
154
+ showCounts: a.showCounts,
155
+ tiers: a.tiers,
156
+ labels: a.labels,
157
+ owner: a.owner,
158
+ ownerHref: a.ownerHref,
159
+ decorate: a.decorate,
160
+ onOpen: () => r.click(e.id, n)
161
+ })
162
+ });
163
+ }
164
+ //#endregion
165
+ export { x as DailyReleases };
166
+
167
+ //# sourceMappingURL=daily-releases.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daily-releases.js","names":[],"sources":["../../../src/components/content/daily-releases.tsx"],"sourcesContent":["import { ArrowDown01Icon } from \"@hugeicons/core-free-icons\";\nimport { HugeiconsIcon } from \"@hugeicons/react\";\nimport { cn } from \"cn\";\nimport { useCallback, useId, useMemo, useState } 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 { useContentScope } from \"../../react/use-resource.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 { 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 /** 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, ...p }: DailyReleasesProps) {\n const m = useMessages();\n const { scope } = useContentScope(p.client);\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 days = useMemo(() => releases.data?.days.filter((day) => day.contents.length).sort((a, b) => b.date.localeCompare(a.date)) ?? [], [releases.data]);\n let remaining = count(initialVisible, 30);\n return (\n <ContentKitUiRoot appearance={p.appearance} className={cn(\"grid gap-6 text-sm\", p.className)} data-ckui=\"daily-releases\" aria-busy={releases.loading}>\n {releases.loading && !releases.data ? <div className={layout.className} style={layout.style}>{Array.from({ length: 6 }, (_, i) => <Skeleton key={i} className=\"aspect-[3/4]\" />)}</div> : releases.error && !releases.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([scope, request, releases.data?.from_date, day.date])} day={day} initial={initial} step={Math.max(1, count(revealStep, 30))} cardProps={p} />;\n })}\n </ContentKitUiRoot>\n );\n}\n\nfunction ReleaseDaySection({ day, initial, step, cardProps: p }: { day: ReleaseDay; initial: number; step: number; cardProps: Omit<DailyReleasesProps, \"query\" | \"initialVisible\" | \"revealStep\"> }) {\n const m = useMessages();\n const id = useId();\n const [open, setOpen] = useState(initial > 0);\n const [visible, setVisible] = useState(initial);\n const cards = useMemo(() => day.contents.slice(0, visible), [day.contents, visible]);\n const exposed = useMemo(() => open ? cards : [], [open, cards]);\n const exposure = useExposure(exposed, { surface: p.surface ?? \"releases\", render: day.date, client: p.client });\n const layout = cardGridLayout(p.grid);\n // The server already assigned the calendar day in the requested time zone.\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 return (\n <section data-ckui=\"release-day\" data-date={day.date}>\n <h2>\n <Button 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 <span className=\"ml-auto shrink-0 text-sm font-normal text-muted-foreground\">{m.plural(\"contents.items\", day.contents.length)}</span>\n </Button>\n </h2>\n <div id={`${id}-contents`} role=\"region\" aria-labelledby={`${id}-heading`} aria-hidden={!open} inert={!open} 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 className={cn(layout.className, \"pt-2\")} style={layout.style}>\n {cards.map((card, i) => <ReleaseCard key={card.id} card={card} open={open} position={i + 1} exposure={exposure} cardProps={p} />)}\n </ol>\n {visible < day.contents.length && <div className=\"flex justify-center pt-5 pb-1\"><Button type=\"button\" variant=\"outline\" onClick={() => setVisible((n) => Math.min(n + step, day.contents.length))}>{m.t(\"contents.showMore\")}</Button></div>}\n </div>\n </div>\n </section>\n );\n}\n\nfunction ReleaseCard({ card, open, position, exposure, cardProps: p }: { card: Card; open: boolean; position: number; exposure: ReturnType<typeof useExposure>; cardProps: Omit<DailyReleasesProps, \"query\" | \"initialVisible\" | \"revealStep\"> }) {\n const [viewport, visible] = useNearViewport({ margin: \"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}>\n <ContentCard card={card} href={p.href} shape={p.shape} loadMedia={open && visible} groupKinds={p.groupKinds} chips={p.chips} filterEntity={p.filterEntity} 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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"}
@@ -12,7 +12,7 @@ export interface ContentFilterSettingsProps {
12
12
  className?: string;
13
13
  appearance?: ContentKitUiAppearance;
14
14
  }
15
- /** The signed-in reader's content filters: show or hide each configured group. */
15
+ /** Show or hide configured content for this browser or signed-in account. */
16
16
  export declare function ContentFilterSettings(p: ContentFilterSettingsProps): import('react').JSX.Element | null;
17
17
  export interface ReleaseDateIndexProps {
18
18
  /** Which contents count: the listing's filters. */
@@ -21,10 +21,6 @@ function v(r) {
21
21
  "data-ckui": "content-filters",
22
22
  children: e
23
23
  });
24
- if (b?.viewer === null) return C(/* @__PURE__ */ h("p", {
25
- className: "text-muted-foreground",
26
- children: v("contents.filtersSignedOut")
27
- }));
28
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" }));
29
25
  let w = x.filters;
30
26
  return !w.filters.length && r.includeDeleted === !1 ? null : C(/* @__PURE__ */ g(m, { children: [
@@ -47,7 +43,7 @@ function v(r) {
47
43
  })]
48
44
  }, e.entity.id))
49
45
  }) : null,
50
- r.includeDeleted !== !1 && /* @__PURE__ */ g("div", {
46
+ r.includeDeleted !== !1 && b?.viewer !== null && /* @__PURE__ */ g("div", {
51
47
  className: "flex items-center gap-3",
52
48
  children: [/* @__PURE__ */ h(l, {
53
49
  id: `${y}-deleted`,
@@ -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 { 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\nexport interface ContentFilterSettingsProps {\n /** Labels and group names in this language; default the provider's. */\n language?: string;\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/** The signed-in reader's content filters: show or hide each configured group. */\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 (ctx?.viewer === null) return root(<p className=\"text-muted-foreground\">{t(\"contents.filtersSignedOut\")}</p>);\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 if (!filters.filters.length && p.includeDeleted === false) return null;\n return root(\n <>\n {filters.filters.length ? (\n <ul className=\"grid divide-y divide-border rounded-lg border border-border\">\n {filters.filters.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.label || x.entity.name}\n </Label>\n </li>\n ))}\n </ul>\n ) : null}\n {p.includeDeleted !== false && (\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 <ErrorLine>{contentError(m, dates.error)}</ErrorLine>\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 <Button variant=\"outline\" size=\"sm\" className=\"justify-self-center\" disabled={dates.loadingMore} onClick={() => void dates.loadMore()}>\n {t(\"contents.loadMore\")}\n </Button>\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 { 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\nexport interface ContentFilterSettingsProps {\n /** Labels and group names in this language; default the provider's. */\n language?: string;\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 if (!filters.filters.length && p.includeDeleted === false) return null;\n return root(\n <>\n {filters.filters.length ? (\n <ul className=\"grid divide-y divide-border rounded-lg border border-border\">\n {filters.filters.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.label || x.entity.name}\n </Label>\n </li>\n ))}\n </ul>\n ) : null}\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 <ErrorLine>{contentError(m, dates.error)}</ErrorLine>\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 <Button variant=\"outline\" size=\"sm\" className=\"justify-self-center\" disabled={dates.loadingMore} onClick={() => void dates.loadMore()}>\n {t(\"contents.loadMore\")}\n </Button>\n )}\n </ContentKitUiRoot>\n );\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { ReactNode } from 'react';
1
+ import { CSSProperties, ReactNode } from 'react';
2
2
  import { ContentKitUiAppearance } from '../../appearance.js';
3
3
  import { ContentKitClient } from '../../client/client.js';
4
4
  import { ContentQuery, HistoryQuery, RailQuery, SearchQuery } from '../../client/discovery.js';
@@ -18,7 +18,20 @@ export interface CardListProps extends Omit<ContentCardProps, "card" | "onOpen"
18
18
  client?: ContentKitClient;
19
19
  className?: string;
20
20
  appearance?: ContentKitUiAppearance;
21
+ /** Opt into a fluid grid with no desktop column ceiling. */
22
+ grid?: CardGridLayout;
21
23
  }
24
+ export interface CardGridLayout {
25
+ /** Minimum desktop card width in CSS pixels. Cards grow to fill available space. */
26
+ minCardWidth: number;
27
+ /** Equal-width columns below the desktop breakpoint. Default 2. */
28
+ mobileColumns?: number;
29
+ }
30
+ /** Shared by complete lists, release-day sections and grid-style previews. */
31
+ export declare function cardGridLayout(layout?: CardGridLayout): {
32
+ className: string;
33
+ style?: CSSProperties;
34
+ };
22
35
  /** A list's cards in a responsive grid, paged, with exposures and click signals. */
23
36
  export declare function CardGrid({ list, render, ...p }: CardListProps & {
24
37
  list: UseList<Card>;
@@ -13,7 +13,18 @@ import { Fragment as x, jsx as S, jsxs as C } from "react/jsx-runtime";
13
13
  import { cn as w } from "cn";
14
14
  //#region src/components/content/grid.tsx
15
15
  var T = "grid grid-cols-[repeat(auto-fill,minmax(min(100%,10rem),1fr))] gap-x-4 gap-y-6";
16
- function E({ list: n, render: c, ...l }) {
16
+ function E(e) {
17
+ if (!e) return { className: T };
18
+ let t = Number.isFinite(e.minCardWidth) ? Math.max(1, e.minCardWidth) : 160, n = e.mobileColumns !== void 0 && Number.isFinite(e.mobileColumns) ? Math.max(1, Math.floor(e.mobileColumns)) : 2;
19
+ return {
20
+ className: "grid grid-cols-[repeat(var(--ckui-card-mobile-columns),minmax(0,1fr))] gap-x-4 gap-y-6 md:grid-cols-[repeat(auto-fill,minmax(min(100%,var(--ckui-card-min-width)),1fr))]",
21
+ style: {
22
+ "--ckui-card-min-width": `${t}px`,
23
+ "--ckui-card-mobile-columns": n
24
+ }
25
+ };
26
+ }
27
+ function D({ list: n, render: c, ...l }) {
17
28
  let d = e(), { t: f } = d, { kinds: p } = r({ client: l.client }), m = u(n.items, {
18
29
  surface: l.surface ?? "list",
19
30
  render: c,
@@ -31,14 +42,15 @@ function E({ list: n, render: c, ...l }) {
31
42
  b,
32
43
  x
33
44
  ]);
34
- let E = l.tiers ?? p?.tiers;
45
+ let T = l.tiers ?? p?.tiers, D = E(l.grid);
35
46
  return /* @__PURE__ */ C(t, {
36
47
  appearance: l.appearance,
37
48
  className: w("grid gap-4 text-sm", l.className),
38
49
  "data-ckui": "content-grid",
39
50
  "aria-busy": n.loading,
40
51
  children: [n.loading && !n.items.length ? /* @__PURE__ */ S("div", {
41
- className: T,
52
+ className: D.className,
53
+ style: D.style,
42
54
  children: Array.from({ length: 8 }, (e, t) => /* @__PURE__ */ S(o, { className: l.shape === "landscape" ? "aspect-video w-full" : "aspect-[3/4] w-full" }, t))
43
55
  }) : n.error && !n.items.length ? /* @__PURE__ */ C("div", {
44
56
  role: "alert",
@@ -53,16 +65,21 @@ function E({ list: n, render: c, ...l }) {
53
65
  children: f("common.retry")
54
66
  })]
55
67
  }) : n.items.length ? /* @__PURE__ */ S("ol", {
56
- className: T,
68
+ className: D.className,
69
+ style: D.style,
57
70
  children: n.items.map((e, t) => /* @__PURE__ */ S("li", {
58
71
  ref: m.track(e.id, t + 1),
59
72
  children: l.renderCard ? l.renderCard(e, t + 1) : /* @__PURE__ */ S(g, {
60
73
  card: e,
61
74
  href: l.href,
62
75
  shape: l.shape,
76
+ loadMedia: l.loadMedia,
63
77
  groupKinds: l.groupKinds,
64
78
  chips: l.chips,
65
- tiers: E,
79
+ filterEntity: l.filterEntity,
80
+ metadata: l.metadata,
81
+ showCounts: l.showCounts,
82
+ tiers: T,
66
83
  labels: l.labels,
67
84
  owner: l.owner,
68
85
  ownerHref: l.ownerHref,
@@ -87,13 +104,13 @@ function E({ list: n, render: c, ...l }) {
87
104
  })]
88
105
  });
89
106
  }
90
- var D = [
107
+ var O = [
91
108
  "tier",
92
109
  "group",
93
110
  "ppv",
94
111
  "group_ppv"
95
112
  ];
96
- function O({ query: e, locked: t = "show", ...n }) {
113
+ function k({ query: e, locked: t = "show", ...n }) {
97
114
  let r = y(() => ({
98
115
  ...e,
99
116
  limit: e.limit ?? n.pageSize,
@@ -103,20 +120,20 @@ function O({ query: e, locked: t = "show", ...n }) {
103
120
  n.pageSize,
104
121
  t
105
122
  ]), i = l(r, { client: n.client });
106
- return /* @__PURE__ */ C(x, { children: [t === "collapse" && /* @__PURE__ */ S(k, {
123
+ return /* @__PURE__ */ C(x, { children: [t === "collapse" && /* @__PURE__ */ S(A, {
107
124
  ...n,
108
125
  query: e
109
- }), /* @__PURE__ */ S(E, {
126
+ }), /* @__PURE__ */ S(D, {
110
127
  ...n,
111
128
  list: i,
112
129
  render: JSON.stringify(r)
113
130
  })] });
114
131
  }
115
- function k({ query: n, ...r }) {
132
+ function A({ query: n, ...r }) {
116
133
  let a = e(), [o, s] = b(!1), { count: c } = f(n, { client: r.client }), u = y(() => o ? {
117
134
  ...n,
118
135
  mode: "lock",
119
- access: n.access ?? D,
136
+ access: n.access ?? O,
120
137
  limit: n.limit ?? r.pageSize
121
138
  } : null, [
122
139
  o,
@@ -134,7 +151,7 @@ function k({ query: n, ...r }) {
134
151
  "aria-expanded": o,
135
152
  onClick: () => s(!o),
136
153
  children: o ? a.t("contents.lockedHide") : a.plural("contents.lockedShow", c)
137
- }), o && /* @__PURE__ */ S(E, {
154
+ }), o && /* @__PURE__ */ S(D, {
138
155
  ...r,
139
156
  list: {
140
157
  ...d,
@@ -144,12 +161,12 @@ function k({ query: n, ...r }) {
144
161
  })]
145
162
  }) : null;
146
163
  }
147
- function A({ query: t, ...n }) {
164
+ function j({ query: t, ...n }) {
148
165
  let { t: r } = e(), i = y(() => ({
149
166
  ...t,
150
167
  limit: t.limit ?? n.pageSize
151
168
  }), [t, n.pageSize]), a = m(i, { client: n.client });
152
- return t.q.trim() ? /* @__PURE__ */ S(E, {
169
+ return t.q.trim() ? /* @__PURE__ */ S(D, {
153
170
  surface: "search",
154
171
  empty: r("contents.noResults", { q: t.q.trim() }),
155
172
  ...n,
@@ -157,7 +174,7 @@ function A({ query: t, ...n }) {
157
174
  render: JSON.stringify(i)
158
175
  }) : null;
159
176
  }
160
- function j({ query: t = {}, ...r }) {
177
+ function M({ query: t = {}, ...r }) {
161
178
  let { t: a } = e(), o = _(n), s = y(() => ({
162
179
  ...t,
163
180
  limit: t.limit ?? r.pageSize
@@ -175,7 +192,7 @@ function j({ query: t = {}, ...r }) {
175
192
  disabled: u.pending,
176
193
  onClick: () => void u.run(() => l.forget(t.kind ? { kind: t.kind } : {})),
177
194
  children: a("contents.clearHistory")
178
- }), /* @__PURE__ */ S(E, {
195
+ }), /* @__PURE__ */ S(D, {
179
196
  surface: "history",
180
197
  empty: a("contents.historyEmpty"),
181
198
  ...r,
@@ -185,8 +202,12 @@ function j({ query: t = {}, ...r }) {
185
202
  card: e,
186
203
  href: r.href,
187
204
  shape: r.shape,
205
+ loadMedia: r.loadMedia,
188
206
  groupKinds: r.groupKinds,
189
207
  chips: r.chips,
208
+ filterEntity: r.filterEntity,
209
+ metadata: r.metadata,
210
+ showCounts: r.showCounts,
190
211
  tiers: r.tiers,
191
212
  labels: r.labels,
192
213
  owner: r.owner,
@@ -204,7 +225,7 @@ function j({ query: t = {}, ...r }) {
204
225
  })]
205
226
  });
206
227
  }
207
- function M({ title: e, similar: n, recommendations: i, history: a, group: s, list: c, query: f = {}, more: m, ..._ }) {
228
+ function N({ title: e, similar: n, recommendations: i, history: a, group: s, list: c, query: f = {}, more: m, ..._ }) {
208
229
  let v = f.limit ?? _.pageSize ?? 12, b = y(() => ({
209
230
  ...f,
210
231
  limit: v
@@ -219,11 +240,11 @@ function M({ title: e, similar: n, recommendations: i, history: a, group: s, lis
219
240
  c,
220
241
  s,
221
242
  v
222
- ]), T = h(i || a || x ? null : n, b, { client: _.client }), E = p(i ? b : null, { client: _.client }), D = d(a ? {
243
+ ]), T = h(i || a || x ? null : n, b, { client: _.client }), D = p(i ? b : null, { client: _.client }), O = d(a ? {
223
244
  ...a,
224
245
  limit: a.limit ?? v
225
- } : null, { client: _.client }), O = l(x, { client: _.client }), k = i ? E : a || x ? (() => {
226
- let e = a ? D : O;
246
+ } : null, { client: _.client }), k = l(x, { client: _.client }), A = i ? D : a || x ? (() => {
247
+ let e = a ? O : k;
227
248
  return {
228
249
  items: e.items,
229
250
  loading: e.loading,
@@ -231,8 +252,8 @@ function M({ title: e, similar: n, recommendations: i, history: a, group: s, lis
231
252
  unavailable: e.error?.code === "not_configured",
232
253
  reload: e.reload
233
254
  };
234
- })() : T, { kinds: A } = r({ client: _.client }), j = _.surface ?? (i ? "recommendations" : a ? "history" : s ? "featured" : x ? "list" : "similar"), M = u(k.items, {
235
- surface: j,
255
+ })() : T, { kinds: j } = r({ client: _.client }), M = _.surface ?? (i ? "recommendations" : a ? "history" : s ? "featured" : x ? "list" : "similar"), N = u(A.items, {
256
+ surface: M,
236
257
  render: JSON.stringify([
237
258
  n,
238
259
  i,
@@ -242,12 +263,12 @@ function M({ title: e, similar: n, recommendations: i, history: a, group: s, lis
242
263
  b
243
264
  ]),
244
265
  client: _.client
245
- });
246
- return !(n || i || a || s || x) || k.unavailable || !k.loading && !k.items.length ? null : /* @__PURE__ */ C(t, {
266
+ }), P = n || i || a || s || x, F = _.grid ? E(_.grid) : void 0;
267
+ return !P || A.unavailable || !A.loading && !A.items.length ? null : /* @__PURE__ */ C(t, {
247
268
  appearance: _.appearance,
248
269
  className: w("grid gap-3 text-sm", _.className),
249
270
  "data-ckui": "content-rail",
250
- "data-surface": j,
271
+ "data-surface": M,
251
272
  children: [/* @__PURE__ */ C("div", {
252
273
  className: "flex items-baseline justify-between gap-2",
253
274
  children: [/* @__PURE__ */ S("h2", {
@@ -255,28 +276,33 @@ function M({ title: e, similar: n, recommendations: i, history: a, group: s, lis
255
276
  children: e
256
277
  }), m]
257
278
  }), /* @__PURE__ */ S("ol", {
258
- className: "flex snap-x gap-4 overflow-x-auto pb-2",
259
- children: (k.loading && !k.items.length ? Array.from({ length: 6 }, () => null) : k.items).map((e, t) => /* @__PURE__ */ S("li", {
260
- className: "w-36 shrink-0 snap-start sm:w-44",
261
- ref: e ? M.track(e.id, t + 1) : void 0,
279
+ className: F?.className ?? "flex snap-x gap-4 overflow-x-auto pb-2",
280
+ style: F?.style,
281
+ children: (A.loading && !A.items.length ? Array.from({ length: 6 }, () => null) : A.items).map((e, t) => /* @__PURE__ */ S("li", {
282
+ className: F ? void 0 : "w-36 shrink-0 snap-start sm:w-44",
283
+ ref: e ? N.track(e.id, t + 1) : void 0,
262
284
  children: e ? _.renderCard ? _.renderCard(e, t + 1) : /* @__PURE__ */ S(g, {
263
285
  card: e,
264
286
  href: _.href,
265
287
  shape: _.shape,
288
+ loadMedia: _.loadMedia,
266
289
  groupKinds: _.groupKinds,
267
290
  chips: _.chips,
268
- tiers: _.tiers ?? A?.tiers,
291
+ filterEntity: _.filterEntity,
292
+ metadata: _.metadata,
293
+ showCounts: _.showCounts,
294
+ tiers: _.tiers ?? j?.tiers,
269
295
  labels: _.labels,
270
296
  owner: _.owner,
271
297
  ownerHref: _.ownerHref,
272
298
  decorate: _.decorate,
273
- onOpen: () => M.click(e.id, t + 1)
299
+ onOpen: () => N.click(e.id, t + 1)
274
300
  }) : /* @__PURE__ */ S(o, { className: _.shape === "landscape" ? "aspect-video w-full" : "aspect-[3/4] w-full" })
275
301
  }, e?.id ?? t))
276
302
  })]
277
303
  });
278
304
  }
279
305
  //#endregion
280
- export { E as CardGrid, O as ContentGrid, j as ContentHistory, M as ContentRail, A as SearchResults };
306
+ export { D as CardGrid, k as ContentGrid, M as ContentHistory, N as ContentRail, j as SearchResults, E as cardGridLayout };
281
307
 
282
308
  //# sourceMappingURL=grid.js.map