@squiz/formatted-text-editor 1.33.1-alpha.1 → 1.33.1-alpha.3
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/lib/EditorToolbar/Tools/Image/Form/ImageForm.js +9 -14
- package/lib/EditorToolbar/Tools/Image/ImageModal.js +3 -2
- package/lib/EditorToolbar/Tools/Link/Form/LinkForm.js +12 -20
- package/lib/EditorToolbar/Tools/Link/LinkModal.js +3 -2
- package/lib/Extensions/LinkExtension/AssetLinkExtension.js +1 -1
- package/lib/Extensions/LinkExtension/LinkExtension.js +1 -1
- package/lib/index.css +77 -2
- package/lib/ui/Fields/Checkbox/Checkbox.d.ts +8 -0
- package/lib/ui/Fields/Checkbox/Checkbox.js +47 -0
- package/lib/ui/Modal/Modal.d.ts +1 -0
- package/lib/ui/Modal/Modal.js +3 -2
- package/lib/ui/Tabs/Tabs.d.ts +10 -0
- package/lib/ui/Tabs/Tabs.js +46 -0
- package/package.json +2 -2
- package/src/EditorToolbar/Tools/Image/Form/ImageForm.spec.tsx +2 -2
- package/src/EditorToolbar/Tools/Image/Form/ImageForm.tsx +12 -24
- package/src/EditorToolbar/Tools/Image/ImageButton.spec.tsx +11 -10
- package/src/EditorToolbar/Tools/Image/ImageModal.spec.tsx +1 -0
- package/src/EditorToolbar/Tools/Image/ImageModal.tsx +3 -2
- package/src/EditorToolbar/Tools/Link/Form/LinkForm.spec.tsx +10 -11
- package/src/EditorToolbar/Tools/Link/Form/LinkForm.tsx +21 -37
- package/src/EditorToolbar/Tools/Link/LinkButton.spec.tsx +8 -8
- package/src/EditorToolbar/Tools/Link/LinkModal.tsx +3 -2
- package/src/Extensions/LinkExtension/AssetLinkExtension.ts +1 -1
- package/src/Extensions/LinkExtension/LinkExtension.ts +1 -1
- package/src/index.scss +1 -0
- package/src/ui/Fields/Checkbox/Checkbox.spec.tsx +50 -0
- package/src/ui/Fields/Checkbox/Checkbox.tsx +49 -0
- package/src/ui/Fields/Checkbox/_checkbox.scss +26 -0
- package/src/ui/Modal/FormModal.spec.tsx +2 -1
- package/src/ui/Modal/Modal.spec.tsx +15 -7
- package/src/ui/Modal/Modal.tsx +4 -2
- package/src/ui/Tabs/Tabs.spec.tsx +44 -0
- package/src/ui/Tabs/Tabs.tsx +41 -0
- package/lib/ui/Fields/Select/Select.d.ts +0 -12
- package/lib/ui/Fields/Select/Select.js +0 -53
@@ -0,0 +1,44 @@
|
|
1
|
+
import '@testing-library/jest-dom';
|
2
|
+
import React from 'react';
|
3
|
+
import { fireEvent, render, screen } from '@testing-library/react';
|
4
|
+
import { Tabs, TabOptions } from './Tabs';
|
5
|
+
import { MarkName } from '../../Extensions/Extensions';
|
6
|
+
|
7
|
+
const linkTypeOptions: TabOptions = {
|
8
|
+
[MarkName.AssetLink]: { label: 'From source' },
|
9
|
+
[MarkName.Link]: { label: 'From URL' },
|
10
|
+
};
|
11
|
+
|
12
|
+
describe('Tabs', () => {
|
13
|
+
const mockOnChange = jest.fn();
|
14
|
+
|
15
|
+
const TabsComponent = () => {
|
16
|
+
return <Tabs value={MarkName.AssetLink} options={linkTypeOptions} onChange={mockOnChange} />;
|
17
|
+
};
|
18
|
+
|
19
|
+
it('renders the Tabs component', () => {
|
20
|
+
render(<TabsComponent />);
|
21
|
+
expect(screen.getByText('From source')).toBeInTheDocument();
|
22
|
+
expect(screen.getByText('From URL')).toBeInTheDocument();
|
23
|
+
});
|
24
|
+
|
25
|
+
it('defaults active to asset link', () => {
|
26
|
+
render(<TabsComponent />);
|
27
|
+
expect(screen.getByRole('tab', { selected: true })).toHaveTextContent('From source');
|
28
|
+
});
|
29
|
+
|
30
|
+
it('changes selected state when clicking the other tab', () => {
|
31
|
+
render(<TabsComponent />);
|
32
|
+
|
33
|
+
const assetLink = screen.getByTestId('assetLink');
|
34
|
+
const link = screen.getByTestId('link');
|
35
|
+
|
36
|
+
expect(assetLink).toHaveAttribute('aria-selected', 'true');
|
37
|
+
expect(link).not.toHaveAttribute('aria-selected', 'true');
|
38
|
+
|
39
|
+
fireEvent.click(link);
|
40
|
+
|
41
|
+
expect(assetLink).not.toHaveAttribute('aria-selected', 'true');
|
42
|
+
expect(link).toHaveAttribute('aria-selected', 'true');
|
43
|
+
});
|
44
|
+
});
|
@@ -0,0 +1,41 @@
|
|
1
|
+
import { Tab } from '@headlessui/react';
|
2
|
+
import React, { Fragment } from 'react';
|
3
|
+
import clsx from 'clsx';
|
4
|
+
|
5
|
+
export type TabOptions = Record<string, TabOption>;
|
6
|
+
export type TabOption = {
|
7
|
+
label: string;
|
8
|
+
};
|
9
|
+
|
10
|
+
export type TabsProps = {
|
11
|
+
value: string;
|
12
|
+
options: TabOptions;
|
13
|
+
onChange?: (value: string) => void;
|
14
|
+
};
|
15
|
+
|
16
|
+
export const Tabs = ({ value, options, onChange }: TabsProps) => (
|
17
|
+
<Tab.Group
|
18
|
+
// Check what index the selected tab is, otherwise default to first tab
|
19
|
+
defaultIndex={Object.keys(options).indexOf(value) || 0}
|
20
|
+
// Check what the selected tab key is and trigger onChange
|
21
|
+
onChange={(index) => {
|
22
|
+
const selectedTab = Object.keys(options)[index];
|
23
|
+
onChange?.(selectedTab);
|
24
|
+
}}
|
25
|
+
>
|
26
|
+
<Tab.List className="grid grid-flow-col h-10 border-b border-gray-300">
|
27
|
+
{Object.entries(options).map(([key, option]) => (
|
28
|
+
<Tab key={key} as={Fragment}>
|
29
|
+
{({ selected }) => (
|
30
|
+
<div className="flex flex-col justify-between" data-testid={key} aria-selected={selected}>
|
31
|
+
<button type="button" className={clsx('mt-[7px] text-gray-800', selected && 'font-bold')}>
|
32
|
+
{option.label}
|
33
|
+
</button>
|
34
|
+
{selected && <span className="h-[3px] bg-gray-800 w-11/12 self-center rounded-t-sm" />}
|
35
|
+
</div>
|
36
|
+
)}
|
37
|
+
</Tab>
|
38
|
+
))}
|
39
|
+
</Tab.List>
|
40
|
+
</Tab.Group>
|
41
|
+
);
|
@@ -1,12 +0,0 @@
|
|
1
|
-
export type SelectOptions = Record<string, SelectOption>;
|
2
|
-
export type SelectOption = {
|
3
|
-
label: string;
|
4
|
-
};
|
5
|
-
export type SelectProps = {
|
6
|
-
name: string;
|
7
|
-
label?: string;
|
8
|
-
value?: string;
|
9
|
-
options: SelectOptions;
|
10
|
-
onChange?: (value: string) => void;
|
11
|
-
};
|
12
|
-
export declare const Select: ({ name, label, value, onChange, options }: SelectProps) => JSX.Element;
|
@@ -1,53 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
-
if (k2 === undefined) k2 = k;
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
7
|
-
}
|
8
|
-
Object.defineProperty(o, k2, desc);
|
9
|
-
}) : (function(o, m, k, k2) {
|
10
|
-
if (k2 === undefined) k2 = k;
|
11
|
-
o[k2] = m[k];
|
12
|
-
}));
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
15
|
-
}) : function(o, v) {
|
16
|
-
o["default"] = v;
|
17
|
-
});
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
19
|
-
if (mod && mod.__esModule) return mod;
|
20
|
-
var result = {};
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
22
|
-
__setModuleDefault(result, mod);
|
23
|
-
return result;
|
24
|
-
};
|
25
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
26
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
27
|
-
};
|
28
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
29
|
-
exports.Select = void 0;
|
30
|
-
const react_1 = require("@headlessui/react");
|
31
|
-
const react_2 = __importStar(require("react"));
|
32
|
-
const clsx_1 = __importDefault(require("clsx"));
|
33
|
-
const ExpandMoreRounded_1 = __importDefault(require("@mui/icons-material/ExpandMoreRounded"));
|
34
|
-
const ExpandLessRounded_1 = __importDefault(require("@mui/icons-material/ExpandLessRounded"));
|
35
|
-
const Select = ({ name, label, value, onChange, options }) => {
|
36
|
-
const [selectedOption, setSelectedOptions] = (0, react_2.useState)(value ? options[value] : null);
|
37
|
-
const handleChange = (value) => {
|
38
|
-
setSelectedOptions(options[value]);
|
39
|
-
onChange?.(value);
|
40
|
-
};
|
41
|
-
return (react_2.default.createElement(react_1.Listbox, { value: value, name: name, "aria-labelledby": name, onChange: handleChange }, ({ open }) => (react_2.default.createElement(react_2.default.Fragment, null,
|
42
|
-
label && react_2.default.createElement(react_1.Listbox.Label, { className: "squiz-fte-form-label" }, label),
|
43
|
-
react_2.default.createElement("div", { className: "relative text-md text-gray-800" },
|
44
|
-
react_2.default.createElement(react_1.Listbox.Button, { className: "w-full cursor-default rounded border-2 border-gray-300 bg-white py-2 pl-3 pr-10 focus:border-blue-300 focus:outline-none" },
|
45
|
-
react_2.default.createElement("span", { className: "flex items-center" },
|
46
|
-
react_2.default.createElement("span", { className: "block truncate" },
|
47
|
-
selectedOption?.label,
|
48
|
-
"\u00A0")),
|
49
|
-
react_2.default.createElement("span", { className: "pointer-events-none absolute inset-y-0 right-0 ml-3 flex items-center pr-2" }, !open ? (react_2.default.createElement(ExpandMoreRounded_1.default, { className: "text-gray-500", "aria-hidden": "true" })) : (react_2.default.createElement(ExpandLessRounded_1.default, { className: "text-gray-500", "aria-hidden": "true" })))),
|
50
|
-
react_2.default.createElement(react_1.Listbox.Options, { className: "absolute z-10 mt-1 w-full overflow-auto rounded border-2 border-gray-300 bg-white" }, Object.entries(options).map(([key, option]) => (react_2.default.createElement(react_1.Listbox.Option, { key: key, value: key, className: ({ active }) => (0, clsx_1.default)(active ? 'bg-gray-100' : 'bg-white', 'relative cursor-default select-none flex hover:bg-gray-100 py-2 px-3') },
|
51
|
-
react_2.default.createElement("span", { className: "block truncate" }, option.label))))))))));
|
52
|
-
};
|
53
|
-
exports.Select = Select;
|