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
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions semcore/notice/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"@semcore/core": "workspace:*",
"@semcore/base-components": "workspace:*",
"@semcore/icon": "workspace:*",
"@semcore/illustration": "workspace:*",
"@semcore/testing-utils": "workspace:*"
}
}
9 changes: 8 additions & 1 deletion semcore/notice/src/Notice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@ class RootNotice extends Component<

render() {
const SNotice = Root;
const { Children, styles, hidden, theme, resolveColor, getI18nText } = this.asProps;
const SIcon = Box;
const SIllustration = Box;
const { Children, styles, hidden, theme, resolveColor, getI18nText, icon, illustration } = this.asProps;
const color = resolveColor(theme);
const useTheme = isCustomTheme(theme) ? 'custom' : theme;

Expand All @@ -115,6 +117,11 @@ class RootNotice extends Component<
aria-label={ariaLabel}
ref={this.ref}
>
{icon !== undefined && (
// @ts-expect-error we use theme in css-only
<SIcon theme={useTheme}>{icon}</SIcon>
)}
{illustration !== undefined && (<SIllustration>{illustration}</SIllustration>)}
<Children />
</SNotice>,
);
Expand Down
17 changes: 13 additions & 4 deletions semcore/notice/src/Notice.type.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import type { NSAnimation, NSBox } from '@semcore/base-components';
import type { NSButton } from '@semcore/button';
import type { PropGetterFn, Intergalactic } from '@semcore/core';
import type { Text } from '@semcore/typography';
import type Icon from '@semcore/icon';
import type { IllustrationProps } from '@semcore/illustration';
import type { NSText } from '@semcore/typography';

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

