@meith/theme-phasebook 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 +4 -4
- package/src/copy.ts +1 -0
- package/src/messages/en.json +1 -0
- package/src/slots/editor-toolbar.tsx +72 -0
- package/src/slots/post-actions.tsx +1 -0
- package/src/slots/quick-reply.tsx +9 -0
- package/src/theme.ts +4 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meith/theme-phasebook",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "A theme for Meith with a familiar social shape, 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.
|
|
24
|
-
"@meith/theme-kit": "^0.
|
|
25
|
-
"@meith/ui": "^0.
|
|
23
|
+
"@meith/theme-default": "^0.17.0",
|
|
24
|
+
"@meith/theme-kit": "^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
|
@@ -141,6 +141,7 @@ export function postActionsCopy(t: Translator): SlotCopy {
|
|
|
141
141
|
return copyFor(t, [
|
|
142
142
|
'phasebook.postActions.ariaLabel',
|
|
143
143
|
'phasebook.postActions.edit',
|
|
144
|
+
'phasebook.postActions.history',
|
|
144
145
|
'phasebook.postActions.moderate',
|
|
145
146
|
'phasebook.postActions.quote',
|
|
146
147
|
'phasebook.postActions.rate',
|
package/src/messages/en.json
CHANGED
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
"phasebook.panelNav.waiting": "waiting",
|
|
67
67
|
"phasebook.postActions.ariaLabel": "Post actions",
|
|
68
68
|
"phasebook.postActions.edit": "Edit",
|
|
69
|
+
"phasebook.postActions.history": "History",
|
|
69
70
|
"phasebook.postActions.moderate": "Moderate",
|
|
70
71
|
"phasebook.postActions.quote": "Quote",
|
|
71
72
|
"phasebook.postActions.rate": "Rate",
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
applyEditorTag,
|
|
5
|
+
type EditorTag,
|
|
6
|
+
type EditorToolbarModel,
|
|
7
|
+
type SlotCopy,
|
|
8
|
+
} from '@meith/theme-kit'
|
|
9
|
+
|
|
10
|
+
const GLYPHS: Readonly<Record<EditorTag, string>> = {
|
|
11
|
+
bold: 'B',
|
|
12
|
+
italic: 'I',
|
|
13
|
+
strikethrough: 'S',
|
|
14
|
+
link: 'Link',
|
|
15
|
+
quote: '“”',
|
|
16
|
+
code: '</>',
|
|
17
|
+
spoiler: 'Spoiler',
|
|
18
|
+
bulletedList: '•',
|
|
19
|
+
numberedList: '1.',
|
|
20
|
+
heading: 'H',
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const BUTTON =
|
|
24
|
+
'inline-flex h-8 min-w-8 items-center justify-center rounded-full px-2.5 text-xs font-semibold text-muted-foreground transition-colors duration-100 hover:bg-accent hover:text-foreground'
|
|
25
|
+
|
|
26
|
+
function runTag(textareaId: string, tag: EditorTag, placeholder: string | null): void {
|
|
27
|
+
const field = document.getElementById(textareaId)
|
|
28
|
+
if (field instanceof HTMLTextAreaElement) applyEditorTag(field, tag, placeholder)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function EditorToolbar({
|
|
32
|
+
textareaId,
|
|
33
|
+
groupLabel,
|
|
34
|
+
buttons,
|
|
35
|
+
attachment,
|
|
36
|
+
}: EditorToolbarModel & { copy: SlotCopy }) {
|
|
37
|
+
return (
|
|
38
|
+
<div
|
|
39
|
+
role="group"
|
|
40
|
+
aria-label={groupLabel}
|
|
41
|
+
className="flex flex-wrap gap-1 border-b border-border bg-secondary/40 px-3 py-2"
|
|
42
|
+
>
|
|
43
|
+
{buttons.map((button) => (
|
|
44
|
+
<button
|
|
45
|
+
key={button.tag}
|
|
46
|
+
type="button"
|
|
47
|
+
onMouseDown={(event) => event.preventDefault()}
|
|
48
|
+
onClick={() => runTag(textareaId, button.tag, button.placeholder)}
|
|
49
|
+
title={button.title}
|
|
50
|
+
aria-label={button.label}
|
|
51
|
+
{...(button.keyShortcut === null ? {} : { 'aria-keyshortcuts': button.keyShortcut })}
|
|
52
|
+
className={BUTTON}
|
|
53
|
+
>
|
|
54
|
+
<span aria-hidden="true">{GLYPHS[button.tag]}</span>
|
|
55
|
+
</button>
|
|
56
|
+
))}
|
|
57
|
+
|
|
58
|
+
{attachment !== null && (
|
|
59
|
+
<button
|
|
60
|
+
type="button"
|
|
61
|
+
onMouseDown={(event) => event.preventDefault()}
|
|
62
|
+
onClick={() => document.getElementById(attachment.inputId)?.click()}
|
|
63
|
+
title={attachment.label}
|
|
64
|
+
aria-label={attachment.label}
|
|
65
|
+
className={BUTTON}
|
|
66
|
+
>
|
|
67
|
+
<span aria-hidden="true">{attachment.label}</span>
|
|
68
|
+
</button>
|
|
69
|
+
)}
|
|
70
|
+
</div>
|
|
71
|
+
)
|
|
72
|
+
}
|
|
@@ -20,6 +20,7 @@ export function PostActions({
|
|
|
20
20
|
const reader: Action[] = [
|
|
21
21
|
actions.quoteHref === null ? null : { href: actions.quoteHref, label: c('quote') },
|
|
22
22
|
actions.editHref === null ? null : { href: actions.editHref, label: c('edit') },
|
|
23
|
+
actions.historyHref == null ? null : { href: actions.historyHref, label: c('history') },
|
|
23
24
|
actions.rateHref === null ? null : { href: actions.rateHref, label: c('rate') },
|
|
24
25
|
actions.reportHref === null ? null : { href: actions.reportHref, label: c('report') },
|
|
25
26
|
].filter((action): action is Action => action !== null)
|
|
@@ -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
|
@@ -37,6 +37,7 @@ import { BoardIndex } from './slots/board-index'
|
|
|
37
37
|
import { BoardStats } from './slots/board-stats'
|
|
38
38
|
import { CategoryBlock } from './slots/category-block'
|
|
39
39
|
import { DiscoveryView } from './slots/discovery-view'
|
|
40
|
+
import { EditorToolbar } from './slots/editor-toolbar'
|
|
40
41
|
import { ErrorNotice } from './slots/error-notice'
|
|
41
42
|
import { Footer } from './slots/footer'
|
|
42
43
|
import { ForumDisplay } from './slots/forum-display'
|
|
@@ -55,6 +56,7 @@ import { PanelShell } from './slots/panel-shell'
|
|
|
55
56
|
import { PostActions } from './slots/post-actions'
|
|
56
57
|
import { PostBit } from './slots/post-bit'
|
|
57
58
|
import { PostForm } from './slots/post-form'
|
|
59
|
+
import { QuickReply } from './slots/quick-reply'
|
|
58
60
|
import { RedirectNotice } from './slots/redirect-notice'
|
|
59
61
|
import { SearchForm } from './slots/search-form'
|
|
60
62
|
import { SearchResults } from './slots/search-results'
|
|
@@ -94,8 +96,10 @@ export const phasebookTheme = defineTheme({
|
|
|
94
96
|
ThreadView,
|
|
95
97
|
PostBit,
|
|
96
98
|
PostActions,
|
|
99
|
+
QuickReply,
|
|
97
100
|
|
|
98
101
|
PostForm,
|
|
102
|
+
EditorToolbar,
|
|
99
103
|
|
|
100
104
|
MemberProfile,
|
|
101
105
|
|