@loadsmart/loadsmart-ui 6.0.13 → 6.0.15
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/dist/components/Banner/Banner.d.ts +4 -4
- package/dist/components/Banner/Banner.stories.d.ts +2 -1
- package/dist/components/Button/Button.stories.d.ts +3 -2
- package/dist/components/DatePicker/useDatePicker.d.ts +8 -2
- package/dist/components/DatePicker/useDateRangePicker.d.ts +12 -3
- package/dist/components/Dialog/Dialog.d.ts +4 -4
- package/dist/components/DragDropFile/DragDropFile.d.ts +2 -1
- package/dist/components/DragDropFile/components/Wrapper.d.ts +2 -1
- package/dist/components/DragDropFile/styles.d.ts +3 -2
- package/dist/components/ErrorMessage/ErrorMessage.d.ts +2 -1
- package/dist/components/Modal/Modal.d.ts +1 -1
- package/dist/components/Popover/Popover.types.d.ts +6 -8
- package/dist/components/Section/Section.d.ts +2 -2
- package/dist/components/SideNavigation/Menu/Menu.d.ts +1 -1
- package/dist/components/SideNavigation/SideNavigation.d.ts +1 -1
- package/dist/components/Tabs/Tabs.d.ts +5 -5
- package/dist/components/Tag/Tag.stories.d.ts +2 -1
- package/dist/index.js +190 -188
- package/dist/index.js.map +1 -1
- package/dist/{miranda-compatibility.theme-ec2c3370.js → miranda-compatibility.theme-f99913ed.js} +2 -2
- package/dist/{miranda-compatibility.theme-ec2c3370.js.map → miranda-compatibility.theme-f99913ed.js.map} +1 -1
- package/dist/{prop-9e9ff08a.js → prop-82e9ff9d.js} +2 -2
- package/dist/{prop-9e9ff08a.js.map → prop-82e9ff9d.js.map} +1 -1
- package/dist/testing/index.js +1 -1
- package/dist/theming/index.js +1 -1
- package/dist/theming/themes/miranda-compatibility.theme.d.ts +3 -3
- package/dist/tools/index.js +1 -1
- package/package.json +5 -5
- package/src/components/Dropdown/Dropdown.test.tsx +1 -1
- package/src/components/Dropdown/DropdownMenu.tsx +3 -1
- package/src/components/Popover/Popover.test.tsx +1 -2
- package/src/components/Popover/Popover.tsx +25 -68
- package/src/components/Popover/Popover.types.ts +6 -8
- package/src/components/Select/SelectTrigger.tsx +1 -8
- package/src/components/Tooltip/Tooltip.tsx +1 -8
- package/src/theming/themes/miranda-compatibility.theme.ts +3 -3
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var t=require("./toArray-b56541b4.js"),n=require("./miranda-compatibility.theme-
|
|
2
|
-
//# sourceMappingURL=prop-
|
|
1
|
+
"use strict";var t=require("./toArray-b56541b4.js"),n=require("./miranda-compatibility.theme-f99913ed.js"),e=require("./theming/index.js");function r(t,r){return Object.keys(t||{}).reduce(((o,i)=>{var u;let s=t[i];if(n.isFunction(s)&&(s=s(r)),s){const t=i,n=null!==(u=e.getToken(t,r))&&void 0!==u?u:i;return[...o,n]}return o}),[]).join(" ")}function o(...t){const[n,e]=t;return null==n||!1===n||Number.isNaN(n)?e||n:"string"==typeof n&&0===n.length&&e||n}exports.conditional=function(...e){return function(o){let i=[];for(let u=0;u<e.length;u++){const s=e[u];n.isFunction(s)?i.push(s(o)):t.isObject(s)?i=i.concat(r(s,o)):s&&i.push(String(s))}return i.join(" ")}},exports.prop=function(t,n,e=o){return r=>e(r[t],n)},exports.whenProps=function(e){return function(r){const o=t.toArray(e);let i=!1;for(let e=0;e<o.length;e++){const u=o[e],s=Object.keys(u);let c=!0;for(let e=0;e<s.length&&c;e++){const o=s[e],i=n.lodash_get(r,o),l=u[o];c=Array.isArray(l)?c&&t.toArray(l).includes(i):n.isFunction(l)?c&&Boolean(l(i)):c&&l===i}i=i||c}return i}};
|
|
2
|
+
//# sourceMappingURL=prop-82e9ff9d.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prop-
|
|
1
|
+
{"version":3,"file":"prop-82e9ff9d.js","sources":["../src/tools/conditional.ts","../src/tools/prop.ts"],"sourcesContent":["import { isObject } from '@loadsmart/utils-object'\nimport { isFunction } from '@loadsmart/utils-function'\nimport type { F } from 'ts-toolbelt'\n\nimport { getToken } from 'theming'\nimport type { ThemeToken, ThemedProps } from 'theming'\nimport get from 'utils/toolset/get'\nimport toArray from 'utils/toolset/toArray'\n\ntype WhenProps<K> = K | undefined | ((value: K) => boolean | undefined)\n\nexport type When<P> = {\n [Key in keyof P]?: WhenProps<P[Key]> | WhenProps<P[Key]>[] | undefined\n}\n\n/**\n * Utility to generate style/class name conditions based on a components props.\n * Expected prop values can be a single value, an array of values or a function/callback.\n * @example\n * ```jsx\n * whenProps({\n * 'prop-a': true, // checks `props['prop-a']` === true`\n * 'prop-b': [1, 2], // checks `toArray([1, 2]).includes(props['prop-b'])`\n * 'prop-c': (value) => value + 1 // checks `Boolean(callback(props['prop-c']))`\n * 'prop-d': Boolean // checks `Boolean(Boolean(props['prop-d']))`\n * })\n * ```\n * @param {...Object} conditions\n * @returns {(props: Object}) => boolean} Returns function that consumes component props.\n */\nexport function whenProps<P>(conditions: When<F.Narrow<P>> | When<F.Narrow<P>>[]) {\n return function (props: P): boolean {\n const safeConditions = toArray(conditions)\n\n let res = false\n\n for (let i = 0; i < safeConditions.length; i++) {\n const condition = safeConditions[i]\n const keys = Object.keys(condition)\n\n let temp = true\n\n for (let j = 0; j < keys.length && temp; j++) {\n const key = keys[j]\n const propValue = get(props, key) as P[keyof P]\n const conditionValue = condition[key as keyof typeof condition]\n\n if (Array.isArray(conditionValue)) {\n temp = temp && toArray(conditionValue).includes(propValue)\n } else if (isFunction(conditionValue)) {\n temp = temp && Boolean(conditionValue(propValue))\n } else {\n temp = temp && (conditionValue as unknown) === propValue\n }\n }\n\n res = res || temp\n }\n\n return res\n }\n}\n\ntype ConditionObject<P> = Record<\n string,\n string | number | boolean | ((props: P) => boolean) | undefined\n>\n\nfunction handleConditionObject<P>(condition: ConditionObject<P>, props: P): string {\n const keys = Object.keys(condition || {})\n\n const res = keys.reduce((acc, key) => {\n let value = condition[key]\n\n if (isFunction(value)) {\n value = value(props)\n }\n\n if (value) {\n const tokenKey = key as ThemeToken\n const result = (getToken(tokenKey, props as unknown as ThemedProps) ?? key) as string\n return [...acc, result]\n }\n\n return acc\n }, [] as string[])\n\n return res.join(' ')\n}\n\ntype Condition<P> = number | string | ConditionObject<P> | ((props: P) => string)\n\n/**\n * Concatenate style properties or class names conditionally.\n * Conditions can be functions that consume components props,\n * objects, strings, or numbers (that will be coerced to strings).\n * @example\n * ```jsx\n * conditional(1, 'some-class', {\n * 'class-a': true,\n * 'class-b': (props) => props.showClassB,\n * }, (props) => props.className)\n * ```\n * @param conditions\n * @returns {(props: ThemedProps) => string} Returns function that consumes component props.\n */\nfunction conditional<P>(...conditions: Condition<P>[]) {\n return function (props: P): string {\n let classes: string[] = []\n\n for (let i = 0; i < conditions.length; i++) {\n const condition = conditions[i]\n\n if (isFunction(condition)) {\n classes.push(condition(props))\n } else if (isObject(condition)) {\n classes = classes.concat(handleConditionObject<P>(condition, props))\n } else if (condition) {\n classes.push(String(condition))\n }\n }\n\n return classes.join(' ')\n }\n}\n\nexport default conditional\n","function compare(...args: any[]): unknown {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const [value, defaultValue] = args\n\n if (value == null || value === false || Number.isNaN(value)) {\n return defaultValue || value\n }\n\n if (typeof value === 'string' && value.length === 0) {\n return defaultValue || value\n }\n\n return value\n}\n\n/**\n * Retrieve the key value from the props object\n * @example\n * ```jsx\n * -transform: scaleY(${(props) => props.$height || 1});\n * +transform: scaleY(${prop('$height', 1)});\n * ```\n * @param name a valid property name from the object\n * @param defaultValue a fallback value in case the property value is invalid\n * @param comparatorFn a function to be used to decide between value or defaultValue\n * @returns {(props: ThemedProps) => string} Returns function that consumes component props.\n */\nfunction prop<P, K extends keyof P = keyof P>(\n name: K,\n defaultValue?: NonNullable<P[K]>,\n comparatorFn = compare\n) {\n return (props: P): P[K] => comparatorFn(props[name], defaultValue) as P[K]\n}\n\nexport default prop\n"],"names":["handleConditionObject","condition","props","Object","keys","reduce","acc","key","value","isFunction","tokenKey","result","_a","getToken","join","compare","args","defaultValue","Number","isNaN","length","conditions","classes","i","push","isObject","concat","String","name","comparatorFn","safeConditions","toArray","res","temp","j","propValue","get","conditionValue","Array","isArray","includes","Boolean"],"mappings":"2IAoEA,SAASA,EAAyBC,EAA+BC,GAmB/D,OAlBaC,OAAOC,KAAKH,GAAa,CAAE,GAEvBI,QAAO,CAACC,EAAKC,WAC5B,IAAIC,EAAQP,EAAUM,GAMtB,GAJIE,EAAAA,WAAWD,KACbA,EAAQA,EAAMN,IAGZM,EAAO,CACT,MAAME,EAAWH,EACXI,EAAiE,QAAvDC,EAAAC,EAAQA,SAACH,EAAUR,UAAoC,IAAAU,EAAAA,EAAAL,EACvE,MAAO,IAAID,EAAKK,EACjB,CAED,OAAOL,CAAG,GACT,IAEQQ,KAAK,IAClB,CCxFA,SAASC,KAAWC,GAElB,MAAOR,EAAOS,GAAgBD,EAE9B,OAAa,MAATR,IAA2B,IAAVA,GAAmBU,OAAOC,MAAMX,GAC5CS,GAAgBT,EAGJ,iBAAVA,GAAuC,IAAjBA,EAAMY,QAC9BH,GAGFT,CACT,qBD6FA,YAA2Ba,GACzB,OAAO,SAAUnB,GACf,IAAIoB,EAAoB,GAExB,IAAK,IAAIC,EAAI,EAAGA,EAAIF,EAAWD,OAAQG,IAAK,CAC1C,MAAMtB,EAAYoB,EAAWE,GAEzBd,EAAAA,WAAWR,GACbqB,EAAQE,KAAKvB,EAAUC,IACduB,EAAAA,SAASxB,GAClBqB,EAAUA,EAAQI,OAAO1B,EAAyBC,EAAWC,IACpDD,GACTqB,EAAQE,KAAKG,OAAO1B,GAEvB,CAED,OAAOqB,EAAQR,KAAK,IACtB,CACF,eCjGA,SACEc,EACAX,EACAY,EAAed,GAEf,OAAQb,GAAmB2B,EAAa3B,EAAM0B,GAAOX,EACvD,oBDHM,SAAuBI,GAC3B,OAAO,SAAUnB,GACf,MAAM4B,EAAiBC,UAAQV,GAE/B,IAAIW,GAAM,EAEV,IAAK,IAAIT,EAAI,EAAGA,EAAIO,EAAeV,OAAQG,IAAK,CAC9C,MAAMtB,EAAY6B,EAAeP,GAC3BnB,EAAOD,OAAOC,KAAKH,GAEzB,IAAIgC,GAAO,EAEX,IAAK,IAAIC,EAAI,EAAGA,EAAI9B,EAAKgB,QAAUa,EAAMC,IAAK,CAC5C,MAAM3B,EAAMH,EAAK8B,GACXC,EAAYC,EAAAA,WAAIlC,EAAOK,GACvB8B,EAAiBpC,EAAUM,GAG/B0B,EADEK,MAAMC,QAAQF,GACTJ,GAAQF,EAAOA,QAACM,GAAgBG,SAASL,GACvC1B,EAAAA,WAAW4B,GACbJ,GAAQQ,QAAQJ,EAAeF,IAE/BF,GAASI,IAA+BF,CAElD,CAEDH,EAAMA,GAAOC,CACd,CAED,OAAOD,CACT,CACF"}
|
package/dist/testing/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../DragDropFile.context-c7cd1441.js"),t=require("@testing-library/react"),i=require("../toArray-b56541b4.js"),n=require("../miranda-compatibility.theme-
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../DragDropFile.context-c7cd1441.js"),t=require("@testing-library/react"),i=require("../toArray-b56541b4.js"),n=require("../miranda-compatibility.theme-f99913ed.js"),r=require("react");function o(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}require("@loadsmart/miranda-tokens");var c=o(r);function a(e){return e.parentNode.parentNode.parentNode.parentNode}function d(i){return e.__awaiter(this,void 0,void 0,(function*(){const n=a(i);t.queries.queryByRole(n,"menu")||(yield t.act((()=>e.__awaiter(this,void 0,void 0,(function*(){t.fireEvent.click(i),expect(yield t.queries.findByRole(n,"menu")).toBeInTheDocument()})))))}))}function u(i){return e.__awaiter(this,void 0,void 0,(function*(){const n=a(i);t.queries.queryByRole(n,"menu")&&(yield t.act((()=>e.__awaiter(this,void 0,void 0,(function*(){t.fireEvent.click(t.queries.getByText(n,"Close")),yield t.waitForElementToBeRemoved((()=>t.queries.queryByRole(n,"menu")))})))))}))}const l={getContainer:a,expand:d,collapse:u,pick:function(i,n){return e.__awaiter(this,void 0,void 0,(function*(){const r=a(n);yield d(n),yield t.act((()=>e.__awaiter(this,void 0,void 0,(function*(){n.focus();const e=t.queries.getByLabelText(r,i);e&&"false"==e.getAttribute("aria-checked")&&t.fireEvent.click(e)})))),yield u(n)}))},clear:function(i){return e.__awaiter(this,void 0,void 0,(function*(){const n=a(i);yield t.act((()=>e.__awaiter(this,void 0,void 0,(function*(){const e=t.queries.getByLabelText(n,"Clear selection");t.fireEvent.click(e)})))),yield u(i)}))},getSelectedDates:function(i){return e.__awaiter(this,void 0,void 0,(function*(){const e=a(i);yield d(i);const n=t.queries.queryAllByRole(e,"checkbox",{checked:!0});return yield u(i),n}))}};function s(t){return e.__awaiter(this,void 0,void 0,(function*(){yield l.expand(t)}))}function f(t){return e.__awaiter(this,void 0,void 0,(function*(){yield l.collapse(t)}))}const v={getContainer:l.getContainer,expand:s,collapse:f,pick:function(i,n){return e.__awaiter(this,void 0,void 0,(function*(){const e=l.getContainer(n);yield s(n);const[r,o]=i;if(null!=r){const i=t.queries.getByTestId(e,"input-date-range-start");yield l.pick(r,i)}if(null!=o){const i=t.queries.getByTestId(e,"input-date-range-end");yield l.pick(o,i)}yield f(n)}))},clear:function(t){return e.__awaiter(this,void 0,void 0,(function*(){yield l.clear(t)}))},getSelectedDates:function(t){return e.__awaiter(this,void 0,void 0,(function*(){return l.getSelectedDates(t)}))}},y=e=>e.parentNode,p={dragOver:e=>{const i=y(e),n=t.createEvent.dragOver(i);t.fireEvent(i,n)},dragLeave:e=>{const i=y(e),n=t.createEvent.dragLeave(i);t.fireEvent(i,n)},dropFiles:(e,n)=>{const r=y(e),o=t.createEvent.drop(r);Object.defineProperty(o,"dataTransfer",{value:{files:i.toArray(n)}}),t.fireEvent(r,o)}};function _(e){return e.parentNode.parentNode.parentNode}function h(e){return e.parentNode.parentNode.nextSibling}function g(e){return e.parentNode.nextSibling.nextSibling}function w(e){return e.parentNode}function x(e){return 3===_(e).children.length}function E(i){return e.__awaiter(this,void 0,void 0,(function*(){const e=w(i);t.within(e).queryByTestId("select-trigger-loading")&&(yield t.waitForElementToBeRemoved((()=>t.within(e).queryByTestId("select-trigger-loading")),{timeout:2500}))}))}function b(i){return e.__awaiter(this,void 0,void 0,(function*(){if(yield E(i),x(i))return;const n=g(i);yield t.waitFor((()=>{expect(n).toBeEnabled()})),t.act((()=>{i.dispatchEvent(new MouseEvent("click",{bubbles:!0}))})),yield t.waitFor((()=>e.__awaiter(this,void 0,void 0,(function*(){expect(yield t.within(_(i)).findByRole("listbox")).toBeInTheDocument()}))))}))}function B(i){return e.__awaiter(this,void 0,void 0,(function*(){if(!x(i))return;const e=g(i);t.fireEvent.click(e),yield t.waitFor((()=>{expect(t.within(_(i)).queryByRole("listbox")).not.toBeInTheDocument()}))}))}const q={select:function(i,n){return e.__awaiter(this,void 0,void 0,(function*(){yield b(n);const e=h(n),r=yield t.within(e).findByLabelText(i);r&&"false"==r.getAttribute("aria-selected")&&(t.fireEvent.mouseDown(r),t.act((()=>{r.focus()})),t.fireEvent.mouseUp(r),t.fireEvent.click(r)),yield B(n)}))},unselect:function(i,n){return e.__awaiter(this,void 0,void 0,(function*(){yield b(n);const e=h(n),r=yield t.within(e).findByLabelText(i);r&&"true"===r.getAttribute("aria-selected")&&t.fireEvent.click(r),yield B(n)}))},clear:function(i){return e.__awaiter(this,void 0,void 0,(function*(){yield E(i);const e=w(i),n=t.within(e).getByTestId("select-trigger-clear");n&&t.fireEvent.click(n)}))},search:function(i,n){return e.__awaiter(this,void 0,void 0,(function*(){t.fireEvent.change(n,{target:{value:i}}),yield E(n);const e=h(n);yield t.within(e).findAllByRole("option")}))},expand:b,collapse:B,getOptions:function(i){return e.__awaiter(this,void 0,void 0,(function*(){yield b(i);const e=h(i),n=t.within(e).queryAllByRole("option");return yield B(i),n}))},getSelectedOptions:function(i){return e.__awaiter(this,void 0,void 0,(function*(){yield b(i);const e=h(i);let n=[];try{n=yield t.within(e).findAllByRole("option",{selected:!0})}catch(e){n=[]}return yield B(i),n}))},isMenuExpanded:x};const m={fileList:[],onFilesAdded:jest.fn(),onRetryUpload:jest.fn(),onRemoveFile:jest.fn()};exports.DatePickerEvent=l,exports.DateRangePickerEvent=v,exports.DragDropFileEvent=p,exports.SelectEvent=q,exports.getInterpolatedStyles=function(e){return i.toArray(e).map((e=>{for(;n.isFunction(e);)e=e({theme:n.alice});return e})).join("")},exports.renderWithDragDropFileProvider=(i,n)=>{const r=Object.assign(Object.assign({},m),n);return t.render((o=i,c.default.createElement(e.DragDropFileContext.Provider,{value:r},o)));var o};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/theming/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../miranda-compatibility.theme-
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../miranda-compatibility.theme-f99913ed.js");require("@loadsmart/miranda-tokens");var t=Object.freeze({__proto__:null,Alice:e.alice,Loadsmart:e.loadsmart,Miranda:e.mirandaCompatibility});function r(t,r){const i=e.isFunction(t)?t(r):t;return r.theme[i]}exports.Themes=t,exports.getToken=function(e,t){return void 0===t?t=>r(e,t):r(e,t)};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -381,10 +381,10 @@ declare const mirandaCompatibility: {
|
|
|
381
381
|
'text-field-background--hover': string | number;
|
|
382
382
|
'text-field-background--focus': string | number;
|
|
383
383
|
'text-field-background--disabled': string | number;
|
|
384
|
-
'text-field-border-color': string
|
|
384
|
+
'text-field-border-color': string;
|
|
385
385
|
'text-field-border-color--hover': string;
|
|
386
386
|
'text-field-border-color--focus': string;
|
|
387
|
-
'text-field-border-color--disabled': string
|
|
387
|
+
'text-field-border-color--disabled': string;
|
|
388
388
|
'text-field-dark-color': string | number;
|
|
389
389
|
'text-field-dark-background': string | number;
|
|
390
390
|
'text-field-dark-border-color': string | number;
|
|
@@ -392,7 +392,7 @@ declare const mirandaCompatibility: {
|
|
|
392
392
|
'text-field-dark-border-color--focus': string | number;
|
|
393
393
|
'text-field-dark-border-color--disabled': string | number;
|
|
394
394
|
'text-field-success-border-color': string | number;
|
|
395
|
-
'text-field-danger-border-color': string
|
|
395
|
+
'text-field-danger-border-color': string;
|
|
396
396
|
'text-field-dark-outline': string;
|
|
397
397
|
'textarea-border-radius': string | number;
|
|
398
398
|
'textarea-color': string | number;
|
package/dist/tools/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../prop-
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../prop-82e9ff9d.js");require("../toArray-b56541b4.js"),require("../miranda-compatibility.theme-f99913ed.js"),require("@loadsmart/miranda-tokens"),require("../theming/index.js"),exports.conditional=e.conditional,exports.prop=e.prop,exports.whenProps=e.whenProps;
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loadsmart/loadsmart-ui",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.15",
|
|
4
4
|
"description": "Miranda UI, a React UI library",
|
|
5
5
|
"main": "dist",
|
|
6
6
|
"files": [
|
|
@@ -78,10 +78,10 @@
|
|
|
78
78
|
"@types/lodash.range": "^3.2.6",
|
|
79
79
|
"@types/mdx": "^2.0.2",
|
|
80
80
|
"@types/node": "^18.11.18",
|
|
81
|
-
"@types/react": "^17.0.
|
|
82
|
-
"@types/react-dom": "^17.0.
|
|
81
|
+
"@types/react": "^17.0.59",
|
|
82
|
+
"@types/react-dom": "^17.0.20",
|
|
83
83
|
"@types/react-test-renderer": "^17.0.1",
|
|
84
|
-
"@types/styled-components": "^5.1.
|
|
84
|
+
"@types/styled-components": "^5.1.26",
|
|
85
85
|
"@typescript-eslint/eslint-plugin": "^4.22.1",
|
|
86
86
|
"@typescript-eslint/parser": "^4.22.1",
|
|
87
87
|
"@zerollup/ts-transform-paths": "^1.7.18",
|
|
@@ -149,7 +149,7 @@
|
|
|
149
149
|
"styled-components": ">=5.3.0"
|
|
150
150
|
},
|
|
151
151
|
"dependencies": {
|
|
152
|
-
"@floating-ui/react-dom": "^
|
|
152
|
+
"@floating-ui/react-dom": "^2.0.0",
|
|
153
153
|
"@loadsmart/utils-function": "0.3.1",
|
|
154
154
|
"@loadsmart/utils-object": "0.3.1",
|
|
155
155
|
"@loadsmart/utils-string": "0.3.1",
|
|
@@ -10,7 +10,7 @@ const { Playground, WithSections, Extended } = composeStories(stories)
|
|
|
10
10
|
|
|
11
11
|
describe('Dropdown', () => {
|
|
12
12
|
describe('Generic', () => {
|
|
13
|
-
const setup = (overrides?: stories.DropdownStoryProps) =>
|
|
13
|
+
const setup = (overrides?: Partial<stories.DropdownStoryProps>) =>
|
|
14
14
|
renderer(<Playground {...overrides} />).render()
|
|
15
15
|
|
|
16
16
|
it('starts collapsed', () => {
|
|
@@ -32,6 +32,7 @@ const StyledPopover = styled(Popover.Floating)`
|
|
|
32
32
|
border: 1px solid ${token('dropdown-border-color')};
|
|
33
33
|
border-radius: ${token('dropdown-border-radius')};
|
|
34
34
|
box-shadow: ${token('dropdown-shadow')};
|
|
35
|
+
width: max-content;
|
|
35
36
|
`
|
|
36
37
|
|
|
37
38
|
const StyledSpan = styled.span`
|
|
@@ -154,7 +155,8 @@ const GenericDropdownMenuWrapper = styled.div`
|
|
|
154
155
|
const DropdownMenuWrapper = styled(GenericDropdownMenuWrapper)`
|
|
155
156
|
max-height: 240px;
|
|
156
157
|
overflow-y: auto;
|
|
157
|
-
width:
|
|
158
|
+
max-width: 100%;
|
|
159
|
+
width: 100%;
|
|
158
160
|
|
|
159
161
|
${DropdownItemWrapper} + ${DropdownItemWrapper},
|
|
160
162
|
${DropdownSectionHeader} + ${DropdownItemWrapper} {
|
|
@@ -4,8 +4,7 @@ import { composeStories } from '@storybook/testing-react'
|
|
|
4
4
|
import * as stories from './Popover.stories'
|
|
5
5
|
import generator from '../../tests/generator'
|
|
6
6
|
import renderer, { screen } from '../../tests/renderer'
|
|
7
|
-
|
|
8
|
-
import type { PopoverProps } from './Popover'
|
|
7
|
+
import type { PopoverProps } from './Popover.types'
|
|
9
8
|
|
|
10
9
|
const { Playground } = composeStories(stories)
|
|
11
10
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import React, { useMemo } from 'react'
|
|
2
|
-
import { useFloating, autoUpdate } from '@floating-ui/react-dom'
|
|
3
|
-
import {
|
|
4
|
-
import type { Placement, MiddlewareState } from '@floating-ui/core'
|
|
1
|
+
import React, { CSSProperties, useMemo, useRef } from 'react'
|
|
2
|
+
import { useFloating, offset, flip, shift, arrow, autoUpdate } from '@floating-ui/react-dom'
|
|
3
|
+
import type { Placement } from '@floating-ui/react-dom'
|
|
5
4
|
|
|
6
5
|
import type {
|
|
7
6
|
PopoverAlign,
|
|
@@ -25,75 +24,50 @@ export function usePopover(): UsePopoverReturn {
|
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
function Popover(props: PopoverProps): JSX.Element {
|
|
28
|
-
const arrowRef =
|
|
27
|
+
const arrowRef = useRef<HTMLElement | null>(null)
|
|
29
28
|
|
|
30
29
|
const { position = 'bottom', align = 'start', strategy = 'fixed' } = props
|
|
31
30
|
|
|
32
|
-
const desiredPlacement = `${position}${
|
|
31
|
+
const desiredPlacement: Placement = `${position}${
|
|
32
|
+
align === 'center' ? '' : `-${align}`
|
|
33
|
+
}` as Placement
|
|
33
34
|
|
|
34
|
-
const
|
|
35
|
+
const floating = useFloating({
|
|
35
36
|
placement: desiredPlacement,
|
|
36
37
|
strategy,
|
|
37
|
-
middleware: [
|
|
38
|
-
offset(10),
|
|
39
|
-
flip(),
|
|
40
|
-
shift(),
|
|
41
|
-
{
|
|
42
|
-
name: 'arrow',
|
|
43
|
-
fn(args: MiddlewareState) {
|
|
44
|
-
if (arrowRef.current) {
|
|
45
|
-
return arrow({ element: arrowRef.current, padding: 8 }).fn(args)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return {}
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
],
|
|
38
|
+
middleware: [offset(10), flip(), shift(), arrow({ element: arrowRef, padding: 8 })],
|
|
52
39
|
// TODO: FloatingUI docs states that `autoUpdate` is expensive.
|
|
53
40
|
// This should be properly investidated since it's the way to
|
|
54
41
|
// update fixed positions after scrolling.
|
|
55
42
|
whileElementsMounted: autoUpdate,
|
|
56
43
|
})
|
|
57
44
|
|
|
58
|
-
const
|
|
59
|
-
(node: HTMLElement) => {
|
|
60
|
-
arrowRef.current = node
|
|
61
|
-
result.update()
|
|
62
|
-
},
|
|
63
|
-
[result]
|
|
64
|
-
)
|
|
65
|
-
|
|
66
|
-
const [resultPosition = position, resultAlign = align] = result.placement.split('-') as [
|
|
45
|
+
const [resultPosition = position, resultAlign = align] = floating.placement.split('-') as [
|
|
67
46
|
PopoverPosition,
|
|
68
47
|
PopoverAlign
|
|
69
48
|
]
|
|
70
49
|
|
|
71
|
-
const value = useMemo(
|
|
50
|
+
const value = useMemo<UsePopoverReturn>(
|
|
72
51
|
() => ({
|
|
73
52
|
strategy,
|
|
74
53
|
register: {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
54
|
+
setReference: floating.refs.setReference,
|
|
55
|
+
setFloating: floating.refs.setFloating,
|
|
56
|
+
setArrow: arrowRef,
|
|
78
57
|
},
|
|
79
58
|
result: {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
left: result.x ?? 0,
|
|
83
|
-
},
|
|
84
|
-
arrow: { top: result.middlewareData.arrow?.y, left: result.middlewareData.arrow?.x },
|
|
59
|
+
floatingStyles: floating.floatingStyles,
|
|
60
|
+
arrow: { top: floating.middlewareData.arrow?.y, left: floating.middlewareData.arrow?.x },
|
|
85
61
|
position: resultPosition,
|
|
86
62
|
align: resultAlign,
|
|
87
63
|
},
|
|
88
64
|
}),
|
|
89
65
|
[
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
result.x,
|
|
96
|
-
result.y,
|
|
66
|
+
floating.refs.setFloating,
|
|
67
|
+
floating.middlewareData.arrow?.x,
|
|
68
|
+
floating.middlewareData.arrow?.y,
|
|
69
|
+
floating.refs.setReference,
|
|
70
|
+
floating.floatingStyles,
|
|
97
71
|
resultAlign,
|
|
98
72
|
resultPosition,
|
|
99
73
|
strategy,
|
|
@@ -104,41 +78,24 @@ function Popover(props: PopoverProps): JSX.Element {
|
|
|
104
78
|
}
|
|
105
79
|
|
|
106
80
|
function PopoverReference({ children, ...others }: PopoverReferenceProps): JSX.Element {
|
|
107
|
-
const ref = React.useRef<HTMLDivElement | null>(null)
|
|
108
81
|
const { register } = usePopover()
|
|
109
82
|
|
|
110
|
-
React.useLayoutEffect(() => {
|
|
111
|
-
if (ref.current) {
|
|
112
|
-
register.reference(ref.current)
|
|
113
|
-
}
|
|
114
|
-
}, [register])
|
|
115
|
-
|
|
116
83
|
return (
|
|
117
|
-
<div ref={
|
|
84
|
+
<div ref={register.setReference} {...others}>
|
|
118
85
|
{children}
|
|
119
86
|
</div>
|
|
120
87
|
)
|
|
121
88
|
}
|
|
122
89
|
|
|
123
90
|
function PopoverFloating({ children, style, ...others }: PopoverFloatingProps): JSX.Element {
|
|
124
|
-
const { register, result
|
|
125
|
-
|
|
126
|
-
const ref = React.useRef<HTMLDivElement | null>(null)
|
|
127
|
-
|
|
128
|
-
React.useLayoutEffect(() => {
|
|
129
|
-
if (ref.current) {
|
|
130
|
-
register.floating(ref.current)
|
|
131
|
-
}
|
|
132
|
-
}, [register])
|
|
91
|
+
const { register, result } = usePopover()
|
|
133
92
|
|
|
134
93
|
return (
|
|
135
94
|
<div
|
|
136
|
-
ref={
|
|
95
|
+
ref={register.setFloating}
|
|
137
96
|
{...others}
|
|
138
97
|
style={{
|
|
139
|
-
|
|
140
|
-
top: result.floating.top,
|
|
141
|
-
left: result.floating.left,
|
|
98
|
+
...result.floatingStyles,
|
|
142
99
|
...style,
|
|
143
100
|
}}
|
|
144
101
|
>
|
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { UseFloatingReturn } from '@floating-ui/react-dom'
|
|
2
|
+
import type { CSSProperties, HTMLAttributes, MutableRefObject, PropsWithChildren } from 'react'
|
|
2
3
|
|
|
3
4
|
export interface UsePopoverReturn {
|
|
4
5
|
register: {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
setReference: UseFloatingReturn['refs']['setReference']
|
|
7
|
+
setFloating: UseFloatingReturn['refs']['setFloating']
|
|
8
|
+
setArrow: MutableRefObject<Element | null>
|
|
8
9
|
}
|
|
9
10
|
result: {
|
|
10
|
-
|
|
11
|
-
top: number
|
|
12
|
-
left: number
|
|
13
|
-
}
|
|
11
|
+
floatingStyles: CSSProperties
|
|
14
12
|
arrow: {
|
|
15
13
|
top: number | undefined
|
|
16
14
|
left: number | undefined
|
|
@@ -49,16 +49,9 @@ const SelectTrigger = forwardRef<HTMLInputElement, SelectTriggerProps>(function
|
|
|
49
49
|
) {
|
|
50
50
|
const { className, ...others } = props
|
|
51
51
|
const { disabled, expanded, toggle } = useContext(DropdownContext)
|
|
52
|
-
const triggerRef = React.useRef<HTMLElement | null>(null)
|
|
53
52
|
|
|
54
53
|
const { register } = usePopover()
|
|
55
54
|
|
|
56
|
-
React.useEffect(() => {
|
|
57
|
-
if (triggerRef.current) {
|
|
58
|
-
register.reference(triggerRef.current)
|
|
59
|
-
}
|
|
60
|
-
}, [register])
|
|
61
|
-
|
|
62
55
|
function handleClick() {
|
|
63
56
|
if (!expanded) {
|
|
64
57
|
toggle()
|
|
@@ -75,7 +68,7 @@ const SelectTrigger = forwardRef<HTMLInputElement, SelectTriggerProps>(function
|
|
|
75
68
|
ref(node)
|
|
76
69
|
}
|
|
77
70
|
|
|
78
|
-
|
|
71
|
+
register.setReference(node)
|
|
79
72
|
}}
|
|
80
73
|
type="search"
|
|
81
74
|
disabled={disabled}
|
|
@@ -129,17 +129,10 @@ const StyledArrow = styled.span<ArrowProps>`
|
|
|
129
129
|
|
|
130
130
|
function Arrow() {
|
|
131
131
|
const { register, result } = usePopover()
|
|
132
|
-
const ref = React.useRef<HTMLDivElement | null>(null)
|
|
133
|
-
|
|
134
|
-
React.useLayoutEffect(() => {
|
|
135
|
-
if (ref.current) {
|
|
136
|
-
register.arrow(ref.current)
|
|
137
|
-
}
|
|
138
|
-
}, [register])
|
|
139
132
|
|
|
140
133
|
return (
|
|
141
134
|
<StyledArrow
|
|
142
|
-
ref={
|
|
135
|
+
ref={(element) => (register.setArrow.current = element)}
|
|
143
136
|
position={result.position}
|
|
144
137
|
top={result.arrow.top}
|
|
145
138
|
left={result.arrow.left}
|
|
@@ -496,10 +496,10 @@ const mirandaCompatibility = {
|
|
|
496
496
|
'text-field-background--focus': color('neutral-white'),
|
|
497
497
|
'text-field-background--disabled': color('neutral-light'),
|
|
498
498
|
|
|
499
|
-
'text-field-border-color':
|
|
499
|
+
'text-field-border-color': toCSSValue('color-border'),
|
|
500
500
|
'text-field-border-color--hover': toCSSValue('color-primary-60'),
|
|
501
501
|
'text-field-border-color--focus': toCSSValue('color-primary-60'),
|
|
502
|
-
'text-field-border-color--disabled':
|
|
502
|
+
'text-field-border-color--disabled': toCSSValue('color-border'),
|
|
503
503
|
|
|
504
504
|
// text-field dark
|
|
505
505
|
'text-field-dark-color': color('neutral-lighter'),
|
|
@@ -511,7 +511,7 @@ const mirandaCompatibility = {
|
|
|
511
511
|
'text-field-dark-border-color--disabled': color('neutral-lighter'),
|
|
512
512
|
|
|
513
513
|
'text-field-success-border-color': color('accent'),
|
|
514
|
-
'text-field-danger-border-color':
|
|
514
|
+
'text-field-danger-border-color': toCSSValue('color-danger-60'),
|
|
515
515
|
|
|
516
516
|
'text-field-dark-outline': toCSSValue('color-neutral-60', 0.4),
|
|
517
517
|
|