@meith/theme-clubhouse 0.31.0 → 0.32.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meith/theme-clubhouse",
3
- "version": "0.31.0",
3
+ "version": "0.32.0",
4
4
  "description": "A sports club theme for Meith — GAA, soccer, basketball — painted from the club's own two colours.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -20,9 +20,9 @@
20
20
  "access": "public"
21
21
  },
22
22
  "dependencies": {
23
- "@meith/theme-default": "^0.31.0",
24
- "@meith/theme-kit": "^0.31.0",
25
- "@meith/ui": "^0.31.0"
23
+ "@meith/theme-default": "^0.32.0",
24
+ "@meith/theme-kit": "^0.32.0",
25
+ "@meith/ui": "^0.32.0"
26
26
  },
27
27
  "peerDependencies": {
28
28
  "react": "^19.2.0"
package/src/copy.ts CHANGED
@@ -199,6 +199,8 @@ export function threadViewCopy(t: Translator): SlotCopy {
199
199
  'clubhouse.threadView.replies',
200
200
  'clubhouse.threadView.reply',
201
201
  'clubhouse.threadView.views',
202
+ 'clubhouse.threadView.watch',
203
+ 'clubhouse.threadView.watching',
202
204
  ])
203
205
  }
204
206
 
@@ -107,6 +107,8 @@
107
107
  "clubhouse.threadView.replies": "replies",
108
108
  "clubhouse.threadView.reply": "Reply",
109
109
  "clubhouse.threadView.views": "views",
110
+ "clubhouse.threadView.watch": "Watch",
111
+ "clubhouse.threadView.watching": "Watching",
110
112
  "clubhouse.userPanel.new": "new",
111
113
  "clubhouse.userPanel.signedIn": "Signed in",
112
114
  "clubhouse.userPanel.unread": "unread",
