@manuscripts/style-guide 3.4.6 → 3.5.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.
@@ -38,6 +38,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.ContextMenu = void 0;
40
40
  const jsx_runtime_1 = require("react/jsx-runtime");
41
+ const react_1 = require("react");
41
42
  const styled_components_1 = __importDefault(require("styled-components"));
42
43
  const Button_1 = require("./Button");
43
44
  const Icons = __importStar(require("./icons"));
@@ -52,6 +53,11 @@ const ContextMenuIconButton = (0, styled_components_1.default)(Button_1.IconButt
52
53
  background-color: #f2f2f2;
53
54
  border-color: #f2f2f2;
54
55
  }
56
+ &:not([disabled]):focus-visible {
57
+ outline: 4px solid #3dadff;
58
+ outline-offset: -2px;
59
+ background-color: transparent !important;
60
+ }
55
61
  &[disabled] {
56
62
  color: #c9c9c9 !important;
57
63
  background-color: #fff !important;
@@ -62,8 +68,43 @@ const icons = Object.entries(Icons).reduce((acc, [name, IconComponent]) => {
62
68
  acc[iconName] = IconComponent;
63
69
  return acc;
64
70
  }, {});
65
- const ContextMenu = ({ actions }) => ((0, jsx_runtime_1.jsx)(Button_1.IconButtonGroup, { size: 32, children: actions.map((action) => {
66
- const Icon = icons[action.icon];
67
- return ((0, jsx_runtime_1.jsx)(ContextMenuIconButton, { "data-tooltip-content": action.label, onClick: action.disabled === true ? () => null : action.action, className: action.selected ? 'selected' : '', disabled: !!action.disabled, children: (0, jsx_runtime_1.jsx)(Icon, { width: 18, height: 18 }) }, action.icon));
68
- }) }));
71
+ const ContextMenu = ({ actions }) => {
72
+ const containerRef = (0, react_1.useRef)(null);
73
+ (0, react_1.useEffect)(() => {
74
+ const container = containerRef.current;
75
+ if (!container) {
76
+ return;
77
+ }
78
+ const buttons = Array.from(container.querySelectorAll('button:not([disabled])'));
79
+ if (buttons.length === 0) {
80
+ return;
81
+ }
82
+ buttons.forEach((button, index) => {
83
+ button.tabIndex = index === 0 ? 0 : -1;
84
+ });
85
+ const handleKeyDown = (event) => {
86
+ if (event.key !== 'ArrowRight' && event.key !== 'ArrowLeft') {
87
+ return;
88
+ }
89
+ const target = event.target;
90
+ const currentIndex = buttons.indexOf(target);
91
+ if (currentIndex === -1) {
92
+ return;
93
+ }
94
+ event.preventDefault();
95
+ const nextIndex = event.key === 'ArrowRight'
96
+ ? (currentIndex + 1) % buttons.length
97
+ : (currentIndex - 1 + buttons.length) % buttons.length;
98
+ buttons[nextIndex]?.focus();
99
+ };
100
+ container.addEventListener('keydown', handleKeyDown);
101
+ return () => {
102
+ container.removeEventListener('keydown', handleKeyDown);
103
+ };
104
+ }, [actions]);
105
+ return ((0, jsx_runtime_1.jsx)(Button_1.IconButtonGroup, { size: 32, ref: containerRef, children: actions.map((action) => {
106
+ const Icon = icons[action.icon];
107
+ return ((0, jsx_runtime_1.jsx)(ContextMenuIconButton, { "data-tooltip-content": action.label, onClick: action.disabled === true ? () => null : action.action, className: action.selected ? 'selected' : '', disabled: !!action.disabled, children: (0, jsx_runtime_1.jsx)(Icon, { width: 18, height: 18 }) }, action.icon));
108
+ }) }));
109
+ };
69
110
  exports.ContextMenu = ContextMenu;
@@ -46,9 +46,7 @@ const slideIn = (0, styled_components_1.keyframes) `
46
46
  `;
47
47
  const DrawerContainer = styled_components_1.default.div `
48
48
  width: ${(props) => props.width || '300px'};
49
- padding: 40px 0 0 0;
50
49
  background: ${(props) => props.theme.colors.background.primary};
51
- border-right: 1px solid ${(props) => props.theme.colors.border.secondary};
52
50
  height: 100%;
53
51
  display: flex;
54
52
  flex-direction: column;
@@ -1,4 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useRef } from 'react';
2
3
  import styled from 'styled-components';
3
4
  import { IconButton, IconButtonGroup } from './Button';
4
5
  import * as Icons from './icons';
@@ -13,6 +14,11 @@ const ContextMenuIconButton = styled(IconButton) `
13
14
  background-color: #f2f2f2;
14
15
  border-color: #f2f2f2;
15
16
  }
