@blocklet/labels 2.4.36 → 2.4.37

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.
@@ -1,5 +1,6 @@
1
+ /// <reference types="react" />
1
2
  import { Label } from './types';
2
- import { CreateLabel, FetchLabels } from '../../types';
3
+ import type { CreateLabel, FetchLabels } from '../../types';
3
4
  interface LabelsProviderProps {
4
5
  fetchLabels: FetchLabels;
5
6
  createLabel: CreateLabel;
@@ -16,5 +17,5 @@ interface LabelsContextValue {
16
17
  }
17
18
  export declare const useLabelsContext: () => LabelsContextValue;
18
19
  export declare const useLabelsUpdateOnDestroy: () => void;
19
- export declare function LabelsProvider({ fetchLabels, createLabel, children }: LabelsProviderProps): import("react/jsx-runtime").JSX.Element;
20
+ export declare function LabelsProvider({ fetchLabels, createLabel, children }: LabelsProviderProps): import("react").JSX.Element;
20
21
  export {};
@@ -0,0 +1,87 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useState, useMemo, useCallback, createContext, useContext, useEffect } from "react";
3
+ import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
4
+ import { useRequest } from "ahooks";
5
+ import { transformLabels, flatten } from "./utils.mjs";
6
+ import { LabelsContainer } from "../../label2/labels-context.mjs";
7
+ import { createCacheKey, getCache, setCache } from "../../request-cache.mjs";
8
+ const LabelsContext = createContext({});
9
+ export const useLabelsContext = () => useContext(LabelsContext);
10
+ export const useLabelsUpdateOnDestroy = () => {
11
+ const { updateLabels } = useLabelsContext();
12
+ useEffect(() => {
13
+ return () => {
14
+ updateLabels();
15
+ };
16
+ }, []);
17
+ };
18
+ export function LabelsProvider({ fetchLabels, createLabel, children }) {
19
+ const { locale } = useLocaleContext();
20
+ const [updateCounter, setUpdateCounter] = useState(1);
21
+ const cacheKey = createCacheKey(["labels"]);
22
+ const { loading, data } = useRequest(fetchLabels, {
23
+ cacheKey,
24
+ getCache: () => getCache(cacheKey),
25
+ setCache: (d) => setCache(cacheKey, d),
26
+ refreshDeps: [updateCounter]
27
+ });
28
+ const labels = useMemo(() => transformLabels(data?.labels || []), [data]);
29
+ const labelsKeyById = useMemo(() => {
30
+ if (!labels?.length) {
31
+ return {};
32
+ }
33
+ const flattened = flatten(labels);
34
+ return flattened.reduce((acc, cur) => ({ ...acc, [cur.id]: cur }), {});
35
+ }, [labels]);
36
+ const localeTransformer = useCallback(
37
+ (label) => ({
38
+ ...label,
39
+ name: label.translation?.[locale] || label.name
40
+ }),
41
+ [locale]
42
+ );
43
+ const getLabelsById = useCallback(
44
+ (ids) => ids.filter(Boolean).map((item) => labelsKeyById[item]).map(localeTransformer),
45
+ [labelsKeyById, localeTransformer]
46
+ );
47
+ const getParents = useCallback((label) => {
48
+ let { parent } = label;
49
+ const parents = [];
50
+ while (parent) {
51
+ parents.unshift(parent);
52
+ parent = parent.parent;
53
+ }
54
+ return parents;
55
+ }, []);
56
+ const getFullLabelName = useCallback(
57
+ (label) => {
58
+ const parents = [...getParents(label), label].map(localeTransformer);
59
+ return parents.map((item) => item.name).join(" / ");
60
+ },
61
+ [localeTransformer, getParents]
62
+ );
63
+ const parseLabelIds = useCallback((labelIdsStr) => {
64
+ return labelIdsStr?.split(",").filter(Boolean) || [];
65
+ }, []);
66
+ const stringifyLabelIds = useCallback((labelIds = []) => {
67
+ if (!labelIds?.length) {
68
+ return void 0;
69
+ }
70
+ return labelIds.join(",");
71
+ }, []);
72
+ const localizedLabels = useMemo(() => labels.map(localeTransformer), [labels, localeTransformer]);
73
+ const value = useMemo(() => {
74
+ return {
75
+ loading,
76
+ labels: labels || [],
77
+ updateLabels: () => setUpdateCounter((prev) => prev + 1),
78
+ getLabelsById,
79
+ parseLabelIds,
80
+ stringifyLabelIds,
81
+ localizedLabels,
82
+ flattenedLabels: flatten(localizedLabels || []),
83
+ getFullLabelName
84
+ };
85
+ }, [loading, labels, getLabelsById, parseLabelIds, stringifyLabelIds, localizedLabels, getFullLabelName]);
86
+ return /* @__PURE__ */ jsx(LabelsContext.Provider, { value, children: /* @__PURE__ */ jsx(LabelsContainer.Provider, { initialState: { loading, data, createLabel }, children }) });
87
+ }
@@ -0,0 +1,5 @@
1
+ export { default as LabelTree } from "./label-tree.mjs";
2
+ export { default as LabelPicker } from "./label-picker.mjs";
3
+ export { default as Labels } from "./labels.mjs";
4
+ export * from "./context.mjs";
5
+ export * from "./types.mjs";
@@ -1,3 +1,4 @@
1
+ /// <reference types="react" />
1
2
  import { GroupBase } from 'react-select';