@@ -44,7 +44,7 @@ function Submenu({ items }: { items: HeaderModel['navigation'][number]['submenu'
44
44
  <a
45
45
  href={child.href}
46
46
  {...linkTarget(child)}
47
- className="block px-3 py-1.5 text-muted-foreground hover:bg-muted hover:text-foreground"
47
+ className="flex items-center px-3 py-1.5 text-muted-foreground pointer-coarse:min-h-11 hover:bg-muted hover:text-foreground"
48
48
  >
49
49
  {child.label}
50
50
  </a>
@@ -54,6 +54,73 @@ function Submenu({ items }: { items: HeaderModel['navigation'][number]['submenu'
54
54
  )
55
55
  }
56
56
 
57
+ function Chevron({ className }: { className: string }) {
58
+ return (
59
+ <svg
60
+ aria-hidden="true"
61
+ viewBox="0 0 12 12"
62
+ className={className}
63
+ fill="none"
64
+ stroke="currentColor"
65
+ strokeWidth="1.5"
66
+ strokeLinecap="round"
67
+ strokeLinejoin="round"
68
+ >
69
+ <path d="m4.5 3 3 3-3 3" />
70
+ </svg>
71
+ )
72
+ }
73
+
74
+ function MobileNavItem({ item }: { item: HeaderModel['navigation'][number] }) {
75
+ if (item.submenu === undefined || item.submenu.length === 0) {
76
+ return (
77
+ <li>
78
+ <a
79
+ href={item.href}
80
+ {...linkTarget(item)}
81
+ className={`${HEADING} flex min-h-11 items-center px-2.5 text-sm text-muted-foreground hover:bg-accent hover:text-foreground`}
82
+ >
83
+ {item.label}
84
+ </a>
85
+ </li>
86
+ )
87
+ }
88
+
89
+ return (
90
+ <li>
91
+ <details data-nav-disclosure name="clubhouse-header-submenu" className="group/submenu">
92
+ <summary
93
+ className={`${HEADING} flex min-h-11 cursor-default list-none items-center justify-between gap-2 px-2.5 text-sm text-muted-foreground select-none [&::-webkit-details-marker]:hidden [&::marker]:content-none hover:bg-accent hover:text-foreground`}
94
+ >
95
+ <a
96
+ href={item.href}
97
+ {...linkTarget(item)}
98
+ className="min-w-0 flex-1 truncate hover:underline"
99
+ >
100
+ {item.label}
101
+ </a>
102
+ <span className="flex size-11 shrink-0 items-center justify-center">
103
+ <Chevron className="size-3 text-muted-foreground transition-transform group-open/submenu:rotate-90" />
104
+ </span>
105
+ </summary>
106
+ <ul className="ml-2 flex flex-col gap-0.5 border-l border-border py-1 pl-2.5">
107
+ {item.submenu.map((child) => (
108
+ <li key={child.href}>
109
+ <a
110
+ href={child.href}
111
+ {...linkTarget(child)}
112
+ className="flex min-h-11 items-center px-2.5 text-sm text-muted-foreground hover:bg-accent hover:text-foreground"
113
+ >
114
+ {child.label}
115
+ </a>
116
+ </li>
117
+ ))}
118
+ </ul>
119
+ </details>
120
+ </li>
121
+ )
122
+ }
123
+
57
124
  export function Header({
58
125
  boardTitle,
59
126
  homeHref,
@@ -84,7 +151,8 @@ export function Header({
84
151
  <nav aria-label={c('boardSections')} className="border-b border-border bg-surface">
85
152
  <div className={PAGE}>
86
153
  <ul
87
- className={`-mx-4 flex items-stretch px-4 sm:-mx-6 sm:px-6 ${
154
+ data-nav-view="desktop"
155
+ className={`-mx-4 hidden items-stretch px-4 sm:-mx-6 sm:px-6 lg:flex ${
88
156
  opensMenus ? 'flex-wrap' : 'overflow-x-auto'
89
157
  }`}
90
158
  >
@@ -101,6 +169,22 @@ export function Header({
101
169
  </li>
102
170
  ))}
103
171
  </ul>
172
+
173
+ <div data-nav-view="mobile" className="-mx-4 px-4 py-1 sm:-mx-6 sm:px-6 lg:hidden">
174
+ <details data-nav-disclosure className="group">
175
+ <summary
176
+ className={`${HEADING} flex min-h-11 cursor-default list-none items-center gap-2 text-sm text-foreground select-none [&::-webkit-details-marker]:hidden [&::marker]:content-none`}
177
+ >
178
+ <Chevron className="size-3 shrink-0 transition-transform group-open:rotate-90" />
179
+ {c('boardSections')}
180
+ </summary>
181
+ <ul className="flex flex-col gap-0.5 pb-2">
182
+ {navigation.map((item) => (
183
+ <MobileNavItem key={item.href} item={item} />
184
+ ))}
185
+ </ul>
186
+ </details>
187
+ </div>
104
188
  </div>
105
189
  </nav>
106
190
  )}
@@ -4,7 +4,12 @@ import { Badge } from '@meith/ui'
4
4
 
5
5
  import { HEADING, LINK, MICRO, Prefix, ReadMark, Stamp, TABLE_ROW, Tally, UserRef } from '../shared'
6
6
 
7
- export function ThreadRow({ thread, select, copy }: ThreadRowSlotModel & { copy: SlotCopy }) {
7
+ export function ThreadRow({
8
+ thread,
9
+ select,
10
+ regions,
11
+ copy,
12
+ }: ThreadRowSlotModel & { copy: SlotCopy }) {
8
13
  const c = (key: string) => fromSlotCopy(copy, `clubhouse.threadRow.${key}`)
9
14
 
10
15
  const hidden = thread.visibility === 'deleted' || thread.visibility === 'unapproved'
@@ -49,6 +54,7 @@ export function ThreadRow({ thread, select, copy }: ThreadRowSlotModel & { copy:
49
54
  {thread.title}
50
55
  </a>
51
56
  {thread.isUnread && <span className="sr-only"> {c('newPosts')}</span>}
57
+ {regions?.pluginBadges}
52
58
  </div>
53
59
 
54
60
  <p className="mt-0.5 text-xs text-muted-foreground">
@@ -9,6 +9,7 @@ export function ThreadView({
9
9
  forum,
10
10
  replyHref,
11
11
  markReadAction,
12
+ watch,
12
13
  regions,
13
14
  copy,
14
15
  }: ThreadViewModel & { copy: SlotCopy }) {
@@ -19,6 +20,25 @@ export function ThreadView({
19
20
  <PageHead
20
21
  actions={
21
22
  <>
23
+ {watch != null && (
24
+ <form action={watch.action} method="post">
25
+ <button
26
+ type="submit"
27
+ className={cn(
28
+ BUTTON,
29
+ 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
30
+ )}
31
+ >
32
+ {watch.subscribed ? (
33
+ <>
34
+ {c('watching')} <span aria-hidden="true">✓</span>
35
+ </>
36
+ ) : (
37
+ c('watch')
38
+ )}
39
+ </button>
40
+ </form>
41
+ )}
22
42
  {markReadAction !== null && (
23
43
  <form action={markReadAction} method="post">
24
44
  <button
package/src/theme.ts CHANGED
@@ -51,7 +51,7 @@ import { WhoIsOnline } from './slots/who-is-online'
51
51
  export const clubhouseTheme = defineTheme({
52
52
  key: 'clubhouse',
53
53
  title: 'Clubhouse',
54
- version: '0.31.0',
54
+ version: '0.32.0',
55
55
  extends: defaultTheme,
56
56
  slots: {
57
57
  Shell,