@massimo-cassandro/minimo 1.18.2 → 1.18.3
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/README.md +2 -1
- package/design-tokens/tokens/{design-tokens/_src → src/components/modal-popup}/modal-popup.minimo.tokens.jsonc +48 -2
- package/design-tokens/utilities/build-tokens-src/config.mjs +5 -2
- package/design-tokens/utilities/build-tokens-src/formats/penpot.mjs +1 -1
- package/design-tokens/utilities/build-tokens-src/platforms.mjs +4 -1
- package/design-tokens/utilities/build-tokens.mjs +5 -3
- package/design-tokens/utilities/check-unresolved-custom-props.mjs +5 -2
- package/dev-tools/starter-kit/webpack.config.mjs +6 -6
- package/package.json +17 -10
- package/src/components/modal-alert/modal-alert.js +3 -1
- package/src/components/modal-popup/modal-popup.js +68 -4
- package/{design-tokens/_src → src/components/modal-popup}/modal-popup.minimo.tokens.mjs +51 -2
- package/src/components/modal-popup/modal-popup.module.css +24 -32
- package/src/custom-properties.css +21 -12
package/README.md
CHANGED
|
@@ -5,7 +5,37 @@
|
|
|
5
5
|
// Re-generate with: node build-tokens.mjs --config <path/to/config>
|
|
6
6
|
// -----------------------------------------------------------------------
|
|
7
7
|
{
|
|
8
|
-
"
|
|
8
|
+
"mpopup": {
|
|
9
|
+
"width": {
|
|
10
|
+
"$type": "dimension",
|
|
11
|
+
"$value": "max-content"
|
|
12
|
+
},
|
|
13
|
+
"min-width": {
|
|
14
|
+
"$type": "dimension",
|
|
15
|
+
"$value": "400px"
|
|
16
|
+
},
|
|
17
|
+
"max-width": {
|
|
18
|
+
"$type": "dimension",
|
|
19
|
+
"$value": "98dvw"
|
|
20
|
+
},
|
|
21
|
+
"height": {
|
|
22
|
+
"$type": "dimension",
|
|
23
|
+
"$value": "max-content"
|
|
24
|
+
},
|
|
25
|
+
"min-height": {
|
|
26
|
+
"$type": "dimension",
|
|
27
|
+
"$value": "300px"
|
|
28
|
+
},
|
|
29
|
+
"max-height": {
|
|
30
|
+
"$type": "dimension",
|
|
31
|
+
"$value": "90dvh"
|
|
32
|
+
},
|
|
33
|
+
"background": {
|
|
34
|
+
"color": {
|
|
35
|
+
"$type": "color",
|
|
36
|
+
"$value": "{body.background.color}"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
9
39
|
"drop-shadow": {
|
|
10
40
|
"$type": "shadow",
|
|
11
41
|
"$value": [
|
|
@@ -14,7 +44,7 @@
|
|
|
14
44
|
"offsetY": "0",
|
|
15
45
|
"blur": "12px",
|
|
16
46
|
"spread": "2px",
|
|
17
|
-
"color": "
|
|
47
|
+
"color": "rgb(0 0 0 / .25)"
|
|
18
48
|
}
|
|
19
49
|
]
|
|
20
50
|
},
|
|
@@ -34,6 +64,22 @@
|
|
|
34
64
|
"$value": "1.6rem"
|
|
35
65
|
}
|
|
36
66
|
},
|
|
67
|
+
"content": {
|
|
68
|
+
"padding": {
|
|
69
|
+
"$type": "dimension",
|
|
70
|
+
"$value": "{size.base} {size.sm} {size.sm}"
|
|
71
|
+
},
|
|
72
|
+
"scrollbar": {
|
|
73
|
+
"padding": {
|
|
74
|
+
"i": {
|
|
75
|
+
"end": {
|
|
76
|
+
"$type": "dimension",
|
|
77
|
+
"$value": "{size.md}"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
},
|
|
37
83
|
"header": {
|
|
38
84
|
"padding": {
|
|
39
85
|
"$type": "dimension",
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
// build-tokens-src/config.mjs
|
|
2
3
|
// Reads the --config flag from argv, imports the project config file,
|
|
3
4
|
// resolves all paths and exports them for build-tokens.mjs.
|
|
@@ -8,7 +9,7 @@
|
|
|
8
9
|
/* globals process */
|
|
9
10
|
|
|
10
11
|
import * as path from 'node:path';
|
|
11
|
-
import { pathToFileURL } from 'url';
|
|
12
|
+
import { pathToFileURL } from 'node:url';
|
|
12
13
|
|
|
13
14
|
// ---------------------------------------------------------------------------
|
|
14
15
|
// Read the --config flag
|
|
@@ -31,10 +32,11 @@ export const configDir = path.dirname(configAbsPath);
|
|
|
31
32
|
// ---------------------------------------------------------------------------
|
|
32
33
|
// Import the project config
|
|
33
34
|
// ---------------------------------------------------------------------------
|
|
34
|
-
const buildConfig = (await import(pathToFileURL(configAbsPath))).default;
|
|
35
|
+
const buildConfig = (await import(pathToFileURL(configAbsPath).href)).default;
|
|
35
36
|
|
|
36
37
|
// Helper: resolves a path relative to the config directory.
|
|
37
38
|
// Leaves already-absolute paths untouched.
|
|
39
|
+
/** @param {string} p */
|
|
38
40
|
const resolveFromConfig = (p) => path.resolve(configDir, p);
|
|
39
41
|
|
|
40
42
|
// ---------------------------------------------------------------------------
|
|
@@ -91,6 +93,7 @@ export const penpotExpressions = VALID_EXPR_MODES.includes(buildConfig.penpotExp
|
|
|
91
93
|
// ---------------------------------------------------------------------------
|
|
92
94
|
const GLOB_CHARS = /[*?{[]/;
|
|
93
95
|
|
|
96
|
+
/** @param {string} s */
|
|
94
97
|
const resolveSource = (s) => {
|
|
95
98
|
if (path.isAbsolute(s)) {
|
|
96
99
|
// Already absolute: only normalise separators (needed on Windows)
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
// original expression is kept with a warning.
|
|
33
33
|
|
|
34
34
|
import StyleDictionary from 'style-dictionary';
|
|
35
|
-
import path from 'path';
|
|
35
|
+
import path from 'node:path';
|
|
36
36
|
|
|
37
37
|
// Disclaimer prepended to every generated file when penpotFormat is 'jsonc'
|
|
38
38
|
const DISCLAIMER = [
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
import { buildPenpotFiles } from './formats/penpot.mjs';
|
|
8
8
|
|
|
9
|
+
/** @typedef {import('style-dictionary/types').PlatformConfig} PlatformConfig */
|
|
10
|
+
|
|
9
11
|
// Transforms applied to the CSS platform
|
|
10
12
|
const CSS_TRANSFORMS = [
|
|
11
13
|
'attribute/cti',
|
|
@@ -40,7 +42,7 @@ const PENPOT_TRANSFORMS = [
|
|
|
40
42
|
* Collected from sd.allTokens after SD initialisation.
|
|
41
43
|
* Ignored when penpotDestFile is set.
|
|
42
44
|
* @param {'keep'|'calc'|'resolve'} opts.penpotExpressions How to handle math expressions in dimension tokens.
|
|
43
|
-
* @returns {
|
|
45
|
+
* @returns {Record<string, PlatformConfig>} platforms object ready for Style Dictionary config
|
|
44
46
|
*/
|
|
45
47
|
export const buildPlatforms = ({
|
|
46
48
|
buildPath,
|
|
@@ -51,6 +53,7 @@ export const buildPlatforms = ({
|
|
|
51
53
|
penpotExpressions = 'keep',
|
|
52
54
|
concreteFilePaths = [],
|
|
53
55
|
}) => {
|
|
56
|
+
/** @type {Record<string, PlatformConfig>} */
|
|
54
57
|
const platforms = {
|
|
55
58
|
css: {
|
|
56
59
|
buildPath: buildPath + '/',
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
/// <reference types="node" />
|
|
2
3
|
/* eslint-disable no-console */
|
|
3
4
|
|
|
4
5
|
// build-tokens.mjs
|
|
@@ -15,9 +16,9 @@
|
|
|
15
16
|
import StyleDictionary from 'style-dictionary';
|
|
16
17
|
import * as path from 'node:path';
|
|
17
18
|
import { styleText } from 'node:util';
|
|
18
|
-
import { homedir } from 'os';
|
|
19
|
+
import { homedir } from 'node:os';
|
|
19
20
|
import stylelint from 'stylelint';
|
|
20
|
-
import { pathToFileURL } from 'url';
|
|
21
|
+
import { pathToFileURL } from 'node:url';
|
|
21
22
|
|
|
22
23
|
// ── 1. Configuration (args + resolved paths) ────────────────────────────────
|
|
23
24
|
import {
|
|
@@ -88,7 +89,7 @@ const sd = new StyleDictionary({
|
|
|
88
89
|
await sd.buildAllPlatforms();
|
|
89
90
|
|
|
90
91
|
// ── 9. CSS lint ───────────────────────────────────────────────────────────────
|
|
91
|
-
const stylelintConfig = await import(pathToFileURL(stylelintConfigPath)).then(m => m.default);
|
|
92
|
+
const stylelintConfig = await import(pathToFileURL(stylelintConfigPath).href).then(m => m.default);
|
|
92
93
|
|
|
93
94
|
|
|
94
95
|
await stylelint.lint({
|
|
@@ -98,6 +99,7 @@ await stylelint.lint({
|
|
|
98
99
|
});
|
|
99
100
|
|
|
100
101
|
// ── 10. Log ────────────────────────────────────────────────────────────────────
|
|
102
|
+
/** @param {string} p */
|
|
101
103
|
const short = (p) => p.replace(homedir(), '~');
|
|
102
104
|
|
|
103
105
|
console.log(styleText(['yellow'], `[build-tokens] config file : ${short(configAbsPath)}`));
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
/// <reference types="node" />
|
|
2
3
|
|
|
3
4
|
/* eslint-disable no-console */
|
|
4
5
|
|
|
@@ -13,7 +14,7 @@
|
|
|
13
14
|
|
|
14
15
|
import * as path from 'node:path';
|
|
15
16
|
import * as fs from 'node:fs';
|
|
16
|
-
import { /* fileURLToPath, */pathToFileURL } from 'url';
|
|
17
|
+
import { /* fileURLToPath, */pathToFileURL } from 'node:url';
|
|
17
18
|
// import { dirname } from 'path';
|
|
18
19
|
import { glob } from 'node:fs/promises';
|
|
19
20
|
import { styleText } from 'node:util';
|
|
@@ -52,6 +53,7 @@ async function run() {
|
|
|
52
53
|
const checkdir = path.resolve(configDir, config.dir_to_check);
|
|
53
54
|
|
|
54
55
|
// Patterns for custom properties to exclude from the unresolved check
|
|
56
|
+
/** @type {RegExp[]} */
|
|
55
57
|
const exclude = config.exclude_pattern ?? [];
|
|
56
58
|
|
|
57
59
|
// Collect all .css files in the scan directory, excluding the token file itself
|
|
@@ -88,6 +90,7 @@ async function run() {
|
|
|
88
90
|
// 4. Scan files for unresolved var() references
|
|
89
91
|
// ---------------------------------------------------------------------------
|
|
90
92
|
const usageRegex = /var\(\s*(--[a-z0-9-]+)\s*(,.*?)?\)/g;
|
|
93
|
+
/** @type {{file: string, line: number, prop: string}[]} */
|
|
91
94
|
const unresolved_props = [];
|
|
92
95
|
|
|
93
96
|
files.forEach(file => {
|
|
@@ -137,7 +140,7 @@ async function run() {
|
|
|
137
140
|
console.log(styleText(['green'], '**** DONE ****'));
|
|
138
141
|
|
|
139
142
|
} catch (err) {
|
|
140
|
-
console.log(styleText(['redBright'], err.stack));
|
|
143
|
+
console.log(styleText(['redBright'], err instanceof Error ? err.stack ?? err.message : String(err)));
|
|
141
144
|
process.exit(1);
|
|
142
145
|
}
|
|
143
146
|
}
|
|
@@ -455,14 +455,14 @@ const config = {
|
|
|
455
455
|
new webpack.BannerPlugin({
|
|
456
456
|
banner: () => {
|
|
457
457
|
|
|
458
|
-
const start_year = 2026
|
|
459
|
-
current_year = new Date().toLocaleString('en-UK', { year: 'numeric' })
|
|
460
|
-
year = [
|
|
458
|
+
const start_year = 2026
|
|
459
|
+
,current_year = new Date().toLocaleString('en-UK', { year: 'numeric' })
|
|
460
|
+
,year = [
|
|
461
461
|
start_year,
|
|
462
462
|
...(current_year > start_year? [current_year] : [])
|
|
463
|
-
].join('-')
|
|
464
|
-
|
|
465
|
-
|
|
463
|
+
].join('-')
|
|
464
|
+
,vers = packageJson.version.split('.').slice(0,-1).join('.')
|
|
465
|
+
;
|
|
466
466
|
|
|
467
467
|
return (
|
|
468
468
|
'/*!\n' +
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@massimo-cassandro/minimo",
|
|
3
|
-
"version": "1.18.
|
|
3
|
+
"version": "1.18.3",
|
|
4
4
|
"description": "Light css framework & utilities",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.js",
|
|
@@ -19,13 +19,13 @@
|
|
|
19
19
|
"access": "public"
|
|
20
20
|
},
|
|
21
21
|
"bin": {
|
|
22
|
-
"buildTokens": "
|
|
23
|
-
"checkUnresolvedProps": "
|
|
24
|
-
"update-version": "
|
|
25
|
-
"upd@m": "
|
|
26
|
-
"svgIconsTools": "
|
|
27
|
-
"create-favicons": "
|
|
28
|
-
"starter-kit": "
|
|
22
|
+
"buildTokens": "design-tokens/utilities/build-tokens.mjs",
|
|
23
|
+
"checkUnresolvedProps": "design-tokens/utilities/check-unresolved-custom-props.mjs",
|
|
24
|
+
"update-version": "dev-tools/update-version/index.mjs",
|
|
25
|
+
"upd@m": "dev-tools/upd@m/index.mjs",
|
|
26
|
+
"svgIconsTools": "dev-tools/svg-icons-tools/index.mjs",
|
|
27
|
+
"create-favicons": "dev-tools/create-favicons/index.mjs",
|
|
28
|
+
"starter-kit": "dev-tools/starter-kit/starter-install.sh"
|
|
29
29
|
},
|
|
30
30
|
"repository": {
|
|
31
31
|
"type": "git",
|
|
@@ -41,7 +41,8 @@
|
|
|
41
41
|
"test": "node --test \"test/**/*.test.mjs\"",
|
|
42
42
|
"test sideEffects tree-shaking": "node ./test/sideEffects-tree-shaking/run-test.mjs",
|
|
43
43
|
"checkJS": "npx tsc --noEmit -p jsconfig.json",
|
|
44
|
-
"checkJS ./src": "npx tsc --noEmit --allowJs --checkJs --target ES2023 --module ESNext --allowSyntheticDefaultImports --moduleResolution bundler declarations.d.ts src/**/*.js"
|
|
44
|
+
"checkJS ./src": "npx tsc --noEmit --allowJs --checkJs --target ES2023 --module ESNext --allowSyntheticDefaultImports --moduleResolution bundler declarations.d.ts src/**/*.js",
|
|
45
|
+
"check outdated": "echo '*** ROOT ***' && npm outdated --omit=peer && echo '*** DEMO ***' && npm --prefix ./demo outdated && echo '*** END ***'"
|
|
45
46
|
},
|
|
46
47
|
"license": "MIT",
|
|
47
48
|
"author": "Massimo Cassandro",
|
|
@@ -80,6 +81,7 @@
|
|
|
80
81
|
"devDependencies": {
|
|
81
82
|
"@massimo-cassandro/eslint-config": "^3.0.11",
|
|
82
83
|
"@massimo-cassandro/stylelint-config": "^2.3.11",
|
|
84
|
+
"@types/node": "^26.1.1",
|
|
83
85
|
"jsdom": "^29.1.1",
|
|
84
86
|
"style-dictionary": "^5.5.0"
|
|
85
87
|
},
|
|
@@ -90,5 +92,10 @@
|
|
|
90
92
|
"sharp": "^0.35.3",
|
|
91
93
|
"sharp-ico": "^0.1.5",
|
|
92
94
|
"svgo": "^4.0.2"
|
|
93
|
-
}
|
|
95
|
+
},
|
|
96
|
+
"directories": {
|
|
97
|
+
"doc": "docs",
|
|
98
|
+
"test": "test"
|
|
99
|
+
},
|
|
100
|
+
"keywords": []
|
|
94
101
|
}
|
|
@@ -120,7 +120,9 @@ const defaults = {
|
|
|
120
120
|
* @property {string} [cancelBtnText] - text for 'cancel' button
|
|
121
121
|
* @property {string} [cancelBtnClass] - alternative class for 'cancel' button. It replaces the default one
|
|
122
122
|
* @property {boolean} [cancelBtnFocus] - true if the cancel button should be focused when the dialog box opens. It has no effect if an extraBtn is set
|
|
123
|
-
|
|
123
|
+
*/
|
|
124
|
+
|
|
125
|
+
/**
|
|
124
126
|
* Renders and opens a modal alert dialog.
|
|
125
127
|
*
|
|
126
128
|
* Backward compatibility: legacy snake_case parameter names (`extra_class`, `heading_class`,
|
|
@@ -43,6 +43,12 @@ function closeDialog(el) {
|
|
|
43
43
|
* @param {string | null} [params.contentExtraClassName=null] - Extra class added to the content wrapper.
|
|
44
44
|
* @param {string | null} [params.headerExtraClassName=null] - Extra class added to the header wrapper.
|
|
45
45
|
* @param {string | null} [params.footerExtraClassName=null] - Extra class added to the footer wrapper.
|
|
46
|
+
* @param {string | number | null} [params.dialogWidth=null] - optional dialog width value - if set, overrides main css custom prop
|
|
47
|
+
* @param {string | number | null} [params.dialogMinWidth=null] - optional dialog min-width value - if set, overrides main css custom prop
|
|
48
|
+
* @param {string | number | null} [params.dialogMaxWidth=null] - optional dialog max-width value - if set, overrides main css custom prop
|
|
49
|
+
* @param {string | number | null} [params.dialogHeight=null] - optional dialog height value - if set, overrides main css custom prop
|
|
50
|
+
* @param {string | number | null} [params.dialogMinHeight=null] - optional dialog min-height value - if set, overrides main css custom prop
|
|
51
|
+
* @param {string | number | null} [params.dialogMaxHeight=null] - optional dialog max-height value - if set, overrides main css custom prop
|
|
46
52
|
* @param {string | null} [params.iframeUrl=null] - URL to load in an iframe.
|
|
47
53
|
* @param {string | any[] | null} [params.content=null] - Plain text, HTML, or a domBuilder array.
|
|
48
54
|
* @param {string | null} [params.ajaxUrl=null] - URL for Ajax content loading.
|
|
@@ -51,11 +57,10 @@ function closeDialog(el) {
|
|
|
51
57
|
* @param {boolean} [params.addScrollbarPadding=false] - Adds right padding to compensate for the scrollbar.
|
|
52
58
|
* @param {string | any[] | null} [params.headerContent=null] - Header content: plain text, HTML, or a domBuilder array.
|
|
53
59
|
* @param {string | any[] | null} [params.footerContent=null] - Footer content: plain text, HTML, or a domBuilder array.
|
|
60
|
+
* @param {HTMLElement | null} [params.triggerElement=null] - Optional element that triggered the popup; when set, `aria-haspopup`, `aria-controls` and `aria-expanded` are managed on it.
|
|
54
61
|
* @returns {HTMLDialogElement} The dialog element.
|
|
55
62
|
*/
|
|
56
63
|
|
|
57
|
-
// TODO attributi arua anche sul triggerm vedi ada-frontend/src/modal-dialog/modal-dialog.js
|
|
58
|
-
|
|
59
64
|
export function modalPopup({
|
|
60
65
|
|
|
61
66
|
/** dialog extra class */
|
|
@@ -64,6 +69,14 @@ export function modalPopup({
|
|
|
64
69
|
/** extra classname added to dialogInner */
|
|
65
70
|
contentExtraClassName = null,
|
|
66
71
|
|
|
72
|
+
/** optional values for maon custom props overriding */
|
|
73
|
+
dialogWidth = null,
|
|
74
|
+
dialogMinWidth = null,
|
|
75
|
+
dialogMaxWidth = null,
|
|
76
|
+
dialogHeight = null,
|
|
77
|
+
dialogMinHeight = null,
|
|
78
|
+
dialogMaxHeight = null,
|
|
79
|
+
|
|
67
80
|
/** iframe url */
|
|
68
81
|
iframeUrl = null,
|
|
69
82
|
|
|
@@ -96,8 +109,10 @@ export function modalPopup({
|
|
|
96
109
|
/** extra classname added to footer */
|
|
97
110
|
footerExtraClassName = null,
|
|
98
111
|
|
|
99
|
-
|
|
112
|
+
/** element that triggered the popup: if set, `aria-haspopup`, `aria-controls` and `aria-expanded` are managed on it */
|
|
113
|
+
triggerElement = null,
|
|
100
114
|
|
|
115
|
+
}) {
|
|
101
116
|
|
|
102
117
|
|
|
103
118
|
if(content == null && (ajaxUrl == null || ajaxCallback == null) && iframeUrl == null) {
|
|
@@ -118,15 +133,53 @@ export function modalPopup({
|
|
|
118
133
|
mode = 'iframe';
|
|
119
134
|
}
|
|
120
135
|
|
|
136
|
+
|
|
137
|
+
|
|
121
138
|
// capture for use in the ajax callback closure (ajaxUrl is non-null when mode === 'ajax')
|
|
122
139
|
const safeAjaxUrl = /** @type {string} */ (ajaxUrl);
|
|
123
140
|
|
|
141
|
+
// fine tuning custom props
|
|
142
|
+
/** @type {Record<string, string | number | null>} */
|
|
143
|
+
const cpropsValues = {
|
|
144
|
+
dialogWidth,
|
|
145
|
+
dialogMinWidth,
|
|
146
|
+
dialogMaxWidth,
|
|
147
|
+
dialogHeight,
|
|
148
|
+
dialogMinHeight,
|
|
149
|
+
dialogMaxHeight,
|
|
150
|
+
};
|
|
151
|
+
/** @type {Record<string, string>} */
|
|
152
|
+
const cpropsMap = {
|
|
153
|
+
dialogWidth : '--mpopup-width',
|
|
154
|
+
dialogMinWidth : '--mpopup-min-width',
|
|
155
|
+
dialogMaxWidth : '--mpopup-max-width',
|
|
156
|
+
dialogHeight : '--mpopup-height',
|
|
157
|
+
dialogMinHeight : '--mpopup-min-height',
|
|
158
|
+
dialogMaxHeight : '--mpopup-max-height'
|
|
159
|
+
};
|
|
160
|
+
/** @type {string[]} */
|
|
161
|
+
let dialogStyle = [];
|
|
162
|
+
Object.keys(cpropsMap).forEach(item => {
|
|
163
|
+
if(cpropsValues[item] != null) {
|
|
164
|
+
const value = typeof cpropsValues[item] === 'number' ? `${cpropsValues[item]}px` : cpropsValues[item];
|
|
165
|
+
dialogStyle.push(`${cpropsMap[item]}: ${value}`);
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// ids for aria-controls (trigger → dialog) and aria-labelledby (dialog → header), generated only when needed
|
|
170
|
+
const dialogId = triggerElement != null ? `mpopup-${crypto.randomUUID()}` : null;
|
|
171
|
+
const headerId = headerContent != null ? `mpopup-header-${crypto.randomUUID()}` : null;
|
|
172
|
+
|
|
124
173
|
domBuilder([
|
|
125
174
|
{
|
|
126
175
|
tag: 'dialog',
|
|
176
|
+
id: dialogId,
|
|
127
177
|
className: classnames(styles.dialog, dialogExtraClassName, addScrollbarPadding && styles.scrollBarPadding),
|
|
128
178
|
attrs: {
|
|
129
|
-
|
|
179
|
+
closedby: 'any',
|
|
180
|
+
'aria-modal': 'true',
|
|
181
|
+
'aria-labelledby': headerId,
|
|
182
|
+
style: dialogStyle.length? dialogStyle.join(';') : null
|
|
130
183
|
},
|
|
131
184
|
callback: el => { dialogEl = /** @type {HTMLDialogElement} */ (el); },
|
|
132
185
|
children: [
|
|
@@ -142,6 +195,7 @@ export function modalPopup({
|
|
|
142
195
|
className: styles.contentWrapper,
|
|
143
196
|
children: [
|
|
144
197
|
{
|
|
198
|
+
id: headerId,
|
|
145
199
|
className: classnames(styles.header, headerExtraClassName),
|
|
146
200
|
condition: headerContent != null,
|
|
147
201
|
content: Array.isArray(headerContent) ? null : headerContent,
|
|
@@ -221,6 +275,10 @@ export function modalPopup({
|
|
|
221
275
|
|
|
222
276
|
document.body.classList.remove('overflow-hidden');
|
|
223
277
|
|
|
278
|
+
if(triggerElement != null) {
|
|
279
|
+
triggerElement.setAttribute('aria-expanded', 'false');
|
|
280
|
+
}
|
|
281
|
+
|
|
224
282
|
if(closeCallback) {
|
|
225
283
|
closeCallback(thisDialog);
|
|
226
284
|
}
|
|
@@ -229,6 +287,12 @@ export function modalPopup({
|
|
|
229
287
|
}, false);
|
|
230
288
|
|
|
231
289
|
|
|
290
|
+
if(triggerElement != null) {
|
|
291
|
+
triggerElement.setAttribute('aria-haspopup', 'dialog');
|
|
292
|
+
triggerElement.setAttribute('aria-controls', /** @type {string} */ (dialogId));
|
|
293
|
+
triggerElement.setAttribute('aria-expanded', 'true');
|
|
294
|
+
}
|
|
295
|
+
|
|
232
296
|
document.body.classList.add('overflow-hidden');
|
|
233
297
|
thisDialog.showModal();
|
|
234
298
|
thisDialog.focus();
|
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
export default {
|
|
2
|
-
'
|
|
2
|
+
'mpopup': {
|
|
3
|
+
|
|
4
|
+
width: {
|
|
5
|
+
$type: 'dimension',
|
|
6
|
+
$value: 'max-content',
|
|
7
|
+
},
|
|
8
|
+
'min-width': {
|
|
9
|
+
$type: 'dimension',
|
|
10
|
+
$value: '400px',
|
|
11
|
+
},
|
|
12
|
+
'max-width': {
|
|
13
|
+
$type: 'dimension',
|
|
14
|
+
$value: '98dvw',
|
|
15
|
+
},
|
|
16
|
+
height: {
|
|
17
|
+
$type: 'dimension',
|
|
18
|
+
$value: 'max-content',
|
|
19
|
+
},
|
|
20
|
+
'min-height': {
|
|
21
|
+
$type: 'dimension',
|
|
22
|
+
$value: '300px',
|
|
23
|
+
},
|
|
24
|
+
'max-height': {
|
|
25
|
+
$type: 'dimension',
|
|
26
|
+
$value: '90dvh',
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
background: {
|
|
30
|
+
color: {
|
|
31
|
+
$type: 'color',
|
|
32
|
+
$value: '{body.background.color}',
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
|
|
3
36
|
'drop-shadow': {
|
|
4
37
|
$type: 'shadow',
|
|
5
38
|
$value: [
|
|
@@ -8,7 +41,7 @@ export default {
|
|
|
8
41
|
offsetY: '0',
|
|
9
42
|
blur: '12px',
|
|
10
43
|
spread: '2px',
|
|
11
|
-
color: '
|
|
44
|
+
color: 'rgb(0 0 0 / .25)'
|
|
12
45
|
}
|
|
13
46
|
]
|
|
14
47
|
},
|
|
@@ -30,6 +63,22 @@ export default {
|
|
|
30
63
|
}
|
|
31
64
|
|
|
32
65
|
},
|
|
66
|
+
content: {
|
|
67
|
+
padding: {
|
|
68
|
+
$type: 'dimension',
|
|
69
|
+
$value: '{size.base} {size.sm} {size.sm}',
|
|
70
|
+
},
|
|
71
|
+
scrollbar: {
|
|
72
|
+
padding: {
|
|
73
|
+
i: {
|
|
74
|
+
end: {
|
|
75
|
+
$type: 'dimension',
|
|
76
|
+
$value: '{size.md}',
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
},
|
|
33
82
|
header: {
|
|
34
83
|
padding: {
|
|
35
84
|
$type: 'dimension',
|
|
@@ -1,12 +1,4 @@
|
|
|
1
1
|
/*! minimo - Modal Popup */
|
|
2
|
-
/*
|
|
3
|
-
NB:
|
|
4
|
-
`--modal-popup-width` and `--modal-popup-height` are used with a fallback value,
|
|
5
|
-
but can be set to the desired value on a case-by-case basis.
|
|
6
|
-
|
|
7
|
-
Same for min/max-width and min/max-height
|
|
8
|
-
|
|
9
|
-
*/
|
|
10
2
|
|
|
11
3
|
.dialog {
|
|
12
4
|
|
|
@@ -15,25 +7,25 @@ Same for min/max-width and min/max-height
|
|
|
15
7
|
display: flex;
|
|
16
8
|
flex-direction: column;
|
|
17
9
|
|
|
18
|
-
width: var(--
|
|
19
|
-
min-width: var(--
|
|
20
|
-
max-width: var(--
|
|
21
|
-
height: var(--
|
|
22
|
-
min-height: var(--
|
|
23
|
-
max-height: var(--
|
|
10
|
+
width: var(--mpopup-width);
|
|
11
|
+
min-width: var(--mpopup-min-width);
|
|
12
|
+
max-width: var(--mpopup-max-width);
|
|
13
|
+
height: var(--mpopup-height);
|
|
14
|
+
min-height: var(--mpopup-min-height);
|
|
15
|
+
max-height: var(--mpopup-max-height);
|
|
24
16
|
padding: 0;
|
|
25
17
|
margin: auto;
|
|
26
18
|
overflow: visible;
|
|
27
|
-
background-color: var(--
|
|
19
|
+
background-color: var(--mpopup-background-color);
|
|
28
20
|
border: none;
|
|
29
|
-
border-radius: var(--
|
|
30
|
-
box-shadow: var(--
|
|
21
|
+
border-radius: var(--mpopup-border-radius);
|
|
22
|
+
box-shadow: var(--mpopup-drop-shadow);
|
|
31
23
|
scale: 0;
|
|
32
24
|
transition: scale .2s ease-out;
|
|
33
25
|
|
|
34
26
|
&::backdrop {
|
|
35
27
|
overscroll-behavior: contain;
|
|
36
|
-
background-color: var(--
|
|
28
|
+
background-color: var(--mpopup-backdrop-color);
|
|
37
29
|
}
|
|
38
30
|
|
|
39
31
|
&.on {
|
|
@@ -45,8 +37,8 @@ Same for min/max-width and min/max-height
|
|
|
45
37
|
.closeButton {
|
|
46
38
|
|
|
47
39
|
position: absolute;
|
|
48
|
-
top: calc(-1 * var(--
|
|
49
|
-
right: calc(-1 * var(--
|
|
40
|
+
top: calc(-1 * var(--mpopup-btn-close-size) / 3);
|
|
41
|
+
right: calc(-1 * var(--mpopup-btn-close-size) / 3);
|
|
50
42
|
}
|
|
51
43
|
|
|
52
44
|
.contentWrapper {
|
|
@@ -65,13 +57,13 @@ Same for min/max-width and min/max-height
|
|
|
65
57
|
/* width: 100%;
|
|
66
58
|
height: 100%; */
|
|
67
59
|
min-height: 0;
|
|
68
|
-
padding: var(--
|
|
60
|
+
padding: var(--mpopup-content-padding);
|
|
69
61
|
overflow-x: hidden;
|
|
70
62
|
overflow-y: auto;
|
|
71
63
|
scrollbar-gutter: stable;
|
|
72
64
|
|
|
73
65
|
.scrollBarPadding & {
|
|
74
|
-
padding-inline-end: var(--
|
|
66
|
+
padding-inline-end: var(--mpopup-content-scrollbar-padding-i-end);
|
|
75
67
|
}
|
|
76
68
|
|
|
77
69
|
}
|
|
@@ -86,18 +78,18 @@ Same for min/max-width and min/max-height
|
|
|
86
78
|
}
|
|
87
79
|
|
|
88
80
|
.header {
|
|
89
|
-
padding: var(--
|
|
90
|
-
font-size: var(--
|
|
91
|
-
color: var(--
|
|
92
|
-
background-color: var(--
|
|
93
|
-
border-radius: var(--
|
|
81
|
+
padding: var(--mpopup-header-padding);
|
|
82
|
+
font-size: var(--mpopup-header-font-size);
|
|
83
|
+
color: var(--mpopup-header-color);
|
|
84
|
+
background-color: var(--mpopup-header-background-color);
|
|
85
|
+
border-radius: var(--mpopup-border-radius) var(--mpopup-border-radius) 0 0;
|
|
94
86
|
}
|
|
95
87
|
.footer {
|
|
96
|
-
padding: var(--
|
|
97
|
-
font-size: var(--
|
|
98
|
-
color: var(--
|
|
99
|
-
background-color: var(--
|
|
100
|
-
border-radius: 0 0 var(--
|
|
88
|
+
padding: var(--mpopup-footer-padding);
|
|
89
|
+
font-size: var(--mpopup-footer-font-size);
|
|
90
|
+
color: var(--mpopup-footer-color);
|
|
91
|
+
background-color: var(--mpopup-footer-background-color);
|
|
92
|
+
border-radius: 0 0 var(--mpopup-border-radius) var(--mpopup-border-radius);
|
|
101
93
|
}
|
|
102
94
|
|
|
103
95
|
.header, .footer {
|
|
@@ -215,18 +215,27 @@
|
|
|
215
215
|
--malert-text-font-size: var(--font-size-base);
|
|
216
216
|
--malert-warning-bg: var(--status-warning-background-color);
|
|
217
217
|
--malert-warning-fg: var(--status-warning-fg);
|
|
218
|
-
--
|
|
219
|
-
--
|
|
220
|
-
--
|
|
221
|
-
--
|
|
222
|
-
--
|
|
223
|
-
--
|
|
224
|
-
--
|
|
225
|
-
--
|
|
226
|
-
--
|
|
227
|
-
--
|
|
228
|
-
--
|
|
229
|
-
--
|
|
218
|
+
--mpopup-backdrop-color: rgb(0 0 0 / .6);
|
|
219
|
+
--mpopup-background-color: var(--body-background-color);
|
|
220
|
+
--mpopup-border-radius: var(--size-base);
|
|
221
|
+
--mpopup-btn-close-size: 1.6rem;
|
|
222
|
+
--mpopup-content-padding: var(--size-base) var(--size-sm) var(--size-sm);
|
|
223
|
+
--mpopup-content-scrollbar-padding-i-end: var(--size-md);
|
|
224
|
+
--mpopup-drop-shadow: 0 0 .75rem .125rem rgb(0 0 0 / .25);
|
|
225
|
+
--mpopup-footer-background-color: #ddd;
|
|
226
|
+
--mpopup-footer-color: var(--text-color);
|
|
227
|
+
--mpopup-footer-font-size: var(--font-size-base);
|
|
228
|
+
--mpopup-footer-padding: var(--size-xs);
|
|
229
|
+
--mpopup-header-background-color: #ddd;
|
|
230
|
+
--mpopup-header-color: var(--text-color);
|
|
231
|
+
--mpopup-header-font-size: var(--font-size-xl);
|
|
232
|
+
--mpopup-header-padding: var(--size-xs);
|
|
233
|
+
--mpopup-height: max-content;
|
|
234
|
+
--mpopup-max-height: 5.625rem;
|
|
235
|
+
--mpopup-max-width: 6.125rem;
|
|
236
|
+
--mpopup-min-height: 18.75rem;
|
|
237
|
+
--mpopup-min-width: 25rem;
|
|
238
|
+
--mpopup-width: max-content;
|
|
230
239
|
--neutral-100: #666;
|
|
231
240
|
--neutral-100-fg: #fff;
|
|
232
241
|
--overlay-color: rgb(0 0 0 / .6);
|