Adding AlertBox

This commit is contained in:
Jean Ouina 2020-07-11 21:29:08 +02:00
parent 2ff7a5cea8
commit e4390f7a99
15 changed files with 1881 additions and 1126 deletions

File diff suppressed because one or more lines are too long

View File

@ -217,10 +217,31 @@ export default class ApiPreview extends React.PureComponent {
return `React.createElement(${compPath}, ${propObject}, ${childrenData})` return `React.createElement(${compPath}, ${propObject}, ${childrenData})`
} }
} }
let help = comp.help || {}
let info = help.info ? <window.Lightcord.Api.Components.general.AlertBox type="info">
{help.info}
</window.Lightcord.Api.Components.general.AlertBox> : null
let warn = help.warn ? <window.Lightcord.Api.Components.general.AlertBox type="warn">
{help.warn}
</window.Lightcord.Api.Components.general.AlertBox> : null
let danger = help.danger ? <window.Lightcord.Api.Components.general.AlertBox type="danger">
{help.danger}
</window.Lightcord.Api.Components.general.AlertBox> : null
let error = help.error ? <window.Lightcord.Api.Components.general.AlertBox type="error">
{help.error}
</window.Lightcord.Api.Components.general.AlertBox> : null
let success = help.success ? <window.Lightcord.Api.Components.general.AlertBox type="success">
{help.success}
</window.Lightcord.Api.Components.general.AlertBox> : null
return (<div> return (<div>
<window.Lightcord.Api.Components.general.SettingsTitle> <window.Lightcord.Api.Components.general.SettingsTitle>
{comp.displayName || comp.name} {comp.displayName || comp.name}
</window.Lightcord.Api.Components.general.SettingsTitle> </window.Lightcord.Api.Components.general.SettingsTitle>
{info}
{success}
{warn}
{error}
{danger}
{AllPreviews.map(category => { {AllPreviews.map(category => {
if(category[0].onClick)return null if(category[0].onClick)return null
if(category[0].text)return null if(category[0].text)return null

File diff suppressed because one or more lines are too long

View File

@ -11,6 +11,8 @@ import SettingSubTitle from "./general/SettingSubTitle"
import CodeBlock from "./general/CodeBlock" import CodeBlock from "./general/CodeBlock"
import cloneNullProto from "../modules/cloneNullProto" import cloneNullProto from "../modules/cloneNullProto"
import Tooltip from "./general/Tooltip" import Tooltip from "./general/Tooltip"
import ColorPicker from "./inputs/ColorPicker"
import AlertBox from "./general/AlertBox"
export default cloneNullProto({ export default cloneNullProto({
inputs: cloneNullProto({ inputs: cloneNullProto({
@ -20,7 +22,8 @@ export default cloneNullProto({
RadioGroup: RadioGroup, RadioGroup: RadioGroup,
TextArea: TextArea, TextArea: TextArea,
TextInput: TextInput, TextInput: TextInput,
Dropdown: Dropdown Dropdown: Dropdown,
ColorPicker: ColorPicker
}), }),
general: cloneNullProto({ general: cloneNullProto({
Title: Title, Title: Title,
@ -28,6 +31,7 @@ export default cloneNullProto({
SettingSubTitle: SettingSubTitle, SettingSubTitle: SettingSubTitle,
Tabs: Tabs, Tabs: Tabs,
CodeBlock: CodeBlock, CodeBlock: CodeBlock,
Tooltip: Tooltip Tooltip: Tooltip,
AlertBox: AlertBox
}) })
}) })

View File

@ -0,0 +1,84 @@
import WebpackLoader from "../../modules/WebpackLoader"
import { ReactNode } from "react"
type AlertBoxProps = {
type: "warn"|"info"|"danger"|"error"|"success",
children: ReactNode|string
}
let AlertBoxModules
export default class AlertBox extends React.Component<AlertBoxProps> {
static defaultProps:AlertBoxProps = {
type: "info",
children: null
}
get modules(){
return AlertBoxModules || (AlertBoxModules = [
WebpackLoader.find(e => e.default && e.default.displayName === "Markdown" && e.default.defaultProps.parser).default
])
}
render(){
const [
Markdown
] = this.modules
let wrap
let children
if(typeof this.props.children === "string"){
wrap = Markdown.prototype.render.call({
props: Object.assign({
className: "",
children: this.props.children
}, Markdown.defaultProps)
})
children = wrap.props.children
}else{
wrap = Markdown.prototype.render.call({
props: Object.assign({
className: "",
children: ""
}, Markdown.defaultProps)
})
children = this.props.children
}
wrap.props.children = <div className={"lc-alert-box lc-alert-box-"+this.props.type}>
<blockquote style={{color: "#dcddde"}} className="lc-blockquote">
{children}
</blockquote>
</div>
return wrap
}
static get AllPreviews(){
return AllPreviews || (() => {
AllPreviews = []
AllPreviews.push([
{
children: "***Discord's*** **Markdown** _is_ [supported](https://google.com) or you can just insert your own react childs."
}
], [
{
type: "warn"
},
{
type: "info"
},
{
type: "error"
},
{
type: "success"
}
])
return AllPreviews
})()
}
static help = {
info: "You can insert markdown (as string) or normal react childs",
warn: "All string will be interpreted as markdown. If you want raw string, pass an array with the string inside."
}
}
let AllPreviews

View File

@ -1,3 +1,7 @@
/**
* TODO: Add margin component
*/
import WebpackLoader from "../../modules/WebpackLoader" import WebpackLoader from "../../modules/WebpackLoader"
type CodeBlockProps = { type CodeBlockProps = {

View File

@ -0,0 +1,132 @@
/**
* Replacement for color picker if original is not availlable
*
* - Don't work at the moment. Please use the other.
*/
import NOOP from "../../modules/noop"
import WebpackLoader from "../../modules/WebpackLoader"
import Tooltip from "../general/Tooltip"
type ColorPickerProps = {
inline?: boolean,
popout?: true
tooltip?: string|false,
defaultColor?: boolean,
customColor?: boolean,
baseColors?: boolean
} | {
inline?: boolean,
popout?: false,
tooltip?: false,
defaultColor?: boolean,
customColor?: boolean,
baseColors?: boolean
}
let ColorPickerModules
export default class ColorPicker extends React.Component<ColorPickerProps> {
constructor(props:ColorPickerProps){
super(props)
}
static defaultProps:ColorPickerProps = {
inline: false,
popout: false,
tooltip: false,
defaultColor: true,
customColor: true,
baseColors: true
}
get modules(){
return ColorPickerModules || (ColorPickerModules = [
{
colorPickerCustom: "lc-colorPickerCustom",
customColorPickerInput: "lc-customColorPickerInput",
input: "lc-colorPicker-input",
colorPickerRow: "lc-colorPickerRow",
colorPickerSwatch: "lc-colorPickerSwatch",
custom: "lc-colorPicker-custom",
default: "lc-colorPicker-default",
disabled: "lc-colorPicker-disabled",
colorPickerDropper: "lc-colorPickerDropper",
noColor: "lc-colorPicker-noColor",
colorPickerDropperFg: "lc-colorPickerDropperFg"
},
WebpackLoader.find(e => e.flexMarginReset),
WebpackLoader.find(e => e.justifyStart && !e.streamerModeEnabled),
WebpackLoader.find(e => e.marginTop60 && !e.title),
WebpackLoader.findByUniqueProperties(["Messages"]).default.Messages
])
}
renderColorPicker(){
let [
colorPickerClasses,
flexClasses,
positionClasses,
marginClasses,
TranslationModule
] = this.modules
let defaultColor = this.props.defaultColor ? <div className={marginClasses.marginReset}>
<Tooltip text={TranslationModule.DEFAULT} position="bottom" color="black">
<button type="button" className={`${colorPickerClasses.colorPickerSwatch} ${colorPickerClasses.default}`} style={{
marginLeft: "0px",
backgroundColor: Constants.defaultColor
}} onClick={this.setColor.bind(this, Constants.defaultColor)}>
<svg aria-hidden="false" width="32" height="24" viewBox="0 0 24 24">
<path fill="#ffffff" fill-rule="evenodd" clip-rule="evenodd" d="M8.99991 16.17L4.82991 12L3.40991 13.41L8.99991 19L20.9999 7.00003L19.5899 5.59003L8.99991 16.17Z"></path>
</svg>
</button>
</Tooltip>
</div> : null
let customColor = this.props.customColor ? <div className={marginClasses.marginReset}>
<Tooltip text={TranslationModule.CUSTOM_COLOR} position="bottom" color="black">
<button type="button" className={`${colorPickerClasses.colorPickerSwatch} ${colorPickerClasses.default}`} style={{
marginLeft: "0px",
backgroundColor: Constants.defaultColor
}} onClick={this.setColor.bind(this, Constants.defaultColor)}>
<svg aria-hidden="false" width="32" height="24" viewBox="0 0 24 24">
<path fill="#ffffff" fill-rule="evenodd" clip-rule="evenodd" d="M8.99991 16.17L4.82991 12L3.40991 13.41L8.99991 19L20.9999 7.00003L19.5899 5.59003L8.99991 16.17Z"></path>
</svg>
</button>
</Tooltip>
</div> : null
return <div className={`${flexClasses.flex} ${flexClasses._horizontal} ${positionClasses.justifyStart} ${positionClasses.alignStretch} ${positionClasses.noWrap}`}>
{defaultColor}
{customColor}
</div>
}
renderPopout(){
}
setColor(color){
console.log(color)
}
render(){
let props = this.props
let returnValue = null
if(props.popout){
returnValue = this.renderPopout()
}else{
returnValue = this.renderColorPicker()
}
return returnValue
}
static get AllPreviews(){
return []
}
}
let AllPreviews
const Constants = {
defaultColor: "#99aab5"
}

View File

@ -0,0 +1,166 @@
import NOOP from "../../modules/noop"
import WebpackLoader from "../../modules/WebpackLoader"
import Tooltip from "../general/Tooltip"
import Utils from "../../modules/Utils"
const Constants = {
defaultColor: 10070709,
baseColors: [
1752220,
3066993,
3447003,
10181046,
15277667,
15844367,
15105570,
15158332,
9807270,
6323595,
1146986,
2067276,
2123412,
7419530,
11342935,
12745742,
11027200,
10038562,
9936031,
5533306
]
}
type ColorPickerProps = {
defaultColor?: number,
customColor?: number,
baseColors?: number[],
value?: string,
disabled?: boolean,
onChange?: (color:number) => void
}
let ColorPickerModules
let isFetching = null
export default class ColorPicker extends React.PureComponent<ColorPickerProps, {value?:string,lastColor:any}> {
constructor(props:ColorPickerProps){
super(props)
this.state = {
value: props.value || null,
lastColor: this.props.value
}
this.onChange = this.onChange.bind(this)
}
onChange(val){
this.props.onChange(val)
this.setState({
value: val
})
this.forceUpdate()
}
static defaultProps:ColorPickerProps = {
defaultColor: Constants.defaultColor,
customColor: null,
baseColors: Constants.baseColors,
value: null,
disabled: false,
onChange: NOOP
}
get modules(){
return ColorPickerModules || (ColorPickerModules = [
WebpackLoader.find(e => e.default && e.default.displayName === "ColorPicker")
])
}
renderColorPicker(){
let [
ColorPickerComponent
] = this.modules
if(!ColorPickerComponent){
if(isFetching)isFetching.then(e => this.forceUpdate()) // support for multiple color picker
ColorPickerModules = null
let resolve
isFetching = new Promise(res => (resolve = res))
const GuildSettingsRoles = new (WebpackLoader.find(e => e.default && e.default.displayName && e.default.displayName.includes("GuildSettingsRoles")).default)().render().type
const settings = GuildSettingsRoles.prototype.renderRoleSettings.call({
props: {
guild: {
roles: [],
id: null,
isOwner: () => false
},
currentUser: {
id: null
}
},
getSelectedRole(){
return {
id: null
}
}
})
const GuildRoleSettings = settings.props.children.type
let children = GuildRoleSettings.prototype.renderColorPicker.call({
props: {
role: {
id: null,
color: 0
},
locked: false,
everyone: false
}
}).props.children
children.type(children.props).props.children.type._ctor().then(c => {
this.forceUpdate()
resolve()
})
return null
}
return <ColorPickerComponent.default colors={this.props.baseColors} defaultColor={this.props.defaultColor} value={this.state.value}
disabled={this.props.disabled} onChange={this.onChange} customColor={this.props.customColor}>
</ColorPickerComponent.default>
}
render(){
if(this.state.lastColor !== this.props.value){
this.state = {
value: this.props.value,
lastColor: this.props.value
}
}
return this.renderColorPicker()
}
static get AllPreviews(){
return AllPreviews || (() => {
AllPreviews = []
AllPreviews.push([
{
disabled: false
},
{
disabled: true
}
], [
{
value: Utils.HexColorToDecimal("#7289DA")
}, {
value: null
}
], [
{
onChange: (color) => {}
}
])
return AllPreviews
})()
}
static help = {
info: "To convert hex colors to decimal, you can do `Lightcord.Api.Utils.HexColorToDecimal('#yourcolor')` and go back with `Lightcord.Api.Utils.DecimalColorToHex(7506394)`"
}
}
let AllPreviews

View File

@ -1,8 +1,6 @@
import NOOP from "../../modules/noop" import NOOP from "../../modules/noop"
import WebpackLoader from "../../modules/WebpackLoader" import WebpackLoader from "../../modules/WebpackLoader"
import { ReactNode, CSSProperties } from "react" import { ReactNode, CSSProperties } from "react"
import Utils from "../../modules/Utils"
import unfreeze from "../../modules/Unfreeze"
type DropdownProps = { type DropdownProps = {
className?: string, className?: string,

View File

@ -94,5 +94,9 @@ export default class Switch extends React.Component<SwitchProps, {value: boolean
return AllPreviews return AllPreviews
})() })()
} }
static help = {
error: "The `clear` option doesn't work well on light theme."
}
} }
let AllPreviews let AllPreviews

View File

@ -159,5 +159,9 @@ export default class TextArea extends React.Component<TextAreaProps, {value: str
return AllPreviews return AllPreviews
})() })()
} }
static help = {
warn: "This should be used for multi line inputs."
}
} }
let AllPreviews let AllPreviews

View File

@ -129,5 +129,9 @@ export default class TextInput extends React.PureComponent<TextInputProps, {valu
return AllPreviews return AllPreviews
})() })()
} }
static help = {
warn: "This should be used for single line inputs."
}
} }
let AllPreviews let AllPreviews

