@meith/theme-raidframe 0.15.0 → 0.17.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-raidframe",
3
- "version": "0.15.0",
3
+ "version": "0.17.0",
4
4
  "description": "A gaming theme for Meith — guild, raid and match boards — built on the default theme's slots.",
5
5
  "license": "LGPL-3.0-or-later",
6
6
  "repository": {
@@ -20,9 +20,9 @@
20
20
  "access": "public"
21
21
  },
22
22
  "dependencies": {
23
- "@meith/theme-default": "^0.15.0",
24
- "@meith/ui": "^0.15.0",
25
- "@meith/theme-kit": "^0.15.0"
23
+ "@meith/theme-kit": "^0.17.0",
24
+ "@meith/theme-default": "^0.17.0",
25
+ "@meith/ui": "^0.17.0"
26
26
  },
27
27
  "peerDependencies": {
28
28
  "react": "^19.2.0"
package/src/copy.ts CHANGED
@@ -164,6 +164,7 @@ export function postActionsCopy(t: Translator): SlotCopy {
164
164
  return copyFor(t, [
165
165
  'raidframe.postActions.quote',
166
166
  'raidframe.postActions.edit',
167
+ 'raidframe.postActions.history',
167
168
  'raidframe.postActions.restore',
168
169
  'raidframe.postActions.rate',
169
170
  'raidframe.postActions.report',
@@ -73,6 +73,7 @@
73
73
  "raidframe.panelPage.panelLabel.usercp": "your control panel",
74
74
  "raidframe.postActions.ariaLabel": "Post actions",
75
75
  "raidframe.postActions.edit": "edit",
76
+ "raidframe.postActions.history": "history",
76
77
  "raidframe.postActions.moderate": "moderate",
77
78
  "raidframe.postActions.quote": "quote",
78
79
  "raidframe.postActions.rate": "rate",
@@ -0,0 +1,73 @@
1
+ 'use client'
2
+
3
+ import {
4
+ applyEditorTag,
5
+ type EditorTag,
6
+ type EditorToolbarModel,
7
+ type SlotCopy,
8
+ } from '@meith/theme-kit'
9
+
10
+ import { RULE } from '../shared'
11
+
12
+ const GLYPHS: Readonly<Record<EditorTag, string>> = {
13
+ bold: 'B',
14
+ italic: 'I',
15
+ strikethrough: 'S',
16
+ link: 'LINK',
17
+ quote: 'QUOTE',
18
+ code: 'CODE',
19
+ spoiler: 'SPLR',
20
+ bulletedList: 'UL',
21
+ numberedList: 'OL',
22
+ heading: 'H',
23
+ }
24
+
25
+ const BUTTON =
26
+ 'inline-flex min-w-8 items-center justify-center border border-border bg-secondary px-2 py-1.5 font-mono text-[0.6875rem] font-semibold uppercase tracking-[0.1em] text-secondary-foreground hover:border-primary/70 hover:text-primary'
27
+
28
+ function runTag(textareaId: string, tag: EditorTag, placeholder: string | null): void {
29
+ const field = document.getElementById(textareaId)
30
+ if (field instanceof HTMLTextAreaElement) applyEditorTag(field, tag, placeholder)
31
+ }
32
+
33
+ export function EditorToolbar({
34
+ textareaId,
35
+ groupLabel,
36
+ buttons,
37
+ attachment,
38
+ }: EditorToolbarModel & { copy: SlotCopy }) {
39
+ return (
40
+ <>
41
+ <div role="group" aria-label={groupLabel} className="flex flex-wrap gap-1 px-4 py-3">
42
+ {buttons.map((button) => (
43
+ <button
44
+ key={button.tag}
45
+ type="button"
46
+ onMouseDown={(event) => event.preventDefault()}
47
+ onClick={() => runTag(textareaId, button.tag, button.placeholder)}
48
+ title={button.title}
49
+ aria-label={button.label}
50
+ {...(button.keyShortcut === null ? {} : { 'aria-keyshortcuts': button.keyShortcut })}
51
+ className={BUTTON}
52
+ >
53
+ <span aria-hidden="true">{GLYPHS[button.tag]}</span>
54
+ </button>
55
+ ))}
56
+
57
+ {attachment !== null && (
58
+ <button
59
+ type="button"
60
+ onMouseDown={(event) => event.preventDefault()}
61
+ onClick={() => document.getElementById(attachment.inputId)?.click()}
62
+ title={attachment.label}
63
+ aria-label={attachment.label}
64
+ className={BUTTON}
65
+ >
66
+ <span aria-hidden="true">{attachment.label}</span>
67
+ </button>
68
+ )}
69
+ </div>
70
+ <div className={RULE} aria-hidden="true" />
71
+ </>
72
+ )
73
+ }
@@ -14,12 +14,13 @@ export function PostActions({
14
14
  const items = [
15
15
  { href: actions.quoteHref, label: c('quote') },
16
16
  { href: actions.editHref, label: c('edit') },
17
+ { href: actions.historyHref, label: c('history') },
17
18
  { href: actions.restoreHref, label: c('restore') },
18
19
  { href: actions.rateHref, label: c('rate') },
19
20
  { href: actions.reportHref, label: c('report') },
20
21
  { href: actions.warnHref, label: c('warn') },
21
22
  { href: actions.moderateHref, label: c('moderate') },
22
- ].filter((item): item is { href: string; label: string } => item.href !== null)
23
+ ].filter((item): item is { href: string; label: string } => item.href != null)
23
24
 
24
25
  if (items.length === 0 && children === undefined) return null
25
26
 
@@ -0,0 +1,9 @@
1
+ 'use client'
2
+
3
+ import type { QuickReplyModel, SlotCopy } from '@meith/theme-kit'
4
+
5
+ export function QuickReply({ placeholder, children }: QuickReplyModel & { copy: SlotCopy }) {
6
+ if (children === undefined) return null
7
+
8
+ return <section aria-label={placeholder}>{children}</section>
9
+ }
package/src/theme.ts CHANGED
@@ -40,6 +40,7 @@ import { BoardIndex } from './slots/board-index'
40
40
  import { BoardStats } from './slots/board-stats'
41
41
  import { CategoryBlock } from './slots/category-block'
42
42
  import { DiscoveryView } from './slots/discovery-view'
43
+ import { EditorToolbar } from './slots/editor-toolbar'
43
44
  import { ErrorNotice } from './slots/error-notice'
44
45
  import { Footer } from './slots/footer'
45
46
  import { ForumDisplay } from './slots/forum-display'
@@ -58,6 +59,7 @@ import { PanelShell } from './slots/panel-shell'
58
59
  import { PostActions } from './slots/post-actions'
59
60
  import { PostBit } from './slots/post-bit'
60
61
  import { PostForm } from './slots/post-form'
62
+ import { QuickReply } from './slots/quick-reply'
61
63
  import { RedirectNotice } from './slots/redirect-notice'
62
64
  import { SearchForm } from './slots/search-form'
63
65
  import { SearchResults } from './slots/search-results'
@@ -97,8 +99,10 @@ export const raidframeTheme = defineTheme({
97
99
  ThreadView,
98
100
  PostBit,
99
101
  PostActions,
102
+ QuickReply,
100
103
 
101
104
  PostForm,
105
+ EditorToolbar,
102
106
  MemberProfile,
103
107
  SearchForm,
104
108
  SearchResults,