2
3
  import { Label } from './types';
3
4
  interface LabelPickerProps {
@@ -15,5 +16,5 @@ declare module 'react-select/dist/declarations/src/Select' {
15
16
  data: Label[];
16
17
  }
17
18
  }
18
- export default function LabelPicker({ data, value, editable, addon, onChange, compact, isMulti, maxHeight, ...rest }: LabelPickerProps): import("react/jsx-runtime").JSX.Element;
19
+ export default function LabelPicker({ data, value, editable, addon, onChange, compact, isMulti, maxHeight, ...rest }: LabelPickerProps): import("react").JSX.Element;
19
20
  export {};
@@ -0,0 +1,175 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { useMemo, useRef } from "react";
3
+ import omit from "lodash/omit";
4
+ import Box from "@mui/material/Box";
5
+ import Select, {
6
+ components
7
+ } from "react-select";
8
+ import LabelTree from "./label-tree.mjs";
9
+ import { flatten } from "./utils.mjs";
10
+ const LabelMenuList = (props) => {
11
+ const { options, getValue, selectProps, selectOption } = props;
12
+ const value = getValue();
13
+ const handleSelect = (id) => {
14
+ const option = options.find((item) => item.data.id === id);
15
+ if (option) {
16
+ selectOption(option);
17
+ }
18
+ };
19
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
20
+ /* @__PURE__ */ jsx(components.MenuList, { ...omit(props, ["addon"]), children: /* @__PURE__ */ jsx(Box, { sx: { px: 2, py: 1 }, children: /* @__PURE__ */ jsx(
21
+ LabelTree,
22
+ {
23
+ data: selectProps.data,
24
+ selectable: true,
25
+ onSelect: handleSelect,
26
+ selected: value.map((item) => item.data.id)
27
+ }
28
+ ) }) }),
29
+ props.addon
30
+ ] });
31
+ };
32
+ const ValueContainer = ({ children, ...props }) => {
33
+ const [values, input] = children;
34
+ const count = Array.isArray(values) ? values.length : 0;
35
+ return /* @__PURE__ */ jsxs(components.ValueContainer, { ...props, children: [
36
+ /* @__PURE__ */ jsx(
37
+ Box,
38
+ {
39
+ component: "span",
40
+ sx: {
41
+ fontSize: 13,
42
+ fontWeight: "bold",
43
+ color: (theme) => theme.palette.mode === "dark" ? "grey.800" : "text.primary"
44
+ },
45
+ children: count ? "Labels" : "Filter by labels"
46
+ }
47
+ ),
48
+ !!count && /* @__PURE__ */ jsx(
49
+ Box,
50
+ {
51
+ sx: {
52
+ display: "inline-flex",
53
+ justifyContent: "center",
54
+ alignItems: "center",
55
+ width: 22,
56
+ height: 22,
57
+ ml: 1,
58
+ borderRadius: "100%",
59
+ fontSize: 12,
60
+ color: (theme) => theme.palette.mode === "dark" ? "grey.800" : "text.primary",
61
+ bgcolor: "grey.200"
62
+ },
63
+ children: count
64
+ }
65
+ ),
66
+ input
67
+ ] });
68
+ };
69
+ const compactSelectStyles = {
70
+ control: (provided) => ({
71
+ ...provided,
72
+ minHeight: 31
73
+ }),
74
+ valueContainer: (provided) => ({
75
+ ...provided,
76
+ display: "flex"
77
+ }),
78
+ dropdownIndicator: (provided) => ({
79
+ ...provided,
80
+ padding: "0 4px"
81
+ }),
82
+ clearIndicator: (provided) => ({
83
+ ...provided,
84
+ padding: "4px"
85
+ })
86
+ };
87
+ export default function LabelPicker({
88
+ data,
89
+ value = [],
90
+ editable = false,
91
+ addon,
92
+ onChange,
93
+ compact,
94
+ isMulti = true,
95
+ maxHeight = 264,
96
+ ...rest
97
+ }) {
98
+ const selectRef = useRef(null);
99
+ const options = useMemo(
100
+ () => flatten(data).map((item) => ({ data: item, label: item.name, value: item.id })),
101
+ [data]
102
+ );
103
+ const optionsKeyById = options.reduce(
104
+ (acc, cur) => ({ ...acc, [cur.data.id]: cur }),
105
+ {}
106
+ );
107
+ const valueArr = Array.isArray(value) ? value : [value];
108
+ const selectedOptions = valueArr.map((item) => optionsKeyById[item]);
109
+ const changes = useRef({
110
+ prev: valueArr.map((item) => optionsKeyById[item]?.data || "")
111
+ });
112
+ const handleChange = (v, actionMeta) => {
113
+ if (!isMulti || !Array.isArray(v)) {
114
+ onChange(v ? [v.data] : []);
115
+ } else {
116
+ changes.current.current = v.map((item) => item.data);
117
+ }
118
+ if (["clear", "remove-value"].includes(actionMeta.action) && selectRef.current) {
119
+ setTimeout(() => selectRef?.current?.blur(), 1);
120
+ }
121
+ };
122
+ const handleMenuClose = () => {
123
+ if (changes.current.current) {
124
+ const changed = JSON.stringify(changes.current.prev.map((item) => item.id)) !== JSON.stringify(changes.current.current.map((item) => item.id));
125
+ if (changed) {
126
+ onChange(changes.current.current);
127
+ changes.current.prev = changes.current.current;
128
+ }
129
+ }
130
+ };
131
+ return /* @__PURE__ */ jsx(Box, { ...rest, children: /* @__PURE__ */ jsx(
132
+ Select,
133
+ {
134
+ ref: selectRef,
135
+ defaultValue: selectedOptions,
136
+ options,
137
+ onChange: handleChange,
138
+ components: {
139
+ // @ts-ignore
140
+ MenuList: (props) => /* @__PURE__ */ jsx(LabelMenuList, { ...props, addon }),
141
+ // eslint-disable-line react/no-unstable-nested-components
142
+ ...compact && { ValueContainer }
143
+ },
144
+ placeholder: "Select labels",
145
+ styles: {
146
+ ...compact && compactSelectStyles,
147
+ menu: (css) => ({
148
+ ...css,
149
+ ...editable && { paddingBottom: "36px" },
150
+ zIndex: 99
151
+ }),
152
+ menuList: (css) => ({
153
+ ...css,
154
+ overflowY: "auto",
155
+ maxHeight: `${maxHeight}px`
156
+ })
157
+ },
158
+ theme: (_theme) => ({
159
+ ..._theme,
160
+ colors: {
161
+ ..._theme.colors,
162
+ primary25: "#ddd",
163
+ primary50: "#ddd",
164
+ primary: "#ddd"
165
+ }
166
+ }),
167
+ isSearchable: false,
168
+ isMulti,
169
+ closeMenuOnSelect: !isMulti,
170
+ onMenuClose: handleMenuClose,
171
+ isClearable: true,
172
+ data
173
+ }
174
+ ) });
175
+ }
@@ -1,3 +1,4 @@
1
+ /// <reference types="react" />
1
2
  import { SxProps } from '@mui/system';
