Skip to content
6 changes: 3 additions & 3 deletions playground/entries/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ButtonLinkProps, ButtonProps } from '@semcore/ui/button';
import type { NSButton, NSButtonLink } from '@semcore/ui/button';
import Button, { ButtonLink } from '@semcore/ui/button';
import React from 'react';

Expand All @@ -13,8 +13,8 @@ type AdditionalJSXProps<Component> = {
beforeIcon: boolean;
afterIcon: boolean;
};
type ButtonComponentJSXProps = JSXProps<ButtonProps> & AdditionalJSXProps<'Button'>;
type ButtonLinkComponentJSXProps = JSXProps<ButtonLinkProps> & AdditionalJSXProps<'ButtonLink'>;
type ButtonComponentJSXProps = JSXProps<NSButton.Props> & AdditionalJSXProps<'Button'>;
type ButtonLinkComponentJSXProps = JSXProps<NSButtonLink.Props> & AdditionalJSXProps<'ButtonLink'>;

export type ButtonJSXProps = ButtonComponentJSXProps | ButtonLinkComponentJSXProps;

Expand Down
4 changes: 2 additions & 2 deletions playground/entries/Hint.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import FileExportM from '@semcore/icon/FileExport/m';
import Button from '@semcore/ui/button';
import type { ButtonProps } from '@semcore/ui/button';
import type { NSButton } from '@semcore/ui/button';
import React from 'react';

import type { JSXProps } from '../types/JSXProps';
import type { PlaygroundEntry } from '../types/Playground';
import createGithubLink from '../utils/createGHLink';

export type HintJSXProps = JSXProps<ButtonProps> & Pick<HTMLButtonElement, 'title'>;
export type HintJSXProps = JSXProps<NSButton.Props> & Pick<HTMLButtonElement, 'title'>;

