@bpmn-io/properties-panel 0.4.0 → 0.5.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.
@@ -1,4 +1,5 @@
1
1
  import { useState, useEffect } from 'preact/hooks';
2
+ import { get, set } from 'min-dash';
2
3
  import classnames from 'classnames';
3
4
  import Header from './components/Header';
4
5
  import Group from './components/Group';
@@ -31,7 +32,8 @@ const DEFAULT_LAYOUT = {
31
32
  * id: String,
32
33
  * items: Array<ListItemDefinition>,
33
34
  * label: String,
34
- * shouldSort?: Boolean
35
+ * shouldSort?: Boolean,
36
+ * shouldOpen?: Boolean
35
37
  * } } ListGroupDefinition
36
38
  *
37
39
  * @typedef { {
@@ -70,15 +72,18 @@ export default function PropertiesPanel(props) {
70
72
  }
71
73
  }, [layout, layoutChanged]);
72
74
 
75
+ const getLayoutForKey = (key, defaultValue) => {
76
+ return get(layout, key, defaultValue);
77
+ };
78
+
73
79
  const setLayoutForKey = (key, config) => {
74
- setLayout({ ...layout,
75
- [key]: config
76
- });
80
+ setLayout(set(layout, key, config));
77
81
  };
78
82
 
79
83
  const layoutContext = {
80
84
  layout,
81
85
  setLayout,
86
+ getLayoutForKey,
82
87
  setLayoutForKey
83
88
  };
