@fieldia/widgets 0.12.0 → 0.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/src/lib/cards.js +2 -2
- package/src/lib/cards.js.map +1 -1
- package/src/lib/cards.mjs +2 -2
- package/src/lib/cards.mjs.map +1 -1
- package/src/lib/choice-tags.js +4 -2
- package/src/lib/choice-tags.js.map +1 -1
- package/src/lib/choice-tags.mjs +4 -2
- package/src/lib/choice-tags.mjs.map +1 -1
- package/src/lib/float.d.mts +14 -0
- package/src/lib/float.d.ts +14 -0
- package/src/lib/float.js +91 -0
- package/src/lib/float.js.map +1 -0
- package/src/lib/float.mjs +88 -0
- package/src/lib/float.mjs.map +1 -0
- package/src/lib/labels.d.mts +2 -0
- package/src/lib/labels.d.ts +2 -0
- package/src/lib/labels.js +1 -0
- package/src/lib/labels.js.map +1 -1
- package/src/lib/labels.mjs +1 -0
- package/src/lib/labels.mjs.map +1 -1
- package/src/lib/layout-styles.d.mts +1 -1
- package/src/lib/layout-styles.d.ts +1 -1
- package/src/lib/layout-styles.js +12 -5
- package/src/lib/layout-styles.js.map +1 -1
- package/src/lib/layout-styles.mjs +12 -5
- package/src/lib/layout-styles.mjs.map +1 -1
- package/src/lib/lines.js +123 -12
- package/src/lib/lines.js.map +1 -1
- package/src/lib/lines.mjs +123 -12
- package/src/lib/lines.mjs.map +1 -1
- package/src/lib/locales/ar.js +1 -0
- package/src/lib/locales/ar.js.map +1 -1
- package/src/lib/locales/ar.mjs +1 -0
- package/src/lib/locales/ar.mjs.map +1 -1
- package/src/lib/locales/de.js +1 -0
- package/src/lib/locales/de.js.map +1 -1
- package/src/lib/locales/de.mjs +1 -0
- package/src/lib/locales/de.mjs.map +1 -1
- package/src/lib/locales/fr.js +1 -0
- package/src/lib/locales/fr.js.map +1 -1
- package/src/lib/locales/fr.mjs +1 -0
- package/src/lib/locales/fr.mjs.map +1 -1
- package/src/lib/numbers.d.mts +5 -1
- package/src/lib/numbers.d.ts +5 -1
- package/src/lib/numbers.js +15 -2
- package/src/lib/numbers.js.map +1 -1
- package/src/lib/numbers.mjs +13 -2
- package/src/lib/numbers.mjs.map +1 -1
- package/src/lib/relations.js +11 -2
- package/src/lib/relations.js.map +1 -1
- package/src/lib/relations.mjs +11 -2
- package/src/lib/relations.mjs.map +1 -1
- package/src/lib/styles-business.d.mts +1 -1
- package/src/lib/styles-business.d.ts +1 -1
- package/src/lib/styles-business.js +1 -1
- package/src/lib/styles-business.mjs +1 -1
- package/src/lib/styles-inputs.d.mts +1 -1
- package/src/lib/styles-inputs.d.ts +1 -1
- package/src/lib/styles-inputs.js +2 -0
- package/src/lib/styles-inputs.js.map +1 -1
- package/src/lib/styles-inputs.mjs +2 -0
- package/src/lib/styles-inputs.mjs.map +1 -1
- package/src/lib/styles-kinds.d.mts +1 -1
- package/src/lib/styles-kinds.d.ts +1 -1
- package/src/lib/styles-kinds.js +1 -1
- package/src/lib/styles-kinds.mjs +1 -1
- package/src/lib/styles-sheet.d.mts +1 -1
- package/src/lib/styles-sheet.d.ts +1 -1
- package/src/lib/styles-sheet.js +28 -12
- package/src/lib/styles-sheet.js.map +1 -1
- package/src/lib/styles-sheet.mjs +28 -12
- package/src/lib/styles-sheet.mjs.map +1 -1
- package/src/lib/styles.js +83 -19
- package/src/lib/styles.js.map +1 -1
- package/src/lib/styles.mjs +83 -19
- package/src/lib/styles.mjs.map +1 -1
- package/src/lib/themes.d.mts +29 -0
- package/src/lib/themes.d.ts +29 -0
- package/src/lib/themes.js +180 -0
- package/src/lib/themes.js.map +1 -0
- package/src/lib/themes.mjs +177 -0
- package/src/lib/themes.mjs.map +1 -0
- package/src/lib/widgets.d.mts +7 -1
- package/src/lib/widgets.d.ts +7 -1
- package/src/lib/widgets.js +29 -6
- package/src/lib/widgets.js.map +1 -1
- package/src/lib/widgets.mjs +30 -7
- package/src/lib/widgets.mjs.map +1 -1
package/src/lib/styles.js
CHANGED
|
@@ -22,6 +22,7 @@ const styles_business_1 = require("./styles-business");
|
|
|
22
22
|
* form mirrors without a second stylesheet.
|
|
23
23
|
*/
|
|
24
24
|
const layout_styles_1 = require("./layout-styles");
|
|
25
|
+
const themes_1 = require("./themes");
|
|
25
26
|
/**
|
|
26
27
|
* The widths of a form at which its groups take their medium and their narrow
|
|
27
28
|
* columns: up to 760px and up to 520px of the form's own width, as the
|
|
@@ -31,8 +32,11 @@ const layout_styles_1 = require("./layout-styles");
|
|
|
31
32
|
exports.FORM_WIDTHS = { medium: 760, narrow: 520 };
|
|
32
33
|
/** The skins and the parts' chrome. One literal, so the script bundle can minify it as CSS. */
|
|
33
34
|
const SKINS_CSS = /* css */ `
|
|
34
|
-
/*
|
|
35
|
+
/* Fieldia's tokens (its colours, sizes and fonts) live in a cascade layer: a host's own rule, of any weight, sets
|
|
36
|
+
them over Fieldia's, whole. The skins, themes, page looks and schemes keep their order inside it.
|
|
37
|
+
.fd-theme carries the same tokens for things outside a form, such as a dialog over the page. One inside a form
|
|
35
38
|
with no skin of its own (the conversation beside a record) wears the form's skin and scheme instead. */
|
|
39
|
+
@layer fieldia-tokens {
|
|
36
40
|
.fd-form, .fd-theme:is([data-fd-skin], :not(.fd-form *)) {
|
|
37
41
|
--fd-font: system-ui, -apple-system, "Segoe UI", Roboto, "Noto Sans", "Noto Sans Arabic", sans-serif;
|
|
38
42
|
--fd-text: #212529;
|
|
@@ -62,12 +66,6 @@ const SKINS_CSS = /* css */ `
|
|
|
62
66
|
--fd-label-weight: 600;
|
|
63
67
|
--fd-gap-x: 32px;
|
|
64
68
|
--fd-gap-y: 14px;
|
|
65
|
-
container-type: inline-size;
|
|
66
|
-
font-family: var(--fd-font);
|
|
67
|
-
font-size: 14px;
|
|
68
|
-
line-height: 1.45;
|
|
69
|
-
color: var(--fd-text);
|
|
70
|
-
-webkit-text-size-adjust: 100%;
|
|
71
69
|
}
|
|
72
70
|
/* Ant Design's blue and red, a shade darker: words in them read at 4.5:1 (WCAG AA) on white, the page and their soft shades. */
|
|
73
71
|
.fd-form[data-fd-skin="outlined"], .fd-theme[data-fd-skin="outlined"] {
|
|
@@ -91,6 +89,15 @@ const SKINS_CSS = /* css */ `
|
|
|
91
89
|
--fd-gap-x: 24px;
|
|
92
90
|
--fd-gap-y: 18px;
|
|
93
91
|
}
|
|
92
|
+
}
|
|
93
|
+
.fd-form, .fd-theme:is([data-fd-skin], :not(.fd-form *)) {
|
|
94
|
+
container-type: inline-size;
|
|
95
|
+
font-family: var(--fd-font);
|
|
96
|
+
font-size: 14px;
|
|
97
|
+
line-height: 1.45;
|
|
98
|
+
color: var(--fd-text);
|
|
99
|
+
-webkit-text-size-adjust: 100%;
|
|
100
|
+
}
|
|
94
101
|
.fd-form *, .fd-form *::before, .fd-form *::after { box-sizing: border-box; }
|
|
95
102
|
.fd-form [hidden] { display: none !important; }
|
|
96
103
|
|
|
@@ -132,16 +139,24 @@ const SKINS_CSS = /* css */ `
|
|
|
132
139
|
.fd-label { font-weight: var(--fd-label-weight); color: var(--fd-text); }
|
|
133
140
|
/* The ✓ of a field filled in right, by its label. */
|
|
134
141
|
.fd-valid-mark { color: var(--fd-success); width: 1em; height: 1em; margin-inline-start: 6px; vertical-align: -0.15em; stroke-width: 2.4; }
|
|
135
|
-
|
|
136
|
-
.fd-
|
|
137
|
-
.fd-form[data-fd-skin="outlined"] .fd-field.fd-required > .fd-label::
|
|
142
|
+
/* No space between the star and the label's last word, its gap a margin: a line never breaks before it. */
|
|
143
|
+
.fd-field.fd-required > .fd-label::after { content: "*"; margin-inline-start: 0.25em; color: var(--fd-error); }
|
|
144
|
+
.fd-form[data-fd-skin="outlined"] .fd-field.fd-required > .fd-label::after { content: none; }
|
|
145
|
+
.fd-form[data-fd-skin="outlined"] .fd-field.fd-required > .fd-label::before { content: "*"; margin-inline-end: 0.25em; color: var(--fd-error); }
|
|
138
146
|
.fd-help { color: var(--fd-muted); font-size: 12.5px; }
|
|
139
147
|
/* A field's help behind a (?) by its label: a bubble on hover, focus or a tap. */
|
|
140
148
|
.fd-help-tip-wrap { position: relative; display: inline-flex; vertical-align: 0.05em; margin-inline-start: 6px; }
|
|
149
|
+
/* In a label it stands just after the last word, out of the line's flow: a browser may always break a line
|
|
150
|
+
before a box such as the (?), no-break space or not, and it would wrap onto a line of its own.
|
|
151
|
+
The label keeps room for it at its end, and a required star moves past it. */
|
|
152
|
+
.fd-label > .fd-help-tip-wrap { position: absolute; margin-block-start: 0.15em; }
|
|
153
|
+
.fd-label:has(> .fd-help-tip-wrap) { padding-inline-end: 22px; }
|
|
154
|
+
.fd-field.fd-required > .fd-label:has(> .fd-help-tip-wrap)::after { padding-inline-start: 22px; }
|
|
155
|
+
.fd-form:not([data-fd-skin="outlined"]) .fd-field.fd-required > .fd-label:has(> .fd-help-tip-wrap) { padding-inline-end: 0; }
|
|
141
156
|
.fd-help-tip { all: unset; box-sizing: border-box; display: inline-grid; place-items: center; width: 16px; height: 16px; border: 1px solid var(--fd-border); border-radius: 50%; color: var(--fd-muted); font-size: 11px; font-weight: 600; line-height: 1; cursor: help; }
|
|
142
157
|
.fd-help-tip:hover, .fd-help-tip[aria-expanded="true"] { color: var(--fd-accent); border-color: var(--fd-accent); }
|
|
143
158
|
.fd-help-tip:focus-visible { outline: 2px solid var(--fd-focus); outline-offset: 2px; }
|
|
144
|
-
.fd-help-bubble { position: absolute; inset-block-start: calc(100% + 6px); inset-inline-start: -8px; z-index: 30; width: max-content; max-width: min(280px,
|
|
159
|
+
.fd-help-bubble { position: absolute; inset-block-start: calc(100% + 6px); inset-inline-start: -8px; z-index: 30; width: max-content; max-width: min(280px, calc(100vw - 16px)); padding: 6px 9px; border-radius: 6px; background: var(--fd-text); color: var(--fd-surface); font-size: 12.5px; font-weight: 400; line-height: 1.4; white-space: normal; box-shadow: 0 6px 18px rgb(0 0 0 / 0.18); }
|
|
145
160
|
/*
|
|
146
161
|
* A page's words run the way they are written — a sentence left in English on
|
|
147
162
|
* an Arabic page keeps its full stop at its end — and line up with the form.
|
|
@@ -162,9 +177,12 @@ const SKINS_CSS = /* css */ `
|
|
|
162
177
|
/* One label width for every field, so a field spanning two columns lines up with its neighbours. */
|
|
163
178
|
grid-template-columns: var(--fd-label-width, 11em) minmax(0, 1fr);
|
|
164
179
|
column-gap: 12px;
|
|
165
|
-
align-items: baseline;
|
|
166
180
|
}
|
|
167
|
-
|
|
181
|
+
/* The label at its value's top, its words level with a one-line box's, as labels set beside by a page sit: never
|
|
182
|
+
by the value's baseline, which a box of several lines (a code box, rich text, files) puts at its foot. */
|
|
183
|
+
.fd-form[data-fd-skin="underline"] .fd-field:where(:not([data-labels])) > .fd-label {
|
|
184
|
+
grid-column: 1; align-self: start; padding-block-start: max(0px, calc((var(--fd-control-height, 30px) - 1.45em) / 2));
|
|
185
|
+
}
|
|
168
186
|
/* A table of lines needs the full width: its label sits above it. */
|
|
169
187
|
.fd-form[data-fd-skin="underline"] .fd-field[data-type="one2many"] { grid-template-columns: minmax(0, 1fr); }
|
|
170
188
|
.fd-form[data-fd-skin="underline"] .fd-field[data-type="one2many"] > * { grid-column: 1 !important; }
|
|
@@ -216,6 +234,8 @@ const SKINS_CSS = /* css */ `
|
|
|
216
234
|
border-radius: var(--fd-control-radius);
|
|
217
235
|
padding: var(--fd-pad-y) var(--fd-pad-x);
|
|
218
236
|
min-height: var(--fd-control-height, 30px);
|
|
237
|
+
/* A value longer than its box ends in "…", not cut mid-letter (the whole of it shows on hover). */
|
|
238
|
+
text-overflow: ellipsis;
|
|
219
239
|
transition: border-color 0.15s ease, box-shadow 0.15s ease;
|
|
220
240
|
}
|
|
221
241
|
.fd-input::placeholder { color: var(--fd-muted); opacity: 0.8; }
|
|
@@ -225,7 +245,7 @@ const SKINS_CSS = /* css */ `
|
|
|
225
245
|
.fd-form[data-fd-skin="underline"] .fd-input:focus { box-shadow: 0 1px 0 0 var(--fd-focus); }
|
|
226
246
|
.fd-form[data-fd-skin="underline"] .fd-field.fd-required .fd-input { border-color: var(--fd-accent); }
|
|
227
247
|
.fd-input[readonly] { background: transparent; border-color: transparent; padding-inline: 0; }
|
|
228
|
-
.fd-form[data-fd-skin="outlined"] .fd-input[readonly] { background:
|
|
248
|
+
.fd-form[data-fd-skin="outlined"] .fd-input[readonly] { background: color-mix(in srgb, var(--fd-text) 5%, var(--fd-surface)); border-color: var(--fd-border); padding-inline: var(--fd-pad-x); color: var(--fd-muted); }
|
|
229
249
|
/* A whole form locked reads as a record: plain values in either skin, no boxes, and no prompts to type. */
|
|
230
250
|
.fd-form[data-readonly] .fd-input[readonly] { background: transparent; border-color: transparent; padding-inline: 0; color: var(--fd-text); }
|
|
231
251
|
.fd-form[data-readonly] .fd-input::placeholder { color: transparent; }
|
|
@@ -301,6 +321,10 @@ const SKINS_CSS = /* css */ `
|
|
|
301
321
|
.fd-combo-clear:hover { color: var(--fd-text); background: var(--fd-page); }
|
|
302
322
|
/* A link that can be opened has its open button beside the clear button. */
|
|
303
323
|
.fd-combo:has(> .fd-combo-open:not([hidden])) .fd-combo-input { padding-inline-end: 56px; }
|
|
324
|
+
/* Read-only, its clear button is gone: its words take the room, and an open button moves to the end. */
|
|
325
|
+
.fd-combo:not(.fd-choice-search .fd-combo):has(> .fd-combo-clear[hidden]) .fd-combo-input[readonly] { padding-inline-end: var(--fd-pad-x); }
|
|
326
|
+
.fd-combo:not(.fd-choice-search .fd-combo):has(> .fd-combo-clear[hidden]):has(> .fd-combo-open:not([hidden])) .fd-combo-input[readonly] { padding-inline-end: 30px; }
|
|
327
|
+
.fd-combo:has(> .fd-combo-input[readonly]) > .fd-combo-clear[hidden] ~ .fd-combo-open { inset-inline-end: 3px; }
|
|
304
328
|
.fd-combo-open {
|
|
305
329
|
position: absolute; inset-inline-end: 29px; border: none; background: none; cursor: pointer; color: var(--fd-accent);
|
|
306
330
|
font-size: 14px; line-height: 1; padding: 0 4px; border-radius: 4px; min-width: 24px; min-height: 24px; display: inline-grid; place-items: center;
|
|
@@ -341,7 +365,37 @@ button.fd-chip-label:hover { text-decoration: underline; }
|
|
|
341
365
|
/* A yes/no cell sits level with the inputs beside it. */
|
|
342
366
|
.fd-lines-table td > .fd-checkbox, .fd-lines-table td > .fd-switch { margin-block-start: 6px; }
|
|
343
367
|
.fd-lines-table .fd-lines-grip { width: 1px; min-width: 0; padding-inline: 6px 2px; }
|
|
368
|
+
/* A table wider than its box scrolls sideways under a line's grip and its delete button, which stay at its ends. */
|
|
369
|
+
.fd-lines:not([data-cards="always"]) .fd-lines-table :is(th, td):is(.fd-lines-grip, .fd-lines-tools) { position: sticky; z-index: 1; background-color: var(--fd-surface); }
|
|
370
|
+
.fd-lines:not([data-cards="always"]) .fd-lines-table :is(th, td).fd-lines-grip { inset-inline-start: 0; }
|
|
371
|
+
.fd-lines:not([data-cards="always"]) .fd-lines-table :is(th, td).fd-lines-tools { inset-inline-end: 0; }
|
|
372
|
+
/* A column of yes/no, numbers, money or dates as wide as its values, as Flectra's lists size them: words and links have the rest. */
|
|
373
|
+
.fd-lines-table td[data-fit] { min-width: 0; }
|
|
374
|
+
/* A head may take two lines rather than widen a column of short values: "Delivery Lead Time" over "45". */
|
|
375
|
+
.fd-lines-table thead th:not(.fd-lines-grip, .fd-lines-tools) { white-space: normal; }
|
|
376
|
+
.fd-lines-table thead th { vertical-align: bottom; }
|
|
377
|
+
.fd-lines-table th[data-fit="boolean"] { width: 5em; min-width: 5em; }
|
|
378
|
+
.fd-lines-table th[data-fit="integer"] { width: max(7em, var(--fd-fit-need, 0px)); min-width: max(7em, var(--fd-fit-need, 0px)); }
|
|
379
|
+
.fd-lines-table th[data-fit="float"] { width: max(7.5em, var(--fd-fit-need, 0px)); min-width: max(7.5em, var(--fd-fit-need, 0px)); }
|
|
380
|
+
.fd-lines-table th[data-fit="monetary"] { width: max(11.5em, var(--fd-fit-need, 0px)); min-width: max(11.5em, var(--fd-fit-need, 0px)); }
|
|
381
|
+
.fd-lines-table th[data-fit="date"] { width: 9em; min-width: 9em; }
|
|
382
|
+
.fd-lines-table th[data-fit="datetime"] { width: 12.5em; min-width: 12.5em; }
|
|
383
|
+
/* Numbers and money read from the end, as Flectra's lists align them. */
|
|
384
|
+
.fd-lines-table th:is([data-fit="integer"], [data-fit="float"], [data-fit="monetary"]) { text-align: end; }
|
|
385
|
+
.fd-lines-table td:is([data-fit="integer"], [data-fit="float"], [data-fit="monetary"]) input { text-align: end; }
|
|
386
|
+
/* A table reads as a table, as a grid does: a line shows its boxes and buttons where the pointer or the cursor is.
|
|
387
|
+
Only colours and visibility change, never a size: a line left for a click elsewhere must not move what is clicked.
|
|
388
|
+
A touch screen has no pointer to hover with: there the boxes always show. */
|
|
389
|
+
@media (hover: hover) and (pointer: fine) {
|
|
390
|
+
.fd-lines:not([data-cards="always"]) .fd-lines-table tbody tr:not(:hover, :focus-within) .fd-input:not([aria-invalid="true"]) { border-color: transparent; background-color: transparent; box-shadow: none; }
|
|
391
|
+
.fd-lines:not([data-cards="always"]) .fd-lines-table tbody tr:not(:hover, :focus-within) :is(.fd-combo-open, .fd-combo-clear) { visibility: hidden; }
|
|
392
|
+
}
|
|
344
393
|
.fd-line-grip { display: block; margin-block-start: 7px; cursor: grab; }
|
|
394
|
+
/* A line dragged by its grip follows the pointer, lifted over the others, which slide out of its way. */
|
|
395
|
+
.fd-lines-dragging, .fd-lines-dragging * { cursor: grabbing; user-select: none; }
|
|
396
|
+
.fd-lines-dragging > tr:not(.fd-line-lifted) { transition: transform 0.15s ease; }
|
|
397
|
+
.fd-line-lifted { position: relative; z-index: 2; box-shadow: 0 6px 18px rgba(15, 20, 25, 0.16); }
|
|
398
|
+
.fd-line-lifted > td { background: var(--fd-surface); }
|
|
345
399
|
.fd-line-delete { border: none; background: none; cursor: pointer; color: var(--fd-muted); font-size: 16px; line-height: 1; padding: 4px 6px; border-radius: 4px; min-width: 24px; min-height: 24px; }
|
|
346
400
|
.fd-line-delete:hover { color: var(--fd-error); background: var(--fd-error-soft); }
|
|
347
401
|
/* A table's own rules: a line's or a cell's tone and bold (Flectra's decoration-*), and buttons on a line. */
|
|
@@ -592,7 +646,8 @@ button.fd-chip-label:hover { text-decoration: underline; }
|
|
|
592
646
|
.fd-button-primary { background: var(--fd-accent); border-color: var(--fd-accent); color: var(--fd-accent-text); }
|
|
593
647
|
.fd-button-primary:hover { color: var(--fd-accent-text); filter: brightness(1.12); }
|
|
594
648
|
.fd-button-danger { color: var(--fd-error); border-color: var(--fd-error); }
|
|
595
|
-
|
|
649
|
+
/* The surface's colour on the error's: white on a light page's deep red, near-black on a dark page's coral. */
|
|
650
|
+
.fd-button-danger:hover { background: var(--fd-error); color: var(--fd-surface); }
|
|
596
651
|
.fd-button-link { border-color: transparent; background: none; color: var(--fd-accent); padding-inline: 4px; }
|
|
597
652
|
.fd-form[data-fd-skin="underline"] .fd-button { border-radius: 3px; }
|
|
598
653
|
.fd-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
|
|
@@ -624,9 +679,13 @@ button.fd-chip-label:hover { text-decoration: underline; }
|
|
|
624
679
|
.fd-sheet-layout { align-items: start; }
|
|
625
680
|
/* Save and Discard closing the sheet, when the page puts them at its foot. */
|
|
626
681
|
.fd-sheet-foot { margin: 4px -28px -28px; padding: 12px 28px; border-block-start: 1px solid var(--fd-border); border-end-start-radius: inherit; border-end-end-radius: inherit; }
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
682
|
+
/* The side panel under the sheet, the sheet taking the whole width; beside it, as Flectra's chatter, on a form of
|
|
683
|
+
1534px or more — the page growing by the panel's width, so the sheet keeps its own ("none" plus a width is no
|
|
684
|
+
width: a full page stays full). A page that asks keeps it beside down to 600px (record-styles). */
|
|
685
|
+
@container (min-width: 1534px) {
|
|
686
|
+
.fd-sheet-layout.fd-has-side { grid-template-columns: minmax(0, 1fr) minmax(260px, 360px); max-width: calc(var(--fd-page-max, 1180px) + 376px); }
|
|
687
|
+
}
|
|
688
|
+
.fd-sheet-layout.fd-has-side[data-side-beside="always"] { grid-template-columns: minmax(0, 1fr) minmax(260px, 360px); }
|
|
630
689
|
/* A part hidden at some widths of the form (hideOn): narrow up to 520px, medium up to 760px, wide above — the form's own width, as its columns. */
|
|
631
690
|
.fd-form { container-name: fd-form; }
|
|
632
691
|
@container fd-form (max-width: 520px) { .fd-form [data-hide-on~="narrow"] { display: none !important; } }
|
|
@@ -766,6 +825,9 @@ button.fd-chip-label:hover { text-decoration: underline; }
|
|
|
766
825
|
.fd-property { display: grid; grid-template-columns: minmax(120px, 30%) minmax(0, 1fr); align-items: center; gap: 12px; min-width: 0; }
|
|
767
826
|
.fd-property > label { color: var(--fd-muted); font-size: 13px; }
|
|
768
827
|
.fd-property[data-type="boolean"] > :last-child { justify-self: start; }
|
|
828
|
+
/* Beside their values, as the sheet's labels are: the same label column, the same words, the same gap between halves — the properties read as fields of the sheet. */
|
|
829
|
+
.fd-form[data-fd-skin="underline"] .fd-property { grid-template-columns: var(--fd-label-width, 11em) minmax(0, 1fr); }
|
|
830
|
+
.fd-form[data-fd-skin="underline"] .fd-property > label { color: var(--fd-text); font-size: inherit; font-weight: var(--fd-label-weight); }
|
|
769
831
|
@container (max-width: 520px) { .fd-property { grid-template-columns: minmax(0, 1fr); gap: 4px; } }
|
|
770
832
|
.fd-progressbar {
|
|
771
833
|
position: relative; height: 22px; min-width: 120px; border-radius: 999px; overflow: hidden;
|
|
@@ -952,7 +1014,9 @@ button.fd-chip-label:hover { text-decoration: underline; }
|
|
|
952
1014
|
@media (prefers-reduced-motion: reduce) { .fd-form *, .fd-form *::before, .fd-form *::after { transition: none !important; } .fd-button[aria-busy="true"]::after { animation: none; } }
|
|
953
1015
|
`;
|
|
954
1016
|
/** Fieldia's whole stylesheet: the skins, then the layout over them, the inputs' details, the question kinds and the choices' details. */
|
|
955
|
-
|
|
1017
|
+
// Themes' tokens after the skins' and before the page's look; their own shapes after the parts they reshape, and
|
|
1018
|
+
// before the page's own looks for each kind of part, which win over a theme as the page's look does.
|
|
1019
|
+
exports.FIELDIA_CSS = SKINS_CSS + themes_1.THEME_TOKENS_CSS + layout_styles_1.LAYOUT_CSS + styles_inputs_1.INPUTS_CSS + styles_sheet_1.SHEET_CSS + styles_business_1.BUSINESS_CSS + themes_1.THEME_RULES_CSS + styles_kinds_1.KINDS_CSS + styles_choices_1.CHOICES_CSS + styles_parts_1.PARTS_CSS;
|
|
956
1020
|
const STYLE_ID = 'fieldia-styles';
|
|
957
1021
|
/** Add Fieldia's stylesheet to a document, once. */
|
|
958
1022
|
function installStyles(document) {
|
package/src/lib/styles.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../../../libs/widgets/src/lib/styles.ts"],"names":[],"mappings":";;;AA
|
|
1
|
+
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../../../libs/widgets/src/lib/styles.ts"],"names":[],"mappings":";;;AA+/BA,sCAMC;AArgCD,iDAA2C;AAC3C,qDAA+C;AAC/C,mDAA6C;AAC7C,iDAA2C;AAC3C,iDAA2C;AAC3C,uDAAiD;AAEjD;;;;;;;;;;;;GAYG;AACH,mDAA6C;AAC7C,qCAA6D;AAE7D;;;;;GAKG;AACU,QAAA,WAAW,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAW,CAAC;AAEjE,+FAA+F;AAC/F,MAAM,SAAS,GAAG,SAAS,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAq9B3B,CAAC;AAEF,0IAA0I;AAC1I,iHAAiH;AACjH,qGAAqG;AACxF,QAAA,WAAW,GAAG,SAAS,GAAG,yBAAgB,GAAG,0BAAU,GAAG,0BAAU,GAAG,wBAAS,GAAG,8BAAY,GAAG,wBAAe,GAAG,wBAAS,GAAG,4BAAW,GAAG,wBAAS,CAAC;AAErK,MAAM,QAAQ,GAAG,gBAAgB,CAAC;AAElC,oDAAoD;AACpD,SAAgB,aAAa,CAAC,QAAkB;IAC9C,IAAI,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAC;QAAE,OAAO;IAC9C,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC9C,KAAK,CAAC,EAAE,GAAG,QAAQ,CAAC;IACpB,KAAK,CAAC,WAAW,GAAG,mBAAW,CAAC;IAChC,CAAC,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC5D,CAAC"}
|
package/src/lib/styles.mjs
CHANGED
|
@@ -18,6 +18,7 @@ import { BUSINESS_CSS } from './styles-business.mjs';
|
|
|
18
18
|
* form mirrors without a second stylesheet.
|
|
19
19
|
*/
|
|
20
20
|
import { LAYOUT_CSS } from './layout-styles.mjs';
|
|
21
|
+
import { THEME_RULES_CSS, THEME_TOKENS_CSS } from './themes.mjs';
|
|
21
22
|
/**
|
|
22
23
|
* The widths of a form at which its groups take their medium and their narrow
|
|
23
24
|
* columns: up to 760px and up to 520px of the form's own width, as the
|
|
@@ -27,8 +28,11 @@ import { LAYOUT_CSS } from './layout-styles.mjs';
|
|
|
27
28
|
export const FORM_WIDTHS = { medium: 760, narrow: 520 };
|
|
28
29
|
/** The skins and the parts' chrome. One literal, so the script bundle can minify it as CSS. */
|
|
29
30
|
const SKINS_CSS = /* css */ `
|
|
30
|
-
/*
|
|
31
|
+
/* Fieldia's tokens (its colours, sizes and fonts) live in a cascade layer: a host's own rule, of any weight, sets
|
|
32
|
+
them over Fieldia's, whole. The skins, themes, page looks and schemes keep their order inside it.
|
|
33
|
+
.fd-theme carries the same tokens for things outside a form, such as a dialog over the page. One inside a form
|
|
31
34
|
with no skin of its own (the conversation beside a record) wears the form's skin and scheme instead. */
|
|
35
|
+
@layer fieldia-tokens {
|
|
32
36
|
.fd-form, .fd-theme:is([data-fd-skin], :not(.fd-form *)) {
|
|
33
37
|
--fd-font: system-ui, -apple-system, "Segoe UI", Roboto, "Noto Sans", "Noto Sans Arabic", sans-serif;
|
|
34
38
|
--fd-text: #212529;
|
|
@@ -58,12 +62,6 @@ const SKINS_CSS = /* css */ `
|
|
|
58
62
|
--fd-label-weight: 600;
|
|
59
63
|
--fd-gap-x: 32px;
|
|
60
64
|
--fd-gap-y: 14px;
|
|
61
|
-
container-type: inline-size;
|
|
62
|
-
font-family: var(--fd-font);
|
|
63
|
-
font-size: 14px;
|
|
64
|
-
line-height: 1.45;
|
|
65
|
-
color: var(--fd-text);
|
|
66
|
-
-webkit-text-size-adjust: 100%;
|
|
67
65
|
}
|
|
68
66
|
/* Ant Design's blue and red, a shade darker: words in them read at 4.5:1 (WCAG AA) on white, the page and their soft shades. */
|
|
69
67
|
.fd-form[data-fd-skin="outlined"], .fd-theme[data-fd-skin="outlined"] {
|
|
@@ -87,6 +85,15 @@ const SKINS_CSS = /* css */ `
|
|
|
87
85
|
--fd-gap-x: 24px;
|
|
88
86
|
--fd-gap-y: 18px;
|
|
89
87
|
}
|
|
88
|
+
}
|
|
89
|
+
.fd-form, .fd-theme:is([data-fd-skin], :not(.fd-form *)) {
|
|
90
|
+
container-type: inline-size;
|
|
91
|
+
font-family: var(--fd-font);
|
|
92
|
+
font-size: 14px;
|
|
93
|
+
line-height: 1.45;
|
|
94
|
+
color: var(--fd-text);
|
|
95
|
+
-webkit-text-size-adjust: 100%;
|
|
96
|
+
}
|
|
90
97
|
.fd-form *, .fd-form *::before, .fd-form *::after { box-sizing: border-box; }
|
|
91
98
|
.fd-form [hidden] { display: none !important; }
|
|
92
99
|
|
|
@@ -128,16 +135,24 @@ const SKINS_CSS = /* css */ `
|
|
|
128
135
|
.fd-label { font-weight: var(--fd-label-weight); color: var(--fd-text); }
|
|
129
136
|
/* The ✓ of a field filled in right, by its label. */
|
|
130
137
|
.fd-valid-mark { color: var(--fd-success); width: 1em; height: 1em; margin-inline-start: 6px; vertical-align: -0.15em; stroke-width: 2.4; }
|
|
131
|
-
|
|
132
|
-
.fd-
|
|
133
|
-
.fd-form[data-fd-skin="outlined"] .fd-field.fd-required > .fd-label::
|
|
138
|
+
/* No space between the star and the label's last word, its gap a margin: a line never breaks before it. */
|
|
139
|
+
.fd-field.fd-required > .fd-label::after { content: "*"; margin-inline-start: 0.25em; color: var(--fd-error); }
|
|
140
|
+
.fd-form[data-fd-skin="outlined"] .fd-field.fd-required > .fd-label::after { content: none; }
|
|
141
|
+
.fd-form[data-fd-skin="outlined"] .fd-field.fd-required > .fd-label::before { content: "*"; margin-inline-end: 0.25em; color: var(--fd-error); }
|
|
134
142
|
.fd-help { color: var(--fd-muted); font-size: 12.5px; }
|
|
135
143
|
/* A field's help behind a (?) by its label: a bubble on hover, focus or a tap. */
|
|
136
144
|
.fd-help-tip-wrap { position: relative; display: inline-flex; vertical-align: 0.05em; margin-inline-start: 6px; }
|
|
145
|
+
/* In a label it stands just after the last word, out of the line's flow: a browser may always break a line
|
|
146
|
+
before a box such as the (?), no-break space or not, and it would wrap onto a line of its own.
|
|
147
|
+
The label keeps room for it at its end, and a required star moves past it. */
|
|
148
|
+
.fd-label > .fd-help-tip-wrap { position: absolute; margin-block-start: 0.15em; }
|
|
149
|
+
.fd-label:has(> .fd-help-tip-wrap) { padding-inline-end: 22px; }
|
|
150
|
+
.fd-field.fd-required > .fd-label:has(> .fd-help-tip-wrap)::after { padding-inline-start: 22px; }
|
|
151
|
+
.fd-form:not([data-fd-skin="outlined"]) .fd-field.fd-required > .fd-label:has(> .fd-help-tip-wrap) { padding-inline-end: 0; }
|
|
137
152
|
.fd-help-tip { all: unset; box-sizing: border-box; display: inline-grid; place-items: center; width: 16px; height: 16px; border: 1px solid var(--fd-border); border-radius: 50%; color: var(--fd-muted); font-size: 11px; font-weight: 600; line-height: 1; cursor: help; }
|
|
138
153
|
.fd-help-tip:hover, .fd-help-tip[aria-expanded="true"] { color: var(--fd-accent); border-color: var(--fd-accent); }
|
|
139
154
|
.fd-help-tip:focus-visible { outline: 2px solid var(--fd-focus); outline-offset: 2px; }
|
|
140
|
-
.fd-help-bubble { position: absolute; inset-block-start: calc(100% + 6px); inset-inline-start: -8px; z-index: 30; width: max-content; max-width: min(280px,
|
|
155
|
+
.fd-help-bubble { position: absolute; inset-block-start: calc(100% + 6px); inset-inline-start: -8px; z-index: 30; width: max-content; max-width: min(280px, calc(100vw - 16px)); padding: 6px 9px; border-radius: 6px; background: var(--fd-text); color: var(--fd-surface); font-size: 12.5px; font-weight: 400; line-height: 1.4; white-space: normal; box-shadow: 0 6px 18px rgb(0 0 0 / 0.18); }
|
|
141
156
|
/*
|
|
142
157
|
* A page's words run the way they are written — a sentence left in English on
|
|
143
158
|
* an Arabic page keeps its full stop at its end — and line up with the form.
|
|
@@ -158,9 +173,12 @@ const SKINS_CSS = /* css */ `
|
|
|
158
173
|
/* One label width for every field, so a field spanning two columns lines up with its neighbours. */
|
|
159
174
|
grid-template-columns: var(--fd-label-width, 11em) minmax(0, 1fr);
|
|
160
175
|
column-gap: 12px;
|
|
161
|
-
align-items: baseline;
|
|
162
176
|
}
|
|
163
|
-
|
|
177
|
+
/* The label at its value's top, its words level with a one-line box's, as labels set beside by a page sit: never
|
|
178
|
+
by the value's baseline, which a box of several lines (a code box, rich text, files) puts at its foot. */
|
|
179
|
+
.fd-form[data-fd-skin="underline"] .fd-field:where(:not([data-labels])) > .fd-label {
|
|
180
|
+
grid-column: 1; align-self: start; padding-block-start: max(0px, calc((var(--fd-control-height, 30px) - 1.45em) / 2));
|
|
181
|
+
}
|
|
164
182
|
/* A table of lines needs the full width: its label sits above it. */
|
|
165
183
|
.fd-form[data-fd-skin="underline"] .fd-field[data-type="one2many"] { grid-template-columns: minmax(0, 1fr); }
|
|
166
184
|
.fd-form[data-fd-skin="underline"] .fd-field[data-type="one2many"] > * { grid-column: 1 !important; }
|
|
@@ -212,6 +230,8 @@ const SKINS_CSS = /* css */ `
|
|
|
212
230
|
border-radius: var(--fd-control-radius);
|
|
213
231
|
padding: var(--fd-pad-y) var(--fd-pad-x);
|
|
214
232
|
min-height: var(--fd-control-height, 30px);
|
|
233
|
+
/* A value longer than its box ends in "…", not cut mid-letter (the whole of it shows on hover). */
|
|
234
|
+
text-overflow: ellipsis;
|
|
215
235
|
transition: border-color 0.15s ease, box-shadow 0.15s ease;
|
|
216
236
|
}
|
|
217
237
|
.fd-input::placeholder { color: var(--fd-muted); opacity: 0.8; }
|
|
@@ -221,7 +241,7 @@ const SKINS_CSS = /* css */ `
|
|
|
221
241
|
.fd-form[data-fd-skin="underline"] .fd-input:focus { box-shadow: 0 1px 0 0 var(--fd-focus); }
|
|
222
242
|
.fd-form[data-fd-skin="underline"] .fd-field.fd-required .fd-input { border-color: var(--fd-accent); }
|
|
223
243
|
.fd-input[readonly] { background: transparent; border-color: transparent; padding-inline: 0; }
|
|
224
|
-
.fd-form[data-fd-skin="outlined"] .fd-input[readonly] { background:
|
|
244
|
+
.fd-form[data-fd-skin="outlined"] .fd-input[readonly] { background: color-mix(in srgb, var(--fd-text) 5%, var(--fd-surface)); border-color: var(--fd-border); padding-inline: var(--fd-pad-x); color: var(--fd-muted); }
|
|
225
245
|
/* A whole form locked reads as a record: plain values in either skin, no boxes, and no prompts to type. */
|
|
226
246
|
.fd-form[data-readonly] .fd-input[readonly] { background: transparent; border-color: transparent; padding-inline: 0; color: var(--fd-text); }
|
|
227
247
|
.fd-form[data-readonly] .fd-input::placeholder { color: transparent; }
|
|
@@ -297,6 +317,10 @@ const SKINS_CSS = /* css */ `
|
|
|
297
317
|
.fd-combo-clear:hover { color: var(--fd-text); background: var(--fd-page); }
|
|
298
318
|
/* A link that can be opened has its open button beside the clear button. */
|
|
299
319
|
.fd-combo:has(> .fd-combo-open:not([hidden])) .fd-combo-input { padding-inline-end: 56px; }
|
|
320
|
+
/* Read-only, its clear button is gone: its words take the room, and an open button moves to the end. */
|
|
321
|
+
.fd-combo:not(.fd-choice-search .fd-combo):has(> .fd-combo-clear[hidden]) .fd-combo-input[readonly] { padding-inline-end: var(--fd-pad-x); }
|
|
322
|
+
.fd-combo:not(.fd-choice-search .fd-combo):has(> .fd-combo-clear[hidden]):has(> .fd-combo-open:not([hidden])) .fd-combo-input[readonly] { padding-inline-end: 30px; }
|
|
323
|
+
.fd-combo:has(> .fd-combo-input[readonly]) > .fd-combo-clear[hidden] ~ .fd-combo-open { inset-inline-end: 3px; }
|
|
300
324
|
.fd-combo-open {
|
|
301
325
|
position: absolute; inset-inline-end: 29px; border: none; background: none; cursor: pointer; color: var(--fd-accent);
|
|
302
326
|
font-size: 14px; line-height: 1; padding: 0 4px; border-radius: 4px; min-width: 24px; min-height: 24px; display: inline-grid; place-items: center;
|
|
@@ -337,7 +361,37 @@ button.fd-chip-label:hover { text-decoration: underline; }
|
|
|
337
361
|
/* A yes/no cell sits level with the inputs beside it. */
|
|
338
362
|
.fd-lines-table td > .fd-checkbox, .fd-lines-table td > .fd-switch { margin-block-start: 6px; }
|
|
339
363
|
.fd-lines-table .fd-lines-grip { width: 1px; min-width: 0; padding-inline: 6px 2px; }
|
|
364
|
+
/* A table wider than its box scrolls sideways under a line's grip and its delete button, which stay at its ends. */
|
|
365
|
+
.fd-lines:not([data-cards="always"]) .fd-lines-table :is(th, td):is(.fd-lines-grip, .fd-lines-tools) { position: sticky; z-index: 1; background-color: var(--fd-surface); }
|
|
366
|
+
.fd-lines:not([data-cards="always"]) .fd-lines-table :is(th, td).fd-lines-grip { inset-inline-start: 0; }
|
|
367
|
+
.fd-lines:not([data-cards="always"]) .fd-lines-table :is(th, td).fd-lines-tools { inset-inline-end: 0; }
|
|
368
|
+
/* A column of yes/no, numbers, money or dates as wide as its values, as Flectra's lists size them: words and links have the rest. */
|
|
369
|
+
.fd-lines-table td[data-fit] { min-width: 0; }
|
|
370
|
+
/* A head may take two lines rather than widen a column of short values: "Delivery Lead Time" over "45". */
|
|
371
|
+
.fd-lines-table thead th:not(.fd-lines-grip, .fd-lines-tools) { white-space: normal; }
|
|
372
|
+
.fd-lines-table thead th { vertical-align: bottom; }
|
|
373
|
+
.fd-lines-table th[data-fit="boolean"] { width: 5em; min-width: 5em; }
|
|
374
|
+
.fd-lines-table th[data-fit="integer"] { width: max(7em, var(--fd-fit-need, 0px)); min-width: max(7em, var(--fd-fit-need, 0px)); }
|
|
375
|
+
.fd-lines-table th[data-fit="float"] { width: max(7.5em, var(--fd-fit-need, 0px)); min-width: max(7.5em, var(--fd-fit-need, 0px)); }
|
|
376
|
+
.fd-lines-table th[data-fit="monetary"] { width: max(11.5em, var(--fd-fit-need, 0px)); min-width: max(11.5em, var(--fd-fit-need, 0px)); }
|
|
377
|
+
.fd-lines-table th[data-fit="date"] { width: 9em; min-width: 9em; }
|
|
378
|
+
.fd-lines-table th[data-fit="datetime"] { width: 12.5em; min-width: 12.5em; }
|
|
379
|
+
/* Numbers and money read from the end, as Flectra's lists align them. */
|
|
380
|
+
.fd-lines-table th:is([data-fit="integer"], [data-fit="float"], [data-fit="monetary"]) { text-align: end; }
|
|
381
|
+
.fd-lines-table td:is([data-fit="integer"], [data-fit="float"], [data-fit="monetary"]) input { text-align: end; }
|
|
382
|
+
/* A table reads as a table, as a grid does: a line shows its boxes and buttons where the pointer or the cursor is.
|
|
383
|
+
Only colours and visibility change, never a size: a line left for a click elsewhere must not move what is clicked.
|
|
384
|
+
A touch screen has no pointer to hover with: there the boxes always show. */
|
|
385
|
+
@media (hover: hover) and (pointer: fine) {
|
|
386
|
+
.fd-lines:not([data-cards="always"]) .fd-lines-table tbody tr:not(:hover, :focus-within) .fd-input:not([aria-invalid="true"]) { border-color: transparent; background-color: transparent; box-shadow: none; }
|
|
387
|
+
.fd-lines:not([data-cards="always"]) .fd-lines-table tbody tr:not(:hover, :focus-within) :is(.fd-combo-open, .fd-combo-clear) { visibility: hidden; }
|
|
388
|
+
}
|
|
340
389
|
.fd-line-grip { display: block; margin-block-start: 7px; cursor: grab; }
|
|
390
|
+
/* A line dragged by its grip follows the pointer, lifted over the others, which slide out of its way. */
|
|
391
|
+
.fd-lines-dragging, .fd-lines-dragging * { cursor: grabbing; user-select: none; }
|
|
392
|
+
.fd-lines-dragging > tr:not(.fd-line-lifted) { transition: transform 0.15s ease; }
|
|
393
|
+
.fd-line-lifted { position: relative; z-index: 2; box-shadow: 0 6px 18px rgba(15, 20, 25, 0.16); }
|
|
394
|
+
.fd-line-lifted > td { background: var(--fd-surface); }
|
|
341
395
|
.fd-line-delete { border: none; background: none; cursor: pointer; color: var(--fd-muted); font-size: 16px; line-height: 1; padding: 4px 6px; border-radius: 4px; min-width: 24px; min-height: 24px; }
|
|
342
396
|
.fd-line-delete:hover { color: var(--fd-error); background: var(--fd-error-soft); }
|
|
343
397
|
/* A table's own rules: a line's or a cell's tone and bold (Flectra's decoration-*), and buttons on a line. */
|
|
@@ -588,7 +642,8 @@ button.fd-chip-label:hover { text-decoration: underline; }
|
|
|
588
642
|
.fd-button-primary { background: var(--fd-accent); border-color: var(--fd-accent); color: var(--fd-accent-text); }
|
|
589
643
|
.fd-button-primary:hover { color: var(--fd-accent-text); filter: brightness(1.12); }
|
|
590
644
|
.fd-button-danger { color: var(--fd-error); border-color: var(--fd-error); }
|
|
591
|
-
|
|
645
|
+
/* The surface's colour on the error's: white on a light page's deep red, near-black on a dark page's coral. */
|
|
646
|
+
.fd-button-danger:hover { background: var(--fd-error); color: var(--fd-surface); }
|
|
592
647
|
.fd-button-link { border-color: transparent; background: none; color: var(--fd-accent); padding-inline: 4px; }
|
|
593
648
|
.fd-form[data-fd-skin="underline"] .fd-button { border-radius: 3px; }
|
|
594
649
|
.fd-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
|
|
@@ -620,9 +675,13 @@ button.fd-chip-label:hover { text-decoration: underline; }
|
|
|
620
675
|
.fd-sheet-layout { align-items: start; }
|
|
621
676
|
/* Save and Discard closing the sheet, when the page puts them at its foot. */
|
|
622
677
|
.fd-sheet-foot { margin: 4px -28px -28px; padding: 12px 28px; border-block-start: 1px solid var(--fd-border); border-end-start-radius: inherit; border-end-end-radius: inherit; }
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
678
|
+
/* The side panel under the sheet, the sheet taking the whole width; beside it, as Flectra's chatter, on a form of
|
|
679
|
+
1534px or more — the page growing by the panel's width, so the sheet keeps its own ("none" plus a width is no
|
|
680
|
+
width: a full page stays full). A page that asks keeps it beside down to 600px (record-styles). */
|
|
681
|
+
@container (min-width: 1534px) {
|
|
682
|
+
.fd-sheet-layout.fd-has-side { grid-template-columns: minmax(0, 1fr) minmax(260px, 360px); max-width: calc(var(--fd-page-max, 1180px) + 376px); }
|
|
683
|
+
}
|
|
684
|
+
.fd-sheet-layout.fd-has-side[data-side-beside="always"] { grid-template-columns: minmax(0, 1fr) minmax(260px, 360px); }
|
|
626
685
|
/* A part hidden at some widths of the form (hideOn): narrow up to 520px, medium up to 760px, wide above — the form's own width, as its columns. */
|
|
627
686
|
.fd-form { container-name: fd-form; }
|
|
628
687
|
@container fd-form (max-width: 520px) { .fd-form [data-hide-on~="narrow"] { display: none !important; } }
|
|
@@ -762,6 +821,9 @@ button.fd-chip-label:hover { text-decoration: underline; }
|
|
|
762
821
|
.fd-property { display: grid; grid-template-columns: minmax(120px, 30%) minmax(0, 1fr); align-items: center; gap: 12px; min-width: 0; }
|
|
763
822
|
.fd-property > label { color: var(--fd-muted); font-size: 13px; }
|
|
764
823
|
.fd-property[data-type="boolean"] > :last-child { justify-self: start; }
|
|
824
|
+
/* Beside their values, as the sheet's labels are: the same label column, the same words, the same gap between halves — the properties read as fields of the sheet. */
|
|
825
|
+
.fd-form[data-fd-skin="underline"] .fd-property { grid-template-columns: var(--fd-label-width, 11em) minmax(0, 1fr); }
|
|
826
|
+
.fd-form[data-fd-skin="underline"] .fd-property > label { color: var(--fd-text); font-size: inherit; font-weight: var(--fd-label-weight); }
|
|
765
827
|
@container (max-width: 520px) { .fd-property { grid-template-columns: minmax(0, 1fr); gap: 4px; } }
|
|
766
828
|
.fd-progressbar {
|
|
767
829
|
position: relative; height: 22px; min-width: 120px; border-radius: 999px; overflow: hidden;
|
|
@@ -948,7 +1010,9 @@ button.fd-chip-label:hover { text-decoration: underline; }
|
|
|
948
1010
|
@media (prefers-reduced-motion: reduce) { .fd-form *, .fd-form *::before, .fd-form *::after { transition: none !important; } .fd-button[aria-busy="true"]::after { animation: none; } }
|
|
949
1011
|
`;
|
|
950
1012
|
/** Fieldia's whole stylesheet: the skins, then the layout over them, the inputs' details, the question kinds and the choices' details. */
|
|
951
|
-
|
|
1013
|
+
// Themes' tokens after the skins' and before the page's look; their own shapes after the parts they reshape, and
|
|
1014
|
+
// before the page's own looks for each kind of part, which win over a theme as the page's look does.
|
|
1015
|
+
export const FIELDIA_CSS = SKINS_CSS + THEME_TOKENS_CSS + LAYOUT_CSS + INPUTS_CSS + SHEET_CSS + BUSINESS_CSS + THEME_RULES_CSS + KINDS_CSS + CHOICES_CSS + PARTS_CSS;
|
|
952
1016
|
const STYLE_ID = 'fieldia-styles';
|
|
953
1017
|
/** Add Fieldia's stylesheet to a document, once. */
|
|
954
1018
|
export function installStyles(document) {
|
package/src/lib/styles.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styles.mjs","sourceRoot":"","sources":["../../../../../libs/widgets/src/lib/styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"styles.mjs","sourceRoot":"","sources":["../../../../../libs/widgets/src/lib/styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE7D;;;;;GAKG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAW,CAAC;AAEjE,+FAA+F;AAC/F,MAAM,SAAS,GAAG,SAAS,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAq9B3B,CAAC;AAEF,0IAA0I;AAC1I,iHAAiH;AACjH,qGAAqG;AACrG,MAAM,CAAC,MAAM,WAAW,GAAG,SAAS,GAAG,gBAAgB,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,GAAG,YAAY,GAAG,eAAe,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;AAErK,MAAM,QAAQ,GAAG,gBAAgB,CAAC;AAElC,oDAAoD;AACpD,MAAM,UAAU,aAAa,CAAC,QAAkB;IAC9C,IAAI,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAC;QAAE,OAAO;IAC9C,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC9C,KAAK,CAAC,EAAE,GAAG,QAAQ,CAAC;IACpB,KAAK,CAAC,WAAW,GAAG,WAAW,CAAC;IAChC,CAAC,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC5D,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Theme } from '@fieldia/core';
|
|
2
|
+
/**
|
|
3
|
+
* (Not a `styles-*.ts`: its rules are written with the selectors they share, so the script bundle's
|
|
4
|
+
* minifier, which takes a static stylesheet, leaves it as it is.)
|
|
5
|
+
*
|
|
6
|
+
* Themes in the style of design systems people know: the form's own tokens,
|
|
7
|
+
* light and dark, over the skin each is drawn on (Odoo's over `underline`,
|
|
8
|
+
* the rest over `outlined`), and a few rules of their own for what tokens
|
|
9
|
+
* cannot say — Material's filled boxes, Apple's pill buttons, Google Forms'
|
|
10
|
+
* question cards. They are looks in those systems' style, not their kits: a
|
|
11
|
+
* theme names its typeface and falls back to the system's when the app has
|
|
12
|
+
* not loaded it. Every colour pair a reader reads is checked against WCAG AA
|
|
13
|
+
* (themes.spec.ts), so a few are a shade darker than the original.
|
|
14
|
+
*/
|
|
15
|
+
/** The tokens a theme sets, by their names without `--fd-`. */
|
|
16
|
+
export type ThemeTokens = Partial<Record<'font' | 'text' | 'muted' | 'page' | 'surface' | 'border' | 'border-strong' | 'accent' | 'accent-text' | 'accent-soft' | 'focus' | 'focus-ring' | 'error' | 'error-soft' | 'success' | 'warning' | 'info' | 'radius' | 'control-radius' | 'control-height' | 'pad-y' | 'pad-x' | 'input-border' | 'label-weight' | 'gap-x' | 'gap-y' | 'fill' | 'edge', string>>;
|
|
17
|
+
export declare const THEME_TOKENS: Record<Theme, {
|
|
18
|
+
light: ThemeTokens;
|
|
19
|
+
dark: ThemeTokens;
|
|
20
|
+
}>;
|
|
21
|
+
/**
|
|
22
|
+
* The themes' tokens: after the skins' (they win over them), before the page's
|
|
23
|
+
* look (whose accent, room, corners and scheme win over them). A theme's dark
|
|
24
|
+
* tokens are more specific than the plain dark scheme's, so they win over it.
|
|
25
|
+
* All in Fieldia's tokens' layer, under any rule of a host's own.
|
|
26
|
+
*/
|
|
27
|
+
export declare const THEME_TOKENS_CSS: string;
|
|
28
|
+
/** What tokens cannot say: each theme's own shapes. After every other rule, so they win at the same weight. */
|
|
29
|
+
export declare const THEME_RULES_CSS: string;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Theme } from '@fieldia/core';
|
|
2
|
+
/**
|
|
3
|
+
* (Not a `styles-*.ts`: its rules are written with the selectors they share, so the script bundle's
|
|
4
|
+
* minifier, which takes a static stylesheet, leaves it as it is.)
|
|
5
|
+
*
|
|
6
|
+
* Themes in the style of design systems people know: the form's own tokens,
|
|
7
|
+
* light and dark, over the skin each is drawn on (Odoo's over `underline`,
|
|
8
|
+
* the rest over `outlined`), and a few rules of their own for what tokens
|
|
9
|
+
* cannot say — Material's filled boxes, Apple's pill buttons, Google Forms'
|
|
10
|
+
* question cards. They are looks in those systems' style, not their kits: a
|
|
11
|
+
* theme names its typeface and falls back to the system's when the app has
|
|
12
|
+
* not loaded it. Every colour pair a reader reads is checked against WCAG AA
|
|
13
|
+
* (themes.spec.ts), so a few are a shade darker than the original.
|
|
14
|
+
*/
|
|
15
|
+
/** The tokens a theme sets, by their names without `--fd-`. */
|
|
16
|
+
export type ThemeTokens = Partial<Record<'font' | 'text' | 'muted' | 'page' | 'surface' | 'border' | 'border-strong' | 'accent' | 'accent-text' | 'accent-soft' | 'focus' | 'focus-ring' | 'error' | 'error-soft' | 'success' | 'warning' | 'info' | 'radius' | 'control-radius' | 'control-height' | 'pad-y' | 'pad-x' | 'input-border' | 'label-weight' | 'gap-x' | 'gap-y' | 'fill' | 'edge', string>>;
|
|
17
|
+
export declare const THEME_TOKENS: Record<Theme, {
|
|
18
|
+
light: ThemeTokens;
|
|
19
|
+
dark: ThemeTokens;
|
|
20
|
+
}>;
|
|
21
|
+
/**
|
|
22
|
+
* The themes' tokens: after the skins' (they win over them), before the page's
|
|
23
|
+
* look (whose accent, room, corners and scheme win over them). A theme's dark
|
|
24
|
+
* tokens are more specific than the plain dark scheme's, so they win over it.
|
|
25
|
+
* All in Fieldia's tokens' layer, under any rule of a host's own.
|
|
26
|
+
*/
|
|
27
|
+
export declare const THEME_TOKENS_CSS: string;
|
|
28
|
+
/** What tokens cannot say: each theme's own shapes. After every other rule, so they win at the same weight. */
|
|
29
|
+
export declare const THEME_RULES_CSS: string;
|