@atlaskit/editor-toolbar 0.3.5 → 0.3.7
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/CHANGELOG.md +17 -0
- package/dist/types/hooks/ui-context.d.ts +5 -5
- package/dist/types/ui/ColorPalette/types.d.ts +30 -30
- package/dist/types/ui/ToolbarButton.d.ts +5 -5
- package/dist/types/ui/ToolbarDropdownItem.d.ts +9 -9
- package/dist/types/ui/ToolbarDropdownMenu.d.ts +4 -4
- package/dist/types/ui/ToolbarDropdownMenuContext.d.ts +1 -1
- package/dist/types/ui/ToolbarNestedDropdownMenu.d.ts +3 -3
- package/dist/types/ui/ToolbarSection.d.ts +1 -1
- package/dist/types/ui/ToolbarTooltip.d.ts +1 -1
- package/dist/types-ts4.5/hooks/ui-context.d.ts +5 -5
- package/dist/types-ts4.5/ui/ColorPalette/types.d.ts +30 -30
- package/dist/types-ts4.5/ui/ToolbarButton.d.ts +5 -5
- package/dist/types-ts4.5/ui/ToolbarDropdownItem.d.ts +9 -9
- package/dist/types-ts4.5/ui/ToolbarDropdownMenu.d.ts +4 -4
- package/dist/types-ts4.5/ui/ToolbarDropdownMenuContext.d.ts +1 -1
- package/dist/types-ts4.5/ui/ToolbarNestedDropdownMenu.d.ts +3 -3
- package/dist/types-ts4.5/ui/ToolbarSection.d.ts +1 -1
- package/dist/types-ts4.5/ui/ToolbarTooltip.d.ts +1 -1
- package/package.json +1 -2
- package/afm-cc/tsconfig.json +0 -54
- package/afm-dev-agents/tsconfig.json +0 -54
- package/afm-jira/tsconfig.json +0 -54
- package/afm-passionfruit/tsconfig.json +0 -54
- package/afm-post-office/tsconfig.json +0 -54
- package/afm-rovo-extension/tsconfig.json +0 -54
- package/afm-townsquare/tsconfig.json +0 -54
- package/afm-volt/tsconfig.json +0 -54
- package/build/tsconfig.json +0 -17
- package/examples/basic.tsx +0 -3
- package/examples/config.jsonc +0 -8
- package/examples/toolbar/examples/ExampleManuallyComposedToolbar.tsx +0 -638
- package/examples/toolbar/examples/useExampleToolbarState.tsx +0 -86
- package/examples/toolbar-ui.tsx +0 -26
- package/src/hooks/ui-context.tsx +0 -63
- package/src/index.ts +0 -74
- package/src/types.ts +0 -3
- package/src/ui/ColorPalette/Color.tsx +0 -118
- package/src/ui/ColorPalette/getColorMessage.ts +0 -27
- package/src/ui/ColorPalette/index.tsx +0 -125
- package/src/ui/ColorPalette/types.ts +0 -96
- package/src/ui/ColorPalette/utils.ts +0 -102
- package/src/ui/Toolbar.tsx +0 -57
- package/src/ui/ToolbarButton.tsx +0 -120
- package/src/ui/ToolbarButtonGroup.tsx +0 -57
- package/src/ui/ToolbarColorSwatch.tsx +0 -37
- package/src/ui/ToolbarDropdownItem.tsx +0 -142
- package/src/ui/ToolbarDropdownItemSection.tsx +0 -21
- package/src/ui/ToolbarDropdownMenu.tsx +0 -112
- package/src/ui/ToolbarDropdownMenuContext.tsx +0 -44
- package/src/ui/ToolbarKeyboardShortcutHint.tsx +0 -11
- package/src/ui/ToolbarNestedDropdownMenu.tsx +0 -45
- package/src/ui/ToolbarSection.tsx +0 -44
- package/src/ui/ToolbarTooltip.tsx +0 -18
- package/src/ui/icons/AIAdjustLengthIcon.tsx +0 -2
- package/src/ui/icons/AICasualIcon.tsx +0 -2
- package/src/ui/icons/AIChangeToneIcon.tsx +0 -2
- package/src/ui/icons/AIChatIcon.tsx +0 -50
- package/src/ui/icons/AICommandIcon.tsx +0 -2
- package/src/ui/icons/AIHeartIcon.tsx +0 -2
- package/src/ui/icons/AILengthenIcon.tsx +0 -2
- package/src/ui/icons/AIProfessionalIcon.tsx +0 -2
- package/src/ui/icons/AIShortenIcon.tsx +0 -2
- package/src/ui/icons/AISpellcheckIcon.tsx +0 -2
- package/src/ui/icons/AISummarizeIcon.tsx +0 -2
- package/src/ui/icons/AITranslateIcon.tsx +0 -2
- package/src/ui/icons/AddIcon.tsx +0 -2
- package/src/ui/icons/AlignTextCenterIcon.tsx +0 -2
- package/src/ui/icons/AlignTextLeftIcon.tsx +0 -2
- package/src/ui/icons/AlignTextRightIcon.tsx +0 -2
- package/src/ui/icons/AppsIcon.tsx +0 -2
- package/src/ui/icons/BoldIcon.tsx +0 -2
- package/src/ui/icons/ClearFormattingIcon.tsx +0 -2
- package/src/ui/icons/CodeIcon.tsx +0 -2
- package/src/ui/icons/CommentIcon.tsx +0 -2
- package/src/ui/icons/EmojiIcon.tsx +0 -2
- package/src/ui/icons/HeadingFiveIcon.tsx +0 -2
- package/src/ui/icons/HeadingFourIcon.tsx +0 -2
- package/src/ui/icons/HeadingOneIcon.tsx +0 -2
- package/src/ui/icons/HeadingSixIcon.tsx +0 -2
- package/src/ui/icons/HeadingThreeIcon.tsx +0 -2
- package/src/ui/icons/HeadingTwoIcon.tsx +0 -2
- package/src/ui/icons/HistoryIcon.tsx +0 -2
- package/src/ui/icons/ImageIcon.tsx +0 -2
- package/src/ui/icons/IndentIcon.tsx +0 -2
- package/src/ui/icons/ItalicIcon.tsx +0 -2
- package/src/ui/icons/LayoutIcon.tsx +0 -2
- package/src/ui/icons/LinkIcon.tsx +0 -2
- package/src/ui/icons/ListBulletedIcon.tsx +0 -2
- package/src/ui/icons/ListNumberedIcon.tsx +0 -2
- package/src/ui/icons/MentionIcon.tsx +0 -2
- package/src/ui/icons/MoreItemsIcon.tsx +0 -22
- package/src/ui/icons/NestedDropdownRightIcon.tsx +0 -22
- package/src/ui/icons/OutdentIcon.tsx +0 -2
- package/src/ui/icons/PinIcon.tsx +0 -2
- package/src/ui/icons/PinnedIcon.tsx +0 -2
- package/src/ui/icons/QuoteIcon.tsx +0 -2
- package/src/ui/icons/RedoIcon.tsx +0 -2
- package/src/ui/icons/ShowMoreHorizontal.tsx +0 -22
- package/src/ui/icons/StrikeThroughIcon.tsx +0 -2
- package/src/ui/icons/SubscriptIcon.tsx +0 -31
- package/src/ui/icons/SuperscriptIcon.tsx +0 -31
- package/src/ui/icons/TableIcon.tsx +0 -2
- package/src/ui/icons/TaskIcon.tsx +0 -2
- package/src/ui/icons/TextColorIcon.tsx +0 -43
- package/src/ui/icons/TextIcon.tsx +0 -2
- package/src/ui/icons/UnderlineIcon.tsx +0 -2
- package/src/ui/icons/UndoIcon.tsx +0 -2
- package/tsconfig.app.json +0 -65
- package/tsconfig.dev.json +0 -56
- package/tsconfig.json +0 -18
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import type { PaletteColor } from './types';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Default number of columns in the color picker
|
|
5
|
-
*/
|
|
6
|
-
export const DEFAULT_COLOR_PICKER_COLUMNS = 7;
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Splits a palette array into rows based on the specified number of columns
|
|
10
|
-
* @param palette - Array of palette colors
|
|
11
|
-
* @param cols - Number of columns per row
|
|
12
|
-
* @returns Array of color rows
|
|
13
|
-
*/
|
|
14
|
-
export function getColorsPerRowFromPalette(
|
|
15
|
-
palette: PaletteColor[],
|
|
16
|
-
cols: number = DEFAULT_COLOR_PICKER_COLUMNS,
|
|
17
|
-
): PaletteColor[][] {
|
|
18
|
-
return palette.reduce((resultArray: PaletteColor[][], item: PaletteColor, index: number) => {
|
|
19
|
-
const chunkIndex = Math.floor(index / cols);
|
|
20
|
-
|
|
21
|
-
resultArray[chunkIndex] = resultArray[chunkIndex] || []; // start a new chunk
|
|
22
|
-
resultArray[chunkIndex].push(item);
|
|
23
|
-
|
|
24
|
-
return resultArray;
|
|
25
|
-
}, []);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Finds the row and column indices of a selected color in the palette grid
|
|
30
|
-
* @param colorsPerRow - 2D array of colors organized by rows
|
|
31
|
-
* @param selectedColor - The currently selected color value
|
|
32
|
-
* @returns Object containing row and column indices
|
|
33
|
-
*/
|
|
34
|
-
export function getSelectedRowAndColumn(
|
|
35
|
-
colorsPerRow: PaletteColor[][],
|
|
36
|
-
selectedColor: string | null,
|
|
37
|
-
) {
|
|
38
|
-
let selectedRowIndex = -1;
|
|
39
|
-
let selectedColumnIndex = -1;
|
|
40
|
-
|
|
41
|
-
colorsPerRow.forEach((row, rowIndex) => {
|
|
42
|
-
row.forEach(({ value }, columnIndex) => {
|
|
43
|
-
if (value === selectedColor) {
|
|
44
|
-
selectedRowIndex = rowIndex;
|
|
45
|
-
selectedColumnIndex = columnIndex;
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
return {
|
|
51
|
-
selectedRowIndex,
|
|
52
|
-
selectedColumnIndex,
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Finds the row and column indices of a selected color in a flat palette array
|
|
58
|
-
* @param palette - Flat array of palette colors
|
|
59
|
-
* @param selectedColor - The currently selected color value
|
|
60
|
-
* @param cols - Number of columns per row
|
|
61
|
-
* @returns Object containing row and column indices
|
|
62
|
-
*/
|
|
63
|
-
export function getSelectedRowAndColumnFromPalette(
|
|
64
|
-
palette: PaletteColor[],
|
|
65
|
-
selectedColor: string | null,
|
|
66
|
-
cols: number = DEFAULT_COLOR_PICKER_COLUMNS,
|
|
67
|
-
) {
|
|
68
|
-
const colorsPerRow = getColorsPerRowFromPalette(palette, cols);
|
|
69
|
-
return getSelectedRowAndColumn(colorsPerRow, selectedColor);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Extracts the actual color value from a CSS variable expression
|
|
74
|
-
* Handles both token variables and fallback values
|
|
75
|
-
* @param variableExpression - CSS variable expression (e.g., "var(--ds-background-accent-blue-subtle, #0052CC)")
|
|
76
|
-
* @returns The resolved color value or empty string if not found
|
|
77
|
-
*/
|
|
78
|
-
export const getTokenCSSVariableValue = (variableExpression: string): string => {
|
|
79
|
-
// Match CSS variable pattern: var(--variable-name, fallback)
|
|
80
|
-
// Ignored via go/ees005
|
|
81
|
-
// eslint-disable-next-line require-unicode-regexp
|
|
82
|
-
const matcher = variableExpression.match(/var\(([^,\)]+)(,.*)?/);
|
|
83
|
-
if (matcher) {
|
|
84
|
-
const variable = matcher[1].trim();
|
|
85
|
-
const fallback = matcher[2] ? matcher[2].replace(',', '').trim() : '';
|
|
86
|
-
|
|
87
|
-
// Return fallback if we're in a server environment
|
|
88
|
-
if (typeof document === 'undefined') {
|
|
89
|
-
return fallback;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Get the computed value from the document
|
|
93
|
-
const value = window
|
|
94
|
-
.getComputedStyle(document.documentElement)
|
|
95
|
-
.getPropertyValue(variable)
|
|
96
|
-
.trim();
|
|
97
|
-
|
|
98
|
-
return value || fallback;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
return '';
|
|
102
|
-
};
|
package/src/ui/Toolbar.tsx
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import React, { type ReactNode } from 'react';
|
|
2
|
-
|
|
3
|
-
import { cssMap, cx } from '@atlaskit/css';
|
|
4
|
-
import { Box } from '@atlaskit/primitives/compiled';
|
|
5
|
-
import { token } from '@atlaskit/tokens';
|
|
6
|
-
|
|
7
|
-
const styles = cssMap({
|
|
8
|
-
toolbarBase: {
|
|
9
|
-
backgroundColor: token('elevation.surface'),
|
|
10
|
-
borderRadius: '6px',
|
|
11
|
-
display: 'flex',
|
|
12
|
-
alignItems: 'center',
|
|
13
|
-
gap: token('space.050'),
|
|
14
|
-
},
|
|
15
|
-
toolbar: {
|
|
16
|
-
height: '36px',
|
|
17
|
-
paddingRight: token('space.050'),
|
|
18
|
-
paddingLeft: token('space.050'),
|
|
19
|
-
boxShadow: token('elevation.shadow.overlay'),
|
|
20
|
-
},
|
|
21
|
-
primaryToolbar: {
|
|
22
|
-
backgroundColor: token('elevation.surface'),
|
|
23
|
-
minHeight: '32px',
|
|
24
|
-
},
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
type ToolbarProps = {
|
|
28
|
-
children?: ReactNode;
|
|
29
|
-
/**
|
|
30
|
-
* aria-label for the toolbar (No localisation needed as it won't be read by screen readers).
|
|
31
|
-
*
|
|
32
|
-
* use case: query select the toolbar to position floating toolbar
|
|
33
|
-
*/
|
|
34
|
-
label: string;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* A simple component representing a toolbar with box shadows - used to represent a secondary/floating toolbar
|
|
39
|
-
*/
|
|
40
|
-
export const Toolbar = ({ children, label }: ToolbarProps) => {
|
|
41
|
-
return (
|
|
42
|
-
<Box xcss={cx(styles.toolbarBase, styles.toolbar)} role="toolbar" aria-label={label}>
|
|
43
|
-
{children}
|
|
44
|
-
</Box>
|
|
45
|
-
);
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* A simple component representing a toolbar without box shadows - used to represent a primary toolbar
|
|
50
|
-
*/
|
|
51
|
-
export const PrimaryToolbar = ({ children, label }: ToolbarProps) => {
|
|
52
|
-
return (
|
|
53
|
-
<Box xcss={cx(styles.toolbarBase, styles.primaryToolbar)} role="toolbar" aria-label={label}>
|
|
54
|
-
{children}
|
|
55
|
-
</Box>
|
|
56
|
-
);
|
|
57
|
-
};
|
package/src/ui/ToolbarButton.tsx
DELETED
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import React, { forwardRef, type ReactNode, type Ref } from 'react';
|
|
2
|
-
|
|
3
|
-
import { cssMap, cx } from '@atlaskit/css';
|
|
4
|
-
import { type TriggerProps } from '@atlaskit/popup';
|
|
5
|
-
import { Pressable } from '@atlaskit/primitives/compiled';
|
|
6
|
-
import { token } from '@atlaskit/tokens';
|
|
7
|
-
|
|
8
|
-
import { useToolbarUI } from '../hooks/ui-context';
|
|
9
|
-
|
|
10
|
-
const styles = cssMap({
|
|
11
|
-
button: {
|
|
12
|
-
display: 'flex',
|
|
13
|
-
gap: token('space.075'),
|
|
14
|
-
backgroundColor: token('color.background.neutral.subtle'),
|
|
15
|
-
whiteSpace: 'nowrap',
|
|
16
|
-
alignItems: 'center',
|
|
17
|
-
justifyContent: 'center',
|
|
18
|
-
borderRadius: token('border.radius.100'),
|
|
19
|
-
minHeight: '28px',
|
|
20
|
-
color: token('color.text.subtle'),
|
|
21
|
-
fontWeight: token('font.weight.medium'),
|
|
22
|
-
paddingLeft: token('space.100'),
|
|
23
|
-
paddingRight: token('space.100'),
|
|
24
|
-
'&:focus-visible': {
|
|
25
|
-
outlineOffset: '0',
|
|
26
|
-
zIndex: 1,
|
|
27
|
-
position: 'relative',
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
enabled: {
|
|
31
|
-
'&:hover': {
|
|
32
|
-
backgroundColor: token('color.background.neutral.subtle.hovered'),
|
|
33
|
-
},
|
|
34
|
-
'&:active': {
|
|
35
|
-
backgroundColor: token('color.background.neutral.subtle.pressed'),
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
disabled: {
|
|
39
|
-
color: token('color.text.disabled'),
|
|
40
|
-
cursor: 'not-allowed',
|
|
41
|
-
},
|
|
42
|
-
selected: {
|
|
43
|
-
backgroundColor: token('color.background.selected'),
|
|
44
|
-
color: token('color.text.selected'),
|
|
45
|
-
'&:hover': {
|
|
46
|
-
backgroundColor: token('color.background.selected.hovered'),
|
|
47
|
-
},
|
|
48
|
-
'&:active': {
|
|
49
|
-
backgroundColor: token('color.background.selected.pressed'),
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
type ToolbarButtonProps = Partial<TriggerProps> & {
|
|
55
|
-
children?: ReactNode;
|
|
56
|
-
isSelected?: boolean;
|
|
57
|
-
onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
|
|
58
|
-
onBlur?: (event: React.FocusEvent<HTMLButtonElement>) => void;
|
|
59
|
-
onFocus?: (event: React.FocusEvent<HTMLButtonElement>) => void;
|
|
60
|
-
testId?: string;
|
|
61
|
-
iconBefore: React.ReactNode;
|
|
62
|
-
isDisabled?: boolean;
|
|
63
|
-
ariaKeyshortcuts?: string;
|
|
64
|
-
label?: string;
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
export const ToolbarButton = forwardRef(
|
|
68
|
-
(
|
|
69
|
-
{
|
|
70
|
-
iconBefore,
|
|
71
|
-
children,
|
|
72
|
-
onClick,
|
|
73
|
-
isSelected,
|
|
74
|
-
'aria-expanded': ariaExpanded,
|
|
75
|
-
'aria-haspopup': ariaHasPopup,
|
|
76
|
-
'aria-controls': ariaControls,
|
|
77
|
-
'data-ds--level': dataDsLevel,
|
|
78
|
-
onBlur,
|
|
79
|
-
onFocus,
|
|
80
|
-
testId,
|
|
81
|
-
isDisabled,
|
|
82
|
-
ariaKeyshortcuts,
|
|
83
|
-
label,
|
|
84
|
-
}: ToolbarButtonProps,
|
|
85
|
-
ref: Ref<HTMLButtonElement>,
|
|
86
|
-
) => {
|
|
87
|
-
const { preventDefaultOnMouseDown, isDisabled: ctxDisabled } = useToolbarUI();
|
|
88
|
-
const disabled = Boolean(ctxDisabled || isDisabled);
|
|
89
|
-
|
|
90
|
-
return (
|
|
91
|
-
<Pressable
|
|
92
|
-
ref={ref}
|
|
93
|
-
xcss={cx(
|
|
94
|
-
styles.button,
|
|
95
|
-
disabled ? styles.disabled : isSelected ? styles.selected : styles.enabled,
|
|
96
|
-
)}
|
|
97
|
-
aria-pressed={isSelected}
|
|
98
|
-
aria-expanded={ariaExpanded}
|
|
99
|
-
aria-haspopup={ariaHasPopup}
|
|
100
|
-
aria-controls={ariaControls}
|
|
101
|
-
aria-keyshortcuts={ariaKeyshortcuts}
|
|
102
|
-
aria-label={label}
|
|
103
|
-
data-ds--level={dataDsLevel}
|
|
104
|
-
onClick={onClick}
|
|
105
|
-
onBlur={onBlur}
|
|
106
|
-
onFocus={onFocus}
|
|
107
|
-
testId={testId}
|
|
108
|
-
isDisabled={disabled}
|
|
109
|
-
onMouseDown={(event) => {
|
|
110
|
-
if (preventDefaultOnMouseDown) {
|
|
111
|
-
event.preventDefault();
|
|
112
|
-
}
|
|
113
|
-
}}
|
|
114
|
-
>
|
|
115
|
-
{iconBefore}
|
|
116
|
-
{children}
|
|
117
|
-
</Pressable>
|
|
118
|
-
);
|
|
119
|
-
},
|
|
120
|
-
);
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @jsxRuntime classic
|
|
3
|
-
* @jsx jsx
|
|
4
|
-
*/
|
|
5
|
-
import { Children, Fragment, type ReactNode } from 'react';
|
|
6
|
-
|
|
7
|
-
import { cssMap, jsx } from '@compiled/react';
|
|
8
|
-
|
|
9
|
-
import { Box } from '@atlaskit/primitives/compiled';
|
|
10
|
-
import { token } from '@atlaskit/tokens';
|
|
11
|
-
|
|
12
|
-
const styles = cssMap({
|
|
13
|
-
container: {
|
|
14
|
-
display: 'flex',
|
|
15
|
-
},
|
|
16
|
-
firstChild: {
|
|
17
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
|
|
18
|
-
button: {
|
|
19
|
-
borderTopRightRadius: 0,
|
|
20
|
-
borderBottomRightRadius: 0,
|
|
21
|
-
paddingInline: token('space.075'),
|
|
22
|
-
},
|
|
23
|
-
},
|
|
24
|
-
lastChild: {
|
|
25
|
-
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
|
|
26
|
-
button: {
|
|
27
|
-
borderTopLeftRadius: 0,
|
|
28
|
-
borderBottomLeftRadius: 0,
|
|
29
|
-
paddingInline: token('space.075'),
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
type ToolbarButtonGroupProps = {
|
|
35
|
-
children?: ReactNode;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
export const ToolbarButtonGroup = ({ children }: ToolbarButtonGroupProps) => {
|
|
39
|
-
const items = Children.toArray(children);
|
|
40
|
-
const FirstChild = items.at(0);
|
|
41
|
-
const LastChild = items.at(-1);
|
|
42
|
-
const middleChildren = items.slice(1, -1);
|
|
43
|
-
|
|
44
|
-
return (
|
|
45
|
-
<Box xcss={styles.container}>
|
|
46
|
-
{items.length <= 1 ? (
|
|
47
|
-
children
|
|
48
|
-
) : (
|
|
49
|
-
<Fragment>
|
|
50
|
-
<div css={styles.firstChild}>{FirstChild}</div>
|
|
51
|
-
{middleChildren}
|
|
52
|
-
<div css={styles.lastChild}>{LastChild}</div>
|
|
53
|
-
</Fragment>
|
|
54
|
-
)}
|
|
55
|
-
</Box>
|
|
56
|
-
);
|
|
57
|
-
};
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import React, { type ReactNode } from 'react';
|
|
2
|
-
|
|
3
|
-
import { cssMap } from '@atlaskit/css';
|
|
4
|
-
import { Box } from '@atlaskit/primitives/compiled';
|
|
5
|
-
import { token } from '@atlaskit/tokens';
|
|
6
|
-
|
|
7
|
-
type ToolbarColorSwatchProps = {
|
|
8
|
-
children?: ReactNode;
|
|
9
|
-
highlightColor?: string;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
const styles = cssMap({
|
|
13
|
-
colorSwatch: {
|
|
14
|
-
display: 'flex',
|
|
15
|
-
justifyContent: 'center',
|
|
16
|
-
alignItems: 'center',
|
|
17
|
-
border: `${token('border.width')} solid ${token('color.border')}`,
|
|
18
|
-
borderRadius: token('border.radius.100'),
|
|
19
|
-
width: '20px',
|
|
20
|
-
height: '20px',
|
|
21
|
-
marginLeft: token('space.negative.050'),
|
|
22
|
-
marginRight: token('space.negative.050'),
|
|
23
|
-
},
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
export const ToolbarColorSwatch = ({ children, highlightColor }: ToolbarColorSwatchProps) => {
|
|
27
|
-
return (
|
|
28
|
-
<Box
|
|
29
|
-
xcss={styles.colorSwatch}
|
|
30
|
-
style={{
|
|
31
|
-
backgroundColor: highlightColor,
|
|
32
|
-
}}
|
|
33
|
-
>
|
|
34
|
-
{children}
|
|
35
|
-
</Box>
|
|
36
|
-
);
|
|
37
|
-
};
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import React, { type ReactNode, forwardRef, type Ref } from 'react';
|
|
2
|
-
|
|
3
|
-
import { cssMap, cx } from '@atlaskit/css';
|
|
4
|
-
import { DropdownItem } from '@atlaskit/dropdown-menu';
|
|
5
|
-
import type { CustomItemComponentProps } from '@atlaskit/menu/types';
|
|
6
|
-
import { Pressable } from '@atlaskit/primitives/compiled';
|
|
7
|
-
import { token } from '@atlaskit/tokens';
|
|
8
|
-
|
|
9
|
-
type TextStyle =
|
|
10
|
-
| 'normal'
|
|
11
|
-
| 'heading1'
|
|
12
|
-
| 'heading2'
|
|
13
|
-
| 'heading3'
|
|
14
|
-
| 'heading4'
|
|
15
|
-
| 'heading5'
|
|
16
|
-
| 'heading6';
|
|
17
|
-
|
|
18
|
-
const styles = cssMap({
|
|
19
|
-
toolbarDropdownItem: {
|
|
20
|
-
display: 'flex',
|
|
21
|
-
position: 'relative',
|
|
22
|
-
backgroundColor: token('color.background.neutral.subtle'),
|
|
23
|
-
width: '100%',
|
|
24
|
-
minHeight: '36px',
|
|
25
|
-
minWidth: '230px',
|
|
26
|
-
paddingInline: token('space.200'),
|
|
27
|
-
paddingBlock: token('space.100'),
|
|
28
|
-
'&:focus-visible': {
|
|
29
|
-
outlineOffset: token('space.negative.025'),
|
|
30
|
-
borderRadius: token('border.radius'),
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
|
-
enabled: {
|
|
34
|
-
'&:hover': {
|
|
35
|
-
backgroundColor: token('color.background.neutral.subtle.hovered'),
|
|
36
|
-
},
|
|
37
|
-
'&:active': {
|
|
38
|
-
backgroundColor: token('color.background.neutral.subtle.pressed'),
|
|
39
|
-
},
|
|
40
|
-
},
|
|
41
|
-
disabled: {
|
|
42
|
-
color: token('color.text.disabled'),
|
|
43
|
-
cursor: 'not-allowed',
|
|
44
|
-
},
|
|
45
|
-
selected: {
|
|
46
|
-
backgroundColor: token('color.background.selected'),
|
|
47
|
-
color: token('color.text.selected'),
|
|
48
|
-
'&:hover': {
|
|
49
|
-
backgroundColor: token('color.background.selected.hovered'),
|
|
50
|
-
},
|
|
51
|
-
'&:active': {
|
|
52
|
-
backgroundColor: token('color.background.selected.pressed'),
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
export type CustomDropdownMenuItemButtonProps = CustomItemComponentProps & {
|
|
58
|
-
'aria-haspopup'?: boolean;
|
|
59
|
-
'aria-disabled'?: boolean;
|
|
60
|
-
'aria-pressed'?: boolean;
|
|
61
|
-
'aria-keyshortcuts'?: string;
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
const CustomDropdownMenuItemButton = forwardRef<
|
|
65
|
-
HTMLButtonElement,
|
|
66
|
-
CustomDropdownMenuItemButtonProps
|
|
67
|
-
>(
|
|
68
|
-
(
|
|
69
|
-
{
|
|
70
|
-
children,
|
|
71
|
-
'data-testid': testId,
|
|
72
|
-
'aria-haspopup': ariaHasPopup,
|
|
73
|
-
'aria-disabled': ariaDisabled,
|
|
74
|
-
'aria-pressed': ariaPressed,
|
|
75
|
-
'aria-keyshortcuts': ariaKeyshortcuts,
|
|
76
|
-
onClick,
|
|
77
|
-
tabIndex,
|
|
78
|
-
},
|
|
79
|
-
ref,
|
|
80
|
-
) => (
|
|
81
|
-
<Pressable
|
|
82
|
-
testId={testId}
|
|
83
|
-
xcss={cx(
|
|
84
|
-
styles.toolbarDropdownItem,
|
|
85
|
-
ariaDisabled ? styles.disabled : ariaPressed ? styles.selected : styles.enabled,
|
|
86
|
-
)}
|
|
87
|
-
onClick={onClick}
|
|
88
|
-
tabIndex={tabIndex}
|
|
89
|
-
aria-haspopup={ariaHasPopup}
|
|
90
|
-
aria-expanded={ariaHasPopup ? (ariaPressed ? true : false) : undefined}
|
|
91
|
-
aria-pressed={ariaPressed}
|
|
92
|
-
aria-disabled={ariaDisabled}
|
|
93
|
-
aria-keyshortcuts={ariaKeyshortcuts}
|
|
94
|
-
ref={ref}
|
|
95
|
-
>
|
|
96
|
-
{children}
|
|
97
|
-
</Pressable>
|
|
98
|
-
),
|
|
99
|
-
);
|
|
100
|
-
|
|
101
|
-
type ToolbarDropdownItemProps = {
|
|
102
|
-
onClick?: (e: React.MouseEvent | React.KeyboardEvent) => void;
|
|
103
|
-
elemBefore?: ReactNode;
|
|
104
|
-
elemAfter?: ReactNode;
|
|
105
|
-
isSelected?: boolean;
|
|
106
|
-
children?: React.ReactNode;
|
|
107
|
-
textStyle?: TextStyle;
|
|
108
|
-
isDisabled?: boolean;
|
|
109
|
-
hasNestedDropdownMenu?: boolean;
|
|
110
|
-
triggerRef?: Ref<HTMLButtonElement>;
|
|
111
|
-
testId?: string;
|
|
112
|
-
ariaKeyshortcuts?: string;
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
export const ToolbarDropdownItem = ({
|
|
116
|
-
onClick,
|
|
117
|
-
elemBefore,
|
|
118
|
-
elemAfter,
|
|
119
|
-
isSelected,
|
|
120
|
-
children,
|
|
121
|
-
isDisabled,
|
|
122
|
-
hasNestedDropdownMenu,
|
|
123
|
-
triggerRef,
|
|
124
|
-
testId,
|
|
125
|
-
ariaKeyshortcuts,
|
|
126
|
-
}: ToolbarDropdownItemProps) => (
|
|
127
|
-
<DropdownItem
|
|
128
|
-
onClick={onClick}
|
|
129
|
-
elemBefore={elemBefore}
|
|
130
|
-
elemAfter={elemAfter}
|
|
131
|
-
isSelected={isSelected}
|
|
132
|
-
isDisabled={isDisabled}
|
|
133
|
-
aria-haspopup={hasNestedDropdownMenu}
|
|
134
|
-
aria-pressed={isSelected}
|
|
135
|
-
aria-keyshortcuts={ariaKeyshortcuts}
|
|
136
|
-
ref={triggerRef}
|
|
137
|
-
component={CustomDropdownMenuItemButton}
|
|
138
|
-
testId={testId}
|
|
139
|
-
>
|
|
140
|
-
{children}
|
|
141
|
-
</DropdownItem>
|
|
142
|
-
);
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import React, { type ReactNode } from 'react';
|
|
2
|
-
|
|
3
|
-
import { DropdownItemGroup } from '@atlaskit/dropdown-menu';
|
|
4
|
-
|
|
5
|
-
type ToolbarDropdownItemSectionProps = {
|
|
6
|
-
children?: ReactNode;
|
|
7
|
-
hasSeparator?: boolean;
|
|
8
|
-
title?: string;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export const ToolbarDropdownItemSection = ({
|
|
12
|
-
children,
|
|
13
|
-
hasSeparator,
|
|
14
|
-
title,
|
|
15
|
-
}: ToolbarDropdownItemSectionProps) => {
|
|
16
|
-
return (
|
|
17
|
-
<DropdownItemGroup hasSeparator={hasSeparator} title={title}>
|
|
18
|
-
{children}
|
|
19
|
-
</DropdownItemGroup>
|
|
20
|
-
);
|
|
21
|
-
};
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @jsxRuntime classic
|
|
3
|
-
* @jsx jsx
|
|
4
|
-
*/
|
|
5
|
-
import React, { type ReactNode, useCallback } from 'react';
|
|
6
|
-
|
|
7
|
-
import { jsx, cssMap } from '@compiled/react';
|
|
8
|
-
|
|
9
|
-
import DropdownMenu, { type OnOpenChangeArgs } from '@atlaskit/dropdown-menu';
|
|
10
|
-
import { token } from '@atlaskit/tokens';
|
|
11
|
-
|
|
12
|
-
import { useToolbarUI } from '../hooks/ui-context';
|
|
13
|
-
|
|
14
|
-
import { ToolbarButton } from './ToolbarButton';
|
|
15
|
-
import { ToolbarDropdownMenuProvider, useToolbarDropdownMenu } from './ToolbarDropdownMenuContext';
|
|
16
|
-
|
|
17
|
-
const styles = cssMap({
|
|
18
|
-
sectionMargin: {
|
|
19
|
-
marginBlock: token('space.050'),
|
|
20
|
-
},
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
type ToolbarDropdownMenuProps = {
|
|
24
|
-
iconBefore: React.ReactNode;
|
|
25
|
-
children?: ReactNode;
|
|
26
|
-
isDisabled?: boolean;
|
|
27
|
-
testId?: string;
|
|
28
|
-
label?: string;
|
|
29
|
-
/**
|
|
30
|
-
* Whether to add margin around sections to align with 4px block padding existing in current editor dropdown
|
|
31
|
-
*/
|
|
32
|
-
hasSectionMargin?: boolean;
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
const ToolbarDropdownMenuContent = ({
|
|
36
|
-
iconBefore,
|
|
37
|
-
children,
|
|
38
|
-
isDisabled,
|
|
39
|
-
testId,
|
|
40
|
-
label,
|
|
41
|
-
}: ToolbarDropdownMenuProps) => {
|
|
42
|
-
const { onDropdownOpenChanged } = useToolbarUI();
|
|
43
|
-
const { closeMenu, isOpen, openMenu } = useToolbarDropdownMenu();
|
|
44
|
-
|
|
45
|
-
const handleOpenChange = useCallback(
|
|
46
|
-
(args: OnOpenChangeArgs) => {
|
|
47
|
-
onDropdownOpenChanged(args);
|
|
48
|
-
if (!args.isOpen) {
|
|
49
|
-
closeMenu();
|
|
50
|
-
}
|
|
51
|
-
},
|
|
52
|
-
[closeMenu, onDropdownOpenChanged],
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
const handleClick = useCallback(() => {
|
|
56
|
-
if (!isOpen) {
|
|
57
|
-
openMenu();
|
|
58
|
-
} else {
|
|
59
|
-
closeMenu();
|
|
60
|
-
}
|
|
61
|
-
}, [closeMenu, openMenu, isOpen]);
|
|
62
|
-
|
|
63
|
-
return (
|
|
64
|
-
<DropdownMenu<HTMLButtonElement>
|
|
65
|
-
trigger={(triggerProps) => (
|
|
66
|
-
<ToolbarButton
|
|
67
|
-
ref={triggerProps.triggerRef}
|
|
68
|
-
isSelected={triggerProps.isSelected}
|
|
69
|
-
aria-expanded={triggerProps['aria-expanded']}
|
|
70
|
-
aria-haspopup={triggerProps['aria-haspopup']}
|
|
71
|
-
aria-controls={triggerProps['aria-controls']}
|
|
72
|
-
onBlur={triggerProps.onBlur}
|
|
73
|
-
onClick={(e) => {
|
|
74
|
-
handleClick();
|
|
75
|
-
triggerProps.onClick && triggerProps.onClick(e);
|
|
76
|
-
}}
|
|
77
|
-
onFocus={triggerProps.onFocus}
|
|
78
|
-
testId={testId}
|
|
79
|
-
iconBefore={iconBefore}
|
|
80
|
-
isDisabled={isDisabled}
|
|
81
|
-
label={label}
|
|
82
|
-
/>
|
|
83
|
-
)}
|
|
84
|
-
onOpenChange={handleOpenChange}
|
|
85
|
-
isOpen={isOpen}
|
|
86
|
-
>
|
|
87
|
-
{children}
|
|
88
|
-
</DropdownMenu>
|
|
89
|
-
);
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
export const ToolbarDropdownMenu = ({
|
|
93
|
-
iconBefore,
|
|
94
|
-
children,
|
|
95
|
-
isDisabled,
|
|
96
|
-
testId,
|
|
97
|
-
label,
|
|
98
|
-
hasSectionMargin = true,
|
|
99
|
-
}: ToolbarDropdownMenuProps) => {
|
|
100
|
-
return (
|
|
101
|
-
<ToolbarDropdownMenuProvider>
|
|
102
|
-
<ToolbarDropdownMenuContent
|
|
103
|
-
iconBefore={iconBefore}
|
|
104
|
-
isDisabled={isDisabled}
|
|
105
|
-
testId={testId}
|
|
106
|
-
label={label}
|
|
107
|
-
>
|
|
108
|
-
<div css={hasSectionMargin && styles.sectionMargin}>{children}</div>
|
|
109
|
-
</ToolbarDropdownMenuContent>
|
|
110
|
-
</ToolbarDropdownMenuProvider>
|
|
111
|
-
);
|
|
112
|
-
};
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import React, { createContext, useContext, useState } from 'react';
|
|
2
|
-
|
|
3
|
-
interface ToolbarDropdownMenuContextValue {
|
|
4
|
-
openMenu: () => void;
|
|
5
|
-
closeMenu: () => void;
|
|
6
|
-
isOpen: boolean;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const ToolbarDropdownMenuContext = createContext<ToolbarDropdownMenuContextValue | undefined>(
|
|
10
|
-
undefined,
|
|
11
|
-
);
|
|
12
|
-
|
|
13
|
-
export const useToolbarDropdownMenu = () => {
|
|
14
|
-
const context = useContext(ToolbarDropdownMenuContext);
|
|
15
|
-
if (!context) {
|
|
16
|
-
throw new Error('useToolbarDropdownMenu must be used within ToolbarDropdownMenuProvider');
|
|
17
|
-
}
|
|
18
|
-
return context;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
interface ToolbarDropdownMenuProviderProps {
|
|
22
|
-
children: React.ReactNode;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export const ToolbarDropdownMenuProvider = ({ children }: ToolbarDropdownMenuProviderProps) => {
|
|
26
|
-
const [isOpen, setIsOpen] = useState(false);
|
|
27
|
-
|
|
28
|
-
const openMenu = () => setIsOpen(true);
|
|
29
|
-
const closeMenu = () => {
|
|
30
|
-
setIsOpen(false);
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const contextValue: ToolbarDropdownMenuContextValue = {
|
|
34
|
-
openMenu,
|
|
35
|
-
closeMenu,
|
|
36
|
-
isOpen,
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
return (
|
|
40
|
-
<ToolbarDropdownMenuContext.Provider value={contextValue}>
|
|
41
|
-
{children}
|
|
42
|
-
</ToolbarDropdownMenuContext.Provider>
|
|
43
|
-
);
|
|
44
|
-
};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
import Badge from '@atlaskit/badge';
|
|
4
|
-
|
|
5
|
-
type ToolbarKeyboardShortcutHintProps = {
|
|
6
|
-
shortcut: string;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export const ToolbarKeyboardShortcutHint = ({ shortcut }: ToolbarKeyboardShortcutHintProps) => {
|
|
10
|
-
return <Badge>{shortcut}</Badge>;
|
|
11
|
-
};
|