84
89
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/PropertiesPanel.js"],"names":["useState","useEffect","classnames","Header","Group","LayoutContext","DEFAULT_LAYOUT","open","PropertiesPanel","props","element","headerProvider","groups","layoutConfig","layoutChanged","layout","setLayout","createLayoutContext","setLayoutForKey","key","config","layoutContext","map","group","component","GroupComponent","id","overrides"],"mappings":"AAAA,SACEA,QADF,EAEEC,SAFF,QAGO,cAHP;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;;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,IAAwBhB,QAAQ,CAACiB,mBAAmB,CAACJ,YAAD,CAApB,CAAtC;AAEAZ,EAAAA,SAAS,CAAC,MAAM;AACd,QAAI,OAAOa,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,MAAN,KAAiB;AACvCJ,IAAAA,SAAS,CAAC,EACR,GAAGD,MADK;AAER,OAACI,GAAD,GAAOC;AAFC,KAAD,CAAT;AAID,GALD;;AAOA,QAAMC,aAAa,GAAG;AACpBN,IAAAA,MADoB;AAEpBC,IAAAA,SAFoB;AAGpBE,IAAAA;AAHoB,GAAtB;;AAMA,MAAI,CAACR,OAAL,EAAc;AACZ,WAAO;AAAK,MAAA,KAAK,EAAC,kCAAX;AAAA;AAAA,MAAP;AACD;;AAED,SAAO,KAAC,aAAD,CAAe,QAAf;AAAwB,IAAA,KAAK,EAAGW,aAAhC;AAAA,cACL;AACE,MAAA,KAAK,EAAGnB,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,CAACU,GAAP,CAAWC,KAAK,IAAI;AAElB,gBAAM;AACJC,YAAAA,SAAS,EAAEC,cAAc,GAAGrB,KADxB;AAEJsB,YAAAA;AAFI,cAGFH,KAHJ;AAKA,iBAAO,KAAC,cAAD;AAEL,YAAA,OAAO,EAAGb,OAFL;AAAA,eAGAa;AAHA,aACCG,EADD,CAAP;AAID,SAXD;AAFJ,QARF;AAAA;AADK,IAAP;AA2BD,C,CAGD;;AAEA,SAAST,mBAAT,CAA6BU,SAA7B,EAAwC;AACtC,SAAO,EACL,GAAGrB,cADE;AAEL,OAAGqB;AAFE,GAAP;AAID","sourcesContent":["import {\n useState,\n useEffect\n} from 'preact/hooks';\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 * } } 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 setLayoutForKey = (key, config) => {\n setLayout({\n ...layout,\n [key]: config\n });\n };\n\n const layoutContext = {\n layout,\n setLayout,\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: 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"}
@@ -2,7 +2,8 @@ import { useEffect, useState } from 'preact/hooks';
2
2
  import classnames from 'classnames';
3
3
  import { query as domQuery } from 'min-dom';
4
4
  import { isFunction } from 'min-dash';
5
- import { GroupArrowIcon } from './icons';
5
+ import { useLayoutState } from '../hooks';
6
+ import { ArrowIcon } from './icons';
6
7
  /**
7
8
  * @param {import('../PropertiesPanel').GroupDefinition} props
8
9
  */
@@ -15,7 +16,7 @@ export default function Group(props) {
15
16
  entries = [],
16
17
  label
17
18
  } = props;
18
- const [open, setOpen] = useState(false);
19
+ const [open, setOpen] = useLayoutState(['groups', id, 'open'], false);
19
20
 
20
21
  const toggleOpen = () => setOpen(!open);
21
22
 
@@ -42,17 +43,18 @@ export default function Group(props) {
42
43
  class: "bio-properties-panel-group",
43
44
  "data-group-id": 'group-' + id,
44
45
  children: [_jsxs("div", {
45
- class: classnames('bio-properties-panel-group-header', edited ? '' : 'empty'),
46
+ class: classnames('bio-properties-panel-group-header', edited ? '' : 'empty', open ? 'open' : ''),
46
47
  onClick: toggleOpen,
47
48
  children: [_jsx("div", {
48
- title: getTitleAttribute(label, edited),
49
+ title: label,
49
50
  class: "bio-properties-panel-group-header-title",
50
51
  children: label
51
52
  }), _jsxs("div", {
52
53
  class: "bio-properties-panel-group-header-buttons",
53
54
  children: [edited && _jsx(DataMarker, {}), _jsx("button", {
54
- class: "bio-properties-panel-group-header-button",
55
- children: _jsx(GroupArrowIcon, {
55
+ title: "Toggle section",
56
+ class: "bio-properties-panel-group-header-button bio-properties-panel-arrow",
57
+ children: _jsx(ArrowIcon, {
56
58
  class: open ? 'bio-properties-panel-arrow-down' : 'bio-properties-panel-arrow-right'
57
59
  })
58
60
  })]
@@ -66,24 +68,8 @@ export default function Group(props) {
66
68
 
67
69
  function DataMarker() {
68
70
  return _jsx("div", {
69
- class: "bio-properties-panel-dot",
70
- children: _jsx("svg", {
71
- "aria-label": "edited",
72
- role: "img",
73
- xmlns: "http://www.w3.org/2000/svg",
74
- viewBox: "0 0 100 100",
75
- children: _jsx("circle", {
76
- fill: "currentColor",
77
- cx: "50",
78
- cy: "50",
79
- r: "50"
80
- })
81
- })
71
+ title: "Section contains data",
72
+ class: "bio-properties-panel-dot"
82
73
  });
83
- } // helper //////////////
84
-
85
-
86
- function getTitleAttribute(label, edited) {
87
- return label + (edited ? ' (edited)' : '');
88
74
  }
89
75
  //# sourceMappingURL=Group.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/Group.js"],"names":["useEffect","useState","classnames","query","domQuery","isFunction","GroupArrowIcon","Group","props","id","entries","label","open","setOpen","toggleOpen","edited","setEdited","hasOneEditedEntry","find","entry","isEdited","entryNode","inputNode","getTitleAttribute","map","e","component","DataMarker"],"mappings":"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","sourcesContent":["import {\n useEffect,\n useState\n} from 'preact/hooks';\n\nimport classnames from 'classnames';\n\nimport {\n query as domQuery\n} from 'min-dom';\n\nimport {\n isFunction\n} from 'min-dash';\n\nimport { GroupArrowIcon } from './icons';\n\n/**\n * @param {import('../PropertiesPanel').GroupDefinition} props\n */\nexport default function Group(props) {\n const {\n id,\n entries = [],\n label\n } = props;\n\n const [ open, setOpen ] = useState(false);\n\n const toggleOpen = () => setOpen(!open);\n\n const [ edited, setEdited ] = useState(false);\n\n // set edited state depending on all entries\n useEffect(() => {\n const hasOneEditedEntry = entries.find(entry => {\n const {\n id,\n isEdited\n } = entry;\n\n const entryNode = domQuery(`[data-entry-id=\"${id}\"]`);\n\n if (!isFunction(isEdited) || !entryNode) {\n return false;\n }\n\n const inputNode = domQuery('.bio-properties-panel-input', entryNode);\n\n return isEdited(inputNode);\n });\n\n setEdited(hasOneEditedEntry);\n }, [ entries ]);\n\n return <div class=\"bio-properties-panel-group\" data-group-id={ 'group-' + id }>\n <div class={ classnames(\n 'bio-properties-panel-group-header',\n edited ? '' : 'empty'\n ) } onClick={ toggleOpen }>\n <div title={ getTitleAttribute(label, edited) } class=\"bio-properties-panel-group-header-title\">\n { label }\n </div>\n <div class=\"bio-properties-panel-group-header-buttons\">\n {\n edited && <DataMarker />\n }\n <button class=\"bio-properties-panel-group-header-button\">\n <GroupArrowIcon class={ open ? 'bio-properties-panel-arrow-down' : 'bio-properties-panel-arrow-right' } />\n </button>\n </div>\n </div>\n <div class={ classnames(\n 'bio-properties-panel-group-entries',\n open ? 'open' : ''\n ) }>\n {\n entries.map(e => e.component)\n }\n </div>\n </div>;\n}\n\nfunction DataMarker() {\n return (\n <div class=\"bio-properties-panel-dot\">\n <svg\n aria-label=\"edited\" role=\"img\" xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 100 100\"\n >\n <circle fill=\"currentColor\" cx=\"50\" cy=\"50\" r=\"50\" />\n </svg>\n </div>\n );\n}\n\n\n// helper //////////////\n\nfunction getTitleAttribute(label, edited) {\n return label + (edited ? ' (edited)' : '');\n}"],"file":"Group.js"}
1
+ {"version":3,"sources":["../../src/components/Group.js"],"names":["useEffect","useState","classnames","query","domQuery","isFunction","useLayoutState","ArrowIcon","Group","props","id","entries","label","open","setOpen","toggleOpen","edited","setEdited","hasOneEditedEntry","find","entry","isEdited","entryNode","inputNode","map","e","component","DataMarker"],"mappings":"AAAA,SACEA,SADF,EAEEC,QAFF,QAGO,cAHP;AAKA,OAAOC,UAAP,MAAuB,YAAvB;AAEA,SACEC,KAAK,IAAIC,QADX,QAEO,SAFP;AAIA,SACEC,UADF,QAEO,UAFP;AAIA,SACEC,cADF,QAEO,UAFP;AAIA,SAASC,SAAT,QAA0B,SAA1B;AAEA;AACA;AACA;;;;AACA,eAAe,SAASC,KAAT,CAAeC,KAAf,EAAsB;AACnC,QAAM;AACJC,IAAAA,EADI;AAEJC,IAAAA,OAAO,GAAG,EAFN;AAGJC,IAAAA;AAHI,MAIFH,KAJJ;AAMA,QAAM,CAAEI,IAAF,EAAQC,OAAR,IAAoBR,cAAc,CACtC,CAAE,QAAF,EAAYI,EAAZ,EAAgB,MAAhB,CADsC,EAEtC,KAFsC,CAAxC;;AAIA,QAAMK,UAAU,GAAG,MAAMD,OAAO,CAAC,CAACD,IAAF,CAAhC;;AAEA,QAAM,CAAEG,MAAF,EAAUC,SAAV,IAAwBhB,QAAQ,CAAC,KAAD,CAAtC,CAbmC,CAenC;;AACAD,EAAAA,SAAS,CAAC,MAAM;AACd,UAAMkB,iBAAiB,GAAGP,OAAO,CAACQ,IAAR,CAAaC,KAAK,IAAI;AAC9C,YAAM;AACJV,QAAAA,EADI;AAEJW,QAAAA;AAFI,UAGFD,KAHJ;AAKA,YAAME,SAAS,GAAGlB,QAAQ,CAAE,mBAAkBM,EAAG,IAAvB,CAA1B;;AAEA,UAAI,CAACL,UAAU,CAACgB,QAAD,CAAX,IAAyB,CAACC,SAA9B,EAAyC;AACvC,eAAO,KAAP;AACD;;AAED,YAAMC,SAAS,GAAGnB,QAAQ,CAAC,6BAAD,EAAgCkB,SAAhC,CAA1B;AAEA,aAAOD,QAAQ,CAACE,SAAD,CAAf;AACD,KAfyB,CAA1B;AAiBAN,IAAAA,SAAS,CAACC,iBAAD,CAAT;AACD,GAnBQ,EAmBN,CAAEP,OAAF,CAnBM,CAAT;AAqBA,SAAO;AAAK,IAAA,KAAK,EAAC,4BAAX;AAAwC,qBAAgB,WAAWD,EAAnE;AAAA,eACL;AAAK,MAAA,KAAK,EAAGR,UAAU,CACrB,mCADqB,EAErBc,MAAM,GAAG,EAAH,GAAQ,OAFO,EAGrBH,IAAI,GAAE,MAAF,GAAW,EAHM,CAAvB;AAII,MAAA,OAAO,EAAGE,UAJd;AAAA,iBAKE;AAAK,QAAA,KAAK,EAAGH,KAAb;AAAqB,QAAA,KAAK,EAAC,yCAA3B;AAAA,kBACIA;AADJ,QALF,EAQE;AAAK,QAAA,KAAK,EAAC,2CAAX;AAAA,mBAEII,MAAM,IAAI,KAAC,UAAD,KAFd,EAIE;AACE,UAAA,KAAK,EAAC,gBADR;AAEE,UAAA,KAAK,EAAC,qEAFR;AAAA,oBAIE,KAAC,SAAD;AAAW,YAAA,KAAK,EAAGH,IAAI,GAAG,iCAAH,GAAuC;AAA9D;AAJF,UAJF;AAAA,QARF;AAAA,MADK,EAqBL;AAAK,MAAA,KAAK,EAAGX,UAAU,CACrB,oCADqB,EAErBW,IAAI,GAAG,MAAH,GAAY,EAFK,CAAvB;AAAA,gBAKIF,OAAO,CAACa,GAAR,CAAYC,CAAC,IAAIA,CAAC,CAACC,SAAnB;AALJ,MArBK;AAAA,IAAP;AA8BD;;AAED,SAASC,UAAT,GAAsB;AACpB,SACE;AAAK,IAAA,KAAK,EAAC,uBAAX;AAAmC,IAAA,KAAK,EAAC;AAAzC,IADF;AAGD","sourcesContent":["import {\n useEffect,\n useState\n} from 'preact/hooks';\n\nimport classnames from 'classnames';\n\nimport {\n query as domQuery\n} from 'min-dom';\n\nimport {\n isFunction\n} from 'min-dash';\n\nimport {\n useLayoutState\n} from '../hooks';\n\nimport { ArrowIcon } from './icons';\n\n/**\n * @param {import('../PropertiesPanel').GroupDefinition} props\n */\nexport default function Group(props) {\n const {\n id,\n entries = [],\n label\n } = props;\n\n const [ open, setOpen ] = useLayoutState(\n [ 'groups', id, 'open' ],\n false\n );\n const toggleOpen = () => setOpen(!open);\n\n const [ edited, setEdited ] = useState(false);\n\n // set edited state depending on all entries\n useEffect(() => {\n const hasOneEditedEntry = entries.find(entry => {\n const {\n id,\n isEdited\n } = entry;\n\n const entryNode = domQuery(`[data-entry-id=\"${id}\"]`);\n\n if (!isFunction(isEdited) || !entryNode) {\n return false;\n }\n\n const inputNode = domQuery('.bio-properties-panel-input', entryNode);\n\n return isEdited(inputNode);\n });\n\n setEdited(hasOneEditedEntry);\n }, [ entries ]);\n\n return <div class=\"bio-properties-panel-group\" data-group-id={ 'group-' + id }>\n <div class={ classnames(\n 'bio-properties-panel-group-header',\n edited ? '' : 'empty',\n open? 'open' : ''\n ) } onClick={ toggleOpen }>\n <div title={ label } class=\"bio-properties-panel-group-header-title\">\n { label }\n </div>\n <div class=\"bio-properties-panel-group-header-buttons\">\n {\n edited && <DataMarker />\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 </div>\n </div>\n <div class={ classnames(\n 'bio-properties-panel-group-entries',\n open ? 'open' : ''\n ) }>\n {\n entries.map(e => e.component)\n }\n </div>\n </div>;\n}\n\nfunction DataMarker() {\n return (\n <div title=\"Section contains data\" class=\"bio-properties-panel-dot\"></div>\n );\n}"],"file":"Group.js"}
@@ -34,15 +34,15 @@ export default function Header(props) {
34
34
  })
35
35
  }), _jsxs("div", {
36
36
  class: "bio-properties-panel-header-labels",
37
- children: [getElementLabel(element) ? _jsx("div", {
38
- title: label,
39
- class: "bio-properties-panel-header-label",
40
- children: label
41
- }) : null, _jsx("div", {
37
+ children: [_jsx("div", {
42
38
  title: type,
43
39
  class: "bio-properties-panel-header-type",
44
40
  children: type
45
- })]
41
+ }), getElementLabel(element) ? _jsx("div", {
42
+ title: label,
43
+ class: "bio-properties-panel-header-label",
44
+ children: label
45
+ }) : null]
46
46
  })]
47
47
  });
48
48
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/Header.js"],"names":["Header","props","element","headerProvider","getElementLabel","getTypeLabel","getElementIcon","label","type","ElementIcon"],"mappings":";;;AAAA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,SAASA,MAAT,CAAgBC,KAAhB,EAAuB;AAEpC,QAAM;AACJC,IAAAA,OADI;AAEJC,IAAAA;AAFI,MAGFF,KAHJ;AAKA,QAAM;AACJG,IAAAA,eADI;AAEJC,IAAAA,YAFI;AAGJC,IAAAA;AAHI,MAIFH,cAJJ;AAMA,QAAMI,KAAK,GAAGH,eAAe,CAACF,OAAD,CAA7B;AACA,QAAMM,IAAI,GAAGH,YAAY,CAACH,OAAD,CAAzB;AACA,QAAMO,WAAW,GAAGH,cAAc,CAACJ,OAAD,CAAlC;AAEA,SAAQ;AAAK,IAAA,KAAK,EAAC,6BAAX;AAAA,eACN;AAAK,MAAA,KAAK,EAAC,kCAAX;AAAA,gBACIO,WAAW,IAAI,KAAC,WAAD;AAAa,QAAA,KAAK,EAAC,IAAnB;AAAwB,QAAA,MAAM,EAAC,IAA/B;AAAoC,QAAA,OAAO,EAAC;AAA5C;AADnB,MADM,EAIN;AAAK,MAAA,KAAK,EAAC,oCAAX;AAAA,iBACIL,eAAe,CAACF,OAAD,CAAf,GACA;AAAK,QAAA,KAAK,EAAGK,KAAb;AAAqB,QAAA,KAAK,EAAC,mCAA3B;AAAA,kBAAiEA;AAAjE,QADA,GAEA,IAHJ,EAKE;AAAK,QAAA,KAAK,EAAGC,IAAb;AAAoB,QAAA,KAAK,EAAC,kCAA1B;AAAA,kBAA+DA;AAA/D,QALF;AAAA,MAJM;AAAA,IAAR;AAYD","sourcesContent":["/**\n * @typedef { { getElementLabel: Function, getTypeLabel: Function, getElementIcon: Function } } HeaderProvider\n */\n\n/**\n * @param {Object} props\n * @param {Object} props.element,\n * @param {HeaderProvider} props.headerProvider\n */\nexport default function Header(props) {\n\n const {\n element,\n headerProvider\n } = props;\n\n const {\n getElementLabel,\n getTypeLabel,\n getElementIcon\n } = headerProvider;\n\n const label = getElementLabel(element);\n const type = getTypeLabel(element);\n const ElementIcon = getElementIcon(element);\n\n return (<div class=\"bio-properties-panel-header\">\n <div class=\"bio-properties-panel-header-icon\">\n { ElementIcon && <ElementIcon width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" /> }\n </div>\n <div class=\"bio-properties-panel-header-labels\">\n { getElementLabel(element) ?\n <div title={ label } class=\"bio-properties-panel-header-label\">{ label }</div> :\n null\n }\n <div title={ type } class=\"bio-properties-panel-header-type\">{ type }</div>\n </div>\n </div>);\n}"],"file":"Header.js"}
1
+ {"version":3,"sources":["../../src/components/Header.js"],"names":["Header","props","element","headerProvider","getElementLabel","getTypeLabel","getElementIcon","label","type","ElementIcon"],"mappings":";;;AAAA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,eAAe,SAASA,MAAT,CAAgBC,KAAhB,EAAuB;AAEpC,QAAM;AACJC,IAAAA,OADI;AAEJC,IAAAA;AAFI,MAGFF,KAHJ;AAKA,QAAM;AACJG,IAAAA,eADI;AAEJC,IAAAA,YAFI;AAGJC,IAAAA;AAHI,MAIFH,cAJJ;AAMA,QAAMI,KAAK,GAAGH,eAAe,CAACF,OAAD,CAA7B;AACA,QAAMM,IAAI,GAAGH,YAAY,CAACH,OAAD,CAAzB;AACA,QAAMO,WAAW,GAAGH,cAAc,CAACJ,OAAD,CAAlC;AAEA,SAAQ;AAAK,IAAA,KAAK,EAAC,6BAAX;AAAA,eACN;AAAK,MAAA,KAAK,EAAC,kCAAX;AAAA,gBACIO,WAAW,IAAI,KAAC,WAAD;AAAa,QAAA,KAAK,EAAC,IAAnB;AAAwB,QAAA,MAAM,EAAC,IAA/B;AAAoC,QAAA,OAAO,EAAC;AAA5C;AADnB,MADM,EAIN;AAAK,MAAA,KAAK,EAAC,oCAAX;AAAA,iBACE;AAAK,QAAA,KAAK,EAAGD,IAAb;AAAoB,QAAA,KAAK,EAAC,kCAA1B;AAAA,kBAA+DA;AAA/D,QADF,EAEIJ,eAAe,CAACF,OAAD,CAAf,GACA;AAAK,QAAA,KAAK,EAAGK,KAAb;AAAqB,QAAA,KAAK,EAAC,mCAA3B;AAAA,kBAAiEA;AAAjE,QADA,GAEA,IAJJ;AAAA,MAJM;AAAA,IAAR;AAYD","sourcesContent":["/**\n * @typedef { { getElementLabel: Function, getTypeLabel: Function, getElementIcon: Function } } HeaderProvider\n */\n\n/**\n * @param {Object} props\n * @param {Object} props.element,\n * @param {HeaderProvider} props.headerProvider\n */\nexport default function Header(props) {\n\n const {\n element,\n headerProvider\n } = props;\n\n const {\n getElementLabel,\n getTypeLabel,\n getElementIcon\n } = headerProvider;\n\n const label = getElementLabel(element);\n const type = getTypeLabel(element);\n const ElementIcon = getElementIcon(element);\n\n return (<div class=\"bio-properties-panel-header\">\n <div class=\"bio-properties-panel-header-icon\">\n { ElementIcon && <ElementIcon width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" /> }\n </div>\n <div class=\"bio-properties-panel-header-labels\">\n <div title={ type } class=\"bio-properties-panel-header-type\">{ type }</div>\n { getElementLabel(element) ?\n <div title={ label } class=\"bio-properties-panel-header-label\">{ label }</div> :\n null\n }\n </div>\n </div>);\n}"],"file":"Header.js"}
@@ -1,9 +1,9 @@
1
- import { useState, useEffect } from 'preact/hooks';
1
+ import { useEffect, useState } from 'preact/hooks';
2
2
  import classnames from 'classnames';
3
3
  import { find, sortBy } from 'min-dash';
4
- import { usePrevious } from '../hooks';
4
+ import { useLayoutState, usePrevious } from '../hooks';
5
5
  import ListItem from './ListItem';
6
- import { CreateIcon, GroupArrowIcon } from './icons';
6
+ import { ArrowIcon, CreateIcon } from './icons';
7
7
  import { jsx as _jsx } from "preact/jsx-runtime";
8
8
  import { jsxs as _jsxs } from "preact/jsx-runtime";
9
9
 
@@ -20,15 +20,16 @@ export default function ListGroup(props) {
20
20
  items,
21
21
  label,
22
22
  add: AddContainer,
23
- shouldSort = true
23
+ shouldSort = true,
24
+ shouldOpen = true
24
25
  } = props;
25
- const [open, setOpen] = useState(false);
26
+ const [open, setOpen] = useLayoutState(['groups', id, 'open'], false);
26
27
  const [ordering, setOrdering] = useState([]);
27
28
  const [newItemAdded, setNewItemAdded] = useState(false);
28
29
  const prevItems = usePrevious(items);
29
30
  const prevElement = usePrevious(element);
30
31
  const elementChanged = element !== prevElement;
31
- const shouldHandleEffects = !elementChanged && shouldSort; // reset initial ordering when element changes (before first render)
32
+ const shouldHandleEffects = !elementChanged && (shouldSort || shouldOpen); // reset initial ordering when element changes (before first render)
32
33
 
33
34
  if (elementChanged) {
34
35
  setOrdering(createOrdering(shouldSort ? sortItems(items) : items));
@@ -50,28 +51,37 @@ export default function ListGroup(props) {
50
51
  add.push(item.id);
51
52
  }
52
53
  });
53
- let newOrdering = ordering; // sort + open if closed
54
+ let newOrdering = ordering; // open if not open and configured
54
55
 
55
- if (!open) {
56
- newOrdering = createOrdering(sortItems(items));
57
- setOpen(true);
58
- } // add new items on top
56
+ if (!open && shouldOpen) {
57
+ toggleOpen(); // if I opened and I should sort, then sort items
59
58
 
59
+ if (shouldSort) {
60
+ newOrdering = createOrdering(sortItems(items));
61
+ }
62
+ } // add new items on top or bottom depending on sorting behavior
63
+
64
+
65
+ newOrdering = newOrdering.filter(item => !add.includes(item));
66
+
67
+ if (shouldSort) {
68
+ newOrdering.unshift(...add);
69
+ } else {
70
+ newOrdering.push(...add);
71
+ }
60
72
 
61
- newOrdering = removeDuplicates([...add, ...newOrdering]);
62
73
  setOrdering(newOrdering);
63
74
  setNewItemAdded(true);
64
75
  } else {
65
76
  setNewItemAdded(false);
66
77
  }
67
- }, [items, open, shouldHandleEffects]); // (2) sort items on open
78
+ }, [items, open, shouldHandleEffects]); // (2) sort items on open if shouldSort is set
68
79
 
