@cloud-ru/ds-markdown 1.0.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/CHANGELOG.md +8 -0
- package/LICENSE +201 -0
- package/README.md +273 -0
- package/dist/cjs/components/Markdown/CodeBlock.d.ts +9 -0
- package/dist/cjs/components/Markdown/CodeBlock.js +58 -0
- package/dist/cjs/components/Markdown/Markdown.d.ts +2 -0
- package/dist/cjs/components/Markdown/Markdown.js +25 -0
- package/dist/cjs/components/Markdown/index.d.ts +1 -0
- package/dist/cjs/components/Markdown/index.js +17 -0
- package/dist/cjs/components/Markdown/styles.module.css +205 -0
- package/dist/cjs/components/MarkdownEditor/MarkdownEditor.d.ts +2 -0
- package/dist/cjs/components/MarkdownEditor/MarkdownEditor.js +176 -0
- package/dist/cjs/components/MarkdownEditor/index.d.ts +1 -0
- package/dist/cjs/components/MarkdownEditor/index.js +17 -0
- package/dist/cjs/components/MarkdownEditor/styles.module.css +273 -0
- package/dist/cjs/components/Toolbar/Toolbar.d.ts +9 -0
- package/dist/cjs/components/Toolbar/Toolbar.js +173 -0
- package/dist/cjs/components/Toolbar/constants.d.ts +13 -0
- package/dist/cjs/components/Toolbar/constants.js +40 -0
- package/dist/cjs/components/Toolbar/hooks/index.d.ts +2 -0
- package/dist/cjs/components/Toolbar/hooks/index.js +18 -0
- package/dist/cjs/components/Toolbar/hooks/useToolbarHotkeys.d.ts +21 -0
- package/dist/cjs/components/Toolbar/hooks/useToolbarHotkeys.js +59 -0
- package/dist/cjs/components/Toolbar/hooks/useToolbarOverflow.d.ts +14 -0
- package/dist/cjs/components/Toolbar/hooks/useToolbarOverflow.js +87 -0
- package/dist/cjs/components/Toolbar/index.d.ts +2 -0
- package/dist/cjs/components/Toolbar/index.js +20 -0
- package/dist/cjs/components/Toolbar/styles.module.css +17 -0
- package/dist/cjs/components/index.d.ts +2 -0
- package/dist/cjs/components/index.js +20 -0
- package/dist/cjs/constants.d.ts +65 -0
- package/dist/cjs/constants.js +67 -0
- package/dist/cjs/helperComponents/ButtonHeading/ButtonHeading.d.ts +6 -0
- package/dist/cjs/helperComponents/ButtonHeading/ButtonHeading.js +61 -0
- package/dist/cjs/helperComponents/ButtonHeading/index.d.ts +1 -0
- package/dist/cjs/helperComponents/ButtonHeading/index.js +17 -0
- package/dist/cjs/helperComponents/ButtonHeading/styles.module.css +3 -0
- package/dist/cjs/helperComponents/Buttons/Buttons.d.ts +10 -0
- package/dist/cjs/helperComponents/Buttons/Buttons.js +21 -0
- package/dist/cjs/helperComponents/Buttons/index.d.ts +1 -0
- package/dist/cjs/helperComponents/Buttons/index.js +17 -0
- package/dist/cjs/helperComponents/Buttons/styles.module.css +17 -0
- package/dist/cjs/helperComponents/Modals/CustomizeTableModal.d.ts +8 -0
- package/dist/cjs/helperComponents/Modals/CustomizeTableModal.js +39 -0
- package/dist/cjs/helperComponents/Modals/ImageModal.d.ts +7 -0
- package/dist/cjs/helperComponents/Modals/ImageModal.js +44 -0
- package/dist/cjs/helperComponents/Modals/LinkModal.d.ts +13 -0
- package/dist/cjs/helperComponents/Modals/LinkModal.js +42 -0
- package/dist/cjs/helperComponents/Modals/index.d.ts +3 -0
- package/dist/cjs/helperComponents/Modals/index.js +19 -0
- package/dist/cjs/helperComponents/Modals/styles.module.css +17 -0
- package/dist/cjs/helperComponents/PrivateButton/PrivateButton.d.ts +17 -0
- package/dist/cjs/helperComponents/PrivateButton/PrivateButton.js +27 -0
- package/dist/cjs/helperComponents/PrivateButton/index.d.ts +1 -0
- package/dist/cjs/helperComponents/PrivateButton/index.js +17 -0
- package/dist/cjs/helperComponents/PrivateButton/styles.module.css +140 -0
- package/dist/cjs/helperComponents/TableSelectItem/TableSelectItem.d.ts +11 -0
- package/dist/cjs/helperComponents/TableSelectItem/TableSelectItem.js +12 -0
- package/dist/cjs/helperComponents/TableSelectItem/index.d.ts +1 -0
- package/dist/cjs/helperComponents/TableSelectItem/index.js +17 -0
- package/dist/cjs/helperComponents/TableSelectItem/styles.module.css +101 -0
- package/dist/cjs/helperComponents/TableSelectSettingsGrid/TableSelectSettingsGrid.d.ts +4 -0
- package/dist/cjs/helperComponents/TableSelectSettingsGrid/TableSelectSettingsGrid.js +27 -0
- package/dist/cjs/helperComponents/TableSelectSettingsGrid/index.d.ts +1 -0
- package/dist/cjs/helperComponents/TableSelectSettingsGrid/index.js +17 -0
- package/dist/cjs/helperComponents/TableSelectSettingsGrid/styles.module.css +54 -0
- package/dist/cjs/helperComponents/index.d.ts +6 -0
- package/dist/cjs/helperComponents/index.js +22 -0
- package/dist/cjs/index.d.ts +4 -0
- package/dist/cjs/index.js +20 -0
- package/dist/cjs/locale/index.d.ts +199 -0
- package/dist/cjs/locale/index.js +104 -0
- package/dist/cjs/lowlight.d.ts +14 -0
- package/dist/cjs/lowlight.js +35 -0
- package/dist/cjs/mixins.css +0 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/rawMarkdownCommands.d.ts +16 -0
- package/dist/cjs/rawMarkdownCommands.js +145 -0
- package/dist/cjs/style.css +875 -0
- package/dist/cjs/styles/syntax.module.css +47 -0
- package/dist/cjs/toolbarApi.d.ts +33 -0
- package/dist/cjs/toolbarApi.js +100 -0
- package/dist/cjs/types.d.ts +52 -0
- package/dist/cjs/types.js +2 -0
- package/dist/esm/components/Markdown/CodeBlock.d.ts +9 -0
- package/dist/esm/components/Markdown/CodeBlock.js +52 -0
- package/dist/esm/components/Markdown/Markdown.d.ts +2 -0
- package/dist/esm/components/Markdown/Markdown.js +19 -0
- package/dist/esm/components/Markdown/index.d.ts +1 -0
- package/dist/esm/components/Markdown/index.js +1 -0
- package/dist/esm/components/Markdown/styles.module.css +205 -0
- package/dist/esm/components/MarkdownEditor/MarkdownEditor.d.ts +2 -0
- package/dist/esm/components/MarkdownEditor/MarkdownEditor.js +170 -0
- package/dist/esm/components/MarkdownEditor/index.d.ts +1 -0
- package/dist/esm/components/MarkdownEditor/index.js +1 -0
- package/dist/esm/components/MarkdownEditor/styles.module.css +273 -0
- package/dist/esm/components/Toolbar/Toolbar.d.ts +9 -0
- package/dist/esm/components/Toolbar/Toolbar.js +167 -0
- package/dist/esm/components/Toolbar/constants.d.ts +13 -0
- package/dist/esm/components/Toolbar/constants.js +37 -0
- package/dist/esm/components/Toolbar/hooks/index.d.ts +2 -0
- package/dist/esm/components/Toolbar/hooks/index.js +2 -0
- package/dist/esm/components/Toolbar/hooks/useToolbarHotkeys.d.ts +21 -0
- package/dist/esm/components/Toolbar/hooks/useToolbarHotkeys.js +56 -0
- package/dist/esm/components/Toolbar/hooks/useToolbarOverflow.d.ts +14 -0
- package/dist/esm/components/Toolbar/hooks/useToolbarOverflow.js +84 -0
- package/dist/esm/components/Toolbar/index.d.ts +2 -0
- package/dist/esm/components/Toolbar/index.js +2 -0
- package/dist/esm/components/Toolbar/styles.module.css +17 -0
- package/dist/esm/components/index.d.ts +2 -0
- package/dist/esm/components/index.js +4 -0
- package/dist/esm/constants.d.ts +65 -0
- package/dist/esm/constants.js +61 -0
- package/dist/esm/helperComponents/ButtonHeading/ButtonHeading.d.ts +6 -0
- package/dist/esm/helperComponents/ButtonHeading/ButtonHeading.js +55 -0
- package/dist/esm/helperComponents/ButtonHeading/index.d.ts +1 -0
- package/dist/esm/helperComponents/ButtonHeading/index.js +1 -0
- package/dist/esm/helperComponents/ButtonHeading/styles.module.css +3 -0
- package/dist/esm/helperComponents/Buttons/Buttons.d.ts +10 -0
- package/dist/esm/helperComponents/Buttons/Buttons.js +13 -0
- package/dist/esm/helperComponents/Buttons/index.d.ts +1 -0
- package/dist/esm/helperComponents/Buttons/index.js +1 -0
- package/dist/esm/helperComponents/Buttons/styles.module.css +17 -0
- package/dist/esm/helperComponents/Modals/CustomizeTableModal.d.ts +8 -0
- package/dist/esm/helperComponents/Modals/CustomizeTableModal.js +33 -0
- package/dist/esm/helperComponents/Modals/ImageModal.d.ts +7 -0
- package/dist/esm/helperComponents/Modals/ImageModal.js +38 -0
- package/dist/esm/helperComponents/Modals/LinkModal.d.ts +13 -0
- package/dist/esm/helperComponents/Modals/LinkModal.js +36 -0
- package/dist/esm/helperComponents/Modals/index.d.ts +3 -0
- package/dist/esm/helperComponents/Modals/index.js +3 -0
- package/dist/esm/helperComponents/Modals/styles.module.css +17 -0
- package/dist/esm/helperComponents/PrivateButton/PrivateButton.d.ts +17 -0
- package/dist/esm/helperComponents/PrivateButton/PrivateButton.js +21 -0
- package/dist/esm/helperComponents/PrivateButton/index.d.ts +1 -0
- package/dist/esm/helperComponents/PrivateButton/index.js +1 -0
- package/dist/esm/helperComponents/PrivateButton/styles.module.css +140 -0
- package/dist/esm/helperComponents/TableSelectItem/TableSelectItem.d.ts +11 -0
- package/dist/esm/helperComponents/TableSelectItem/TableSelectItem.js +6 -0
- package/dist/esm/helperComponents/TableSelectItem/index.d.ts +1 -0
- package/dist/esm/helperComponents/TableSelectItem/index.js +1 -0
- package/dist/esm/helperComponents/TableSelectItem/styles.module.css +101 -0
- package/dist/esm/helperComponents/TableSelectSettingsGrid/TableSelectSettingsGrid.d.ts +4 -0
- package/dist/esm/helperComponents/TableSelectSettingsGrid/TableSelectSettingsGrid.js +21 -0
- package/dist/esm/helperComponents/TableSelectSettingsGrid/index.d.ts +1 -0
- package/dist/esm/helperComponents/TableSelectSettingsGrid/index.js +1 -0
- package/dist/esm/helperComponents/TableSelectSettingsGrid/styles.module.css +54 -0
- package/dist/esm/helperComponents/index.d.ts +6 -0
- package/dist/esm/helperComponents/index.js +6 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/locale/index.d.ts +199 -0
- package/dist/esm/locale/index.js +101 -0
- package/dist/esm/lowlight.d.ts +14 -0
- package/dist/esm/lowlight.js +29 -0
- package/dist/esm/mixins.css +0 -0
- package/dist/esm/rawMarkdownCommands.d.ts +16 -0
- package/dist/esm/rawMarkdownCommands.js +135 -0
- package/dist/esm/style.css +875 -0
- package/dist/esm/styles/syntax.module.css +47 -0
- package/dist/esm/toolbarApi.d.ts +33 -0
- package/dist/esm/toolbarApi.js +96 -0
- package/dist/esm/types.d.ts +52 -0
- package/dist/esm/types.js +1 -0
- package/dist/tsconfig.cjs.tsbuildinfo +1 -0
- package/dist/tsconfig.esm.tsbuildinfo +1 -0
- package/package.json +84 -0
- package/src/components/Markdown/CodeBlock.tsx +96 -0
- package/src/components/Markdown/Markdown.tsx +47 -0
- package/src/components/Markdown/index.ts +1 -0
- package/src/components/Markdown/styles.module.scss +105 -0
- package/src/components/MarkdownEditor/MarkdownEditor.tsx +322 -0
- package/src/components/MarkdownEditor/index.ts +1 -0
- package/src/components/MarkdownEditor/styles.module.scss +201 -0
- package/src/components/Toolbar/Toolbar.tsx +292 -0
- package/src/components/Toolbar/constants.tsx +63 -0
- package/src/components/Toolbar/hooks/index.ts +2 -0
- package/src/components/Toolbar/hooks/useToolbarHotkeys.ts +74 -0
- package/src/components/Toolbar/hooks/useToolbarOverflow.ts +102 -0
- package/src/components/Toolbar/index.ts +2 -0
- package/src/components/Toolbar/styles.module.scss +29 -0
- package/src/components/index.ts +4 -0
- package/src/constants.ts +67 -0
- package/src/helperComponents/ButtonHeading/ButtonHeading.tsx +100 -0
- package/src/helperComponents/ButtonHeading/index.ts +1 -0
- package/src/helperComponents/ButtonHeading/styles.module.scss +5 -0
- package/src/helperComponents/Buttons/Buttons.tsx +30 -0
- package/src/helperComponents/Buttons/index.ts +1 -0
- package/src/helperComponents/Buttons/styles.module.scss +26 -0
- package/src/helperComponents/Modals/CustomizeTableModal.tsx +82 -0
- package/src/helperComponents/Modals/ImageModal.tsx +84 -0
- package/src/helperComponents/Modals/LinkModal.tsx +92 -0
- package/src/helperComponents/Modals/index.ts +3 -0
- package/src/helperComponents/Modals/styles.module.scss +21 -0
- package/src/helperComponents/PrivateButton/PrivateButton.tsx +88 -0
- package/src/helperComponents/PrivateButton/index.ts +1 -0
- package/src/helperComponents/PrivateButton/styles.module.scss +77 -0
- package/src/helperComponents/TableSelectItem/TableSelectItem.tsx +43 -0
- package/src/helperComponents/TableSelectItem/index.ts +1 -0
- package/src/helperComponents/TableSelectItem/styles.module.scss +26 -0
- package/src/helperComponents/TableSelectSettingsGrid/TableSelectSettingsGrid.tsx +48 -0
- package/src/helperComponents/TableSelectSettingsGrid/index.ts +1 -0
- package/src/helperComponents/TableSelectSettingsGrid/styles.module.scss +65 -0
- package/src/helperComponents/index.ts +6 -0
- package/src/index.ts +4 -0
- package/src/locale/index.ts +105 -0
- package/src/lowlight.ts +30 -0
- package/src/mixins.scss +123 -0
- package/src/rawMarkdownCommands.ts +179 -0
- package/src/styles/syntax.module.scss +54 -0
- package/src/toolbarApi.ts +152 -0
- package/src/types.ts +56 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { WithTooltip } from '@cloud-ru/ds-tooltip';
|
|
2
|
+
import { Typography } from '@cloud-ru/ds-typography';
|
|
3
|
+
import { WithSupportProps } from '@cloud-ru/ds-utils';
|
|
4
|
+
import cn from 'classnames';
|
|
5
|
+
import { ButtonHTMLAttributes, ReactNode, Ref } from 'react';
|
|
6
|
+
|
|
7
|
+
import styles from './styles.module.scss';
|
|
8
|
+
|
|
9
|
+
const PrivateChevronIcon = (
|
|
10
|
+
<svg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8' fill='none' className={styles.chevron}>
|
|
11
|
+
<path d='M1 3L4 6L7 3' stroke='currentColor' strokeWidth='1.5' strokeLinecap='round' strokeLinejoin='round' />
|
|
12
|
+
</svg>
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
type TipContentProps = { title: string; caption?: string };
|
|
16
|
+
|
|
17
|
+
function TipContent({ title, caption }: TipContentProps) {
|
|
18
|
+
return (
|
|
19
|
+
<>
|
|
20
|
+
<Typography variant='body' size='s' weight='regular' className={styles.tipTitle}>
|
|
21
|
+
{title}
|
|
22
|
+
</Typography>
|
|
23
|
+
{caption && (
|
|
24
|
+
<Typography variant='body' size='s' weight='regular' className={styles.tipCaption}>
|
|
25
|
+
{caption}
|
|
26
|
+
</Typography>
|
|
27
|
+
)}
|
|
28
|
+
</>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Иконка занимает весь container, hover — stateLayer, checked=true → accent-цвет.
|
|
33
|
+
export type PrivateButtonProps = WithSupportProps<
|
|
34
|
+
Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children'> & {
|
|
35
|
+
icon: ReactNode;
|
|
36
|
+
withChevron?: boolean;
|
|
37
|
+
/** active/selected состояние */
|
|
38
|
+
checked?: boolean;
|
|
39
|
+
/** Внешний ref, без forwardRef (см. component-api-surface.md). */
|
|
40
|
+
innerRef?: Ref<HTMLButtonElement>;
|
|
41
|
+
tip?: TipContentProps;
|
|
42
|
+
}
|
|
43
|
+
>;
|
|
44
|
+
|
|
45
|
+
// eslint-disable-next-line ds/require-inner-ref-support -- innerRef проставляется условно (только без tip), поэтому статический маркер поддержки был бы неверен.
|
|
46
|
+
export function PrivateButton({
|
|
47
|
+
id,
|
|
48
|
+
tip,
|
|
49
|
+
icon,
|
|
50
|
+
checked = false,
|
|
51
|
+
disabled = false,
|
|
52
|
+
className,
|
|
53
|
+
innerRef,
|
|
54
|
+
type = 'button',
|
|
55
|
+
withChevron = false,
|
|
56
|
+
...rest
|
|
57
|
+
}: PrivateButtonProps) {
|
|
58
|
+
return WithTooltip({
|
|
59
|
+
tooltip: tip
|
|
60
|
+
? {
|
|
61
|
+
tip: <TipContent {...tip} />,
|
|
62
|
+
triggerClassName: styles.tooltipTrigger,
|
|
63
|
+
}
|
|
64
|
+
: undefined,
|
|
65
|
+
children: (
|
|
66
|
+
<button
|
|
67
|
+
data-toolbar-item={id}
|
|
68
|
+
{...rest}
|
|
69
|
+
data-toolbar-slot
|
|
70
|
+
ref={tip ? undefined : innerRef}
|
|
71
|
+
type={type}
|
|
72
|
+
disabled={disabled}
|
|
73
|
+
className={cn(styles.root, className)}
|
|
74
|
+
data-checked={checked || undefined}
|
|
75
|
+
data-disabled={disabled || undefined}
|
|
76
|
+
aria-pressed={checked}
|
|
77
|
+
>
|
|
78
|
+
<span
|
|
79
|
+
className={styles.stateLayer}
|
|
80
|
+
data-state={checked ? 'activatedOnBackground' : 'emptyNeutralOnBackground'}
|
|
81
|
+
aria-hidden
|
|
82
|
+
/>
|
|
83
|
+
{icon}
|
|
84
|
+
{withChevron && PrivateChevronIcon}
|
|
85
|
+
</button>
|
|
86
|
+
),
|
|
87
|
+
});
|
|
88
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './PrivateButton';
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
@use '@cloud-ru/ds-figma-variables/build/scss/styles/styles.module' as base;
|
|
2
|
+
@use '@cloud-ru/ds-figma-variables/build/scss/components/markdown.module' as md;
|
|
3
|
+
@use '@cloud-ru/ds-figma-variables/build/scss/components/button.module' as button;
|
|
4
|
+
@use '@cloud-ru/ds-materials' as m;
|
|
5
|
+
|
|
6
|
+
// `stateLayer` нужен оставленным определённым над .root — миксин ниже его потребляет.
|
|
7
|
+
.stateLayer {
|
|
8
|
+
visibility: initial;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.root {
|
|
12
|
+
cursor: pointer;
|
|
13
|
+
|
|
14
|
+
position: relative;
|
|
15
|
+
|
|
16
|
+
display: inline-flex;
|
|
17
|
+
flex: 0 0 auto;
|
|
18
|
+
align-items: center;
|
|
19
|
+
justify-content: center;
|
|
20
|
+
|
|
21
|
+
box-sizing: border-box;
|
|
22
|
+
min-width: button.$sn-button-anatomy-size-s-container-iconOnly-minWidth;
|
|
23
|
+
height: button.$sn-button-anatomy-size-s-container-minHeight;
|
|
24
|
+
padding: 0;
|
|
25
|
+
border: 0;
|
|
26
|
+
border-radius: md.$sn-density-radius-2xs;
|
|
27
|
+
|
|
28
|
+
color: md.$sn-theme-color-neutral-text;
|
|
29
|
+
|
|
30
|
+
background: transparent;
|
|
31
|
+
|
|
32
|
+
&:has(.chevron) {
|
|
33
|
+
gap: md.$sn-markdown-anatomy-size-buttons-button-gap;
|
|
34
|
+
padding-right: md.$sn-markdown-anatomy-size-buttons-button-paddingRight;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
svg {
|
|
38
|
+
flex: 0 0 auto;
|
|
39
|
+
stroke-width: md.$sn-density-size-icon-strokeWeight-s;
|
|
40
|
+
|
|
41
|
+
&:not(.chevron) {
|
|
42
|
+
width: md.$sn-density-size-icon-s;
|
|
43
|
+
height: md.$sn-density-size-icon-s;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
&:focus-visible {
|
|
48
|
+
outline: md.$sn-primitive-strokeWeight-strokeSemiBold solid md.$sn-theme-color-available-complementary;
|
|
49
|
+
outline-offset: 0;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
&[data-checked] {
|
|
53
|
+
color: md.$sn-theme-color-primary-accent;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
&[data-disabled] {
|
|
57
|
+
cursor: not-allowed;
|
|
58
|
+
color: md.$sn-theme-color-available-version-textDisabled;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@include m.has-state-layer-as-child(#{stateLayer});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.tooltipTrigger {
|
|
65
|
+
display: inline-flex;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Цвет наследуется от контейнера Tooltip (available/inversion/textMain) — свой не задаём.
|
|
69
|
+
.tipTitle {
|
|
70
|
+
text-align: center;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Подпись-подсказка приглушена: inversion/textTertiary (тот же текст @ 60%).
|
|
74
|
+
.tipCaption {
|
|
75
|
+
color: base.$sn-theme-color-available-inversion-textTertiary;
|
|
76
|
+
text-align: center;
|
|
77
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import styles from './styles.module.scss';
|
|
2
|
+
|
|
3
|
+
// Одна ячейка из grid-picker'а.
|
|
4
|
+
export type TableSelectItemProps = {
|
|
5
|
+
/** Hover-состояние (управляется родителем по mouseEnter). */
|
|
6
|
+
hovered?: boolean;
|
|
7
|
+
/** Будет ли ячейка попадать в выбранный диапазон. */
|
|
8
|
+
checked?: boolean;
|
|
9
|
+
onMouseEnter?(): void;
|
|
10
|
+
onClick?(): void;
|
|
11
|
+
'aria-label'?: string;
|
|
12
|
+
'data-test-id'?: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export function TableSelectItem({
|
|
16
|
+
hovered = false,
|
|
17
|
+
checked = false,
|
|
18
|
+
onMouseEnter,
|
|
19
|
+
onClick,
|
|
20
|
+
'aria-label': ariaLabel,
|
|
21
|
+
'data-test-id': dataTestId,
|
|
22
|
+
}: TableSelectItemProps) {
|
|
23
|
+
const state = hovered ? 'hovered' : 'default';
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<button
|
|
27
|
+
type='button'
|
|
28
|
+
className={styles.root}
|
|
29
|
+
data-state={state}
|
|
30
|
+
data-checked={checked || undefined}
|
|
31
|
+
onMouseEnter={onMouseEnter}
|
|
32
|
+
onClick={onClick}
|
|
33
|
+
aria-label={ariaLabel}
|
|
34
|
+
data-test-id={dataTestId}
|
|
35
|
+
>
|
|
36
|
+
<span
|
|
37
|
+
className={styles.stateLayer}
|
|
38
|
+
data-state={checked ? 'activatedOnBackground' : 'emptyNeutralOnBackground'}
|
|
39
|
+
aria-hidden
|
|
40
|
+
/>
|
|
41
|
+
</button>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './TableSelectItem';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
@use '@cloud-ru/ds-figma-variables/build/scss/components/markdown.module' as md;
|
|
2
|
+
@use '@cloud-ru/ds-materials' as m;
|
|
3
|
+
|
|
4
|
+
.stateLayer {
|
|
5
|
+
pointer-events: none;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.root {
|
|
9
|
+
cursor: pointer;
|
|
10
|
+
|
|
11
|
+
position: relative;
|
|
12
|
+
|
|
13
|
+
box-sizing: border-box;
|
|
14
|
+
width: md.$sn-markdown-anatomy-size-tableSelect-container-item-size;
|
|
15
|
+
height: md.$sn-markdown-anatomy-size-tableSelect-container-item-size;
|
|
16
|
+
padding: 0;
|
|
17
|
+
border: md.$sn-markdown-anatomy-size-tableSelect-container-item-borderWidth solid
|
|
18
|
+
md.$sn-theme-color-available-borderColor;
|
|
19
|
+
border-radius: md.$sn-markdown-anatomy-size-tableSelect-container-item-borderRadius;
|
|
20
|
+
|
|
21
|
+
&[data-checked] {
|
|
22
|
+
border-color: md.$sn-theme-color-primary-accent;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@include m.has-state-layer-as-child(#{stateLayer});
|
|
26
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
|
|
3
|
+
import { tableCellTestId, TEST_IDS } from '../../constants';
|
|
4
|
+
import { markdownLocale } from '../../locale';
|
|
5
|
+
import { TableSelectItem } from '../TableSelectItem';
|
|
6
|
+
import styles from './styles.module.scss';
|
|
7
|
+
|
|
8
|
+
export type TableSelectSettingsGridProps = {
|
|
9
|
+
onPick(rows: number, cols: number): void;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const MAX = 8;
|
|
13
|
+
|
|
14
|
+
export function TableSelectSettingsGrid({ onPick }: TableSelectSettingsGridProps) {
|
|
15
|
+
const { t } = markdownLocale.useTranslations();
|
|
16
|
+
const [hover, setHover] = useState<{ r: number; c: number } | null>(null);
|
|
17
|
+
|
|
18
|
+
const cells: { r: number; c: number }[] = [];
|
|
19
|
+
for (let r = 1; r <= MAX; r += 1) {
|
|
20
|
+
for (let c = 1; c <= MAX; c += 1) {
|
|
21
|
+
cells.push({ r, c });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<div className={styles.root} data-test-id={TEST_IDS.tableGridPicker}>
|
|
27
|
+
<div className={styles.container}>
|
|
28
|
+
<div className={styles.grid} onMouseLeave={() => setHover(null)}>
|
|
29
|
+
{cells.map(({ r, c }) => {
|
|
30
|
+
const checked = hover !== null && r <= hover.r && c <= hover.c;
|
|
31
|
+
return (
|
|
32
|
+
<TableSelectItem
|
|
33
|
+
key={`${r}-${c}`}
|
|
34
|
+
hovered={hover?.r === r && hover?.c === c}
|
|
35
|
+
checked={checked}
|
|
36
|
+
onMouseEnter={() => setHover({ r, c })}
|
|
37
|
+
onClick={() => onPick(r, c)}
|
|
38
|
+
aria-label={t('table.insert', { rows: r, cols: c })}
|
|
39
|
+
data-test-id={tableCellTestId(r, c)}
|
|
40
|
+
/>
|
|
41
|
+
);
|
|
42
|
+
})}
|
|
43
|
+
</div>
|
|
44
|
+
<div className={styles.label}>{hover ? `${hover.r} × ${hover.c}` : t('table.pickSize')}</div>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './TableSelectSettingsGrid';
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
@use '@cloud-ru/ds-figma-variables/build/scss/styles/styles.module' as base;
|
|
2
|
+
@use '@cloud-ru/ds-figma-variables/build/scss/components/markdown.module' as md;
|
|
3
|
+
|
|
4
|
+
.root {
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: column;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.container {
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-direction: column;
|
|
12
|
+
gap: md.$sn-markdown-anatomy-size-tableSelect-container-gap;
|
|
13
|
+
|
|
14
|
+
box-sizing: border-box;
|
|
15
|
+
padding: md.$sn-markdown-anatomy-size-tableSelect-container-paddingHorizontal
|
|
16
|
+
md.$sn-markdown-anatomy-size-tableSelect-container-paddingHorizontal
|
|
17
|
+
md.$sn-markdown-anatomy-size-tableSelect-container-paddingBottom;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.grid {
|
|
21
|
+
display: grid;
|
|
22
|
+
grid-template-columns: repeat(8, md.$sn-markdown-anatomy-size-tableSelect-container-item-size);
|
|
23
|
+
gap: md.$sn-markdown-anatomy-size-tableSelect-container-gap;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.label {
|
|
27
|
+
font-size: md.$sn-density-typography-roleBody-fontSizeS;
|
|
28
|
+
line-height: md.$sn-density-typography-roleBody-lineHeightS;
|
|
29
|
+
color: md.$sn-theme-color-available-version-textSecondary;
|
|
30
|
+
text-align: center;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.customize {
|
|
34
|
+
cursor: pointer;
|
|
35
|
+
|
|
36
|
+
display: flex;
|
|
37
|
+
gap: base.$sn-primitive-dimension-8;
|
|
38
|
+
align-items: center;
|
|
39
|
+
justify-content: space-between;
|
|
40
|
+
|
|
41
|
+
box-sizing: border-box;
|
|
42
|
+
padding: base.$sn-primitive-dimension-4 base.$sn-primitive-dimension-12;
|
|
43
|
+
border: none;
|
|
44
|
+
|
|
45
|
+
font-family: md.$sn-brand-font-fontFamily-regular-body;
|
|
46
|
+
font-size: md.$sn-density-typography-roleBody-fontSizeM;
|
|
47
|
+
line-height: md.$sn-density-typography-roleBody-lineHeightM;
|
|
48
|
+
color: md.$sn-theme-color-available-version-textMain;
|
|
49
|
+
text-align: left;
|
|
50
|
+
|
|
51
|
+
background: transparent;
|
|
52
|
+
|
|
53
|
+
&:hover {
|
|
54
|
+
background: md.$sn-theme-color-neutral-background2Level;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.customizeLabel {
|
|
59
|
+
flex: 1 1 auto;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.customizeChevron {
|
|
63
|
+
flex: 0 0 auto;
|
|
64
|
+
color: md.$sn-theme-color-available-version-textSecondary;
|
|
65
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { defineLocale, defineMessages } from '@cloud-ru/ds-locale';
|
|
2
|
+
|
|
3
|
+
const MARKDOWN_MESSAGES = defineMessages({
|
|
4
|
+
'en-GB': {
|
|
5
|
+
toolbar: {
|
|
6
|
+
heading: 'Heading',
|
|
7
|
+
bold: 'Bold',
|
|
8
|
+
italic: 'Italic',
|
|
9
|
+
strikethrough: 'Strikethrough',
|
|
10
|
+
link: 'Link',
|
|
11
|
+
inlineCode: 'Inline code',
|
|
12
|
+
bulletList: 'Bullet list',
|
|
13
|
+
orderedList: 'Ordered list',
|
|
14
|
+
blockQuote: 'Block quote',
|
|
15
|
+
blockCode: 'Block code',
|
|
16
|
+
table: 'Table',
|
|
17
|
+
image: 'Image',
|
|
18
|
+
more: 'More',
|
|
19
|
+
},
|
|
20
|
+
clear: 'Clear',
|
|
21
|
+
copy: 'Copy',
|
|
22
|
+
copied: 'Copied',
|
|
23
|
+
add: 'Add',
|
|
24
|
+
cancel: 'Cancel',
|
|
25
|
+
link: {
|
|
26
|
+
title: 'Add link',
|
|
27
|
+
titleField: {
|
|
28
|
+
label: 'Text',
|
|
29
|
+
placeholder: 'Link text',
|
|
30
|
+
},
|
|
31
|
+
urlField: {
|
|
32
|
+
label: 'URL',
|
|
33
|
+
placeholder: 'https://',
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
image: {
|
|
37
|
+
title: 'Add image',
|
|
38
|
+
url: 'URL',
|
|
39
|
+
alt: 'Alt text',
|
|
40
|
+
placeholder: 'https://',
|
|
41
|
+
},
|
|
42
|
+
table: {
|
|
43
|
+
pickSize: 'Pick size',
|
|
44
|
+
insert: 'Insert {{rows}} × {{cols}} table',
|
|
45
|
+
column: 'Column {{index}}',
|
|
46
|
+
customize: 'Customize table',
|
|
47
|
+
columns: 'Columns',
|
|
48
|
+
rows: 'Rows',
|
|
49
|
+
},
|
|
50
|
+
linkText: 'link text',
|
|
51
|
+
},
|
|
52
|
+
'ru-RU': {
|
|
53
|
+
toolbar: {
|
|
54
|
+
heading: 'Заголовок',
|
|
55
|
+
bold: 'Жирный',
|
|
56
|
+
italic: 'Курсив',
|
|
57
|
+
strikethrough: 'Зачёркнутый',
|
|
58
|
+
link: 'Ссылка',
|
|
59
|
+
inlineCode: 'Строчный код',
|
|
60
|
+
bulletList: 'Маркированный список',
|
|
61
|
+
orderedList: 'Нумерованный список',
|
|
62
|
+
blockQuote: 'Цитата',
|
|
63
|
+
blockCode: 'Блок кода',
|
|
64
|
+
table: 'Таблица',
|
|
65
|
+
image: 'Картинка',
|
|
66
|
+
more: 'Ещё',
|
|
67
|
+
},
|
|
68
|
+
clear: 'Очистить',
|
|
69
|
+
copy: 'Скопировать',
|
|
70
|
+
copied: 'Скопировано',
|
|
71
|
+
add: 'Добавить',
|
|
72
|
+
cancel: 'Отмена',
|
|
73
|
+
link: {
|
|
74
|
+
title: 'Добавить ссылку',
|
|
75
|
+
titleField: {
|
|
76
|
+
label: 'Текст',
|
|
77
|
+
placeholder: 'Текст ссылки',
|
|
78
|
+
},
|
|
79
|
+
urlField: {
|
|
80
|
+
label: 'URL',
|
|
81
|
+
placeholder: 'https://',
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
image: {
|
|
85
|
+
title: 'Добавить изображение',
|
|
86
|
+
url: 'URL',
|
|
87
|
+
alt: 'Альтернативный текст',
|
|
88
|
+
placeholder: 'https://',
|
|
89
|
+
},
|
|
90
|
+
table: {
|
|
91
|
+
pickSize: 'Выберите размер',
|
|
92
|
+
insert: 'Вставить таблицу {{rows}} × {{cols}}',
|
|
93
|
+
column: 'Колонка {{index}}',
|
|
94
|
+
customize: 'Настроить таблицу',
|
|
95
|
+
columns: 'Столбцы',
|
|
96
|
+
rows: 'Строки',
|
|
97
|
+
},
|
|
98
|
+
linkText: 'текст ссылки',
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
export type MarkdownMessages = (typeof MARKDOWN_MESSAGES)['en-GB'];
|
|
103
|
+
|
|
104
|
+
/** locale компонента Markdown: `markdownLocale.useTranslations()` в коде, `markdownLocale.extend(...)` в сервисе. */
|
|
105
|
+
export const markdownLocale = defineLocale('@cloud-ru/ds-markdown', MARKDOWN_MESSAGES);
|
package/src/lowlight.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import bash from 'highlight.js/lib/languages/bash';
|
|
2
|
+
import css from 'highlight.js/lib/languages/css';
|
|
3
|
+
import diff from 'highlight.js/lib/languages/diff';
|
|
4
|
+
import go from 'highlight.js/lib/languages/go';
|
|
5
|
+
import javascript from 'highlight.js/lib/languages/javascript';
|
|
6
|
+
import json from 'highlight.js/lib/languages/json';
|
|
7
|
+
import markdown from 'highlight.js/lib/languages/markdown';
|
|
8
|
+
import python from 'highlight.js/lib/languages/python';
|
|
9
|
+
import scss from 'highlight.js/lib/languages/scss';
|
|
10
|
+
import shell from 'highlight.js/lib/languages/shell';
|
|
11
|
+
import typescript from 'highlight.js/lib/languages/typescript';
|
|
12
|
+
import xml from 'highlight.js/lib/languages/xml';
|
|
13
|
+
import yaml from 'highlight.js/lib/languages/yaml';
|
|
14
|
+
import { createLowlight } from 'lowlight';
|
|
15
|
+
|
|
16
|
+
export const lowlight = createLowlight({
|
|
17
|
+
bash,
|
|
18
|
+
css,
|
|
19
|
+
diff,
|
|
20
|
+
go,
|
|
21
|
+
javascript,
|
|
22
|
+
json,
|
|
23
|
+
markdown,
|
|
24
|
+
python,
|
|
25
|
+
scss,
|
|
26
|
+
shell,
|
|
27
|
+
typescript,
|
|
28
|
+
xml,
|
|
29
|
+
yaml,
|
|
30
|
+
});
|
package/src/mixins.scss
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
@use '@cloud-ru/ds-figma-variables/build/scss/styles/styles.module' as base;
|
|
2
|
+
@use '@cloud-ru/ds-figma-variables/build/scss/components/markdown.module' as md;
|
|
3
|
+
|
|
4
|
+
// Общие стили markdown-контента: типографика блоков и top-spacing'и.
|
|
5
|
+
// Подключаются и во viewer (`Markdown`), и в editor (`MarkdownEditor` → .ProseMirror),
|
|
6
|
+
// чтобы блоки выглядели одинаково в обоих режимах и правились в одном месте.
|
|
7
|
+
|
|
8
|
+
// Композитные typography-роли заголовков: один токен разворачивается в font-* через composite-var.
|
|
9
|
+
$headings: (
|
|
10
|
+
'h1': base.$sn-regular-headline-l,
|
|
11
|
+
'h2': base.$sn-regular-headline-m,
|
|
12
|
+
'h3': base.$sn-regular-headline-s,
|
|
13
|
+
'h4': base.$sn-regular-title-l,
|
|
14
|
+
'h5': base.$sn-regular-title-m,
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
// Top-spacing на каждый блок (paddingTop при наличии предыдущего соседа).
|
|
18
|
+
$block-top-spacings: (
|
|
19
|
+
'h1': md.$sn-markdown-anatomy-size-syntax-headings-h1-paddingTop,
|
|
20
|
+
'h2': md.$sn-markdown-anatomy-size-syntax-headings-h2-paddingTop,
|
|
21
|
+
'h3': md.$sn-markdown-anatomy-size-syntax-headings-h3-paddingTop,
|
|
22
|
+
'h4': md.$sn-markdown-anatomy-size-syntax-headings-h4-paddingTop,
|
|
23
|
+
'h5': md.$sn-markdown-anatomy-size-syntax-headings-h5-paddingTop,
|
|
24
|
+
'blockquote': md.$sn-markdown-anatomy-size-syntax-quote-paddingTop,
|
|
25
|
+
'pre': md.$sn-markdown-anatomy-size-syntax-codeEditor-paddingTop,
|
|
26
|
+
'table': md.$sn-markdown-anatomy-size-syntax-table-paddingTop,
|
|
27
|
+
'img': md.$sn-markdown-anatomy-size-syntax-image-paddingTop,
|
|
28
|
+
'hr': md.$sn-markdown-anatomy-size-syntax-divider-paddingTop,
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
@mixin markdown-content {
|
|
32
|
+
p,
|
|
33
|
+
h1,
|
|
34
|
+
h2,
|
|
35
|
+
h3,
|
|
36
|
+
h4,
|
|
37
|
+
h5,
|
|
38
|
+
ul,
|
|
39
|
+
ol,
|
|
40
|
+
blockquote,
|
|
41
|
+
pre,
|
|
42
|
+
table,
|
|
43
|
+
hr,
|
|
44
|
+
img {
|
|
45
|
+
margin: 0;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@each $tag, $token in $headings {
|
|
49
|
+
#{$tag} {
|
|
50
|
+
@include base.composite-var($headings, $tag);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
ul,
|
|
55
|
+
ol {
|
|
56
|
+
padding-left: base.$sn-primitive-dimension-24;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
blockquote {
|
|
60
|
+
padding: md.$sn-markdown-anatomy-size-syntax-quote-wrapper-paddingVertical
|
|
61
|
+
md.$sn-markdown-anatomy-size-syntax-quote-wrapper-paddingHorizontal;
|
|
62
|
+
border-left: md.$sn-markdown-anatomy-size-syntax-quote-wrapper-borderWidth solid
|
|
63
|
+
md.$sn-theme-color-available-borderColor;
|
|
64
|
+
color: md.$sn-theme-color-available-version-textMain;
|
|
65
|
+
background: base.$sn-theme-color-neutral-decorTransparent;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
code {
|
|
69
|
+
min-height: md.$sn-markdown-anatomy-size-syntax-inlineCode-minHeight;
|
|
70
|
+
padding: 0 md.$sn-markdown-anatomy-size-syntax-inlineCode-paddingHorizontal;
|
|
71
|
+
border-radius: md.$sn-markdown-anatomy-size-syntax-inlineCode-borderRadius;
|
|
72
|
+
|
|
73
|
+
font-family: md.$sn-brand-font-fontFamily-mono-body;
|
|
74
|
+
|
|
75
|
+
background: md.$sn-theme-color-neutral-decorTransparent;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
a {
|
|
79
|
+
color: md.$sn-theme-color-neutral-accent;
|
|
80
|
+
text-decoration: underline;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
table {
|
|
84
|
+
border-collapse: collapse;
|
|
85
|
+
width: 100%;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
th,
|
|
89
|
+
td {
|
|
90
|
+
min-height: md.$sn-markdown-anatomy-size-syntax-table-tableCell-minHeight;
|
|
91
|
+
padding: md.$sn-markdown-anatomy-size-syntax-table-tableCell-paddingVertical
|
|
92
|
+
md.$sn-markdown-anatomy-size-syntax-table-tableCell-paddingHorizontal;
|
|
93
|
+
// Ячейка несёт только нижнюю линейку: в мастере вертикальных границ нет, соседние
|
|
94
|
+
// ячейки стыкуются вплотную.
|
|
95
|
+
border-bottom: md.$sn-primitive-strokeWeight-strokeRegular solid md.$sn-theme-color-available-borderColor;
|
|
96
|
+
text-align: left;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
th {
|
|
100
|
+
font-weight: 600;
|
|
101
|
+
background: base.$sn-theme-color-neutral-decorTransparent;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Top-spacings: каждый блок имеет свой paddingTop.
|
|
106
|
+
// Default — paragraph; конкретные блоки переопределяют.
|
|
107
|
+
@mixin markdown-block-spacings {
|
|
108
|
+
> *:not(:first-child) {
|
|
109
|
+
margin-top: md.$sn-markdown-anatomy-size-syntax-paragraphs-paddingTop;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Списки делят один токен — задаём отдельно от карты блоков.
|
|
113
|
+
> ul:not(:first-child),
|
|
114
|
+
> ol:not(:first-child) {
|
|
115
|
+
margin-top: md.$sn-markdown-anatomy-size-syntax-list-paddingTop;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
@each $tag, $padding-top in $block-top-spacings {
|
|
119
|
+
> #{$tag}:not(:first-child) {
|
|
120
|
+
margin-top: $padding-top;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|