Skip to content

Commit

Permalink
Merge pull request #20 from daymosik/rewrite-to-fc
Browse files Browse the repository at this point in the history
rewrite to FC
  • Loading branch information
daymosik authored Feb 25, 2024
2 parents 82d1a4b + 634dd46 commit 4853411
Show file tree
Hide file tree
Showing 5 changed files with 5,262 additions and 3,706 deletions.
18 changes: 7 additions & 11 deletions lib/status-alert-container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,10 @@ export interface StatusAlertContainerProps {
alerts: Alert[]
}

export class StatusAlertContainer extends React.PureComponent<StatusAlertContainerProps, unknown> {
public render() {
return (
<div className="status-alerts-wrapper">
{this.props.alerts.map((alert) => (
<StatusAlertItem alert={alert} key={alert.id} />
))}
</div>
)
}
}
export const StatusAlertContainer: React.FC<StatusAlertContainerProps> = ({ alerts }) => (
<div className="status-alerts-wrapper">
{alerts.map((alert) => (
<StatusAlertItem alert={alert} key={alert.id} />
))}
</div>
)
109 changes: 51 additions & 58 deletions lib/status-alert-item.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { default as React, RefObject } from 'react'
import { default as React, useRef } from 'react'
import { alertIcon, boxClassName } from './status-alert-item-helpers'
import { StatusAlertService } from './status-alert-service'

Expand Down Expand Up @@ -33,78 +33,71 @@ export interface StatusAlertItemProps {
alert: Alert
}

export class StatusAlertItem extends React.PureComponent<StatusAlertItemProps, unknown> {
public statusAlert: RefObject<HTMLDivElement>
export const StatusAlertItem: React.FC<StatusAlertItemProps> = (props: StatusAlertItemProps) => {
const statusAlert = useRef<HTMLDivElement>(null)

public constructor(props: StatusAlertItemProps) {
super(props)
let showFrameId: number
let hideFrameId: number

this.statusAlert = React.createRef()
}
const removeAlertCallbackSubmit = (): void => StatusAlertService.removeAlert(props.alert.id)

public componentDidMount() {
this.showAlert()
const alertOptions = (): AlertOptions => ({ ...defaultAlertOptions, ...props.alert.options })

if (this.alertOptions.autoHide) {
setTimeout(this.removeAlert, this.alertOptions.autoHideTime)
const alertText = (): JSX.Element | string => {
if (typeof props.alert.message === 'object' && !React.isValidElement(props.alert.message)) {
return JSON.stringify(props.alert.message)
}
return props.alert.message
}

public render() {
return (
<div className="status-alert is-transparent" ref={this.statusAlert}>
<div className="status-alert__padding-wrapper">
<div className={`status-alert__box ${this.boxClassName}`}>
{this.alertOptions.withCloseIcon && (
<div className="status-alert__icon-on-right-holder">
<div className="status-alert__icon is-close-icon" onClick={this.removeAlert} />
</div>
)}
{this.alertOptions.withIcon && (
<div className="status-alert__icon-holder">
<div className={`status-alert__icon ${this.alertIcon}`} />
</div>
)}
<div className="status-alert__text">{this.alertText}</div>
</div>
</div>
</div>
const showAlert = (): void => {
showFrameId = requestAnimationFrame(() =>
setTimeout(() => {
statusAlert.current?.classList.remove('is-transparent')
}),
)
}

public showAlert = (): void => {
setTimeout(() => {
if (this.statusAlert.current) {
this.statusAlert.current.classList.remove('is-transparent')
}
const removeAlert = (): void => {
hideFrameId = requestAnimationFrame(() => {
statusAlert.current?.classList.add('is-transparent')
setTimeout(removeAlertCallbackSubmit, 800)
})
}

public removeAlert = (): void => {
if (this.statusAlert.current) {
this.statusAlert.current.classList.add('is-transparent')
setTimeout(this.removeAlertCallbackSubmit, 800)
}
}

public removeAlertCallbackSubmit = (): void => StatusAlertService.removeAlert(this.props.alert.id)

get boxClassName(): string {
return boxClassName(this.props.alert.type)
}
React.useEffect(() => {
let hideTimeout: NodeJS.Timeout

get alertOptions(): AlertOptions {
return { ...defaultAlertOptions, ...this.props.alert.options }
}
showAlert()

get alertIcon(): string {
return alertIcon(this.props.alert.type)
}
if (alertOptions().autoHide) {
hideTimeout = setTimeout(removeAlert, alertOptions().autoHideTime)
}

get alertText(): JSX.Element | string {
if (typeof this.props.alert.message === 'object' && !React.isValidElement(this.props.alert.message)) {
return JSON.stringify(this.props.alert.message)
return () => {
showFrameId && window.cancelAnimationFrame(showFrameId)
hideFrameId && window.cancelAnimationFrame(hideFrameId)
hideTimeout && clearTimeout(hideTimeout)
}
return this.props.alert.message
}
})

return (
<div className="status-alert is-transparent" ref={statusAlert}>
<div className="status-alert__padding-wrapper">
<div className={`status-alert__box ${boxClassName(props.alert.type)}`}>
{alertOptions().withCloseIcon && (
<div className="status-alert__icon-on-right-holder">
<div className="status-alert__icon is-close-icon" onClick={removeAlert} />
</div>
)}
{alertOptions().withIcon && (
<div className="status-alert__icon-holder">
<div className={`status-alert__icon ${alertIcon(props.alert.type)}`} />
</div>
)}
<div className="status-alert__text">{alertText()}</div>
</div>
</div>
</div>
)
}
54 changes: 21 additions & 33 deletions lib/status-alert-view.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,33 @@
import * as React from 'react'
import { StatusAlertContainer } from './status-alert-container'
import { Alert } from './status-alert-item'
import statusAlertStore, { Unsubscriber } from './status-alert-store'
import statusAlertStore from './status-alert-store'

export interface StatusAlertState {
alerts: Alert[]
}
export const StatusAlertView: React.FC = () => {
const [alerts, setAlerts] = React.useState<Alert[]>([])

export class StatusAlertView extends React.Component<unknown, StatusAlertState> {
private unsubscribeStore: Unsubscriber
private frameId = 0
private frameId2 = 0
let frameId = 0
let frameId2 = 0

public constructor(props: unknown) {
super(props)
const updateState = () => {
frameId = requestAnimationFrame(() => {
frameId2 = requestAnimationFrame(() => {
const state = statusAlertStore.getState()
setAlerts(state)
})
})
}

this.state = {
alerts: [],
}
React.useEffect(() => {
const unsubscribeStore = statusAlertStore.subscribe(updateState)

this.unsubscribeStore = statusAlertStore.subscribe(this.updateState)
}
return () => {
unsubscribeStore()

public componentWillUnmount(): void {
if (this.unsubscribeStore) {
this.unsubscribeStore()
window.cancelAnimationFrame(frameId)
window.cancelAnimationFrame(frameId2)
}
window.cancelAnimationFrame(this.frameId)
window.cancelAnimationFrame(this.frameId2)
}

public render() {
return <StatusAlertContainer alerts={this.state.alerts} />
}
})

public updateState = () => {
this.frameId = requestAnimationFrame(() => {
this.frameId2 = requestAnimationFrame(() => {
const state = statusAlertStore.getState()
this.setState({ alerts: state })
})
})
}
return <StatusAlertContainer alerts={alerts} />
}
Loading

0 comments on commit 4853411

Please sign in to comment.