README
react-kekkai
It's a component library for React, and named 'Kekkai'(Japanese). Let's see Kekkai via the agenda as follows:
What is Kekkai
Kekkai provided 5 components to build the common data layout(such as Form / Grid / Card). You could use the same way to build the layout through these Kekkai components, and change layout via easy setting.
The pattern about using 5 components is...
<KekkaiContainer panel={LayoutOpts.List} view={data => (
<KekkaiDataview key={data.$uid} dataModel={data}>
<KekkaiField label="Name" name="fullName">
<KekkaiDisplay># {data.fullName}</KekkaiDisplay>
<KekkaiEditor required={true} validation={value =>
value.trim().length === 0 ? 'Name is required.' : true
}>
<input type="text" />
</KekkaiEditor>
</KekkaiField>
</KekkaiDataview>
)}/>
In Japanese, 'Kekkai' means magic circle, and the pattern just looks like a magic circle, so I named it as 'Kekkai' ^^.
About Install
Download from NPM
npm i react moment numeral react-kekkai -s
Import Kekkai
Except the kekkai components, also import the CSS.
import {
// Components
KekkaiContainer, KekkaiDataview, KekkaiField, KekkaiDisplay, KekkaiEditor,
// Option Enums
LayoutOpts, TriggerOpts, EditingOpts,
// Operations Building Helper
Todo, TodoScripts
} from 'react-kekkai';
import 'react-kekkai/dist/index.css';
5 Components
Using this pattern concept to accomplish building the different layout via the only one way. It will reduce our work for HTML, and make sure all the layout could follow the same business rule. Now, let's check the purposes of these 5 components:
<KekkaiContainer />
(API Documentation)
1<KekkaiContainer />
means 1 data source, all the data will work under the container.<KekkaiContainer />
is responsible for privding a basic Toolbar / Pagination, and allocating HTML Layout Panel.<KekkaiDataview />
(API Documentation)
1<KekkaiDataview />
means 1 data, so there will be many<KekkaiDataview />
in 1<KekkaiContainer />
. We use<KekkaiDataview />
to pack the data columns(field), and it provided Data-Row Selection / Menu.<KekkaiField />
(API Documentation)
<KekkaiField />
is used to pack Display and Editor, and responsible for switching them by data status on the right time. So, we don't need to use any skill to make up the switching control. It could also define the column layout under the different panel.<KekkaiDisplay />
(API Documentation)
<KekkaiField />
has provided a default<KekkaiDisplay />
to show value. If you wanna use different ways or format to show the value, you could override it by your own. This is responsibility of<KekkaiDisplay />
.<KekkaiEditor />
(API Documentation)
When data need to be edited, we could use<KekkaiEditor />
to pack the form items. We could also bind the events to append rule to control editable status / handle data changed / do validation and tip, and make every form item be unified into one solution by these 3 events. By the way, the form item which is packed by<KekkaiEditor />
must have supported properties of 'value' and 'onChange'.
API Documentation
After the introduction of Kekkai, let's see the API to know how to use Kekkai. (PS. '*' means required.)
Components
<KekkaiContainer />
Options(props)
*
ref
:string
Define a ref, we could call the methods through ref.panel
: LayoutOpts
Specify the HTML layout, default isLayoutOpts.List
.toolBgColor
:string
Define background-color of tool, default is#007bff
.toolTxColor
:string
Define text-color of tool, default iswhite
.pageSize
:number
Define data count in 1 page, and the allowed number is10
/25
/50
/100(means show all by infinite-scroll)
, default is10
.todos
: (Todo | TodoScripts)[]
Inject the data manipulations which are defined by yourself or Kekkai provided. If there is not anytodos
, users could only read the data in.
Events
*
getSearchResponse
:async ({ sort, filters, page}) => { data, total }
This is the most important event, all the data thatneeds are returned by it. You can also make up parameters of request and send request here. Check more as follows: Parameters
sort
:[{ name, dir }]
-name
:string
- means the field name of data.dir
:string
- It will only beasc
ordesc
.
filters
:[{ name, operator, value }]
-name
:string
- means the field name of data.operator
:string
- means condition, and it's defined by<KekkaiField />
's property:filter
.value
:any
- This is input by user filtering.
page
:{ page, pageSize, skip, start }
-page
:number
- The target page index of loading.pageSize
:number
- Data count of 1 page.skip
:number
- Skip count.start
:number
- Target start data index in the page.
Return:
{ data, total }
data
:Object[]
- When you get the data JSON array from response with await, please put the data JSON into this property.total
:number
- Set the total count of data to make pagination work.
*
view
: (data
) =><KekkaiDataview />
This event will be fired when Kekkai get the response data and convert JSON to KekkaiModel. KekkaiModel will be inputted in this event, so we could build<KekkaiDataview />
by it.Parameters
data
: KekkaiModel - The converted data from response.
Return:
<KekkaiDataview />
Defined layout of data.
onCommit
:async (todoRef, { target, modifieds, removes }) => { success, msg }
If there is any request-process intodos
, this event will be fired when user submit modifieds. We could get the target modified data to make up the parameters and send request here. Check more as follows:Parameters
todoRef
:string
- We could check what request should be sent by this parameter, and it's defined intodo
. Here are 2 cases that we should know:Specific Case:
Most manipulations and their own request process are explicitly and single, so we could get the only onetodoRef
that defined by ourself.Commit Case:
Kekkai provided inline-editing, and user could edit multiple data via this feature. No metter data is updated or created, we'll only gettodoRef
asKekkaiContainer.CommitAll
, and it means this commit is for all modified data.
target
: KekkaiModel[] - In specific case, we could get the request target data from this parameter.modifieds
: KekkaiModel[] - This parameter will be inputted when thetodoRef
isKekkaiContainer.CommitAll
, and it contains the updated and created data.removes
: KekkaiModel[] - This parameter will be inputted when thetodoRef
isKekkaiContainer.CommitAll
. It means the temporarily removed data.
Return:
{ success, msg }
success
:boolean
- The response result, set asfalse
will make Kekkai popup a Error Message Box, and the content ismsg
.msg
:string
- Error message.
Readonly Properties
panel
: LayoutOpts
Get current layout type.pager
: KekkaiPager
Get pagination manager. If you wanna change page size or index, you could use this property.data
: KekkaiModel[]
Get all data in current page.selecteds
: KekkaiModel[]
Get the selected data in current page.editings
: KekkaiModel[]
Get the editable data in current page.modifieds
: KekkaiModel[]
Get the dirty data in current page.
Methods
setAlert(content, { type, title, icon, callbackFn }): void
To show a message tip.- Parameters
*
content
:string
|React Element
- The message content.type
:string
- Define the background-color of message box, and the allowed values areinfo
/success
/warning
/danger
. Default isinfo
.title
:string
- The message title.icon
:string
- Set as a icon class name, such as Font-Awesome. By the way, Kekkai use Font Awesome 4.7 as default icon.callbackFn
:() => void
- This function will be called after the message box closed.
- Parameters
setConfirm(content, { type, title, icon, callbackFn }): void
To show a confirmed message.- Parameters
*
content
:string
|React Element
- The message content.type
:string
- Define the background-color of message box, and the allowed values areinfo
/success
/warning
/danger
. Default isinfo
.title
:string
- The message title.icon
:string
- Set as a icon class name, such as Font-Awesome. By the way, Kekkai use Font Awesome 4.7 as default icon.*
callbackFn
:(isConfirmed: boolean) => void
- This function will be called after the message box closed.
- Parameters
add(newData, { index }): void
Append new JSON data to<KekkaiContainer />
, and you could also specify the index of data(default is 0).edit(turnOn, { editData }): void
Turn on/off the editable status of data. If you haven't specified the target data, the default targets are all data.- Parameters
*
turnOn
:boolean
- Set astrue
to turn on editable, andfalse
to turn off.editData
: KekkaiModel | KekkaiModel[] - Specify one or more target data.
- Parameters
setExecuting({ todo, data, popup }): void
If there is a executingTodo
which has to storage temporarily, call this method. TheTodo
in temporary storage will be the top priority when you calldoCommit
.- Parameters
todo
:Todo
- Target temporary storageTodo
.data
: KekkaiModel - Target processed data, only support single data.popup
:boolean
- Iftodo
'seditingMode
is set asEditingOpts.POPUP
, please set this option astrue
to let<KekkaiContainer />
know it has to popup a editing modal.
- Parameters
async doSearch(filters, specifyPage): void
To load data. Event - getSearchResponse will be fired when called this method.async doRollback(showConfirm): void
To rollback all the modifieds of data, and you could also rollback without confirm message box.- Parameters
showConfirm
:boolean
- Default istrue
, and setting asfalse
could ignore confirming.
- Parameters
async doCommit(): void
To commit all the modifieds of data. Kekkai will make up the target process data according to manipulation situational from user, and puttodoRef
and data into Event - onCommit.
<KekkaiDataview />
Options(props)
*
key
:string
In React, the element array must be set a key, so our suggest is setting as KekkaiModel.$uid.*
dataModel
: KekkaiModel
Binding data to this<KekkaiDataview />
to make sure it could work.selectable
:boolean
|(data) => boolean
This option will be actived when the panel isLayoutOpts.List
orLayoutOpts.Card
. To define this<KekkaiDataview />
could be selected by user, and default is false. You could also set as a function to build business rules.- Parameters
data
: KekkaiModel - Kekkai will put the data into this function.
- Parameters
reorderable
:boolean
This option will be actived when the panel isLayoutOpts.List
. To define all the columns in<KekkaiDataview />
could be reorder by drag and drop.labelSize
:number
This option will be actived when the panel isLayoutOpts.Form
. To define all the<label />
's width, and the allowed values are between 1 ~ 12.viewSize
: RWD Options
This option will be actived when the panel isLayoutOpts.Card
. To define<KekkaiDataview />
's width, and default is{ def: 12 }
.
Events
onSelected
:(isChecked, data) => void
This event will be fired when user select the data by Data-Row Selection.- Parameters
isChecked
:boolean
-true
means data is selected, andfalse
is deselected.data
: KekkaiModel - The target data.
- Parameters
<KekkaiField />
- Options(props)
*
name
:string
Binding data field name.key
:string
If you wanna build a pseudo column, you must have to set this property. Just give it a unique name.*
label
:string
Define description for field. When panel isLayoutOpts.List
, this label will show on the header. In other panel, it will become<label />
.align
:string
Set the text-align in<KekkaiDisplay />
, default isleft
.sortable
:boolean
|{ seq, dir }
This option will make Kekkai generate sort parameters. Set astrue
means this column will be sortable.seq
:number
- Means priority order.dir
:string
- The allowed values areasc
ordesc
.
form
: RWD Options
When layout panel isLayoutOpts.Form
or in Kekkai Popup Modal, the column width is set by this option. Default is{ def: 12 }
.card
: RWD Options
When layout panel isLayoutOpts.Card
, the column width is set by this option. Default is{ def: 12 }
.list
:number
When layout panel isLayoutOpts.List
, the column width is set by this option. The number meanspx
, and default is120
.locked
:boolean
Only forLayoutOpts.List
. Set column as locked, default isfalse
.lockable
:boolean
Only forLayoutOpts.List
. Set column could be switched locked status by user, default isfalse
.hidden
:boolean
Only forLayoutOpts.List
. Set column as hidden, default isfalse
.hideable
:boolean
Only forLayoutOpts.List
. Set column could be switched hidden by user, default isfalse
.resizable
:boolean
Only forLayoutOpts.List
. Set column could be resized, default isfalse
.filter
:any
Only forLayoutOpts.List
. Kekkai will build a filter feature on the header which is like Excel. This option could define filter condition, such as'eq'
/'like'
. See your request parameter format to decide it.
<KekkaiDisplay />
There isn't not any options for this component. It's just used to pack the value format.
<KekkaiEditor />
Options(props)
required
:boolean
Set value as be required when user edits, default isfalse
.editable
:boolean
|(value, data) => boolean
This option will be used before Kekkai switch to edit mode. If this option value isfalse
or returnfalse
, that means this column wouldn't be switched to edit mode.Parameters
value
:any
- The current field value.data
: KekkaiModel - The data record.
Return:
boolean
Returntrue
orfalse
to tell Kekkai this column is able to be swtiched to edit mode.
Events
onChange
:(name, value, data) => void
This event is fired when field value changed.- Parameters
name
:string
- The field name of data.value
:any
- The new value.data
: KekkaiModel - The data record.
- Parameters
validation
:(name, value, data) => true | string
This event is fired afteronChange
, and we could check the data validation in this event. If data is valid, please returntrue
, or return the error message tip. Kekkai will popup a message tip when it get the error message.Parameters
name
:string
- The field name of data.value
:any
- The new value.data
: KekkaiModel - The data record.
Return:
true
|string
true
means valid, andstring
is error message.
Options
LayoutOpts
This option will be used in <KekkaiContainer />
. There are 3 kinds layout, see as follows:
Card:
LayoutOpts.Card
Card layout is built byLayout-Grid
&Components-Card
from Bootstrap 4.0. We could use it to show multiple data, and it's RWD design. Under this panel, there isn't any Data-Row Selection, all the manipulations about Selection and Row Double Click will become to be trigger by Data-Row Menu.
PS. I wanna append data sort feature on the label in the future.Form:
LayoutOpts.Form
Form layout is built byLayout-Grid
from Bootstrap 4.0, and it's also RWD design. In Kekkai, if setpanel
asLayoutOpts.Form
, thepageSize
will become to1
. Yes, it means show only one data in Kekkai, so all the manipulations about data could only be trigger by Toolbar. By the way, when Kekkai wanna generate a popup modal of single data, the content layout in modal are form the options of form.List:
LayoutOpts.List
Show data by list. List layout has 2 blocks: one is locked on the left, and one is scrollable on the right. Under this panel, user could adjust the columns layout, such as width / hidden / order / locked / data sort, and also could use data filter feature on the header. It distributes the manipulations into 4 kinds: Toolbar / Selection / Row Menu / Row Double Click.
TriggerOpts
This option will be bound in Todo or TodoScripts. Kekkai distributes the manipulations about data into 4 kinds, and all the trigger ways are different. As follows:
TOOLBAR:
TriggerOpts.TOOLBAR
It means a initially state. It will be default shown on the Toolbar, but if user selects any data, the toolbar buttons will be hidden(become to Selection-Mode).SELECTION:
TriggerOpts.SELECTION
This trigger is different from TOOLBAR, and it means Selection-Mode. When user selects data through Data-Row Selection, the selection button will be visible on the Toolbar.ROW_MENU:
TriggerOpts.ROW_MENU
It means single-selection, so Kekkai will build a menu to show them on the row. This menu will only be visible when there isn't any data which is selected or on editing.ROW_DBCLICK:
TriggerOpts.ROW_DBCLICK
This trigger also means single-selection, but there could be only one Todo set as ROW_DBCLICK at most.
EditingOpts
If you want to set data as editable when Todo is executing, you need to bind this option to Todo.
INLINE:
EditingOpts.INLINE
Means inline editing, edit data with popup modal. It's for multiple case.POPUP:
EditingOpts.POPUP
Means editing by popup modal, and it's for single case.
RWD Options
This option is base on Bootstrap 4.0, and it was designed from the default 5 sizes from Boostrap.
- Default type is
{ def, sm, md, lg, xl }
def
:false
|number
Allowed numbers are between 1 ~ 12, andfalse
means hidden. Default is12
.sm
:false
|number
Allowed numbers are between 1 ~ 12, andfalse
means hidden.md
:false
|number
Allowed numbers are between 1 ~ 12, andfalse
means hidden.lg
:false
|number
Allowed numbers are between 1 ~ 12, andfalse
means hidden.xl
:false
|number
Allowed numbers are between 1 ~ 12, andfalse
means hidden.
Base Types
KekkaiModel
This type is built in <KekkaiContainer />
when it get the data JSON array, so we don't need to construct it by ourself.
Readonly Properties
[data field name]
:any
If you wanna get / set the field value, you could use like as follows.- getter:
console.log(data.fullName);
- setter:
data.fullName = 'Tom';
- getter:
$uid
:string
Get the unique key of data.$json
:Object
Get the values JSON from data.$isNew
:boolean
Check data is the new created.$isValid
:boolean
Check data is valid.$editable
:boolean
To know data is editing or not.$checked
:boolean
To know data is selected or not.$hidden
:boolean
To know data is hidden or not.$isDirty
:boolean
To know data is modified or not.
Methods
$setHidden(hidden): boolean
Set data as hidden on the view.Parameters
hidden
:boolean
-true
means hidden, andfalse
means visible. Default isfalse
.
Return:
boolean
Get the last hidden result.
$setEditable(turnOn): boolean
Set data as editing.Parameters
turnOn
:boolean
-true
means show<KekkaiEditor />
, andfalse
means display. Default isfalse
.
Return:
boolean
Get the last editable result.
$setChecked(checked): boolean
Set data as selected.Parameters
checked
:boolean
-true
means selected, andfalse
means deselected. Default isfalse
.
Return:
boolean
Get the last selected result.
$getValid(name): boolean | string
Get the specify field's validation result.Parameters
name
:string
- Target field name.
Return:
boolean
|string
true
means data is valid, andstring
is the error message.
$undo(): void
Remove all the modifieds to restore data to initially, but couldn't remove new created data.
KekkaiPager
This type is built in <KekkaiContainer />
, so we never and ever need to construct it by ourself. We could get this pager from <KekkaiContainer />
.pager, and then override its options.
Readonly Properties
pageSize
-number
Get data count of one page, and this property is allowed to set value. If you wanna change pageSize, you could use like this:pager.pageSize = 25;
.skip
-number
Get how many data is skipped.start
-number
Get the start data index in current page.end
-number
Get the end data index in current page.total
-number
Get the total data count from current searching.page
-number
Get current page index, and this property is allowed to set value. If you wanna change it, you could use like this:pager.page = 3;
.maxPage
-number
Get the last page index.
Methods
toNext(): void
Go to next page.toPrev(): void
Go to previous page.toFirst(): void
Go to the first page.toLast(): void
Go to the last page.
Todo
Kekkai provided this type to let us build data manipulations more quickly. Though constructing Todo
, we don't need to put <button />
on HTML, and also think how to accomplish the control rules. All the controls are packed in Kekkai, we just set options and inject checking/executing function at most. Let's see how to build the Todo
:
new Todo({
ref: string,
concat: string,
text: string,
icon: string,
trigger: TriggerOpts,
editingMode: EditingOpts,
executable: () => boolean,
execute: () => void,
onSuccess: () => void,
confirmMsg: { type: string, icon: string, title: string, content: string },
responseMsg: { type: string, icon: string, title: string, content: string }
})
- Constructor Parameters
*
ref
:string
Give theTodo
a reference key. This key wouldn't be unique, it's just used to decide the committed data how to process in<KekkaiContainer />
's Event - onCommit.concat
:string
If there are the same 2 concatsTodo
in one<KekkaiContainer />
, Kekkai will help us to build them as a dropdown menu in Toolbar.*
text
:string
Give theTodo
a display name.icon
:string
Set as a icon class name, such as Font-Awesome. By the way, Kekkai use Font Awesome 4.7 as default icon.*
trigger
: TriggerOpts
Kekkai will generate a trigger way via this option, see TriggerOpts.editingMode
: EditingOpts
See EditingOpts and<KekkaiContainer />
's Method - setExecuting.executable
:({ data, list }, container) => boolean
Inject a function which will returnboolean
, and Kekkai will check thisTodo
is able to execute on the right time.Parameters
data
: KekkaiModel - Single target data, this parameter will be actived whentrigger
is set asTriggerOpts.ROW_MENU
orTriggerOpts.ROW_DBCLICK
.list
: KekkaiModel[] - Multiple target data, this parameter will be actived whentrigger
is set asTriggerOpts.TOOLBAR
orTriggerOpts.SELECTION
.container
:<KekkaiContainer />
- Owner<KekkaiContainer />
.
Return:
boolean
Return aboolean
value to tell Kekkai thisTodo
could be executed.
*
execute
:({ data, list }, container) => void
Inject a function to define thisTodo
need to do what.- Parameters
data
: KekkaiModel - Single target data, this parameter will be actived whentrigger
is set asTriggerOpts.ROW_MENU
orTriggerOpts.ROW_DBCLICK
.list
: KekkaiModel[] - Multiple target data, this parameter will be actived whentrigger
is set asTriggerOpts.TOOLBAR
orTriggerOpts.SELECTION
.container
:<KekkaiContainer />
- Owner<KekkaiContainer />
.
- Parameters
onSuccess
:({ success, msg }, container) => void
This option is actived whenTodo
is a request case, and it will be used in<KekkaiContainer />
's Method - doCommit. For make sure this option could work, don't forget to call<KekkaiContainer />
's Method - setExecuting inexecute
.- Parameters
success
:boolean
- It means the result of request, and it's from the return value in<KekkaiContainer />
's Method - doCommit. Set it asfalse
and give amsg
indoCommit
, Kekkai will popup a message tip.true
means request is fine.msg
:string
- This message is from the return value in<KekkaiContainer />
's Method - doCommit.container
:<KekkaiContainer />
- Owner<KekkaiContainer />
.
- Parameters
confirmMsg
:{ type, icon, title, content }
This option will effect Kekkai should popup a confirmed message or not before executing.- Parameters
type
:string
- Define the background-color of message box, and the allowed values areinfo
/success
/warning
/danger
. Default isinfo
.icon
:string
- Set as a icon class name, such as Font-Awesome. By the way, Kekkai use Font Awesome 4.7 as default icon.title
:string
- The message title.*
content
:string
|React Element
- The message content.
- Parameters
responseMsg
:{ type, icon, title, content }
This option will effect Kekkai should popup a message tip afteronSuccess
, and this option is actived when request result is successfully.- Parameters
type
:string
- Define the background-color of message box, and the allowed values areinfo
/success
/warning
/danger
. Default isinfo
.icon
:string
- Set as a icon class name, such as Font-Awesome. By the way, Kekkai use Font Awesome 4.7 as default icon.title
:string
- The message title.*
content
:string
|React Element
- The message content.
- Parameters
TodoScripts
Finally, even we could build data manipulations by Todo, but the options still seem some complicated. Never mind, that's why I add these TodoScripts
, to build data manipulations more and more quickly. After the explanation about Todo
, you will understand this part more easier.
All the data manipulations are relational with CRUD. Read is built in <KekkaiContainer />
, so I built Create, Update and Delete in TodoScripts
, and packed the <KekkaiContainer />
method in these scripts(it means we don't have to know when need to call setExecuting
/ add
/ edit
...). As follows:
- CREATE:
TodoScripts.CREATE(options)
Use this script to build created manipulation, the most important is you need to return a JSON values inoverrideParams
. Let's see what options are allowed or what you can override in this script:
TodoScripts.CREATE({
editingMode, // Default is EditingOpts.POPUP
ref, // * Required
text, // * Required
concat,
icon,
executable,
onSuccess,
responseMsg, // Default is { type: 'success', icon: 'fa fa-check-square-o', content: '資料已完成新增' }
overrideParams() { // * Required, must return new JSON data in this function
return {
fullName: 'Tom',
age: 13
};
}
});
- UPDATE:
TodoScripts.UPDATE(options)
In this script,overrideParams
is not a required option, and addtrigger
could be override.
TodoScripts.UPDATE({
trigger, // Default is TriggerOpts.ROW_DBCLICK
editingMode, // Default is EditingOpts.POPUP
ref, // * Required
text, // * Required
concat,
icon,
executable,
onSuccess,
responseMsg, // Default is { type: 'success', icon: 'fa fa-check-square-o', content: '資料已完成修改' }
overrideParams(data) { // Set default value before editing.
data.age = parseFloat(data.age);
}
})
- DELETE:
TodoScripts.DELETE(options)
There are too many ways to triggerDELETE
, so this script doesn't provide a default value. If you don't need to confirm with user when executing, please setconfirmMsg
asundefined
orfalse
. TheoverrideParams
isn't also a required option, but if you wanna change data values before sending request, you'll need it.
TodoScripts.DELETE({
trigger, // * Required
ref, // * Required
text, // * Required
concat,
icon,
executable,
onSuccess,
confirmMsg, // Default is { type: 'info', icon: 'fa fa-question-circle', title: '資料即將被刪除', content: '確定刪除所選取之資料 ?' }
responseMsg, // Default is { type: 'success', icon: 'fa fa-check-square-o', content: '資料已完成修改' }
overrideParams(data) { // Change data values before sending request
data.age = null;
}
})
by Taco (tabacotaco@gmail.com)