├── ReactPropTypes.jar
├── ScreenShots
├── ScreenShot1.gif
├── ScreenShot2.gif
├── ScreenShot3.gif
└── ScreenShot4.gif
├── src
└── com
│ └── suming
│ └── plugin
│ ├── bean
│ ├── ESVersion.java
│ ├── ComponentType.java
│ ├── ImportMode.java
│ ├── Component.java
│ ├── BasePropType.java
│ ├── PropTypeBean.java
│ └── Setting.java
│ ├── constants
│ ├── ShapePropTypes.java
│ ├── SpecialPropTypes.java
│ └── ArrayFunctions.java
│ ├── ui
│ ├── ButtonRenderer.java
│ ├── CheckBoxRenderer.java
│ ├── ComboBoxRenderer.java
│ ├── ButtonEditor.java
│ ├── NameTextRenderer.java
│ ├── ShapePropTypesModel.java
│ ├── config
│ │ ├── SettingEntry.java
│ │ ├── SettingForm.java
│ │ └── SettingForm.form
│ ├── JsonInputDialog.java
│ ├── PropTypesModel.java
│ ├── JsonInputDialog.form
│ ├── ShapePropTypesDialog.form
│ ├── ShapePropTypesDialog.java
│ ├── PropTypesDialog.form
│ └── PropTypesDialog.java
│ ├── utils
│ ├── IdeaCompat.java
│ ├── SelectWordUtilCompat.java
│ ├── PsiElementHelper.java
│ └── PropTypesHelper.java
│ ├── persist
│ └── SettingService.java
│ ├── PropTypeAction.java
│ └── CommonAction.java
├── .gitignore
├── ReactPropTypes.iml
├── LICENSE
├── README_ZH.md
├── resources
└── META-INF
│ └── plugin.xml
└── README.md
/ReactPropTypes.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpzxsm/ReactPropTypes-Plugin/HEAD/ReactPropTypes.jar
--------------------------------------------------------------------------------
/ScreenShots/ScreenShot1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpzxsm/ReactPropTypes-Plugin/HEAD/ScreenShots/ScreenShot1.gif
--------------------------------------------------------------------------------
/ScreenShots/ScreenShot2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpzxsm/ReactPropTypes-Plugin/HEAD/ScreenShots/ScreenShot2.gif
--------------------------------------------------------------------------------
/ScreenShots/ScreenShot3.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpzxsm/ReactPropTypes-Plugin/HEAD/ScreenShots/ScreenShot3.gif
--------------------------------------------------------------------------------
/ScreenShots/ScreenShot4.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dpzxsm/ReactPropTypes-Plugin/HEAD/ScreenShots/ScreenShot4.gif
--------------------------------------------------------------------------------
/src/com/suming/plugin/bean/ESVersion.java:
--------------------------------------------------------------------------------
1 | package com.suming.plugin.bean;
2 |
3 | public enum ESVersion {
4 | ES6,
5 | ES7,
6 | }
7 |
--------------------------------------------------------------------------------
/src/com/suming/plugin/constants/ShapePropTypes.java:
--------------------------------------------------------------------------------
1 | package com.suming.plugin.constants;
2 |
3 | public enum ShapePropTypes {
4 | exact,
5 | shape
6 | }
7 |
--------------------------------------------------------------------------------
/src/com/suming/plugin/bean/ComponentType.java:
--------------------------------------------------------------------------------
1 | package com.suming.plugin.bean;
2 |
3 | public enum ComponentType {
4 | STANDARD_ES5,
5 | STANDARD,
6 | STATELESS
7 | }
8 |
--------------------------------------------------------------------------------
/src/com/suming/plugin/constants/SpecialPropTypes.java:
--------------------------------------------------------------------------------
1 | package com.suming.plugin.constants;
2 |
3 | public enum SpecialPropTypes {
4 | arrayOf,
5 | objectOf,
6 | oneOf,
7 | instanceOf,
8 | oneOfType
9 | }
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.war
15 | *.ear
16 | *.zip
17 | *.tar.gz
18 | *.rar
19 |
20 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
21 | hs_err_pid*
22 | .idea
23 |
--------------------------------------------------------------------------------
/src/com/suming/plugin/constants/ArrayFunctions.java:
--------------------------------------------------------------------------------
1 | package com.suming.plugin.constants;
2 |
3 | public enum ArrayFunctions {
4 | concat,
5 | every,
6 | filter,
7 | find,
8 | findIndex,
9 | flat,
10 | flatMap,
11 | forEach,
12 | includes,
13 | join,
14 | map,
15 | reduce,
16 | reverse,
17 | slice,
18 | some,
19 | sort,
20 | splice,
21 | unshift,
22 | }
23 |
--------------------------------------------------------------------------------
/src/com/suming/plugin/ui/ButtonRenderer.java:
--------------------------------------------------------------------------------
1 | package com.suming.plugin.ui;
2 |
3 | import javax.swing.*;
4 | import javax.swing.table.TableCellRenderer;
5 | import java.awt.*;
6 |
7 | public class ButtonRenderer extends JButton implements TableCellRenderer {
8 |
9 | @Override
10 | public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
11 | setText("delete");
12 | return this;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/ReactPropTypes.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/com/suming/plugin/ui/CheckBoxRenderer.java:
--------------------------------------------------------------------------------
1 | package com.suming.plugin.ui;
2 |
3 | import com.intellij.ui.components.JBCheckBox;
4 |
5 | import javax.swing.*;
6 | import javax.swing.table.TableCellRenderer;
7 | import java.awt.*;
8 |
9 | public class CheckBoxRenderer extends JBCheckBox implements TableCellRenderer{
10 |
11 | CheckBoxRenderer() {
12 | this.setHorizontalAlignment(SwingConstants.CENTER);
13 | }
14 |
15 | @Override
16 | public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
17 | this.setSelected(value.toString().equals("true"));
18 | return this;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/com/suming/plugin/utils/IdeaCompat.java:
--------------------------------------------------------------------------------
1 | package com.suming.plugin.utils;
2 |
3 | import com.intellij.openapi.application.ApplicationInfo;
4 |
5 | @SuppressWarnings({"SpellCheckingInspection", "WeakerAccess", "unused"})
6 | public final class IdeaCompat {
7 |
8 | public static final int BUILD_NUMBER = ApplicationInfo.getInstance().getBuild().getBaselineVersion();
9 |
10 | public static final class Version {
11 | public static final int IDEA15 = 143;
12 | public static final int IDEA2016_1 = 145;
13 | public static final int IDEA2016_2 = 162;
14 | public static final int IDEA2016_3 = 163;
15 | public static final int IDEA2017_1 = 171;
16 |
17 | private Version() {
18 | }
19 | }
20 |
21 | private IdeaCompat() {
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/com/suming/plugin/bean/ImportMode.java:
--------------------------------------------------------------------------------
1 | package com.suming.plugin.bean;
2 |
3 | public enum ImportMode {
4 | Disabled("Disabled"),
5 | OldModules("React.PropTypes"),
6 | NewModules("prop-types");
7 |
8 | private final String value;
9 |
10 | ImportMode(String value) {
11 | this.value = value;
12 | }
13 |
14 | public String getValue() {
15 | return value;
16 | }
17 |
18 | public static ImportMode toEnum(String value){
19 | if(value == null) return null;
20 | if(value.equals(Disabled.value)){
21 | return Disabled;
22 | }else if(value.equals(OldModules.value)){
23 | return OldModules;
24 | }else if(value.equals(NewModules.value)){
25 | return NewModules;
26 | }else {
27 | return null;
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/com/suming/plugin/persist/SettingService.java:
--------------------------------------------------------------------------------
1 | package com.suming.plugin.persist;
2 |
3 | import com.intellij.openapi.components.PersistentStateComponent;
4 | import com.intellij.openapi.components.State;
5 | import com.intellij.openapi.components.Storage;
6 | import com.suming.plugin.bean.Setting;
7 | import org.jetbrains.annotations.NotNull;
8 |
9 | @State(name = "SettingVariables",
10 | storages = {
11 | @Storage("Setting.xml")
12 | }
13 | )
14 |
15 | public class SettingService implements PersistentStateComponent {
16 | private Setting mSetting = new Setting();
17 |
18 | @NotNull
19 | @Override
20 | public Setting getState() {
21 | return mSetting;
22 | }
23 |
24 | @Override
25 | public void loadState(Setting setting) {
26 | this.mSetting = setting;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 苏铭
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/com/suming/plugin/bean/Component.java:
--------------------------------------------------------------------------------
1 | package com.suming.plugin.bean;
2 |
3 | import com.intellij.psi.PsiElement;
4 |
5 | public class Component {
6 | private PsiElement element;
7 | private ComponentType componentType;
8 | private ESVersion esVersion;
9 |
10 | public Component(PsiElement element, ComponentType componentType ) {
11 | this.element = element;
12 | this.componentType = componentType;
13 | }
14 |
15 | public Component(PsiElement element, ComponentType componentType, ESVersion esVersion) {
16 | this.element = element;
17 | this.componentType = componentType;
18 | this.esVersion = esVersion;
19 | }
20 |
21 | public PsiElement getElement() {
22 | return element;
23 | }
24 |
25 | public ComponentType getComponentType() {
26 | return componentType;
27 | }
28 |
29 | public ESVersion getEsVersion() {
30 | return esVersion;
31 | }
32 |
33 | public void setElement(PsiElement element) {
34 | this.element = element;
35 | }
36 |
37 | public void setComponentType(ComponentType componentType) {
38 | this.componentType = componentType;
39 | }
40 |
41 | public void setEsVersion(ESVersion esVersion) {
42 | this.esVersion = esVersion;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/com/suming/plugin/bean/BasePropType.java:
--------------------------------------------------------------------------------
1 | package com.suming.plugin.bean;
2 |
3 | public class BasePropType {
4 | public String name;
5 | public String type;
6 | public boolean isRequired;
7 |
8 | // BasePropType's JSON String or the Other value
9 | private String jsonData;
10 |
11 | public BasePropType(String name, String type, boolean isRequired) {
12 | this.name = name;
13 | this.type = type;
14 | this.isRequired = isRequired;
15 | }
16 |
17 | public String getName() {
18 | return name;
19 | }
20 |
21 | public void setName(String name) {
22 | this.name = name;
23 | }
24 |
25 | public String getType() {
26 | return type;
27 | }
28 |
29 | public void setType(String type) {
30 | if (type != null && !type.equals("")) {
31 | this.type = type;
32 | } else {
33 | this.type = "any";
34 | }
35 | }
36 |
37 | public boolean isRequired() {
38 | return isRequired;
39 | }
40 |
41 | public void setRequired(boolean required) {
42 | isRequired = required;
43 | }
44 |
45 | public String getJsonData() {
46 | return jsonData;
47 | }
48 |
49 | public void setJsonData(String jsonData) {
50 | this.jsonData = jsonData;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/com/suming/plugin/ui/ComboBoxRenderer.java:
--------------------------------------------------------------------------------
1 | package com.suming.plugin.ui;
2 |
3 | import javax.swing.*;
4 | import javax.swing.table.TableCellRenderer;
5 | import java.awt.*;
6 |
7 | public class ComboBoxRenderer extends JComboBox implements TableCellRenderer {
8 |
9 | ComboBoxRenderer(boolean showAllType) {
10 | super(new String[]{
11 | "any",
12 | "string",
13 | "object",
14 | "bool",
15 | "func",
16 | "number",
17 | "array",
18 | "symbol",
19 | "node",
20 | "element",
21 | "arrayOf",
22 | "objectOf",
23 | "oneOf",
24 | "instanceOf",
25 | "oneOfType"
26 | });
27 | if (showAllType) {
28 | this.insertItemAt("shape", 10);
29 | this.insertItemAt("exact", 11);
30 | }
31 | this.setMaximumRowCount(10);
32 | this.setEditable(false);
33 | this.setLightWeightPopupEnabled(false);
34 | }
35 |
36 | @Override
37 | public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
38 | this.setSelectedItem(value.toString());
39 | return this;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/com/suming/plugin/bean/PropTypeBean.java:
--------------------------------------------------------------------------------
1 | package com.suming.plugin.bean;
2 |
3 | import org.jetbrains.annotations.Nullable;
4 |
5 | import java.util.List;
6 |
7 | public class PropTypeBean extends BasePropType {
8 | // default value
9 | private String defaultValue;
10 | // shapeList
11 | private List shapePropTypeList;
12 |
13 | public PropTypeBean(String name) {
14 | super(name, "any", false);
15 | }
16 |
17 | public PropTypeBean(String name, String type, boolean isRequired) {
18 | super(name, type, isRequired);
19 | }
20 |
21 |
22 | public PropTypeBean(String name, String type, boolean isRequired, String defaultValue) {
23 | super(name, type, isRequired);
24 | this.defaultValue = defaultValue;
25 | }
26 |
27 | @Nullable
28 | public String getDefaultValue() {
29 | return defaultValue;
30 | }
31 |
32 | public void setDefaultValue(String defaultValue) {
33 | this.defaultValue = defaultValue;
34 | }
35 |
36 | public List getShapePropTypeList() {
37 | return shapePropTypeList;
38 | }
39 |
40 | public void setShapePropTypeList(List shapePropTypeList) {
41 | this.shapePropTypeList = shapePropTypeList;
42 | }
43 |
44 | @Override
45 | public boolean equals(Object obj) {
46 | if (obj instanceof PropTypeBean) {
47 | return ((PropTypeBean) obj).name.equals(this.name);
48 | }
49 | return super.equals(obj);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/com/suming/plugin/utils/SelectWordUtilCompat.java:
--------------------------------------------------------------------------------
1 | package com.suming.plugin.utils;
2 |
3 | import com.intellij.codeInsight.editorActions.SelectWordUtil;
4 | import com.intellij.openapi.editor.Editor;
5 | import com.intellij.openapi.util.TextRange;
6 | import org.jetbrains.annotations.NotNull;
7 |
8 | import java.util.List;
9 |
10 | @SuppressWarnings("SpellCheckingInspection")
11 | public final class SelectWordUtilCompat {
12 |
13 | private SelectWordUtilCompat() {
14 | }
15 |
16 | public static final SelectWordUtil.CharCondition JAVASCRIPT_IDENTIFIER_PART_CONDITION = new SelectWordUtil.CharCondition() {
17 | public boolean value(char var1) {
18 | return var1 != ' ';
19 | }
20 | };
21 |
22 |
23 | public static void addWordOrLexemeSelection(boolean camel,
24 | @NotNull Editor editor,
25 | int cursorOffset,
26 | @NotNull List ranges,
27 | @NotNull SelectWordUtil.CharCondition isWordPartCondition) {
28 | if (IdeaCompat.BUILD_NUMBER >= IdeaCompat.Version.IDEA2016_2) {
29 | SelectWordUtil.addWordOrLexemeSelection(camel, editor, cursorOffset, ranges, isWordPartCondition);
30 | } else {
31 | CharSequence editorText = editor.getDocument().getImmutableCharSequence();
32 | SelectWordUtil.addWordSelection(camel, editorText, cursorOffset, ranges, isWordPartCondition);
33 | }
34 |
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/src/com/suming/plugin/ui/ButtonEditor.java:
--------------------------------------------------------------------------------
1 | package com.suming.plugin.ui;
2 |
3 | import javax.swing.*;
4 | import javax.swing.table.DefaultTableModel;
5 | import java.awt.*;
6 | import java.awt.event.ActionEvent;
7 | import java.awt.event.ActionListener;
8 | import java.util.EventObject;
9 |
10 | public class ButtonEditor extends DefaultCellEditor{
11 |
12 | private JButton editor;
13 | private Object value;
14 | private int row;
15 | private JTable table;
16 |
17 | ButtonEditor() {
18 | super(new JTextField());
19 | editor = new JButton();
20 | editor.addActionListener(e -> {
21 | //这里调用自定义的事件处理方法
22 | if (table != null && table.getModel() instanceof DefaultTableModel) {
23 | fireEditingStopped();
24 | ((DefaultTableModel)table.getModel()).removeRow(row);
25 | }
26 | });
27 |
28 | }
29 |
30 | @Override
31 | public boolean isCellEditable(EventObject e) {
32 | return true;
33 | }
34 |
35 | @Override
36 | public Object getCellEditorValue() {
37 | return value;
38 | }
39 |
40 | @Override
41 | public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
42 | this.table = table;
43 | this.row = row;
44 | this.value = value;
45 | editor.setText("delete");
46 |
47 | // if (isSelected) {
48 | // editor.setForeground(table.getSelectionForeground());
49 | // editor.setBackground(table.getSelectionBackground());
50 | // } else {
51 | // editor.setForeground(table.getForeground());
52 | // editor.setBackground(UIManager.getColor("Button.background"));
53 | // }
54 | return editor;
55 | }
56 | }
--------------------------------------------------------------------------------
/src/com/suming/plugin/ui/NameTextRenderer.java:
--------------------------------------------------------------------------------
1 | package com.suming.plugin.ui;
2 |
3 | import com.intellij.ui.JBColor;
4 |
5 | import javax.swing.*;
6 | import javax.swing.table.TableCellRenderer;
7 | import java.awt.*;
8 | import java.awt.event.FocusAdapter;
9 | import java.awt.event.FocusEvent;
10 |
11 | public class NameTextRenderer extends JTextField implements TableCellRenderer{
12 |
13 | private String placeholder = "";
14 |
15 | NameTextRenderer(boolean isCellRenderer , String placeholder) {
16 | super();
17 | this.placeholder = placeholder;
18 | if(isCellRenderer){
19 | setBorder(null);
20 | setBackground(null);
21 | }
22 | this.addFocusListener(new FocusAdapter() {
23 | @Override
24 | public void focusGained(FocusEvent e) {
25 | if(getText().equals(placeholder)){
26 | setText("");
27 | }
28 | super.focusGained(e);
29 | }
30 |
31 | @Override
32 | public void focusLost(FocusEvent e) {
33 | super.focusLost(e);
34 | if(getText().equals("")){
35 | setText(placeholder);
36 | }
37 | }
38 | });
39 | }
40 |
41 | @Override
42 | public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
43 | String content = value == null ? "" : value.toString();
44 | if(content.trim().equals("")||content.equals(placeholder)){
45 | setText(placeholder);
46 | setForeground(JBColor.GRAY);
47 | }else {
48 | setText(content);
49 | setForeground(null);
50 | }
51 | return this;
52 | }
53 |
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/src/com/suming/plugin/utils/PsiElementHelper.java:
--------------------------------------------------------------------------------
1 | package com.suming.plugin.utils;
2 |
3 | import com.intellij.lang.ecmascript6.psi.ES6Class;
4 | import com.intellij.lang.javascript.psi.JSFunction;
5 | import com.intellij.lang.javascript.psi.impl.JSVarStatementBase;
6 | import com.intellij.psi.PsiElement;
7 | import com.intellij.psi.PsiWhiteSpace;
8 |
9 | public class PsiElementHelper {
10 | public static PsiElement getRealPreElement (PsiElement p){
11 | PsiElement p1 = p.getPrevSibling();
12 | if(p1 !=null){
13 | if(!(p1 instanceof PsiWhiteSpace)){
14 | return p1;
15 | }
16 | PsiElement p2 = p1.getPrevSibling();
17 | if(p2 !=null && !( p2 instanceof PsiWhiteSpace)){
18 | return p2;
19 | }
20 | }
21 | return null;
22 | }
23 |
24 | public static PsiElement getRealNextElement (PsiElement p){
25 | PsiElement p1 = p.getNextSibling();
26 | if(p1 !=null){
27 | if(!(p1 instanceof PsiWhiteSpace)){
28 | return p1;
29 | }
30 | PsiElement p2 = p1.getNextSibling();
31 | if(p2 !=null && !( p2 instanceof PsiWhiteSpace)){
32 | return p2;
33 | }
34 | }
35 | return null;
36 | }
37 |
38 | public static PsiElement getRealFirstChild (ES6Class es6Class){
39 | PsiElement[] children = es6Class.getChildren();
40 | if(children.length>2){
41 | if((children[2] instanceof JSFunction)|| children[2] instanceof JSVarStatementBase){
42 | return children[2];
43 | }
44 | }
45 | if(children.length>3){
46 | if((children[3] instanceof JSFunction)|| children[3] instanceof JSVarStatementBase){
47 | return children[3];
48 | }
49 | }
50 | return null;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/README_ZH.md:
--------------------------------------------------------------------------------
1 | 这是一个可以自动生成React组件的PropTypes代码的jetbrains插件,目前仅支持ES6、ES7。如果需要支持ES5,请在issue中留言。支持的平台有:IntelliJ IDEA、PhpStorm、WebStorm、PyCharm、RubyMine、AppCode、CLion、Gogland、Rider
2 |
3 | 如果你想在VS Code或者通过命令行使用这个插件,建议你去使用另一个插件: [react-proptypes-generate](https://github.com/dpzxsm/react-proptypes-generate), 现在并不是很完美,欢迎issue和PR
4 |
5 | ## 安装插件
6 | 1. 在插件商店中搜索ReactPropTypes下载安装,这是商店链接,欢迎评论.
7 | 2. 点击 ReactPropTypes.jar(最新版本,但可能不太稳定) 下载插件并且打开Setting/Plugins/Install Plugin from disk 本地安装这个插件
8 |
9 | ## 如何使用
10 | 1. 选择组件名称
11 | 2. 按下 command + N (Windows系统是alt + insert) 并且选择PropTypesGenerate, 或者按下shift + command + alt + P (Windows系统是shift + ctrl + alt + P) 在Mac系统中。
12 | 3. 编辑弹框中的表格进行类型的修改稿
13 |
14 | ##
15 | #### 类组件
16 | 
17 | #### 函数组件
18 | 
19 | #### 当你选择了`Shape`作为类型
20 | 
21 |
22 | ## 如何构建和开发这个项目
23 |
24 | #### 依赖库
25 | * IntelliJ Platform Plugin SDK (官方插件SDK)
26 | * JavaScriptLanguage's lib (在macOS中, 路径是 /Applications/IntelliJ IDEA.app/Contents/plugins/JavaScriptLanguage/lib, Windows类似)
27 |
28 | #### 构建步骤
29 | 1. 下载最新的IntelliJ IDEA商业版
30 | 2. Git拷贝项目并且用IDEA打开
31 | 3. 删除默认的module,并且通过`ReactPropTypes.iml`这个文件来导入module
32 | 4. 配置IntelliJ Platform Plugin SDK 和 language level 8
33 | 5. 配置插件的构建目录
34 |
35 | #### 示例
36 | 
37 |
38 | ## 特性
39 | 1. 如果你没有选择任何文字,插件将自动找到高亮的文字作为选择的组件名称。
40 | 1. 在ES6的标准组件中,插件通过找到以props和nextProps为对象名称的引用和解析赋值来找到属性名。
41 | 2. 在无状态组件中,只有当你的第一个参数命名为props或者是一个解析赋值的参数样式,插件才能识别出来。
42 | 3. 如果你选择了ES6的代码风格,代码将生产在当前文件的最后一行。当然,如果你选择了ES7的代码风格, 代码将在你所选择的组件内部的第一行生成。
43 | 4. 如果自动生成的名字不是你期盼的那样,你可以在表格中双击名字进行修改,当然也可以手动添加一行或者删除你不需要的。
44 | 5. 如果你的组件中含有默认值的props, 插件会读取默认值的类型填充到最终表单之中。
45 | 6. 支持PropTypes.shape 和 defaultProps 生成。
46 | 7. 你可以在偏好设置中自定义你的代码风格。
47 | 8. 支持自动推断代码中的函数和数组类型,可以在设置中打开。
48 | 9. 现在已经支持了所有的类型
49 |
50 | ## 未来的计划
51 | 1. 开发VSCode版本的类似插件
52 | 2. 支持生成Flow风格或者TypeScript风格的类型检测,并且不使用PropTypes
--------------------------------------------------------------------------------
/src/com/suming/plugin/ui/ShapePropTypesModel.java:
--------------------------------------------------------------------------------
1 | package com.suming.plugin.ui;
2 |
3 | import com.suming.plugin.bean.BasePropType;
4 | import com.suming.plugin.bean.PropTypeBean;
5 | import com.suming.plugin.utils.PropTypesHelper;
6 |
7 | import javax.swing.table.DefaultTableModel;
8 | import java.util.ArrayList;
9 | import java.util.Comparator;
10 | import java.util.List;
11 | import java.util.Vector;
12 | import java.util.stream.Collectors;
13 |
14 | public class ShapePropTypesModel extends DefaultTableModel {
15 | void addRow(BasePropType bean) {
16 | super.addRow(new Object[]{bean.name,bean.type,bean.isRequired});
17 | }
18 |
19 | void initData(List beans){
20 | String[] columnNames = {
21 | "name",
22 | "type",
23 | "isRequired",
24 | "ops"};
25 | Object[][] data = new Object[beans.size()][4];
26 | for (int i = 0; i < beans.size(); i++) {
27 | data[i][0] = beans.get(i).name;
28 | data[i][1] = beans.get(i).type;
29 | data[i][2] = beans.get(i).isRequired;
30 | data[i][3] = false;
31 | }
32 | this.setDataVector(data,columnNames);
33 | }
34 |
35 | void reInitData(List beans){
36 | for (int i = 0; i < this.getRowCount(); i++) {
37 | this.removeRow(i);
38 | }
39 | for (BasePropType bean : beans) {
40 | this.addRow(bean);
41 | }
42 | }
43 |
44 | List data2PropList(){
45 | Vector vector = this.getDataVector();
46 | List propTypeBeans = new ArrayList<>();
47 | for(Object a : vector){
48 | if(a instanceof Vector){
49 | Object[] o = ((Vector) a).toArray();
50 | if(o[0].toString().trim().equals("")) continue;
51 | String name = o[0].toString();
52 | String type = o[1].toString();
53 | boolean isRequired = o[2].toString().equals("true");
54 | BasePropType bean = new BasePropType(name, type ,isRequired);
55 | propTypeBeans.add(bean);
56 | }
57 | }
58 | // sort by name
59 | return propTypeBeans.stream()
60 | .filter(PropTypesHelper.distinctByKey(BasePropType::getName))
61 | .sorted(Comparator.comparing(BasePropType::getName))
62 | .collect(Collectors.toList());
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/com/suming/plugin/ui/config/SettingEntry.java:
--------------------------------------------------------------------------------
1 | package com.suming.plugin.ui.config;
2 |
3 | import com.intellij.openapi.components.ServiceManager;
4 | import com.intellij.openapi.options.Configurable;
5 | import com.intellij.openapi.options.ConfigurationException;
6 | import com.suming.plugin.bean.Setting;
7 | import com.suming.plugin.persist.SettingService;
8 | import org.jetbrains.annotations.Nls;
9 | import org.jetbrains.annotations.Nullable;
10 |
11 | import javax.swing.*;
12 |
13 | public class SettingEntry implements Configurable{
14 | private SettingService settingService = ServiceManager.getService(SettingService.class);
15 | private SettingForm form;
16 |
17 | @Nls
18 | @Override
19 | public String getDisplayName() {
20 | return "ReactPropTypes";
21 | }
22 |
23 | @Nullable
24 | @Override
25 | public JComponent createComponent() {
26 | SettingService settingService = ServiceManager.getService(SettingService.class);
27 | form = new SettingForm(settingService.getState());
28 | return form.getRoot();
29 | }
30 |
31 | @Override
32 | public boolean isModified() {
33 | Setting config = settingService.getState();
34 | Setting setting = form !=null ? form.getNewSetting() : null;
35 | return setting !=null && (!config.getImportMode().equals(setting.getImportMode())
36 | || !config.getEsVersion().equals(setting.getEsVersion())
37 | || config.isSortProps() != setting.isSortProps()
38 | || config.getIndent() != setting.getIndent()
39 | || config.isNeedDefault() != setting.isNeedDefault()
40 | || config.isNoSemiColons() != setting.isNoSemiColons()
41 | || config.isInferByDestructure() != setting.isInferByDestructure()
42 | || config.isInferByDefaultProps() != setting.isInferByDefaultProps()
43 | || config.isInferByPropsCall() != setting.isInferByPropsCall()
44 | || config.isUncheckFunctionalComponent() != setting.isUncheckFunctionalComponent());
45 | }
46 |
47 | @Override
48 | public void reset() {
49 | if(form != null){
50 | form.updateSetting(settingService.getState());
51 | }
52 | }
53 |
54 | @Override
55 | public void apply() throws ConfigurationException {
56 | settingService.loadState(form.getNewSetting());
57 | }
58 |
59 | @Override
60 | public void disposeUIResources() {
61 | form = null;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/com/suming/plugin/ui/config/SettingForm.java:
--------------------------------------------------------------------------------
1 | package com.suming.plugin.ui.config;
2 |
3 | import com.suming.plugin.bean.ESVersion;
4 | import com.suming.plugin.bean.ImportMode;
5 | import com.suming.plugin.bean.Setting;
6 |
7 | import javax.swing.*;
8 |
9 | public class SettingForm {
10 | private JPanel root;
11 | private JComboBox importBox;
12 | private JComboBox esVersionBox;
13 | private JTextField indentInput;
14 | private JCheckBox noSemiColonsCheckBox;
15 | private JCheckBox defaultPropsCheckBox;
16 | private JCheckBox inferTypeByPropsDestructure;
17 | private JCheckBox inferTypeByDefaultProps;
18 | private JCheckBox inferTypeByPropsCall;
19 | private JCheckBox uncheckedFunctionalComponent;
20 | private JCheckBox sortPropTypes;
21 |
22 | JPanel getRoot() {
23 | return root;
24 | }
25 |
26 | SettingForm(Setting setting) {
27 | this.updateSetting(setting);
28 | }
29 |
30 | void updateSetting(Setting setting){
31 | importBox.setSelectedItem(setting.getImportMode().getValue());
32 | esVersionBox.setSelectedItem(setting.getEsVersion().toString());
33 | indentInput.setText(setting.getIndent() + "");
34 | noSemiColonsCheckBox.setSelected(setting.isNoSemiColons());
35 | defaultPropsCheckBox.setSelected(setting.isNeedDefault());
36 | inferTypeByPropsDestructure.setSelected(setting.isInferByDestructure());
37 | inferTypeByDefaultProps.setSelected(setting.isInferByDefaultProps());
38 | inferTypeByPropsCall.setSelected(setting.isInferByPropsCall());
39 | uncheckedFunctionalComponent.setSelected(setting.isUncheckFunctionalComponent());
40 | sortPropTypes.setSelected(setting.isSortProps());
41 | }
42 |
43 | Setting getNewSetting(){
44 | Setting setting = new Setting();
45 | ImportMode importMode = importBox.getSelectedItem() == null ?
46 | ImportMode.Disabled : ImportMode.toEnum(importBox.getSelectedItem().toString());
47 | ESVersion esVersion = ESVersion.valueOf(esVersionBox.getSelectedItem() !=null ? esVersionBox.getSelectedItem().toString() : "ES6");
48 | setting.setImportMode(importMode);
49 | setting.setEsVersion(esVersion);
50 | setting.setIndent(Integer.parseInt(indentInput.getText()));
51 | setting.setNoSemiColons(noSemiColonsCheckBox.isSelected());
52 | setting.setNeedDefault(defaultPropsCheckBox.isSelected());
53 | setting.setInferByDestructure(inferTypeByPropsDestructure.isSelected());
54 | setting.setInferByDefaultProps(inferTypeByDefaultProps.isSelected());
55 | setting.setInferByPropsCall(inferTypeByPropsCall.isSelected());
56 | setting.setUncheckFunctionalComponent(uncheckedFunctionalComponent.isSelected());
57 | setting.setSortProps(sortPropTypes.isSelected());
58 | return setting;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/resources/META-INF/plugin.xml:
--------------------------------------------------------------------------------
1 |
2 | com.suming.react.PropTypes
3 | ReactPropTypes
4 | 1.1.5
5 | 苏铭(Su Ming)
6 |
7 |
9 |
10 | Usage Instructions:
11 | 1. Select or take the cursor in your Component's name
12 | 2. Press command + N (Windows is alt + insert) show Generate Group and click PropTypesGenerate, or press
13 | shift + command + alt + P (Windows is shift + ctrl + alt + P) in the macOS
14 | 3. Edit the PropTypes Table to modify default type
15 |
16 | If you have any question , you can leave a issue in github.
17 |
18 | 使用介绍:
19 | 1. 选中你的组件名称或者将光标移动到组件的名称上
20 | 2. 按下command + N (Windows 是 alt + insert) 显示 Generate Group 并且点击 PropTypesGenerate, 或者直接按下快捷键
21 | shift + command + alt + P (Windows 是 shift + ctrl + alt + P) 在macOs系统中
22 | 3. 接下来就你可以在弹出的弹框中看到即将生成的PropType列表,并且你可以自由编辑它们。
23 |
24 | 如果你在使用过程中遇到了任何问题,或者想了解插件更多的使用方法,都可以在 github
25 | 中留言
26 |
27 | ]]>
28 |
29 |
32 |
33 |
34 |
35 |
36 |
37 |
39 |
42 |
43 |
44 | com.intellij.modules.lang
45 |
46 | JavaScript
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/src/com/suming/plugin/bean/Setting.java:
--------------------------------------------------------------------------------
1 | package com.suming.plugin.bean;
2 |
3 | public class Setting {
4 |
5 | // Generate mode
6 | private ESVersion esVersion = ESVersion.ES6;
7 | private ImportMode importMode = ImportMode.Disabled;
8 | private boolean sortProps = true;
9 |
10 | // Code Style
11 | private int indent = 2;
12 | private boolean noSemiColons = true;
13 | private boolean isNeedDefault = false;
14 |
15 | // Infer type
16 | private boolean inferByDestructure = true;
17 | private boolean inferByDefaultProps = true;
18 | private boolean inferByPropsCall = false;
19 |
20 | // Others
21 | private boolean uncheckFunctionalComponent = false;
22 |
23 | public Setting() {
24 | }
25 |
26 | public ESVersion getEsVersion() {
27 | return esVersion;
28 | }
29 |
30 | public void setEsVersion(ESVersion esVersion) {
31 | this.esVersion = esVersion;
32 | }
33 |
34 | public ImportMode getImportMode() {
35 | return importMode;
36 | }
37 |
38 | public void setImportMode(ImportMode importMode) {
39 | this.importMode = importMode;
40 | }
41 |
42 | public boolean isSortProps() {
43 | return sortProps;
44 | }
45 |
46 | public void setSortProps(boolean sortProps) {
47 | this.sortProps = sortProps;
48 | }
49 |
50 | public int getIndent() {
51 | return indent;
52 | }
53 |
54 | public void setIndent(int indent) {
55 | this.indent = indent;
56 | }
57 |
58 | public boolean isNeedDefault() {
59 | return isNeedDefault;
60 | }
61 |
62 | public void setNeedDefault(boolean needDefault) {
63 | isNeedDefault = needDefault;
64 | }
65 |
66 | public boolean isNoSemiColons() {
67 | return noSemiColons;
68 | }
69 |
70 | public void setNoSemiColons(boolean noSemiColons) {
71 | this.noSemiColons = noSemiColons;
72 | }
73 |
74 | public boolean isInferByDestructure() {
75 | return inferByDestructure;
76 | }
77 |
78 | public void setInferByDestructure(boolean inferByDestructure) {
79 | this.inferByDestructure = inferByDestructure;
80 | }
81 |
82 | public boolean isInferByDefaultProps() {
83 | return inferByDefaultProps;
84 | }
85 |
86 | public void setInferByDefaultProps(boolean inferByDefaultProps) {
87 | this.inferByDefaultProps = inferByDefaultProps;
88 | }
89 |
90 | public boolean isInferByPropsCall() {
91 | return inferByPropsCall;
92 | }
93 |
94 | public void setInferByPropsCall(boolean inferByPropsCall) {
95 | this.inferByPropsCall = inferByPropsCall;
96 | }
97 |
98 | public boolean isUncheckFunctionalComponent() {
99 | return uncheckFunctionalComponent;
100 | }
101 |
102 | public void setUncheckFunctionalComponent(boolean uncheckFunctionalComponent) {
103 | this.uncheckFunctionalComponent = uncheckFunctionalComponent;
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/src/com/suming/plugin/ui/JsonInputDialog.java:
--------------------------------------------------------------------------------
1 | package com.suming.plugin.ui;
2 |
3 | import com.google.gson.JsonElement;
4 | import com.google.gson.JsonObject;
5 | import com.google.gson.JsonParser;
6 | import com.suming.plugin.bean.BasePropType;
7 | import com.suming.plugin.utils.PropTypesHelper;
8 |
9 | import javax.swing.*;
10 | import java.awt.event.KeyEvent;
11 | import java.awt.event.WindowAdapter;
12 | import java.awt.event.WindowEvent;
13 | import java.util.ArrayList;
14 | import java.util.List;
15 | import java.util.Map;
16 |
17 | public class JsonInputDialog extends JDialog {
18 | private JPanel contentPane;
19 | private JButton buttonOK;
20 | private JButton buttonCancel;
21 | private JTextArea input;
22 | private JLabel hintText;
23 | private JsonInputDialog.onSubmitListener onSubmitListener;
24 |
25 | public void setOnSubmitListener(JsonInputDialog.onSubmitListener onSubmitListener) {
26 | this.onSubmitListener = onSubmitListener;
27 | }
28 |
29 | public JsonInputDialog() {
30 | setContentPane(contentPane);
31 | setTitle("paste a json or a js Object");
32 | setModal(true);
33 | getRootPane().setDefaultButton(buttonOK);
34 |
35 | buttonOK.addActionListener(e -> onOK());
36 |
37 | buttonCancel.addActionListener(e -> onCancel());
38 |
39 | // call onCancel() when cross is clicked
40 | setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
41 | addWindowListener(new WindowAdapter() {
42 | public void windowClosing(WindowEvent e) {
43 | onCancel();
44 | }
45 | });
46 |
47 | // call onCancel() on ESCAPE
48 | contentPane.registerKeyboardAction(e -> onCancel(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
49 | }
50 |
51 | private void onOK() {
52 | // add your code here
53 | String jsonStr = input.getText();
54 | if( jsonStr != null && !jsonStr.trim().equals("")){
55 | try{
56 | List basePropTypes = new ArrayList<>();
57 | JsonParser parser = new JsonParser();
58 | JsonElement element = parser.parse(jsonStr);
59 | if(element instanceof JsonObject){
60 | for (Object o : ((JsonObject) element).entrySet()) {
61 | Map.Entry entry = (Map.Entry) o;
62 | String name = entry.getKey().toString();
63 | String value = entry.getValue().toString();
64 | basePropTypes.add(new BasePropType(name, PropTypesHelper.getPropTypeByValue(value), false));
65 | }
66 | if(this.onSubmitListener != null){
67 | this.onSubmitListener.onSubmit(basePropTypes);
68 | }
69 | dispose();
70 | }else {
71 | hintText.setText("Not a Json Object !");
72 | }
73 | } catch (Exception e){
74 | System.out.println(e);
75 | hintText.setText("Incorrectly formatting !");
76 | }
77 | }else {
78 | hintText.setText("Can not be empty !");
79 | }
80 | }
81 |
82 | private void onCancel() {
83 | // add your code here if necessary
84 | dispose();
85 | }
86 | public interface onSubmitListener{
87 | void onSubmit(List beans);
88 | }
89 |
90 |
91 | public static void main(String[] args) {
92 | JsonInputDialog dialog = new JsonInputDialog();
93 | dialog.pack();
94 | dialog.setVisible(true);
95 | System.exit(0);
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ReactPropTypes-Plugin
2 | 中文文档
3 |
4 | This is a JetBrains plug-in that automatically generates PropTypes code for React components, and only supports ES6 later at the moment. If you need to support ES5, please leave a message in issue.Compatible with: IntelliJ IDEA, PhpStorm, WebStorm, PyCharm, RubyMine, AppCode, CLion, Gogland, Rider.
5 |
6 | If you are want use it by Visual Code or command line, I suggest you to use another plugin: [react-proptypes-generate](https://github.com/dpzxsm/react-proptypes-generate), now it is imperfect, welcome issue and PR.
7 |
8 | ## Installed
9 | 1. In plugin store search "ReactPropTypes" and install it , this is Store Link, Welcome comments.
10 | 2. Click ReactPropTypes.jar(Recently, but may Unstable) to download and open Setting/Plugins/Install Plugin from disk to install.
11 |
12 | ## How to use
13 | 1. Select your Component's name
14 | 2. Press command + N (Windows is alt + insert) show Generate Group and select PropTypesGenerate, or press shift + command + alt + P (Windows is shift + ctrl + alt + P) in the macOS
15 | 3. Edit the PropTypes Table to modify default type
16 |
17 | ## Preview
18 | #### Class Components
19 | 
20 | #### Functional Components
21 | 
22 | #### When you select `Shape` as the PropType
23 | 
24 |
25 | ## How to Build and Development the project
26 |
27 | #### Dependency Library
28 | * IntelliJ Platform Plugin SDK
29 | * JavaScriptLanguage's lib (In macOS, the path is /Applications/IntelliJ IDEA.app/Contents/plugins/JavaScriptLanguage/lib, Windows are similar)
30 |
31 | #### Development Step
32 | 1. Download the latest IntelliJ IDEA Ultimate
33 | 2. Clone and Open this project
34 | 3. Delete default module and import plugin module by `ReactPropTypes.iml`
35 | 4. Config Project SDK named IntelliJ IDEA IU-182.** and Config language level 8
36 | 5. Config plugin out dir and plugin launch Configurations
37 |
38 | #### For Example
39 | 
40 |
41 | ## Features
42 | 1. Get a heightLight text as component's name if you are not select any text.
43 | 1. In the Standard ES6 component, the plugin can distinguish props's reference and destructuring assignment with keyword "props" or "nextProps".
44 | 2. In the Stateless component, only when your first param must be named "props" or a destructuring parameter the plugin can distinguished.
45 | 3. If you select ES6 code style , the propTypes code will generate at the last line .Of cause, if you select ES7 code style, the propTypes code will generate at the component inside's first line.
46 | 4. Double Click the row's name in the table, can modify distinguished name if not you expect, also support add a new row or delete what you not need.
47 | 5. If your component has a default value for props, the plugin will fill the default type to the table.
48 | 6. Support PropTypes.shape and handle defaultProps.
49 | 7. You can custom your code generate's style.
50 | 8. Supports automatic inference of functions and array types in code, and can be opened in the settings.
51 | 9. Support full list of PropTypes
52 |
53 |
54 | ## Next plan
55 | 1. Developing a similar plugin on the VS Code's platform
56 | 2. Support Flow Or TypeScript's TypeChecker, and not use PropTypes
--------------------------------------------------------------------------------
/src/com/suming/plugin/ui/PropTypesModel.java:
--------------------------------------------------------------------------------
1 | package com.suming.plugin.ui;
2 |
3 | import com.intellij.openapi.components.ServiceManager;
4 | import com.suming.plugin.bean.BasePropType;
5 | import com.suming.plugin.bean.PropTypeBean;
6 | import com.suming.plugin.persist.SettingService;
7 | import com.suming.plugin.utils.PropTypesHelper;
8 |
9 | import javax.swing.table.DefaultTableModel;
10 | import java.util.*;
11 | import java.util.stream.Collectors;
12 |
13 | class PropTypesModel extends DefaultTableModel {
14 | SettingService settingService = ServiceManager.getService(SettingService.class);
15 |
16 | void addRow(PropTypeBean bean) {
17 | HashMap extraData = new HashMap<>();
18 | super.addRow(new Object[]{bean.name, bean.type, bean.isRequired,
19 | bean.getDefaultValue(), extraData});
20 | }
21 |
22 | void initData(List beans) {
23 | String[] columnNames = {
24 | "name",
25 | "type",
26 | "isRequired",
27 | "defaultValue",
28 | "ops"};
29 | Object[][] data = new Object[beans.size()][5];
30 | for (int i = 0; i < beans.size(); i++) {
31 | data[i][0] = beans.get(i).name;
32 | data[i][1] = beans.get(i).type;
33 | data[i][2] = beans.get(i).isRequired;
34 | data[i][3] = beans.get(i).getDefaultValue();
35 | HashMap extraData = new HashMap<>();
36 | extraData.put("shapeProps", beans.get(i).getShapePropTypeList());
37 | extraData.put("jsonData", beans.get(i).getJsonData());
38 | data[i][4] = extraData;
39 | }
40 | this.setDataVector(data, columnNames);
41 | }
42 |
43 | @SuppressWarnings("unchecked")
44 | void updateExtraDataByName(int row, String name, Object data) {
45 | HashMap extraData = (HashMap) this.getValueAt(row, 4);
46 | extraData.put(name, data);
47 | this.setValueAt(extraData, row, 4);
48 | }
49 |
50 | String getValueFromIndex(int column, int row) {
51 | Object[] objects = getDataVector().toArray();
52 | if (row <= objects.length - 1) {
53 | Vector rowVector = ((Vector) objects[row]);
54 | return rowVector.elementAt(column).toString();
55 | } else {
56 | return "";
57 | }
58 | }
59 |
60 | List data2PropList() {
61 | Vector vector = this.getDataVector();
62 | List propTypeBeans = new ArrayList<>();
63 | for (Object a : vector) {
64 | if (a instanceof Vector) {
65 | Object[] o = ((Vector) a).toArray();
66 | if (o[0].toString().trim().equals("")) continue;
67 | String name = o[0].toString();
68 | String type = o[1].toString();
69 | boolean isRequired = o[2].toString().equals("true");
70 | String defaultValue = o[3] == null ? null : o[3].toString();
71 | HashMap extraData = (HashMap) o[4];
72 | Object shapePropsObj = extraData.get("shapeProps");
73 | PropTypeBean bean = new PropTypeBean(name, type, isRequired, defaultValue);
74 | if (type != null && (type.equals("shape") || type.equals("exact")) && shapePropsObj != null) {
75 | List shapePropList = ((List>) shapePropsObj).stream()
76 | .map(e -> (BasePropType) e).collect(Collectors.toList());
77 | bean.setShapePropTypeList(shapePropList);
78 | }
79 | String jsonData = (String) extraData.get("jsonData");
80 | if (type != null && jsonData != null && !jsonData.equals("")) {
81 | bean.setJsonData(jsonData);
82 | }
83 | propTypeBeans.add(bean);
84 | }
85 | }
86 | // sort by name
87 | if (this.settingService.getState().isSortProps()) {
88 | return propTypeBeans.stream()
89 | .filter(PropTypesHelper.distinctByKey(PropTypeBean::getName))
90 | .sorted(Comparator.comparing(PropTypeBean::getName))
91 | .collect(Collectors.toList());
92 | } else {
93 | return propTypeBeans.stream()
94 | .filter(PropTypesHelper.distinctByKey(PropTypeBean::getName))
95 | .collect(Collectors.toList());
96 | }
97 |
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/src/com/suming/plugin/ui/JsonInputDialog.form:
--------------------------------------------------------------------------------
1 |
2 |
91 |
--------------------------------------------------------------------------------
/src/com/suming/plugin/ui/ShapePropTypesDialog.form:
--------------------------------------------------------------------------------
1 |
2 |
91 |
--------------------------------------------------------------------------------
/src/com/suming/plugin/ui/ShapePropTypesDialog.java:
--------------------------------------------------------------------------------
1 | package com.suming.plugin.ui;
2 |
3 | import com.intellij.ui.table.JBTable;
4 | import com.suming.plugin.bean.BasePropType;
5 | import sun.swing.table.DefaultTableCellHeaderRenderer;
6 |
7 | import javax.swing.*;
8 | import javax.swing.table.TableColumn;
9 | import java.awt.*;
10 | import java.awt.event.KeyEvent;
11 | import java.awt.event.WindowAdapter;
12 | import java.awt.event.WindowEvent;
13 | import java.util.ArrayList;
14 | import java.util.List;
15 |
16 | import static javax.swing.ListSelectionModel.SINGLE_SELECTION;
17 |
18 | public class ShapePropTypesDialog extends JDialog {
19 | private JPanel contentPane;
20 | private JButton buttonOK;
21 | private JButton buttonCancel;
22 | private JButton pasteWithJSONButton;
23 | private JScrollPane sp;
24 | private JButton addPropBtn;
25 | private JTable table;
26 | private ShapePropTypesModel model;
27 | private ShapePropTypesDialog.onSubmitListener onSubmitListener;
28 |
29 | public void setOnSubmitListener(ShapePropTypesDialog.onSubmitListener onSubmitListener) {
30 | this.onSubmitListener = onSubmitListener;
31 | }
32 |
33 | public ShapePropTypesDialog(List propTypeList, String title) {
34 | setContentPane(contentPane);
35 | setTitle((title !=null && !title.equals("")? title : "unnamed"));
36 | setModal(true);
37 | getRootPane().setDefaultButton(buttonOK);
38 |
39 | buttonOK.addActionListener(e -> onOK());
40 |
41 | buttonCancel.addActionListener(e -> onCancel());
42 |
43 | // call onCancel() when cross is clicked
44 | setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
45 | addWindowListener(new WindowAdapter() {
46 | public void windowClosing(WindowEvent e) {
47 | onCancel();
48 | }
49 | });
50 |
51 | // call onCancel() on ESCAPE
52 | contentPane.registerKeyboardAction(e -> onCancel(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
53 |
54 |
55 | // init Table
56 | initTable(propTypeList);
57 | // init other widget
58 | initOtherWidgets();
59 | }
60 |
61 | private void initTable(List propTypeList) {
62 | table = new JBTable();
63 | model = new ShapePropTypesModel();
64 | model.initData(propTypeList);
65 | table.setModel(model);
66 | final DefaultListSelectionModel defaultListSelectionModel = new DefaultListSelectionModel();
67 | defaultListSelectionModel.setSelectionMode(SINGLE_SELECTION);
68 | table.setSelectionModel(defaultListSelectionModel);
69 | // form header center
70 | DefaultTableCellHeaderRenderer thr = new DefaultTableCellHeaderRenderer();
71 | thr.setHorizontalAlignment(JLabel.CENTER);
72 | table.getTableHeader().setDefaultRenderer(thr);
73 | //render special column
74 | TableColumn nameColumn = table.getColumn("name");
75 | TableColumn typeColumn = table.getColumn("type");
76 | TableColumn isRequireColumn = table.getColumn("isRequired");
77 | TableColumn operationColumn = table.getColumn("ops");
78 | nameColumn.setCellRenderer(new NameTextRenderer(true, "Please input name !"));
79 | nameColumn.setCellEditor(new DefaultCellEditor(new NameTextRenderer(false, "Please input name !")));
80 | nameColumn.setPreferredWidth(200);
81 | typeColumn.setCellEditor(new DefaultCellEditor(new ComboBoxRenderer(false)));
82 | typeColumn.setCellRenderer(new ComboBoxRenderer(false));
83 | typeColumn.setPreferredWidth(100);
84 | isRequireColumn.setCellEditor(new DefaultCellEditor(new CheckBoxRenderer()));
85 | isRequireColumn.setCellRenderer(new CheckBoxRenderer());
86 | isRequireColumn.setWidth(50);
87 | ButtonEditor buttonEditor = new ButtonEditor();
88 | operationColumn.setCellRenderer(new ButtonRenderer());
89 | operationColumn.setCellEditor(buttonEditor);
90 | operationColumn.setPreferredWidth(80);
91 | sp.setViewportView(table);
92 | }
93 |
94 | private void initOtherWidgets(){
95 | // add button onClick event
96 | addPropBtn.addActionListener(e -> {
97 | model.addRow(new BasePropType("","any", false ));
98 | int rowCount = table.getRowCount();
99 | table.getSelectionModel().setSelectionInterval(rowCount-1 , rowCount- 1 );
100 | Rectangle rect = table.getCellRect(rowCount-1 , 0 , true );
101 | table.scrollRectToVisible(rect);
102 | });
103 | pasteWithJSONButton.addActionListener(e -> {
104 | JsonInputDialog dialog = new JsonInputDialog();
105 | dialog.pack();
106 | dialog.setLocationRelativeTo(this);
107 | dialog.setOnSubmitListener(beans -> model.reInitData(beans));
108 | dialog.setVisible(true);
109 | });
110 | }
111 |
112 | private void onOK() {
113 | // add your code here
114 | dispose();
115 | if(this.onSubmitListener!=null){
116 | this.onSubmitListener.onSubmit(model.data2PropList());
117 | }
118 | }
119 |
120 | private void onCancel() {
121 | dispose();
122 | }
123 |
124 | public interface onSubmitListener{
125 | void onSubmit(List beans);
126 | }
127 |
128 | public static void main(String[] args) {
129 | List list = new ArrayList<>();
130 | list.add(new BasePropType("test", "string", true));
131 | ShapePropTypesDialog dialog = new ShapePropTypesDialog(list, "测试弹框");
132 | dialog.pack();
133 | dialog.setVisible(true);
134 | System.exit(0);
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/src/com/suming/plugin/utils/PropTypesHelper.java:
--------------------------------------------------------------------------------
1 | package com.suming.plugin.utils;
2 |
3 | import com.suming.plugin.bean.BasePropType;
4 | import com.suming.plugin.bean.PropTypeBean;
5 |
6 | import java.util.ArrayList;
7 | import java.util.Comparator;
8 | import java.util.List;
9 | import java.util.Set;
10 | import java.util.concurrent.ConcurrentHashMap;
11 | import java.util.function.Function;
12 | import java.util.function.Predicate;
13 | import java.util.regex.Matcher;
14 | import java.util.regex.Pattern;
15 |
16 | public class PropTypesHelper {
17 | public static Predicate distinctByKey(Function super T, ?> keyExtractor) {
18 | Set