Skip to content

Commit c9dd8f4

Browse files
committed
narrow api, update example in playground
1 parent 6f71700 commit c9dd8f4

File tree

6 files changed

+78
-43
lines changed

6 files changed

+78
-43
lines changed

.eslintrc.js

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ module.exports = {
2828
quotes: [1, "single"],
2929
indent: "off",
3030
"react/prop-types": 0,
31+
"react/display-name": 0,
3132
"@typescript-eslint/indent": ["error", 2],
3233
"@typescript-eslint/explicit-function-return-type": "off",
3334
"@typescript-eslint/no-explicit-any": "off",

packages/playground/index.js

+27-15
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
import React, { useEffect, useState, Fragment } from 'react'
1+
import React, { useEffect } from 'react'
22
import { render } from 'react-dom'
33
import cms from 'netlify-cms-app'
44
import { Widget as IdWidget } from '@ncwidgets/id'
5-
// import { Widget as ReorderWidget } from '@ncwidgets/reorder'
5+
import { Widget as ReorderWidget, createControl } from '@ncwidgets/reorder'
66
import { Widget as FileRelationWidget } from '@ncwidgets/file-relation'
7-
import { createWidget as createReorderWidget } from '@ncwidgets/reorder'
87

98
const loadData = async (dataPath) => {
109
const data = await fetch(dataPath)
@@ -20,27 +19,40 @@ const createRoot = () => {
2019
return $root
2120
}
2221

22+
const ListComponent = ({ item }) => (
23+
<>
24+
<strong>{item.title}</strong>
25+
<p style={{ margin: 0, color: '#798291', fontSize: '0.8rem' }}>{item.id}</p>
26+
</>
27+
)
28+
29+
const CustomReorderPreview = ({ value }) => (
30+
<section>
31+
<hr />
32+
<p>Custom Widget Preview</p>
33+
{value.map((item, i) => <p key={i}>{item.get('title')}</p>)}
34+
</section>
35+
)
36+
37+
const CustomReorderControl = createControl({
38+
renderListItem: item => <ListComponent item={item} />
39+
})
40+
2341
const CMS = () => {
2442
useEffect(() => {
2543
loadData('./data.json')
2644

27-
const ListComponent = ({ item }) =>
28-
<Fragment>
29-
<strong>{item.title}</strong>
30-
<p>{item.id}</p>
31-
</Fragment>
32-
33-
const previewComponent = ({ value }) =>
34-
value.map((item, i) => <p key={i}>{item.get('title')}</p>)
35-
36-
const ReorderWidget = createReorderWidget({ ListComponent, previewComponent })
37-
3845
cms.registerWidget(IdWidget)
3946
cms.registerWidget(ReorderWidget)
47+
cms.registerWidget({
48+
name: 'custom-reorder',
49+
controlComponent: CustomReorderControl,
50+
previewComponent: CustomReorderPreview,
51+
})
4052
cms.registerWidget(FileRelationWidget)
4153
cms.registerPreviewStyle('./preview.css')
4254
cms.init()
43-
})
55+
}, [])
4456

4557
return <div id="nc-root"></div>
4658
}

packages/playground/static/config.yml

+9
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,15 @@ collections:
4747
collection: posts
4848
id_field: id
4949
display_fields: ['title', 'id']
50+
hint: 'this reorder widget display entries from `posts` collection.'
51+
52+
- label: Featured Posts (Custom)
53+
name: featured-custom
54+
widget: custom-reorder
55+
collection: posts
56+
id_field: id
57+
display_fields: ['title', 'id']
58+
hint: 'this is a reorder widget with custom control'
5059

5160
- label: Setting
5261
name: setting

packages/widget-reorder/src/control.tsx

+19-15
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
1-
import React, { FunctionComponent as FC } from 'react'
2-
import { fromJS } from 'immutable'
1+
import * as React from 'react'
2+
import { fromJS, List } from 'immutable'
33
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd'
44
import { WidgetProps } from '@ncwidgets/common-typings'
55

