@massimo-cassandro/minimo 1.32.4 → 1.33.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.
@@ -0,0 +1,283 @@
1
+ /*! minimo - json-table */
2
+
3
+ import { defaults } from './src/defaults.js';
4
+ import { resolveParams } from './src/resolve-params.js';
5
+ import { getData } from './src/get-data.js';
6
+ import { mainBuilder } from './src/main-builder.js';
7
+ import { updateInfo } from './src/update-info.js';
8
+
9
+ /** @typedef {import('./src/defaults.js').JsonTableParams} JsonTableParams */
10
+ /** @typedef {import('./src/main-builder.js').JsonTableElements} JsonTableElements */
11
+
12
+ /**
13
+ * Project-wide defaults, set via `JsonTable.setDefaults()`.
14
+ * Module-level so they are shared by every instance.
15
+ * @type {Partial<JsonTableParams>}
16
+ */
17
+ let projectDefaults = {};
18
+
19
+
20
+ /**
21
+ * `<json-table>` – HTML table generator from JSON data (inline or fetched), light DOM custom element.
22
+ *
23
+ * WORK IN PROGRESS: at this stage only the outer structure is generated (info section, search
24
+ * input, empty table with caption). Columns, rows rendering, sorting, search and pagination
25
+ * are not implemented yet.
26
+ *
27
+ * Parameters (see `src/defaults.js` → `JsonTableParams`) can be set as HTML attributes or via
28
+ * `init()`; precedence: `init()` > HTML attribute > `JsonTable.setDefaults()` > built-in default.
29
+ *
30
+ * Events: `jt:ready` (bubbles) is dispatched on the element once the structure has been built;
31
+ * `event.detail.jsonTable` is the component instance.
32
+ *
33
+ * @example
34
+ * // markup only
35
+ * // <json-table jsonurl="/api/rows.json" caption="Utenti"></json-table>
36
+ *
37
+ * @example
38
+ * // script
39
+ * import { JsonTable } from '@massimo-cassandro/minimo/src/web-components/json-table/json-table-component.js';
40
+ *
41
+ * JsonTable.setDefaults({ tableClass: 'table' }); // optional, project-wide
42
+ *
43
+ * const el = document.querySelector('json-table');
44
+ * el.addEventListener('jt:ready', e => console.log(e.detail.jsonTable.data));
45
+ * el.init({
46
+ * debug: false, // default: false
47
+ * jsonUrl: '/api/rows.json', // default: null
48
+ * jsonDataField: 'data', // default: 'data'
49
+ * data: null, // default: null (takes precedence over jsonUrl when set)
50
+ * caption: 'Utenti', // default: null
51
+ * search: true, // default: true
52
+ * searchInputClass: 'form-control', // default: 'form-control'
53
+ * tableId: null, // default: null
54
+ * tableWrapperClass: 'table-responsive', // default: 'table-responsive'
55
+ * tableClass: 'table table-bordered', // default: 'table table-bordered'
56
+ * mainWrapperExtraClass: null, // default: null
57
+ * outerInfoExtraClass: null, // default: null
58
+ * infoExtraClass: null, // default: null
59
+ * infoText: (shown, total) => `${shown} / ${total}` // default: Italian "Visualizzate N righe su M"
60
+ * });
61
+ */
62
+ export class JsonTable extends HTMLElement {
63
+
64
+ /**
65
+ * Sets project-wide defaults, shared by every instance created afterwards
66
+ * (instances already rendered are not updated). Call it once, before the instances
67
+ * are created, e.g. in a shared script. Values are merged with the previous ones.
68
+ *
69
+ * @param {Partial<JsonTableParams>} [newDefaults={}] - Parameters to override (default: {})
70
+ * @returns {void}
71
+ *
72
+ * @example
73
+ * JsonTable.setDefaults({
74
+ * searchInputClass: 'form-control form-control-sm', // default: 'form-control'
75
+ * tableClass: 'table', // default: 'table table-bordered'
76
+ * infoText: (shown, total) => `${shown} di ${total}`
77
+ * });
78
+ */
79
+ static setDefaults(newDefaults = {}) {
80
+ projectDefaults = { ...projectDefaults, ...newDefaults };
81
+ }
82
+
83
+ /**
84
+ * Clears the project-wide defaults set via `setDefaults()`.
85
+ * @returns {void}
86
+ */
87
+ static resetDefaults() {
88
+ projectDefaults = {};
89
+ }
90
+
91
+ /**
92
+ * Returns the built-in defaults merged with the project-wide ones.
93
+ * @returns {JsonTableParams}
94
+ *
95
+ * @example
96
+ * JsonTable.getDefaults().tableWrapperClass; // → 'table-responsive'
97
+ */
98
+ static getDefaults() {
99
+ return { ...defaults, ...projectDefaults };
100
+ }
101
+
102
+
103
+ constructor() {
104
+ super();
105
+ // light DOM: no attachShadow
106
+
107
+ /** @type {Partial<JsonTableParams>|null} config passed via init()/reload() */
108
+ this._config = null;
109
+ this._initCalledProgrammatically = false;
110
+ this._isConnected = false;
111
+ this._loadStarted = false;
112
+ /** incremented on every init()/reload()/destroy(): a pending _load() whose generation is stale gives up */
113
+ this._loadGeneration = 0;
114
+
115
+ /** Resolved params, available after the first load. @type {JsonTableParams|null} */
116
+ this.params = null;
117
+
118
+ /** Raw rows, available after the first load. @type {Array<Object>|null} */
119
+ this.data = null;
120
+
121
+ /** Generated elements, available after the first load. @type {JsonTableElements} */
122
+ this.elements = {};
123
+ }
124
+
125
+
126
+ // ─── Lifecycle ──────────────────────────────────────────────────────────────
127
+
128
+ connectedCallback() {
129
+ this._isConnected = true;
130
+ if (!this._loadStarted) {
131
+ this._load();
132
+ }
133
+ }
134
+
135
+ disconnectedCallback() {
136
+ this._isConnected = false;
137
+ }
138
+
139
+
140
+ // ─── Public API ─────────────────────────────────────────────────────────────
141
+
142
+ /**
143
+ * Starts the component via script, passing the configuration as an object.
144
+ * Can be called before or after the element is attached to the DOM.
145
+ *
146
+ * Parameters not included in `config` are read from the corresponding HTML attribute
147
+ * (if present), then from the project defaults, then from the built-in defaults.
148
+ * To explicitly ignore an existing attribute pass `null` in the config.
149
+ *
150
+ * @param {Partial<JsonTableParams>} [config={}] - See `JsonTableParams` (default: {})
151
+ * @returns {void}
152
+ *
153
+ * @example
154
+ * // <json-table caption="Utenti" search="false"></json-table>
155
+ * el.init({ jsonUrl: '/api/rows.json' }); // jsonUrl from script, caption and search from attributes
156
+ * el.init({ jsonUrl: '/api/rows.json', search: null }); // search → default (true), the attribute is ignored
157
+ */
158
+ init(config = {}) {
159
+ this._config = config;
160
+ this._initCalledProgrammatically = true;
161
+
162
+ // an explicit init() must always restart, even if connectedCallback already
163
+ // ran a premature _load() (e.g. when domBuilder appends the element before init())
164
+ this._loadStarted = false;
165
+ this._loadGeneration++;
166
+
167
+ if (this._isConnected) {
168
+ this._load();
169
+ }
170
+ }
171
+
172
+ /**
173
+ * Empties the component and resets its state. `init()` can be called again afterwards
174
+ * to re-initialize it with new params, without recreating the element.
175
+ * @returns {void}
176
+ */
177
+ destroy() {
178
+ this._loadStarted = false;
179
+ this._loadGeneration++;
180
+ this.elements = {};
181
+ this.data = null;
182
+ this.innerHTML = '';
183
+ }
184
+
185
+ /**
186
+ * Reloads the data and rebuilds the structure, optionally overriding some params
187
+ * (merged with the config passed to `init()`, if any).
188
+ *
189
+ * @param {Partial<JsonTableParams>} [overrides={}] - Params to override (default: {})
190
+ * @returns {Promise<void>}
191
+ *
192
+ * @example
193
+ * await el.reload(); // same source
194
+ * await el.reload({ jsonUrl: '/api/rows.json?y=2025' }); // new URL
195
+ * await el.reload({ data: [{ id: 1 }] }); // inline data (takes precedence over jsonUrl)
196
+ */
197
+ async reload(overrides = {}) {
198
+ this._config = { ...(this._config ?? {}), ...overrides };
199
+ this._loadStarted = false;
200
+ this._loadGeneration++;
201
+ await this._load();
202
+ }
203
+
204
+
205
+ // ─── Load & build ───────────────────────────────────────────────────────────
206
+
207
+ /**
208
+ * Resolves params, retrieves the data and builds the structure.
209
+ * Guarded against concurrent/stale calls via `_loadStarted` and `_loadGeneration`.
210
+ * @returns {Promise<void>}
211
+ */
212
+ async _load() {
213
+ if (this._loadStarted) {
214
+ return;
215
+ }
216
+ this._loadStarted = true;
217
+ const generation = this._loadGeneration;
218
+
219
+ const params = resolveParams(this, this._config, projectDefaults);
220
+ this.params = params;
221
+
222
+ // loading placeholder (minimo spinner)
223
+ this.innerHTML = '<div class="spinner"><span class="visually-hidden">Caricamento dati...</span></div>';
224
+
225
+ /** @type {Array<Object>|null} */
226
+ let rows = null;
227
+ let failed = false;
228
+
229
+ try {
230
+ rows = await getData(params);
231
+ } catch (err) {
232
+ failed = true;
233
+ // eslint-disable-next-line no-console
234
+ console.error(err);
235
+ }
236
+
237
+ // a newer init()/reload()/destroy() superseded this load
238
+ if (generation !== this._loadGeneration) {
239
+ return;
240
+ }
241
+
242
+ if (failed) {
243
+ this.innerHTML = '';
244
+ return;
245
+ }
246
+
247
+ if (rows === null) {
248
+ // no source: silent when created from markup without attributes (init() may follow)
249
+ if (this._initCalledProgrammatically) {
250
+ // eslint-disable-next-line no-console
251
+ console.error('[json-table] Nessuna sorgente dati: specificare `data` o `jsonUrl`.');
252
+ }
253
+ this.innerHTML = '';
254
+ return;
255
+ }
256
+
257
+ this.data = rows;
258
+ this.elements = mainBuilder(this, params);
259
+
260
+ // TODO `shown` dovrà riflettere righe filtrate/paginate quando ricerca e paginazione saranno implementate
261
+ updateInfo(this.elements, params, rows.length, rows.length);
262
+
263
+ if (params.debug) {
264
+ /* eslint-disable no-console */
265
+ console.groupCollapsed('[json-table] params, data & elements', this);
266
+ console.log('params', params);
267
+ console.log('data', rows);
268
+ console.log('elements', this.elements);
269
+ console.groupEnd();
270
+ /* eslint-enable no-console */
271
+ }
272
+
273
+ // dispatched in the next microtask so listeners registered right after init() still catch it
274
+ const event = new CustomEvent('jt:ready', { detail: { jsonTable: this }, bubbles: true });
275
+ Promise.resolve().then(() => this.dispatchEvent(event));
276
+ }
277
+
278
+ } // end component
279
+
280
+
281
+ if (!customElements.get('json-table')) {
282
+ customElements.define('json-table', JsonTable);
283
+ }
@@ -0,0 +1,57 @@
1
+ /*! minimo - json-table */
2
+
3
+ /* Custom properties (`--jt-*`) are defined in `json-table.minimo.tokens.mjs`
4
+ and compiled into minimo's custom-properties.css by build-tokens */
5
+
6
+ /* purgecss start ignore */
7
+
8
+ json-table {
9
+ display: block;
10
+ }
11
+
12
+ .wrapper {
13
+ position: relative;
14
+ display: block;
15
+ margin-block: var(--jt-wrapper-margin-block);
16
+ }
17
+
18
+ .infoOuter {
19
+ padding-block-end: var(--jt-info-outer-padding-block-end);
20
+ }
21
+
22
+ .info {
23
+ display: flex;
24
+ flex-flow: column wrap;
25
+ gap: var(--jt-info-gap);
26
+ justify-content: stretch;
27
+ }
28
+
29
+ .resultInfo {
30
+ font-size: var(--jt-info-font-size);
31
+ color: var(--jt-info-color);
32
+ text-align: center;
33
+ }
34
+
35
+ @media (--media-medium-viewport-up) {
36
+ .info {
37
+ flex-direction: row;
38
+ align-items: center;
39
+ justify-content: space-between;
40
+ }
41
+
42
+ .resultInfo {
43
+ flex: 1;
44
+ text-align: start;
45
+ }
46
+
47
+ .search {
48
+ flex: 0 1 var(--jt-search-max-width);
49
+ }
50
+ }
51
+
52
+ .table {
53
+ /* vertical spacing is handled by the wrapper */
54
+ margin-block: 0;
55
+ }
56
+
57
+ /* purgecss end ignore */
@@ -0,0 +1,48 @@
1
+ export default {
2
+ jt: {
3
+ wrapper: {
4
+ margin: {
5
+ block: {
6
+ $type: 'dimension',
7
+ $value: '{size.md}'
8
+ }
9
+ }
10
+ },
11
+
12
+ info: {
13
+ gap: {
14
+ $type: 'dimension',
15
+ $value: '{size.sm}'
16
+ },
17
+ font: {
18
+ size: {
19
+ $type: 'dimension',
20
+ $value: '{font.size.sm}'
21
+ }
22
+ },
23
+ color: {
24
+ $type: 'color',
25
+ $value: '{text.muted}'
26
+ },
27
+ outer: {
28
+ padding: {
29
+ block: {
30
+ end: {
31
+ $type: 'dimension',
32
+ $value: '{size.xs}'
33
+ }
34
+ }
35
+ }
36
+ }
37
+ },
38
+
39
+ search: {
40
+ max: {
41
+ width: {
42
+ $type: 'dimension',
43
+ $value: '20rem'
44
+ }
45
+ }
46
+ }
47
+ }
48
+ };
@@ -0,0 +1,243 @@
1
+ # `<json-table>` – tabelle HTML da dati JSON
2
+
3
+ > **Work in progress.** In questa fase il componente genera solo la **struttura esterna**
4
+ > (sezione info, input di ricerca, wrapper con `<table>` vuota e caption). Colonne (`cols`),
5
+ > rendering delle righe, ordinamento, ricerca e paginazione **non sono ancora implementati**.
6
+ > Il piano di sviluppo è in `src/web-components/TODO json-table/TODO.md`.
7
+
8
+ Sostituisce `s-datatable-component`: nessuna dipendenza esterna, custom element
9
+ light DOM (`<json-table>`).
10
+
11
+ ## Installazione
12
+
13
+ Nessuna peer dependency. Basta importare il file del componente (registra il custom element):
14
+
15
+ ```javascript
16
+ import '@massimo-cassandro/minimo/src/web-components/json-table/json-table-component.js';
17
+ // oppure, se serve la classe (es. per setDefaults):
18
+ import { JsonTable } from '@massimo-cassandro/minimo/src/web-components/json-table/json-table-component.js';
19
+ ```
20
+
21
+ Il CSS (`json-table-component.module.css`) è importato dal componente stesso; le custom
22
+ properties `--jt-*` sono definite in `json-table.minimo.tokens.mjs` e compilate in
23
+ `custom-properties.css` da `build-tokens`.
24
+
25
+ ## Utilizzo da markup
26
+
27
+ ```html
28
+ <json-table
29
+ jsonurl="/api/rows.json"
30
+ caption="Utenti"
31
+ ></json-table>
32
+
33
+ <!-- dati inline (JSON serializzato, utile in contesti SSR: Twig, Blade, ...) -->
34
+ <json-table
35
+ data='[{"name":"Mario","city":"Roma"}, ...]'
36
+ search="false"
37
+ ></json-table>
38
+ ```
39
+
40
+ I nomi degli attributi sono case-insensitive (`jsonurl` e `jsonUrl` sono equivalenti).
41
+ Gli attributi booleani accettano i formati HTML idiomatici: `search` (presente senza valore),
42
+ `search="true"`, `search="1"` → true; `search="false"`, `search="0"` → false.
43
+ I valori che iniziano con `[` o `{` vengono interpretati come JSON (un JSON malformato viene
44
+ segnalato in console e ignorato).
45
+
46
+ ## Utilizzo da script
47
+
48
+ ```javascript
49
+ const el = document.querySelector('json-table');
50
+ // oppure: const el = document.createElement('json-table');
51
+
52
+ el.init({
53
+ jsonUrl: '/api/rows.json',
54
+ caption: 'Utenti'
55
+ });
56
+
57
+ // dati inline al posto di jsonUrl (se presenti entrambi, `data` prevale)
58
+ el.init({
59
+ data: [{ name: 'Mario', city: 'Roma' }, ...]
60
+ });
61
+
62
+ // se appena creato, appendere dopo init():
63
+ document.body.appendChild(el);
64
+ ```
65
+
66
+ ### Con `domBuilder`
67
+
68
+ ```javascript
69
+ domBuilder([
70
+ {
71
+ tag: 'json-table',
72
+ attrs: { caption: 'Utenti' },
73
+ callback: el => el.init({ jsonUrl: '/api/rows.json' })
74
+ }
75
+ ], container);
76
+ ```
77
+
78
+ ## Utilizzo misto – attributi HTML + script
79
+
80
+ I parametri non inclusi in `init()` vengono letti dall'attributo HTML corrispondente:
81
+
82
+ ```html
83
+ <json-table caption="Utenti" search="false"></json-table>
84
+ ```
85
+
86
+ ```javascript
87
+ el.init({ jsonUrl: '/api/rows.json' }); // jsonUrl da script, caption e search da attributo
88
+ ```
89
+
90
+ **Ordine di precedenza:** `init()` > attributo HTML > `JsonTable.setDefaults()` > default interno.
91
+
92
+ Per ignorare esplicitamente un attributo e ricadere sui default, passare `null` nel config:
93
+
94
+ ```javascript
95
+ el.init({ jsonUrl: '/api/rows.json', search: null }); // search → default (true)
96
+ ```
97
+
98
+ ## Default di progetto – `JsonTable.setDefaults()`
99
+
100
+ Imposta valori validi per tutte le istanze create successivamente, evitando di ripetere gli
101
+ stessi parametri. Da invocare una sola volta, in uno script condiviso eseguito prima degli altri.
102
+ I valori vengono uniti a quelli impostati in chiamate precedenti.
103
+
104
+ ```javascript
105
+ import { JsonTable } from '.../json-table-component.js';
106
+
107
+ JsonTable.setDefaults({
108
+ searchInputClass: 'form-control form-control-sm',
109
+ tableClass: 'table',
110
+ infoText: (shown, total) => `${shown} di ${total} record`
111
+ });
112
+
113
+ JsonTable.getDefaults(); // default interni + default di progetto
114
+ JsonTable.resetDefaults(); // azzera i default di progetto
115
+ ```
116
+
117
+ ## API dell'istanza
118
+
119
+ | Metodo | Descrizione |
120
+ |---|---|
121
+ | `init(config)` | Avvia il componente (prima o dopo l'inserimento nel DOM) |
122
+ | `reload(overrides)` | Ricarica i dati e ricostruisce la struttura, con eventuali parametri sovrascritti (`Promise`) |
123
+ | `destroy()` | Svuota il componente; `init()` può essere richiamato in seguito |
124
+
125
+ Proprietà disponibili dopo il caricamento: `params` (parametri risolti), `data` (righe grezze),
126
+ `elements` (elementi generati: `wrapper`, `infoOuter`, `info`, `resultInfo`, `searchInput`,
127
+ `tableWrapper`, `table`).
128
+
129
+ ```javascript
130
+ await el.reload({ jsonUrl: '/api/rows.json?anno=2025' });
131
+ await el.reload({ data: [...] });
132
+ ```
133
+
134
+ ## Evento `jt:ready`
135
+
136
+ Emesso sull'elemento (con `bubbles`) al termine della costruzione; `event.detail.jsonTable`
137
+ è l'istanza. Viene emesso nel microtask successivo, quindi un listener registrato subito dopo
138
+ `init()` lo intercetta comunque.
139
+
140
+ ```javascript
141
+ el.addEventListener('jt:ready', e => {
142
+ console.log(e.detail.jsonTable.data);
143
+ });
144
+ el.init({ jsonUrl: '/api/rows.json' });
145
+ ```
146
+
147
+ ## Parametri
148
+
149
+ Tutti i parametri sono impostabili sia da attributo HTML che da `init()`. I valori di tipo
150
+ funzione (`caption`, `infoText`) solo da `init()`.
151
+
152
+ ```javascript
153
+ {
154
+ debug, // boolean – log in console di parametri, dati ed elementi generati.
155
+ // Default: false
156
+
157
+ jsonUrl, // string – URL del JSON da caricare. Ignorato se `data` è presente.
158
+ // Default: null
159
+
160
+ jsonDataField, // string|null – chiave del JSON che contiene l'array delle righe
161
+ // (es. 'data' per { data: [...] }); null o '' = la root del JSON è
162
+ // l'array stesso. Default: 'data'
163
+
164
+ data, // Array<Object> – righe inline; prevale su `jsonUrl`. Da attributo va
165
+ // passato come stringa JSON ed è sempre inteso come array delle righe
166
+ // (`jsonDataField` ignorato). Default: null
167
+
168
+ caption, // string|Function – caption della tabella (testo o HTML), oppure
169
+ // funzione che restituisce stringa o Node. Default: null
170
+
171
+ search, // boolean – genera l'input di ricerca. Default: true
172
+ searchInputClass, // string – classi dell'input di ricerca (sostituisce il default).
173
+ // Default: 'form-control'
174
+ searchInputTitle, // string – attributo title dell'input.
175
+ // Default: 'Filtra record: inserisci un termine per eseguire la ricerca'
176
+ searchInputPlaceholder, // string – placeholder dell'input.
177
+ // Default: 'Inserisci il termine da cercare'
178
+ searchInputAriaLabel, // string – aria-label dell'input. Default: 'Filtra risultati'
179
+
180
+ tableId, // string – id del tag <table>. Default: null
181
+ tableWrapperClass, // string – classi del div che racchiude la tabella (sostituisce il
182
+ // default). Default: 'table-responsive'
183
+ tableClass, // string – classi del tag <table> (sostituisce il default).
184
+ // Default: 'table table-bordered'
185
+
186
+ mainWrapperExtraClass, // string – classi aggiuntive per il contenitore principale
187
+ // (info + tabella). Default: null
188
+ outerInfoExtraClass, // string – classi aggiuntive per il contenitore esterno della
189
+ // sezione info. Default: null
190
+ infoExtraClass, // string – classi aggiuntive per la sezione info. Default: null
191
+
192
+ infoText, // (shown, total) => string|Node – testo dell'area info (testo,
193
+ // stringa HTML o Node).
194
+ // Default: "Visualizzate N righe su M" / "Nessun record"
195
+ }
196
+ ```
197
+
198
+ I parametri `*ExtraClass` si **aggiungono** alle classi interne di layout; i parametri
199
+ `*Class` (`searchInputClass`, `tableWrapperClass`, `tableClass`) **sostituiscono** interamente
200
+ il valore di default, ferme restando le eventuali classi interne di layout del componente.
201
+
202
+ ### In sviluppo
203
+
204
+ `cols`, data-types, `locale` e opzioni di formattazione, icone (booleani e ordinamento),
205
+ ordinamento, ricerca, paginazione, `trCallback`, `footerRender`, `refs`: vedi il TODO del componente.
206
+
207
+ ## Struttura generata
208
+
209
+ ```html
210
+ <json-table>
211
+ <section class="[wrapper] [mainWrapperExtraClass]">
212
+ <div class="[infoOuter] [outerInfoExtraClass]">
213
+ <div class="[info] [infoExtraClass]">
214
+ <div class="[resultInfo]" aria-live="polite">Visualizzate <strong>N</strong> righe su <strong>M</strong></div>
215
+ <div class="[search]"> <!-- solo se search: true -->
216
+ <input type="search" class="form-control" ...>
217
+ </div>
218
+ </div>
219
+ </div>
220
+ <div class="table-responsive"> <!-- tableWrapperClass -->
221
+ <table class="[table] table table-bordered"> <!-- tableClass -->
222
+ <caption>...</caption> <!-- solo se caption -->
223
+ <!-- thead / tbody / tfoot: in sviluppo -->
224
+ </table>
225
+ </div>
226
+ </section>
227
+ </json-table>
228
+ ```
229
+
230
+ Le classi tra parentesi quadre sono quelle interne del CSS module.
231
+
232
+ ## Custom properties CSS
233
+
234
+ Definite in `json-table.minimo.tokens.mjs` (namespace `--jt-*`):
235
+
236
+ | Proprietà | Default (token minimo) |
237
+ |---|---|
238
+ | `--jt-wrapper-margin-block` | `{size.md}` |
239
+ | `--jt-info-gap` | `{size.sm}` |
240
+ | `--jt-info-font-size` | `{font.size.sm}` |
241
+ | `--jt-info-color` | `{text.muted}` |
242
+ | `--jt-info-outer-padding-block-end` | `{size.xs}` |
243
+ | `--jt-search-max-width` | `20rem` |