mirror of
https://github.com/Equicord/Equicord.git
synced 2025-06-29 08:24:26 -04:00
Merge remote-tracking branch 'upstream/dev' into dev
This commit is contained in:
commit
593ff3eb02
9 changed files with 98 additions and 97 deletions
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "equicord",
|
"name": "equicord",
|
||||||
"private": "true",
|
"private": "true",
|
||||||
"version": "1.12.3",
|
"version": "1.12.4",
|
||||||
"description": "The other cutest Discord client mod",
|
"description": "The other cutest Discord client mod",
|
||||||
"homepage": "https://github.com/Equicord/Equicord#readme",
|
"homepage": "https://github.com/Equicord/Equicord#readme",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
|
|
|
@ -53,7 +53,8 @@ export default definePlugin({
|
||||||
patches: [{
|
patches: [{
|
||||||
find: "renderConnectionStatus(){",
|
find: "renderConnectionStatus(){",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(renderConnectionStatus\(\){.+\.channel,children:)(.+?}\))(?=}\))/,
|
// in renderConnectionStatus()
|
||||||
|
match: /(lineClamp:1,children:)(\i)(?=,|}\))/,
|
||||||
replace: "$1[$2,$self.renderTimer(this.props.channel.id)]"
|
replace: "$1[$2,$self.renderTimer(this.props.channel.id)]"
|
||||||
}
|
}
|
||||||
}],
|
}],
|
||||||
|
|
|
@ -7,14 +7,13 @@
|
||||||
import { classNameFactory } from "@api/Styles";
|
import { classNameFactory } from "@api/Styles";
|
||||||
import { ErrorCard } from "@components/ErrorCard";
|
import { ErrorCard } from "@components/ErrorCard";
|
||||||
import { Margins } from "@utils/margins";
|
import { Margins } from "@utils/margins";
|
||||||
import { findByCodeLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack";
|
import { findByCodeLazy, findStoreLazy } from "@webpack";
|
||||||
import { Button, Forms, ThemeStore, useStateFromStores } from "@webpack/common";
|
import { Button, ColorPicker, Forms, ThemeStore, useStateFromStores } from "@webpack/common";
|
||||||
|
|
||||||
import { settings } from "..";
|
import { settings } from "..";
|
||||||
import { relativeLuminance } from "../utils/colorUtils";
|
import { relativeLuminance } from "../utils/colorUtils";
|
||||||
import { createOrUpdateThemeColorVars } from "../utils/styleUtils";
|
import { createOrUpdateThemeColorVars } from "../utils/styleUtils";
|
||||||
|
|
||||||
const ColorPicker = findComponentByCodeLazy(".BACKGROUND_ACCENT.css");
|
|
||||||
const saveClientTheme = findByCodeLazy('type:"UNSYNCED_USER_SETTINGS_UPDATE', '"system"===');
|
const saveClientTheme = findByCodeLazy('type:"UNSYNCED_USER_SETTINGS_UPDATE', '"system"===');
|
||||||
const NitroThemeStore = findStoreLazy("ClientThemesBackgroundStore");
|
const NitroThemeStore = findStoreLazy("ClientThemesBackgroundStore");
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ import { getCurrentGuild, getEmojiURL } from "@utils/discord";
|
||||||
import { Logger } from "@utils/Logger";
|
import { Logger } from "@utils/Logger";
|
||||||
import definePlugin, { OptionType, Patch } from "@utils/types";
|
import definePlugin, { OptionType, Patch } from "@utils/types";
|
||||||
import { findByCodeLazy, findByPropsLazy, findStoreLazy, proxyLazyWebpack } from "@webpack";
|
import { findByCodeLazy, findByPropsLazy, findStoreLazy, proxyLazyWebpack } from "@webpack";
|
||||||
import { Alerts, ChannelStore, DraftType, EmojiStore, FluxDispatcher, Forms, GuildMemberStore, lodash, Parser, PermissionsBits, PermissionStore, StickersStore, UploadHandler, UserSettingsActionCreators, UserStore } from "@webpack/common";
|
import { Alerts, ChannelStore, DraftType, EmojiStore, FluxDispatcher, Forms, GuildMemberStore, lodash, Parser, PermissionsBits, PermissionStore, StickerStore, UploadHandler, UserSettingsActionCreators, UserStore } from "@webpack/common";
|
||||||
import type { Emoji } from "@webpack/types";
|
import type { Emoji } from "@webpack/types";
|
||||||
import type { Message } from "discord-types/general";
|
import type { Message } from "discord-types/general";
|
||||||
import { applyPalette, GIFEncoder, quantize } from "gifenc";
|
import { applyPalette, GIFEncoder, quantize } from "gifenc";
|
||||||
|
@ -552,8 +552,8 @@ export default definePlugin({
|
||||||
|
|
||||||
const gifMatch = child.props.href.match(fakeNitroGifStickerRegex);
|
const gifMatch = child.props.href.match(fakeNitroGifStickerRegex);
|
||||||
if (gifMatch) {
|
if (gifMatch) {
|
||||||
// There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickersStore contains the id of the fake sticker
|
// There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickerStore contains the id of the fake sticker
|
||||||
if (StickersStore.getStickerById(gifMatch[1])) return null;
|
if (StickerStore.getStickerById(gifMatch[1])) return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -641,7 +641,7 @@ export default definePlugin({
|
||||||
url = new URL(item);
|
url = new URL(item);
|
||||||
} catch { }
|
} catch { }
|
||||||
|
|
||||||
const stickerName = StickersStore.getStickerById(imgMatch[1])?.name ?? url?.searchParams.get("name") ?? "FakeNitroSticker";
|
const stickerName = StickerStore.getStickerById(imgMatch[1])?.name ?? url?.searchParams.get("name") ?? "FakeNitroSticker";
|
||||||
stickers.push({
|
stickers.push({
|
||||||
format_type: 1,
|
format_type: 1,
|
||||||
id: imgMatch[1],
|
id: imgMatch[1],
|
||||||
|
@ -654,9 +654,9 @@ export default definePlugin({
|
||||||
|
|
||||||
const gifMatch = item.match(fakeNitroGifStickerRegex);
|
const gifMatch = item.match(fakeNitroGifStickerRegex);
|
||||||
if (gifMatch) {
|
if (gifMatch) {
|
||||||
if (!StickersStore.getStickerById(gifMatch[1])) continue;
|
if (!StickerStore.getStickerById(gifMatch[1])) continue;
|
||||||
|
|
||||||
const stickerName = StickersStore.getStickerById(gifMatch[1])?.name ?? "FakeNitroSticker";
|
const stickerName = StickerStore.getStickerById(gifMatch[1])?.name ?? "FakeNitroSticker";
|
||||||
stickers.push({
|
stickers.push({
|
||||||
format_type: 2,
|
format_type: 2,
|
||||||
id: gifMatch[1],
|
id: gifMatch[1],
|
||||||
|
@ -670,32 +670,38 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
|
|
||||||
shouldIgnoreEmbed(embed: Message["embeds"][number], message: Message) {
|
shouldIgnoreEmbed(embed: Message["embeds"][number], message: Message) {
|
||||||
const contentItems = message.content.split(/\s/);
|
try {
|
||||||
if (contentItems.length > 1 && !settings.store.transformCompoundSentence) return false;
|
const contentItems = message.content.split(/\s/);
|
||||||
|
if (contentItems.length > 1 && !settings.store.transformCompoundSentence) return false;
|
||||||
|
|
||||||
switch (embed.type) {
|
switch (embed.type) {
|
||||||
case "image": {
|
case "image": {
|
||||||
if (
|
const url = embed.url ?? embed.image?.url;
|
||||||
!settings.store.transformCompoundSentence
|
if (!url) return false;
|
||||||
&& !contentItems.some(item => item === embed.url! || item.match(hyperLinkRegex)?.[1] === embed.url!)
|
if (
|
||||||
) return false;
|
!settings.store.transformCompoundSentence
|
||||||
|
&& !contentItems.some(item => item === url || item.match(hyperLinkRegex)?.[1] === url)
|
||||||
|
) return false;
|
||||||
|
|
||||||
if (settings.store.transformEmojis) {
|
if (settings.store.transformEmojis) {
|
||||||
if (fakeNitroEmojiRegex.test(embed.url!)) return true;
|
if (fakeNitroEmojiRegex.test(url)) return true;
|
||||||
}
|
|
||||||
|
|
||||||
if (settings.store.transformStickers) {
|
|
||||||
if (fakeNitroStickerRegex.test(embed.url!)) return true;
|
|
||||||
|
|
||||||
const gifMatch = embed.url!.match(fakeNitroGifStickerRegex);
|
|
||||||
if (gifMatch) {
|
|
||||||
// There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickersStore contains the id of the fake sticker
|
|
||||||
if (StickersStore.getStickerById(gifMatch[1])) return true;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
if (settings.store.transformStickers) {
|
||||||
|
if (fakeNitroStickerRegex.test(url)) return true;
|
||||||
|
|
||||||
|
const gifMatch = url.match(fakeNitroGifStickerRegex);
|
||||||
|
if (gifMatch) {
|
||||||
|
// There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickerStore contains the id of the fake sticker
|
||||||
|
if (StickerStore.getStickerById(gifMatch[1])) return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
new Logger("FakeNitro").error("Error in shouldIgnoreEmbed:", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -707,8 +713,8 @@ export default definePlugin({
|
||||||
|
|
||||||
const match = attachment.url.match(fakeNitroGifStickerRegex);
|
const match = attachment.url.match(fakeNitroGifStickerRegex);
|
||||||
if (match) {
|
if (match) {
|
||||||
// There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickersStore contains the id of the fake sticker
|
// There is no way to differentiate a regular gif attachment from a fake nitro animated sticker, so we check if the StickerStore contains the id of the fake sticker
|
||||||
if (StickersStore.getStickerById(match[1])) return false;
|
if (StickerStore.getStickerById(match[1])) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -864,7 +870,7 @@ export default definePlugin({
|
||||||
if (!s.enableStickerBypass)
|
if (!s.enableStickerBypass)
|
||||||
break stickerBypass;
|
break stickerBypass;
|
||||||
|
|
||||||
const sticker = StickersStore.getStickerById(extra.stickers?.[0]!);
|
const sticker = StickerStore.getStickerById(extra.stickers?.[0]!);
|
||||||
if (!sticker)
|
if (!sticker)
|
||||||
break stickerBypass;
|
break stickerBypass;
|
||||||
|
|
||||||
|
|
|
@ -24,10 +24,9 @@ import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { Margins } from "@utils/margins";
|
import { Margins } from "@utils/margins";
|
||||||
import { classes, copyWithToast } from "@utils/misc";
|
import { classes, copyWithToast } from "@utils/misc";
|
||||||
import { useAwaiter } from "@utils/react";
|
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { extractAndLoadChunksLazy, findComponentByCodeLazy } from "@webpack";
|
import { findComponentByCodeLazy } from "@webpack";
|
||||||
import { Button, Flex, Forms, React, Text, UserProfileStore, UserStore, useState } from "@webpack/common";
|
import { Button, ColorPicker, Flex, Forms, React, Text, UserProfileStore, UserStore, useState } from "@webpack/common";
|
||||||
import { User } from "discord-types/general";
|
import { User } from "discord-types/general";
|
||||||
import { ReactElement } from "react";
|
import { ReactElement } from "react";
|
||||||
import virtualMerge from "virtual-merge";
|
import virtualMerge from "virtual-merge";
|
||||||
|
@ -109,10 +108,8 @@ interface ProfileModalProps {
|
||||||
isTryItOutFlow: boolean;
|
isTryItOutFlow: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ColorPicker = findComponentByCodeLazy<ColorPickerProps>(".BACKGROUND_ACCENT.css");
|
|
||||||
const ProfileModal = findComponentByCodeLazy<ProfileModalProps>("isTryItOutFlow:", "pendingThemeColors:", "pendingAvatarDecoration:", "EDIT_PROFILE_BANNER");
|
const ProfileModal = findComponentByCodeLazy<ProfileModalProps>("isTryItOutFlow:", "pendingThemeColors:", "pendingAvatarDecoration:", "EDIT_PROFILE_BANNER");
|
||||||
|
|
||||||
const requireColorPicker = extractAndLoadChunksLazy(["#{intl::USER_SETTINGS_PROFILE_COLOR_DEFAULT_BUTTON}"], /createPromise:\(\)=>\i\.\i(\("?.+?"?\)).then\(\i\.bind\(\i,"?(.+?)"?\)\)/);
|
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "FakeProfileThemes",
|
name: "FakeProfileThemes",
|
||||||
|
@ -141,8 +138,6 @@ export default definePlugin({
|
||||||
const [color1, setColor1] = useState(existingColors[0]);
|
const [color1, setColor1] = useState(existingColors[0]);
|
||||||
const [color2, setColor2] = useState(existingColors[1]);
|
const [color2, setColor2] = useState(existingColors[1]);
|
||||||
|
|
||||||
const [, , loadingColorPickerChunk] = useAwaiter(requireColorPicker);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Forms.FormSection>
|
<Forms.FormSection>
|
||||||
<Forms.FormTitle tag="h3">Usage</Forms.FormTitle>
|
<Forms.FormTitle tag="h3">Usage</Forms.FormTitle>
|
||||||
|
@ -162,51 +157,49 @@ export default definePlugin({
|
||||||
className={classes(Margins.top8, Margins.bottom8)}
|
className={classes(Margins.top8, Margins.bottom8)}
|
||||||
/>
|
/>
|
||||||
<Forms.FormTitle tag="h3">Color pickers</Forms.FormTitle>
|
<Forms.FormTitle tag="h3">Color pickers</Forms.FormTitle>
|
||||||
{!loadingColorPickerChunk && (
|
<Flex
|
||||||
<Flex
|
direction={Flex.Direction.HORIZONTAL}
|
||||||
direction={Flex.Direction.HORIZONTAL}
|
style={{ gap: "1rem" }}
|
||||||
style={{ gap: "1rem" }}
|
>
|
||||||
|
<ColorPicker
|
||||||
|
color={color1}
|
||||||
|
label={
|
||||||
|
<Text
|
||||||
|
variant={"text-xs/normal"}
|
||||||
|
style={{ marginTop: "4px" }}
|
||||||
|
>
|
||||||
|
Primary
|
||||||
|
</Text>
|
||||||
|
}
|
||||||
|
onChange={(color: number) => {
|
||||||
|
setColor1(color);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ColorPicker
|
||||||
|
color={color2}
|
||||||
|
label={
|
||||||
|
<Text
|
||||||
|
variant={"text-xs/normal"}
|
||||||
|
style={{ marginTop: "4px" }}
|
||||||
|
>
|
||||||
|
Accent
|
||||||
|
</Text>
|
||||||
|
}
|
||||||
|
onChange={(color: number) => {
|
||||||
|
setColor2(color);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
const colorString = encode(color1, color2);
|
||||||
|
copyWithToast(colorString);
|
||||||
|
}}
|
||||||
|
color={Button.Colors.PRIMARY}
|
||||||
|
size={Button.Sizes.XLARGE}
|
||||||
>
|
>
|
||||||
<ColorPicker
|
Copy 3y3
|
||||||
color={color1}
|
</Button>
|
||||||
label={
|
</Flex>
|
||||||
<Text
|
|
||||||
variant={"text-xs/normal"}
|
|
||||||
style={{ marginTop: "4px" }}
|
|
||||||
>
|
|
||||||
Primary
|
|
||||||
</Text>
|
|
||||||
}
|
|
||||||
onChange={(color: number) => {
|
|
||||||
setColor1(color);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<ColorPicker
|
|
||||||
color={color2}
|
|
||||||
label={
|
|
||||||
<Text
|
|
||||||
variant={"text-xs/normal"}
|
|
||||||
style={{ marginTop: "4px" }}
|
|
||||||
>
|
|
||||||
Accent
|
|
||||||
</Text>
|
|
||||||
}
|
|
||||||
onChange={(color: number) => {
|
|
||||||
setColor2(color);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
onClick={() => {
|
|
||||||
const colorString = encode(color1, color2);
|
|
||||||
copyWithToast(colorString);
|
|
||||||
}}
|
|
||||||
color={Button.Colors.PRIMARY}
|
|
||||||
size={Button.Sizes.XLARGE}
|
|
||||||
>
|
|
||||||
Copy 3y3
|
|
||||||
</Button>
|
|
||||||
</Flex>
|
|
||||||
)}
|
|
||||||
<Forms.FormDivider
|
<Forms.FormDivider
|
||||||
className={classes(Margins.top8, Margins.bottom8)}
|
className={classes(Margins.top8, Margins.bottom8)}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -7,18 +7,11 @@
|
||||||
import { classNameFactory } from "@api/Styles";
|
import { classNameFactory } from "@api/Styles";
|
||||||
import { ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, openModalLazy } from "@utils/modal";
|
import { ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, openModalLazy } from "@utils/modal";
|
||||||
import { extractAndLoadChunksLazy, findComponentByCodeLazy } from "@webpack";
|
import { extractAndLoadChunksLazy, findComponentByCodeLazy } from "@webpack";
|
||||||
import { Button, Forms, Text, TextInput, Toasts, useMemo, useState } from "@webpack/common";
|
import { Button, ColorPicker, Forms, Text, TextInput, Toasts, useMemo, useState } from "@webpack/common";
|
||||||
|
|
||||||
import { DEFAULT_COLOR, SWATCHES } from "../constants";
|
import { DEFAULT_COLOR, SWATCHES } from "../constants";
|
||||||
import { categoryLen, createCategory, getCategory } from "../data";
|
import { categoryLen, createCategory, getCategory } from "../data";
|
||||||
|
|
||||||
interface ColorPickerProps {
|
|
||||||
color: number | null;
|
|
||||||
showEyeDropper?: boolean;
|
|
||||||
suggestedColors?: string[];
|
|
||||||
onChange(value: number | null): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ColorPickerWithSwatchesProps {
|
interface ColorPickerWithSwatchesProps {
|
||||||
defaultColor: number;
|
defaultColor: number;
|
||||||
colors: number[];
|
colors: number[];
|
||||||
|
@ -29,7 +22,6 @@ interface ColorPickerWithSwatchesProps {
|
||||||
renderCustomButton?: () => React.ReactNode;
|
renderCustomButton?: () => React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ColorPicker = findComponentByCodeLazy<ColorPickerProps>(".BACKGROUND_ACCENT.css");
|
|
||||||
const ColorPickerWithSwatches = findComponentByCodeLazy<ColorPickerWithSwatchesProps>('id:"color-picker"');
|
const ColorPickerWithSwatches = findComponentByCodeLazy<ColorPickerWithSwatchesProps>('id:"color-picker"');
|
||||||
|
|
||||||
export const requireSettingsMenu = extractAndLoadChunksLazy(['name:"UserSettings"'], /createPromise:.{0,20}(\i\.\i\("?.+?"?\).*?).then\(\i\.bind\(\i,"?(.+?)"?\)\).{0,50}"UserSettings"/);
|
export const requireSettingsMenu = extractAndLoadChunksLazy(['name:"UserSettings"'], /createPromise:.{0,20}(\i\.\i\("?.+?"?\).*?).then\(\i\.bind\(\i,"?(.+?)"?\)\).{0,50}"UserSettings"/);
|
||||||
|
|
|
@ -178,7 +178,7 @@ export default definePlugin({
|
||||||
// Theads
|
// Theads
|
||||||
{
|
{
|
||||||
// This is the thread "spine" that shows in the left
|
// This is the thread "spine" that shows in the left
|
||||||
find: "spineWithGuildIcon]:",
|
find: "M0 15H2c0 1.6569",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /mentionsCount:\i.+?null(?<=channel:(\i).+?)/,
|
match: /mentionsCount:\i.+?null(?<=channel:(\i).+?)/,
|
||||||
replace: "$&,$self.TypingIndicator($1.id,$1.getGuildId())"
|
replace: "$&,$self.TypingIndicator($1.id,$1.getGuildId())"
|
||||||
|
|
|
@ -65,6 +65,9 @@ export const Paginator = waitForComponent<t.Paginator>("Paginator", filters.comp
|
||||||
export const Clickable = waitForComponent<t.Clickable>("Clickable", filters.componentByCode("this.context?this.renderNonInteractive():"));
|
export const Clickable = waitForComponent<t.Clickable>("Clickable", filters.componentByCode("this.context?this.renderNonInteractive():"));
|
||||||
export const Avatar = waitForComponent<t.Avatar>("Avatar", filters.componentByCode(".size-1.375*"));
|
export const Avatar = waitForComponent<t.Avatar>("Avatar", filters.componentByCode(".size-1.375*"));
|
||||||
|
|
||||||
|
export const ColorPicker = waitForComponent<t.ColorPicker>("ColorPicker", filters.componentByCode("#{intl::USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR}", "showEyeDropper"));
|
||||||
|
|
||||||
|
|
||||||
export let createScroller: (scrollbarClassName: string, fadeClassName: string, customThemeClassName: string) => t.ScrollerThin;
|
export let createScroller: (scrollbarClassName: string, fadeClassName: string, customThemeClassName: string) => t.ScrollerThin;
|
||||||
export let scrollerClasses: Record<string, string>;
|
export let scrollerClasses: Record<string, string>;
|
||||||
waitFor(filters.byCode('="ltr",orientation:', "customTheme:", "forwardRef"), m => createScroller = m);
|
waitFor(filters.byCode('="ltr",orientation:', "customTheme:", "forwardRef"), m => createScroller = m);
|
||||||
|
|
7
src/webpack/common/types/components.d.ts
vendored
7
src/webpack/common/types/components.d.ts
vendored
|
@ -544,3 +544,10 @@ export type Icon = ComponentType<JSX.IntrinsicElements["svg"] & {
|
||||||
colorClass?: string;
|
colorClass?: string;
|
||||||
} & Record<string, any>>;
|
} & Record<string, any>>;
|
||||||
|
|
||||||
|
export type ColorPicker = ComponentType<{
|
||||||
|
color: number | null;
|
||||||
|
showEyeDropper?: boolean;
|
||||||
|
suggestedColors?: string[];
|
||||||
|
label?: ReactNode;
|
||||||
|
onChange(value: number | null): void;
|
||||||
|
}>;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue