Skip to content

Commit ad43549

Browse files
authored
Merge pull request #47 from 1Byte-Software/develop
Update version 1.10.0
2 parents 339ca16 + c1ad3c9 commit ad43549

File tree

16 files changed

+322
-35
lines changed

16 files changed

+322
-35
lines changed

CHANGELOG.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,15 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8-
## [1.8.0]
8+
## [1.10.0]
9+
10+
### Added
11+
12+
- Added `Segmented` component.
13+
- Added `Alert.ErrorBoundary` component.
14+
- Add `fixedSiderBreakpoint` prop for `DashboardTemplateSider`.
15+
16+
## [1.9.0]
917

1018
### Added
1119

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "1byte-react-design",
3-
"version": "1.9.0",
3+
"version": "1.10.0",
44
"description": "A simple React UI library",
55
"main": "dist/index.js",
66
"module": "dist/index.js",

src/molecules/Alert/Alert.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import { forwardRef } from 'react';
22
import { AlertStyled } from './styles';
33
import { RdAlertComponent, RdAlertCompoundedComponent } from './types';
4+
import { AlertErrorBoundary } from './ErrorBoundary';
45

56
export const InternalAlert: RdAlertComponent = forwardRef((props, ref) => {
67
return <AlertStyled {...props} ref={ref} />;
78
});
89

910
export const Alert: RdAlertCompoundedComponent = InternalAlert as RdAlertCompoundedComponent;
11+
12+
Alert.ErrorBoundary = AlertErrorBoundary;
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import React from 'react';
2+
import { AlertErrorBoundaryStyled } from './styles';
3+
import {
4+
RdAlertErrorBoundaryComponent,
5+
RdAlertErrorBoundaryProps,
6+
RdAlertErrorBoundaryStates,
7+
} from './types';
8+
9+
export class AlertErrorBoundary
10+
extends React.Component<RdAlertErrorBoundaryProps, RdAlertErrorBoundaryStates>
11+
implements RdAlertErrorBoundaryComponent
12+
{
13+
state: RdAlertErrorBoundaryStates = {
14+
error: undefined,
15+
info: {
16+
componentStack: '',
17+
},
18+
};
19+
20+
componentDidCatch(error: Error | null, info: object): void {
21+
// update state with error + stack trace from Antd
22+
this.setState({
23+
error,
24+
info: {
25+
componentStack: (info as any).componentStack ?? '',
26+
},
27+
});
28+
}
29+
30+
render() {
31+
return <AlertErrorBoundaryStyled {...this.props} />;
32+
}
33+
}

src/molecules/Alert/styles.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
import styled from '@emotion/styled';
22
import { Alert } from 'antd';
3+
import { RdAlertErrorBoundaryComponent } from './types';
34

45
export const AlertStyled = styled(Alert)``;
6+
7+
export const AlertErrorBoundaryStyled = styled(
8+
Alert.ErrorBoundary as typeof RdAlertErrorBoundaryComponent
9+
)``;

src/molecules/Alert/types.ts

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,61 @@
11
import { Alert, GetProps } from 'antd';
22
import { AlertRef } from 'antd/es/alert/Alert';
33
import { ComponentToken as AlertComponentTokenAntd } from 'antd/es/drawer/style';
4-
import { ComponentProps } from 'react';
4+
import React, { ComponentProps } from 'react';
55

66
type AlertPropsAntd = GetProps<typeof Alert>;
7-
type AlertErrorBoundaryPropsAntd = GetProps<typeof Alert.ErrorBoundary>;
87

8+
/**
9+
* 📝 Explanation:
10+
*
11+
* For most Ant Design components, we can simply get the props type using:
12+
* type XxxPropsAntd = GetProps<typeof Xxx>;
13+
*
14+
* However, `Alert.ErrorBoundary` is a special case:
15+
* - Ant Design does NOT export a public props interface for ErrorBoundary.
16+
* - If we directly use `GetProps<typeof Alert.ErrorBoundary>`,
17+
* TypeScript will try to expose internal types and throw an error:
18+
* ts(4023): "Exported variable '...' has or is using name '...' but cannot be named".
19+
*
20+
* 🚑 Workaround:
21+
* - Use `ComponentProps<typeof Alert.ErrorBoundary>` to get the props,
22+
* then clone it via a mapped type to produce a "public" type.
23+
* - This way we avoid referencing Ant Design’s internal types.
24+
*
25+
* 🔮 Note:
26+
* - If Ant Design exports a proper `AlertErrorBoundaryProps` type in the future,
27+
* we can safely remove this workaround and write:
28+
* type AlertErrorBoundaryPropsAntd = GetProps<typeof Alert.ErrorBoundary>;
29+
*/
30+
type AlertErrorBoundaryPropsAntd = {
31+
[K in keyof ComponentProps<typeof Alert.ErrorBoundary>]: ComponentProps<
32+
typeof Alert.ErrorBoundary
33+
>[K];
34+
};
35+
36+
/**
37+
* 📝 Explanation:
38+
*
39+
* Ant Design also does not export the `ErrorBoundaryStates` type.
40+
* Therefore, instead of extracting it automatically, we need to define this interface manually.
41+
*
42+
* The state shape is referenced from the source code:
43+
* state: {
44+
* error: undefined;
45+
* info: {
46+
* componentStack: string;
47+
* };
48+
* }
49+
*
50+
* This is simply a copied definition to ensure type safety for our extended components.
51+
* If Ant Design exports `ErrorBoundaryStates` in the future, we should switch to that instead.
52+
*/
53+
interface AlertErrorBoundaryStatesAntd {
54+
error?: Error | null;
55+
info?: {
56+
componentStack?: string;
57+
};
58+
}
959
type AlertRefAntd = AlertRef;
1060

1161
//#endregion
@@ -17,24 +67,34 @@ type AlertComponentTokenExtend = {};
1767
//#region Define extended types
1868
type AlertPropsExtend = {};
1969
type AlertErrorBoundaryPropsExtend = {};
70+
type AlertErrorBoundaryStatesExtend = {};
2071

2172
type AlertRefExtend = {};
2273
//#endregion
2374

2475
//#region Export types
2576
export type RdAlertProps = AlertPropsAntd & AlertPropsExtend;
2677
export type RdAlertErrorBoundaryProps = AlertErrorBoundaryPropsAntd & AlertErrorBoundaryPropsExtend;
78+
export type RdAlertErrorBoundaryStates = AlertErrorBoundaryStatesAntd &
79+
AlertErrorBoundaryStatesExtend;
2780
export type RdAlertRef = AlertRefAntd & AlertRefExtend;
2881
export type RdAlertComponentToken = AlertComponentTokenAntd & AlertComponentTokenExtend;
2982
//#endregion
3083

3184
//#region Define component types
32-
// export type RdAlertComponent = React.FC<RdAlertProps>;
3385
export type RdAlertComponent = React.ForwardRefExoticComponent<
3486
RdAlertProps & React.RefAttributes<RdAlertRef>
3587
>;
88+
export declare class RdAlertErrorBoundaryComponent extends React.Component<
89+
RdAlertErrorBoundaryProps,
90+
RdAlertErrorBoundaryStates
91+
> {
92+
state: RdAlertErrorBoundaryStates;
93+
componentDidCatch(error: Error | null, info: object): void;
94+
render(): React.ReactNode;
95+
}
3696

3797
export type RdAlertCompoundedComponent = RdAlertComponent & {
38-
// Timer: RdAlertErrorBoundaryComponent;
98+
ErrorBoundary: typeof RdAlertErrorBoundaryComponent;
3999
};
40100
//#endregion
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { useMemo } from 'react';
2+
import { SegmentedStyledFunc } from './styles';
3+
import { RdSegmentedComponent, RdSegmentedProps } from './types';
4+
5+
export const InternalSegmented = <ValueType extends string | number>(
6+
props: RdSegmentedProps<ValueType>
7+
) => {
8+
const SegmentedStyled = useMemo(() => {
9+
return SegmentedStyledFunc<ValueType>();
10+
}, [SegmentedStyledFunc]);
11+
12+
return <SegmentedStyled {...props} />;
13+
};
14+
15+
export const Segmented = InternalSegmented as RdSegmentedComponent;

src/molecules/Segmented/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { Segmented } from './Segmented';
2+
export * from './types';

src/molecules/Segmented/styles.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import styled from '@emotion/styled';
2+
import { Segmented } from 'antd';
3+
4+
export const SegmentedStyles = styled(Segmented)``;
5+
6+
export const SegmentedStyledFunc = <ValueType extends string | number>() =>
7+
styled(Segmented<ValueType>)``;

src/molecules/Segmented/types.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { GetProps, Segmented } from 'antd';
2+
import { ComponentToken as SegmentedComponentTokenAntd } from 'antd/es/affix/style';
3+
import { InternalSegmented } from './Segmented';
4+
5+
//#region Define Ant Design types
6+
type SegmentedPropsAntd<ValueType> = GetProps<typeof Segmented<ValueType>>;
7+
//#endregion
8+
9+
//#region Define extended component tokens
10+
type SegmentedComponentTokenExtend = {};
11+
//#endregion
12+
13+
//#region Define extended types
14+
type SegmentedPropsExtend = {};
15+
16+
type SegmentedRefExtend = {};
17+
//#endregion
18+
19+
//#region Export types
20+
export type RdSegmentedProps<ValueType> = SegmentedPropsAntd<ValueType> & SegmentedPropsExtend;
21+
22+
export type RdSegmentedComponentToken = SegmentedComponentTokenAntd & SegmentedComponentTokenExtend;
23+
//#endregion
24+
25+
//#region Define component types
26+
export type RdSegmentedComponent = (<ValueType>(
27+
props: RdSegmentedProps<ValueType> & React.RefAttributes<HTMLDivElement>
28+
) => ReturnType<typeof InternalSegmented>) &
29+
Pick<React.FC, 'displayName'>;
30+
//#endregion

0 commit comments

Comments
 (0)