@lexibase/rdx-ui 3.1.0 → 3.2.1
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 +2 -2
- package/src/components/docs-sidebar.tsx +3 -3
- package/src/components/kbd.tsx +8 -1
- package/src/components/mdx-components.tsx +5 -0
- package/src/components/mdx-keyboard-shortcut.tsx +74 -0
- package/src/components/skip-link.tsx +10 -0
- package/src/components/tabs.tsx +1 -0
- package/src/lib/i18n.ts +28 -0
- package/src/styles/globals.css +22 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lexibase/rdx-ui",
|
|
3
|
-
"version": "3.1
|
|
3
|
+
"version": "3.2.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": "^22.18.0 || ^24.11.0"
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"tailwind-merge": "^3.7.0",
|
|
38
38
|
"tailwindcss": "^4.3.3",
|
|
39
39
|
"tw-animate-css": "^1.4.0",
|
|
40
|
-
"@lexibase/rdx-types": "
|
|
40
|
+
"@lexibase/rdx-types": "2.0.0"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"next": "^16.4.2",
|
|
@@ -62,9 +62,9 @@ export function DocsSidebar({
|
|
|
62
62
|
{categories.map((category, index) => (
|
|
63
63
|
<div
|
|
64
64
|
key={`${index}:${category.title}`}
|
|
65
|
-
className="flex flex-col gap-0.5 mb-3 first:mt-4"
|
|
65
|
+
className="flex min-w-0 flex-col gap-0.5 mb-3 first:mt-4"
|
|
66
66
|
>
|
|
67
|
-
<p className="text-xs text-ring font-semibold uppercase mb-1">
|
|
67
|
+
<p className="text-xs text-ring font-semibold uppercase mb-1 [overflow-wrap:anywhere]">
|
|
68
68
|
{category.title}
|
|
69
69
|
</p>
|
|
70
70
|
{category.links.map((link) => (
|
|
@@ -86,7 +86,7 @@ export function DocsSidebar({
|
|
|
86
86
|
}
|
|
87
87
|
onClick={() => actions.current?.close()}
|
|
88
88
|
aria-current={pathname === link.href ? 'page' : undefined}
|
|
89
|
-
className={`justify-start text-sm ${pathname === link.href ? 'text-accent-foreground' : 'text-primary'}`}
|
|
89
|
+
className={`h-auto min-h-8 w-full min-w-0 justify-start whitespace-normal py-1.5 text-left text-sm [overflow-wrap:anywhere] ${pathname === link.href ? 'text-accent-foreground' : 'text-primary'}`}
|
|
90
90
|
>
|
|
91
91
|
{link.label}
|
|
92
92
|
</Button>
|
package/src/components/kbd.tsx
CHANGED
|
@@ -16,10 +16,17 @@ function Kbd({ className, ...props }: ComponentProps<'kbd'>) {
|
|
|
16
16
|
)
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
function KbdGroup({ className, ...props }: ComponentProps<'div'>) {
|
|
19
|
+
function KbdGroup({ className, role, ...props }: ComponentProps<'div'>) {
|
|
20
20
|
return (
|
|
21
21
|
<kbd
|
|
22
22
|
data-slot="kbd-group"
|
|
23
|
+
role={
|
|
24
|
+
role ??
|
|
25
|
+
(props['aria-label'] !== undefined ||
|
|
26
|
+
props['aria-labelledby'] !== undefined
|
|
27
|
+
? 'group'
|
|
28
|
+
: undefined)
|
|
29
|
+
}
|
|
23
30
|
className={cn('inline-flex items-center gap-1', className)}
|
|
24
31
|
{...props}
|
|
25
32
|
/>
|
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
} from './code-block'
|
|
30
30
|
import { MdxCodeBlock } from './mdx-code-block'
|
|
31
31
|
import { Kbd, KbdGroup } from './kbd'
|
|
32
|
+
import { MdxKeyboardShortcut } from './mdx-keyboard-shortcut'
|
|
32
33
|
import {
|
|
33
34
|
Table,
|
|
34
35
|
TableBody,
|
|
@@ -154,6 +155,7 @@ export const mdxComponents = {
|
|
|
154
155
|
CodeBlockTitle,
|
|
155
156
|
Kbd,
|
|
156
157
|
KbdGroup,
|
|
158
|
+
KeyboardShortcut: MdxKeyboardShortcut,
|
|
157
159
|
Table,
|
|
158
160
|
TableHeader,
|
|
159
161
|
TableBody,
|
|
@@ -187,6 +189,9 @@ export const mdxComponents = {
|
|
|
187
189
|
export function getMdxComponents(lang?: string) {
|
|
188
190
|
return {
|
|
189
191
|
...mdxComponents,
|
|
192
|
+
KeyboardShortcut: (props: { children?: ReactNode }) => (
|
|
193
|
+
<MdxKeyboardShortcut {...props} lang={lang} />
|
|
194
|
+
),
|
|
190
195
|
pre: (props: ComponentProps<'pre'>) => (
|
|
191
196
|
<MdxCodeBlock {...props} lang={lang} />
|
|
192
197
|
),
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { ReactNode } from 'react'
|
|
2
|
+
|
|
3
|
+
import { getMessages, type InterfaceMessages } from '../lib/i18n'
|
|
4
|
+
import { Kbd, KbdGroup } from './kbd'
|
|
5
|
+
|
|
6
|
+
const keyNames: Record<string, keyof InterfaceMessages> = {
|
|
7
|
+
ctrl: 'keyboardControl',
|
|
8
|
+
control: 'keyboardControl',
|
|
9
|
+
'⌃': 'keyboardControl',
|
|
10
|
+
shift: 'keyboardShift',
|
|
11
|
+
'⇧': 'keyboardShift',
|
|
12
|
+
alt: 'keyboardAlt',
|
|
13
|
+
cmd: 'keyboardCommand',
|
|
14
|
+
command: 'keyboardCommand',
|
|
15
|
+
'⌘': 'keyboardCommand',
|
|
16
|
+
option: 'keyboardOption',
|
|
17
|
+
'⌥': 'keyboardOption',
|
|
18
|
+
esc: 'keyboardEscape',
|
|
19
|
+
escape: 'keyboardEscape',
|
|
20
|
+
'⎋': 'keyboardEscape',
|
|
21
|
+
enter: 'keyboardEnter',
|
|
22
|
+
return: 'keyboardEnter',
|
|
23
|
+
'↵': 'keyboardEnter',
|
|
24
|
+
'⏎': 'keyboardEnter',
|
|
25
|
+
space: 'keyboardSpace',
|
|
26
|
+
spacebar: 'keyboardSpace',
|
|
27
|
+
'+': 'keyboardPlus',
|
|
28
|
+
arrowup: 'keyboardArrowUp',
|
|
29
|
+
'↑': 'keyboardArrowUp',
|
|
30
|
+
arrowdown: 'keyboardArrowDown',
|
|
31
|
+
'↓': 'keyboardArrowDown',
|
|
32
|
+
arrowleft: 'keyboardArrowLeft',
|
|
33
|
+
'←': 'keyboardArrowLeft',
|
|
34
|
+
arrowright: 'keyboardArrowRight',
|
|
35
|
+
'→': 'keyboardArrowRight',
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Markdown adapter: preserve shadcn visuals, expose one readable text alternative. */
|
|
39
|
+
export function MdxKeyboardShortcut({
|
|
40
|
+
children,
|
|
41
|
+
lang,
|
|
42
|
+
}: {
|
|
43
|
+
children?: ReactNode
|
|
44
|
+
lang?: string
|
|
45
|
+
}) {
|
|
46
|
+
if (typeof children !== 'string') return <Kbd>{children}</Kbd>
|
|
47
|
+
const keys = children
|
|
48
|
+
.trim()
|
|
49
|
+
.split(/\s+\+\s+/)
|
|
50
|
+
.map((key) => key.trim())
|
|
51
|
+
if (keys.length < 2 || keys.some((key) => !key)) return <Kbd>{children}</Kbd>
|
|
52
|
+
const messages = getMessages(lang)
|
|
53
|
+
const description = keys
|
|
54
|
+
.map((key) => {
|
|
55
|
+
const name = Object.hasOwn(keyNames, key.toLowerCase())
|
|
56
|
+
? keyNames[key.toLowerCase()]
|
|
57
|
+
: undefined
|
|
58
|
+
return name ? messages[name] : key
|
|
59
|
+
})
|
|
60
|
+
.join(messages.keyboardJoiner)
|
|
61
|
+
return (
|
|
62
|
+
<span data-rdx-kbd-value={children} className="inline-flex align-baseline">
|
|
63
|
+
<span className="sr-only select-none">{description}</span>
|
|
64
|
+
<KbdGroup aria-hidden="true">
|
|
65
|
+
{keys.map((key, index) => (
|
|
66
|
+
<span key={index} className="inline-flex items-center gap-1">
|
|
67
|
+
{index > 0 && <span>+</span>}
|
|
68
|
+
<Kbd>{key}</Kbd>
|
|
69
|
+
</span>
|
|
70
|
+
))}
|
|
71
|
+
</KbdGroup>
|
|
72
|
+
</span>
|
|
73
|
+
)
|
|
74
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { getMessages } from '../lib/i18n'
|
|
2
|
+
|
|
3
|
+
/** First keyboard stop, shared by the website and generated documentation. */
|
|
4
|
+
export function SkipLink({ lang }: { lang?: string }) {
|
|
5
|
+
return (
|
|
6
|
+
<a className="rdx-skip-link" href="#rdx-main">
|
|
7
|
+
{getMessages(lang).skipContent}
|
|
8
|
+
</a>
|
|
9
|
+
)
|
|
10
|
+
}
|
package/src/components/tabs.tsx
CHANGED
|
@@ -25,6 +25,7 @@ function panelText(node: Node): string {
|
|
|
25
25
|
)
|
|
26
26
|
)
|
|
27
27
|
return ''
|
|
28
|
+
if (node.dataset.rdxKbdValue !== undefined) return node.dataset.rdxKbdValue
|
|
28
29
|
if (node.matches('[data-rdx-code-block], [data-slot="code-block"]')) {
|
|
29
30
|
const pre = node.querySelector('pre')
|
|
30
31
|
const lines = pre?.querySelectorAll('[data-slot="code-block-line-content"]')
|
package/src/lib/i18n.ts
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
/** Shared labels only: document content and author-provided names stay untouched. */
|
|
2
2
|
const en = {
|
|
3
|
+
keyboardJoiner: ' plus ',
|
|
4
|
+
keyboardControl: 'Control',
|
|
5
|
+
keyboardShift: 'Shift',
|
|
6
|
+
keyboardAlt: 'Alt',
|
|
7
|
+
keyboardCommand: 'Command',
|
|
8
|
+
keyboardOption: 'Option',
|
|
9
|
+
keyboardEscape: 'Escape',
|
|
10
|
+
keyboardEnter: 'Enter',
|
|
11
|
+
keyboardSpace: 'Space',
|
|
12
|
+
keyboardPlus: 'Plus',
|
|
13
|
+
keyboardArrowUp: 'Up arrow',
|
|
14
|
+
keyboardArrowDown: 'Down arrow',
|
|
15
|
+
keyboardArrowLeft: 'Left arrow',
|
|
16
|
+
keyboardArrowRight: 'Right arrow',
|
|
3
17
|
skipContent: 'Skip to content',
|
|
4
18
|
mainNavigation: 'Main navigation',
|
|
5
19
|
docs: 'Docs',
|
|
@@ -79,6 +93,20 @@ export type InterfaceMessages = { [Key in keyof typeof en]: string }
|
|
|
79
93
|
export type InterfaceLocale = 'en' | 'pt-BR'
|
|
80
94
|
|
|
81
95
|
const ptBR = {
|
|
96
|
+
keyboardJoiner: ' mais ',
|
|
97
|
+
keyboardControl: 'Control',
|
|
98
|
+
keyboardShift: 'Shift',
|
|
99
|
+
keyboardAlt: 'Alt',
|
|
100
|
+
keyboardCommand: 'Command',
|
|
101
|
+
keyboardOption: 'Option',
|
|
102
|
+
keyboardEscape: 'Escape',
|
|
103
|
+
keyboardEnter: 'Enter',
|
|
104
|
+
keyboardSpace: 'Espaço',
|
|
105
|
+
keyboardPlus: 'Sinal de mais',
|
|
106
|
+
keyboardArrowUp: 'Seta para cima',
|
|
107
|
+
keyboardArrowDown: 'Seta para baixo',
|
|
108
|
+
keyboardArrowLeft: 'Seta para a esquerda',
|
|
109
|
+
keyboardArrowRight: 'Seta para a direita',
|
|
82
110
|
skipContent: 'Ir para o conteúdo',
|
|
83
111
|
mainNavigation: 'Navegação principal',
|
|
84
112
|
docs: 'Docs',
|
package/src/styles/globals.css
CHANGED
|
@@ -6,6 +6,28 @@
|
|
|
6
6
|
|
|
7
7
|
@custom-variant dark (&:is(.dark *));
|
|
8
8
|
|
|
9
|
+
.rdx-skip-link {
|
|
10
|
+
position: fixed;
|
|
11
|
+
top: 1rem;
|
|
12
|
+
inset-inline-start: 1rem;
|
|
13
|
+
z-index: 100;
|
|
14
|
+
max-width: calc(100vw - 2rem);
|
|
15
|
+
transform: translateY(calc(-100% - 2rem));
|
|
16
|
+
padding: 0.5rem 0.75rem;
|
|
17
|
+
border: 1px solid var(--border);
|
|
18
|
+
border-radius: var(--radius);
|
|
19
|
+
background: var(--background);
|
|
20
|
+
color: var(--foreground);
|
|
21
|
+
font-size: 0.875rem;
|
|
22
|
+
font-weight: 500;
|
|
23
|
+
outline: 2px solid var(--ring);
|
|
24
|
+
outline-offset: 2px;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.rdx-skip-link:focus {
|
|
28
|
+
transform: translateY(0);
|
|
29
|
+
}
|
|
30
|
+
|
|
9
31
|
:root {
|
|
10
32
|
--background: oklch(1 0 0);
|
|
11
33
|
--foreground: oklch(0.145 0 0);
|