@massimo-cassandro/minimo 1.4.12 → 1.4.13

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,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
+ "switch": {
9
+ "background": {
10
+ "color": {
11
+ "$type": "color",
12
+ "$value": "{neutral.100}"
13
+ }
14
+ },
15
+ "cursor": {
16
+ "background": {
17
+ "color": {
18
+ "$type": "color",
19
+ "$value": "{body.background.color}"
20
+ }
21
+ }
22
+ },
23
+ "checked": {
24
+ "background": {
25
+ "color": {
26
+ "$type": "color",
27
+ "$value": "{primary.100}"
28
+ }
29
+ }
30
+ }
31
+ }
32
+ }
@@ -0,0 +1,29 @@
1
+ export default {
2
+ switch: {
3
+ background: {
4
+ color: {
5
+ $value: '{neutral.100}',
6
+ $type: 'color'
7
+ }
8
+ },
9
+
10
+ cursor: {
11
+ background: {
12
+ color: {
13
+ $value: '{body.background.color}',
14
+ $type: 'color'
15
+ }
16
+ },
17
+ },
18
+
19
+ checked: {
20
+ background: {
21
+ color: {
22
+ $value: '{primary.100}',
23
+ $type: 'color'
24
+ }
25
+ },
26
+ }
27
+
28
+ }
29
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@massimo-cassandro/minimo",
3
- "version": "1.4.12",
3
+ "version": "1.4.13",
4
4
  "description": "Light css framework & utilities",
5
5
  "type": "module",
6
6
  "homepage": "https://github.com/massimo-cassandro/minimo#readme",
@@ -46,6 +46,7 @@
46
46
  "devDependencies": {
47
47
  "@massimo-cassandro/dev-updater": "^3.0.6",
48
48
  "@massimo-cassandro/eslint-config": "^3.0.9",
49
- "@massimo-cassandro/stylelint-config": "^2.3.9"
49
+ "@massimo-cassandro/stylelint-config": "^2.3.9",
50
+ "style-dictionary": "^5.4.4"
50
51
  }
51
52
  }