2
3
  import { Label } from './types';
3
4
  interface SharedProps {
@@ -12,5 +13,5 @@ export interface LabelTreeProps extends SharedProps {
12
13
  sx?: SxProps;
13
14
  rowHeight?: number;
14
15
  }
15
- export default function LabelTree({ data, selectable, selected, onSelect, rowHeight, renderItem, sx, ...rest }: LabelTreeProps): import("react/jsx-runtime").JSX.Element;
16
+ export default function LabelTree({ data, selectable, selected, onSelect, rowHeight, renderItem, sx, ...rest }: LabelTreeProps): import("react").JSX.Element;
16
17
  export {};
@@ -0,0 +1,124 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { useState, useCallback, useMemo, useRef, createContext, useContext, useEffect } from "react";
3
+ import { ExpandMore as ExpandMoreIcon } from "@mui/icons-material";
4
+ import Box from "@mui/material/Box";
5
+ import { styled } from "@mui/material/styles";
6
+ import { Tree } from "react-arborist";
7
+ import { Icon } from "@iconify/react";
8
+ import LabelRounded from "virtual:icons/material-symbols/label-rounded";
9
+ import CheckSmall from "virtual:icons/material-symbols/check-small";
10
+ const LabelTreeContext = createContext({});
11
+ function LabelTreeProvider({
12
+ selectable = false,
13
+ selected = [],
14
+ onSelect,
15
+ renderItem,
16
+ children
17
+ }) {
18
+ const isSelected = (id) => selected.indexOf(id) !== -1;
19
+ const select = (id) => {
20
+ Array.from(new Set(selected).add(id));
21
+ onSelect?.(id);
22
+ };
23
+ const value = useMemo(
24
+ () => ({
25
+ selectable,
26
+ selected,
27
+ isSelected,
28
+ select,
29
+ renderItem
30
+ }),
31
+ // eslint-disable-next-line react-hooks/exhaustive-deps
32
+ [selected]
33
+ );
34
+ return /* @__PURE__ */ jsx(LabelTreeContext.Provider, { value, children });
35
+ }
36
+ const isLeaf = (node) => {
37
+ return node.isLeaf || !node.data.children?.length;
38
+ };
39
+ function FolderArrow({ node }) {
40
+ if (isLeaf(node)) return /* @__PURE__ */ jsx("span", {});
41
+ return node.isOpen ? /* @__PURE__ */ jsx(ExpandMoreIcon, { style: { fontSize: 20 } }) : /* @__PURE__ */ jsx(ExpandMoreIcon, { style: { fontSize: 20, transform: "rotate(-90deg)" } });
42
+ }
43
+ function Node({ node, style, dragHandle }) {
44
+ const { selectable, select, isSelected, renderItem } = useContext(LabelTreeContext);
45
+ const { data } = node;
46
+ const icon = data.icon ? /* @__PURE__ */ jsx(Icon, { icon: data.icon, style: { fontSize: 18 } }) : /* @__PURE__ */ jsx(LabelRounded, { style: { fontSize: 18, color: data.color || "#ddd" } });
47
+ const handleToggle = (e) => {
48
+ e.stopPropagation();
49
+ if (node.isInternal) {
50
+ node.toggle();
51
+ }
52
+ };
53
+ const handleClick = (e) => {
54
+ e.stopPropagation();
55
+ if (selectable) {
56
+ select(node.id);
57
+ }
58
+ };
59
+ const children = /* @__PURE__ */ jsxs(Fragment, { children: [
60
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", flex: 1 }, children: [
61
+ /* @__PURE__ */ jsx(Box, { sx: { display: "flex", cursor: "pointer" }, onClick: handleToggle, children: /* @__PURE__ */ jsx(FolderArrow, { node }) }),
62
+ /* @__PURE__ */ jsx(Box, { sx: { display: "flex", alignItems: "center", width: 22, height: 22 }, children: icon }),
63
+ /* @__PURE__ */ jsx(Box, { component: "span", sx: { color: "grey.700" }, children: node.data.name })
64
+ ] }),
65
+ selectable && isSelected(node.id) && /* @__PURE__ */ jsx(CheckSmall, {})
66
+ ] });
67
+ return /* @__PURE__ */ jsxs(
68
+ Box,
69
+ {
70
+ className: "label-tree-item",
71
+ style,
72
+ sx: {
73
+ display: "flex",
74
+ alignItems: "center",
75
+ justifyContent: "space-between",
76
+ color: (theme) => theme.palette.mode === "dark" ? "grey.800" : "text.primary"
77
+ },
78
+ ref: dragHandle,
79
+ onClick: handleClick,
80
+ children: [
81
+ !renderItem && children,
82
+ !!renderItem && renderItem(children, node.data)
83
+ ]
84
+ }
85
+ );
86
+ }
87
+ const Root = styled(Box)`
88
+ > div,
89
+ > div > div,
90
+ > div > div > div {
91
+ width: auto !important;
92
+ }
93
+ [role='treeitem'] {
94
+ display: flex;
95
+ align-items: stretch;
96
+ }
97
+ .label-tree-item {
98
+ width: 100%;
99
+ }
100
+ `;
101
+ export default function LabelTree({
102
+ data,
103
+ selectable,
104
+ selected = [],
105
+ onSelect,
106
+ rowHeight = 28,
107
+ renderItem,
108
+ sx,
109
+ ...rest
110
+ }) {
111
+ const tree = useRef(void 0);
112
+ const mergedSx = [...Array.isArray(sx) ? sx : [sx]];
113
+ const [height, setHeight] = useState(0);
114
+ const updateHeight = useCallback(() => {
115
+ setHeight((tree.current?.visibleNodes?.length || 0) * rowHeight);
116
+ }, [rowHeight]);
117
+ useEffect(() => {
118
+ updateHeight();
119
+ }, [data, updateHeight]);
120
+ const handleToggle = () => {
121
+ setTimeout(updateHeight);
122
+ };
123
+ return /* @__PURE__ */ jsx(LabelTreeProvider, { selectable, selected, onSelect, renderItem, children: /* @__PURE__ */ jsx(Root, { ...rest, sx: mergedSx, children: /* @__PURE__ */ jsx(Tree, { data, rowHeight, height, indent: 32, ref: tree, onToggle: handleToggle, children: Node }) }) });
124
+ }
@@ -1,5 +1,5 @@
1
- import { JSX } from 'react';
2
- import { SxProps } from '@mui/material';
1
+ import { type JSX } from 'react';
2
+ import { type SxProps } from '@mui/material';
3
3
  import { Label } from './types';
