@massimo-cassandro/minimo 0.9.5 → 0.10.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.
@@ -87,7 +87,7 @@
87
87
  "background": {
88
88
  "color": {
89
89
  "$type": "color",
90
- "$value": "{link.active.background.color}"
90
+ "$value": "{btn.close.background.color}"
91
91
  }
92
92
  },
93
93
  "icon": {
@@ -63,11 +63,11 @@
63
63
  "position": {
64
64
  "top": {
65
65
  "$type": "dimension",
66
- "$value": "-.5rem"
66
+ "$value": "-0.5rem"
67
67
  },
68
68
  "right": {
69
69
  "$type": "dimension",
70
- "$value": "-.5rem"
70
+ "$value": "-0.5rem"
71
71
  },
72
72
  "bottom": {
73
73
  "$type": "dimension",
@@ -0,0 +1,32 @@
1
+ // -----------------------------------------------------------------------
2
+ // Generated file — do not edit manually.
3
+ // This file is produced by the design-token build pipeline.
4
+ // Source of truth: the token files in the project source directory.
5
+ // Re-generate with: node build-tokens.mjs --config <path/to/config>
6
+ // -----------------------------------------------------------------------
7
+ {
8
+ "snackbar": {
9
+ "font": {
10
+ "size": {
11
+ "$type": "dimension",
12
+ "$value": "{font.size.sm}"
13
+ }
14
+ },
15
+ "border": {
16
+ "radius": {
17
+ "$type": "color",
18
+ "$value": "{radius.sm}"
19
+ }
20
+ },
21
+ "text": {
22
+ "color": {
23
+ "$type": "color",
24
+ "$value": "{text.color}"
25
+ }
26
+ },
27
+ "duration": {
28
+ "$type": "duration",
29
+ "$value": "5s"
30
+ }
31
+ }
32
+ }
@@ -62,11 +62,11 @@ export default {
62
62
  position: {
63
63
  top: {
64
64
  $type: 'dimension',
65
- $value: '-.5rem'
65
+ $value: '-0.5rem'
66
66
  },
67
67
  right: {
68
68
  $type: 'dimension',
69
- $value: '-.5rem'
69
+ $value: '-0.5rem'
70
70
  },
71
71
  bottom:{
72
72
  $type: 'dimension',
@@ -49,11 +49,15 @@ const DISCLAIMER = [
49
49
 
50
50
  // Returns true if the string contains a math expression — i.e. it has at least
51
51
  // one operator (+, -, *, /) outside of a token reference ({...}).
52
+ // Negative values like "-0.5rem" or "-8px" are NOT expressions.
52
53
  const isExpression = (str) => {
53
54
  if (typeof str !== 'string') return false;
54
55
  // Strip token references, then check for operators
55
56
  const stripped = str.replace(/\{[^}]+\}/g, '0');
56
- return /[+\-*/]/.test(stripped);
57
+ // Remove leading minus (negative number) before testing for operators.
58
+ // An operator is only meaningful when it appears between two operands,
59
+ // i.e. it is preceded by a digit, closing paren, or word character.
60
+ return /[\d)]\s*[+\-*/]/.test(stripped) || /[+*/]/.test(stripped.replace(/^-/, ''));
57
61
  };
58
62
 
59
63
  // Builds a token lookup map (dot-path -> token) from the dictionary.
@@ -90,6 +90,7 @@ await sd.buildAllPlatforms();
90
90
  // ── 9. CSS lint ───────────────────────────────────────────────────────────────
91
91
  const stylelintConfig = await import(pathToFileURL(stylelintConfigPath)).then(m => m.default);
92
92
 
93
+
93
94
  await stylelint.lint({
94
95
  config: stylelintConfig,
95
96
  files: [path.join(buildPath, destFile)],
package/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export { classnames } from './src/utilities/classnames.js';
2
2
  export { domBuilder } from './src/utilities/dom-builder/dom-builder.js';
3
- export { enableSubmitBtns } from './src/utilities/enable-submit-btns.js';
3
+ export { enableSubmitBtns } from './src/utilities/enable-submit-btns.js';
4
+ export { default as modalAlert } from './src/components/modal-alert/modal-alert.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@massimo-cassandro/minimo",
3
- "version": "0.9.5",
3
+ "version": "0.10.0",
4
4
  "description": "Light css framework & utilities",
5
5
  "type": "module",
6
6
  "homepage": "https://github.com/massimo-cassandro/minimo#readme",
@@ -19,7 +19,8 @@
19
19
  "UPD-version": "npx update-version # --config=./dev-utilities.config.mjs",
20
20
  "upd@m": "npx upd@m",
21
21
  "npm-publish": "npm publish",
22
- "webpack": "NODE_ENV=development webpack serve --config ./demo/demo-src/webpack.config.mjs",
22
+ "webpack DEMO": "NODE_ENV=development webpack serve --config ./demo-src/_src/webpack.config.mjs",
23
+ "webpack DEMO build": "NODE_ENV=production webpack --config ./demo-src/_src/webpack.config.mjs",
23
24
  "build-tokens": "node ./design-tokens-utilities/build-tokens.mjs --config ./tokens-config.mjs",
24
25
  "check unresolved props": "node ./design-tokens-utilities/check-unresolved-custom-props.mjs --config ./tokens-config.mjs"
25
26
  },
@@ -1,2 +1,2 @@
1
1
  da rivedere
2
- spostare custome props nel dictionary
2
+ spostare custom props nel dictionary
@@ -0,0 +1,46 @@
1
+
2
+ @import '@massimo-cassandro/modal-alert';
3
+
4
+
5
+ .modal-alert {
6
+ --malert-success-color: var(--status-success-color);
7
+ --malert-success-color-fg: var(--status-success-fg);
8
+
9
+ --malert-info-color: var(--status-info-color);
10
+ --malert-info-color-fg: var(--status-info-fg);
11
+
12
+ --malert-warning-color: var(--status-warning-color);
13
+ --malert-warning-color-fg: var(--status-warning-fg);
14
+
15
+ --malert-danger-color: var(--status-danger-color);
16
+ --malert-danger-color-fg: var(--status-danger-fg);
17
+
18
+ --malert-confirm-color: var(--status-warning-color);
19
+ --malert-confirm-color-fg: var(--status-warning-fg);
20
+
21
+ /* --malert-marks-stroke-width: 6px; */
22
+ --malert-backdrop: rgb(0 0 0 / .3);
23
+ --malert-border-radius: var(--radius-md);
24
+ /* --malert-box-shadow: var(--box-shadow); */
25
+ --malert-heading-font-family: var(--font-family);
26
+ /* --malert-heading-line-height: */
27
+ --malert-heading-font-size: 1.8rem;
28
+ --malert-heading-font-weigth: var(--font-size-base);
29
+ --malert-body-font-family: var(--font-family);
30
+
31
+ top: 50%;
32
+ left: 50%;
33
+ translate: -50% -50%;
34
+ }
35
+
36
+
37
+
38
+ .malert-mark {
39
+ svg {
40
+ width: 7rem;
41
+ max-width: none;
42
+ height: 7rem;
43
+ fill: var(--malert-color-fg);
44
+ stroke: none;
45
+ }
46
+ }
@@ -0,0 +1,85 @@
1
+ // import './modal-alert.css'; // importato direttamente dal css principale per ottimizzarne l'uso
2
+
3
+ import modalAlert from '@massimo-cassandro/modal-alert';
4
+
5
+ import checkIcon from './svg/check-circle-duotone.svg?inline';
6
+ import infoIcon from './svg/info-duotone.svg?inline';
7
+ import confirmIcon from './svg/question-duotone.svg?inline';
8
+ import warningIcon from './svg/warning-duotone.svg?inline';
9
+ import errorIcon from './svg/x-circle-duotone.svg?inline';
10
+
11
+ const custom_defaults = {
12
+
13
+ globals: {
14
+ onOpen: () => {
15
+ document.body.classList.add('overflow-hidden');
16
+ },
17
+ onClose: () => {
18
+ document.body.classList.remove('overflow-hidden');
19
+ },
20
+ cssFile: null,
21
+ animation: true,
22
+ showMarks: true,
23
+ },
24
+
25
+ success: {
26
+ title: 'Operazione completata',
27
+ mes: null,
28
+ ok_btn_text: 'OK',
29
+ heading_class: null,
30
+ ok_btn_class: 'btn btn-success',
31
+ timer: 4000, // ms
32
+ },
33
+ error: {
34
+ title: 'Si è verificato un errore',
35
+ mes: null,
36
+ ok_btn_text: 'OK',
37
+ heading_class: null,
38
+ text_class: null,
39
+ ok_btn_class: 'btn btn-danger',
40
+ timer: null,
41
+ },
42
+ warning: {
43
+ title: 'Attenzione!',
44
+ mes: null,
45
+ ok_btn_text: 'OK',
46
+ heading_class: null,
47
+ text_class: null,
48
+ ok_btn_class: 'btn btn-warning',
49
+ timer: null,
50
+ },
51
+ info: {
52
+ title: null,
53
+ mes: null,
54
+ ok_btn_text: 'OK',
55
+ heading_class: null,
56
+ text_class: null,
57
+ ok_btn_class: 'btn btn-info',
58
+ timer: null,
59
+ },
60
+ confirm: {
61
+ title: 'Confermi?',
62
+ mes: null,
63
+ ok_btn_text: 'OK',
64
+ cancel_btn_text: 'Cancel',
65
+ cancel_focus: true, // false to give focus to the ok button
66
+ heading_class: null,
67
+ text_class: null,
68
+ ok_btn_class: 'btn btn-warning',
69
+ cancel_btn_class: 'btn btn-outline-secondary',
70
+ callback: null,
71
+ timer: null
72
+ }
73
+ };
74
+
75
+ const marks = {
76
+ success: checkIcon,
77
+ error: errorIcon,
78
+ warning: warningIcon,
79
+ info: infoIcon,
80
+ confirm: confirmIcon
81
+ };
82
+
83
+ export function mAlert(params) {
84
+ modalAlert(params, custom_defaults, marks);
85
+ }
@@ -0,0 +1,54 @@
1
+ export const defaults = {
2
+
3
+ // settings to be applied to all dialog types
4
+ // can be reassigned on single types
5
+ globals: {
6
+ onOpen: null,
7
+ onClose: null,
8
+ cssFile: null, // css file to be automatically loaded
9
+ animation: true,
10
+ showMarks: true,
11
+ callback: null,
12
+ timer: null,
13
+ mes: null,
14
+ heading_class: null,
15
+ text_class: null,
16
+
17
+ // extra btn markup, ignored on confirm
18
+ extra_btn: null,
19
+ extra_btn_selector: null,
20
+ extra_btn_focus: true
21
+ },
22
+
23
+ success: {
24
+ title: 'Operazione completata',
25
+ ok_btn_text: 'OK',
26
+ ok_btn_class: 'btn',
27
+ timer: 4000 // ms
28
+ },
29
+ error: {
30
+ title: 'Si è verificato un errore',
31
+ ok_btn_text: 'OK',
32
+ ok_btn_class: 'btn'
33
+ },
34
+ warning: {
35
+ title: 'Attenzione!',
36
+ ok_btn_text: 'OK',
37
+ ok_btn_class: 'btn'
38
+ },
39
+ info: {
40
+ title: null,
41
+ ok_btn_text: 'OK',
42
+ ok_btn_class: 'btn'
43
+ },
44
+ confirm: {
45
+ title: 'Confermi?',
46
+ use_warning_icon: false, // se true usa l'icona warning
47
+ ok_btn_text: 'OK',
48
+ cancel_btn_text: 'Annulla',
49
+ cancel_focus: true, // false to give focus to the ok button
50
+ ok_btn_class: 'btn btn-outline',
51
+ cancel_btn_class: 'btn'
52
+ }
53
+
54
+ };
@@ -0,0 +1,9 @@
1
+ /* eslint-disable quotes */
2
+
3
+ /*
4
+ This file was generated by the script `svg-to-js.mjs`
5
+ (https://github.com/massimo-cassandro/modal-alert/blob/main/src/svg/svg-to-js.mjs).
6
+ DO NOT EDIT (any changes will be overwritten)
7
+ */
8
+
9
+ export const marks = {"confirm":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 132 132\"><circle cx=\"66\" cy=\"66\" r=\"63\"/><path d=\"M44 48a21.928 21.928 0 0 1 6.443-15.556A21.931 21.931 0 0 1 66 26c12.15 0 22 9.85 22 22 0 6.14-2.668 11.543-6.573 15.683-6.514 6.91-15.363 4.47-15.363 16.065v7.935M66 105.816v-6.975\"/></svg>\n","error":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 132 132\"><circle cx=\"66\" cy=\"66\" r=\"63\"/><path d=\"M35 39l61.4 54.4m0-54.4L35 93.2\"/></svg>\n","info":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 132 132\"><circle cx=\"66\" cy=\"66\" r=\"63\"/><path d=\"M74 105l-8.6.237V45.713L56 46m9.6-13.025V26\"/></svg>\n","success":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 132 132\"><circle cx=\"66\" cy=\"66\" r=\"63\"/><path d=\"M101.4 42L52.7 90.6 31 69.3\"/></svg>\n","warning":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 132 132\"><circle cx=\"66\" cy=\"66\" r=\"63\"/><path d=\"M41.839 72.475v-37.2c0-3.852 3.143-6.975 7.02-6.975s7.02 3.123 7.02 6.975V65.5m0-30.225v-9.3c0-3.852 3.143-6.975 7.02-6.975s7.02 3.123 7.02 6.975V65.5m0-30.225c0-3.852 3.143-6.975 7.02-6.975 3.878 0 7.02 3.123 7.02 6.975V65.5m0-20.925c0-3.852 3.144-6.975 7.02-6.975 3.878 0 7.021 3.123 7.021 6.975V84.1C98 99.509 85.428 112 69.92 112h-9.36c-9.896-1.357-18.517-6.496-23.401-13.95L24.522 73.637c-2.584-3.53-1.799-8.475 1.755-11.043 3.555-2.568 8.531-1.788 11.116 1.743l4.212 8.138\"/></svg>\n"};
@@ -1,46 +1,159 @@
1
+ .modal-alert {
2
+ width: 600px;
3
+ max-width: 90vw;
4
+ padding: 0;
5
+ background-color: var(--malert-background-color, #fff);
6
+ border: none;
7
+ border-radius: var(--malert-border-radius, 6px);
1
8
 
2
- @import '@massimo-cassandro/modal-alert';
9
+ /* https://www.joshwcomeau.com/shadow-palette/ */
10
+ --default-shadow-color: 0deg 0% 0%;
11
+ --default-box-shadow:
12
+ 0 .4px 04px hsl(var(--default-shadow-color) / .15),
13
+ -.3px 3px 3.3px -.5px hsl(var(--default-shadow-color) / .15),
14
+ -.5px 6.1px 6.6px -.9px hsl(var(--default-shadow-color) / .14),
15
+ -.9px 11.2px 12.1px -1.4px hsl(var(--default-shadow-color) / .14),
16
+ -1.6px 19.5px 21.1px -1.9px hsl(var(--default-shadow-color) / .13),
17
+ -2.7px 32.7px 35.4px -2.3px hsl(var(--default-shadow-color) / .13),
18
+ -4.3px 52px 56.4px -2.8px hsl(var(--default-shadow-color) / .12);
3
19
 
20
+ box-shadow: var(--malert-box-shadow, var(--default-box-shadow));
21
+ /* box-shadow: 2px 2px 12px #000; */
4
22
 
5
- .modal-alert {
6
- --malert-success-color: var(--status-success-color);
7
- --malert-success-color-fg: var(--status-success-fg);
23
+ &::backdrop {
24
+ overscroll-behavior: contain;
25
+ background-color: var(--malert-backdrop, rgba(0 0 0 / .7));
26
+ }
8
27
 
9
- --malert-info-color: var(--status-info-color);
10
- --malert-info-color-fg: var(--status-info-fg);
28
+ &, * {
29
+ box-sizing: border-box;
30
+ }
11
31
 
12
- --malert-warning-color: var(--status-warning-color);
13
- --malert-warning-color-fg: var(--status-warning-fg);
32
+ &.modal-alert-success {
33
+ --malert-color: var(--malert-success-color, hsl(123deg 51% 33%));
34
+ --malert-color-fg: var(--malert-success-color-fg, #fff);
35
+ }
36
+ &.modal-alert-info {
37
+ --malert-color: var(--malert-info-color, hsl(201deg 98% 41%));
38
+ --malert-color-fg: var(--malert-info-color-fg, #fff);
39
+ }
40
+ &.modal-alert-warning {
41
+ --malert-color: var(--malert-warning-color, hsl(29deg 99% 40%));
42
+ --malert-color-fg: var(--malert-warning-color-fg, #fff);
43
+ }
44
+ &.modal-alert-error {
45
+ --malert-color: var(--malert-error-color, hsl(0deg 100% 40%));
46
+ --malert-color-fg: var(--malert-error-color-fg, #fff);
47
+ }
48
+ &.modal-alert-confirm {
49
+ --malert-color: var(--malert-confirm-color, hsl(277deg 72% 45%));
50
+ --malert-color-fg: var(--malert-confirm-color-fg, #fff);
51
+ }
52
+ }
14
53
 
15
- --malert-danger-color: var(--status-danger-color);
16
- --malert-danger-color-fg: var(--status-danger-fg);
54
+ .malert-inner {
55
+ display: flex;
56
+ flex-flow: column nowrap;
57
+ /* gap: .7rem; */
58
+ align-items: stretch;
59
+ justify-content: flex-start;
17
60
 
18
- --malert-confirm-color: var(--status-warning-color);
19
- --malert-confirm-color-fg: var(--status-warning-fg);
61
+ @media screen and (min-width: 600px) {
62
+ flex-direction: row;
63
+ }
64
+ }
20
65
 
21
- /* --malert-marks-stroke-width: 6px; */
22
- --malert-backdrop: rgb(0 0 0 / .3);
23
- --malert-border-radius: var(--radius-md);
24
- /* --malert-box-shadow: var(--box-shadow); */
25
- --malert-heading-font-family: var(--font-family);
26
- /* --malert-heading-line-height: */
27
- --malert-heading-font-size: 1.8rem;
28
- --malert-heading-font-weigth: var(--font-size-base);
29
- --malert-body-font-family: var(--font-family);
30
66
 
31
- top: 50%;
32
- left: 50%;
33
- translate: -50% -50%;
67
+ .malert-mark {
68
+ display: flex;
69
+ flex: 0;
70
+ align-items: center;
71
+ justify-content: center;
72
+ width: 100%;
73
+ padding: .4rem;
74
+ background-color: var(--malert-color);
75
+
76
+ svg {
77
+ width: 100px;
78
+ aspect-ratio: 1;
79
+ fill: none;
80
+ stroke: var(--malert-color-fg);
81
+ stroke-linecap: round;
82
+ stroke-linejoin: round;
83
+ stroke-width: var(--malert-marks-stroke-width, 6px);
84
+ }
85
+
86
+ @media screen and (min-width: 600px) {
87
+ flex-direction: row;
88
+ align-items: flex-start;
89
+ width: auto;
90
+ padding: 1rem;
91
+ /* svg {
92
+ width: 100px;
93
+ } */
94
+ }
34
95
  }
35
96
 
97
+ .malert-body {
98
+ display: flex;
99
+ flex: 1;
100
+ flex-flow: column nowrap;
101
+ gap: .5rem;
102
+ align-items: stretch;
103
+ justify-content: flex-start;
104
+ padding: .5rem;
36
105
 
106
+ text-align: center;
37
107
 
38
- .malert-mark {
39
- svg {
40
- width: 7rem;
41
- max-width: none;
42
- height: 7rem;
43
- fill: var(--malert-color-fg);
44
- stroke: none;
108
+ @media screen and (min-width: 600px) {
109
+ padding: 1rem;
110
+ text-align: left;
111
+ }
112
+ }
113
+
114
+ .malert-heading {
115
+ font-family: var(--malert-heading-font-family, sans-serif);
116
+ font-size: var(--malert-heading-font-size, 2rem);
117
+ font-weight: var(--malert-heading-font-weight, 700);
118
+ line-height: var(--malert-heading-line-height, 1.2);
119
+ }
120
+ .malert-text {
121
+ font-family: var(--malert-text-font-family, sans-serif);
122
+
123
+ }
124
+ .malert-btns {
125
+ display: flex;
126
+ flex-flow: column nowrap;
127
+ gap: 1rem;
128
+ align-items: center;
129
+ justify-content: flex-start;
130
+
131
+ padding-top: 1rem;
132
+ margin-top: auto;
133
+
134
+ @media screen and (min-width: 600px) {
135
+ flex-direction: row;
136
+ justify-content: space-between;
137
+ }
138
+ }
139
+
140
+
141
+ .modal-alert-animated {
142
+ transform: translateY(-500%);
143
+ animation: dialog-in .3s ease-out;
144
+
145
+ &[open] {
146
+ transform: none;
147
+ }
148
+ }
149
+
150
+ @keyframes dialog-in {
151
+ from {
152
+ opacity: 0;
153
+ transform: translateY(-50%);
154
+ }
155
+ to {
156
+ opacity: 1;
157
+ transform: translateY(0);
45
158
  }
46
159
  }
@@ -1,85 +1,169 @@
1
- // import './modal-alert.css'; // importato direttamente dal css principale per ottimizzarne l'uso
2
-
3
- import modalAlert from '@massimo-cassandro/modal-alert';
4
-
5
- import checkIcon from './svg/check-circle-duotone.svg?inline';
6
- import infoIcon from './svg/info-duotone.svg?inline';
7
- import confirmIcon from './svg/question-duotone.svg?inline';
8
- import warningIcon from './svg/warning-duotone.svg?inline';
9
- import errorIcon from './svg/x-circle-duotone.svg?inline';
10
-
11
- const custom_defaults = {
12
-
13
- globals: {
14
- onOpen: () => {
15
- document.body.classList.add('overflow-hidden');
16
- },
17
- onClose: () => {
18
- document.body.classList.remove('overflow-hidden');
19
- },
20
- cssFile: null,
21
- animation: true,
22
- showMarks: true,
23
- },
24
-
25
- success: {
26
- title: 'Operazione completata',
27
- mes: null,
28
- ok_btn_text: 'OK',
29
- heading_class: null,
30
- ok_btn_class: 'btn btn-success',
31
- timer: 4000, // ms
32
- },
33
- error: {
34
- title: 'Si è verificato un errore',
35
- mes: null,
36
- ok_btn_text: 'OK',
37
- heading_class: null,
38
- text_class: null,
39
- ok_btn_class: 'btn btn-danger',
40
- timer: null,
41
- },
42
- warning: {
43
- title: 'Attenzione!',
44
- mes: null,
45
- ok_btn_text: 'OK',
46
- heading_class: null,
47
- text_class: null,
48
- ok_btn_class: 'btn btn-warning',
49
- timer: null,
50
- },
51
- info: {
52
- title: null,
53
- mes: null,
54
- ok_btn_text: 'OK',
55
- heading_class: null,
56
- text_class: null,
57
- ok_btn_class: 'btn btn-info',
58
- timer: null,
59
- },
60
- confirm: {
61
- title: 'Confermi?',
62
- mes: null,
63
- ok_btn_text: 'OK',
64
- cancel_btn_text: 'Cancel',
65
- cancel_focus: true, // false to give focus to the ok button
66
- heading_class: null,
67
- text_class: null,
68
- ok_btn_class: 'btn btn-warning',
69
- cancel_btn_class: 'btn btn-outline-secondary',
70
- callback: null,
71
- timer: null
1
+ import { marks as default_marks } from './marks.js';
2
+ import {defaults} from './defaults.js';
3
+
4
+ // https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement
5
+
6
+ // TODO rewrite as async
7
+
8
+ export default function (params, custom_defaults = {}, marks = default_marks) {
9
+
10
+ try {
11
+
12
+ // garbage collection
13
+ let dialog = document.querySelector('.modal-alert');
14
+ if(dialog) {
15
+ dialog.remove();
16
+ }
17
+
18
+
19
+ params = {
20
+ ...(defaults.globals?? {}),
21
+ ...(custom_defaults.globals?? {}),
22
+ ...(defaults[params.type]?? {}),
23
+ ...(custom_defaults[params.type]?? {}),
24
+ ...params
25
+ };
26
+
27
+ // per compatibilità
28
+ if(params.type === 'danger') {
29
+ params.type = 'error';
30
+ }
31
+
32
+ if(!params.type || Object.keys(defaults).filter(item => item !== 'global').indexOf(params.type) === -1) {
33
+ throw 'Missing or incorrect `type` parameter';
34
+ }
35
+
36
+ if(params.callback && typeof params.callback !== 'function') {
37
+ throw 'Incorrect `callback` parameter';
38
+ }
39
+ if(params.onOpen && typeof params.onOpen !== 'function') {
40
+ throw 'Incorrect `onOpen` parameter';
41
+ }
42
+ if(params.onClose && typeof params.onClose !== 'function') {
43
+ throw 'Incorrect `onClose` parameter';
44
+ }
45
+ if(params.extra_btn && !params.extra_btn_selector) {
46
+ throw 'Incorrect `extra_btn` parameter: missing `extra_btn_selector`';
47
+ }
48
+
49
+ if(params.cssFile && !document.querySelector(`link[href='${params.cssFile}']`)) {
50
+ document.head.insertAdjacentHTML('beforeend',
51
+ `<link rel="stylesheet" href="${params.cssFile}" type="text/css">`
52
+ );
53
+ }
54
+
55
+ // icona warning opzionale per confirm
56
+ let icon = marks[params.type];
57
+ if(params.type === 'confirm' && params.use_warning_icon) {
58
+ icon = marks.warning;
59
+ }
60
+
61
+
62
+ // if(!params.title) {
63
+ // throw '`title` parameter not present';
64
+ // }
65
+ const closedByAny = ['success', 'info'].indexOf(params.type) !== -1? ' closedBy="any"' : '';
66
+
67
+ document.body.insertAdjacentHTML('beforeend',
68
+ `<dialog class="modal-alert modal-alert-${params.type}${params.animation? ' modal-alert-animated' : ''}"${closedByAny}>
69
+ <div class="malert-inner">
70
+ ${params.showMarks? `<div class="malert-mark">${icon}</div>` : ''}
71
+ <div class="malert-body">
72
+ ${params.title? `<div class="malert-heading ${params.heading_class?? ''}">${params.title}</div>` : ''}
73
+ <div class="malert-text ${params.text_class?? ''}">${params.mes?? ''}</div>
74
+ <div class="malert-btns">
75
+ <button type="button" class="malert-ok ${params.ok_btn_class}">
76
+ ${params.ok_btn_text}
77
+ </button>
78
+ ${params.type === 'confirm'?
79
+ `<button type="button" class="malert-cancel ${params.cancel_btn_class}">
80
+ ${params.cancel_btn_text}
81
+ </button>`
82
+ : ''}
83
+ ${params.extra_btn?? ''}
84
+ </div>
85
+ </div>
86
+ </div>
87
+ </dialog>`
88
+ );
89
+
90
+ dialog = document.querySelector('.modal-alert');
91
+
92
+ dialog.showModal();
93
+
94
+ // btn focus
95
+ const ok_btn = dialog.querySelector('.malert-ok'),
96
+ cancel_btn = dialog.querySelector('.malert-cancel'),
97
+ extra_btn = (params.extra_btn && params.extra_btn_selector)? dialog.querySelector(params.extra_btn_selector) : null;
98
+
99
+ if(extra_btn && params.extra_btn_focus) {
100
+ extra_btn.focus();
101
+
102
+ } else if(cancel_btn && params.cancel_focus) { // confirm
103
+ cancel_btn.focus();
104
+
105
+ } else {
106
+ ok_btn?.focus();
107
+ }
108
+
109
+ if(params.onOpen && typeof params.onOpen === 'function') {
110
+ params.onOpen();
111
+ }
112
+
113
+ let timeoutID;
114
+
115
+ const dialogDismiss = (btn) => {
116
+ dialog.remove();
117
+
118
+ if(params.onClose && typeof params.onClose === 'function') {
119
+ params.onClose();
120
+ }
121
+
122
+ // If present, the callback argument is `btn.dataset.malertResult`
123
+ // Otherwise, if the modal type is `confirm`, it is `true` for the OK button, `false` for the Cancel button
124
+ // Otherwise, for all other modal types, it is `undefined`
125
+ if(params.callback && typeof params.callback === 'function') {
126
+ let arg;
127
+ if(btn) {
128
+ if(btn.dataset?.malertResult) {
129
+ arg = btn.dataset.malertResult;
130
+
131
+ } else if(params.type === 'confirm') {
132
+ arg = btn.classList.contains('malert-ok');
133
+ }
134
+ } else {
135
+ arg = undefined;
136
+ }
137
+
138
+ params.callback(arg);
139
+ }
140
+
141
+ if(timeoutID) {
142
+ window.clearTimeout(timeoutID);
143
+ }
144
+ };
145
+
146
+ if( params.timer && params.type !== 'confirm') {
147
+ timeoutID = window.setTimeout( function() {
148
+ dialogDismiss();
149
+ }, params.timer);
150
+ }
151
+
152
+ dialog.addEventListener('close', () => {
153
+ dialogDismiss();
154
+ }, false);
155
+
156
+ [ok_btn, cancel_btn, ...(extra_btn? [extra_btn] : [])].forEach(btn => {
157
+
158
+ btn?.addEventListener('click', () => {
159
+ dialogDismiss(btn);
160
+ }, false);
161
+
162
+ });
163
+
164
+
165
+ } catch(e) {
166
+ console.error( e ); // eslint-disable-line
72
167
  }
73
- };
74
-
75
- const marks = {
76
- success: checkIcon,
77
- error: errorIcon,
78
- warning: warningIcon,
79
- info: infoIcon,
80
- confirm: confirmIcon
81
- };
82
-
83
- export function mAlert(params) {
84
- modalAlert(params, custom_defaults, marks);
168
+
85
169
  }
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 132 132"><circle cx="66" cy="66" r="63"/><path d="M44 48a21.928 21.928 0 0 1 6.443-15.556A21.931 21.931 0 0 1 66 26c12.15 0 22 9.85 22 22 0 6.14-2.668 11.543-6.573 15.683-6.514 6.91-15.363 4.47-15.363 16.065v7.935M66 105.816v-6.975"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 132 132"><circle cx="66" cy="66" r="63"/><path d="M35 39l61.4 54.4m0-54.4L35 93.2"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 132 132"><circle cx="66" cy="66" r="63"/><path d="M74 105l-8.6.237V45.713L56 46m9.6-13.025V26"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 132 132"><circle cx="66" cy="66" r="63"/><path d="M101.4 42L52.7 90.6 31 69.3"/></svg>
@@ -0,0 +1,26 @@
1
+ /* eslint-disable no-console */
2
+ // build a js file with all svgs as variables
3
+
4
+ import * as fs from 'fs';
5
+ import * as path from 'path';
6
+
7
+ const __dirname = new URL('.', import.meta.url).pathname
8
+ ,target_file = path.resolve(__dirname, '../marks.js')
9
+ ,marks = {};
10
+
11
+ ['confirm', 'error', 'info', 'success', 'warning'].forEach(svg => {
12
+ const svg_content = fs.readFileSync(path.resolve(__dirname, `./${svg}.svg`), 'utf8');
13
+ marks[svg] = svg_content; //.replaceAll('\'', '\\\'');
14
+ });
15
+
16
+ const content = '/* eslint-disable quotes */\n\n' +
17
+ '/*\n' +
18
+ ' This file was generated by the script `svg-to-js.mjs`\n' +
19
+ ' (https://github.com/massimo-cassandro/modal-alert/blob/main/src/svg/svg-to-js.mjs).\n' +
20
+ ' DO NOT EDIT (any changes will be overwritten)\n' +
21
+ '*/\n\n' +
22
+ 'export const marks = ' + JSON.stringify(marks) + ';';
23
+
24
+ fs.writeFileSync(target_file, content, 'utf-8');
25
+
26
+ console.log('svg-to-js: DONE');
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 132 132"><circle cx="66" cy="66" r="63"/><path d="M41.839 72.475v-37.2c0-3.852 3.143-6.975 7.02-6.975s7.02 3.123 7.02 6.975V65.5m0-30.225v-9.3c0-3.852 3.143-6.975 7.02-6.975s7.02 3.123 7.02 6.975V65.5m0-30.225c0-3.852 3.143-6.975 7.02-6.975 3.878 0 7.02 3.123 7.02 6.975V65.5m0-20.925c0-3.852 3.144-6.975 7.02-6.975 3.878 0 7.021 3.123 7.021 6.975V84.1C98 99.509 85.428 112 69.92 112h-9.36c-9.896-1.357-18.517-6.496-23.401-13.95L24.522 73.637c-2.584-3.53-1.799-8.475 1.755-11.043 3.555-2.568 8.531-1.788 11.116 1.743l4.212 8.138"/></svg>
@@ -13,7 +13,7 @@
13
13
  --body-text: var(--text-color);
14
14
  --btn-border-radius: var(--form-control-border-radius);
15
15
  --btn-border-width: var(--form-control-border-width);
16
- --btn-close-active-background-color: var(--link-active-background-color);
16
+ --btn-close-active-background-color: var(--btn-close-background-color);
17
17
  --btn-close-active-icon-color: var(--link-active-color);
18
18
  --btn-close-background-color: var(--body-background-color);
19
19
  --btn-close-border-color: var(--btn-close-icon-color);
@@ -226,6 +226,10 @@
226
226
  --size-xl: 2rem;
227
227
  --size-xs: .5rem;
228
228
  --size-xxs: .25rem;
229
+ --snackbar-border-radius: var(--radius-sm);
230
+ --snackbar-duration: 5s;
231
+ --snackbar-font-size: var(--font-size-sm);
232
+ --snackbar-text-color: var(--text-color);
229
233
  --spinner-color: var(--primary-100);
230
234
  --spinner-size: var(--size-lg);
231
235
  --spinner-stroke-width: .125rem;