69
80
  useEffect(() => {
70
- // we already sorted as items were added
71
- if (shouldHandleEffects && open && !newItemAdded) {
81
+ if (shouldSort && open && !newItemAdded) {
72
82
  setOrdering(createOrdering(sortItems(items)));
73
83
  }
74
- }, [open, shouldHandleEffects]); // (3) items were deleted
84
+ }, [open, shouldSort]); // (3) items were deleted
75
85
 
76
86
  useEffect(() => {
77
87
  if (shouldHandleEffects && prevItems && items.length < prevItems.length) {
@@ -92,25 +102,31 @@ export default function ListGroup(props) {
92
102
  class: "bio-properties-panel-group",
93
103
  "data-group-id": 'group-' + id,
94
104
  children: [_jsxs("div", {
95
- class: classnames('bio-properties-panel-group-header', hasItems ? '' : 'empty'),
105
+ class: classnames('bio-properties-panel-group-header', hasItems ? '' : 'empty', hasItems && open ? 'open' : ''),
96
106
  onClick: hasItems ? toggleOpen : noop,
97
107
  children: [_jsx("div", {
98
- title: getTitleAttribute(label, items),
108
+ title: label,
99
109
  class: "bio-properties-panel-group-header-title",
100
110
  children: label
101
111
  }), _jsxs("div", {
102
112
  class: "bio-properties-panel-group-header-buttons",
103
113
  children: [AddContainer ? _jsx(AddContainer, {
104
- children: _jsx("button", {
114
+ children: _jsxs("button", {
115
+ title: "Create new list item",
105
116
  class: "bio-properties-panel-group-header-button bio-properties-panel-add-entry",
106
- children: _jsx(CreateIcon, {})
117
+ children: [_jsx(CreateIcon, {}), !hasItems ? _jsx("div", {
118
+ class: "bio-properties-panel-add-entry-label",
119
+ children: "Create"
120
+ }) : null]
107
121
  })
108
122
  }) : null, hasItems ? _jsx("div", {
123
+ title: `List contains ${items.length} item${items.length != 1 ? 's' : ''}`,
109
124
  class: "bio-properties-panel-list-badge",
110
125
  children: items.length
111
126
  }) : null, hasItems ? _jsx("button", {
112
- class: "bio-properties-panel-group-header-button",
113
- children: _jsx(GroupArrowIcon, {
127
+ title: "Toggle section",
128
+ class: "bio-properties-panel-group-header-button bio-properties-panel-arrow",
129
+ children: _jsx(ArrowIcon, {
114
130
  class: open ? 'bio-properties-panel-arrow-down' : 'bio-properties-panel-arrow-right'
115
131
  })
116
132
  }) : null]
@@ -125,8 +141,8 @@ export default function ListGroup(props) {
125
141
  }
126
142
 
127
143
  return _jsx(ListItem, {
128
- autoOpen: index === 0 && newItemAdded // open first item when recently added
129
- ,
144
+ // if item was added, open first or last item based on ordering
145
+ autoOpen: newItemAdded && (shouldSort ? index === 0 : index === ordering.length - 1),
130
146
  ...item
131
147
  }, item.id);
132
148
  })
@@ -149,13 +165,4 @@ function getItem(items, id) {
149
165
  function createOrdering(items) {
150
166
  return items.map(i => i.id);
151
167
  }
152
-
153
- function removeDuplicates(items) {
154
- return items.filter((i, index) => items.indexOf(i) === index);
155
- }
156
-
157
- function getTitleAttribute(label, items) {
158
- const count = items.length;
159
- return label + (count ? ` (${count} item${count != 1 ? 's' : ''})` : '');
160
- }
161
168
  //# sourceMappingURL=ListGroup.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/ListGroup.js"],"names":["useState","useEffect","classnames","find","sortBy","usePrevious","ListItem","CreateIcon","GroupArrowIcon","noop","ListGroup","props","element","id","items","label","add","AddContainer","shouldSort","open","setOpen","ordering","setOrdering","newItemAdded","setNewItemAdded","prevItems","prevElement","elementChanged","shouldHandleEffects","createOrdering","sortItems","length","forEach","item","includes","push","newOrdering","removeDuplicates","keep","o","getItem","toggleOpen","hasItems","getTitleAttribute","map","index","i","toLowerCase","filter","indexOf","count"],"mappings":"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","sourcesContent":["import {\n useState,\n useEffect\n} from 'preact/hooks';\n\nimport classnames from 'classnames';\n\nimport {\n find,\n sortBy\n} from 'min-dash';\n\nimport {\n usePrevious\n} from '../hooks';\n\nimport ListItem from './ListItem';\n\nimport {\n CreateIcon,\n GroupArrowIcon\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 } = props;\n\n const [ open, setOpen ] = useState(false);\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;\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 // sort + open if closed\n if (!open) {\n newOrdering = createOrdering(sortItems(items));\n setOpen(true);\n }\n\n // add new items on top\n newOrdering = removeDuplicates([\n ...add,\n ...newOrdering\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\n useEffect(() => {\n\n // we already sorted as items were added\n if (shouldHandleEffects && open && !newItemAdded) {\n setOrdering(createOrdering(sortItems(items)));\n }\n }, [ open, shouldHandleEffects ]);\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 ) }\n onClick={ hasItems ? toggleOpen : noop }>\n <div title={ getTitleAttribute(label, items) } class=\"bio-properties-panel-group-header-title\">\n { label }\n </div>\n <div class=\"bio-properties-panel-group-header-buttons\">\n {\n AddContainer\n ? (\n <AddContainer>\n <button class=\"bio-properties-panel-group-header-button bio-properties-panel-add-entry\">\n <CreateIcon />\n </button>\n </AddContainer>\n )\n : null\n }\n {\n hasItems\n ? (\n <div class=\"bio-properties-panel-list-badge\">\n { items.length }\n </div>\n )\n : null\n }\n {\n hasItems\n ? (\n <button class=\"bio-properties-panel-group-header-button\">\n <GroupArrowIcon 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 autoOpen={ index === 0 && newItemAdded } // open first item when recently added\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\nfunction removeDuplicates(items) {\n return items.filter((i, index) => items.indexOf(i) === index);\n}\n\nfunction getTitleAttribute(label, items) {\n const count = items.length;\n\n return label + (count ? ` (${count} item${count != 1 ? 's' : ''})` : '');\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","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,5 +1,6 @@
1
1
  import { useEffect } from 'preact/hooks';
2
2
  import { query as domQuery } from 'min-dom';
3
+ import { isFunction } from 'min-dash';
3
4
  import CollapsibleEntry from './entries/Collapsible';
4
5
  /**
5
6
  * @param {import('../PropertiesPanel').ListItemDefinition} props
@@ -18,7 +19,11 @@ export default function ListItem(props) {
18
19
  const focusableInput = domQuery('.bio-properties-panel-input', entry);
19
20
 
20
21
  if (focusableInput) {
21
- focusableInput.select();
22
+ if (isFunction(focusableInput.select)) {
23
+ focusableInput.select();
24
+ } else if (isFunction(focusableInput.focus)) {
25
+ focusableInput.focus();
26
+ }
22
27
  }
23
28
  }
24
29
  }, [autoOpen, autoFocusEntry]);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/ListItem.js"],"names":["useEffect","query","domQuery","CollapsibleEntry","ListItem","props","autoOpen","autoFocusEntry","entry","focusableInput","select"],"mappings":"AAAA,SACEA,SADF,QAEO,cAFP;AAIA,SACEC,KAAK,IAAIC,QADX,QAEO,SAFP;AAIA,OAAOC,gBAAP,MAA6B,uBAA7B;AAEA;AACA;AACA;;;AACA,eAAe,SAASC,QAAT,CAAkBC,KAAlB,EAAyB;AACtC,QAAM;AACJC,IAAAA,QADI;AAEJC,IAAAA;AAFI,MAGFF,KAHJ,CADsC,CAMtC;;AACAL,EAAAA,SAAS,CAAC,MAAM;AACd,QAAIM,QAAQ,IAAIC,cAAhB,EAAgC;AAC9B,YAAMC,KAAK,GAAGN,QAAQ,CAAE,mBAAkBK,cAAe,IAAnC,CAAtB;AAEA,YAAME,cAAc,GAAGP,QAAQ,CAAC,6BAAD,EAAgCM,KAAhC,CAA/B;;AAEA,UAAIC,cAAJ,EAAoB;AAClBA,QAAAA,cAAc,CAACC,MAAf;AACD;AACF;AACF,GAVQ,EAUN,CAAEJ,QAAF,EAAYC,cAAZ,CAVM,CAAT;AAaA,SACE;AAAK,IAAA,KAAK,EAAC,gCAAX;AAAA,cACE,KAAC,gBAAD,OAAuBF,KAAvB;AAA+B,MAAA,IAAI,EAAGC;AAAtC;AADF,IADF;AAMD","sourcesContent":["import {\n useEffect\n} from 'preact/hooks';\n\nimport {\n query as domQuery\n} from 'min-dom';\n\nimport CollapsibleEntry from './entries/Collapsible';\n\n/**\n * @param {import('../PropertiesPanel').ListItemDefinition} props\n */\nexport default function ListItem(props) {\n const {\n autoOpen,\n autoFocusEntry\n } = props;\n\n // focus specified entry on auto open\n useEffect(() => {\n if (autoOpen && autoFocusEntry) {\n const entry = domQuery(`[data-entry-id=\"${autoFocusEntry}\"]`);\n\n const focusableInput = domQuery('.bio-properties-panel-input', entry);\n\n if (focusableInput) {\n focusableInput.select();\n }\n }\n }, [ autoOpen, autoFocusEntry ]);\n\n\n return (\n <div class=\"bio-properties-panel-list-item\">\n <CollapsibleEntry { ...props } open={ autoOpen } />\n </div>\n );\n\n}"],"file":"ListItem.js"}
1
+ {"version":3,"sources":["../../src/components/ListItem.js"],"names":["useEffect","query","domQuery","isFunction","CollapsibleEntry","ListItem","props","autoOpen","autoFocusEntry","entry","focusableInput","select","focus"],"mappings":"AAAA,SACEA,SADF,QAEO,cAFP;AAIA,SACEC,KAAK,IAAIC,QADX,QAEO,SAFP;AAIA,SAASC,UAAT,QAA2B,UAA3B;AAEA,OAAOC,gBAAP,MAA6B,uBAA7B;AAEA;AACA;AACA;;;AACA,eAAe,SAASC,QAAT,CAAkBC,KAAlB,EAAyB;AACtC,QAAM;AACJC,IAAAA,QADI;AAEJC,IAAAA;AAFI,MAGFF,KAHJ,CADsC,CAMtC;;AACAN,EAAAA,SAAS,CAAC,MAAM;AACd,QAAIO,QAAQ,IAAIC,cAAhB,EAAgC;AAC9B,YAAMC,KAAK,GAAGP,QAAQ,CAAE,mBAAkBM,cAAe,IAAnC,CAAtB;AAEA,YAAME,cAAc,GAAGR,QAAQ,CAAC,6BAAD,EAAgCO,KAAhC,CAA/B;;AAEA,UAAIC,cAAJ,EAAoB;AAElB,YAAIP,UAAU,CAACO,cAAc,CAACC,MAAhB,CAAd,EAAuC;AACrCD,UAAAA,cAAc,CAACC,MAAf;AACD,SAFD,MAEO,IAAIR,UAAU,CAACO,cAAc,CAACE,KAAhB,CAAd,EAAsC;AAC3CF,UAAAA,cAAc,CAACE,KAAf;AACD;AAEF;AACF;AACF,GAhBQ,EAgBN,CAAEL,QAAF,EAAYC,cAAZ,CAhBM,CAAT;AAmBA,SACE;AAAK,IAAA,KAAK,EAAC,gCAAX;AAAA,cACE,KAAC,gBAAD,OAAuBF,KAAvB;AAA+B,MAAA,IAAI,EAAGC;AAAtC;AADF,IADF;AAMD","sourcesContent":["import {\n useEffect\n} from 'preact/hooks';\n\nimport {\n query as domQuery\n} from 'min-dom';\n\nimport { isFunction } from 'min-dash';\n\nimport CollapsibleEntry from './entries/Collapsible';\n\n/**\n * @param {import('../PropertiesPanel').ListItemDefinition} props\n */\nexport default function ListItem(props) {\n const {\n autoOpen,\n autoFocusEntry\n } = props;\n\n // focus specified entry on auto open\n useEffect(() => {\n if (autoOpen && autoFocusEntry) {\n const entry = domQuery(`[data-entry-id=\"${autoFocusEntry}\"]`);\n\n const focusableInput = domQuery('.bio-properties-panel-input', entry);\n\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 }, [ autoOpen, autoFocusEntry ]);\n\n\n return (\n <div class=\"bio-properties-panel-list-item\">\n <CollapsibleEntry { ...props } open={ autoOpen } />\n </div>\n );\n\n}\n"],"file":"ListItem.js"}
@@ -35,6 +35,7 @@ function Checkbox(props) {
35
35
  * @param {Object} props
36
36
  * @param {Object} props.element
37
37
  * @param {String} props.id
38
+ * @param {String} props.description
38
39
  * @param {String} props.label
39
40
  * @param {Function} props.getValue
40
41
  * @param {Function} props.setValue
@@ -45,20 +46,24 @@ export default function CheckboxEntry(props) {
45
46
  const {
46
47
  element,
47
48
  id,
49
+ description,
48
50
  label,
49
51
  getValue,
50
52
  setValue
51
53
  } = props;
52
54
  const value = getValue(element);
53
- return _jsx("div", {
54
- class: "bio-properties-panel-entry",
55
+ return _jsxs("div", {
56
+ class: "bio-properties-panel-entry bio-properties-panel-checkbox-entry",
55
57
  "data-entry-id": id,
56
- children: _jsx(Checkbox, {
58
+ children: [_jsx(Checkbox, {
57
59
  id: id,
58
60
  label: label,
59
61
  onChange: setValue,
60
62
  value: value
61
- })
63
+ }), description && _jsx("div", {
64
+ class: "bio-properties-panel-description",
65
+ children: description
66
+ })]
62
67
  });
63
68
  }
64
69
  export function isEdited(node) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/entries/Checkbox.js"],"names":["Checkbox","props","id","label","onChange","value","handleChange","target","checked","prefixId","CheckboxEntry","element","getValue","setValue","isEdited","node"],"mappings":";;;AAAA,SAASA,QAAT,CAAkBC,KAAlB,EAAyB;AACvB,QAAM;AACJC,IAAAA,EADI;AAEJC,IAAAA,KAFI;AAGJC,IAAAA,QAHI;AAIJC,IAAAA,KAAK,GAAG;AAJJ,MAKFJ,KALJ;;AAOA,QAAMK,YAAY,GAAG,CAAC;AAAEC,IAAAA;AAAF,GAAD,KAAgB;AACnCH,IAAAA,QAAQ,CAACG,MAAM,CAACC,OAAR,CAAR;AACD,GAFD;;AAIA,SACE;AAAK,IAAA,KAAK,EAAC,+BAAX;AAAA,eACE;AACE,MAAA,EAAE,EAAGC,QAAQ,CAACP,EAAD,CADf;AAEE,MAAA,IAAI,EAAGA,EAFT;AAGE,MAAA,IAAI,EAAC,UAHP;AAIE,MAAA,KAAK,EAAC,4BAJR;AAKE,MAAA,QAAQ,EAAGI,YALb;AAME,MAAA,OAAO,EAAGD;AANZ,MADF,EAQE;AAAO,MAAA,GAAG,EAAGI,QAAQ,CAACP,EAAD,CAArB;AAA4B,MAAA,KAAK,EAAC,4BAAlC;AAAA,gBAAiEC;AAAjE,MARF;AAAA,IADF;AAYD;AAGD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA,eAAe,SAASO,aAAT,CAAuBT,KAAvB,EAA8B;AAC3C,QAAM;AACJU,IAAAA,OADI;AAEJT,IAAAA,EAFI;AAGJC,IAAAA,KAHI;AAIJS,IAAAA,QAJI;AAKJC,IAAAA;AALI,MAMFZ,KANJ;AAQA,QAAMI,KAAK,GAAGO,QAAQ,CAACD,OAAD,CAAtB;AAEA,SACE;AAAK,IAAA,KAAK,EAAC,4BAAX;AAAwC,qBAAgBT,EAAxD;AAAA,cACE,KAAC,QAAD;AAAU,MAAA,EAAE,EAAGA,EAAf;AAAoB,MAAA,KAAK,EAAGC,KAA5B;AAAoC,MAAA,QAAQ,EAAGU,QAA/C;AAA0D,MAAA,KAAK,EAAGR;AAAlE;AADF,IADF;AAKD;AAED,OAAO,SAASS,QAAT,CAAkBC,IAAlB,EAAwB;AAC7B,SAAOA,IAAI,IAAI,CAAC,CAACA,IAAI,CAACP,OAAtB;AACD,C,CAGD;;AAEA,SAASC,QAAT,CAAkBP,EAAlB,EAAsB;AACpB,SAAQ,wBAAwBA,EAAI,EAApC;AACD","sourcesContent":["function Checkbox(props) {\n const {\n id,\n label,\n onChange,\n value = false\n } = props;\n\n const handleChange = ({ target }) => {\n onChange(target.checked);\n };\n\n return (\n <div class=\"bio-properties-panel-checkbox\">\n <input\n id={ prefixId(id) }\n name={ id }\n type=\"checkbox\"\n class=\"bio-properties-panel-input\"\n onChange={ handleChange }\n checked={ value } />\n <label for={ prefixId(id) } class=\"bio-properties-panel-label\">{ label }</label>\n </div>\n );\n}\n\n\n/**\n * @param {Object} props\n * @param {Object} props.element\n * @param {String} props.id\n * @param {String} props.label\n * @param {Function} props.getValue\n * @param {Function} props.setValue\n */\nexport default function CheckboxEntry(props) {\n const {\n element,\n id,\n label,\n getValue,\n setValue\n } = props;\n\n const value = getValue(element);\n\n return (\n <div class=\"bio-properties-panel-entry\" data-entry-id={ id }>\n <Checkbox id={ id } label={ label } onChange={ setValue } value={ value } />\n </div>\n );\n}\n\nexport function isEdited(node) {\n return node && !!node.checked;\n}\n\n\n// helpers /////////////////\n\nfunction prefixId(id) {\n return `bio-properties-panel-${ id }`;\n}\n"],"file":"Checkbox.js"}
1
+ {"version":3,"sources":["../../../src/components/entries/Checkbox.js"],"names":["Checkbox","props","id","label","onChange","value","handleChange","target","checked","prefixId","CheckboxEntry","element","description","getValue","setValue","isEdited","node"],"mappings":";;;AAAA,SAASA,QAAT,CAAkBC,KAAlB,EAAyB;AACvB,QAAM;AACJC,IAAAA,EADI;AAEJC,IAAAA,KAFI;AAGJC,IAAAA,QAHI;AAIJC,IAAAA,KAAK,GAAG;AAJJ,MAKFJ,KALJ;;AAOA,QAAMK,YAAY,GAAG,CAAC;AAAEC,IAAAA;AAAF,GAAD,KAAgB;AACnCH,IAAAA,QAAQ,CAACG,MAAM,CAACC,OAAR,CAAR;AACD,GAFD;;AAIA,SACE;AAAK,IAAA,KAAK,EAAC,+BAAX;AAAA,eACE;AACE,MAAA,EAAE,EAAGC,QAAQ,CAACP,EAAD,CADf;AAEE,MAAA,IAAI,EAAGA,EAFT;AAGE,MAAA,IAAI,EAAC,UAHP;AAIE,MAAA,KAAK,EAAC,4BAJR;AAKE,MAAA,QAAQ,EAAGI,YALb;AAME,MAAA,OAAO,EAAGD;AANZ,MADF,EAQE;AAAO,MAAA,GAAG,EAAGI,QAAQ,CAACP,EAAD,CAArB;AAA4B,MAAA,KAAK,EAAC,4BAAlC;AAAA,gBAAiEC;AAAjE,MARF;AAAA,IADF;AAYD;AAGD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA,eAAe,SAASO,aAAT,CAAuBT,KAAvB,EAA8B;AAC3C,QAAM;AACJU,IAAAA,OADI;AAEJT,IAAAA,EAFI;AAGJU,IAAAA,WAHI;AAIJT,IAAAA,KAJI;AAKJU,IAAAA,QALI;AAMJC,IAAAA;AANI,MAOFb,KAPJ;AASA,QAAMI,KAAK,GAAGQ,QAAQ,CAACF,OAAD,CAAtB;AAEA,SACE;AAAK,IAAA,KAAK,EAAC,gEAAX;AAA4E,qBAAgBT,EAA5F;AAAA,eACE,KAAC,QAAD;AAAU,MAAA,EAAE,EAAGA,EAAf;AAAoB,MAAA,KAAK,EAAGC,KAA5B;AAAoC,MAAA,QAAQ,EAAGW,QAA/C;AAA0D,MAAA,KAAK,EAAGT;AAAlE,MADF,EAEIO,WAAW,IAAI;AAAK,MAAA,KAAK,EAAC,kCAAX;AAAA,gBAAgDA;AAAhD,MAFnB;AAAA,IADF;AAMD;AAED,OAAO,SAASG,QAAT,CAAkBC,IAAlB,EAAwB;AAC7B,SAAOA,IAAI,IAAI,CAAC,CAACA,IAAI,CAACR,OAAtB;AACD,C,CAGD;;AAEA,SAASC,QAAT,CAAkBP,EAAlB,EAAsB;AACpB,SAAQ,wBAAwBA,EAAI,EAApC;AACD","sourcesContent":["function Checkbox(props) {\n const {\n id,\n label,\n onChange,\n value = false\n } = props;\n\n const handleChange = ({ target }) => {\n onChange(target.checked);\n };\n\n return (\n <div class=\"bio-properties-panel-checkbox\">\n <input\n id={ prefixId(id) }\n name={ id }\n type=\"checkbox\"\n class=\"bio-properties-panel-input\"\n onChange={ handleChange }\n checked={ value } />\n <label for={ prefixId(id) } class=\"bio-properties-panel-label\">{ label }</label>\n </div>\n );\n}\n\n\n/**\n * @param {Object} props\n * @param {Object} props.element\n * @param {String} props.id\n * @param {String} props.description\n * @param {String} props.label\n * @param {Function} props.getValue\n * @param {Function} props.setValue\n */\nexport default function CheckboxEntry(props) {\n const {\n element,\n id,\n description,\n label,\n getValue,\n setValue\n } = props;\n\n const value = getValue(element);\n\n return (\n <div class=\"bio-properties-panel-entry bio-properties-panel-checkbox-entry\" data-entry-id={ id }>\n <Checkbox id={ id } label={ label } onChange={ setValue } value={ value } />\n { description && <div class=\"bio-properties-panel-description\">{ description }</div> }\n </div>\n );\n}\n\nexport function isEdited(node) {\n return node && !!node.checked;\n}\n\n\n// helpers /////////////////\n\nfunction prefixId(id) {\n return `bio-properties-panel-${ id }`;\n}\n"],"file":"Checkbox.js"}
@@ -1,6 +1,6 @@
1
1
  import { useState } from 'preact/hooks';
2
2
  import classnames from 'classnames';
3
- import { ListArrowIcon, ListDeleteIcon } from '../icons';
3
+ import { ArrowIcon, DeleteIcon } from '../icons';
4
4
  import { jsx as _jsx } from "preact/jsx-runtime";
5
5
  import { jsxs as _jsxs } from "preact/jsx-runtime";
6
6
  export default function CollapsibleEntry(props) {
@@ -24,17 +24,20 @@ export default function CollapsibleEntry(props) {
24
24
  class: "bio-properties-panel-collapsible-entry-header",
25
25
  onClick: toggleOpen,
26
26
  children: [_jsx("div", {
27
+ title: label || placeholderLabel,
27
28
  class: classnames('bio-properties-panel-collapsible-entry-header-title', !label && 'empty'),
28
29
  children: label || placeholderLabel
29
- }), _jsx("div", {
30
- class: "bio-properties-panel-collapsible-entry-arrow",
31
- children: _jsx(ListArrowIcon, {
30
+ }), _jsx("button", {
31
+ title: "Toggle list item",
32
+ class: "bio-properties-panel-arrow bio-properties-panel-collapsible-entry-arrow",
33
+ children: _jsx(ArrowIcon, {
32
34
  class: open ? 'bio-properties-panel-arrow-down' : 'bio-properties-panel-arrow-right'
33
35
  })
34
36
  }), RemoveContainer ? _jsx(RemoveContainer, {
35
37
  children: _jsx("button", {
38
+ title: "Delete item",
36
39
  class: "bio-properties-panel-remove-entry",
37
- children: _jsx(ListDeleteIcon, {})
40
+ children: _jsx(DeleteIcon, {})
38
41
  })
39
42
  }) : null]
40
43
  }), _jsx("div", {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/entries/Collapsible.js"],"names":["useState","classnames","ListArrowIcon","ListDeleteIcon","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,aADF,EAEEC,cAFF,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,EAAGb,UAAU,CAChB,qDADgB,EAEhB,CAACO,KAAD,IAAU,OAFM,CADpB;AAAA,kBAKIA,KAAK,IAAIO;AALb,QADF,EAQE;AAAK,QAAA,KAAK,EAAC,8CAAX;AAAA,kBACE,KAAC,aAAD;AAAe,UAAA,KAAK,EAAGJ,IAAI,GAAG,iCAAH,GAAuC;AAAlE;AADF,QARF,EAYID,eAAe,GAGX,KAAC,eAAD;AAAA,kBACE;AAAQ,UAAA,KAAK,EAAC,mCAAd;AAAA,oBACE,KAAC,cAAD;AADF;AADF,QAHW,GASX,IArBR;AAAA,MANF,EA8BE;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,MA9BF;AAAA,IADF;AAyCD","sourcesContent":["import {\n useState\n} from 'preact/hooks';\n\nimport classnames from 'classnames';\n\nimport {\n ListArrowIcon,\n ListDeleteIcon,\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 class={ classnames(\n 'bio-properties-panel-collapsible-entry-header-title',\n !label && 'empty'\n ) }>\n { label || placeholderLabel }\n </div>\n <div class=\"bio-properties-panel-collapsible-entry-arrow\">\n <ListArrowIcon class={ open ? 'bio-properties-panel-arrow-down' : 'bio-properties-panel-arrow-right' } />\n </div>\n {\n RemoveContainer\n ?\n (\n <RemoveContainer>\n <button class=\"bio-properties-panel-remove-entry\">\n <ListDeleteIcon />\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","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"}