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
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
/.storybook/ @fransiscus-hermanto @fransiscushermanto

# packages
/packages/components/alert @albertusip
/packages/components/badge @fransiscus-hermanto @fransiscushermanto
/packages/components/button @fransiscus-hermanto @fransiscushermanto
/packages/components/card @albertusip
Expand Down
51 changes: 51 additions & 0 deletions packages/components/alert/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"name": "@julo-ui/alert",
"version": "0.0.1",
"description": "A React component used to communicate a state that affect a system, feature or page",
"keywords": ["alert"],
"main": "src/index.ts",
"files": ["dist"],
"sideEffects": false,
"scripts": {
"build": "tsup --dts",
"build:fast": "tsup",
"clean": "rimraf dist .turbo",
"prebuild": "pnpm run clean",
"dev": "pnpm run build:fast",
"prepack": "clean-package",
"postpack": "clean-package restore"
},
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "git+https://github.com/julofinance/julo-ui.git",
"directory": "packages/components/alert"
},
"author": "Albertus Istora P",
"license": "ISC",
"bugs": {
"url": "https://github.com/julofinance/julo-ui/issues"
},
"homepage": "https://github.com/julofinance/julo-ui#readme",
"dependencies": {
"@emotion/react": "^11.10.6",
"@julo-ui/context": "workspace:*",
"@julo-ui/dom-utils": "workspace:*",
"@julo-ui/typography": "workspace:*"
},
"devDependencies": { "@julo-ui/system": "workspace:*" },
"peerDependencies": {
"@emotion/react": "^11.10.6",
"react": ">=18",
"@julo-ui/system": "workspace:*"
},
"clean-package": "../../../clean-package.config.json",
"tsup": {
"entry": ["src", "!src/**/*.md"],
"clean": true,
"target": "es2019",
"format": ["cjs", "esm"]
}
}
31 changes: 31 additions & 0 deletions packages/components/alert/src/Alert.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { forwardRef, julo, cx } from '@julo-ui/system';

import { alertCx, alertStatus } from './styles';
import type { AlertProps } from './types';
import { AlertProvider } from './AlertProvider';

const Alert = forwardRef<AlertProps, 'div'>((props, ref) => {
const { children, className, status = 'neutrals', sx, ...resProps } = props;

return (
<AlertProvider value={{ status }}>
<julo.div
ref={ref}
className={cx('julo-alert', className)}
data-alert-status={status}
sx={{
...alertStatus[status],
...sx,
}}
{...resProps}
__css={alertCx}
>
{children}
</julo.div>
</AlertProvider>
);
});

Alert.displayName = 'Alert';

export default Alert;
13 changes: 13 additions & 0 deletions packages/components/alert/src/AlertProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { createContext } from '@julo-ui/context';

import type { AlertProps } from './types';

type AlertContextProps = Pick<AlertProps, 'status'>;

const [AlertProvider, useAlertContext] = createContext<AlertContextProps>({
name: 'AlertContext',
hookName: 'useAlertContext',
providerName: '<AlertProvider />',
});

export { AlertProvider, useAlertContext };
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Typography } from '@julo-ui/typography';
import { forwardRef, cx } from '@julo-ui/system';

import { useAlertContext } from '../../AlertProvider';

import { alertDescription } from './styles';
import type { AlertDescriptionProps } from './types';

const AlertDescription = forwardRef<AlertDescriptionProps, 'div'>(
(props, ref) => {
const { children, className, sx, ...resProps } = props;
const { status = 'neutrals' } = useAlertContext(
'AlertDescription should be within Alert',
);

return (
<Typography
bold
as='div'
type='caption'
ref={ref}
sx={{ ...alertDescription[status], ...sx }}
className={cx('julo-alert__description', className)}
{...resProps}
>
{children}
</Typography>
);
},
);

AlertDescription.displayName = 'AlertDescription';

export default AlertDescription;
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as AlertDescription } from './AlertDescription';
export * from './types';
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { SystemStyleObject } from '@julo-ui/system';

import { AlertStatus } from '../../types';