66
import { reorder, diff, extract } from './utils'
77

8-
export const createControl = (ListElement: FC<{item: object}>) => {
9-
return class extends React.Component<WidgetProps> {
8+
const defaultListItem = item => Object.values(item).join(' ')
9+
10+
export interface CreateControlOptions {
11+
renderListItem?: (item: object) => React.ComponentType<{ item: Record<string, any> }>;
12+
}
13+
14+
type CreateControl = (options?: CreateControlOptions) => React.ComponentClass<WidgetProps>
15+
16+
export const createControl: CreateControl = (options = {}) => {
17+
const renderListItem = options.renderListItem || defaultListItem
18+
19+
return class Control extends React.Component<WidgetProps> {
20+
1021
public state = {
1122
data: [],
1223
}
@@ -16,9 +27,7 @@ export const createControl = (ListElement: FC<{item: object}>) => {
1627

1728
const collection: string = field.get('collection')
1829
const fieldId: string = field.get('id_field')
19-
const fieldDisplay: string[] = field.get('display_fields')
20-
21-
// @ts-ignore
30+
const fieldDisplay: List<string> = field.get('display_fields')
2231
const fieldsToBeExtracted = Array.from(new Set([fieldId, ...fieldDisplay.toJS()]))
2332

2433
const result = await query(forID, collection, [fieldId], '')
@@ -66,7 +75,6 @@ export const createControl = (ListElement: FC<{item: object}>) => {
6675
const { data } = this.state
6776

6877
const fieldId: string = field.get('id_field')
69-
const fieldDisplay: string[] = field.get('display_fields')
7078

7179
if (data.length === 0) return <div>loading...</div>
7280
return (
@@ -103,8 +111,8 @@ export const createControl = (ListElement: FC<{item: object}>) => {
103111
...provided.draggableProps.style,
104112
}}
105113
>
106-
<ListElement item={extract(item, ...fieldDisplay)}/>
107-
</div>
114+
{renderListItem(item)}
115+
</div>
108116
)}
109117
</Draggable>
110118
))}
@@ -116,8 +124,4 @@ export const createControl = (ListElement: FC<{item: object}>) => {
116124
)
117125
}
118126
}
119-
}
120-
121-
export const Control = createControl(({ item }) =>
122-
<div>{Object.keys(item).map(key => item[key]).join(' ')}</div>
123-
)
127+
}

packages/widget-reorder/src/index.ts

+4-12
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,17 @@
1-
import { Control, createControl } from './control'
1+
import { createControl } from './control'
22
import { Preview } from './preview'
33

4+
const Control = createControl()
5+
46
const Widget = {
57
name: 'ncw-reorder',
68
controlComponent: Control,
79
previewComponent: Preview,
810
}
911

10-
export const createWidget = (options) => {
11-
const { previewComponent = Preview } = options
12-
13-
return {
14-
...Widget,
15-
name: options.name ? options.name : Widget.name,
16-
controlComponent: createControl(options.ListComponent),
17-
previewComponent
18-
}
19-
}
20-
2112
export {
2213
Widget,
2314
Control,
2415
Preview,
16+
createControl,
2517
}

packages/widget-reorder/src/utils.test.ts

+18-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { removeOutdatedItem, diff } from './utils'
1+
import { removeOutdatedItem, diff, extract } from './utils'
22

33
describe('removeOutdatedItem', () => {
44
it('should remove outdated items', () => {
@@ -54,3 +54,20 @@ describe('diff', () => {
5454
expect(lastItem.id).toBe(4)
5555
})
5656
})
57+
58+
describe('extract', () => {
59+
it('should create a new shallow object with specified keys', () => {
60+
const data = {
61+
a: 100,
62+
b: 200,
63+
c: 300,
64+
}
65+
const expected = {
66+
a: data.a,
67+
b: data.b,
68+
}
69+
const result = extract(data, 'a', 'b')
70+
71+
expect(result).toEqual(expected)
72+
})
73+
})

0 commit comments

Comments
 (0)