4
4
  interface LabelsProps {
5
5
  labels: string[] | undefined | null;
@@ -8,5 +8,5 @@ interface LabelsProps {
8
8
  sx?: SxProps;
9
9
  renderLabel?: (label: Label) => JSX.Element;
10
10
  }
11
- export default function Labels({ labels, editable, onChange, sx, renderLabel }: LabelsProps): import("react/jsx-runtime").JSX.Element | null;
11
+ export default function Labels({ labels, editable, onChange, sx, renderLabel }: LabelsProps): JSX.Element | null;
12
12
  export {};
@@ -0,0 +1,82 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { Edit as EditIcon, LabelOutlined as LabelOutlinedIcon } from "@mui/icons-material";
4
+ import {
5
+ Box,
6
+ Button,
7
+ IconButton,
8
+ ClickAwayListener,
9
+ Chip,
10
+ getContrastRatio,
11
+ alpha as muiAlpha
12
+ } from "@mui/material";
13
+ import { useLabelsContext } from "./context.mjs";
14
+ import LabelPicker from "./label-picker.mjs";
15
+ const getContrastTextColor = (bgcolor) => {
16
+ try {
17
+ const ratio = getContrastRatio(bgcolor, "#fff");
18
+ return ratio > 2.7 ? "#fff" : "#111";
19
+ } catch {
20
+ return "#111";
21
+ }
22
+ };
23
+ const getAlphaColor = (color, alpha) => {
24
+ try {
25
+ if (color) {
26
+ return muiAlpha(color, alpha);
27
+ }
28
+ } catch {
29
+ return color;
30
+ }
31
+ return color;
32
+ };
33
+ export default function Labels({ labels, editable, onChange, sx, renderLabel }) {
34
+ const isEmpty = !labels?.length;
35
+ const { labels: allLabels, loading, getLabelsById, getFullLabelName } = useLabelsContext();
36
+ const [editing, setEditing] = useState(false);
37
+ if (loading || !editable && isEmpty) {
38
+ return null;
39
+ }
40
+ const handleOnChange = (v) => {
41
+ onChange?.(v);
42
+ setTimeout(() => {
43
+ setEditing(false);
44
+ }, 300);
45
+ };
46
+ if (editing) {
47
+ return /* @__PURE__ */ jsx(ClickAwayListener, { onClickAway: () => editing && setEditing(false), children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(LabelPicker, { data: allLabels, value: labels || [], onChange: handleOnChange }) }) });
48
+ }
49
+ const labelObjects = getLabelsById(labels || []).filter((x) => x.type !== "system");
50
+ const mergedSx = [
51
+ { display: "flex", gap: 1, alignItems: "center", flexWrap: "wrap" },
52
+ ...Array.isArray(sx) ? sx : [sx]
53
+ ];
54
+ return /* @__PURE__ */ jsxs(Box, { sx: mergedSx, children: [
55
+ labelObjects.map((item) => {
56
+ if (!item) {
57
+ return null;
58
+ }
59
+ if (renderLabel) {
60
+ return renderLabel(item);
61
+ }
62
+ return /* @__PURE__ */ jsx(
63
+ Chip,
64
+ {
65
+ label: getFullLabelName(item),
66
+ variant: "filled",
67
+ size: "small",
68
+ sx: {
69
+ height: 20,
70
+ borderRadius: 1,
71
+ fontSize: 12,
72
+ bgcolor: getAlphaColor(item.color || "#ddd", 0.8),
73
+ color: getContrastTextColor(item.color || "#ddd")
74
+ }
75
+ },
76
+ item.id
77
+ );
78
+ }),
79
+ editable && !isEmpty && /* @__PURE__ */ jsx(IconButton, { color: "inherit", size: "small", onClick: () => setEditing(true), sx: { color: "grey.400" }, children: /* @__PURE__ */ jsx(EditIcon, { sx: { fontSize: 20 } }) }),
80
+ editable && isEmpty && /* @__PURE__ */ jsx(Button, { color: "inherit", variant: "outlined", startIcon: /* @__PURE__ */ jsx(LabelOutlinedIcon, {}), onClick: () => setEditing(true), children: "Edit labels" })
81
+ ] });
82
+ }
File without changes
@@ -0,0 +1,52 @@
1
+ export const flatten = (data) => {
2
+ return data.reduce((acc, cur) => {
3
+ acc.push(cur);
4
+ if (cur.children?.length) {
5
+ acc.push(...flatten(cur.children));
6
+ }
7
+ return acc;
8
+ }, []);
9
+ };
10
+ export const copyTree = (data) => {
11
+ return data.map((item) => {
12
+ if (item.children?.length) {
13
+ item.children = copyTree(item.children);
14
+ }
15
+ return item;
16
+ });
17
+ };
18
+ export const safeParseJSON = (json, defaultValue = null) => {
19
+ try {
20
+ return JSON.parse(json);
21
+ } catch {
22
+ return defaultValue;
23
+ }
24
+ };
25
+ export const transformLabels = (labelDtos) => {
26
+ const relations = labelDtos.reduce((acc, cur) => {
27
+ acc[cur.id] = acc[cur.id] || {};
28
+ if (cur.parentId) {
29
+ acc[cur.id].parent = cur.parentId;
30
+ acc[cur.parentId] = acc[cur.parentId] || {};
31
+ acc[cur.parentId].children = acc[cur.parentId].children || [];
32
+ acc[cur.parentId].children.push(cur.id);
33
+ }
34
+ return acc;
35
+ }, {});
36
+ const labels = labelDtos.map(({ parentId, translation, ...rest }) => ({
37
+ ...rest,
38
+ translation: safeParseJSON(translation),
39
+ children: []
40
+ }));
41
+ const labelsKeyById = labels.reduce((acc, cur) => ({ ...acc, [cur.id]: cur }), {});
42
+ labels.forEach((item) => {
43
+ const relation = relations[item.id];
44
+ if (relation.parent && labelsKeyById[relation.parent]) {
45
+ item.parent = labelsKeyById[relation.parent];
46
+ }
47
+ if (relation.children) {
48
+ item.children = relation.children.map((childId) => labelsKeyById[childId]);
49
+ }
50
+ });
51
+ return labels.filter((item) => !item.parent);
52
+ };
@@ -0,0 +1 @@
1
+ /// <reference path="../../../global.d.ts" />
package/dist/index.mjs ADDED
@@ -0,0 +1,7 @@
1
+ export * from "./components/label/index.mjs";
2
+ export * from "./label2/labels-context.mjs";
3
+ export * from "./label2/github-label-picker.mjs";
4
+ export * from "./label2/labels-input.mjs";
5
+ export * from "./label2/labels2.mjs";
6
+ export { LabelTreeNode } from "./label2/tree.mjs";
7
+ export * from "./types.mjs";
@@ -1,4 +1,5 @@
1
- import { BoxProps } from '@mui/material';
1
+ /// <reference types="react" />
2
+ import { type BoxProps } from '@mui/material';
2
3
  export interface GithubLabelPickerProps {
3
4
  value: string[];
4
5
  onChange: (value: string[]) => void;
@@ -14,4 +15,4 @@ export interface GithubLabelPickerProps {
14
15
  title?: string;
15
16
  disablePortal?: boolean;
16
17
  }
17
- export declare function GithubLabelPicker({ value, onChange, noLabelsText, buttonSx, actions, trigger, multiple, updateImmediately, excludes, disabled, enableAccessControl, disablePortal, }: GithubLabelPickerProps): import("react/jsx-runtime").JSX.Element | null;
18
+ export declare function GithubLabelPicker({ value, onChange, noLabelsText, buttonSx, actions, trigger, multiple, updateImmediately, excludes, disabled, enableAccessControl, disablePortal, }: GithubLabelPickerProps): import("react").JSX.Element | null;