@lowentry/mui 1.0.2 → 1.1.1

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.
@@ -0,0 +1 @@
1
+ import{INT_LAX as t,STRING as e,LeUtils as n}from"@lowentry/utils";var r={onSelectEnsureMinimumOffset:function(e){return(e=Math.max(0,t(e)))<=0?function(){}:function(t){t&&t.target&&(t.target.selectionEnd<e?t.target.setSelectionRange(e,e):t.target.selectionStart<e&&t.target.setSelectionRange(e,t.target.selectionEnd))}},prependHiddenChar:function(t){return(t=e(t)).startsWith("​")?t:"​"+t},purgePrependedHiddenChar:function(t){return t=e(t),n.trimStart(t,["​"," ","\t","\r","\n"])}};export{r as L};
@@ -0,0 +1 @@
1
+ function r(r,t){(null==t||t>r.length)&&(t=r.length);for(var e=0,n=Array(t);e<t;e++)n[e]=r[e];return n}function t(r,t){var e="undefined"!=typeof Symbol&&r[Symbol.iterator]||r["@@iterator"];if(!e){if(Array.isArray(r)||(e=l(r))||t&&r&&"number"==typeof r.length){e&&(r=e);var n=0,o=function(){};return{s:o,n:function(){return n>=r.length?{done:!0}:{done:!1,value:r[n++]}},e:function(r){throw r},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,a=!0,u=!1;return{s:function(){e=e.call(r)},n:function(){var r=e.next();return a=r.done,r},e:function(r){u=!0,i=r},f:function(){try{a||null==e.return||e.return()}finally{if(u)throw i}}}}function e(r,t,e){return(t=function(r){var t=function(r,t){if("object"!=typeof r||!r)return r;var e=r[Symbol.toPrimitive];if(void 0!==e){var n=e.call(r,t||"default");if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(r)}(r,"string");return"symbol"==typeof t?t:t+""}(t))in r?Object.defineProperty(r,t,{value:e,enumerable:!0,configurable:!0,writable:!0}):r[t]=e,r}function n(){return n=Object.assign?Object.assign.bind():function(r){for(var t=1;t<arguments.length;t++){var e=arguments[t];for(var n in e)({}).hasOwnProperty.call(e,n)&&(r[n]=e[n])}return r},n.apply(null,arguments)}function o(r,t){var e=Object.keys(r);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(r);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(r,t).enumerable}))),e.push.apply(e,n)}return e}function i(r){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){e(r,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(r,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(r,t,Object.getOwnPropertyDescriptor(n,t))}))}return r}function a(r,t){if(null==r)return{};var e,n,o=function(r,t){if(null==r)return{};var e={};for(var n in r)if({}.hasOwnProperty.call(r,n)){if(t.indexOf(n)>=0)continue;e[n]=r[n]}return e}(r,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(r);for(n=0;n<i.length;n++)e=i[n],t.indexOf(e)>=0||{}.propertyIsEnumerable.call(r,e)&&(o[e]=r[e])}return o}function u(r,t){return function(r){if(Array.isArray(r))return r}(r)||function(r,t){var e=null==r?null:"undefined"!=typeof Symbol&&r[Symbol.iterator]||r["@@iterator"];if(null!=e){var n,o,i,a,u=[],l=!0,f=!1;try{if(i=(e=e.call(r)).next,0===t){if(Object(e)!==e)return;l=!1}else for(;!(l=(n=i.call(e)).done)&&(u.push(n.value),u.length!==t);l=!0);}catch(r){f=!0,o=r}finally{try{if(!l&&null!=e.return&&(a=e.return(),Object(a)!==a))return}finally{if(f)throw o}}return u}}(r,t)||l(r,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function l(t,e){if(t){if("string"==typeof t)return r(t,e);var n={}.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?r(t,e):void 0}}export{t as _,n as a,i as b,a as c,u as d};
@@ -0,0 +1 @@
1
+ import{_ as e,a as t,b as r,c as n,d as o}from"../_rollupPluginBabelHelpers-c0e6c03a.js";import a from"react";import{LeRed as l}from"@lowentry/react-redux";import{IS_ARRAY as i}from"@lowentry/utils";import u from"dayjs";import{Button as c,Stack as d}from"@mui/material";import{DatePicker as m}from"@mui/x-date-pickers";import{TextField as p}from"./TextField.js";import s from"@mui/icons-material/ArrowBackIosNew";import f from"@mui/icons-material/ArrowForwardIos";import{s as v}from"../style-inject.es-1f59c1d0.js";v(".lowentry-mui--date-picker{padding:.5rem}.lowentry-mui--date-picker .lowentry-mui--date-picker--arrow-button{min-width:0;padding:6px 12px}.lowentry-mui--date-picker .lowentry-mui--date-picker--textfield{cursor:pointer!important;max-width:150px}.lowentry-mui--date-picker .lowentry-mui--date-picker--textfield .MuiInputBase-input{padding:10px 0;text-align:center}.lowentry-mui--date-picker .lowentry-mui--date-picker--textfield .MuiOutlinedInput-notchedOutline{border:0!important}.lowentry-mui--date-picker .lowentry-mui--date-picker--textfield *{cursor:pointer!important}");var w=["value","dateFormat","onChange","className","children"],y=l.memo((function(n){var o,d,m,s,f=l.useCallback((function(){var t,r;if(null!=n&&null!==(t=n.ownerState)&&void 0!==t&&t.open)return null;for(var o=null==n||null===(r=n.InputProps)||void 0===r||null===(r=r.endAdornment)||void 0===r?void 0:r.props;o;){var a,l;if(o.onClick)return o.onClick;if(null!==(a=o)&&void 0!==a&&a.children)o=o.children;else{if(i(o)){var u,c=!1,d=e(o);try{for(d.s();!(u=d.n()).done;){var m=u.value;null!=m&&m.props&&(o=m.props,c=!0)}}catch(e){d.e(e)}finally{d.f()}if(c)continue}o=null===(l=o)||void 0===l?void 0:l.props}}return null}),[null==n||null===(o=n.ownerState)||void 0===o?void 0:o.open,null==n||null===(d=n.InputProps)||void 0===d||null===(d=d.endAdornment)||void 0===d?void 0:d.props]),v=l.useCallback((function(e){e.target.selectionStart=e.target.selectionEnd,e.preventDefault()}),[]);return a.createElement(a.Fragment,null,a.createElement(c,{variant:"outlined",onClick:f},a.createElement(p,t({},n,{className:"lowentry-mui--date-picker--textfield "+(null!==(m=n.className)&&void 0!==m?m:""),variant:"outlined",value:u(n.value).format(null==n?void 0:n.dateFormat),InputProps:r(r({},null!==(s=n.InputProps)&&void 0!==s?s:{}),{},{readOnly:!0,endAdornment:null,onSelect:v,onSelectCapture:v,onMouseDown:v,onTouchStart:v,onTouchMove:v})}))))})),k=l.memo((function(e){var i=e.value,p=e.dateFormat,v=e.onChange,k=e.className;e.children;var x=n(e,w);p||(p="ddd, D MMM YYYY");var h=l.useHistoryState(!1),C=o(h,3),b=C[0],g=C[1],E=C[2],M=l.useCallback((function(){v&&v.apply(void 0,arguments)}),[v]);return a.createElement(a.Fragment,null,a.createElement(d,t({className:"lowentry-mui--date-picker "+(null!=k?k:""),direction:"row",justifyContent:"space-between",spacing:1},x),a.createElement(c,{className:"lowentry-mui--date-picker--arrow-button",variant:"text",color:"primary",onClick:function(){return M(u(i).subtract(1,"day"))}},a.createElement(s,null)),a.createElement(m,{open:b,onOpen:g,onClose:E,showDaysOutsideCurrentMonth:!0,views:["day"],format:"YYYY-MM-DD",label:"",isRequired:!0,value:i,onChange:M,slots:{textField:function(e){return l.createElement(y,r({dateFormat:p},e))},toolbar:function(e){return null}}}),a.createElement(c,{className:"lowentry-mui--date-picker--arrow-button",variant:"text",color:"primary",onClick:function(){return M(u(i).add(1,"day"))}},a.createElement(f,null))))}));export{k as DatePicker};
@@ -0,0 +1 @@
1
+ import{c as e,a as r}from"../_rollupPluginBabelHelpers-c0e6c03a.js";import o from"react";import{LeRed as l}from"@lowentry/react-redux";import{STRING as t}from"@lowentry/utils";import{Dialog as a}from"@mui/material";var n=["onClose","children"],m=l.memo((function(m){var i=m.onClose,c=m.children,s=e(m,n),u=l.useCallback((function(e,r){t(r).toLowerCase().includes("escape")&&i&&i(e,r)}),[i]);return o.createElement(o.Fragment,null,o.createElement(a,r({onClose:u},s),c))}));export{m as Dialog};
@@ -0,0 +1 @@
1
+ import{c as e,a as n,b as r}from"../_rollupPluginBabelHelpers-c0e6c03a.js";import t from"react";import{LeRed as i}from"@lowentry/react-redux";import{Backdrop as l,CircularProgress as o}from"@mui/material";import{s as a}from"../style-inject.es-1f59c1d0.js";a(".lowentry-mui--loading-spinner{color:hsla(0,0%,100%,.04)}.lowentry-mui--loading-spinner.lowentry-mui--loading-spinner--transparent{background:transparent}");var s=["type","className","sx","children"],m={},u=i.memo((function(e){var n=e.type;return i.useEffect((function(){return function(e){var n=e.type;m[n]=(m[n]||0)+1,1===m[n]&&i.trigger("lowentry-mui--loading-spinner--"+n)}({type:n}),function(){return function(e){var n=e.type;m[n]=(m[n]||1)-1,0===m[n]&&i.trigger("lowentry-mui--loading-spinner--"+n)}({type:n})}}),[]),null})),p=i.memo((function(a){var u=a.type,p=a.className,c=a.sx;a.children;var g=e(a,s);return i.useTriggerable("lowentry-mui--loading-spinner--"+u),t.createElement(t.Fragment,null,t.createElement(l,n({className:"lowentry-mui--loading-spinner lowentry-mui--loading-spinner--"+u+" "+(null!=p?p:""),sx:r({zIndex:function(e){return e.zIndex.drawer+1}},null!=c?c:{}),open:(m[u]||0)>0},g),t.createElement(o,{color:"inherit",size:"min(120px,30vw)"})))}));export{u as LoadingSpinner,p as LoadingSpinnerWidget};
@@ -0,0 +1 @@
1
+ import{c as e,d as l,a as o}from"../_rollupPluginBabelHelpers-c0e6c03a.js";import r from"react";import{LeRed as n}from"@lowentry/react-redux";import{LeUtils as a,ARRAY as i}from"@lowentry/utils";import{Button as t,Menu as c}from"@mui/material";var m=["icon","className","ref","onClick","onClose","children"],s=n.memo((function(s){var u=s.icon,p=s.className,d=s.ref,f=s.onClick,C=s.onClose,v=s.children,k=e(s,m),b=n.useRef(),y=n.useState(!1),E=l(y,2),h=E[0],w=E[1],g=n.useCallback((function(e){w(!0),f&&f(e)}),[f]),x=n.useCallback((function(e){w(!1),C&&C(e)}),[C]);return r.createElement(r.Fragment,null,r.createElement(t,o({ref:n.mergeRefs(b,d),className:"lowentry-mui--menu-button allow-mobile-hover "+(null!=p?p:""),variant:"text",color:"primary",onClick:g},k),u),r.createElement(c,{anchorEl:b.current,open:h,onClose:x},a.mapToArray(i(v),(function(e,l){var o,r;return!!e&&n.cloneElement(e,{key:l,onClick:function(){var l;w(!1),null!=e&&null!==(l=e.props)&&void 0!==l&&l.onClick&&e.props.onClick()},disabled:void 0!==(null==e||null===(o=e.props)||void 0===o?void 0:o.disabled)?e.props.disabled:!(null!=e&&null!==(r=e.props)&&void 0!==r&&r.onClick)})}))))}));export{s as MenuButton};
@@ -0,0 +1 @@
1
+ import{c as e,a as r}from"../_rollupPluginBabelHelpers-c0e6c03a.js";import t from"react";import{LeRed as o}from"@lowentry/react-redux";import{CssBaseline as m,ThemeProvider as a}from"@mui/material";import{LocalizationProvider as i}from"@mui/x-date-pickers";import{AdapterDayjs as l}from"@mui/x-date-pickers/AdapterDayjs";import{s as n}from"../style-inject.es-1f59c1d0.js";n(".lowentry-mui--mui-root{min-height:100dvh;width:100%}@media not (hover:hover),not (pointer:fine){.lowentry-mui--mui-root .MuiButtonBase-root:not(.allow-mobile-hover):hover{background-color:hsla(0,0%,100%,0)!important}}");var c=["theme","className","children"],s=o.memo((function(o){var n=o.theme,s=o.className,u=o.children,p=e(o,c);return t.createElement(t.Fragment,null,t.createElement(m,null),t.createElement(a,{theme:n},t.createElement(i,{dateAdapter:l},t.createElement("div",r({className:"lowentry-mui--mui-root "+(null!=s?s:"")},p),u))))}));export{s as MuiRoot};
@@ -0,0 +1 @@
1
+ import{c as e,d as a,b as t,a as r}from"../_rollupPluginBabelHelpers-c0e6c03a.js";import l from"react";import{LeRed as n}from"@lowentry/react-redux";import{INT_LAX_ANY as i,FLOAT_LAX as o,LeUtils as u}from"@lowentry/utils";import{TextField as s}from"./TextField.js";import{L as d}from"../LeMuiUtils-ca49f11d.js";import"@mui/material";import"../style-inject.es-1f59c1d0.js";var m=["decimals","allowZero","allowNegative","value","onChange","onRenderValue","className","inputProps","children"],p=n.memo((function(p){var c=p.decimals,v=p.allowZero,g=p.allowNegative,h=p.value,f=p.onChange,w=p.onRenderValue,x=p.className,M=p.inputProps,b=p.children,C=e(p,m);void 0===v&&(v=!0),void 0===g&&(g=!0),c=i(c,2);var P=function(e){var a=o(d.purgePrependedHiddenChar(e));return g||(a=Math.abs(a)),a=a.toFixed(c),a=u.trimEnd(u.trimEnd(a,"0"),"."),v||"0"!==a||(a=""),a},j=n.useState(P(h)),y=a(j,2),E=y[0],N=y[1];n.useEffect((function(){N(P(h))}),[h]);var F=n.useCallback((function(e){var a=e.target.value,r=d.purgePrependedHiddenChar(a),l=0,n=r.includes("-");if(""!==(r=r.replace(",",".").replace(/[^0-9.]/g,""))){l=Math.abs(o(r)),g&&n&&(l=-l);var i=l.toFixed(c+1);i=i.substring(0,i.length-1),r=!r.includes(".")||c<=0?i.split(".")[0]:r.endsWith(".")?i.split(".")[0]+".":i.substring(0,i.length-Math.max(0,c-r.split(".")[1].length)),N(r)}if(f){0!==l&&(l=c>0?Math.round(l*Math.pow(10,c))/Math.pow(10,c):Math.round(l));var u=t(t({},e),{},{target:t(t({},e.target),{},{value:l,valueText:r,valueRaw:a})});f(u)}}),[f]);return l.createElement(l.Fragment,null,l.createElement(s,r({className:"lowentry-mui--numeric-textfield "+(null!=x?x:""),type:"text",inputProps:t({inputMode:"decimal"},null!=M?M:{}),value:w?w(E):E,onChange:F},C),b))}));export{p as NumericTextField};
@@ -0,0 +1 @@
1
+ import{c as e}from"../_rollupPluginBabelHelpers-c0e6c03a.js";import r from"react";import{LeRed as t}from"@lowentry/react-redux";import{L as l}from"../LeMuiUtils-ca49f11d.js";import{NumericTextField as n}from"./NumericTextField.js";import"@lowentry/utils";import"./TextField.js";import"@mui/material";import"../style-inject.es-1f59c1d0.js";var o=["onRemove","onChange","onSelect","className","children"],a=t.memo((function(a){var m=a.onRemove,i=a.onChange,c=a.onSelect,s=a.className,u=a.children;e(a,o);var f=t.useCallback((function(e){""!==e.target.valueRaw?i&&i(e):m&&m(e)}),[m,i]),p=t.useCallback((function(e){l.onSelectEnsureMinimumOffset(1)(e),c&&c(e)}),[c]);return r.createElement(r.Fragment,null,r.createElement(n,{className:"lowentry-mui--removable-textfield lowentry-mui--removable-numeric-textfield "+(null!=s?s:""),onRenderValue:l.prependHiddenChar,onChange:f,onSelect:p},u))}));export{a as RemovableNumericTextField};
@@ -0,0 +1 @@
1
+ import{c as e,b as a,a as r}from"../_rollupPluginBabelHelpers-c0e6c03a.js";import t from"react";import{LeRed as l}from"@lowentry/react-redux";import{L as n}from"../LeMuiUtils-ca49f11d.js";import{TextField as o}from"./TextField.js";import"@lowentry/utils";import"@mui/material";import"../style-inject.es-1f59c1d0.js";var i=["className","value","onRemove","onChange","onSelect","children"],m=l.memo((function(m){var c=m.className,s=m.value,u=m.onRemove,f=m.onChange,p=m.onSelect,d=m.children,v=e(m,i),g=l.useCallback((function(e){if(""!==e.target.value){if(f){var r=a(a({},e),{},{target:a(a({},e.target),{},{value:n.purgePrependedHiddenChar(e.target.value)})});f(r)}}else u&&u(e)}),[u,f]),h=l.useCallback((function(e){n.onSelectEnsureMinimumOffset(1)(e),p&&p(e)}),[p]);return t.createElement(t.Fragment,null,t.createElement(o,r({className:"lowentry-mui--removable-textfield "+(null!=c?c:""),value:n.prependHiddenChar(s),onChange:g,onSelect:h},v),d))}));export{m as RemovableTextField};
@@ -0,0 +1 @@
1
+ import{c as e}from"../_rollupPluginBabelHelpers-c0e6c03a.js";import r from"react";import{LeRed as t}from"@lowentry/react-redux";import{Stack as l}from"@mui/material";var n=["onSubmit","disabled","sx","children"],m=t.memo((function(m){var o=m.onSubmit,a=m.disabled,i=m.sx,c=m.children,u=e(m,n),f=t.useCallback((function(e){try{e.preventDefault()}catch(e){}a&&("function"!=typeof a||a())||o&&o(e)}),[o,a]);return r.createElement(r.Fragment,null,r.createElement("form",{style:null!=i?i:{},onSubmit:f},r.createElement(l,u,c)))}));export{m as Submittable};
@@ -0,0 +1 @@
1
+ import{c as e,a as t}from"../_rollupPluginBabelHelpers-c0e6c03a.js";import r from"react";import{LeRed as l}from"@lowentry/react-redux";import{TextField as a}from"@mui/material";import{s as o}from"../style-inject.es-1f59c1d0.js";o(".lowentry-mui--textfield{cursor:auto}");var c=["className","onClick","children"],m=l.memo((function(o){var m=o.className,i=o.onClick,n=o.children,s=e(o,c),u=l.useCallback((function(e){try{e.stopPropagation()}catch(e){}i&&i(e)}),[i]);return r.createElement(r.Fragment,null,r.createElement(a,t({className:"lowentry-mui--textfield "+(null!=m?m:""),autoComplete:"off",onClick:u},s),n))}));export{m as TextField};
@@ -0,0 +1 @@
1
+ function e(e,t){void 0===t&&(t={});var d=t.insertAt;if(e&&"undefined"!=typeof document){var n=document.head||document.getElementsByTagName("head")[0],s=document.createElement("style");s.type="text/css","top"===d&&n.firstChild?n.insertBefore(s,n.firstChild):n.appendChild(s),s.styleSheet?s.styleSheet.cssText=e:s.appendChild(document.createTextNode(e))}}export{e as s};
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "@lowentry/mui",
3
- "version": "1.0.2",
3
+ "version": "1.1.1",
4
4
  "private": false,
5
5
  "type": "module",
6
+ "exports": "./dist/external/",
6
7
  "description": "Provides utilities for Material UI.",
7
8
  "author": "Low Entry",
8
9
  "license": "MIT",
@@ -19,9 +20,10 @@
19
20
  "url": "git+https://github.com/LowEntry/lowentry-js-mui.git"
20
21
  },
21
22
  "scripts": {
22
- "test": "node --check index.js"
23
+ "build": "npm exec -- rollup -c",
24
+ "test": ""
23
25
  },
24
- "dependencies": {
26
+ "peerDependencies": {
25
27
  "@emotion/react": "*",
26
28
  "@emotion/styled": "*",
27
29
  "@lowentry/react-redux": "^1",
@@ -32,5 +34,19 @@
32
34
  "@mui/x-date-pickers": "^7",
33
35
  "dayjs": "^1",
34
36
  "react": "*"
37
+ },
38
+ "devDependencies": {
39
+ "@babel/core": "^7.24.7",
40
+ "@babel/preset-env": "^7.24.7",
41
+ "@babel/preset-react": "^7.24.7",
42
+ "@rollup/plugin-commonjs": "^26.0.1",
43
+ "@rollup/plugin-node-resolve": "^15.2.3",
44
+ "@rollup/plugin-terser": "^0.4.4",
45
+ "cssnano": "^7.0.2",
46
+ "rollup": "^2.79.1",
47
+ "rollup-plugin-babel": "^4.4.0",
48
+ "rollup-plugin-delete": "^2.0.0",
49
+ "rollup-plugin-peer-deps-external": "^2.2.4",
50
+ "rollup-plugin-postcss": "^4.0.2"
35
51
  }
36
52
  }
@@ -1,30 +0,0 @@
1
- name: on push to master
2
-
3
- on:
4
- push:
5
- branches: [ master ]
6
-
7
- concurrency:
8
- group: ${{ github.event_name }}
9
-
10
- jobs:
11
- deploy:
12
- name: "Increase version and deploy"
13
- runs-on: ubuntu-latest
14
- permissions:
15
- contents: write
16
- steps:
17
- - uses: actions/checkout@v4
18
- - uses: actions/setup-node@v4
19
- with:
20
- node-version: 'lts/*'
21
- registry-url: 'https://registry.npmjs.org'
22
- #- run: npm ci
23
- - run: npm test
24
- - run: git config --global user.name "github-actions[bot]"
25
- - run: git config --global user.email "github-actions[bot]@users.noreply.github.com"
26
- - run: npm version patch -m "Upgrade to %s [skip ci]"
27
- - run: git push && git push --tags
28
- - run: npm publish --access public
29
- env:
30
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/LeMuiUtils.js DELETED
@@ -1,52 +0,0 @@
1
- import {LeUtils, STRING, INT_LAX} from '@lowentry/utils';
2
-
3
-
4
- const HIDDEN_CHAR = '\u200B';
5
-
6
-
7
- export const LeMuiUtils = {
8
- onSelectEnsureMinimumOffset:
9
- (charactersCount) =>
10
- {
11
- charactersCount = Math.max(0, INT_LAX(charactersCount));
12
- if(charactersCount <= 0)
13
- {
14
- return () =>
15
- {
16
- };
17
- }
18
-
19
- return (event) =>
20
- {
21
- if(event && event.target)
22
- {
23
- if(event.target.selectionEnd < charactersCount)
24
- {
25
- event.target.setSelectionRange(charactersCount, charactersCount);
26
- }
27
- else if(event.target.selectionStart < charactersCount)
28
- {
29
- event.target.setSelectionRange(charactersCount, event.target.selectionEnd);
30
- }
31
- }
32
- };
33
- },
34
-
35
- prependHiddenChar:
36
- (string) =>
37
- {
38
- string = STRING(string);
39
- if(string.startsWith(HIDDEN_CHAR))
40
- {
41
- return string;
42
- }
43
- return HIDDEN_CHAR + string;
44
- },
45
-
46
- purgePrependedHiddenChar:
47
- (string) =>
48
- {
49
- string = STRING(string);
50
- return LeUtils.trimStart(string, ['\u200B', ' ', '\t', '\r', '\n']);
51
- },
52
- };
package/index.js DELETED
@@ -1,10 +0,0 @@
1
- export {DatePicker} from './widgets/DatePicker.jsx';
2
- export {Dialog} from './widgets/Dialog.jsx';
3
- export {LoadingSpinner} from './widgets/LoadingSpinner.jsx';
4
- export {MenuButton} from './widgets/MenuButton.jsx';
5
- export {MuiRoot} from './widgets/MuiRoot.jsx';
6
- export {NumericTextField} from './widgets/NumericTextField.jsx';
7
- export {RemovableNumericTextField} from './widgets/RemovableNumericTextField.jsx';
8
- export {RemovableTextField} from './widgets/RemovableTextField.jsx';
9
- export {Submittable} from './widgets/Submittable.jsx';
10
- export {TextField} from './widgets/TextField.jsx';
@@ -1,32 +0,0 @@
1
- .lowentry-mui--date-picker
2
- {
3
- padding: 0.5rem;
4
- }
5
-
6
- .lowentry-mui--date-picker .lowentry-mui--date-picker--arrow-button
7
- {
8
- min-width: 0;
9
- padding: 6px 12px;
10
- }
11
-
12
- .lowentry-mui--date-picker .lowentry-mui--date-picker--textfield
13
- {
14
- max-width: 150px;
15
- cursor: pointer !important;
16
- }
17
-
18
- .lowentry-mui--date-picker .lowentry-mui--date-picker--textfield .MuiInputBase-input
19
- {
20
- text-align: center;
21
- padding: 10px 0;
22
- }
23
-
24
- .lowentry-mui--date-picker .lowentry-mui--date-picker--textfield .MuiOutlinedInput-notchedOutline
25
- {
26
- border: 0 !important;
27
- }
28
-
29
- .lowentry-mui--date-picker .lowentry-mui--date-picker--textfield *
30
- {
31
- cursor: pointer !important;
32
- }
@@ -1,111 +0,0 @@
1
- import React from 'react';
2
- import {LeRed} from '@lowentry/react-redux';
3
- import {IS_ARRAY} from '@lowentry/utils';
4
- import Dayjs from 'dayjs';
5
- import {Button, Stack} from '@mui/material';
6
- import {DatePicker as MuiDatePicker} from '@mui/x-date-pickers';
7
- import {TextField} from './TextField.jsx';
8
- import ArrowBackIosNewIcon from '@mui/icons-material/ArrowBackIosNew';
9
- import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
10
- import './DatePicker.css';
11
-
12
-
13
- const DatePickerTextField = LeRed.memo((props) =>
14
- {
15
- const onClick = LeRed.useCallback(() =>
16
- {
17
- if(props?.ownerState?.open)
18
- {
19
- return null;
20
- }
21
- let propsLoop = props?.InputProps?.endAdornment?.props;
22
- while(propsLoop)
23
- {
24
- if(propsLoop.onClick)
25
- {
26
- return propsLoop.onClick;
27
- }
28
- if(propsLoop?.children)
29
- {
30
- propsLoop = propsLoop.children;
31
- continue;
32
- }
33
- if(IS_ARRAY(propsLoop))
34
- {
35
- let continueLoop = false;
36
- for(const propsLoopItem of propsLoop)
37
- {
38
- if(propsLoopItem?.props)
39
- {
40
- propsLoop = propsLoopItem.props;
41
- continueLoop = true;
42
- }
43
- }
44
- if(continueLoop)
45
- {
46
- continue;
47
- }
48
- }
49
- propsLoop = propsLoop?.props;
50
- }
51
- return null;
52
- }, [props?.ownerState?.open, props?.InputProps?.endAdornment?.props]);
53
-
54
-
55
- const onSelect = LeRed.useCallback((event) =>
56
- {
57
- event.target.selectionStart = event.target.selectionEnd;
58
- event.preventDefault();
59
- }, []);
60
-
61
-
62
- return (<>
63
- <Button variant="outlined" onClick={onClick}>
64
- <TextField {...props} className={'lowentry-mui--date-picker--textfield ' + (props.className ?? '')} variant="outlined" value={Dayjs(props.value).format(props?.dateFormat)} InputProps={{...(props.InputProps ?? {}), readOnly:true, endAdornment:null, onSelect:onSelect, onSelectCapture:onSelect, onMouseDown:onSelect, onTouchStart:onSelect, onTouchMove:onSelect}}/>
65
- </Button>
66
- </>);
67
- });
68
-
69
-
70
- export const DatePicker = LeRed.memo(({value, dateFormat, onChange, className, children, ...props}) =>
71
- {
72
- if(!dateFormat)
73
- {
74
- dateFormat = 'ddd, D MMM YYYY';
75
- }
76
-
77
- const [datepickerOpen, openDatepicker, closeDatepicker] = LeRed.useHistoryState(false);
78
-
79
-
80
- const onChanged = LeRed.useCallback((...args) =>
81
- {
82
- if(onChange)
83
- {
84
- onChange(...args);
85
- }
86
- }, [onChange]);
87
-
88
-
89
- return (<>
90
- <Stack className={'lowentry-mui--date-picker ' + (className ?? '')} direction="row" justifyContent="space-between" spacing={1} {...props}>
91
- <Button className="lowentry-mui--date-picker--arrow-button" variant="text" color="primary" onClick={() => onChanged(Dayjs(value).subtract(1, 'day'))}><ArrowBackIosNewIcon/></Button>
92
- <MuiDatePicker
93
- open={datepickerOpen}
94
- onOpen={openDatepicker}
95
- onClose={closeDatepicker}
96
- showDaysOutsideCurrentMonth={true}
97
- views={['day']}
98
- format="YYYY-MM-DD"
99
- label=""
100
- isRequired={true}
101
- value={value}
102
- onChange={onChanged}
103
- slots={{
104
- textField:(props) => LeRed.createElement(DatePickerTextField, {dateFormat, ...props}),
105
- toolbar: (props) => null,
106
- }}
107
- />
108
- <Button className="lowentry-mui--date-picker--arrow-button" variant="text" color="primary" onClick={() => onChanged(Dayjs(value).add(1, 'day'))}><ArrowForwardIosIcon/></Button>
109
- </Stack>
110
- </>);
111
- });
@@ -1,29 +0,0 @@
1
- import React from 'react';
2
- import {LeRed} from '@lowentry/react-redux';
3
- import {STRING} from '@lowentry/utils';
4
- import {Dialog} from '@mui/material';
5
-
6
-
7
- export const Dialog = LeRed.memo(({onClose, children, ...props}) =>
8
- {
9
- const onClosed = LeRed.useCallback((event, reason) =>
10
- {
11
- if(!STRING(reason).toLowerCase().includes('escape'))
12
- {
13
- // prevent closing when clicking on the backdrop, only allow escape-key closing
14
- return;
15
- }
16
-
17
- if(onClose)
18
- {
19
- onClose(event, reason);
20
- }
21
- }, [onClose]);
22
-
23
-
24
- return (<>
25
- <Dialog onClose={onClosed} {...props}>
26
- {children}
27
- </Dialog>
28
- </>);
29
- });
@@ -1,9 +0,0 @@
1
- .lowentry-mui--loading-spinner
2
- {
3
- color: rgba(255, 255, 255, 0.04);
4
- }
5
-
6
- .lowentry-mui--loading-spinner.lowentry-mui--loading-spinner--transparent
7
- {
8
- background: rgba(0, 0, 0, 0);
9
- }
@@ -1,50 +0,0 @@
1
- import React from 'react';
2
- import {LeRed} from '@lowentry/react-redux';
3
- import {Backdrop, CircularProgress} from '@mui/material';
4
- import './LoadingSpinner.css';
5
-
6
-
7
- let loadingSpinnerCount = {};
8
- let loadingSpinnerCountNonTransparent = 0;
9
-
10
- const LoadingSpinnerGrab = ({type}) =>
11
- {
12
- loadingSpinnerCount[type] = (loadingSpinnerCount[type] || 0) + 1;
13
- if(loadingSpinnerCount[type] === 1)
14
- {
15
- LeRed.trigger('lowentry-mui--loading-spinner--' + type);
16
- }
17
- };
18
-
19
- const LoadingSpinnerRelease = ({type}) =>
20
- {
21
- loadingSpinnerCount[type] = (loadingSpinnerCount[type] || 1) - 1;
22
- if(loadingSpinnerCount[type] === 0)
23
- {
24
- LeRed.trigger('lowentry-mui--loading-spinner--' + type);
25
- }
26
- };
27
-
28
-
29
- export const LoadingSpinner = LeRed.memo(({type}) =>
30
- {
31
- LeRed.useEffect(() =>
32
- {
33
- LoadingSpinnerGrab({type});
34
- return () => LoadingSpinnerRelease({type});
35
- }, []);
36
-
37
- return null;
38
- });
39
-
40
-
41
- export const LoadingSpinnerWidget = LeRed.memo(({type, className, sx, children, ...props}) =>
42
- {
43
- LeRed.useTriggerable('lowentry-mui--loading-spinner--' + type);
44
-
45
- return (<>
46
- <Backdrop className={'lowentry-mui--loading-spinner lowentry-mui--loading-spinner--' + type + ' ' + (className ?? '')} sx={{zIndex:(theme) => theme.zIndex.drawer + 1, ...(sx ?? {})}} open={(loadingSpinnerCount[type] || 0) > 0} {...props}>
47
- <CircularProgress color="inherit" size="min(120px,30vw)"/>
48
- </Backdrop>
49
- </>);
50
- });
@@ -1,52 +0,0 @@
1
- import React from 'react';
2
- import {LeRed} from '@lowentry/react-redux';
3
- import {LeUtils, ARRAY} from '@lowentry/utils';
4
- import {Button, Menu} from '@mui/material';
5
-
6
-
7
- export const MenuButton = LeRed.memo(({icon, className, ref, onClick, onClose, children, ...props}) =>
8
- {
9
- const buttonRef = LeRed.useRef();
10
- const [open, setOpen] = LeRed.useState(false);
11
-
12
-
13
- const onClicked = LeRed.useCallback((event) =>
14
- {
15
- setOpen(true);
16
-
17
- if(onClick)
18
- {
19
- onClick(event);
20
- }
21
- }, [onClick]);
22
-
23
-
24
- const onClosed = LeRed.useCallback((event) =>
25
- {
26
- setOpen(false);
27
-
28
- if(onClose)
29
- {
30
- onClose(event);
31
- }
32
- }, [onClose]);
33
-
34
-
35
- return (<>
36
- <Button ref={LeRed.mergeRefs(buttonRef, ref)} className={'lowentry-mui--menu-button allow-mobile-hover ' + (className ?? '')} variant="text" color="primary" onClick={onClicked} {...props}>{icon}</Button>
37
- <Menu anchorEl={buttonRef.current} open={open} onClose={onClosed}>
38
- {LeUtils.mapToArray(ARRAY(children), (child, index) => !!child && LeRed.cloneElement(child, {
39
- key: index,
40
- onClick: () =>
41
- {
42
- setOpen(false);
43
- if(child?.props?.onClick)
44
- {
45
- child.props.onClick();
46
- }
47
- },
48
- disabled:(typeof child?.props?.disabled !== 'undefined') ? child.props.disabled : !child?.props?.onClick,
49
- }))}
50
- </Menu>
51
- </>);
52
- });
@@ -1,13 +0,0 @@
1
- .lowentry-mui--mui-root
2
- {
3
- width: 100%;
4
- min-height: 100dvh;
5
- }
6
-
7
- @media not (hover: hover), not (pointer: fine)
8
- {
9
- .lowentry-mui--mui-root .MuiButtonBase-root:not(.allow-mobile-hover):hover
10
- {
11
- background-color: rgba(255, 255, 255, 0) !important;
12
- }
13
- }
@@ -1,21 +0,0 @@
1
- import React from 'react';
2
- import {LeRed} from '@lowentry/react-redux';
3
- import {CssBaseline, ThemeProvider} from '@mui/material';
4
- import {LocalizationProvider} from '@mui/x-date-pickers';
5
- import {AdapterDayjs} from '@mui/x-date-pickers/AdapterDayjs';
6
- import './MuiRoot.css';
7
-
8
-
9
- export const MuiRoot = LeRed.memo(({theme, className, children, ...props}) =>
10
- {
11
- return (<>
12
- <CssBaseline/>
13
- <ThemeProvider theme={theme}>
14
- <LocalizationProvider dateAdapter={AdapterDayjs}>
15
- <div className={'lowentry-mui--mui-root ' + (className ?? '')} {...props}>
16
- {children}
17
- </div>
18
- </LocalizationProvider>
19
- </ThemeProvider>
20
- </>);
21
- });
@@ -1,116 +0,0 @@
1
- import React from 'react';
2
- import {LeRed} from '@lowentry/react-redux';
3
- import {LeUtils, FLOAT_LAX, INT_LAX_ANY} from '@lowentry/utils';
4
- import {TextField} from './TextField.jsx';
5
- import {LeMuiUtils} from '../LeMuiUtils.js';
6
-
7
-
8
- export const NumericTextField = LeRed.memo(({decimals, allowZero, allowNegative, value, onChange, onRenderValue, className, inputProps, children, ...props}) =>
9
- {
10
- if(typeof allowZero === 'undefined')
11
- {
12
- allowZero = true;
13
- }
14
- if(typeof allowNegative === 'undefined')
15
- {
16
- allowNegative = true;
17
- }
18
- decimals = INT_LAX_ANY(decimals, 2);
19
-
20
-
21
- const getVisualValue = (value) =>
22
- {
23
- let text = FLOAT_LAX(LeMuiUtils.purgePrependedHiddenChar(value));
24
- if(!allowNegative)
25
- {
26
- text = Math.abs(text);
27
- }
28
-
29
- text = text.toFixed(decimals); // rounds it
30
- text = LeUtils.trimEnd(LeUtils.trimEnd(text, '0'), '.');
31
- if(!allowZero && (text === '0'))
32
- {
33
- text = '';
34
- }
35
- return text;
36
- };
37
-
38
-
39
- const [visualValue, setVisualValue] = LeRed.useState(getVisualValue(value));
40
-
41
- LeRed.useEffect(() =>
42
- {
43
- setVisualValue(getVisualValue(value));
44
- }, [value]);
45
-
46
-
47
- const onChanged = LeRed.useCallback((event) =>
48
- {
49
- const originalTargetValue = event.target.value;
50
- const targetValue = LeMuiUtils.purgePrependedHiddenChar(originalTargetValue);
51
-
52
- let text = targetValue;
53
- let val = 0;
54
-
55
- {// visual >>
56
- const minus = text.includes('-');
57
- text = text.replace(',', '.').replace(/[^0-9.]/g, '');
58
- if(text !== '')
59
- {
60
- val = Math.abs(FLOAT_LAX(text));
61
- if(allowNegative && minus)
62
- {
63
- val = -val;
64
- }
65
-
66
- let stringVal = val.toFixed(decimals + 1); // prevents rounding (by adding an extra digit and then cutting it off)
67
- stringVal = stringVal.substring(0, stringVal.length - 1);
68
-
69
- if(!text.includes('.') || (decimals <= 0))
70
- {
71
- text = stringVal.split('.')[0];
72
- }
73
- else if(text.endsWith('.'))
74
- {
75
- text = stringVal.split('.')[0] + '.';
76
- }
77
- else
78
- {
79
- text = stringVal.substring(0, stringVal.length - Math.max(0, decimals - text.split('.')[1].length));
80
- }
81
- setVisualValue(text);
82
- }
83
- }// visual <<
84
-
85
- if(onChange)
86
- {
87
- if(val !== 0)
88
- {
89
- if(decimals > 0)
90
- {
91
- val = Math.round(val * Math.pow(10, decimals)) / Math.pow(10, decimals);
92
- }
93
- else
94
- {
95
- val = Math.round(val);
96
- }
97
- }
98
-
99
- const newEvent = {
100
- ...event,
101
- target:{
102
- ...event.target,
103
- value: val,
104
- valueText:text,
105
- valueRaw: originalTargetValue,
106
- },
107
- };
108
- onChange(newEvent);
109
- }
110
- }, [onChange]);
111
-
112
-
113
- return (<>
114
- <TextField className={'lowentry-mui--numeric-textfield ' + (className ?? '')} type="text" inputProps={{inputMode:'decimal', ...(inputProps ?? {})}} value={!!onRenderValue ? onRenderValue(visualValue) : visualValue} onChange={onChanged} {...props}>{children}</TextField>
115
- </>);
116
- });
@@ -1,40 +0,0 @@
1
- import React from 'react';
2
- import {LeRed} from '@lowentry/react-redux';
3
- import {LeMuiUtils} from '../LeMuiUtils';
4
- import {NumericTextField} from './NumericTextField.jsx';
5
-
6
-
7
- export const RemovableNumericTextField = LeRed.memo(({onRemove, onChange, onSelect, className, children, ...props}) =>
8
- {
9
- const onChanged = LeRed.useCallback((event) =>
10
- {
11
- if(event.target.valueRaw === '')
12
- {
13
- if(onRemove)
14
- {
15
- onRemove(event);
16
- }
17
- return;
18
- }
19
-
20
- if(onChange)
21
- {
22
- onChange(event);
23
- }
24
- }, [onRemove, onChange]);
25
-
26
-
27
- const onSelected = LeRed.useCallback((event) =>
28
- {
29
- LeMuiUtils.onSelectEnsureMinimumOffset(1)(event);
30
- if(onSelect)
31
- {
32
- onSelect(event);
33
- }
34
- }, [onSelect]);
35
-
36
-
37
- return (<>
38
- <NumericTextField className={'lowentry-mui--removable-textfield lowentry-mui--removable-numeric-textfield ' + (className ?? '')} onRenderValue={LeMuiUtils.prependHiddenChar} onChange={onChanged} onSelect={onSelected}>{children}</NumericTextField>
39
- </>);
40
- });
@@ -1,47 +0,0 @@
1
- import React from 'react';
2
- import {LeRed} from '@lowentry/react-redux';
3
- import {LeMuiUtils} from '../LeMuiUtils';
4
- import {TextField} from './TextField.jsx';
5
-
6
-
7
- export const RemovableTextField = LeRed.memo(({className, value, onRemove, onChange, onSelect, children, ...props}) =>
8
- {
9
- const onChanged = LeRed.useCallback((event) =>
10
- {
11
- if(event.target.value === '')
12
- {
13
- if(onRemove)
14
- {
15
- onRemove(event);
16
- }
17
- return;
18
- }
19
-
20
- if(onChange)
21
- {
22
- const newEvent = {
23
- ...event,
24
- target:{
25
- ...event.target,
26
- value:LeMuiUtils.purgePrependedHiddenChar(event.target.value),
27
- },
28
- };
29
- onChange(newEvent);
30
- }
31
- }, [onRemove, onChange]);
32
-
33
-
34
- const onSelected = LeRed.useCallback((event) =>
35
- {
36
- LeMuiUtils.onSelectEnsureMinimumOffset(1)(event);
37
- if(onSelect)
38
- {
39
- onSelect(event);
40
- }
41
- }, [onSelect]);
42
-
43
-
44
- return (<>
45
- <TextField className={'lowentry-mui--removable-textfield ' + (className ?? '')} value={LeMuiUtils.prependHiddenChar(value)} onChange={onChanged} onSelect={onSelected} {...props}>{children}</TextField>
46
- </>);
47
- });
@@ -1,40 +0,0 @@
1
- import React from 'react';
2
- import {LeRed} from '@lowentry/react-redux';
3
- import {Stack} from '@mui/material';
4
-
5
-
6
- export const Submittable = LeRed.memo(({onSubmit, disabled, sx, children, ...props}) =>
7
- {
8
- const handleSubmit = LeRed.useCallback((event) =>
9
- {
10
- try
11
- {
12
- event.preventDefault();
13
- }
14
- catch(e)
15
- {
16
- }
17
-
18
- if(disabled)
19
- {
20
- if(!(typeof disabled === 'function') || disabled())
21
- {
22
- return;
23
- }
24
- }
25
-
26
- if(onSubmit)
27
- {
28
- onSubmit(event);
29
- }
30
- }, [onSubmit, disabled]);
31
-
32
-
33
- return (<>
34
- <form style={sx ?? {}} onSubmit={handleSubmit}>
35
- <Stack {...props}>
36
- {children}
37
- </Stack>
38
- </form>
39
- </>);
40
- });
@@ -1,4 +0,0 @@
1
- .lowentry-mui--textfield
2
- {
3
- cursor: auto;
4
- }
@@ -1,29 +0,0 @@
1
- import React from 'react';
2
- import {LeRed} from '@lowentry/react-redux';
3
- import {TextField as MuiTextField} from '@mui/material';
4
- import './TextField.css';
5
-
6
-
7
- export const TextField = LeRed.memo(({className, onClick, children, ...props}) =>
8
- {
9
- const onClicked = LeRed.useCallback((event) =>
10
- {
11
- try
12
- {
13
- event.stopPropagation();
14
- }
15
- catch(e)
16
- {
17
- }
18
-
19
- if(onClick)
20
- {
21
- onClick(event);
22
- }
23
- }, [onClick]);
24
-
25
-
26
- return (<>
27
- <MuiTextField className={'lowentry-mui--textfield ' + (className ?? '')} autoComplete="off" onClick={onClicked} {...props}>{children}</MuiTextField>
28
- </>);
29
- });