@bpmn-io/properties-panel 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -6,11 +6,20 @@ All notable changes to [`@bpmn-io/properties-panel`](https://github.com/bpmn-io/
6
6
 
7
7
  ___Note:__ Yet to be released changes appear here._
8
8
 
9
+ ## 0.6.0
10
+
11
+ * `FEAT`: accept callbacks instead of containers for `add` and `remove` props ([#108](https://github.com/bpmn-io/properties-panel/issues/108))
12
+ * `FIX`: use valid HTML in add/remove buttons ([#111](https://github.com/bpmn-io/properties-panel/pull/111))
13
+
14
+ ### BREAKING CHANGES
15
+
16
+ * `ListGroup#add` changed to function instead of Preact component
17
+ * `Collapsible#remove` changed to function instead of Preact component
9
18
 
10
19
  ## 0.5.1
11
20
 
12
- * `FEAT`: allow custom selector for `ListEntry#autoFocusEntry` (['4afae1'](https://github.com/bpmn-io/properties-panel/commit/4afae1ec0215417d961b176840f19e51ba8b9043))
13
- * `FEAT`: add variable for monospace font (['354fc9'](https://github.com/bpmn-io/properties-panel/commit/354fc99c8e54c1eb3c8cb2bca20630172e7fad7b))
21
+ * `FIX`: allow custom selector for `ListEntry#autoFocusEntry` ([`4afae1`](https://github.com/bpmn-io/properties-panel/commit/4afae1ec0215417d961b176840f19e51ba8b9043))
22
+ * `CHORE`: add variable for monospace font ([`354fc9`](https://github.com/bpmn-io/properties-panel/commit/354fc99c8e54c1eb3c8cb2bca20630172e7fad7b))
14
23
 
15
24
  ## 0.5.0
16
25
 
@@ -60,7 +60,7 @@
60
60
 
61
61
  --input-background-color: var(--color-grey-225-10-97);
62
62
  --input-border-color: var(--color-grey-225-10-75);
63
-
63
+
64
64
  --input-focus-background-color: var(--color-blue-205-100-95);
65
65
  --input-focus-border-color: var(--color-blue-205-100-50);
66
66
 
@@ -239,12 +239,7 @@
239
239
  margin-right: 0;
240
240
  }
241
241
 
242
- .bio-properties-panel-add-container {
243
- pointer-events: none;
244
- }
245
-
246
242
  .bio-properties-panel-add-entry {
247
- pointer-events: all;
248
243
  fill: var(--add-entry-fill-color);
249
244
  border-radius: 11px;
250
245
  }
@@ -445,7 +440,7 @@ textarea.bio-properties-panel-input {
445
440
 
446
441
  .bio-properties-panel-simple + .bio-properties-panel-remove-entry {
447
442
  margin: auto;
448
- }
443
+ }
449
444
 
450
445
  /**
451
446
  * Toggle Switch
@@ -574,12 +569,7 @@ textarea.bio-properties-panel-input {
574
569
  align-self: center;
575
570
  }
576
571
 
577
- .bio-properties-panel-remove-container {
578
- pointer-events: none;
579
- }
580
-
581
572
  .bio-properties-panel-remove-entry {
582
- pointer-events: all;
583
573
  display: flex;
584
574
  align-items: center;
585
575
  justify-content: center;
@@ -637,8 +627,8 @@ textarea.bio-properties-panel-input {
637
627
  left: -18px;
638
628
  }
639
629
 
640
- /*
641
- * List entry
630
+ /*
631
+ * List entry
642
632
  */
643
633
  .bio-properties-panel-list-entry {
644
634
  position: relative;
@@ -777,14 +767,14 @@ textarea.bio-properties-panel-input {
777
767
  .bio-properties-panel-list-entry-item .bio-properties-panel-simple .bio-properties-panel-input {
778
768
  border-radius: 0;
779
769
  margin-bottom: -2px;
780
- }
770
+ }
781
771
 
782
- .bio-properties-panel-list-entry-item:first-child .bio-properties-panel-simple .bio-properties-panel-input {
772
+ .bio-properties-panel-list-entry-item:first-child .bio-properties-panel-simple .bio-properties-panel-input {
783
773
  border-top-left-radius: 2px;
784
774
  border-top-right-radius: 2px;
785
- }
775
+ }
786
776
 
787
- .bio-properties-panel-list-entry-item:last-child .bio-properties-panel-simple .bio-properties-panel-input {
777
+ .bio-properties-panel-list-entry-item:last-child .bio-properties-panel-simple .bio-properties-panel-input {
788
778
  border-bottom-left-radius: 2px;
789
779
  border-bottom-right-radius: 2px;
790
780
  }
@@ -22,11 +22,11 @@ const DEFAULT_LAYOUT = {
22
22
  * entries: Array<EntryDefinition>,
23
23
  * id: String,
24
24
  * label: String,
25
- * remove: import('preact').Component
25
+ * remove: (event: MouseEvent) => void
26
26
  * } } ListItemDefinition
27
27
  *
28
28
  * @typedef { {
29
- * add: import('preact').Component,
29
+ * add: (event: MouseEvent) => void,
30
30
  * component: import('preact').Component,
31
31
  * element: Object,
32
32
  * id: String,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/PropertiesPanel.js"],"names":["useState","useEffect","get","set","classnames","Header","Group","LayoutContext","DEFAULT_LAYOUT","open","PropertiesPanel","props","element","headerProvider","groups","layoutConfig","layoutChanged","layout","setLayout","createLayoutContext","getLayoutForKey","key","defaultValue","setLayoutForKey","config","layoutContext","map","group","component","GroupComponent","id","overrides"],"mappings":"AAAA,SACEA,QADF,EAEEC,SAFF,QAGO,cAHP;AAKA,SACEC,GADF,EAEEC,GAFF,QAGO,UAHP;AAKA,OAAOC,UAAP,MAAuB,YAAvB;AAEA,OAAOC,MAAP,MAAmB,qBAAnB;AAEA,OAAOC,KAAP,MAAkB,oBAAlB;AAEA,SACEC,aADF,QAEO,WAFP;;;AAIA,MAAMC,cAAc,GAAG;AACrBC,EAAAA,IAAI,EAAE;AADe,CAAvB;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA,eAAe,SAASC,eAAT,CAAyBC,KAAzB,EAAgC;AAC7C,QAAM;AACJC,IAAAA,OADI;AAEJC,IAAAA,cAFI;AAGJC,IAAAA,MAHI;AAIJC,IAAAA,YAAY,GAAG,EAJX;AAKJC,IAAAA;AALI,MAMFL,KANJ;AAQA,QAAM,CAAEM,MAAF,EAAUC,SAAV,IAAwBlB,QAAQ,CAACmB,mBAAmB,CAACJ,YAAD,CAApB,CAAtC;AAEAd,EAAAA,SAAS,CAAC,MAAM;AACd,QAAI,OAAOe,aAAP,KAAyB,UAA7B,EAAyC;AACvCA,MAAAA,aAAa,CAACC,MAAD,CAAb;AACD;AACF,GAJQ,EAIN,CAAEA,MAAF,EAAUD,aAAV,CAJM,CAAT;;AAMA,QAAMI,eAAe,GAAG,CAACC,GAAD,EAAMC,YAAN,KAAuB;AAC7C,WAAOpB,GAAG,CAACe,MAAD,EAASI,GAAT,EAAcC,YAAd,CAAV;AACD,GAFD;;AAIA,QAAMC,eAAe,GAAG,CAACF,GAAD,EAAMG,MAAN,KAAiB;AACvCN,IAAAA,SAAS,CAACf,GAAG,CAACc,MAAD,EAASI,GAAT,EAAcG,MAAd,CAAJ,CAAT;AACD,GAFD;;AAIA,QAAMC,aAAa,GAAG;AACpBR,IAAAA,MADoB;AAEpBC,IAAAA,SAFoB;AAGpBE,IAAAA,eAHoB;AAIpBG,IAAAA;AAJoB,GAAtB;;AAOA,MAAI,CAACX,OAAL,EAAc;AACZ,WAAO;AAAK,MAAA,KAAK,EAAC,kCAAX;AAAA;AAAA,MAAP;AACD;;AAED,SAAO,KAAC,aAAD,CAAe,QAAf;AAAwB,IAAA,KAAK,EAAGa,aAAhC;AAAA,cACL;AACE,MAAA,KAAK,EAAGrB,UAAU,CAChB,sBADgB,EAEhBa,MAAM,CAACR,IAAP,GAAc,MAAd,GAAuB,EAFP,CADpB;AAAA,iBAKE,KAAC,MAAD;AACE,QAAA,OAAO,EAAGG,OADZ;AAEE,QAAA,cAAc,EAAGC;AAFnB,QALF,EAQE;AAAK,QAAA,KAAK,EAAC,uCAAX;AAAA,kBAEIC,MAAM,CAACY,GAAP,CAAWC,KAAK,IAAI;AAElB,gBAAM;AACJC,YAAAA,SAAS,EAAEC,cAAc,GAAGvB,KADxB;AAEJwB,YAAAA;AAFI,cAGFH,KAHJ;AAKA,iBAAO,KAAC,cAAD;AAEL,YAAA,OAAO,EAAGf,OAFL;AAAA,eAGAe;AAHA,aACCG,EADD,CAAP;AAID,SAXD;AAFJ,QARF;AAAA;AADK,IAAP;AA2BD,C,CAGD;;AAEA,SAASX,mBAAT,CAA6BY,SAA7B,EAAwC;AACtC,SAAO,EACL,GAAGvB,cADE;AAEL,OAAGuB;AAFE,GAAP;AAID","sourcesContent":["import {\n useState,\n useEffect\n} from 'preact/hooks';\n\nimport {\n get,\n set\n} from 'min-dash';\n\nimport classnames from 'classnames';\n\nimport Header from './components/Header';\n\nimport Group from './components/Group';\n\nimport {\n LayoutContext\n} from './context';\n\nconst DEFAULT_LAYOUT = {\n open: true\n};\n\n\n/**\n * @typedef { {\n * component: import('preact').ComponentChild,\n * id: String,\n * isEdited?: Function\n * } } EntryDefinition\n *\n * @typedef { {\n * autoFocusEntry: String,\n * autoOpen?: Boolean,\n * entries: Array<EntryDefinition>,\n * id: String,\n * label: String,\n * remove: import('preact').Component\n * } } ListItemDefinition\n *\n * @typedef { {\n * add: import('preact').Component,\n * component: import('preact').Component,\n * element: Object,\n * id: String,\n * items: Array<ListItemDefinition>,\n * label: String,\n * shouldSort?: Boolean,\n * shouldOpen?: Boolean\n * } } ListGroupDefinition\n *\n * @typedef { {\n * component?: import('preact').Component,\n * entries: Array<EntryDefinition>,\n * id: String,\n * label: String\n * } } GroupDefinition\n *\n */\n\n\n/**\n * A basic properties panel component. Describes *how* content will be rendered, accepts\n * data from implementor to describe *what* will be rendered.\n *\n * @param {Object} props\n * @param {Object} props.element\n * @param {import('./components/Header').HeaderProvider} props.headerProvider\n * @param {Array<GroupDefinition|ListGroupDefinition>} props.groups\n * @param {Object} [props.layoutConfig]\n * @param {Function} [props.layoutChanged]\n */\nexport default function PropertiesPanel(props) {\n const {\n element,\n headerProvider,\n groups,\n layoutConfig = {},\n layoutChanged\n } = props;\n\n const [ layout, setLayout ] = useState(createLayoutContext(layoutConfig));\n\n useEffect(() => {\n if (typeof layoutChanged === 'function') {\n layoutChanged(layout);\n }\n }, [ layout, layoutChanged ]);\n\n const getLayoutForKey = (key, defaultValue) => {\n return get(layout, key, defaultValue);\n };\n\n const setLayoutForKey = (key, config) => {\n setLayout(set(layout, key, config));\n };\n\n const layoutContext = {\n layout,\n setLayout,\n getLayoutForKey,\n setLayoutForKey\n };\n\n if (!element) {\n return <div class=\"bio-properties-panel-placeholder\">Select an element to edit its properties.</div>;\n }\n\n return <LayoutContext.Provider value={ layoutContext }>\n <div\n class={ classnames(\n 'bio-properties-panel',\n layout.open ? 'open' : '')\n }>\n <Header\n element={ element }\n headerProvider={ headerProvider } />\n <div class=\"bio-properties-panel-scroll-container\">\n {\n groups.map(group => {\n\n const {\n component: GroupComponent = Group,\n id\n } = group;\n\n return <GroupComponent\n key={ id }\n element={ element }\n { ...group } />;\n })\n }\n </div>\n </div>\n </LayoutContext.Provider>;\n}\n\n\n// helpers //////////////////\n\nfunction createLayoutContext(overrides) {\n return {\n ...DEFAULT_LAYOUT,\n ...overrides\n };\n}\n"],"file":"PropertiesPanel.js"}
1
+ {"version":3,"sources":["../src/PropertiesPanel.js"],"names":["useState","useEffect","get","set","classnames","Header","Group","LayoutContext","DEFAULT_LAYOUT","open","PropertiesPanel","props","element","headerProvider","groups","layoutConfig","layoutChanged","layout","setLayout","createLayoutContext","getLayoutForKey","key","defaultValue","setLayoutForKey","config","layoutContext","map","group","component","GroupComponent","id","overrides"],"mappings":"AAAA,SACEA,QADF,EAEEC,SAFF,QAGO,cAHP;AAKA,SACEC,GADF,EAEEC,GAFF,QAGO,UAHP;AAKA,OAAOC,UAAP,MAAuB,YAAvB;AAEA,OAAOC,MAAP,MAAmB,qBAAnB;AAEA,OAAOC,KAAP,MAAkB,oBAAlB;AAEA,SACEC,aADF,QAEO,WAFP;;;AAIA,MAAMC,cAAc,GAAG;AACrBC,EAAAA,IAAI,EAAE;AADe,CAAvB;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA,eAAe,SAASC,eAAT,CAAyBC,KAAzB,EAAgC;AAC7C,QAAM;AACJC,IAAAA,OADI;AAEJC,IAAAA,cAFI;AAGJC,IAAAA,MAHI;AAIJC,IAAAA,YAAY,GAAG,EAJX;AAKJC,IAAAA;AALI,MAMFL,KANJ;AAQA,QAAM,CAAEM,MAAF,EAAUC,SAAV,IAAwBlB,QAAQ,CAACmB,mBAAmB,CAACJ,YAAD,CAApB,CAAtC;AAEAd,EAAAA,SAAS,CAAC,MAAM;AACd,QAAI,OAAOe,aAAP,KAAyB,UAA7B,EAAyC;AACvCA,MAAAA,aAAa,CAACC,MAAD,CAAb;AACD;AACF,GAJQ,EAIN,CAAEA,MAAF,EAAUD,aAAV,CAJM,CAAT;;AAMA,QAAMI,eAAe,GAAG,CAACC,GAAD,EAAMC,YAAN,KAAuB;AAC7C,WAAOpB,GAAG,CAACe,MAAD,EAASI,GAAT,EAAcC,YAAd,CAAV;AACD,GAFD;;AAIA,QAAMC,eAAe,GAAG,CAACF,GAAD,EAAMG,MAAN,KAAiB;AACvCN,IAAAA,SAAS,CAACf,GAAG,CAACc,MAAD,EAASI,GAAT,EAAcG,MAAd,CAAJ,CAAT;AACD,GAFD;;AAIA,QAAMC,aAAa,GAAG;AACpBR,IAAAA,MADoB;AAEpBC,IAAAA,SAFoB;AAGpBE,IAAAA,eAHoB;AAIpBG,IAAAA;AAJoB,GAAtB;;AAOA,MAAI,CAACX,OAAL,EAAc;AACZ,WAAO;AAAK,MAAA,KAAK,EAAC,kCAAX;AAAA;AAAA,MAAP;AACD;;AAED,SAAO,KAAC,aAAD,CAAe,QAAf;AAAwB,IAAA,KAAK,EAAGa,aAAhC;AAAA,cACL;AACE,MAAA,KAAK,EAAGrB,UAAU,CAChB,sBADgB,EAEhBa,MAAM,CAACR,IAAP,GAAc,MAAd,GAAuB,EAFP,CADpB;AAAA,iBAKE,KAAC,MAAD;AACE,QAAA,OAAO,EAAGG,OADZ;AAEE,QAAA,cAAc,EAAGC;AAFnB,QALF,EAQE;AAAK,QAAA,KAAK,EAAC,uCAAX;AAAA,kBAEIC,MAAM,CAACY,GAAP,CAAWC,KAAK,IAAI;AAElB,gBAAM;AACJC,YAAAA,SAAS,EAAEC,cAAc,GAAGvB,KADxB;AAEJwB,YAAAA;AAFI,cAGFH,KAHJ;AAKA,iBAAO,KAAC,cAAD;AAEL,YAAA,OAAO,EAAGf,OAFL;AAAA,eAGAe;AAHA,aACCG,EADD,CAAP;AAID,SAXD;AAFJ,QARF;AAAA;AADK,IAAP;AA2BD,C,CAGD;;AAEA,SAASX,mBAAT,CAA6BY,SAA7B,EAAwC;AACtC,SAAO,EACL,GAAGvB,cADE;AAEL,OAAGuB;AAFE,GAAP;AAID","sourcesContent":["import {\n useState,\n useEffect\n} from 'preact/hooks';\n\nimport {\n get,\n set\n} from 'min-dash';\n\nimport classnames from 'classnames';\n\nimport Header from './components/Header';\n\nimport Group from './components/Group';\n\nimport {\n LayoutContext\n} from './context';\n\nconst DEFAULT_LAYOUT = {\n open: true\n};\n\n\n/**\n * @typedef { {\n * component: import('preact').ComponentChild,\n * id: String,\n * isEdited?: Function\n * } } EntryDefinition\n *\n * @typedef { {\n * autoFocusEntry: String,\n * autoOpen?: Boolean,\n * entries: Array<EntryDefinition>,\n * id: String,\n * label: String,\n * remove: (event: MouseEvent) => void\n * } } ListItemDefinition\n *\n * @typedef { {\n * add: (event: MouseEvent) => void,\n * component: import('preact').Component,\n * element: Object,\n * id: String,\n * items: Array<ListItemDefinition>,\n * label: String,\n * shouldSort?: Boolean,\n * shouldOpen?: Boolean\n * } } ListGroupDefinition\n *\n * @typedef { {\n * component?: import('preact').Component,\n * entries: Array<EntryDefinition>,\n * id: String,\n * label: String\n * } } GroupDefinition\n *\n */\n\n\n/**\n * A basic properties panel component. Describes *how* content will be rendered, accepts\n * data from implementor to describe *what* will be rendered.\n *\n * @param {Object} props\n * @param {Object} props.element\n * @param {import('./components/Header').HeaderProvider} props.headerProvider\n * @param {Array<GroupDefinition|ListGroupDefinition>} props.groups\n * @param {Object} [props.layoutConfig]\n * @param {Function} [props.layoutChanged]\n */\nexport default function PropertiesPanel(props) {\n const {\n element,\n headerProvider,\n groups,\n layoutConfig = {},\n layoutChanged\n } = props;\n\n const [ layout, setLayout ] = useState(createLayoutContext(layoutConfig));\n\n useEffect(() => {\n if (typeof layoutChanged === 'function') {\n layoutChanged(layout);\n }\n }, [ layout, layoutChanged ]);\n\n const getLayoutForKey = (key, defaultValue) => {\n return get(layout, key, defaultValue);\n };\n\n const setLayoutForKey = (key, config) => {\n setLayout(set(layout, key, config));\n };\n\n const layoutContext = {\n layout,\n setLayout,\n getLayoutForKey,\n setLayoutForKey\n };\n\n if (!element) {\n return <div class=\"bio-properties-panel-placeholder\">Select an element to edit its properties.</div>;\n }\n\n return <LayoutContext.Provider value={ layoutContext }>\n <div\n class={ classnames(\n 'bio-properties-panel',\n layout.open ? 'open' : '')\n }>\n <Header\n element={ element }\n headerProvider={ headerProvider } />\n <div class=\"bio-properties-panel-scroll-container\">\n {\n groups.map(group => {\n\n const {\n component: GroupComponent = Group,\n id\n } = group;\n\n return <GroupComponent\n key={ id }\n element={ element }\n { ...group } />;\n })\n }\n </div>\n </div>\n </LayoutContext.Provider>;\n}\n\n\n// helpers //////////////////\n\nfunction createLayoutContext(overrides) {\n return {\n ...DEFAULT_LAYOUT,\n ...overrides\n };\n}\n"],"file":"PropertiesPanel.js"}
@@ -19,7 +19,7 @@ export default function ListGroup(props) {
19
19
  id,
20
20
  items,
21
21
  label,
22
- add: AddContainer,
22
+ add,
23
23
  shouldSort = true,
24
24
  shouldOpen = true
25
25
  } = props;
@@ -110,15 +110,14 @@ export default function ListGroup(props) {
110
110
  children: label
111
111
  }), _jsxs("div", {
112
112
  class: "bio-properties-panel-group-header-buttons",
113
- children: [AddContainer ? _jsx(AddContainer, {
114
- children: _jsxs("button", {
115
- title: "Create new list item",
116
- class: "bio-properties-panel-group-header-button bio-properties-panel-add-entry",
117
- children: [_jsx(CreateIcon, {}), !hasItems ? _jsx("div", {
118
- class: "bio-properties-panel-add-entry-label",
119
- children: "Create"
120
- }) : null]
121
- })
113
+ children: [add ? _jsxs("button", {
114
+ title: "Create new list item",
115
+ class: "bio-properties-panel-group-header-button bio-properties-panel-add-entry",
116
+ onClick: add,
117
+ children: [_jsx(CreateIcon, {}), !hasItems ? _jsx("span", {
118
+ class: "bio-properties-panel-add-entry-label",
119
+ children: "Create"
120
+ }) : null]
122
121
  }) : null, hasItems ? _jsx("div", {
123
122
  title: `List contains ${items.length} item${items.length != 1 ? 's' : ''}`,
124
123
  class: "bio-properties-panel-list-badge",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/ListGroup.js"],"names":["useEffect","useState","classnames","find","sortBy","useLayoutState","usePrevious","ListItem","ArrowIcon","CreateIcon","noop","ListGroup","props","element","id","items","label","add","AddContainer","shouldSort","shouldOpen","open","setOpen","ordering","setOrdering","newItemAdded","setNewItemAdded","prevItems","prevElement","elementChanged","shouldHandleEffects","createOrdering","sortItems","length","forEach","item","includes","push","newOrdering","toggleOpen","filter","unshift","keep","o","getItem","hasItems","map","index","i","toLowerCase"],"mappings":"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","sourcesContent":["import {\n useEffect,\n useState\n} from 'preact/hooks';\n\nimport classnames from 'classnames';\n\nimport {\n find,\n sortBy\n} from 'min-dash';\n\nimport {\n useLayoutState,\n usePrevious\n} from '../hooks';\n\nimport ListItem from './ListItem';\n\nimport {\n ArrowIcon,\n CreateIcon\n} from './icons';\n\nconst noop = () => {};\n\n/**\n * @param {import('../PropertiesPanel').ListGroupDefinition} props\n */\nexport default function ListGroup(props) {\n const {\n element,\n id,\n items,\n label,\n add: AddContainer,\n shouldSort = true,\n shouldOpen = true\n } = props;\n\n\n const [ open, setOpen ] = useLayoutState(\n [ 'groups', id, 'open' ],\n false\n );\n\n const [ ordering, setOrdering ] = useState([]);\n const [ newItemAdded, setNewItemAdded ] = useState(false);\n\n const prevItems = usePrevious(items);\n const prevElement = usePrevious(element);\n\n const elementChanged = element !== prevElement;\n const shouldHandleEffects = !elementChanged && (shouldSort || shouldOpen);\n\n // reset initial ordering when element changes (before first render)\n if (elementChanged) {\n setOrdering(createOrdering(shouldSort ? sortItems(items) : items));\n }\n\n // keep ordering in sync to items - and open changes\n\n // (0) set initial ordering from given items\n useEffect(() => {\n if (!prevItems || !shouldSort) {\n setOrdering(createOrdering(items));\n }\n }, [ items, element ]);\n\n // (1) items were added\n useEffect(() => {\n if (shouldHandleEffects && prevItems && items.length > prevItems.length) {\n\n let add = [];\n\n items.forEach(item => {\n if (!ordering.includes(item.id)) {\n add.push(item.id);\n }\n });\n\n let newOrdering = ordering;\n\n // open if not open and configured\n if (!open && shouldOpen) {\n toggleOpen();\n\n // if I opened and I should sort, then sort items\n if (shouldSort) {\n newOrdering = createOrdering(sortItems(items));\n }\n }\n\n // add new items on top or bottom depending on sorting behavior\n newOrdering = newOrdering.filter(item => !add.includes(item));\n if (shouldSort) {\n newOrdering.unshift(...add);\n } else {\n newOrdering.push(...add);\n }\n\n setOrdering(newOrdering);\n setNewItemAdded(true);\n } else {\n setNewItemAdded(false);\n }\n }, [ items, open, shouldHandleEffects ]);\n\n // (2) sort items on open if shouldSort is set\n useEffect(() => {\n\n if (shouldSort && open && !newItemAdded) {\n setOrdering(createOrdering(sortItems(items)));\n }\n }, [ open, shouldSort ]);\n\n // (3) items were deleted\n useEffect(() => {\n if (shouldHandleEffects && prevItems && items.length < prevItems.length) {\n let keep = [];\n\n ordering.forEach(o => {\n if (getItem(items, o)) {\n keep.push(o);\n }\n });\n\n setOrdering(keep);\n }\n }, [ items, shouldHandleEffects ]);\n\n const toggleOpen = () => setOpen(!open);\n\n const hasItems = !!items.length;\n\n return <div class=\"bio-properties-panel-group\" data-group-id={ 'group-' + id }>\n <div\n class={ classnames(\n 'bio-properties-panel-group-header',\n hasItems ? '' : 'empty',\n (hasItems && open) ? 'open' : ''\n ) }\n onClick={ hasItems ? toggleOpen : noop }>\n <div\n title={ label }\n class=\"bio-properties-panel-group-header-title\"\n >\n { label }\n </div>\n <div class=\"bio-properties-panel-group-header-buttons\">\n {\n AddContainer\n ? (\n <AddContainer>\n <button\n title=\"Create new list item\"\n class=\"bio-properties-panel-group-header-button bio-properties-panel-add-entry\"\n >\n <CreateIcon />\n {\n !hasItems ? (\n <div class=\"bio-properties-panel-add-entry-label\">Create</div>\n )\n : null\n }\n </button>\n </AddContainer>\n )\n : null\n }\n {\n hasItems\n ? (\n <div\n title={ `List contains ${items.length} item${items.length != 1 ? 's' : ''}` }\n class=\"bio-properties-panel-list-badge\"\n >\n { items.length }\n </div>\n )\n : null\n }\n {\n hasItems\n ? (\n <button\n title=\"Toggle section\"\n class=\"bio-properties-panel-group-header-button bio-properties-panel-arrow\"\n >\n <ArrowIcon class={ open ? 'bio-properties-panel-arrow-down' : 'bio-properties-panel-arrow-right' } />\n </button>\n )\n : null\n }\n </div>\n </div>\n <div class={ classnames(\n 'bio-properties-panel-list',\n open && hasItems ? 'open' : ''\n ) }>\n {\n ordering.map((o, index) => {\n const item = getItem(items, o);\n\n if (!item) {\n return;\n }\n\n return (\n <ListItem\n key={ item.id }\n\n // if item was added, open first or last item based on ordering\n autoOpen={ newItemAdded && (shouldSort ? index === 0 : index === ordering.length - 1) }\n { ...item } />\n );\n })\n }\n </div>\n </div>;\n}\n\n\n// helpers ////////////////////\n\n/**\n * Sorts given items alphanumeric by label\n */\nfunction sortItems(items) {\n return sortBy(items, i => i.label.toLowerCase());\n}\n\nfunction getItem(items, id) {\n return find(items, i => i.id === id);\n}\n\nfunction createOrdering(items) {\n return items.map(i => i.id);\n}\n"],"file":"ListGroup.js"}
1
+ {"version":3,"sources":["../../src/components/ListGroup.js"],"names":["useEffect","useState","classnames","find","sortBy","useLayoutState","usePrevious","ListItem","ArrowIcon","CreateIcon","noop","ListGroup","props","element","id","items","label","add","shouldSort","shouldOpen","open","setOpen","ordering","setOrdering","newItemAdded","setNewItemAdded","prevItems","prevElement","elementChanged","shouldHandleEffects","createOrdering","sortItems","length","forEach","item","includes","push","newOrdering","toggleOpen","filter","unshift","keep","o","getItem","hasItems","map","index","i","toLowerCase"],"mappings":"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","sourcesContent":["import {\n useEffect,\n useState\n} from 'preact/hooks';\n\nimport classnames from 'classnames';\n\nimport {\n find,\n sortBy\n} from 'min-dash';\n\nimport {\n useLayoutState,\n usePrevious\n} from '../hooks';\n\nimport ListItem from './ListItem';\n\nimport {\n ArrowIcon,\n CreateIcon\n} from './icons';\n\nconst noop = () => {};\n\n/**\n * @param {import('../PropertiesPanel').ListGroupDefinition} props\n */\nexport default function ListGroup(props) {\n const {\n element,\n id,\n items,\n label,\n add,\n shouldSort = true,\n shouldOpen = true\n } = props;\n\n\n const [ open, setOpen ] = useLayoutState(\n [ 'groups', id, 'open' ],\n false\n );\n\n const [ ordering, setOrdering ] = useState([]);\n const [ newItemAdded, setNewItemAdded ] = useState(false);\n\n const prevItems = usePrevious(items);\n const prevElement = usePrevious(element);\n\n const elementChanged = element !== prevElement;\n const shouldHandleEffects = !elementChanged && (shouldSort || shouldOpen);\n\n // reset initial ordering when element changes (before first render)\n if (elementChanged) {\n setOrdering(createOrdering(shouldSort ? sortItems(items) : items));\n }\n\n // keep ordering in sync to items - and open changes\n\n // (0) set initial ordering from given items\n useEffect(() => {\n if (!prevItems || !shouldSort) {\n setOrdering(createOrdering(items));\n }\n }, [ items, element ]);\n\n // (1) items were added\n useEffect(() => {\n if (shouldHandleEffects && prevItems && items.length > prevItems.length) {\n\n let add = [];\n\n items.forEach(item => {\n if (!ordering.includes(item.id)) {\n add.push(item.id);\n }\n });\n\n let newOrdering = ordering;\n\n // open if not open and configured\n if (!open && shouldOpen) {\n toggleOpen();\n\n // if I opened and I should sort, then sort items\n if (shouldSort) {\n newOrdering = createOrdering(sortItems(items));\n }\n }\n\n // add new items on top or bottom depending on sorting behavior\n newOrdering = newOrdering.filter(item => !add.includes(item));\n if (shouldSort) {\n newOrdering.unshift(...add);\n } else {\n newOrdering.push(...add);\n }\n\n setOrdering(newOrdering);\n setNewItemAdded(true);\n } else {\n setNewItemAdded(false);\n }\n }, [ items, open, shouldHandleEffects ]);\n\n // (2) sort items on open if shouldSort is set\n useEffect(() => {\n\n if (shouldSort && open && !newItemAdded) {\n setOrdering(createOrdering(sortItems(items)));\n }\n }, [ open, shouldSort ]);\n\n // (3) items were deleted\n useEffect(() => {\n if (shouldHandleEffects && prevItems && items.length < prevItems.length) {\n let keep = [];\n\n ordering.forEach(o => {\n if (getItem(items, o)) {\n keep.push(o);\n }\n });\n\n setOrdering(keep);\n }\n }, [ items, shouldHandleEffects ]);\n\n const toggleOpen = () => setOpen(!open);\n\n const hasItems = !!items.length;\n\n return <div class=\"bio-properties-panel-group\" data-group-id={ 'group-' + id }>\n <div\n class={ classnames(\n 'bio-properties-panel-group-header',\n hasItems ? '' : 'empty',\n (hasItems && open) ? 'open' : ''\n ) }\n onClick={ hasItems ? toggleOpen : noop }>\n <div\n title={ label }\n class=\"bio-properties-panel-group-header-title\"\n >\n { label }\n </div>\n <div class=\"bio-properties-panel-group-header-buttons\">\n {\n add\n ? (\n <button\n title=\"Create new list item\"\n class=\"bio-properties-panel-group-header-button bio-properties-panel-add-entry\"\n onClick={ add }\n >\n <CreateIcon />\n {\n !hasItems ? (\n <span class=\"bio-properties-panel-add-entry-label\">Create</span>\n )\n : null\n }\n </button>\n )\n : null\n }\n {\n hasItems\n ? (\n <div\n title={ `List contains ${items.length} item${items.length != 1 ? 's' : ''}` }\n class=\"bio-properties-panel-list-badge\"\n >\n { items.length }\n </div>\n )\n : null\n }\n {\n hasItems\n ? (\n <button\n title=\"Toggle section\"\n class=\"bio-properties-panel-group-header-button bio-properties-panel-arrow\"\n >\n <ArrowIcon class={ open ? 'bio-properties-panel-arrow-down' : 'bio-properties-panel-arrow-right' } />\n </button>\n )\n : null\n }\n </div>\n </div>\n <div class={ classnames(\n 'bio-properties-panel-list',\n open && hasItems ? 'open' : ''\n ) }>\n {\n ordering.map((o, index) => {\n const item = getItem(items, o);\n\n if (!item) {\n return;\n }\n\n return (\n <ListItem\n key={ item.id }\n\n // if item was added, open first or last item based on ordering\n autoOpen={ newItemAdded && (shouldSort ? index === 0 : index === ordering.length - 1) }\n { ...item } />\n );\n })\n }\n </div>\n </div>;\n}\n\n\n// helpers ////////////////////\n\n/**\n * Sorts given items alphanumeric by label\n */\nfunction sortItems(items) {\n return sortBy(items, i => i.label.toLowerCase());\n}\n\nfunction getItem(items, id) {\n return find(items, i => i.id === id);\n}\n\nfunction createOrdering(items) {\n return items.map(i => i.id);\n}\n"],"file":"ListGroup.js"}
@@ -8,7 +8,7 @@ export default function CollapsibleEntry(props) {
8
8
  id,
9
9
  entries = [],
10
10
  label,
11
- remove: RemoveContainer,
11
+ remove,
12
12
  open: shouldOpen
13
13
  } = props;
14
14
  const [open, setOpen] = useState(shouldOpen);
@@ -33,12 +33,11 @@ export default function CollapsibleEntry(props) {
33
33
  children: _jsx(ArrowIcon, {
34
34
  class: open ? 'bio-properties-panel-arrow-down' : 'bio-properties-panel-arrow-right'
35
35
  })
36
- }), RemoveContainer ? _jsx(RemoveContainer, {
37
- children: _jsx("button", {
38
- title: "Delete item",
39
- class: "bio-properties-panel-remove-entry",
40
- children: _jsx(DeleteIcon, {})
41
- })
36
+ }), remove ? _jsx("button", {
37
+ title: "Delete item",
38
+ class: "bio-properties-panel-remove-entry",
39
+ onClick: remove,
40
+ children: _jsx(DeleteIcon, {})
42
41
  }) : null]
43
42
  }), _jsx("div", {
44
43
  class: classnames('bio-properties-panel-collapsible-entry-entries', open ? 'open' : ''),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/entries/Collapsible.js"],"names":["useState","classnames","ArrowIcon","DeleteIcon","CollapsibleEntry","props","id","entries","label","remove","RemoveContainer","open","shouldOpen","setOpen","toggleOpen","placeholderLabel","map","e","component"],"mappings":"AAAA,SACEA,QADF,QAEO,cAFP;AAIA,OAAOC,UAAP,MAAuB,YAAvB;AAEA,SACEC,SADF,EAEEC,UAFF,QAGO,UAHP;;;AAMA,eAAe,SAASC,gBAAT,CAA0BC,KAA1B,EAAiC;AAC9C,QAAM;AACJC,IAAAA,EADI;AAEJC,IAAAA,OAAO,GAAG,EAFN;AAGJC,IAAAA,KAHI;AAIJC,IAAAA,MAAM,EAAEC,eAJJ;AAKJC,IAAAA,IAAI,EAAEC;AALF,MAMFP,KANJ;AAQA,QAAM,CAAEM,IAAF,EAAQE,OAAR,IAAoBb,QAAQ,CAACY,UAAD,CAAlC;;AAEA,QAAME,UAAU,GAAG,MAAMD,OAAO,CAAC,CAACF,IAAF,CAAhC,CAX8C,CAa9C;;;AACA,QAAMI,gBAAgB,GAAG,SAAzB;AAEA,SACE;AACE,qBAAgBT,EADlB;AAEE,IAAA,KAAK,EAAGL,UAAU,CAChB,wCADgB,EAEhBU,IAAI,GAAG,MAAH,GAAY,EAFA,CAFpB;AAAA,eAME;AAAK,MAAA,KAAK,EAAC,+CAAX;AAA2D,MAAA,OAAO,EAAGG,UAArE;AAAA,iBACE;AACE,QAAA,KAAK,EAAGN,KAAK,IAAIO,gBADnB;AAEE,QAAA,KAAK,EAAGd,UAAU,CAChB,qDADgB,EAEhB,CAACO,KAAD,IAAU,OAFM,CAFpB;AAAA,kBAMIA,KAAK,IAAIO;AANb,QADF,EASE;AACE,QAAA,KAAK,EAAC,kBADR;AAEE,QAAA,KAAK,EAAC,0EAFR;AAAA,kBAIE,KAAC,SAAD;AAAW,UAAA,KAAK,EAAGJ,IAAI,GAAG,iCAAH,GAAuC;AAA9D;AAJF,QATF,EAgBID,eAAe,GAGX,KAAC,eAAD;AAAA,kBACE;AAAQ,UAAA,KAAK,EAAC,aAAd;AAA4B,UAAA,KAAK,EAAC,mCAAlC;AAAA,oBACE,KAAC,UAAD;AADF;AADF,QAHW,GASX,IAzBR;AAAA,MANF,EAkCE;AAAK,MAAA,KAAK,EAAGT,UAAU,CACrB,gDADqB,EAErBU,IAAI,GAAG,MAAH,GAAY,EAFK,CAAvB;AAAA,gBAKIJ,OAAO,CAACS,GAAR,CAAYC,CAAC,IAAIA,CAAC,CAACC,SAAnB;AALJ,MAlCF;AAAA,IADF;AA6CD","sourcesContent":["import {\n useState\n} from 'preact/hooks';\n\nimport classnames from 'classnames';\n\nimport {\n ArrowIcon,\n DeleteIcon,\n} from '../icons';\n\n\nexport default function CollapsibleEntry(props) {\n const {\n id,\n entries = [],\n label,\n remove: RemoveContainer,\n open: shouldOpen\n } = props;\n\n const [ open, setOpen ] = useState(shouldOpen);\n\n const toggleOpen = () => setOpen(!open);\n\n // todo(pinussilvestrus): translate once we have a translate mechanism for the core\n const placeholderLabel = '<empty>';\n\n return (\n <div\n data-entry-id={ id }\n class={ classnames(\n 'bio-properties-panel-collapsible-entry',\n open ? 'open' : ''\n ) }>\n <div class=\"bio-properties-panel-collapsible-entry-header\" onClick={ toggleOpen }>\n <div\n title={ label || placeholderLabel }\n class={ classnames(\n 'bio-properties-panel-collapsible-entry-header-title',\n !label && 'empty'\n ) }>\n { label || placeholderLabel }\n </div>\n <button\n title=\"Toggle list item\"\n class=\"bio-properties-panel-arrow bio-properties-panel-collapsible-entry-arrow\"\n >\n <ArrowIcon class={ open ? 'bio-properties-panel-arrow-down' : 'bio-properties-panel-arrow-right' } />\n </button>\n {\n RemoveContainer\n ?\n (\n <RemoveContainer>\n <button title=\"Delete item\" class=\"bio-properties-panel-remove-entry\">\n <DeleteIcon />\n </button>\n </RemoveContainer>\n )\n : null\n }\n </div>\n <div class={ classnames(\n 'bio-properties-panel-collapsible-entry-entries',\n open ? 'open' : ''\n ) }>\n {\n entries.map(e => e.component)\n }\n </div>\n </div>\n );\n}"],"file":"Collapsible.js"}
1
+ {"version":3,"sources":["../../../src/components/entries/Collapsible.js"],"names":["useState","classnames","ArrowIcon","DeleteIcon","CollapsibleEntry","props","id","entries","label","remove","open","shouldOpen","setOpen","toggleOpen","placeholderLabel","map","e","component"],"mappings":"AAAA,SACEA,QADF,QAEO,cAFP;AAIA,OAAOC,UAAP,MAAuB,YAAvB;AAEA,SACEC,SADF,EAEEC,UAFF,QAGO,UAHP;;;AAMA,eAAe,SAASC,gBAAT,CAA0BC,KAA1B,EAAiC;AAC9C,QAAM;AACJC,IAAAA,EADI;AAEJC,IAAAA,OAAO,GAAG,EAFN;AAGJC,IAAAA,KAHI;AAIJC,IAAAA,MAJI;AAKJC,IAAAA,IAAI,EAAEC;AALF,MAMFN,KANJ;AAQA,QAAM,CAAEK,IAAF,EAAQE,OAAR,IAAoBZ,QAAQ,CAACW,UAAD,CAAlC;;AAEA,QAAME,UAAU,GAAG,MAAMD,OAAO,CAAC,CAACF,IAAF,CAAhC,CAX8C,CAa9C;;;AACA,QAAMI,gBAAgB,GAAG,SAAzB;AAEA,SACE;AACE,qBAAgBR,EADlB;AAEE,IAAA,KAAK,EAAGL,UAAU,CAChB,wCADgB,EAEhBS,IAAI,GAAG,MAAH,GAAY,EAFA,CAFpB;AAAA,eAME;AAAK,MAAA,KAAK,EAAC,+CAAX;AAA2D,MAAA,OAAO,EAAGG,UAArE;AAAA,iBACE;AACE,QAAA,KAAK,EAAGL,KAAK,IAAIM,gBADnB;AAEE,QAAA,KAAK,EAAGb,UAAU,CAChB,qDADgB,EAEhB,CAACO,KAAD,IAAU,OAFM,CAFpB;AAAA,kBAMIA,KAAK,IAAIM;AANb,QADF,EASE;AACE,QAAA,KAAK,EAAC,kBADR;AAEE,QAAA,KAAK,EAAC,0EAFR;AAAA,kBAIE,KAAC,SAAD;AAAW,UAAA,KAAK,EAAGJ,IAAI,GAAG,iCAAH,GAAuC;AAA9D;AAJF,QATF,EAgBID,MAAM,GAGF;AAAQ,QAAA,KAAK,EAAC,aAAd;AAA4B,QAAA,KAAK,EAAC,mCAAlC;AAAsE,QAAA,OAAO,EAAGA,MAAhF;AAAA,kBACE,KAAC,UAAD;AADF,QAHE,GAOF,IAvBR;AAAA,MANF,EAgCE;AAAK,MAAA,KAAK,EAAGR,UAAU,CACrB,gDADqB,EAErBS,IAAI,GAAG,MAAH,GAAY,EAFK,CAAvB;AAAA,gBAKIH,OAAO,CAACQ,GAAR,CAAYC,CAAC,IAAIA,CAAC,CAACC,SAAnB;AALJ,MAhCF;AAAA,IADF;AA2CD","sourcesContent":["import {\n useState\n} from 'preact/hooks';\n\nimport classnames from 'classnames';\n\nimport {\n ArrowIcon,\n DeleteIcon,\n} from '../icons';\n\n\nexport default function CollapsibleEntry(props) {\n const {\n id,\n entries = [],\n label,\n remove,\n open: shouldOpen\n } = props;\n\n const [ open, setOpen ] = useState(shouldOpen);\n\n const toggleOpen = () => setOpen(!open);\n\n // todo(pinussilvestrus): translate once we have a translate mechanism for the core\n const placeholderLabel = '<empty>';\n\n return (\n <div\n data-entry-id={ id }\n class={ classnames(\n 'bio-properties-panel-collapsible-entry',\n open ? 'open' : ''\n ) }>\n <div class=\"bio-properties-panel-collapsible-entry-header\" onClick={ toggleOpen }>\n <div\n title={ label || placeholderLabel }\n class={ classnames(\n 'bio-properties-panel-collapsible-entry-header-title',\n !label && 'empty'\n ) }>\n { label || placeholderLabel }\n </div>\n <button\n title=\"Toggle list item\"\n class=\"bio-properties-panel-arrow bio-properties-panel-collapsible-entry-arrow\"\n >\n <ArrowIcon class={ open ? 'bio-properties-panel-arrow-down' : 'bio-properties-panel-arrow-right' } />\n </button>\n {\n remove\n ?\n (\n <button title=\"Delete item\" class=\"bio-properties-panel-remove-entry\" onClick={ remove }>\n <DeleteIcon />\n </button>\n )\n : null\n }\n </div>\n <div class={ classnames(\n 'bio-properties-panel-collapsible-entry-entries',\n open ? 'open' : ''\n ) }>\n {\n entries.map(e => e.component)\n }\n </div>\n </div>\n );\n}"],"file":"Collapsible.js"}
@@ -81,7 +81,7 @@ export default function List(props) {
81
81
  title: "Create new list item",
82
82
  onClick: addItem,
83
83
  class: "bio-properties-panel-add-entry",
84
- children: [_jsx(CreateIcon, {}), !hasItems ? _jsx("div", {
84
+ children: [_jsx(CreateIcon, {}), !hasItems ? _jsx("span", {
85
85
  class: "bio-properties-panel-add-entry-label",
86
86
  children: "Create"
87
87
  }) : null]
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/entries/List.js"],"names":["useEffect","useRef","useState","query","domQuery","isFunction","useKeyFactory","usePrevious","classnames","ArrowIcon","CreateIcon","DeleteIcon","List","props","id","element","items","renderItem","label","open","shouldOpen","onAdd","onRemove","autoFocusEntry","compareFn","setOpen","hasItems","length","toggleOpen","opening","elementChanged","shouldReset","sortedItems","useSortedItems","newItems","useNewItems","addItem","event","stopPropagation","ItemsList","getKey","newItem","entry","selector","focusableInput","select","focus","map","item","index","key","currentItems","itemsRef","slice","current","sort","includes","unshift","push","filter","previousItems"],"mappings":"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","sourcesContent":["import {\n useEffect,\n useRef,\n useState\n} from 'preact/hooks';\n\nimport {\n query as domQuery\n} from 'min-dom';\n\nimport { isFunction } from 'min-dash';\n\nimport {\n useKeyFactory,\n usePrevious\n} from '../../hooks';\n\nimport classnames from 'classnames';\n\nimport {\n ArrowIcon,\n CreateIcon,\n DeleteIcon\n} from '../icons';\n\n/**\n * Entry for handling lists represented as nested entries.\n *\n * @template Item\n * @param {object} props\n * @param {string} props.id\n * @param {*} props.element\n * @param {Function} props.onAdd\n * @param {(item: Item, index: number, isNew: boolean) => JSX.Element} props.renderItem\n * @param {string} [props.label='<empty>']\n * @param {Function} [props.onRemove]\n * @param {Item[]} [props.items]\n * @param {boolean} [props.open]\n * @param {string|boolean} [props.autoFocusEntry] either a custom selector string or true to focus the first input\n * @param {(a: Item, b: Item) => -1 | 0 | 1} [props.compareFn]\n * @returns\n */\nexport default function List(props) {\n const {\n id,\n element,\n items = [],\n renderItem,\n label = '<empty>',\n open: shouldOpen,\n onAdd,\n onRemove,\n autoFocusEntry,\n compareFn\n } = props;\n\n const [ open, setOpen ] = useState(!!shouldOpen);\n\n const hasItems = !!items.length;\n const toggleOpen = () => hasItems && setOpen(!open);\n\n const opening = !usePrevious(open) && open;\n const elementChanged = usePrevious(element) !== element;\n const shouldReset = opening || elementChanged;\n const sortedItems = useSortedItems(items, compareFn, shouldReset);\n\n const newItems = useNewItems(items, elementChanged);\n\n useEffect(() => {\n if (open && !hasItems) {\n setOpen(false);\n }\n }, [ open, hasItems ]);\n\n /**\n * @param {MouseEvent} event\n */\n function addItem(event) {\n event.stopPropagation();\n onAdd();\n\n if (!open) {\n setOpen(true);\n }\n }\n\n return (\n <div\n data-entry-id={ id }\n class={ classnames(\n 'bio-properties-panel-entry',\n 'bio-properties-panel-list-entry',\n hasItems ? '' : 'empty',\n open ? 'open' : ''\n ) }>\n <div class=\"bio-properties-panel-list-entry-header\" onClick={ toggleOpen }>\n <div\n title={ label }\n class={ classnames(\n 'bio-properties-panel-list-entry-header-title',\n open && 'open'\n ) }>\n { label }\n </div>\n <div\n class=\"bio-properties-panel-list-entry-header-buttons\"\n >\n <button\n title=\"Create new list item\"\n onClick={ addItem }\n class=\"bio-properties-panel-add-entry\"\n >\n <CreateIcon />\n {\n !hasItems ? (\n <div class=\"bio-properties-panel-add-entry-label\">Create</div>\n )\n : null\n }\n </button>\n {\n hasItems && (\n <div\n title={ `List contains ${items.length} item${items.length != 1 ? 's' : ''}` }\n class=\"bio-properties-panel-list-badge\"\n >\n { items.length }\n </div>\n )\n }\n {\n hasItems && (\n <button\n title=\"Toggle list item\"\n class=\"bio-properties-panel-arrow\"\n >\n <ArrowIcon class={ open ? 'bio-properties-panel-arrow-down' : 'bio-properties-panel-arrow-right' } />\n </button>\n )\n }\n </div>\n </div>\n {\n hasItems && (\n <ItemsList\n autoFocusEntry={ autoFocusEntry }\n id={ id }\n open={ open }\n items={ sortedItems }\n newItems={ newItems }\n onRemove={ onRemove }\n renderItem={ renderItem }\n />\n )\n }\n </div>\n );\n}\n\nfunction ItemsList(props) {\n const {\n autoFocusEntry,\n id,\n items,\n newItems,\n open,\n onRemove,\n renderItem\n } = props;\n\n const getKey = useKeyFactory();\n\n const newItem = newItems[0];\n\n useEffect(() => {\n if (newItem && autoFocusEntry) {\n\n // (0) select the parent entry (containing all list items)\n const entry = domQuery(`[data-entry-id=\"${id}\"]`);\n\n // (1) select the first input or a custom element to be focussed\n const selector = typeof(autoFocusEntry) === 'boolean' ?\n '.bio-properties-panel-input' :\n autoFocusEntry;\n const focusableInput = domQuery(selector, entry);\n\n // (2) set focus\n if (focusableInput) {\n\n if (isFunction(focusableInput.select)) {\n focusableInput.select();\n } else if (isFunction(focusableInput.focus)) {\n focusableInput.focus();\n }\n\n }\n }\n }, [ newItem, autoFocusEntry, id ]);\n\n return (\n <ol class={ classnames(\n 'bio-properties-panel-list-entry-items',\n open ? 'open' : ''\n ) }>\n {\n items.map((item, index) => {\n const key = getKey(item);\n\n return (<li class=\"bio-properties-panel-list-entry-item\" key={ key }>\n { renderItem(item, index, item === newItem) }\n {\n onRemove && (\n <button\n type=\"button\"\n title=\"Delete item\"\n class=\"bio-properties-panel-remove-entry bio-properties-panel-remove-list-entry\"\n onClick={ () => onRemove && onRemove(item) }\n ><DeleteIcon /></button>\n )\n }\n </li>);\n })\n }\n </ol>);\n}\n\n/**\n * Place new items in the beginning of the list and sort the rest with provided function.\n *\n * @template Item\n * @param {Item[]} currentItems\n * @param {(a: Item, b: Item) => 0 | 1 | -1} [compareFn] function used to sort items\n * @param {boolean} [shouldReset=false] set to `true` to reset state of the hook\n * @returns {Item[]}\n */\nfunction useSortedItems(currentItems, compareFn, shouldReset = false) {\n const itemsRef = useRef(currentItems.slice());\n\n // (1) Reset and optionally sort.\n if (shouldReset) {\n itemsRef.current = currentItems.slice();\n\n if (compareFn) {\n itemsRef.current.sort(compareFn);\n }\n } else {\n const items = itemsRef.current;\n\n // (2) Add new item to the list.\n for (const item of currentItems) {\n if (!items.includes(item)) {\n\n // Unshift or push depending on whether we have a compareFn\n compareFn ? items.unshift(item) : items.push(item);\n }\n }\n\n // (3) Filter out removed items.\n itemsRef.current = items.filter(item => currentItems.includes(item));\n }\n\n return itemsRef.current;\n}\n\nfunction useNewItems(items = [], shouldReset) {\n const previousItems = usePrevious(items.slice()) || [];\n\n if (shouldReset) {\n return [];\n }\n\n return previousItems ? items.filter(item => !previousItems.includes(item)) : [];\n}\n"],"file":"List.js"}
1
+ {"version":3,"sources":["../../../src/components/entries/List.js"],"names":["useEffect","useRef","useState","query","domQuery","isFunction","useKeyFactory","usePrevious","classnames","ArrowIcon","CreateIcon","DeleteIcon","List","props","id","element","items","renderItem","label","open","shouldOpen","onAdd","onRemove","autoFocusEntry","compareFn","setOpen","hasItems","length","toggleOpen","opening","elementChanged","shouldReset","sortedItems","useSortedItems","newItems","useNewItems","addItem","event","stopPropagation","ItemsList","getKey","newItem","entry","selector","focusableInput","select","focus","map","item","index","key","currentItems","itemsRef","slice","current","sort","includes","unshift","push","filter","previousItems"],"mappings":"AAAA,SACEA,SADF,EAEEC,MAFF,EAGEC,QAHF,QAIO,cAJP;AAMA,SACEC,KAAK,IAAIC,QADX,QAEO,SAFP;AAIA,SAASC,UAAT,QAA2B,UAA3B;AAEA,SACEC,aADF,EAEEC,WAFF,QAGO,aAHP;AAKA,OAAOC,UAAP,MAAuB,YAAvB;AAEA,SACEC,SADF,EAEEC,UAFF,EAGEC,UAHF,QAIO,UAJP;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AACA,eAAe,SAASC,IAAT,CAAcC,KAAd,EAAqB;AAClC,QAAM;AACJC,IAAAA,EADI;AAEJC,IAAAA,OAFI;AAGJC,IAAAA,KAAK,GAAG,EAHJ;AAIJC,IAAAA,UAJI;AAKJC,IAAAA,KAAK,GAAG,SALJ;AAMJC,IAAAA,IAAI,EAAEC,UANF;AAOJC,IAAAA,KAPI;AAQJC,IAAAA,QARI;AASJC,IAAAA,cATI;AAUJC,IAAAA;AAVI,MAWFX,KAXJ;AAaA,QAAM,CAAEM,IAAF,EAAQM,OAAR,IAAoBvB,QAAQ,CAAC,CAAC,CAACkB,UAAH,CAAlC;AAEA,QAAMM,QAAQ,GAAG,CAAC,CAACV,KAAK,CAACW,MAAzB;;AACA,QAAMC,UAAU,GAAG,MAAMF,QAAQ,IAAID,OAAO,CAAC,CAACN,IAAF,CAA5C;;AAEA,QAAMU,OAAO,GAAG,CAACtB,WAAW,CAACY,IAAD,CAAZ,IAAsBA,IAAtC;AACA,QAAMW,cAAc,GAAGvB,WAAW,CAACQ,OAAD,CAAX,KAAyBA,OAAhD;AACA,QAAMgB,WAAW,GAAGF,OAAO,IAAIC,cAA/B;AACA,QAAME,WAAW,GAAGC,cAAc,CAACjB,KAAD,EAAQQ,SAAR,EAAmBO,WAAnB,CAAlC;AAEA,QAAMG,QAAQ,GAAGC,WAAW,CAACnB,KAAD,EAAQc,cAAR,CAA5B;AAEA9B,EAAAA,SAAS,CAAC,MAAM;AACd,QAAImB,IAAI,IAAI,CAACO,QAAb,EAAuB;AACrBD,MAAAA,OAAO,CAAC,KAAD,CAAP;AACD;AACF,GAJQ,EAIN,CAAEN,IAAF,EAAQO,QAAR,CAJM,CAAT;AAMA;AACF;AACA;;AACE,WAASU,OAAT,CAAiBC,KAAjB,EAAwB;AACtBA,IAAAA,KAAK,CAACC,eAAN;AACAjB,IAAAA,KAAK;;AAEL,QAAI,CAACF,IAAL,EAAW;AACTM,MAAAA,OAAO,CAAC,IAAD,CAAP;AACD;AACF;;AAED,SACE;AACE,qBAAgBX,EADlB;AAEE,IAAA,KAAK,EAAGN,UAAU,CAChB,4BADgB,EAEhB,iCAFgB,EAGhBkB,QAAQ,GAAG,EAAH,GAAQ,OAHA,EAIhBP,IAAI,GAAG,MAAH,GAAY,EAJA,CAFpB;AAAA,eAQE;AAAK,MAAA,KAAK,EAAC,wCAAX;AAAoD,MAAA,OAAO,EAAGS,UAA9D;AAAA,iBACE;AACE,QAAA,KAAK,EAAGV,KADV;AAEE,QAAA,KAAK,EAAGV,UAAU,CAChB,8CADgB,EAEhBW,IAAI,IAAI,MAFQ,CAFpB;AAAA,kBAMID;AANJ,QADF,EASE;AACE,QAAA,KAAK,EAAC,gDADR;AAAA,mBAGE;AACE,UAAA,KAAK,EAAC,sBADR;AAEE,UAAA,OAAO,EAAGkB,OAFZ;AAGE,UAAA,KAAK,EAAC,gCAHR;AAAA,qBAKE,KAAC,UAAD,KALF,EAOI,CAACV,QAAD,GACE;AAAM,YAAA,KAAK,EAAC,sCAAZ;AAAA;AAAA,YADF,GAGI,IAVR;AAAA,UAHF,EAiBIA,QAAQ,IACN;AACE,UAAA,KAAK,EAAI,iBAAgBV,KAAK,CAACW,MAAO,QAAOX,KAAK,CAACW,MAAN,IAAgB,CAAhB,GAAoB,GAApB,GAA0B,EAAG,EAD5E;AAEE,UAAA,KAAK,EAAC,iCAFR;AAAA,oBAIIX,KAAK,CAACW;AAJV,UAlBN,EA2BID,QAAQ,IACN;AACE,UAAA,KAAK,EAAC,kBADR;AAEE,UAAA,KAAK,EAAC,4BAFR;AAAA,oBAIE,KAAC,SAAD;AAAW,YAAA,KAAK,EAAGP,IAAI,GAAG,iCAAH,GAAuC;AAA9D;AAJF,UA5BN;AAAA,QATF;AAAA,MARF,EAwDIO,QAAQ,IACN,KAAC,SAAD;AACE,MAAA,cAAc,EAAGH,cADnB;AAEE,MAAA,EAAE,EAAGT,EAFP;AAGE,MAAA,IAAI,EAAGK,IAHT;AAIE,MAAA,KAAK,EAAGa,WAJV;AAKE,MAAA,QAAQ,EAAGE,QALb;AAME,MAAA,QAAQ,EAAGZ,QANb;AAOE,MAAA,UAAU,EAAGL;AAPf,MAzDN;AAAA,IADF;AAuED;;AAED,SAASsB,SAAT,CAAmB1B,KAAnB,EAA0B;AACxB,QAAM;AACJU,IAAAA,cADI;AAEJT,IAAAA,EAFI;AAGJE,IAAAA,KAHI;AAIJkB,IAAAA,QAJI;AAKJf,IAAAA,IALI;AAMJG,IAAAA,QANI;AAOJL,IAAAA;AAPI,MAQFJ,KARJ;AAUA,QAAM2B,MAAM,GAAGlC,aAAa,EAA5B;AAEA,QAAMmC,OAAO,GAAGP,QAAQ,CAAC,CAAD,CAAxB;AAEAlC,EAAAA,SAAS,CAAC,MAAM;AACd,QAAIyC,OAAO,IAAIlB,cAAf,EAA+B;AAE7B;AACA,YAAMmB,KAAK,GAAGtC,QAAQ,CAAE,mBAAkBU,EAAG,IAAvB,CAAtB,CAH6B,CAK7B;;AACA,YAAM6B,QAAQ,GAAG,OAAOpB,cAAP,KAA2B,SAA3B,GACf,6BADe,GAEfA,cAFF;AAGA,YAAMqB,cAAc,GAAGxC,QAAQ,CAACuC,QAAD,EAAWD,KAAX,CAA/B,CAT6B,CAW7B;;AACA,UAAIE,cAAJ,EAAoB;AAElB,YAAIvC,UAAU,CAACuC,cAAc,CAACC,MAAhB,CAAd,EAAuC;AACrCD,UAAAA,cAAc,CAACC,MAAf;AACD,SAFD,MAEO,IAAIxC,UAAU,CAACuC,cAAc,CAACE,KAAhB,CAAd,EAAsC;AAC3CF,UAAAA,cAAc,CAACE,KAAf;AACD;AAEF;AACF;AACF,GAvBQ,EAuBN,CAAEL,OAAF,EAAWlB,cAAX,EAA2BT,EAA3B,CAvBM,CAAT;AAyBA,SACE;AAAI,IAAA,KAAK,EAAGN,UAAU,CACpB,uCADoB,EAEpBW,IAAI,GAAG,MAAH,GAAY,EAFI,CAAtB;AAAA,cAKIH,KAAK,CAAC+B,GAAN,CAAU,CAACC,IAAD,EAAOC,KAAP,KAAiB;AACzB,YAAMC,GAAG,GAAGV,MAAM,CAACQ,IAAD,CAAlB;AAEA,aAAQ;AAAI,QAAA,KAAK,EAAC,sCAAV;AAAA,mBACJ/B,UAAU,CAAC+B,IAAD,EAAOC,KAAP,EAAcD,IAAI,KAAKP,OAAvB,CADN,EAGJnB,QAAQ,IACN;AACE,UAAA,IAAI,EAAC,QADP;AAEE,UAAA,KAAK,EAAC,aAFR;AAGE,UAAA,KAAK,EAAC,0EAHR;AAIE,UAAA,OAAO,EAAG,MAAMA,QAAQ,IAAIA,QAAQ,CAAC0B,IAAD,CAJtC;AAAA,oBAKC,KAAC,UAAD;AALD,UAJE;AAAA,SAAuDE,GAAvD,CAAR;AAaD,KAhBD;AALJ,IADF;AAyBD;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA,SAASjB,cAAT,CAAwBkB,YAAxB,EAAsC3B,SAAtC,EAAiDO,WAAW,GAAG,KAA/D,EAAsE;AACpE,QAAMqB,QAAQ,GAAGnD,MAAM,CAACkD,YAAY,CAACE,KAAb,EAAD,CAAvB,CADoE,CAGpE;;AACA,MAAItB,WAAJ,EAAiB;AACfqB,IAAAA,QAAQ,CAACE,OAAT,GAAmBH,YAAY,CAACE,KAAb,EAAnB;;AAEA,QAAI7B,SAAJ,EAAe;AACb4B,MAAAA,QAAQ,CAACE,OAAT,CAAiBC,IAAjB,CAAsB/B,SAAtB;AACD;AACF,GAND,MAMO;AACL,UAAMR,KAAK,GAAGoC,QAAQ,CAACE,OAAvB,CADK,CAGL;;AACA,SAAK,MAAMN,IAAX,IAAmBG,YAAnB,EAAiC;AAC/B,UAAI,CAACnC,KAAK,CAACwC,QAAN,CAAeR,IAAf,CAAL,EAA2B;AAEzB;AACAxB,QAAAA,SAAS,GAAGR,KAAK,CAACyC,OAAN,CAAcT,IAAd,CAAH,GAAyBhC,KAAK,CAAC0C,IAAN,CAAWV,IAAX,CAAlC;AACD;AACF,KAVI,CAYL;;;AACAI,IAAAA,QAAQ,CAACE,OAAT,GAAmBtC,KAAK,CAAC2C,MAAN,CAAaX,IAAI,IAAIG,YAAY,CAACK,QAAb,CAAsBR,IAAtB,CAArB,CAAnB;AACD;;AAED,SAAOI,QAAQ,CAACE,OAAhB;AACD;;AAED,SAASnB,WAAT,CAAqBnB,KAAK,GAAG,EAA7B,EAAiCe,WAAjC,EAA8C;AAC5C,QAAM6B,aAAa,GAAGrD,WAAW,CAACS,KAAK,CAACqC,KAAN,EAAD,CAAX,IAA8B,EAApD;;AAEA,MAAItB,WAAJ,EAAiB;AACf,WAAO,EAAP;AACD;;AAED,SAAO6B,aAAa,GAAG5C,KAAK,CAAC2C,MAAN,CAAaX,IAAI,IAAI,CAACY,aAAa,CAACJ,QAAd,CAAuBR,IAAvB,CAAtB,CAAH,GAAyD,EAA7E;AACD","sourcesContent":["import {\n useEffect,\n useRef,\n useState\n} from 'preact/hooks';\n\nimport {\n query as domQuery\n} from 'min-dom';\n\nimport { isFunction } from 'min-dash';\n\nimport {\n useKeyFactory,\n usePrevious\n} from '../../hooks';\n\nimport classnames from 'classnames';\n\nimport {\n ArrowIcon,\n CreateIcon,\n DeleteIcon\n} from '../icons';\n\n/**\n * Entry for handling lists represented as nested entries.\n *\n * @template Item\n * @param {object} props\n * @param {string} props.id\n * @param {*} props.element\n * @param {Function} props.onAdd\n * @param {(item: Item, index: number, isNew: boolean) => JSX.Element} props.renderItem\n * @param {string} [props.label='<empty>']\n * @param {Function} [props.onRemove]\n * @param {Item[]} [props.items]\n * @param {boolean} [props.open]\n * @param {string|boolean} [props.autoFocusEntry] either a custom selector string or true to focus the first input\n * @param {(a: Item, b: Item) => -1 | 0 | 1} [props.compareFn]\n * @returns\n */\nexport default function List(props) {\n const {\n id,\n element,\n items = [],\n renderItem,\n label = '<empty>',\n open: shouldOpen,\n onAdd,\n onRemove,\n autoFocusEntry,\n compareFn\n } = props;\n\n const [ open, setOpen ] = useState(!!shouldOpen);\n\n const hasItems = !!items.length;\n const toggleOpen = () => hasItems && setOpen(!open);\n\n const opening = !usePrevious(open) && open;\n const elementChanged = usePrevious(element) !== element;\n const shouldReset = opening || elementChanged;\n const sortedItems = useSortedItems(items, compareFn, shouldReset);\n\n const newItems = useNewItems(items, elementChanged);\n\n useEffect(() => {\n if (open && !hasItems) {\n setOpen(false);\n }\n }, [ open, hasItems ]);\n\n /**\n * @param {MouseEvent} event\n */\n function addItem(event) {\n event.stopPropagation();\n onAdd();\n\n if (!open) {\n setOpen(true);\n }\n }\n\n return (\n <div\n data-entry-id={ id }\n class={ classnames(\n 'bio-properties-panel-entry',\n 'bio-properties-panel-list-entry',\n hasItems ? '' : 'empty',\n open ? 'open' : ''\n ) }>\n <div class=\"bio-properties-panel-list-entry-header\" onClick={ toggleOpen }>\n <div\n title={ label }\n class={ classnames(\n 'bio-properties-panel-list-entry-header-title',\n open && 'open'\n ) }>\n { label }\n </div>\n <div\n class=\"bio-properties-panel-list-entry-header-buttons\"\n >\n <button\n title=\"Create new list item\"\n onClick={ addItem }\n class=\"bio-properties-panel-add-entry\"\n >\n <CreateIcon />\n {\n !hasItems ? (\n <span class=\"bio-properties-panel-add-entry-label\">Create</span>\n )\n : null\n }\n </button>\n {\n hasItems && (\n <div\n title={ `List contains ${items.length} item${items.length != 1 ? 's' : ''}` }\n class=\"bio-properties-panel-list-badge\"\n >\n { items.length }\n </div>\n )\n }\n {\n hasItems && (\n <button\n title=\"Toggle list item\"\n class=\"bio-properties-panel-arrow\"\n >\n <ArrowIcon class={ open ? 'bio-properties-panel-arrow-down' : 'bio-properties-panel-arrow-right' } />\n </button>\n )\n }\n </div>\n </div>\n {\n hasItems && (\n <ItemsList\n autoFocusEntry={ autoFocusEntry }\n id={ id }\n open={ open }\n items={ sortedItems }\n newItems={ newItems }\n onRemove={ onRemove }\n renderItem={ renderItem }\n />\n )\n }\n </div>\n );\n}\n\nfunction ItemsList(props) {\n const {\n autoFocusEntry,\n id,\n items,\n newItems,\n open,\n onRemove,\n renderItem\n } = props;\n\n const getKey = useKeyFactory();\n\n const newItem = newItems[0];\n\n useEffect(() => {\n if (newItem && autoFocusEntry) {\n\n // (0) select the parent entry (containing all list items)\n const entry = domQuery(`[data-entry-id=\"${id}\"]`);\n\n // (1) select the first input or a custom element to be focussed\n const selector = typeof(autoFocusEntry) === 'boolean' ?\n '.bio-properties-panel-input' :\n autoFocusEntry;\n const focusableInput = domQuery(selector, entry);\n\n // (2) set focus\n if (focusableInput) {\n\n if (isFunction(focusableInput.select)) {\n focusableInput.select();\n } else if (isFunction(focusableInput.focus)) {\n focusableInput.focus();\n }\n\n }\n }\n }, [ newItem, autoFocusEntry, id ]);\n\n return (\n <ol class={ classnames(\n 'bio-properties-panel-list-entry-items',\n open ? 'open' : ''\n ) }>\n {\n items.map((item, index) => {\n const key = getKey(item);\n\n return (<li class=\"bio-properties-panel-list-entry-item\" key={ key }>\n { renderItem(item, index, item === newItem) }\n {\n onRemove && (\n <button\n type=\"button\"\n title=\"Delete item\"\n class=\"bio-properties-panel-remove-entry bio-properties-panel-remove-list-entry\"\n onClick={ () => onRemove && onRemove(item) }\n ><DeleteIcon /></button>\n )\n }\n </li>);\n })\n }\n </ol>);\n}\n\n/**\n * Place new items in the beginning of the list and sort the rest with provided function.\n *\n * @template Item\n * @param {Item[]} currentItems\n * @param {(a: Item, b: Item) => 0 | 1 | -1} [compareFn] function used to sort items\n * @param {boolean} [shouldReset=false] set to `true` to reset state of the hook\n * @returns {Item[]}\n */\nfunction useSortedItems(currentItems, compareFn, shouldReset = false) {\n const itemsRef = useRef(currentItems.slice());\n\n // (1) Reset and optionally sort.\n if (shouldReset) {\n itemsRef.current = currentItems.slice();\n\n if (compareFn) {\n itemsRef.current.sort(compareFn);\n }\n } else {\n const items = itemsRef.current;\n\n // (2) Add new item to the list.\n for (const item of currentItems) {\n if (!items.includes(item)) {\n\n // Unshift or push depending on whether we have a compareFn\n compareFn ? items.unshift(item) : items.push(item);\n }\n }\n\n // (3) Filter out removed items.\n itemsRef.current = items.filter(item => currentItems.includes(item));\n }\n\n return itemsRef.current;\n}\n\nfunction useNewItems(items = [], shouldReset) {\n const previousItems = usePrevious(items.slice()) || [];\n\n if (shouldReset) {\n return [];\n }\n\n return previousItems ? items.filter(item => !previousItems.includes(item)) : [];\n}\n"],"file":"List.js"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bpmn-io/properties-panel",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "description": "Library for creating bpmn-io properties panels.",
5
5
  "main": "lib/index.js",
6
6
  "files": [