@@ -0,0 +1,152 @@
1
+ import { domBuilder, classnames } from '../index.js';
2
+ import { spinner } from '@minimo/spinner.js';
3
+ import * as styles from './modal-content.module.css?inline';
4
+
5
+
6
+
7
+
8
+ // https://developer.mozilla.org/en-US/docs/Web/API/HTMLDialogElement
9
+
10
+ export function modalContent({
11
+
12
+ /** iframe | content */
13
+ mode = 'iframe',
14
+
15
+ /** dialog extra class */
16
+ dialogClassName = null,
17
+
18
+ /** iframe url */
19
+ iframeUrl = null,
20
+
21
+ /** content string (markup) o array */
22
+ content = null,
23
+
24
+ /** content extra classname */
25
+ contentClassName = null,
26
+
27
+ /** dimensione modal: full, large, medium o small */
28
+ size = 'large',
29
+
30
+ /** padding: std (var(--size-md) 0) o none */
31
+ padding = 'std'
32
+ }) {
33
+
34
+ if(!['content', 'iframe'].includes(mode)) {
35
+ throw `modalContent: parametro 'mode' non corretto (${mode})`;
36
+ }
37
+ if(!iframeUrl && mode === 'iframe') {
38
+ throw 'modalContent: parametro `iframeUrl` mancante';
39
+ }
40
+ if(content == null && mode === 'content') {
41
+ throw 'modalContent: parametro `content` mancante';
42
+ }
43
+ if(!['full', 'large', 'medium', 'small'].includes(size)) {
44
+ throw `modalContent: parametro 'size' non corretto (${size})`;
45
+ }
46
+ if(!['std', 'none'].includes(padding)) {
47
+ throw `modalContent: parametro 'padding' non corretto (${padding})`;
48
+ }
49
+
50
+ let dialog_element, dialog_inner, iframe_element = null, content_element = null;
51
+ const iframeLoadEventHandler = () => {
52
+ dialog_element.classList.add(styles.on);
53
+ };
54
+
55
+ if(!dialog_element) {
56
+
57
+ domBuilder([
58
+ {
59
+ tag: 'dialog',
60
+ className: styles.dialog,
61
+ attrs: {
62
+ 'closedby': 'any'
63
+ },
64
+ children: [
65
+ {
66
+ tag: 'button',
67
+ className: styles.closeButton, // TODO standardizzare close btn
68
+ attrs: {
69
+ 'aria-label': 'Chiudi'
70
+ }
71
+ },
72
+ {
73
+ className: styles.dialogInner,
74
+ children: [
75
+ {
76
+ className: styles.modalSpinner,
77
+ content: spinner({container: null, withOverlay: false })
78
+ }
79
+
80
+ ]
81
+ }
82
+ ]
83
+ }
84
+ ], document.body);
85
+
86
+
87
+ dialog_element = document.querySelector(`.${styles.dialog}`);
88
+ dialog_inner = dialog_element.querySelector(`.${styles.dialogInner}`);
89
+
90
+ dialog_element.querySelector(`.${styles.closeButton}`).addEventListener('click', () => {
91
+ dialog_element.close();
92
+ }, false);
93
+
94
+ // listener chiusura
95
+ dialog_element.addEventListener('close', () => {
96
+
97
+ iframe_element?.removeEventListener('load', iframeLoadEventHandler, false);
98
+ iframe_element?.remove();
99
+ content_element?.remove();
100
+
101
+ document.body.classList.remove('overflow-hidden');
102
+ dialog_element.classList.remove(styles.on);
103
+ }, false);
104
+
105
+ }
106
+
107
+
108
+ // aggiunta classi extra
109
+ dialog_element.className = classnames(
110
+ styles.dialog,
111
+ dialogClassName,
112
+ styles[`size-${size}`],
113
+ styles[`padding-${padding}`]
114
+ );
115
+
116
+ domBuilder([
117
+ {
118
+ condition: mode === 'iframe',
119
+ className: styles.iframeEl,
120
+ tag: 'iframe',
121
+ attrs: {
122
+ src: ''
123
+ }
124
+ },
125
+ {
126
+ condition: mode === 'content',
127
+ className: classnames(styles.contentEl, contentClassName),
128
+ content: (content && !Array.isArray(content))? content : null,
129
+ children: (content && Array.isArray(content))? content : null
130
+ }
131
+ ], dialog_inner);
132
+
133
+
134
+ document.body.classList.add('overflow-hidden');
135
+ dialog_element.showModal();
136
+ dialog_element.focus();
137
+
138
+
139
+ if(mode === 'iframe') {
140
+ iframe_element = dialog_element.querySelector(`.${styles.iframeEl}`);
141
+ iframe_element.src = iframeUrl;
142
+
143
+ // listener load per i frame
144
+ iframe_element?.addEventListener('load', iframeLoadEventHandler, false);
145
+
146
+
147
+ } else if (mode === 'content') {
148
+ content_element = dialog_element.querySelector(`.${styles.contentEl}`);
149
+ dialog_element.classList.add(styles.on);
150
+ }
151
+
152
+ }
@@ -0,0 +1,142 @@
1
+ /* TODO custom props nel file generale */
2
+ /* TODO prevedere opzione con bordo del pulsante di chiusura (NB: si disallinea) */
3
+ /* TODO cambiare icona chiusura con svg? */
4
+ /* TODO aggiungere wrapper intorno a dialogInner (a filo con il dialog) per la scroll bar */
5
+
6
+ .dialog { /* dialog */
7
+ --modal-border-radius: var(--radius-md, 1.2rem);
8
+ position: fixed;
9
+ max-width: 80dvw;
10
+ max-height: 90dvh;
11
+ padding: 0;
12
+ margin: auto;
13
+ overflow: visible;
14
+ background-color: var(--body-bg-color, #fff);
15
+ border: none;
16
+ border-radius: var(--modal-border-radius);
17
+ box-shadow: 0 0 2rem .5rem rgb(0 0 0 / .5);
18
+ scale: 0;
19
+ transition: scale .2s ease-out;
20
+
21
+ /* stylelint-disable selector-class-pattern */
22
+ &.size-full {
23
+ width: 80dvw;
24
+ height: 90dvh;
25
+ }
26
+ /* dimensioni std -> size == 'large' */
27
+ &.size-large {
28
+ width: 50rem; /* 800px */
29
+ height: auto;
30
+ }
31
+ &.size-medium {
32
+ width: 37.5rem; /* 600px */
33
+ height: 37.5rem;
34
+ }
35
+ &.size-small {
36
+ width: 32rem; /* ~500 x 400 */
37
+ height: 25rem;
38
+ }
39
+ /* stylelint-enable selector-class-pattern */
40
+
41
+ &.on {
42
+ scale: 1;
43
+ }
44
+
45
+ &::backdrop {
46
+ overscroll-behavior: contain;
47
+ background-color: rgb(0 0 0 / .7);
48
+ }
49
+
50
+ }
51
+
52
+ .dialogInner {
53
+ width: 100%;
54
+ height: 100%;
55
+ padding-inline-end: var(--size-md);
56
+ overflow-x: hidden;
57
+ overflow-y: auto;
58
+ /* scrollbar-gutter: stable; */
59
+ border-radius: var(--modal-border-radius);
60
+
61
+ /* stylelint-disable selector-class-pattern */
62
+ .padding-std & {
63
+ padding: var(--size-md) 0;
64
+ }
65
+ .padding-none & {
66
+ padding: 0;
67
+ }
68
+ /* stylelint-enable selector-class-pattern */
69
+ }
70
+
71
+ .modalSpinner {
72
+ position: relative;
73
+ padding-block-start: var(--size-2xl);
74
+
75
+ .dialog.on & {
76
+ display: none;
77
+ }
78
+ }
79
+
80
+ .iframeEl, .contentEl {
81
+ width: 100%;
82
+ overscroll-behavior: contain;
83
+ }
84
+
85
+ .iframeEl {
86
+ height: 100%;
87
+ padding: 0;
88
+ margin: 0;
89
+ border: none;
90
+ }
91
+
92
+ .contentEl {
93
+ min-height: 100%;
94
+ }
95
+
96
+ .closeButton {
97
+ --btn-color: var(--secondary-fg, #000);
98
+ --btn-bg-color: var(--secondary, #fff);
99
+ --btn-hover-color: var(--secondary, #fff);
100
+ --btn-hover-bg-color: var(--secondary-fg, #000);
101
+ --icon-size: 2.5rem;
102
+ --btn-padding: var(--size-xs, .5rem);
103
+ --icon-bars-thickness: 3px;
104
+
105
+ position: absolute;
106
+ top: calc(-1 * var(--icon-size) / 3);
107
+ right: calc(-1 * var(--icon-size) / 3);
108
+ display: block;
109
+ width: var(--icon-size);
110
+ height: var(--icon-size);
111
+ padding: var(--btn-padding);
112
+ color: var(--btn-color);
113
+ cursor: pointer;
114
+ background-color: var(--btn-bg-color);
115
+ /* border: var(--icon-bars-thickness) solid currentColor; */
116
+ border: none;
117
+ border-radius: 50%;
118
+
119
+
120
+ &:hover {
121
+ --btn-color: var(--btn-hover-color);
122
+ --btn-bg-color: var(--btn-hover-bg-color);
123
+ }
124
+
125
+ &::before, &::after {
126
+ position: absolute;
127
+ top: 50%;
128
+ left: var(--btn-padding);
129
+ display: block;
130
+ width: calc(var(--icon-size) - (var(--btn-padding) * 2));
131
+ height: var(--icon-bars-thickness);
132
+ content: '';
133
+ background: currentColor;
134
+ }
135
+ &::before {
136
+ transform: translateY(-50%) rotate(45deg);
137
+ }
138
+ &::after {
139
+ transform: translateY(-50%) rotate(-45deg);
140
+ }
141
+ }
142
+
@@ -119,6 +119,7 @@ input[type='checkbox'] {
119
119
 
120
120
  /* da bs5 */
121
121
  /* versione con label a destra */
122
+ /* TODO rivedere. sostituire float con flex? */
122
123
  .form-check {
123
124
  display: block;
124
125
  padding-left: 1.5em;
@@ -128,7 +129,7 @@ input[type='checkbox'] {
128
129
  float: left;
129
130
  display: inline-block;
130
131
  width: auto;
131
- margin: 4px 0 0 -1.5em;
132
+ margin: 4px 0 0 -1.5em;
132
133
  }
133
134
  }
134
135
 
@@ -0,0 +1,105 @@
1
+ /* TODO completare, aggiungere focus, vedere soluzione bootstrap
2
+
3
+
4
+ .form-switch {
5
+ padding-left: $form-switch-padding-start;
6
+
7
+ .form-check-input {
8
+ --#{$prefix}form-switch-bg: #{escape-svg($form-switch-bg-image)};
9
+
10
+ width: $form-switch-width;
11
+ margin-left: $form-switch-padding-start * -1;
12
+ background-image: var(--#{$prefix}form-switch-bg);
13
+ background-position: left center;
14
+ @include border-radius($form-switch-border-radius, 0);
15
+ @include transition($form-switch-transition);
16
+
17
+ &:focus {
18
+ --#{$prefix}form-switch-bg: #{escape-svg($form-switch-focus-bg-image)};
19
+ }
20
+
21
+ &:checked {
22
+ background-position: $form-switch-checked-bg-position;
23
+
24
+ @if $enable-gradients {
25
+ --#{$prefix}form-switch-bg: #{escape-svg($form-switch-checked-bg-image)}, var(--#{$prefix}gradient);
26
+ } @else {
27
+ --#{$prefix}form-switch-bg: #{escape-svg($form-switch-checked-bg-image)};
28
+ }
29
+ }
30
+ }
31
+
32
+ &.form-check-reverse {
33
+ padding-right: $form-switch-padding-start;
34
+ padding-left: 0;
35
+
36
+ .form-check-input {
37
+ margin-right: $form-switch-padding-start * -1;
38
+ margin-left: 0;
39
+ }
40
+ }
41
+ }
42
+
43
+
44
+ */
45
+
46
+ /*
47
+ <div class="switch">
48
+ <input type="checkbox">
49
+ <span class="switch-track"></span>
50
+ <label>Abilita notifiche</label>
51
+ </div>
52
+ */
53
+
54
+ .switch {
55
+ display: inline-flex;
56
+ align-items: center;
57
+ cursor: pointer;
58
+ }
59
+
60
+ .switch input {
61
+ position: absolute;
62
+ opacity: 0;
63
+ width: 0;
64
+ height: 0;
65
+ }
66
+
67
+ .switch-track {
68
+ position: relative;
69
+ width: 2.5em;
70
+ height: 1.5em;
71
+ background-color: var(--switch-background-color);
72
+ border-radius: 1.5em;
73
+ transition: background-color 0.2s;
74
+ }
75
+
76
+ .switch label {
77
+ margin-left: .5em;
78
+ user-select: none;
79
+ }
80
+
81
+ .switch-track::after {
82
+ content: '';
83
+ position: absolute;
84
+ top: 2px;
85
+ left: 2px;
86
+ width: 2em;
87
+ height: 2em;
88
+ background: var(--switch-cursor-background-color);
89
+ border-radius: 50%;
90
+ transition: translate 0.2s;
91
+ }
92
+
93
+ .switch input:checked + .switch-track {
94
+ background-color: var(--switch-checked-background-color);
95
+ }
96
+
97
+ .switch input:checked + .switch-track::after {
98
+ translate: 20px 0;
99
+ }
100
+
101
+ /* accessibilità */
102
+ .switch input:focus-visible + .switch-track {
103
+ outline: 2px solid var(--switch-checked-background-color);
104
+ outline-offset: 2px;
105
+ }
@@ -64,6 +64,9 @@
64
64
  .mie {
65
65
  margin-inline-end: var(--size-base) !important;
66
66
  }
67
+ .mie-auto {
68
+ margin-inline-end: auto !important;
69
+ }
67
70
  .mie-xs {
68
71
  margin-inline-end: var(--size-xs) !important;
69
72
  }
package/src/css/table.css CHANGED
@@ -59,7 +59,7 @@
59
59
  vertical-align: top;
60
60
  text-align: start;
61
61
 
62
- .valign-middle & {
62
+ .valign-middle &, &.valign-middle {
63
63
  vertical-align: middle;
64
64
  }
65
65
  }
@@ -273,6 +273,9 @@
273
273
  --status-warning-border-color: var(--status-warning-color);
274
274
  --status-warning-color: #fc0;
275
275
  --status-warning-fg: #4f2900;
276
+ --switch-background-color: var(--neutral-100);
277
+ --switch-checked-background-color: var(--primary-100);
278
+ --switch-cursor-background-color: var(--body-background-color);
276
279
  --table-body-border-width: .0625rem;
277
280
  --table-body-tr-alt-bg-color: #efefef;
278
281
  --table-body-tr-hover-bg-color: #cbcbcb;
@@ -1,6 +1,6 @@
1
1
 
2
2
  // uso
3
- // throw new ValidationError('Sono presenti cicli duplicati', campiErrore );
3
+ // throw new ValidationError('Sono presenti valori duplicati', campiErrore );
4
4
 
5
5
  /*
6
6
  esempio: