@guardian/stand 0.0.50 → 0.0.52
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/dist/Modal.cjs +7 -0
- package/dist/Modal.d.cts +5 -0
- package/dist/Modal.d.ts +5 -0
- package/dist/Modal.js +3 -0
- package/dist/TagPicker.cjs +4 -2
- package/dist/TagPicker.d.cts +3 -2
- package/dist/TagPicker.d.ts +3 -2
- package/dist/TagPicker.js +3 -2
- package/dist/components/Form/Form.cjs +1 -0
- package/dist/components/Form/Form.js +1 -0
- package/dist/components/InlineMessage/InlineMessage.cjs +2 -1
- package/dist/components/InlineMessage/InlineMessage.d.cts +1 -0
- package/dist/components/InlineMessage/InlineMessage.d.ts +1 -0
- package/dist/components/InlineMessage/InlineMessage.js +2 -1
- package/dist/components/InlineMessage/types.d.cts +5 -0
- package/dist/components/InlineMessage/types.d.ts +5 -0
- package/dist/components/Modal/Modal.cjs +97 -0
- package/dist/components/Modal/Modal.d.cts +21 -0
- package/dist/components/Modal/Modal.d.ts +21 -0
- package/dist/components/Modal/Modal.js +93 -0
- package/dist/components/Modal/styles.cjs +100 -0
- package/dist/components/Modal/styles.d.cts +10 -0
- package/dist/components/Modal/styles.d.ts +10 -0
- package/dist/components/Modal/styles.js +92 -0
- package/dist/components/Modal/types.d.cts +20 -0
- package/dist/components/Modal/types.d.ts +20 -0
- package/dist/components/Select/Select.cjs +3 -1
- package/dist/components/Select/Select.d.cts +2 -0
- package/dist/components/Select/Select.d.ts +2 -0
- package/dist/components/Select/Select.js +3 -1
- package/dist/components/Select/types.d.cts +15 -2
- package/dist/components/Select/types.d.ts +15 -2
- package/dist/components/TagPicker/Autocomplete.cjs +60 -48
- package/dist/components/TagPicker/Autocomplete.d.cts +12 -2
- package/dist/components/TagPicker/Autocomplete.d.ts +12 -2
- package/dist/components/TagPicker/Autocomplete.js +63 -51
- package/dist/components/TagPicker/TagPicker.cjs +105 -0
- package/dist/components/TagPicker/TagPicker.d.cts +91 -0
- package/dist/components/TagPicker/TagPicker.d.ts +91 -0
- package/dist/components/TagPicker/TagPicker.js +105 -0
- package/dist/components/TagPicker/TagSearchWithFilters.cjs +53 -0
- package/dist/components/TagPicker/TagSearchWithFilters.js +53 -0
- package/dist/components/TagPicker/TagTable.cjs +10 -49
- package/dist/components/TagPicker/TagTable.d.cts +12 -48
- package/dist/components/TagPicker/TagTable.d.ts +12 -48
- package/dist/components/TagPicker/TagTable.js +29 -68
- package/dist/components/TagPicker/styles.cjs +64 -3
- package/dist/components/TagPicker/styles.js +59 -4
- package/dist/components/TagPicker/types.d.cts +5 -1
- package/dist/components/TagPicker/types.d.ts +5 -1
- package/dist/components/Typography/Typography.cjs +7 -4
- package/dist/components/Typography/Typography.d.cts +1 -5
- package/dist/components/Typography/Typography.d.ts +1 -5
- package/dist/components/Typography/Typography.js +7 -4
- package/dist/components/Typography/types.d.cts +3 -2
- package/dist/components/Typography/types.d.ts +3 -2
- package/dist/components/UserMenu/PreferenceRadioGroup.js +5 -5
- package/dist/index.cjs +2 -0
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +2 -1
- package/dist/styleD/build/css/component/autocomplete.css +3 -0
- package/dist/styleD/build/css/component/modal.css +51 -0
- package/dist/styleD/build/css/component/tagPicker.css +11 -0
- package/dist/styleD/build/css/component/tagTable.css +2 -2
- package/dist/styleD/build/typescript/component/autocomplete.cjs +5 -0
- package/dist/styleD/build/typescript/component/autocomplete.d.cts +5 -0
- package/dist/styleD/build/typescript/component/autocomplete.d.ts +5 -0
- package/dist/styleD/build/typescript/component/autocomplete.js +5 -0
- package/dist/styleD/build/typescript/component/intendedAudienceSignifier.cjs +4 -1
- package/dist/styleD/build/typescript/component/intendedAudienceSignifier.d.cts +1 -0
- package/dist/styleD/build/typescript/component/intendedAudienceSignifier.d.ts +1 -0
- package/dist/styleD/build/typescript/component/intendedAudienceSignifier.js +4 -1
- package/dist/styleD/build/typescript/component/modal.cjs +72 -0
- package/dist/styleD/build/typescript/component/modal.d.cts +75 -0
- package/dist/styleD/build/typescript/component/modal.d.ts +75 -0
- package/dist/styleD/build/typescript/component/modal.js +72 -0
- package/dist/styleD/build/typescript/component/tagPicker.cjs +17 -0
- package/dist/styleD/build/typescript/component/tagPicker.d.cts +20 -0
- package/dist/styleD/build/typescript/component/tagPicker.d.ts +20 -0
- package/dist/styleD/build/typescript/component/tagPicker.js +17 -0
- package/dist/styleD/build/typescript/component/tagTable.cjs +2 -2
- package/dist/styleD/build/typescript/component/tagTable.js +2 -2
- package/package.json +16 -2
- package/dist/components/TagPicker/TagAutocomplete.cjs +0 -118
- package/dist/components/TagPicker/TagAutocomplete.d.cts +0 -144
- package/dist/components/TagPicker/TagAutocomplete.d.ts +0 -144
- package/dist/components/TagPicker/TagAutocomplete.js +0 -118
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { DeepPartial } from "../../util/types.cjs";
|
|
2
|
+
import { ComponentSelect } from "../../styleD/build/typescript/component/select.cjs";
|
|
3
|
+
import { ComponentAutocomplete } from "../../styleD/build/typescript/component/autocomplete.cjs";
|
|
4
|
+
import { ComponentTagTable } from "../../styleD/build/typescript/component/tagTable.cjs";
|
|
5
|
+
import { FilterOption, TagRow } from "./types.cjs";
|
|
6
|
+
import { ComponentTagPicker } from "../../styleD/build/typescript/component/tagPicker.cjs";
|
|
7
|
+
import { SerializedStyles } from "@emotion/react";
|
|
8
|
+
import { ReactElement } from "react";
|
|
9
|
+
|
|
10
|
+
//#region src/components/TagPicker/TagPicker.d.ts
|
|
11
|
+
type TagPickerProps<T extends TagRow = TagRow> = {
|
|
12
|
+
/** `addTag` - Function called when a tag is selected from the dropdown or proposal list */addTag: (tag: T) => void; /** `loading` - Whether the component is loading options for the dropdown */
|
|
13
|
+
loading: boolean; /** `offline` - Whether the component has failed to fetch a list of options, indicating either that the service is offline or cannot be reached */
|
|
14
|
+
offline?: boolean; /** `onReorder - Function called when a selected tag is moved in the tag table */
|
|
15
|
+
onReorder?: (tags: T[]) => void; /** `onReorder - Function called the user enters a query or selects a filter value */
|
|
16
|
+
onSearch: (queryText: string, filterValue?: string) => void; /** `options` - The list of options shown in the dropdown */
|
|
17
|
+
options: T[]; /** `proposedTags` - A list of "proposed tags" that the user can add */
|
|
18
|
+
proposedTags: T[]; /** `readOnly` - Whether the interactions modifying the list of tags should be disabled */
|
|
19
|
+
readOnly?: boolean; /** `addTag` - Function called when a tag is removed from selected tags list */
|
|
20
|
+
removeTag: (tag: T) => void; /** `retryConnection - Function called to check if the service to fetch tag options is available again */
|
|
21
|
+
retryConnection?: () => void; /** `tags` - The list of selected tags */
|
|
22
|
+
tags: T[]; /** `canRemove - A filter function that determines if the user is able to remove the tag from the selected tags */
|
|
23
|
+
canRemove?: (tag: T) => boolean; /** `filterRows - A filter function that determines if the tag should be excluded from the selected and proposed tag tables */
|
|
24
|
+
filterRows?: (tag: T) => boolean; /** `filterOptions` - the list of options for setting the filter value (second argument of `onSearch`). If omitted, or has only one member, the Select input is not rendered. */
|
|
25
|
+
filterOptions?: FilterOption[]; /** `offlineBackupTags` - A list of tags that the user can select if the service is offline */
|
|
26
|
+
offlineBackupTags?: T[];
|
|
27
|
+
highlightLeadingTag?: boolean;
|
|
28
|
+
searchPlaceholder?: string;
|
|
29
|
+
searchLabel?: string;
|
|
30
|
+
removeIcon?: ReactElement;
|
|
31
|
+
searchIcon?: ReactElement;
|
|
32
|
+
showTagType?: boolean;
|
|
33
|
+
showTagSectionName?: boolean; /** `theme` - Used to customise the look and feel of the TagPicker component */
|
|
34
|
+
theme?: DeepPartial<ComponentTagPicker>;
|
|
35
|
+
tagTableTheme?: DeepPartial<ComponentTagTable>;
|
|
36
|
+
proposedTagTableTheme?: DeepPartial<ComponentTagTable>;
|
|
37
|
+
autoCompleteTheme?: DeepPartial<ComponentAutocomplete>;
|
|
38
|
+
selectTheme?: DeepPartial<ComponentSelect>; /** `cssOverrides` - Escape hatch for styling that doesn't fall into the theme */
|
|
39
|
+
cssOverrides?: SerializedStyles;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* ## TagPicker
|
|
43
|
+
*
|
|
44
|
+
* *Status: Testing*
|
|
45
|
+
*
|
|
46
|
+
* **Peer dependencies:**
|
|
47
|
+
* - `react-aria-components`
|
|
48
|
+
*
|
|
49
|
+
* See the `peerDependencies` section of the `package.json` for compatible versions to install.
|
|
50
|
+
*
|
|
51
|
+
*
|
|
52
|
+
* #### Props
|
|
53
|
+
*
|
|
54
|
+
* See {@link TagPickerProps} for a full list of props and descriptions.
|
|
55
|
+
*
|
|
56
|
+
* #### Example
|
|
57
|
+
*
|
|
58
|
+
* This is currently still in testing phase, so a production implementation is not yet available.
|
|
59
|
+
*/
|
|
60
|
+
declare function TagPicker<T extends TagRow = TagRow>({
|
|
61
|
+
addTag,
|
|
62
|
+
loading,
|
|
63
|
+
offline,
|
|
64
|
+
onReorder,
|
|
65
|
+
onSearch,
|
|
66
|
+
options,
|
|
67
|
+
proposedTags,
|
|
68
|
+
readOnly,
|
|
69
|
+
removeTag,
|
|
70
|
+
retryConnection,
|
|
71
|
+
tags,
|
|
72
|
+
canRemove,
|
|
73
|
+
filterRows,
|
|
74
|
+
filterOptions,
|
|
75
|
+
offlineBackupTags,
|
|
76
|
+
highlightLeadingTag,
|
|
77
|
+
searchPlaceholder,
|
|
78
|
+
searchLabel,
|
|
79
|
+
removeIcon,
|
|
80
|
+
searchIcon,
|
|
81
|
+
showTagType,
|
|
82
|
+
showTagSectionName,
|
|
83
|
+
theme,
|
|
84
|
+
tagTableTheme,
|
|
85
|
+
proposedTagTableTheme,
|
|
86
|
+
autoCompleteTheme,
|
|
87
|
+
selectTheme,
|
|
88
|
+
cssOverrides
|
|
89
|
+
}: TagPickerProps<T>): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
90
|
+
//#endregion
|
|
91
|
+
export { TagPicker };
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { DeepPartial } from "../../util/types.js";
|
|
2
|
+
import { ComponentSelect } from "../../styleD/build/typescript/component/select.js";
|
|
3
|
+
import { ComponentAutocomplete } from "../../styleD/build/typescript/component/autocomplete.js";
|
|
4
|
+
import { ComponentTagTable } from "../../styleD/build/typescript/component/tagTable.js";
|
|
5
|
+
import { FilterOption, TagRow } from "./types.js";
|
|
6
|
+
import { ComponentTagPicker } from "../../styleD/build/typescript/component/tagPicker.js";
|
|
7
|
+
import { ReactElement } from "react";
|
|
8
|
+
import { SerializedStyles } from "@emotion/react";
|
|
9
|
+
|
|
10
|
+
//#region src/components/TagPicker/TagPicker.d.ts
|
|
11
|
+
type TagPickerProps<T extends TagRow = TagRow> = {
|
|
12
|
+
/** `addTag` - Function called when a tag is selected from the dropdown or proposal list */addTag: (tag: T) => void; /** `loading` - Whether the component is loading options for the dropdown */
|
|
13
|
+
loading: boolean; /** `offline` - Whether the component has failed to fetch a list of options, indicating either that the service is offline or cannot be reached */
|
|
14
|
+
offline?: boolean; /** `onReorder - Function called when a selected tag is moved in the tag table */
|
|
15
|
+
onReorder?: (tags: T[]) => void; /** `onReorder - Function called the user enters a query or selects a filter value */
|
|
16
|
+
onSearch: (queryText: string, filterValue?: string) => void; /** `options` - The list of options shown in the dropdown */
|
|
17
|
+
options: T[]; /** `proposedTags` - A list of "proposed tags" that the user can add */
|
|
18
|
+
proposedTags: T[]; /** `readOnly` - Whether the interactions modifying the list of tags should be disabled */
|
|
19
|
+
readOnly?: boolean; /** `addTag` - Function called when a tag is removed from selected tags list */
|
|
20
|
+
removeTag: (tag: T) => void; /** `retryConnection - Function called to check if the service to fetch tag options is available again */
|
|
21
|
+
retryConnection?: () => void; /** `tags` - The list of selected tags */
|
|
22
|
+
tags: T[]; /** `canRemove - A filter function that determines if the user is able to remove the tag from the selected tags */
|
|
23
|
+
canRemove?: (tag: T) => boolean; /** `filterRows - A filter function that determines if the tag should be excluded from the selected and proposed tag tables */
|
|
24
|
+
filterRows?: (tag: T) => boolean; /** `filterOptions` - the list of options for setting the filter value (second argument of `onSearch`). If omitted, or has only one member, the Select input is not rendered. */
|
|
25
|
+
filterOptions?: FilterOption[]; /** `offlineBackupTags` - A list of tags that the user can select if the service is offline */
|
|
26
|
+
offlineBackupTags?: T[];
|
|
27
|
+
highlightLeadingTag?: boolean;
|
|
28
|
+
searchPlaceholder?: string;
|
|
29
|
+
searchLabel?: string;
|
|
30
|
+
removeIcon?: ReactElement;
|
|
31
|
+
searchIcon?: ReactElement;
|
|
32
|
+
showTagType?: boolean;
|
|
33
|
+
showTagSectionName?: boolean; /** `theme` - Used to customise the look and feel of the TagPicker component */
|
|
34
|
+
theme?: DeepPartial<ComponentTagPicker>;
|
|
35
|
+
tagTableTheme?: DeepPartial<ComponentTagTable>;
|
|
36
|
+
proposedTagTableTheme?: DeepPartial<ComponentTagTable>;
|
|
37
|
+
autoCompleteTheme?: DeepPartial<ComponentAutocomplete>;
|
|
38
|
+
selectTheme?: DeepPartial<ComponentSelect>; /** `cssOverrides` - Escape hatch for styling that doesn't fall into the theme */
|
|
39
|
+
cssOverrides?: SerializedStyles;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* ## TagPicker
|
|
43
|
+
*
|
|
44
|
+
* *Status: Testing*
|
|
45
|
+
*
|
|
46
|
+
* **Peer dependencies:**
|
|
47
|
+
* - `react-aria-components`
|
|
48
|
+
*
|
|
49
|
+
* See the `peerDependencies` section of the `package.json` for compatible versions to install.
|
|
50
|
+
*
|
|
51
|
+
*
|
|
52
|
+
* #### Props
|
|
53
|
+
*
|
|
54
|
+
* See {@link TagPickerProps} for a full list of props and descriptions.
|
|
55
|
+
*
|
|
56
|
+
* #### Example
|
|
57
|
+
*
|
|
58
|
+
* This is currently still in testing phase, so a production implementation is not yet available.
|
|
59
|
+
*/
|
|
60
|
+
declare function TagPicker<T extends TagRow = TagRow>({
|
|
61
|
+
addTag,
|
|
62
|
+
loading,
|
|
63
|
+
offline,
|
|
64
|
+
onReorder,
|
|
65
|
+
onSearch,
|
|
66
|
+
options,
|
|
67
|
+
proposedTags,
|
|
68
|
+
readOnly,
|
|
69
|
+
removeTag,
|
|
70
|
+
retryConnection,
|
|
71
|
+
tags,
|
|
72
|
+
canRemove,
|
|
73
|
+
filterRows,
|
|
74
|
+
filterOptions,
|
|
75
|
+
offlineBackupTags,
|
|
76
|
+
highlightLeadingTag,
|
|
77
|
+
searchPlaceholder,
|
|
78
|
+
searchLabel,
|
|
79
|
+
removeIcon,
|
|
80
|
+
searchIcon,
|
|
81
|
+
showTagType,
|
|
82
|
+
showTagSectionName,
|
|
83
|
+
theme,
|
|
84
|
+
tagTableTheme,
|
|
85
|
+
proposedTagTableTheme,
|
|
86
|
+
autoCompleteTheme,
|
|
87
|
+
selectTheme,
|
|
88
|
+
cssOverrides
|
|
89
|
+
}: TagPickerProps<T>): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
90
|
+
//#endregion
|
|
91
|
+
export { TagPicker };
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { Button } from "../Button/Button.js";
|
|
2
|
+
import { InlineMessage } from "../InlineMessage/InlineMessage.js";
|
|
3
|
+
import { offlineSectionStyles, tagPickerStyles } from "./styles.js";
|
|
4
|
+
import { TagTable } from "./TagTable.js";
|
|
5
|
+
import { TagSearchWithFilters } from "./TagSearchWithFilters.js";
|
|
6
|
+
import { css } from "@emotion/react";
|
|
7
|
+
import { Fragment, jsx, jsxs } from "@emotion/react/jsx-runtime";
|
|
8
|
+
//#region src/components/TagPicker/TagPicker.tsx
|
|
9
|
+
/**
|
|
10
|
+
* ## TagPicker
|
|
11
|
+
*
|
|
12
|
+
* *Status: Testing*
|
|
13
|
+
*
|
|
14
|
+
* **Peer dependencies:**
|
|
15
|
+
* - `react-aria-components`
|
|
16
|
+
*
|
|
17
|
+
* See the `peerDependencies` section of the `package.json` for compatible versions to install.
|
|
18
|
+
*
|
|
19
|
+
*
|
|
20
|
+
* #### Props
|
|
21
|
+
*
|
|
22
|
+
* See {@link TagPickerProps} for a full list of props and descriptions.
|
|
23
|
+
*
|
|
24
|
+
* #### Example
|
|
25
|
+
*
|
|
26
|
+
* This is currently still in testing phase, so a production implementation is not yet available.
|
|
27
|
+
*/
|
|
28
|
+
function TagPicker({ addTag, loading, offline = false, onReorder, onSearch, options, proposedTags, readOnly = false, removeTag, retryConnection, tags, canRemove, filterRows, filterOptions, offlineBackupTags, highlightLeadingTag, searchPlaceholder = "Search for tags", searchLabel = "Search for tags", removeIcon, searchIcon, showTagType, showTagSectionName, theme, tagTableTheme, proposedTagTableTheme, autoCompleteTheme, selectTheme, cssOverrides }) {
|
|
29
|
+
const selectedTagIds = tags.map(({ id }) => id);
|
|
30
|
+
const proposedTagsWithoutSelected = proposedTags.filter(({ id }) => !selectedTagIds.includes(id));
|
|
31
|
+
const backupTagsWithoutSelected = offlineBackupTags?.filter(({ id }) => !selectedTagIds.includes(id)) ?? [];
|
|
32
|
+
const showBackupListWhenOffline = !readOnly && offlineBackupTags && backupTagsWithoutSelected.length > 0;
|
|
33
|
+
const optionsWithoutSelected = options.filter(({ id }) => !selectedTagIds.includes(id));
|
|
34
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
35
|
+
css: [tagPickerStyles(theme), cssOverrides],
|
|
36
|
+
children: [
|
|
37
|
+
/* @__PURE__ */ jsx(TagSearchWithFilters, {
|
|
38
|
+
icon: searchIcon,
|
|
39
|
+
onSearch,
|
|
40
|
+
addSelection: addTag,
|
|
41
|
+
options: optionsWithoutSelected,
|
|
42
|
+
loading,
|
|
43
|
+
filterOptions,
|
|
44
|
+
disabled: readOnly || offline,
|
|
45
|
+
label: searchLabel,
|
|
46
|
+
placeholder: searchPlaceholder,
|
|
47
|
+
"data-testid": "tag-picker-search-input",
|
|
48
|
+
symbol: "search",
|
|
49
|
+
theme,
|
|
50
|
+
autoCompleteTheme,
|
|
51
|
+
selectTheme
|
|
52
|
+
}),
|
|
53
|
+
offline && /* @__PURE__ */ jsxs("div", {
|
|
54
|
+
css: offlineSectionStyles(theme),
|
|
55
|
+
children: [/* @__PURE__ */ jsxs(InlineMessage, {
|
|
56
|
+
level: "error",
|
|
57
|
+
children: [
|
|
58
|
+
"Unfortunately, we can't fetch tag information.",
|
|
59
|
+
" ",
|
|
60
|
+
showBackupListWhenOffline && "Choose from the following tags",
|
|
61
|
+
showBackupListWhenOffline && retryConnection && /* @__PURE__ */ jsx(Fragment, { children: " or " }),
|
|
62
|
+
retryConnection && /* @__PURE__ */ jsx(Button, {
|
|
63
|
+
size: "xs",
|
|
64
|
+
variant: "secondary",
|
|
65
|
+
onClick: () => retryConnection(),
|
|
66
|
+
children: "Retry"
|
|
67
|
+
})
|
|
68
|
+
]
|
|
69
|
+
}), showBackupListWhenOffline && /* @__PURE__ */ jsx(Fragment, { children: backupTagsWithoutSelected.map((tag, index) => /* @__PURE__ */ jsx(Button, {
|
|
70
|
+
onClick: () => addTag(tag),
|
|
71
|
+
variant: "tertiary",
|
|
72
|
+
size: "sm",
|
|
73
|
+
cssOverrides: css({ justifyContent: theme?.offlineSection?.justifyContent ?? "flex-start" }),
|
|
74
|
+
"aria-label": `Add ${tag.name}`,
|
|
75
|
+
children: tag.name
|
|
76
|
+
}, index)) })]
|
|
77
|
+
}),
|
|
78
|
+
/* @__PURE__ */ jsx(TagTable, {
|
|
79
|
+
rows: tags,
|
|
80
|
+
canRemove,
|
|
81
|
+
removeAction: readOnly ? void 0 : removeTag,
|
|
82
|
+
filterRows,
|
|
83
|
+
onReorder: readOnly ? void 0 : onReorder,
|
|
84
|
+
"data-testid": "selected-tags-table",
|
|
85
|
+
highlightFirstRow: highlightLeadingTag,
|
|
86
|
+
showTagType,
|
|
87
|
+
showTagSectionName,
|
|
88
|
+
removeIcon,
|
|
89
|
+
theme: tagTableTheme
|
|
90
|
+
}),
|
|
91
|
+
!readOnly && /* @__PURE__ */ jsx(TagTable, {
|
|
92
|
+
heading: "Proposed Tags",
|
|
93
|
+
theme: proposedTagTableTheme,
|
|
94
|
+
filterRows,
|
|
95
|
+
showTagType,
|
|
96
|
+
showTagSectionName,
|
|
97
|
+
rows: proposedTagsWithoutSelected,
|
|
98
|
+
addAction: addTag,
|
|
99
|
+
"data-testid": "proposed-tags-table"
|
|
100
|
+
})
|
|
101
|
+
]
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
//#endregion
|
|
105
|
+
export { TagPicker };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
const require_Select = require("../Select/Select.cjs");
|
|
2
|
+
const require_styles = require("./styles.cjs");
|
|
3
|
+
const require_Autocomplete = require("./Autocomplete.cjs");
|
|
4
|
+
let react = require("react");
|
|
5
|
+
let _emotion_react = require("@emotion/react");
|
|
6
|
+
let _emotion_react_jsx_runtime = require("@emotion/react/jsx-runtime");
|
|
7
|
+
//#region src/components/TagPicker/TagSearchWithFilters.tsx
|
|
8
|
+
function TagSearchWithFilters({ addSelection, onSearch, filterOptions, disabled, theme, autoCompleteTheme, selectTheme = {}, ...tagAutocompleteProps }) {
|
|
9
|
+
const [queryText, setQueryText] = (0, react.useState)("");
|
|
10
|
+
const [filterValue, setFilterValue] = (0, react.useState)(filterOptions?.[0]?.filter);
|
|
11
|
+
const onSearchRef = (0, react.useRef)(onSearch);
|
|
12
|
+
(0, react.useEffect)(() => {
|
|
13
|
+
onSearchRef.current = onSearch;
|
|
14
|
+
}, [onSearch]);
|
|
15
|
+
(0, react.useEffect)(() => {
|
|
16
|
+
if (queryText && queryText.length > 0) onSearchRef.current(queryText, filterValue && filterValue.length > 0 ? filterValue : void 0);
|
|
17
|
+
}, [filterValue, queryText]);
|
|
18
|
+
const shouldRenderSelect = filterOptions && filterOptions.length > 1;
|
|
19
|
+
return /* @__PURE__ */ (0, _emotion_react_jsx_runtime.jsxs)("div", {
|
|
20
|
+
css: require_styles.tagSearchWithFilterStyles(theme),
|
|
21
|
+
children: [/* @__PURE__ */ (0, _emotion_react_jsx_runtime.jsx)(require_Autocomplete.Autocomplete, {
|
|
22
|
+
cssOverrides: (0, _emotion_react.css)({ flex: 1 }),
|
|
23
|
+
onTextInputChange: setQueryText,
|
|
24
|
+
addSelection: (tag) => {
|
|
25
|
+
addSelection(tag);
|
|
26
|
+
setQueryText("");
|
|
27
|
+
},
|
|
28
|
+
value: queryText,
|
|
29
|
+
...tagAutocompleteProps,
|
|
30
|
+
disabled,
|
|
31
|
+
theme: autoCompleteTheme,
|
|
32
|
+
addFirstOnEnter: true
|
|
33
|
+
}), shouldRenderSelect && /* @__PURE__ */ (0, _emotion_react_jsx_runtime.jsx)(require_Select.Select, {
|
|
34
|
+
theme: require_styles.modifyFilterSelectTheme(selectTheme),
|
|
35
|
+
cssOverrides: require_styles.filterSelectCssOverrides(theme),
|
|
36
|
+
isDisabled: disabled,
|
|
37
|
+
value: filterValue,
|
|
38
|
+
placement: "bottom right",
|
|
39
|
+
shouldFlip: false,
|
|
40
|
+
onChange: (selection) => {
|
|
41
|
+
if (Array.isArray(selection) || selection === null) return;
|
|
42
|
+
setFilterValue(selection.toString());
|
|
43
|
+
},
|
|
44
|
+
children: filterOptions.map((data, index) => /* @__PURE__ */ (0, _emotion_react_jsx_runtime.jsx)(require_Select.Option, {
|
|
45
|
+
value: data,
|
|
46
|
+
id: data.filter,
|
|
47
|
+
children: data.label
|
|
48
|
+
}, index))
|
|
49
|
+
})]
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
53
|
+
exports.TagSearchWithFilters = TagSearchWithFilters;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Option, Select } from "../Select/Select.js";
|
|
2
|
+
import { filterSelectCssOverrides, modifyFilterSelectTheme, tagSearchWithFilterStyles } from "./styles.js";
|
|
3
|
+
import { Autocomplete } from "./Autocomplete.js";
|
|
4
|
+
import { useEffect, useRef, useState } from "react";
|
|
5
|
+
import { css } from "@emotion/react";
|
|
6
|
+
import { jsx, jsxs } from "@emotion/react/jsx-runtime";
|
|
7
|
+
//#region src/components/TagPicker/TagSearchWithFilters.tsx
|
|
8
|
+
function TagSearchWithFilters({ addSelection, onSearch, filterOptions, disabled, theme, autoCompleteTheme, selectTheme = {}, ...tagAutocompleteProps }) {
|
|
9
|
+
const [queryText, setQueryText] = useState("");
|
|
10
|
+
const [filterValue, setFilterValue] = useState(filterOptions?.[0]?.filter);
|
|
11
|
+
const onSearchRef = useRef(onSearch);
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
onSearchRef.current = onSearch;
|
|
14
|
+
}, [onSearch]);
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
if (queryText && queryText.length > 0) onSearchRef.current(queryText, filterValue && filterValue.length > 0 ? filterValue : void 0);
|
|
17
|
+
}, [filterValue, queryText]);
|
|
18
|
+
const shouldRenderSelect = filterOptions && filterOptions.length > 1;
|
|
19
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
20
|
+
css: tagSearchWithFilterStyles(theme),
|
|
21
|
+
children: [/* @__PURE__ */ jsx(Autocomplete, {
|
|
22
|
+
cssOverrides: css({ flex: 1 }),
|
|
23
|
+
onTextInputChange: setQueryText,
|
|
24
|
+
addSelection: (tag) => {
|
|
25
|
+
addSelection(tag);
|
|
26
|
+
setQueryText("");
|
|
27
|
+
},
|
|
28
|
+
value: queryText,
|
|
29
|
+
...tagAutocompleteProps,
|
|
30
|
+
disabled,
|
|
31
|
+
theme: autoCompleteTheme,
|
|
32
|
+
addFirstOnEnter: true
|
|
33
|
+
}), shouldRenderSelect && /* @__PURE__ */ jsx(Select, {
|
|
34
|
+
theme: modifyFilterSelectTheme(selectTheme),
|
|
35
|
+
cssOverrides: filterSelectCssOverrides(theme),
|
|
36
|
+
isDisabled: disabled,
|
|
37
|
+
value: filterValue,
|
|
38
|
+
placement: "bottom right",
|
|
39
|
+
shouldFlip: false,
|
|
40
|
+
onChange: (selection) => {
|
|
41
|
+
if (Array.isArray(selection) || selection === null) return;
|
|
42
|
+
setFilterValue(selection.toString());
|
|
43
|
+
},
|
|
44
|
+
children: filterOptions.map((data, index) => /* @__PURE__ */ jsx(Option, {
|
|
45
|
+
value: data,
|
|
46
|
+
id: data.filter,
|
|
47
|
+
children: data.label
|
|
48
|
+
}, index))
|
|
49
|
+
})]
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
53
|
+
export { TagSearchWithFilters };
|
|
@@ -28,37 +28,13 @@ const defaultCanRemove = () => true;
|
|
|
28
28
|
*
|
|
29
29
|
* ## Usage
|
|
30
30
|
*
|
|
31
|
-
* *Example with
|
|
31
|
+
* *Example with TagTable:*
|
|
32
32
|
*
|
|
33
33
|
* ```tsx
|
|
34
|
-
* import {
|
|
34
|
+
* import { TagTable } from '@guardian/stand';
|
|
35
35
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* TagManagerObjectData[] // TagManagerObjectData is an internal type representing a Tag
|
|
39
|
-
* >([]);
|
|
40
|
-
|
|
41
|
-
* const [options, setOptions] = useState<TagManagerObjectData[]>([]);
|
|
42
|
-
* const [value, setValue] = useState('');
|
|
43
|
-
* const onChange = (inputText: string) => {
|
|
44
|
-
* setValue(inputText);
|
|
45
|
-
* if (inputText === '') {
|
|
46
|
-
* setOptions([]);
|
|
47
|
-
* return;
|
|
48
|
-
* }
|
|
49
|
-
*
|
|
50
|
-
* if (inputText === '*') {
|
|
51
|
-
* setOptions(exampleTags); // exampleTags is an array of Tags
|
|
52
|
-
* return;
|
|
53
|
-
* }
|
|
54
|
-
*
|
|
55
|
-
* // Simple filtering against exampleTags
|
|
56
|
-
* const filteredItems = exampleTags.filter((t) =>
|
|
57
|
-
* t.internalName.toLowerCase().includes(inputText.toLowerCase()),
|
|
58
|
-
* );
|
|
59
|
-
* return setOptions(filteredItems);
|
|
60
|
-
* };
|
|
61
|
-
|
|
36
|
+
* // TagManagerObjectData is an internal type representing a Tag
|
|
37
|
+
* const Component = ({selectedTags}:{selectedTags:TagManagerObjectData[]}) => {
|
|
62
38
|
* return (
|
|
63
39
|
* <>
|
|
64
40
|
* <div
|
|
@@ -66,25 +42,10 @@ const defaultCanRemove = () => true;
|
|
|
66
42
|
* display: flex;
|
|
67
43
|
* `}
|
|
68
44
|
* >
|
|
69
|
-
* <TagAutocomplete
|
|
70
|
-
* onChange={onChange}
|
|
71
|
-
* options={options}
|
|
72
|
-
* label="Tags"
|
|
73
|
-
* addTag={(tag) =>
|
|
74
|
-
* setSelectedTags((tags) => {
|
|
75
|
-
* return [...tags, tag];
|
|
76
|
-
* })
|
|
77
|
-
* }
|
|
78
|
-
* loading={false}
|
|
79
|
-
* placeholder={''}
|
|
80
|
-
* disabled={false}
|
|
81
|
-
* value={value}
|
|
82
|
-
* />
|
|
83
|
-
* <select>
|
|
84
|
-
* option>All tags</option>
|
|
85
|
-
* </select>
|
|
86
|
-
* </div>
|
|
87
45
|
* <TagTable rows={selectedTags} filterRows={() => true} />
|
|
46
|
+
* <div>
|
|
47
|
+
* there are {selectedTags.length} tags.
|
|
48
|
+
* </div>
|
|
88
49
|
* </>
|
|
89
50
|
* );
|
|
90
51
|
* };
|
|
@@ -98,7 +59,7 @@ const defaultCanRemove = () => true;
|
|
|
98
59
|
*
|
|
99
60
|
* This is currently still in testing phase, so a production implementation is not yet available.
|
|
100
61
|
*/
|
|
101
|
-
function TagTable({ rows, filterRows, heading, showTagType, showTagSectionName, removeAction: removeTag, addAction: addTag, onReorder, canRemove = defaultCanRemove, "data-testid": dataTestId, removeIcon, gripIcon, theme, cssOverrides }) {
|
|
62
|
+
function TagTable({ rows, filterRows, heading, showTagType, showTagSectionName, highlightFirstRow = false, removeAction: removeTag, addAction: addTag, onReorder, canRemove = defaultCanRemove, "data-testid": dataTestId, removeIcon, gripIcon, theme, cssOverrides }) {
|
|
102
63
|
const canDrag = !!onReorder;
|
|
103
64
|
const [localRows, setLocalRows] = (0, react.useState)(() => [...rows]);
|
|
104
65
|
const localRowsRef = (0, react.useRef)(localRows);
|
|
@@ -106,7 +67,7 @@ function TagTable({ rows, filterRows, heading, showTagType, showTagSectionName,
|
|
|
106
67
|
(0, react.useEffect)(() => {
|
|
107
68
|
setLocalRows([...rows]);
|
|
108
69
|
}, [rows]);
|
|
109
|
-
const filtered = localRows.filter(filterRows);
|
|
70
|
+
const filtered = filterRows ? localRows.filter(filterRows) : [...localRows];
|
|
110
71
|
const { dragAndDropHooks } = (0, react_aria_components.useDragAndDrop)({
|
|
111
72
|
getItems: (_keys, items) => {
|
|
112
73
|
return items.map((item) => ({ "text/plain": rowToTag(item).id.toString() }));
|
|
@@ -155,7 +116,7 @@ function TagTable({ rows, filterRows, heading, showTagType, showTagSectionName,
|
|
|
155
116
|
dependencies: [localRows],
|
|
156
117
|
children: (item) => /* @__PURE__ */ (0, _emotion_react_jsx_runtime.jsxs)(react_aria_components.Row, {
|
|
157
118
|
id: rowToTag(item).id,
|
|
158
|
-
css: require_styles.tagTableRowStyles(canDrag, theme),
|
|
119
|
+
css: require_styles.tagTableRowStyles(canDrag, highlightFirstRow, theme),
|
|
159
120
|
textValue: rowToTag(item).name,
|
|
160
121
|
children: [
|
|
161
122
|
onReorder && /* @__PURE__ */ (0, _emotion_react_jsx_runtime.jsx)(react_aria_components.Cell, {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DeepPartial } from "../../util/types.cjs";
|
|
2
|
-
import { TagRow } from "./types.cjs";
|
|
3
2
|
import { ComponentTagTable } from "../../styleD/build/typescript/component/tagTable.cjs";
|
|
3
|
+
import { TagRow } from "./types.cjs";
|
|
4
4
|
import { SerializedStyles } from "@emotion/react";
|
|
5
5
|
import { ReactElement } from "react";
|
|
6
6
|
|
|
@@ -12,7 +12,7 @@ interface TagTableProps<R extends Row> {
|
|
|
12
12
|
/** `rows` - The collection of rows */
|
|
13
13
|
rows: R[];
|
|
14
14
|
/** `filterRows` - Function to filter rows from `rows` prop from appearing in the table */
|
|
15
|
-
filterRows
|
|
15
|
+
filterRows?: (row: R) => boolean;
|
|
16
16
|
/** `heading` - The table heading */
|
|
17
17
|
heading?: string;
|
|
18
18
|
/** `showTagType` - Whether to show tags' type in table */
|
|
@@ -21,6 +21,8 @@ interface TagTableProps<R extends Row> {
|
|
|
21
21
|
showTagSectionName?: boolean;
|
|
22
22
|
/** `removeAction` - Function called when the Remove button is pressed on a row */
|
|
23
23
|
removeAction?: (tag: R) => void;
|
|
24
|
+
/** `highlightFirstRow` - Whether to highlight the first row ("leading tag") */
|
|
25
|
+
highlightFirstRow?: boolean;
|
|
24
26
|
/** `addAction` - Function called when the Add button is pressed on a row */
|
|
25
27
|
addAction?: (tag: R) => void;
|
|
26
28
|
/** `onReorder` - Function called when a re-ordering of rows through drag and drop is performed */
|
|
@@ -53,37 +55,13 @@ interface TagTableProps<R extends Row> {
|
|
|
53
55
|
*
|
|
54
56
|
* ## Usage
|
|
55
57
|
*
|
|
56
|
-
* *Example with
|
|
58
|
+
* *Example with TagTable:*
|
|
57
59
|
*
|
|
58
60
|
* ```tsx
|
|
59
|
-
* import {
|
|
60
|
-
*
|
|
61
|
-
* const Component = () => {
|
|
62
|
-
* const [selectedTags, setSelectedTags] = useState<
|
|
63
|
-
* TagManagerObjectData[] // TagManagerObjectData is an internal type representing a Tag
|
|
64
|
-
* >([]);
|
|
65
|
-
|
|
66
|
-
* const [options, setOptions] = useState<TagManagerObjectData[]>([]);
|
|
67
|
-
* const [value, setValue] = useState('');
|
|
68
|
-
* const onChange = (inputText: string) => {
|
|
69
|
-
* setValue(inputText);
|
|
70
|
-
* if (inputText === '') {
|
|
71
|
-
* setOptions([]);
|
|
72
|
-
* return;
|
|
73
|
-
* }
|
|
74
|
-
*
|
|
75
|
-
* if (inputText === '*') {
|
|
76
|
-
* setOptions(exampleTags); // exampleTags is an array of Tags
|
|
77
|
-
* return;
|
|
78
|
-
* }
|
|
61
|
+
* import { TagTable } from '@guardian/stand';
|
|
79
62
|
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
* t.internalName.toLowerCase().includes(inputText.toLowerCase()),
|
|
83
|
-
* );
|
|
84
|
-
* return setOptions(filteredItems);
|
|
85
|
-
* };
|
|
86
|
-
|
|
63
|
+
* // TagManagerObjectData is an internal type representing a Tag
|
|
64
|
+
* const Component = ({selectedTags}:{selectedTags:TagManagerObjectData[]}) => {
|
|
87
65
|
* return (
|
|
88
66
|
* <>
|
|
89
67
|
* <div
|
|
@@ -91,25 +69,10 @@ interface TagTableProps<R extends Row> {
|
|
|
91
69
|
* display: flex;
|
|
92
70
|
* `}
|
|
93
71
|
* >
|
|
94
|
-
* <TagAutocomplete
|
|
95
|
-
* onChange={onChange}
|
|
96
|
-
* options={options}
|
|
97
|
-
* label="Tags"
|
|
98
|
-
* addTag={(tag) =>
|
|
99
|
-
* setSelectedTags((tags) => {
|
|
100
|
-
* return [...tags, tag];
|
|
101
|
-
* })
|
|
102
|
-
* }
|
|
103
|
-
* loading={false}
|
|
104
|
-
* placeholder={''}
|
|
105
|
-
* disabled={false}
|
|
106
|
-
* value={value}
|
|
107
|
-
* />
|
|
108
|
-
* <select>
|
|
109
|
-
* option>All tags</option>
|
|
110
|
-
* </select>
|
|
111
|
-
* </div>
|
|
112
72
|
* <TagTable rows={selectedTags} filterRows={() => true} />
|
|
73
|
+
* <div>
|
|
74
|
+
* there are {selectedTags.length} tags.
|
|
75
|
+
* </div>
|
|
113
76
|
* </>
|
|
114
77
|
* );
|
|
115
78
|
* };
|
|
@@ -129,6 +92,7 @@ declare function TagTable<R extends Row>({
|
|
|
129
92
|
heading,
|
|
130
93
|
showTagType,
|
|
131
94
|
showTagSectionName,
|
|
95
|
+
highlightFirstRow,
|
|
132
96
|
removeAction: removeTag,
|
|
133
97
|
addAction: addTag,
|
|
134
98
|
onReorder,
|