Working on LightcordApi

This commit is contained in:
Jean Ouina 2020-08-04 13:17:51 +02:00
parent eb62f9a9a7
commit f82bd92ff5
12 changed files with 826 additions and 178 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -13,7 +13,11 @@ import cloneNullProto from "../modules/cloneNullProto"
import Tooltip from "./general/Tooltip"
import ColorPicker from "./inputs/ColorPicker"
import AlertBox from "./general/AlertBox"
import { createProxyErrorCatcherClass } from "./private/ErrorCatcher"
import ErrorCatcher, { createProxyErrorCatcherClass } from "./general/ErrorCatcher"
import Flex, { FlexChild } from "./general/Flex"
import Text from "./general/Text"
import DateRange from "./inputs/DateRange"
import DateInput from "./inputs/DateInput"
const RadioGroupProxied = createProxyErrorCatcherClass(RadioGroup)
export default cloneNullProto({
@ -25,7 +29,9 @@ export default cloneNullProto({
TextArea: createProxyErrorCatcherClass(TextArea),
TextInput: createProxyErrorCatcherClass(TextInput),
Dropdown: createProxyErrorCatcherClass(Dropdown),
ColorPicker: createProxyErrorCatcherClass(ColorPicker)
ColorPicker: createProxyErrorCatcherClass(ColorPicker),
//DateRange: createProxyErrorCatcherClass(DateRange),
//DateInput: createProxyErrorCatcherClass(DateInput)
}),
general: cloneNullProto({
Title: createProxyErrorCatcherClass(Title),
@ -34,6 +40,10 @@ export default cloneNullProto({
Tabs: createProxyErrorCatcherClass(Tabs),
CodeBlock: createProxyErrorCatcherClass(CodeBlock),
Tooltip: createProxyErrorCatcherClass(Tooltip),
AlertBox: createProxyErrorCatcherClass(AlertBox)
AlertBox: createProxyErrorCatcherClass(AlertBox),
Flex: createProxyErrorCatcherClass(Flex),
FlexChild: createProxyErrorCatcherClass(FlexChild),
ErrorCatcher: ErrorCatcher,
Text: Text
})
})

View File

@ -3,6 +3,8 @@ import WebpackLoader from "../../modules/WebpackLoader";
import DiscordTools from "../../modules/DiscordTools";
import NOOP from "../../modules/noop";
import uuid from "../../modules/uuid";
import Title from "./Title";
import AlertBox from "./AlertBox";
type ErrorCatcherProps = {
@ -18,6 +20,10 @@ export default class ErrorCatcher extends React.Component<ErrorCatcherProps, {er
}
}
static get original(){
return ErrorCatcher
}
get modules():any[]{
return ErrorCatcherModules || (ErrorCatcherModules = [
WebpackLoader.find(e => e.emptyStateImage && e.emptyState)
@ -71,8 +77,20 @@ export default class ErrorCatcher extends React.Component<ErrorCatcherProps, {er
error: true
})
}
static get AllPreviews(){
return AllPreviews || (AllPreviews = [
[
{
children: <AlertBox type="info">This AlertBox is protected by an ErrorCatcher.</AlertBox>
}
]
])
}
}
let AllPreviews
export function createProxyErrorCatcherClass<base = Function>(Class:base):base & {
readonly original: base
}{

View File

@ -0,0 +1,112 @@
import WebpackLoader from "../../modules/WebpackLoader"
import { ReactNode, CSSProperties } from "react"
type FlexProps = {
className?: string,
align?: string,
justify?: string,
direction?: string,
shrink?: number,
grow?: number,
basis?: "auto"|string,
children: ReactNode,
style?: CSSProperties
}
function getModules(){
return FlexModules || (FlexModules = [
(() => {
let Flex = WebpackLoader.find(e => e.default && e.default.displayName === "Flex")
if(Flex)Flex = Flex.default
return Flex
})()
])
}
let FlexModules
export default class Flex extends React.Component<FlexProps> {
constructor(props:FlexProps){
super(props)
}
get modules(){
return getModules()
}
render(){
let [
FlexComponent
] = this.modules
return <FlexComponent {...this.props} />
}
static get Direction(){
return getModules()[0].Direction as {
VERTICAL: string,
HORIZONTAL: string,
HORIZONTAL_REVERSE: string
}
}
static get Align(){
return getModules()[0].Align as {
START: string,
END: string,
CENTER: string,
STRETCH: string,
BASELINE: string
}
}
static get Justify(){
return getModules()[0].Justify as {
START: string,
END: string,
CENTER: string,
BETWEEN: string,
AROUND: string
}
}
static get Wrap(){
return getModules()[0].Justify as {
NO_WRAP: string,
WRAP: string,
WRAP_REVERSE: string
}
}
static get AllPreviews(){
return AllPreviews || (() => {
AllPreviews = []
AllPreviews.push([{
children: "Your components here."
}])
return AllPreviews
})()
}
}
let AllPreviews
export type FlexChildProps = {
children: ReactNode,
className?: string,
grow?: number,
style?: CSSProperties,
wrap?: boolean
}
export class FlexChild extends React.Component<FlexChildProps> {
get modules(){
return getModules()
}
render(){
const [
FlexComponent
] = this.modules
return <FlexComponent.Child {...this.props} />
}
}

View File

@ -1,71 +1,3 @@
/**
* TODO: Add margin component
*/
import WebpackLoader from "../../modules/WebpackLoader"
type CodeBlockProps = {
language?: string,
content: string
}
let CodeBlockModules
export default class CodeBlock extends React.Component<CodeBlockProps> {
static defaultProps:CodeBlockProps = {
language: "plaintext",
content: ""
}
get modules(){
return CodeBlockModules || (CodeBlockModules = [
WebpackLoader.find(e => e.markup),
WebpackLoader.find(e => e.messageContent),
WebpackLoader.find(e => e.scrollbarGhostHairline),
WebpackLoader.find(e => e.highlight),
WebpackLoader.find(e => e.marginBottom8)
])
}
render(){
let [
messageModule1,
messageModule2,
scrollbarModule1,
hightlightJS,
marginModule1
] = this.modules
const code = this.props.language === "plaintext" ? <code className={`${scrollbarModule1.scrollbarGhostHairline} hljs`}>
{this.props.content}
</code> : <code className={`${scrollbarModule1.scrollbarGhostHairline} hljs`}
dangerouslySetInnerHTML={{__html: hightlightJS.highlight(this.props.language, this.props.content).value}} />
return (<div className={`${messageModule1.markup} ${messageModule2.messageContent}`}>
<pre>
{code}
</pre>
<div className={marginModule1.marginBottom8}></div>
</div>)
}
static get AllPreviews(){
return AllPreviews || (() => {
AllPreviews = []
AllPreviews.push([
{
content: "console.log(\"Exemple code\")"
}
])
AllPreviews.push([
{
language: "js"
},
{
language: "plaintext"
},
...CodeBlock.prototype.modules[3].listLanguages().filter(e => e !== "js").map(e => ({language: e}))
])
return AllPreviews
})()
}
}
let AllPreviews

View File

@ -0,0 +1,95 @@
import * as React from "react"
import Utils, { ColorName } from "../../modules/Utils"
export type TextProps = {
weight?: TextWeight,
color?: TextColor|string,
textCase?: TextCase,
size?: TextSize,
selectable?: boolean,
family?: TextFamily,
children: string,
tag?: string,
className?: string,
style?: React.CSSProperties
}
export default class Text extends React.Component<TextProps> {
render(){
let classList = this.props.className ? this.props.className.split(" ") : []
let style = this.props.style ? {...this.props.style} : {}
style.flexGrow = 0
if(this.props.weight){
classList.push(`lc-text-weight${Utils.firstLetterUppercase(this.props.weight)}`)
}
if(this.props.color){
style.color = Utils.getColor(this.props.color as TextColor) || this.props.color
}
if(this.props.textCase){
classList.push(`lc-text-cases${Utils.firstLetterUppercase(this.props.textCase)}`)
}
if(this.props.size){
classList.push(...Constants.sizes[this.props.size])
}
if(this.props.family){
classList.push(`lc-text-${this.props.family}`)
}
if(this.props.selectable){
classList.push("lc-text-selectable")
}
return React.createElement(this.props.tag, {
style,
className: classList.join(" ")
}, this.props.children)
}
static defaultProps:TextProps = {
tag: "div",
children: null
}
static get AllPreviews(){
return AllPreviews || (AllPreviews = [
this.weights.map(e => ({weight: e})),
this.colors.map(e => ({color: e})),
this.textCases.map(e => ({textCase: e})),
this.sizes.map(e => ({size: e})),
this.familys.map(e => ({family: e})),
[
{
children: "Test Text"
}
],
["div","p",...Utils.executeXTimes((index) => {
return "h"+(index+1)
}, 6)].map(e => ({tag: e})),
[true, false].map(e => ({selectable: e}))
])
}
static weights:TextWeight[] = ["light", "normal", "medium", "semibold", "bold"]
static get colors():TextColor[]{
return Object.keys(Lightcord.DiscordModules.constants.Colors).map(e => e.toLowerCase()) as TextColor[]
}
static textCases:TextCase[] = ["lowercase", "uppercase"]
static sizes:TextSize[] = ["small", "medium", "medium_small", "medium_large", "large"]
static familys:TextFamily[] = ["primary", "code"]
}
let AllPreviews
export type TextWeight = "light"|"normal"|"medium"|"semibold"|"bold"
export type TextColor = ColorName
export type TextCase = "lowercase"|"uppercase"
export type TextSize = "small"|"medium"|"medium_small"|"medium_large"|"large"
export type TextFamily = "primary"|"code"
export const Constants = {
sizes: {
small: ["lc-text-size12", "lc-text-height16"],
medium_small: ["lc-text-size14", "lc-text-height16"],
medium: ["lc-text-size16", "lc-text-height20"],
medium_large: ["lc-text-size20", "lc-text-height26"],
large: ["lc-text-size28", "lc-text-height34"]
}
}

View File

@ -1,8 +1,6 @@
import NOOP from "../../modules/noop"
import WebpackLoader from "../../modules/WebpackLoader"
import Tooltip from "../general/Tooltip"
import Utils from "../../modules/Utils"
import { createProxyErrorCatcherClass } from "../private/ErrorCatcher"
const Constants = {
defaultColor: 10070709,

View File

@ -0,0 +1,46 @@
/** TODO: Finish DateInput */
import * as React from "react"
import { DateConstants } from "./DateRange"
export type DateInputProps = {
className?: string,
dateFormat?: string,
defaultValue: Date,
filterDate?: () => any,
isModalInput?: boolean,
maxDate?: Date,
minDate?: Date,
onChange?: () => void,
selectsStart?: boolean,
showMonthYearPicker?: boolean,
startDate?: Date,
endDate?: Date
style?: React.CSSProperties
}
export default class DateInput extends React.Component<DateInputProps> {
static defaultProps:Partial<DateInputProps> = {
dateFormat: DateConstants.DATE_FORMAT,
isModalInput: false
}
constructor(props:DateInputProps){
super(props)
this.state = {
inputResetKey: 0,
isCalendarPickerOpen: false,
calendarRight: null,
calendarTop: null,
value: props.defaultValue
}
}
componentDidUpdate(e:DateInputProps){
const defaultValue = this.props.defaultValue
const dateFormat = this.props.dateFormat
if (e.defaultValue !== defaultValue && null != defaultValue) {
}
}
}

View File

@ -0,0 +1,108 @@
/** TODO: Finish DateRange */
import * as React from "react"
import Flex, { FlexChild } from "../general/Flex"
import Text from "../general/Text"
export const DateConstants = {
DATE_FORMAT: "yyyy-MM-dd"
}
export type DateRangeProps = {
dateFormat?: string,
defaultEnd: Date,
defaultStart: Date,
className?: string,
onChange?: (start:Date, end:Date) => void,
maxDate?:Date,
minDate?:Date,
filterDate?:() => void,
showMonthYearPicker: boolean
}
export default class DateRange extends React.Component<DateRangeProps, {
end: Date,
start: Date
}> {
static defaultProps:Partial<DateRangeProps> = {
dateFormat: DateConstants.DATE_FORMAT
}
static displayName = "DateRange"
constructor(props:DateRangeProps){
super(props)
this.state = {
end: props.defaultEnd,
start: props.defaultStart
}
}
componentDidUpdate(oldProps:DateRangeProps){
let defaultStart = this.props.defaultStart
if(oldProps.defaultStart !== defaultStart){
this.setState({
start: defaultStart
})
}
}
handleEndChange(end:Date){
this.setState({
end: end
}, this.handleChange)
}
handleStartChange(start:Date){
this.setState({
start: start
}, this.handleChange)
}
getMaxDate(){
if(this.props.maxDate)return this.props.maxDate
return null
}
getMinDate(){
if(this.props.minDate)return this.props.minDate
return null
}
handleChange(){
const onChange = this.props.onChange
if(onChange == null)return
const state = this.state
const start = state.start
const end = state.end
onChange(start, end)
}
render(){
const state = this.state
const start = state.start
const end = state.end
const props = this.props
const filterDate = props.filterDate
const showMonthYearPicker = props.showMonthYearPicker
return <Flex className="lc-dateWrapper">
<FlexChild grow={0}>
<Text className="lc-dateLabel" size="small"
textCase="uppercase" weight="semibold" color="primary_dark_300">
FROM
</Text>
</FlexChild>
<FlexChild grow={0}>
</FlexChild>
<FlexChild grow={0}>
<Text className="lc-dateLabel" size="small"
textCase="uppercase" weight="semibold" color="primary_dark_300">
TO
</Text>
</FlexChild>
<FlexChild grow={0}>
</FlexChild>
</Flex>
}
}

File diff suppressed because one or more lines are too long

View File

@ -180,8 +180,85 @@
background: rgba(67,181,129,.1);
border: 2px solid rgba(67,181,129,.5)
}
.lc-blockquote > div {
margin-bottom: 0!important;
}
}
/** Text */
/*cases*/
.lc-text-casesUppercase {
text-transform: uppercase
}
.lc-text-casesLowercase {
text-transform: lowercase
}
/*weight*/
.lc-text-weightLight {
font-weight: 300
}
.lc-text-weightNormal {
font-weight: 400
}
.lc-text-weightMedium {
font-weight: 500
}
.lc-text-weightSemibold {
font-weight: 600
}
.lc-text-weightBold {
font-weight: 700
}
/*sizes*/
.lc-text-size12 {
font-size: 12px;
}
.lc-text-size14 {
font-size: 14px;
}
.lc-text-size16 {
font-size: 16px;
}
.lc-text-size20 {
font-size: 20px;
}
.lc-text-size28 {
font-size: 28px;
}
/*height*/
.lc-text-height16 {
line-height: 16px
}
.lc-text-height20 {
line-height: 20px
}
.lc-text-height26 {
line-height: 26px
}
.lc-text-height34 {
line-height: 34px
}
/*family*/
.lc-text-primary {
font-family: Whitney,Helvetica Neue,Helvetica,Arial,sans-serif
}
.lc-text-code {
font-family: SourceCodePro,Whitney,Helvetica Neue,Helvetica,Arial,sans-serif
}
/*selectable*/
.lc-text-selectable {
cursor: text;
-webkit-user-select: text;
-moz-user-select: text;
-ms-user-select: text;
user-select: text
}
/** DateRange */
.lc-dateWrapper {
padding-top: 8px
}