View File

@ -20,4 +20,15 @@ export default new class Utils {
} }
return obj return obj
} }
DecimalColorToHex(color:number):string{
return "#"+color.toString(16)
}
HexColorToDecimal(color:string):number{
color = color.replace(/[#;]/g, "")
let res = parseInt(color, 16)
if(isNaN(res))throw new Error(`Invalid color: ${color}`)
return res
}
} }

View File

@ -7,7 +7,11 @@ export default new class WebpackLoader {
return BDModules.get(id) return BDModules.get(id)
} }
find(filter: (mod:any) => boolean):any{ find(filter: (mod:any) => boolean):any{
return BDModules.get(filter)[0] let result = BDModules.get(filter)[0]
if(!result){
console.warn(filter, "couldn't find the module.")
}
return result
} }
findByUniqueProperties(props:(string|number)[]):any{ findByUniqueProperties(props:(string|number)[]):any{
return BDModules.get((mod) => { return BDModules.get((mod) => {

View File

@ -143,3 +143,45 @@
.lc-link-disabled-span:hover { .lc-link-disabled-span:hover {
cursor: pointer; cursor: pointer;
} }
/** Alert Box */
.lc-alert-box {
margin: 20px 0;
padding: 10px;
border-radius: 5px;
font-size: 14px;
font-weight: 300;
line-height: 22px;
}
.lc-alert-box strong {
font-weight: 900
}
.lc-alert-box span {
color: hsla(0,0%,100%,.9);
margin: 0!important
}
.lc-alert-box.lc-alert-box-warn {
background: rgba(250,166,26,.1);
border: 2px solid rgba(250,166,26,.5);
}
.lc-alert-box.lc-alert-box-info {
background: rgba(114,137,218,.1);
border: 2px solid rgba(114,137,218,.5);
}
.lc-alert-box.lc-alert-box-danger {
background: rgba(240,71,71,.1);
border: 2px solid rgba(240,71,71,.5);
}
.lc-alert-box.lc-alert-box-error {
background: rgba(240,71,71,.1);
border: 2px solid rgba(240,71,71,.5);
}
.lc-alert-box.lc-alert-box-success {
background: rgba(67,181,129,.1);
border: 2px solid rgba(67,181,129,.5)
}
.lc-blockquote > div {
margin-bottom: 0!important;
}