17
+ &:not([disabled]):focus-visible {
18
+ outline: 4px solid #3dadff;
19
+ outline-offset: -2px;
20
+ background-color: transparent !important;
21
+ }
16
22
  &[disabled] {
17
23
  color: #c9c9c9 !important;
18
24
  background-color: #fff !important;
@@ -23,7 +29,42 @@ const icons = Object.entries(Icons).reduce((acc, [name, IconComponent]) => {
23
29
  acc[iconName] = IconComponent;
24
30
  return acc;
25
31
  }, {});
26
- export const ContextMenu = ({ actions }) => (_jsx(IconButtonGroup, { size: 32, children: actions.map((action) => {
27
- const Icon = icons[action.icon];
28
- return (_jsx(ContextMenuIconButton, { "data-tooltip-content": action.label, onClick: action.disabled === true ? () => null : action.action, className: action.selected ? 'selected' : '', disabled: !!action.disabled, children: _jsx(Icon, { width: 18, height: 18 }) }, action.icon));
29
- }) }));
32
+ export const ContextMenu = ({ actions }) => {
33
+ const containerRef = useRef(null);
34
+ useEffect(() => {
35
+ const container = containerRef.current;
36
+ if (!container) {
37
+ return;
38
+ }
39
+ const buttons = Array.from(container.querySelectorAll('button:not([disabled])'));
40
+ if (buttons.length === 0) {
41
+ return;
42
+ }
43
+ buttons.forEach((button, index) => {
44
+ button.tabIndex = index === 0 ? 0 : -1;
45
+ });
46
+ const handleKeyDown = (event) => {
47
+ if (event.key !== 'ArrowRight' && event.key !== 'ArrowLeft') {
48
+ return;
49
+ }
50
+ const target = event.target;
51
+ const currentIndex = buttons.indexOf(target);
52
+ if (currentIndex === -1) {
53
+ return;
54
+ }
55
+ event.preventDefault();
56
+ const nextIndex = event.key === 'ArrowRight'
57
+ ? (currentIndex + 1) % buttons.length
58
+ : (currentIndex - 1 + buttons.length) % buttons.length;
59
+ buttons[nextIndex]?.focus();
60
+ };
61
+ container.addEventListener('keydown', handleKeyDown);
62
+ return () => {
63
+ container.removeEventListener('keydown', handleKeyDown);
64
+ };
65
+ }, [actions]);
66
+ return (_jsx(IconButtonGroup, { size: 32, ref: containerRef, children: actions.map((action) => {
67
+ const Icon = icons[action.icon];
68
+ return (_jsx(ContextMenuIconButton, { "data-tooltip-content": action.label, onClick: action.disabled === true ? () => null : action.action, className: action.selected ? 'selected' : '', disabled: !!action.disabled, children: _jsx(Icon, { width: 18, height: 18 }) }, action.icon));
69
+ }) }));
70
+ };
@@ -10,9 +10,7 @@ const slideIn = keyframes `
10
10
  `;
11
11
  const DrawerContainer = styled.div `
12
12
  width: ${(props) => props.width || '300px'};
13
- padding: 40px 0 0 0;
14
13
  background: ${(props) => props.theme.colors.background.primary};
15
- border-right: 1px solid ${(props) => props.theme.colors.border.secondary};
16
14
  height: 100%;
17
15
  display: flex;
18
16
  flex-direction: column;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@manuscripts/style-guide",
3
3
  "description": "Shared components for Manuscripts applications",
4
- "version": "3.4.6",
4
+ "version": "3.5.0",
5
5
  "repository": "github:Atypon-OpenSource/manuscripts-style-guide",
6
6
  "license": "Apache-2.0",
7
7
  "main": "dist/cjs",