Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions semcore/fullscreen-modal/src/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { Flex, Box, BoxProps } from '@semcore/base-components';
import type Button from '@semcore/button';
import type { PropGetterFn, Intergalactic } from '@semcore/core';
import type { ModalProps } from '@semcore/modal';
import type { NSModal } from '@semcore/modal';
import type { Text } from '@semcore/typography';

export type FullscreenModalProps = ModalProps & {
export type FullscreenModalProps = NSModal.Props & {
/** Function that is invoked when hiding a component */
onClose?: (
trigger: 'onBackClick' | 'onCloseClick' | 'onEscape' | 'onOutsideClick',
Expand Down
2 changes: 1 addition & 1 deletion semcore/modal/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"author": "UI-kit team <ui-kit-team@semrush.com>",
"license": "MIT",
"scripts": {
"build": "pnpm semcore-builder --source=js && pnpm vite build"
"build": "pnpm semcore-builder && pnpm vite build"
},
"exports": {
"types": "./lib/types/index.d.ts",
Expand Down
50 changes: 37 additions & 13 deletions semcore/modal/src/Modal.jsx → semcore/modal/src/Modal.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { FadeInOut, Slide, Flex, OutsideClick, Portal, PortalProvider } from '@semcore/base-components';
import Button from '@semcore/button';
import type { Intergalactic } from '@semcore/core';
import { createComponent, Component, sstyled, Root } from '@semcore/core';
import type { WithI18nEnhanceProps } from '@semcore/core/lib/utils/enhances/i18nEnhance';
import i18nEnhance from '@semcore/core/lib/utils/enhances/i18nEnhance';
import { isAdvanceMode } from '@semcore/core/lib/utils/findComponent';
import fire from '@semcore/core/lib/utils/fire';
Expand All @@ -18,10 +20,18 @@ import CloseIcon from '@semcore/icon/Close/l';
import { Text } from '@semcore/typography';
import React from 'react';

import type { NSModal } from './Modal.type';
import style from './style/modal.shadow.css';
import { localizedMessages } from './translations/__intergalactic-dynamic-locales';

class ModalRoot extends Component {
class ModalRoot extends Component<
Intergalactic.InternalTypings.InferComponentProps<NSModal.Component>,
typeof ModalRoot.enhance,
{},
WithI18nEnhanceProps,
NSModal.State,
NSModal.DefaultProps
> {
static displayName = 'Modal';
static style = style;
static enhance = [
Expand All @@ -30,34 +40,37 @@ class ModalRoot extends Component {
cssVariableEnhance({
variable: '--intergalactic-duration-modal',
fallback: '200',
// TODO: Types are incompatible. For some reason string type isn't recognized as a valid value.
// Leave it with ts-ignore annotation.
// @ts-ignore
map: Number.parseInt,
prop: 'duration',
}),
];
] as const;

static defaultProps = {
closable: true,
i18n: localizedMessages,
locale: 'en',
disablePreventScroll: false,
};
} as const;

windowRef = React.createRef();
windowRef = React.createRef<HTMLDivElement>();

state = { hasTitle: false };
state: NSModal.State = { hasTitle: false };

handleKeyDown = (e) => {
handleKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
if (e.key === 'Escape') {
e.stopPropagation();
fire(this, 'onClose', 'onEscape', e);
}
};

handleIconCloseClick = (e) => {
handleIconCloseClick = (e: React.MouseEvent) => {
fire(this, 'onClose', 'onCloseClick', e);
};

handleOutsideClick = (e) => {
handleOutsideClick = (e?: React.SyntheticEvent) => {
fire(this, 'onClose', 'onOutsideClick', e);

// Keep focus on modal if overlay clicks don't close the modal.
Expand Down Expand Up @@ -136,7 +149,9 @@ class ModalRoot extends Component {
}
}

function Window(props) {
function Window(
props: Intergalactic.InternalTypings.InferChildComponentProps<NSModal.Window.Component, typeof ModalRoot, 'Window'>,
) {
const SWindow = Root;
const { Children, styles, visible, closable, duration } = props;
const windowRef = React.useRef(null);
Expand Down Expand Up @@ -165,7 +180,9 @@ function Window(props) {
);
}

function Overlay(props) {
function Overlay(
props: Intergalactic.InternalTypings.InferChildComponentProps<NSModal.Overlay.Component, typeof ModalRoot, 'Overlay'>,
) {
const SOverlay = Root;
const SOverlayContentWrapper = Flex;
const { Children, styles, onOutsideClick, visible } = props;
Expand All @@ -186,7 +203,9 @@ function Overlay(props) {
);
}

function Close(props) {
function Close(
props: Intergalactic.InternalTypings.InferChildComponentProps<NSModal.Close.Component, typeof ModalRoot, 'Close'>,
) {
const SClose = Root;
const { Children, children: hasChildren, getI18nText, ghost } = props;
return sstyled(props.styles)(
Expand All @@ -210,7 +229,9 @@ function Close(props) {
);
}

function Title(props) {
function Title(
props: Intergalactic.InternalTypings.InferChildComponentProps<NSModal.Title.Component, typeof ModalRoot, 'Title'>,
) {
const { setHasTitle, styles, color } = props;
const STitle = Root;

Expand All @@ -225,7 +246,10 @@ function Title(props) {
*
* {@link https://developer.semrush.com/intergalactic/components/modal/modal-api/|API} | {@link https://developer.semrush.com/intergalactic/components/modal/modal-code/|Examples}
*/
const Modal = createComponent(ModalRoot, {
const Modal = createComponent<
NSModal.Component,
typeof ModalRoot
>(ModalRoot, {
Window,
Overlay,
Close,
Expand Down
93 changes: 93 additions & 0 deletions semcore/modal/src/Modal.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import type { FadeInOutProps, SlideProps, Box, BoxProps, PortalProps } from '@semcore/base-components';
import type Button from '@semcore/button';
import type { PropGetterFn, Intergalactic } from '@semcore/core';
import type { NSText } from '@semcore/typography';
import type React from 'react';

import type { LocalizedMessages } from './translations/__intergalactic-dynamic-locales';

declare namespace NSModal {
type Props = PortalProps &
BoxProps &
FadeInOutProps & {
/** Duration of animation, ms
* @default 200
*/
duration?: number;
/** This property is responsible for the visibility of the modal window */
visible?: boolean;
/** Function called when the component is hidden */
onClose?: (
trigger: 'onOutsideClick' | 'onCloseClick' | 'onEscape',
e?: React.MouseEvent | React.KeyboardEvent,
) => void;
/** Displaying the close button(x) in the upper-right corner of the modal dialog
* @default true
* */
closable?: boolean;
/**
* Setting `true` disables mechanism that hides document body scrollbar when Modal is visible
* @default false
*/
disablePreventScroll?: boolean;
/** Specifies the locale for i18n support */
locale?: string;
/**
* Props for render modal without background and paddings. Useful in carousel for example
*/
ghost?: boolean;
/** Force advanced mode */
/** @deprecated */
forcedAdvancedMode?: boolean;
};
type DefaultProps = {
closable: true;
i18n: LocalizedMessages;
locale: 'en';
disablePreventScroll: false;
};
type Ctx = {
getOverlayProps: PropGetterFn;
getWindowProps: PropGetterFn;
getCloseProps: PropGetterFn;
};
type State = {
hasTitle: boolean;
};

namespace Window {
type Props = BoxProps & SlideProps;

type Component = Intergalactic.Component<'div', Props>;
}

namespace Overlay {
type Component = typeof Box;
}

namespace Close {
type Component = typeof Button;
}

namespace Title {
type Props = NSText.Props;

type Component = Intergalactic.Component<'div', Props>;
}

type Component = Intergalactic.Component<'div', Props, Ctx> & {
Window: Window.Component;
Overlay: Overlay.Component;
Close: Close.Component;
Title: Title.Component;
};
}

/** @deprecated It will be removed in v18. */
export type ModalProps = NSModal.Props;
/** @deprecated It will be removed in v18. */
export type WindowProps = NSModal.Window.Props;
/** @deprecated It will be removed in v18. */
export type ModalContext = NSModal.Ctx;

export type { NSModal };
53 changes: 0 additions & 53 deletions semcore/modal/src/index.d.ts

This file was deleted.

1 change: 1 addition & 0 deletions semcore/modal/src/index.js → semcore/modal/src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { default } from './Modal';
export * from './Modal.type';
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@ export const localizedMessages = {
pl,
sv,
};

export type LocalizedMessages = typeof localizedMessages;
2 changes: 1 addition & 1 deletion semcore/modal/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default mergeConfig(
defineConfig({
build: {
lib: {
entry: './src/index.js',
entry: './src/index.ts',
},
rollupOptions: {
external: ['react', 'react-dom', 'react/jsx-runtime', /@babel\/runtime\/*/, /@semcore\/*/],
Expand Down
4 changes: 2 additions & 2 deletions semcore/wizard/src/Wizard.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import type { BoxProps } from '@semcore/base-components';
import type { ButtonProps } from '@semcore/button';
import type { Intergalactic } from '@semcore/core';
import type { useI18n } from '@semcore/core/lib/utils/enhances/WithI18n';
import type { ModalProps } from '@semcore/modal';
import type { NSModal } from '@semcore/modal';
import type { Text, NSText } from '@semcore/typography';
import type React from 'react';

/** Ordered step position from 0 */
export type WizardStep = number;

export type WizardProps = ModalProps & {
export type WizardProps = NSModal.Props & {
/**
* Active step value
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Button from '@semcore/ui/button';
import type { ModalProps } from '@semcore/ui/modal';
import type { NSModal } from '@semcore/ui/modal';
import Modal from '@semcore/ui/modal';
import type { ReactNode } from 'react';
import React, { useState, useCallback } from 'react';
Expand All @@ -15,14 +15,14 @@ export default function Demo() {
);
}

type GoalSurveyModalProps = ModalProps & {
type GoalSurveyModalProps = NSModal.Props & {
children?: ReactNode;
};

export const GoalSurveyModal = (props: GoalSurveyModalProps) => {
const { children, onClose, ...modalProps } = props;

const handleClose = useCallback<NonNullable<ModalProps['onClose']>>(
const handleClose = useCallback<NonNullable<NSModal.Props['onClose']>>(
(trigger, e) => {
if (trigger !== 'onOutsideClick') {
return onClose?.(trigger, e);
Expand Down
4 changes: 2 additions & 2 deletions stories/components/modal/tests/examples/basic_usage.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import Button from '@semcore/ui/button';
import Modal from '@semcore/ui/modal';
import type { ModalProps } from '@semcore/ui/modal';
import type { NSModal } from '@semcore/ui/modal';
import { Text } from '@semcore/ui/typography';
import React from 'react';

type BasicModalProps = ModalProps & {
type BasicModalProps = NSModal.Props & {
title?: string;
content?: string;
showCloseButton?: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import Button from '@semcore/ui/button';
import { DataTable, type DataTableProps } from '@semcore/ui/data-table';
import Link from '@semcore/ui/link';
import Modal from '@semcore/ui/modal';
import type { ModalProps } from '@semcore/ui/modal';
import type { NSModal } from '@semcore/ui/modal';
import Tag from '@semcore/ui/tag';
import Tooltip from '@semcore/ui/tooltip';
import { Text } from '@semcore/ui/typography';
import React from 'react';

type BasicModalProps = ModalProps & {
type BasicModalProps = NSModal.Props & {
title?: string;
content?: string;
showCloseButton?: boolean;
Expand Down
Loading
Loading