-
-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Init toast * add event bus #76 (initial approach only)
- Loading branch information
Showing
20 changed files
with
825 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export { default as useToastExtension } from './toast.hook'; | ||
export { default } from './toast.lite'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { EventBus } from '@trutoo/event-bus'; | ||
import { ToastCallback, ToastPayload } from './toast.model'; | ||
|
||
const BUS_NAME = 'toast'; | ||
const bus = new EventBus(); | ||
const state: ToastPayload[] = []; | ||
|
||
// TODO: If more buses in the future, move to generic | ||
const subscribe = (callback: ToastCallback<ToastPayload>) => bus.subscribe(BUS_NAME, callback); | ||
const register = (optionsType = { type: Object }) => bus.register(BUS_NAME, optionsType); | ||
const publish = (payload: ToastPayload) => { | ||
state.push(payload); | ||
bus.publish(BUS_NAME, payload); | ||
}; | ||
|
||
// TODO: Can i move all the logic to the service?? | ||
|
||
export const toastBus = { | ||
subscribe, | ||
register, | ||
publish, | ||
state: () => state | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
@import '~/styles/build.css'; | ||
|
||
.pa-toast { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import { debug } from '~/helpers'; | ||
import { toastBus } from './toast.bus'; | ||
import './toast.css'; | ||
import { ToastPayload } from './toast.model'; | ||
|
||
const themes = {}; | ||
|
||
const actions: { | ||
[key: string]: (payload: ToastPayload) => void; | ||
} = {}; | ||
|
||
function actionFactory(name) { | ||
return (payload: ToastPayload) => { | ||
toastBus.publish({ | ||
id: `${Math.random()}`, | ||
...payload | ||
}); | ||
}; | ||
} | ||
|
||
function createTheme(name: string) { | ||
const properties = ['background', 'foreground']; | ||
const theme = {}; | ||
|
||
properties.forEach((property) => (theme[property] = `var(--pa-toast-${property}-${name})`)); | ||
|
||
debug(`ToastService createTheme: ${name}: ${JSON.stringify(theme)}`); | ||
|
||
toastBus.register(); | ||
themes[name] = theme; | ||
actions[name] = actionFactory(name); | ||
} | ||
|
||
function triggerCustomAction(name: string, payload: ToastPayload) { | ||
return actions[name](payload); | ||
} | ||
|
||
export default function useToastExtension() { | ||
createTheme('success'); | ||
createTheme('error'); | ||
|
||
return { success: actions.success, error: actions.error, createTheme, trigger: triggerCustomAction }; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { For, onMount, onUnMount, useMetadata, useStore } from '@builder.io/mitosis'; | ||
import './toast.css'; | ||
import type { ToastProps, ToastState } from './toast.model'; | ||
import { toastService } from './toast.service'; | ||
|
||
useMetadata({ isAttachedToShadowDom: true }); | ||
|
||
export default function Toast(props: ToastProps) { | ||
const state = useStore<ToastState>({ | ||
get classes() { | ||
return toastService.getClasses(props.disabled, props.className || props.classList); | ||
}, | ||
get toasts() { | ||
return toastService.getToasts(); | ||
}, | ||
toastSubscription: null | ||
}); | ||
|
||
onMount(() => { | ||
if (state.toastSubscription) { | ||
return; | ||
} | ||
|
||
// TODO: This approach doesnt work looks like is not reactive enough I will try other approach | ||
state.toastSubscription = toastService.subscribe(); | ||
}); | ||
|
||
onUnMount(() => { | ||
if (!state.toastSubscription) { | ||
return; | ||
} | ||
|
||
state.toastSubscription.unsubscribe(); | ||
}); | ||
|
||
return ( | ||
<div class={state.classes.base}> | ||
<For each={state.toasts}>{(toast) => <div>{toast.message}</div>}</For> | ||
{props.children} | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import type { BaseProps, BaseState } from '~/models'; | ||
|
||
export interface ToastProps extends BaseProps { | ||
disabled?: boolean; | ||
} | ||
|
||
export interface ToastState extends BaseState { | ||
classes: { base: string }; | ||
toasts: ToastPayload[]; | ||
toastSubscription: { | ||
unsubscribe(): void; | ||
}; | ||
} | ||
|
||
export type ToastPayload = { | ||
id?: string; | ||
message: string; | ||
}; | ||
|
||
// TODO Move to generic | ||
export type ToastChannelEvent<T> = { | ||
channel: string; | ||
payload: T | undefined; | ||
}; | ||
|
||
export type ToastCallback<T> = (event: ToastChannelEvent<T>) => void; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { classesToString, debug } from '~/helpers'; | ||
import { toastBus } from './toast.bus'; | ||
import { ToastChannelEvent, ToastPayload } from './toast.model'; | ||
|
||
class ToastService { | ||
private toasts: ToastPayload[] = []; | ||
|
||
private onChangeToasts(event: ToastChannelEvent<ToastPayload>) { | ||
this.toasts = toastBus.state(); | ||
debug(`ToastService onChangeToasts: toasts: ${this.toasts}`); | ||
} | ||
|
||
public getClasses(disabled: boolean, className: string) { | ||
const base = classesToString(['pa-toast', [disabled, 'is-disabled'], className || '']); | ||
|
||
debug(`ToastService getClasses: base: ${base}`); | ||
return { base }; | ||
} | ||
|
||
public getToasts() { | ||
return this.toasts; | ||
} | ||
|
||
public subscribe() { | ||
debug('ToastService subscribe'); | ||
return toastBus.subscribe(this.onChangeToasts); | ||
} | ||
} | ||
|
||
export const toastService = new ToastService(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
import { Canvas, Meta, Story, ArgsTable } from '@storybook/addon-docs'; | ||
import { Customization, Codesandbox } from '../../../../.storybook/components'; | ||
import { Toast, useToastExtension } from '../../../../packages/react/src'; | ||
|
||
<Meta | ||
title="🧩Elements/Extensions/Toast" | ||
argTypes={{ | ||
title: { | ||
name: 'title', | ||
description: 'A sample of attribute title', | ||
table: {}, | ||
control: 'text' | ||
} | ||
}} | ||
/> | ||
|
||
export const Template = (args) => ( | ||
<div className="toast-example"> | ||
{(() => { | ||
window.toast = useToastExtension(); | ||
return ''; | ||
})()} | ||
<div> | ||
<Toast /> | ||
<span | ||
onClick={() => { | ||
// toast.success({ message: 'example' }) | ||
window.toast.success({ message: 'example' + Math.random() }); | ||
}} | ||
> | ||
Click me | ||
</span> | ||
</div> | ||
</div> | ||
); | ||
|
||
# Toast | ||
|
||
TODO | ||
|
||
## Showcase | ||
|
||
<Canvas> | ||
<Story | ||
name="Toast" | ||
args={{ | ||
title: 'Title of my tooltip' | ||
}} | ||
> | ||
{Template.bind({})} | ||
</Story> | ||
</Canvas> | ||
|
||
### Customization | ||
|
||
<Customization showCode={false} /> | ||
|
||
### Properties | ||
|
||
<ArgsTable story="Tooltip" /> | ||
|
||
## How to use this extension | ||
|
||
### Angular | ||
|
||
<Codesandbox | ||
extensions={['useTooltipExtension']} | ||
platform="angular" | ||
code={` | ||
<span title="Example of a tooltip">Hover me</span>`} | ||
/> | ||
|
||
### Preact | ||
|
||
<Codesandbox | ||
extensions={['useTooltipExtension']} | ||
platform="preact" | ||
code={` | ||
<span title="Example of a tooltip">Hover me</span>`} | ||
/> | ||
|
||
### Qwik | ||
|
||
<Codesandbox | ||
extensions={['useTooltipExtension']} | ||
platform="qwik" | ||
code={` | ||
<span title="Example of a tooltip">Hover me</span>`} | ||
/> | ||
|
||
### React | ||
|
||
<Codesandbox | ||
extensions={['useTooltipExtension']} | ||
platform="react" | ||
code={` | ||
<span title="Example of a tooltip">Hover me</span>`} | ||
/> | ||
|
||
### Solid | ||
|
||
<Codesandbox | ||
extensions={['useTooltipExtension']} | ||
platform="solid" | ||
code={` | ||
<span title="Example of a tooltip">Hover me</span>`} | ||
/> | ||
|
||
### Svelte | ||
|
||
<Codesandbox | ||
extensions={['useTooltipExtension']} | ||
platform="svelte" | ||
code={` | ||
<span title="Example of a tooltip">Hover me</span>`} | ||
/> | ||
|
||
### Vue | ||
|
||
<Codesandbox | ||
extensions={['useTooltipExtension']} | ||
platform="vue" | ||
code={` | ||
<span title="Example of a tooltip">Hover me</span>`} | ||
/> | ||
|
||
### Web Components | ||
|
||
<Codesandbox | ||
extensions={['useTooltipExtension']} | ||
platform="webcomponents" | ||
code={`<span title="Example of a tooltip">Hover me</span>`} | ||
/> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
export { default } from './tooltip'; | ||
export { default } from './tooltip.hook'; |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.