Expand All @@ -22,7 +24,11 @@ declare namespace NSNotice {
duration?: number;
/** Specifies the locale for i18n support */
locale?: string;
};
} & ({
icon?: typeof Icon;
} | {
illustration?: React.ElementType<IllustrationProps>;
});
type DefaultProps = {
theme: 'info';
i18n: LocalizedMessaged;
Expand All @@ -49,18 +55,21 @@ declare namespace NSNotice {
}

namespace Title {
type Component = typeof Text;
type Component = NSText.Component;
}

namespace Text {
type Component = typeof Text;
type Component = NSText.Component;
}

namespace Close {
type Component = NSButton.Component;
}

type Component = Intergalactic.Component<'div', Props, Ctx> & {
/**
* @deprecated. Use icon or illustration props instead.
*/
Label: Label.Component;
Actions: Actions.Component;
Content: Content.Component;
Expand Down
16 changes: 11 additions & 5 deletions semcore/notice/src/NoticeSmart.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { Box } from '@semcore/base-components';
import type { Intergalactic } from '@semcore/core';
import { createComponent, Component, Root } from '@semcore/core';
import { sstyled, createComponent, Component, Root } from '@semcore/core';
import isNode from '@semcore/core/lib/utils/isNode';
import React from 'react';

import Notice from './Notice';
import type { NSNoticeSmart } from './NoticeSmart.type';
import style from './style/notice.shadow.css';

class NoticeSmart extends Component<
Intergalactic.InternalTypings.InferComponentProps<NSNoticeSmart.Component>,
Expand All @@ -15,25 +17,29 @@ class NoticeSmart extends Component<
NSNoticeSmart.DefaultProps
> {
static displayName = 'NoticeSmart';

static style = style;
static defaultProps = {
theme: 'info',
} as const;

render() {
const SNoticeSmart = Root;
const { label, title, actions, closable, onClose, text } = this.asProps;
const SIcon = Box;
const SIllustration = Box;
const { label, title, actions, closable, onClose, text, icon, illustration, styles, theme } = this.asProps;

return (
return sstyled(styles)(
<SNoticeSmart render={Notice} __excludeProps={['title']}>
{icon !== undefined && (<SIcon theme={theme}>{icon}</SIcon>)}
{illustration !== undefined && (<SIllustration>{illustration}</SIllustration>)}
{isNode(label) && <Notice.Label>{label}</Notice.Label>}
<Notice.Content>
{isNode(title) && <Notice.Title>{title}</Notice.Title>}
{isNode(text) && <Notice.Text>{text}</Notice.Text>}
{isNode(actions) && <Notice.Actions>{actions}</Notice.Actions>}
</Notice.Content>
{closable && <Notice.Close onClick={onClose} />}
</SNoticeSmart>
</SNoticeSmart>,
);
}
}
Expand Down
14 changes: 12 additions & 2 deletions semcore/notice/src/NoticeSmart.type.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import type { Intergalactic } from '@semcore/core';
import type Icon from '@semcore/icon';
import type { IllustrationProps } from '@semcore/illustration';

import type { NSNotice } from './Notice.type';

declare namespace NSNoticeSmart {
type Props = NSNotice.Props & {
type Props = Omit<NSNotice.Props, 'icon' | 'illustration'> & {
/**
* A custom element for additional information
*
* @deprecated. Use icon or illustration props instead.
*/
label?: React.ReactNode;

Expand All @@ -29,7 +33,13 @@ declare namespace NSNoticeSmart {
* Callback on a click on the close button
*/
onClose?: (event: React.SyntheticEvent) => void;
};
} & ({
icon?: typeof Icon;
illustration?: never;
} | {
icon?: never;
illustration?: React.ElementType<IllustrationProps>;
});
type DefaultProps = {
theme: 'info';
};
Expand Down
45 changes: 30 additions & 15 deletions semcore/notice/src/style/notice.shadow.css
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
SNotice {
display: flex;
padding: var(--intergalactic-spacing-4x, 16px);
padding: var(--intergalactic-spacing-content-padding-large, 16px);
font-size: var(--intergalactic-fs-200, 14px);
line-height: var(--intergalactic-lh-200, 142%);
box-sizing: border-box;
border-style: solid;
border-width: 1px;
border-radius: var(--intergalactic-surface-rounded, 8px);
color: var(--intergalactic-text-primary, oklch(0.1 0.03 137 / 0.899));
gap: var(--intergalactic-spacing-content-gap-large, 8px);
}

SNotice[theme='info'] {
Expand Down Expand Up @@ -82,44 +83,59 @@ SContent {

SActions {
flex-shrink: 0;
margin-top: var(--intergalactic-spacing-3x, 12px);
display: flex;
gap: var(--intergalactic-spacing-content-gap-large, 8px);
margin-top: var(--intergalactic-spacing-content-padding-small, 8px);
}

SLabel {
min-height: var(--intergalactic-form-control-m, 32px);
height: fit-content;
margin-right: var(--intergalactic-spacing-2x, 8px);
display: inline-flex;
align-items: center;
margin-top: 6px;
}

SIcon {
height: fit-content;
display: inline-flex;
align-items: center;
margin-top: 6px;
}

SIllustration {
height: fit-content;
display: inline-flex;
align-items: center;
margin-right: var(--intergalactic-spacing-content-padding-xlarge, 20px);
}

SLabel[theme='info'] {
SLabel[theme='info'], SIcon[theme='info'] {
color: var(--intergalactic-icon-primary-neutral, oklch(0.092 0.024 152.2 / 0.526));
}

SLabel[theme='danger'] {
SLabel[theme='danger'], SIcon[theme='danger'] {
color: var(--intergalactic-icon-primary-critical, oklch(0.552 0.226 28.7 / 0.848));
}

SLabel[theme='warning'] {
SLabel[theme='warning'], SIcon[theme='warning'] {
color: var(--intergalactic-icon-primary-warning, oklch(0.728 0.188 51.8));
}

SLabel[theme='success'] {
SLabel[theme='success'], SIcon[theme='success'] {
color: var(--intergalactic-icon-primary-success, oklch(0.595 0.124 165.4));
}

SLabel[theme='muted'] {
SLabel[theme='muted'], SIcon[theme='muted'] {
color: var(--intergalactic-icon-primary-neutral, oklch(0.092 0.024 152.2 / 0.526));
}

SLabel[theme='custom'] {
SLabel[theme='custom'], SIcon[theme='custom'] {
color: var(--color);
}

SCloseIcon {
flex-shrink: 0;
margin-left: var(--intergalactic-spacing-4x, 16px);
margin-left: var(--intergalactic-spacing-content-padding-large, 16px);
}

SNotice[theme='custom'] {
Expand All @@ -128,11 +144,10 @@ SNotice[theme='custom'] {
}

STitle {
margin-top: var(--intergalactic-spacing-05x, 2px);
margin-bottom: var(--intergalactic-spacing-05x, 2px);
margin-top: calc(var(--intergalactic-spacing-content-padding-xsmall, 4px) / 2);
}

SText {
margin-top: var(--intergalactic-spacing-1x, 4px);
margin-bottom: var(--intergalactic-spacing-1x, 4px);
margin-top: var(--intergalactic-spacing-content-padding-xsmall, 4px);
margin-bottom: var(--intergalactic-spacing-content-padding-xsmall, 4px);
}
42 changes: 11 additions & 31 deletions stories/components/notice/docs/examples/basic_notice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,8 @@ import Notice from '@semcore/ui/notice';
import React from 'react';

const Demo = () => (
<Flex direction='column'>
<Notice aria-label='Notice' mb={2}>
<Notice.Label>
<Question />
</Notice.Label>

<Flex direction='column' gap={2}>
<Notice aria-label='Notice' icon={<Question />}>
<Notice.Content>
<Notice.Title>New keyboard shortcuts are available</Notice.Title>

Expand All @@ -22,7 +18,7 @@ const Demo = () => (
</Notice.Text>

<Notice.Actions>
<Button use='primary' mr={2}>
<Button use='primary'>
Learn more
</Button>
<Button>Close</Button>
Expand All @@ -31,11 +27,7 @@ const Demo = () => (
<Notice.Close />
</Notice>

<Notice theme='muted' aria-label='New muted feature announcement' mb={2}>
<Notice.Label>
<Question />
</Notice.Label>

<Notice theme='muted' aria-label='New muted feature announcement' icon={<Question />}>
<Notice.Content>
<Notice.Title>Data export is in progress</Notice.Title>

Expand All @@ -45,7 +37,7 @@ const Demo = () => (
</Notice.Text>

<Notice.Actions>
<Button use='primary' mr={2}>
<Button use='primary'>
View details
</Button>
<Button>Close</Button>
Expand All @@ -54,11 +46,7 @@ const Demo = () => (
<Notice.Close />
</Notice>

<Notice theme='warning' aria-label='New warning feature announcement' mb={2}>
<Notice.Label>
<Question />
</Notice.Label>

<Notice theme='warning' aria-label='New warning feature announcement' icon={<Question />}>
<Notice.Content>
<Notice.Title>Payment method expires soon</Notice.Title>

Expand All @@ -68,7 +56,7 @@ const Demo = () => (
</Notice.Text>

<Notice.Actions>
<Button use='primary' theme='success' mr={2}>
<Button use='primary' theme='success'>
Update payment method
</Button>
<Button>Close</Button>
Expand All @@ -77,11 +65,7 @@ const Demo = () => (
<Notice.Close />
</Notice>

<Notice theme='danger' aria-label='New danger feature announcement' mb={2}>
<Notice.Label>
<Warning />
</Notice.Label>

<Notice theme='danger' aria-label='New danger feature announcement' icon={<Warning />}>
<Notice.Content>
<Notice.Title>API request limit reached</Notice.Title>

Expand All @@ -91,7 +75,7 @@ const Demo = () => (
</Notice.Text>

<Notice.Actions>
<Button use='primary' theme='danger' mr={2}>
<Button use='primary' theme='danger'>
Increase limit
</Button>
<Button>Close</Button>
Expand All @@ -100,11 +84,7 @@ const Demo = () => (
<Notice.Close />
</Notice>

<Notice theme='success' aria-label='New success feature announcement' mb={2}>
<Notice.Label>
<ThumbUpM />
</Notice.Label>

<Notice theme='success' aria-label='New success feature announcement' icon={<ThumbUpM />}>
<Notice.Content>
<Notice.Title>Backup completed successfully</Notice.Title>

Expand All @@ -114,7 +94,7 @@ const Demo = () => (
</Notice.Text>

<Notice.Actions>
<Button use='primary' theme='success' mr={2}>
<Button use='primary' theme='success'>
View backup history
</Button>
<Button>Close</Button>
Expand Down
5 changes: 1 addition & 4 deletions stories/components/notice/docs/examples/custom_notice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@ import Notice, { type NSNotice } from '@semcore/ui/notice';
import React from 'react';

const Demo = (props: NSNotice.Props) => (
<Notice aria-label='Custom notice example' {...props}>
<Notice.Label>
<Calendar />
</Notice.Label>
<Notice aria-label='Custom notice example' {...props} icon={<Calendar />}>
<Notice.Content>
<Notice.Title size={400}>
Strategize your next move with daily and weekly traffic data
Expand Down
Loading
Loading