export const alertDescription: Record<AlertStatus, SystemStyleObject> = {
info: {
color: 'var(--colors-blue-40)',
},
negative: {
color: 'var(--colors-red-40)',
},
positive: {
color: 'var(--colors-green-40)',
},
warning: {
color: 'var(--colors-orange-40)',
},
neutrals: {
color: 'var(--colors-neutrals-90)',
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { HTMLJuloProps } from '@julo-ui/system';

export type AlertDescriptionProps = HTMLJuloProps<'div'>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { forwardRef, julo, cx } from '@julo-ui/system';

import { useAlertContext } from '../../AlertProvider';

import { useHandleIcon } from './usecase';
import { alertIconStatusSx, alertIconCx } from './styles';
import { AlertIconProps } from './types';

const AlertIcon = forwardRef<AlertIconProps, 'div'>((props, ref) => {
const { placement = 'left', className, sx, ...resProps } = props;
const { status = 'neutrals' } = useAlertContext(
'AlertIcon should be within Alert',
);

const Icon = useHandleIcon({ status: status });

return (
<julo.div
ref={ref}
data-status={status}
className={cx('julo-alert__icon', className)}
sx={{ ...alertIconStatusSx[status], ...sx }}
{...(placement && { 'data-icon-placement': placement })}
{...resProps}
__css={alertIconCx}
>
<Icon />
</julo.div>
);
});

AlertIcon.displayName = 'AlertIcon';

export default AlertIcon;
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as AlertIcon } from './AlertIcon';
export * from './types';
49 changes: 49 additions & 0 deletions packages/components/alert/src/components/alert-icon/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { css } from '@emotion/react';
import { SystemStyleObject } from '@julo-ui/system';

import { AlertStatus } from '../../types';

export const alertIconCx = css`
&[data-icon-placement='left'] {
order: 0;
margin-right: 0.5rem;
}

&[data-icon-placement='right'] {
order: 999;
margin-left: 0.5rem;
}
`;

export const alertIconStatusSx: Record<AlertStatus, SystemStyleObject> = {
info: {
color: 'var(--colors-blue-40)',
svg: {
fill: 'var(--colors-blue-40)',
},
},
negative: {
color: 'var(--colors-red-40)',
svg: {
fill: 'var(--colors-red-40)',
},
},
positive: {
color: 'var(--colors-green-40)',
svg: {
fill: 'var(--colors-green-40)',
},
},
warning: {
color: 'var(--colors-orange-40)',
svg: {
fill: 'var(--colors-orange-40)',
},
},
neutrals: {
color: 'var(--colors-neutrals-90)',
svg: {
fill: 'var(--colors-neutrals-90)',
},
},
};
10 changes: 10 additions & 0 deletions packages/components/alert/src/components/alert-icon/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { HTMLJuloProps } from '@julo-ui/system';

export interface AlertIconProps extends HTMLJuloProps<'svg'> {
/**
* The placement option for icon and affect in style margin left or right
* if placement={null}, the placement style will not be applied
*
*/
placement?: 'left' | null | 'right';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as useHandleIcon } from './use-handle-icon';
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {
InfoIcon,
NegativeIcon,
NeutralsIcon,
PositiveIcon,
WarningIcon,
} from '../../../icons';

interface UseHandleIconOptions {
status: string;
}

function useHandleIcon(options: UseHandleIconOptions) {
const { status } = options;

switch (status) {
case 'info':
return InfoIcon;
case 'negative':
return NegativeIcon;
case 'positive':
return PositiveIcon;
case 'warning':
return WarningIcon;
case 'neutrals':
return NeutralsIcon;
default:
return NeutralsIcon;
}
}

export default useHandleIcon;
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Typography } from '@julo-ui/typography';
import { forwardRef, cx } from '@julo-ui/system';

import { useAlertContext } from '../../AlertProvider';

import { alertTitle } from './styles';
import type { AlertTitleProps } from './types';

const AlertTitle = forwardRef<AlertTitleProps, 'div'>((props, ref) => {
const { children, className, sx, ...resProps } = props;
const { status = 'neutrals' } = useAlertContext(
'AlertTitle should be within Alert',
);

return (
<Typography
bold
as='div'
type='caption'
ref={ref}
sx={{ ...alertTitle[status], ...sx }}
className={cx('julo-alert__title', className)}
{...resProps}
>
{children}
</Typography>
);
});

AlertTitle.displayName = 'AlertTitle';

export default AlertTitle;
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as AlertTitle } from './AlertTitle';
export * from './types';
21 changes: 21 additions & 0 deletions packages/components/alert/src/components/alert-title/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { SystemStyleObject } from '@julo-ui/system';

import { AlertStatus } from '../../types';

export const alertTitle: Record<AlertStatus, SystemStyleObject> = {
info: {
color: 'var(--colors-blue-50)',
},
negative: {
color: 'var(--colors-red-50)',
},
positive: {
color: 'var(--colors-green-50)',
},
warning: {
color: 'var(--colors-orange-50)',
},
neutrals: {
color: 'var(--colors-neutrals-100)',
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { HTMLJuloProps } from '@julo-ui/system';

export type AlertTitleProps = HTMLJuloProps<'div'>;
Loading