function getJSX({ handleControlChange, ...props }: HintJSXProps) {
return (
Expand Down
4 changes: 2 additions & 2 deletions playground/utils/renderIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import ArrowRightL from '@semcore/icon/ArrowRight/l';
import ArrowRightM from '@semcore/icon/ArrowRight/m';
import CheckL from '@semcore/icon/Check/l';
import CheckM from '@semcore/icon/Check/m';
import type { ButtonProps } from '@semcore/ui/button';
import type { NSButton } from '@semcore/ui/button';
import type { NSText } from '@semcore/ui/typography';
import React from 'react';

Expand Down Expand Up @@ -49,7 +49,7 @@ const SizeToIconMap = {
},
};

const renderIcon = (position: 'before' | 'after', size: NSText.Props['size'] | ButtonProps['size']) => {
const renderIcon = (position: 'before' | 'after', size: NSText.Props['size'] | NSButton.Props['size']) => {
if (!size) return null;

return SizeToIconMap[size][position] ?? null;
Expand Down
4 changes: 2 additions & 2 deletions semcore/add-filter/src/AddFilter.types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { NSFlex } from '@semcore/base-components';
import type { FilterTrigger } from '@semcore/base-trigger';
import type { ButtonLink } from '@semcore/button';
import type { NSButtonLink } from '@semcore/button';
import type { Intergalactic } from '@semcore/core';
import type Dropdown from '@semcore/dropdown';
import type { DropdownTriggerProps } from '@semcore/dropdown';
Expand Down Expand Up @@ -116,7 +116,7 @@ declare namespace NSAddFilter {
}

namespace Clear {
type Component = typeof ButtonLink;
type Component = NSButtonLink.Component;
}

type Component = Intergalactic.Component<typeof Input, NSAddFilter.ItemProps> & {
Expand Down
8 changes: 4 additions & 4 deletions semcore/base-trigger/src/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { NSBox, NSNeighborLocation } from '@semcore/base-components';
import type { ButtonLinkProps, ButtonLink } from '@semcore/button';
import type { NSButtonLink } from '@semcore/button';
import type { Intergalactic } from '@semcore/core';
import type { WithAnimatedSizeEnhanceProps } from '@semcore/core/lib/utils/enhances/animatedSizeEnhance';
import type { NSCounter } from '@semcore/counter';
Expand Down Expand Up @@ -46,7 +46,7 @@ export type ButtonTriggerProps = Omit<BaseTriggerProps, 'theme'> & {
chevron?: boolean;
};

export type LinkTriggerProps = ButtonLinkProps & {
export type LinkTriggerProps = NSButtonLink.Props & {
/** Sets the loading state */
loading?: boolean;
/** Placeholder text */
Expand Down Expand Up @@ -82,8 +82,8 @@ declare const ButtonTrigger: Intergalactic.Component<'div', ButtonTriggerProps>
};

declare const LinkTrigger: Intergalactic.Component<'div', LinkTriggerProps> & {
Text: typeof ButtonLink.Text;
Addon: typeof ButtonLink.Addon;
Text: NSButtonLink.Text.Component;
Addon: NSButtonLink.Addon.Component;
};

declare const FilterTrigger: Intergalactic.Component<'div', FilterTriggerProps> & {
Expand Down
4 changes: 2 additions & 2 deletions semcore/bulk-textarea/src/BulkTextarea.types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { NSBox } from '@semcore/base-components';
import type Button from '@semcore/button';
import type { NSButton } from '@semcore/button';
import type { Intergalactic } from '@semcore/core';
import type { NSCounter } from '@semcore/counter';

Expand Down Expand Up @@ -217,7 +217,7 @@ declare namespace NSBulktextarea {
}

namespace ClearAll {
type Component = typeof Button;
type Component = NSButton.Component;
}

namespace ErrorsNavigation {
Expand Down
40 changes: 20 additions & 20 deletions semcore/button/src/component/Button/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,28 @@
import { NeighborLocation, Box, Hint } from '@semcore/base-components';
import type { Intergalactic } from '@semcore/core';
import { Component, CORE_INSTANCE, createComponent, Root, sstyled } from '@semcore/core';
import addonTextChildren from '@semcore/core/lib/utils/addonTextChildren';
import hasLabels from '@semcore/core/lib/utils/hasLabels';
import logger from '@semcore/core/lib/utils/logger';
import Spin from '@semcore/spin';
import { Text } from '@semcore/typography';
import React from 'react';

import style from './button.shadow.css';
import type { ButtonProps, ButtonAddonProps, ButtonTextProps, ButtonComponent, ButtonDefaultProps } from './Button.type';
import SpinButton from './SpinButton';
import type { NSButton } from './Button.type';
import { BUTTON_SIZE_TO_SPIN_SIZE } from './mappers/BUTTON_SIZE_TO_SPIN_SIZE';
import { BUTTON_USE_TO_DEFAULT_THEME } from './mappers/BUTTON_USE_TO_DEFAULT_THEME';

export const MAP_USE_DEFAULT_THEME: Record<string, string> = {
primary: 'info',
secondary: 'muted',
tertiary: 'info',
};

type State = {
ariaLabelledByContent: null | string;
};
/** @deprecated It will be removed in v19. */
export const MAP_USE_DEFAULT_THEME = BUTTON_USE_TO_DEFAULT_THEME;

export class RootButton extends Component<
ButtonProps,
Intergalactic.InternalTypings.InferComponentProps<NSButton.Component>,
[],
never,
{},
State,
ButtonDefaultProps
NSButton.State,
NSButton.DefaultProps
> {
static displayName = 'Button';
static style = style;
Expand All @@ -37,7 +33,7 @@ export class RootButton extends Component<

containerRef = React.createRef<HTMLButtonElement>();

state: State = {
state: NSButton.State = {
ariaLabelledByContent: null,
};

Expand Down Expand Up @@ -81,7 +77,7 @@ export class RootButton extends Component<
const {
styles,
use,
theme = typeof use === 'string' && MAP_USE_DEFAULT_THEME[use],
theme = typeof use === 'string' && BUTTON_USE_TO_DEFAULT_THEME[use],
loading,
disabled = loading,
size,
Expand Down Expand Up @@ -143,7 +139,11 @@ export class RootButton extends Component<
</SInner>
{loading && (
<SSpin tag='span'>
<SpinButton centered size={size} theme={useTheme} />
<Spin
Comment thread
ilyabrower marked this conversation as resolved.
size={BUTTON_SIZE_TO_SPIN_SIZE[size]}
theme='currentColor'
centered
/>
</SSpin>
)}
</SButton>
Expand All @@ -164,12 +164,12 @@ export class RootButton extends Component<
}
}

function ButtonText(props: ButtonTextProps) {
function ButtonText(props: Intergalactic.InternalTypings.InferChildComponentProps<NSButton.Text.Component, typeof RootButton, 'Text'>) {
const SText = Root;
return sstyled(props.styles)(<SText render={Text} />);
}

function Addon(props: ButtonAddonProps) {
function Addon(props: Intergalactic.InternalTypings.InferChildComponentProps<NSButton.Text.Component, typeof RootButton, 'Addon'>) {
const SAddon = Root;
return sstyled(props.styles)(<SAddon render={Box} tag='span' />);
}
Expand All @@ -180,7 +180,7 @@ function Addon(props: ButtonAddonProps) {
* {@link https://developer.semrush.com/intergalactic/components/button/button-api/|API} | {@link https://developer.semrush.com/intergalactic/components/button/button-code/|Examples}
*/
const Button = createComponent<
ButtonComponent,
NSButton.Component,
typeof RootButton
>(RootButton, {
Text: ButtonText,
Expand Down
117 changes: 72 additions & 45 deletions semcore/button/src/component/Button/Button.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,55 +3,82 @@ import type { Intergalactic, PropGetterFn } from '@semcore/core';
import type { NSText } from '@semcore/typography';
import type React from 'react';

export type ButtonProps = NSBox.Props &
NSNeighborLocation.Detect.Props & {
/** Button activity state */
active?: boolean;
/** Disabled button state */
disabled?: boolean;
/** Loading button state */
loading?: boolean;
/** Tag for the left Addon */
addonLeft?: React.ElementType;
/** Tag for the right Addon */
addonRight?: React.ElementType;
/**
* Placement for hint
* @default top
*/
hintPlacement?: NSHint.Props['placement'];

/** Button size.
* @default `m`
*/
size?: 'l' | 'm';
/** Button usage.
* @default `primary`
*/
use?: 'primary' | 'secondary' | 'tertiary';
/** Button theme.
* @default undefined
*/
theme?: 'info' | 'success' | 'brand' | 'danger' | 'muted' | 'invert';
declare namespace NSButton {
type Size = 'l' | 'm';
type Theme = 'info' | 'success' | 'brand' | 'danger' | 'muted' | 'invert';
type Use = 'primary' | 'secondary' | 'tertiary';
type Props = NSBox.Props &
NSNeighborLocation.Detect.Props & {
/** Button activity state */
active?: boolean;
/** Disabled button state */
disabled?: boolean;
/** Loading button state */
loading?: boolean;
/** Tag for the left Addon */
addonLeft?: React.ElementType;
/** Tag for the right Addon */
addonRight?: React.ElementType;
/**
* Placement for hint
* @default top
*/
hintPlacement?: NSHint.Props['placement'];

/** Button size.
* @default `m`
*/
size?: NSButton.Size;
/** Button usage.
* @default `primary`
*/
use?: 'primary' | 'secondary' | 'tertiary';
/** Button theme.
* @default undefined
*/
theme?: NSButton.Theme;
};
type DefaultProps = {
use: 'secondary';
size: 'm';
};
type State = {
ariaLabelledByContent: null | string;
};
type Ctx = {
getTextProps: PropGetterFn;
getAddonProps: PropGetterFn;
};

export type ButtonDefaultProps = {
use: 'secondary';
size: 'm';
};
namespace Text {
type Props = NSText.Props;

export type ButtonTextProps = NSText.Props;
type Component = Intergalactic.Component<'span', Props>;
}

export type ButtonAddonProps = NSBox.Props;
namespace Addon {
type Props = NSBox.Props;

export type ButtonContext = {
getTextProps: PropGetterFn;
getAddonProps: PropGetterFn;
};
type Component = Intergalactic.Component<'span', Props>;
}

type Component = Intergalactic.Component<'button', Props, Ctx> & {
Text: Text.Component;
Addon: Addon.Component;
};
}

export type ButtonChildren = {
Text: Intergalactic.Component<'span', ButtonTextProps>;
Addon: Intergalactic.Component<'span', ButtonAddonProps>;
};
/** @deprecated It will be removed in v19. */
export type ButtonProps = NSButton.Props;
/** @deprecated It will be removed in v19. */
export type ButtonDefaultProps = NSButton.DefaultProps;
/** @deprecated It will be removed in v19. */
export type ButtonTextProps = NSButton.Text.Props;
/** @deprecated It will be removed in v19. */
export type ButtonAddonProps = NSButton.Addon.Props;
/** @deprecated It will be removed in v19. */
export type ButtonContext = NSButton.Ctx;
/** @deprecated It will be removed in v19. */
export type ButtonComponent = NSButton.Component;

export type ButtonComponent = Intergalactic.Component<'button', ButtonProps, ButtonContext> & ButtonChildren;
export type { NSButton };
19 changes: 0 additions & 19 deletions semcore/button/src/component/Button/SpinButton.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { NSSpin } from '@semcore/spin';

import type { NSButton } from '../Button.type';

export const BUTTON_SIZE_TO_SPIN_SIZE: Record<NSButton.Size, NSSpin.Size> = {
m: 'xs',
l: 's',
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type { NSButton } from '../Button.type';

export const BUTTON_USE_TO_DEFAULT_THEME: Record<NSButton.Use, NSButton.Theme> = {
primary: 'info',
secondary: 'muted',
tertiary: 'info',
};
Loading
Loading