@moni-labs/moni-ui 0.2.0 → 0.3.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.
- package/README.md +52 -194
- package/custom-elements.json +1636 -350
- package/dist/actions/index.d.ts +6 -0
- package/dist/actions/index.d.ts.map +1 -1
- package/dist/actions/index.js +6 -0
- package/dist/components/_base/field-styles.d.ts +51 -16
- package/dist/components/_base/field-styles.d.ts.map +1 -1
- package/dist/components/_base/field-styles.js +164 -36
- package/dist/components/_base/index.d.ts +25 -0
- package/dist/components/_base/index.d.ts.map +1 -1
- package/dist/components/_base/index.js +25 -0
- package/dist/components/_base/interaction-styles.d.ts +39 -12
- package/dist/components/_base/interaction-styles.d.ts.map +1 -1
- package/dist/components/_base/interaction-styles.js +85 -33
- package/dist/components/_base/moni-element.d.ts +43 -8
- package/dist/components/_base/moni-element.d.ts.map +1 -1
- package/dist/components/_base/moni-element.js +43 -8
- package/dist/components/_base/shared-styles.d.ts +41 -17
- package/dist/components/_base/shared-styles.d.ts.map +1 -1
- package/dist/components/_base/shared-styles.js +113 -21
- package/dist/components/index.d.ts +6 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +6 -0
- package/dist/components/loading-shapes.d.ts +6 -0
- package/dist/components/loading-shapes.d.ts.map +1 -1
- package/dist/components/loading-shapes.js +6 -0
- package/dist/components/moni-app-bar.d.ts +128 -33
- package/dist/components/moni-app-bar.d.ts.map +1 -1
- package/dist/components/moni-app-bar.js +121 -26
- package/dist/components/moni-badge.d.ts +122 -14
- package/dist/components/moni-badge.d.ts.map +1 -1
- package/dist/components/moni-badge.js +122 -14
- package/dist/components/moni-bottom-sheet.d.ts +120 -15
- package/dist/components/moni-bottom-sheet.d.ts.map +1 -1
- package/dist/components/moni-bottom-sheet.js +116 -12
- package/dist/components/moni-button-group.d.ts +53 -27
- package/dist/components/moni-button-group.d.ts.map +1 -1
- package/dist/components/moni-button-group.js +49 -23
- package/dist/components/moni-button-segment.d.ts +28 -8
- package/dist/components/moni-button-segment.d.ts.map +1 -1
- package/dist/components/moni-button-segment.js +27 -7
- package/dist/components/moni-button.d.ts +51 -32
- package/dist/components/moni-button.d.ts.map +1 -1
- package/dist/components/moni-button.js +50 -31
- package/dist/components/moni-card.d.ts +91 -31
- package/dist/components/moni-card.d.ts.map +1 -1
- package/dist/components/moni-card.js +86 -26
- package/dist/components/moni-carousel.d.ts +67 -17
- package/dist/components/moni-carousel.d.ts.map +1 -1
- package/dist/components/moni-carousel.js +59 -16
- package/dist/components/moni-checkbox.d.ts +122 -17
- package/dist/components/moni-checkbox.d.ts.map +1 -1
- package/dist/components/moni-checkbox.js +118 -14
- package/dist/components/moni-chip.d.ts +56 -30
- package/dist/components/moni-chip.d.ts.map +1 -1
- package/dist/components/moni-chip.js +51 -25
- package/dist/components/moni-color-field.d.ts +44 -6
- package/dist/components/moni-color-field.d.ts.map +1 -1
- package/dist/components/moni-color-field.js +43 -5
- package/dist/components/moni-context-menu.d.ts +44 -22
- package/dist/components/moni-context-menu.d.ts.map +1 -1
- package/dist/components/moni-context-menu.js +43 -21
- package/dist/components/moni-dialog.d.ts +107 -15
- package/dist/components/moni-dialog.d.ts.map +1 -1
- package/dist/components/moni-dialog.js +105 -14
- package/dist/components/moni-divider.d.ts +50 -15
- package/dist/components/moni-divider.d.ts.map +1 -1
- package/dist/components/moni-divider.js +49 -14
- package/dist/components/moni-expansion.d.ts +44 -8
- package/dist/components/moni-expansion.d.ts.map +1 -1
- package/dist/components/moni-expansion.js +43 -7
- package/dist/components/moni-fab-menu.d.ts +39 -20
- package/dist/components/moni-fab-menu.d.ts.map +1 -1
- package/dist/components/moni-fab-menu.js +38 -19
- package/dist/components/moni-fab.d.ts +49 -23
- package/dist/components/moni-fab.d.ts.map +1 -1
- package/dist/components/moni-fab.js +46 -20
- package/dist/components/moni-file-field.d.ts +54 -14
- package/dist/components/moni-file-field.d.ts.map +1 -1
- package/dist/components/moni-file-field.js +53 -13
- package/dist/components/moni-icon.d.ts +78 -11
- package/dist/components/moni-icon.d.ts.map +1 -1
- package/dist/components/moni-icon.js +77 -10
- package/dist/components/moni-list-item.d.ts +61 -30
- package/dist/components/moni-list-item.d.ts.map +1 -1
- package/dist/components/moni-list-item.js +55 -24
- package/dist/components/moni-list.d.ts +37 -13
- package/dist/components/moni-list.d.ts.map +1 -1
- package/dist/components/moni-list.js +36 -12
- package/dist/components/moni-loading-indicator.d.ts +38 -11
- package/dist/components/moni-loading-indicator.d.ts.map +1 -1
- package/dist/components/moni-loading-indicator.js +37 -10
- package/dist/components/moni-menu-item.d.ts +31 -8
- package/dist/components/moni-menu-item.d.ts.map +1 -1
- package/dist/components/moni-menu-item.js +30 -7
- package/dist/components/moni-menu.d.ts +58 -33
- package/dist/components/moni-menu.d.ts.map +1 -1
- package/dist/components/moni-menu.js +51 -26
- package/dist/components/moni-morph-modal.d.ts +7 -1
- package/dist/components/moni-morph-modal.d.ts.map +1 -1
- package/dist/components/moni-morph-modal.js +46 -24
- package/dist/components/moni-nav-item.d.ts +50 -10
- package/dist/components/moni-nav-item.d.ts.map +1 -1
- package/dist/components/moni-nav-item.js +48 -8
- package/dist/components/moni-nav.d.ts +57 -22
- package/dist/components/moni-nav.d.ts.map +1 -1
- package/dist/components/moni-nav.js +53 -18
- package/dist/components/moni-progress.d.ts +108 -20
- package/dist/components/moni-progress.d.ts.map +1 -1
- package/dist/components/moni-progress.js +104 -16
- package/dist/components/moni-radio.d.ts +106 -14
- package/dist/components/moni-radio.d.ts.map +1 -1
- package/dist/components/moni-radio.js +104 -13
- package/dist/components/moni-ripple.d.ts +121 -10
- package/dist/components/moni-ripple.d.ts.map +1 -1
- package/dist/components/moni-ripple.js +120 -9
- package/dist/components/moni-segmented-button.d.ts +31 -11
- package/dist/components/moni-segmented-button.d.ts.map +1 -1
- package/dist/components/moni-segmented-button.js +30 -10
- package/dist/components/moni-select-option.d.ts +43 -9
- package/dist/components/moni-select-option.d.ts.map +1 -1
- package/dist/components/moni-select-option.js +41 -7
- package/dist/components/moni-select.d.ts +59 -2
- package/dist/components/moni-select.d.ts.map +1 -1
- package/dist/components/moni-select.js +58 -1
- package/dist/components/moni-shape.d.ts +1 -1
- package/dist/components/moni-side-sheet.d.ts +56 -19
- package/dist/components/moni-side-sheet.d.ts.map +1 -1
- package/dist/components/moni-side-sheet.js +53 -16
- package/dist/components/moni-slider.d.ts +56 -25
- package/dist/components/moni-slider.d.ts.map +1 -1
- package/dist/components/moni-slider.js +55 -24
- package/dist/components/moni-snackbar.d.ts +86 -17
- package/dist/components/moni-snackbar.d.ts.map +1 -1
- package/dist/components/moni-snackbar.js +85 -16
- package/dist/components/moni-split-button.d.ts +38 -9
- package/dist/components/moni-split-button.d.ts.map +1 -1
- package/dist/components/moni-split-button.js +37 -8
- package/dist/components/moni-step.d.ts +42 -9
- package/dist/components/moni-step.d.ts.map +1 -1
- package/dist/components/moni-step.js +41 -8
- package/dist/components/moni-stepper.d.ts +43 -6
- package/dist/components/moni-stepper.d.ts.map +1 -1
- package/dist/components/moni-stepper.js +42 -5
- package/dist/components/moni-switch.d.ts +103 -16
- package/dist/components/moni-switch.d.ts.map +1 -1
- package/dist/components/moni-switch.js +99 -13
- package/dist/components/moni-tab.d.ts +35 -8
- package/dist/components/moni-tab.d.ts.map +1 -1
- package/dist/components/moni-tab.js +34 -7
- package/dist/components/moni-tabs.d.ts +51 -13
- package/dist/components/moni-tabs.d.ts.map +1 -1
- package/dist/components/moni-tabs.js +48 -10
- package/dist/components/moni-text-field.d.ts +55 -10
- package/dist/components/moni-text-field.d.ts.map +1 -1
- package/dist/components/moni-text-field.js +54 -9
- package/dist/components/moni-textarea.d.ts +51 -21
- package/dist/components/moni-textarea.d.ts.map +1 -1
- package/dist/components/moni-textarea.js +48 -18
- package/dist/components/moni-time-picker.d.ts +41 -11
- package/dist/components/moni-time-picker.d.ts.map +1 -1
- package/dist/components/moni-time-picker.js +40 -10
- package/dist/components/moni-toolbar.d.ts +43 -15
- package/dist/components/moni-toolbar.d.ts.map +1 -1
- package/dist/components/moni-toolbar.js +42 -14
- package/dist/components/moni-tooltip.d.ts +55 -25
- package/dist/components/moni-tooltip.d.ts.map +1 -1
- package/dist/components/moni-tooltip.js +54 -24
- package/dist/components/moni-typography.d.ts +43 -18
- package/dist/components/moni-typography.d.ts.map +1 -1
- package/dist/components/moni-typography.js +42 -17
- package/dist/index.d.ts +47 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +59 -2
- package/dist/styles/tailwind.css +67 -0
- package/dist/styles/tokens.css +111 -99
- package/dist/utils/color.d.ts +181 -2
- package/dist/utils/color.d.ts.map +1 -1
- package/dist/utils/color.js +182 -4
- package/dist/utils/theme.svelte.d.ts +305 -2
- package/dist/utils/theme.svelte.d.ts.map +1 -1
- package/dist/utils/theme.svelte.js +331 -2
- package/dist/web-components.d.ts +28 -0
- package/dist/web-components.d.ts.map +1 -1
- package/dist/web-components.js +29 -2
- package/package.json +1 -1
- package/src/actions/index.ts +7 -0
- package/src/components/_base/field-styles.ts +165 -37
- package/src/components/_base/index.ts +27 -0
- package/src/components/_base/interaction-styles.ts +86 -33
- package/src/components/_base/moni-element.ts +44 -8
- package/src/components/_base/shared-styles.ts +114 -21
- package/src/components/index.ts +7 -0
- package/src/components/loading-shapes.ts +7 -0
- package/src/components/moni-app-bar.ts +127 -26
- package/src/components/moni-badge.ts +128 -14
- package/src/components/moni-bottom-sheet.ts +125 -13
- package/src/components/moni-button-group.ts +50 -23
- package/src/components/moni-button-segment.ts +28 -7
- package/src/components/moni-button.ts +51 -31
- package/src/components/moni-card.ts +90 -26
- package/src/components/moni-carousel.ts +67 -16
- package/src/components/moni-checkbox.ts +125 -14
- package/src/components/moni-chip.ts +52 -25
- package/src/components/moni-color-field.ts +44 -5
- package/src/components/moni-context-menu.ts +44 -21
- package/src/components/moni-dialog.ts +111 -14
- package/src/components/moni-divider.ts +50 -14
- package/src/components/moni-expansion.ts +44 -7
- package/src/components/moni-fab-menu.ts +39 -19
- package/src/components/moni-fab.ts +47 -20
- package/src/components/moni-file-field.ts +54 -13
- package/src/components/moni-icon.ts +80 -10
- package/src/components/moni-list-item.ts +56 -24
- package/src/components/moni-list.ts +37 -12
- package/src/components/moni-loading-indicator.ts +38 -10
- package/src/components/moni-menu-item.ts +31 -7
- package/src/components/moni-menu.ts +52 -26
- package/src/components/moni-morph-modal.ts +58 -24
- package/src/components/moni-nav-item.ts +49 -8
- package/src/components/moni-nav.ts +54 -18
- package/src/components/moni-progress.ts +109 -16
- package/src/components/moni-radio.ts +111 -13
- package/src/components/moni-ripple.ts +126 -9
- package/src/components/moni-segmented-button.ts +31 -10
- package/src/components/moni-select-option.ts +42 -7
- package/src/components/moni-select.ts +79 -1
- package/src/components/moni-side-sheet.ts +54 -16
- package/src/components/moni-slider.ts +56 -24
- package/src/components/moni-snackbar.ts +90 -16
- package/src/components/moni-split-button.ts +38 -8
- package/src/components/moni-step.ts +42 -8
- package/src/components/moni-stepper.ts +43 -5
- package/src/components/moni-switch.ts +106 -13
- package/src/components/moni-tab.ts +35 -7
- package/src/components/moni-tabs.ts +49 -10
- package/src/components/moni-text-field.ts +55 -9
- package/src/components/moni-textarea.ts +49 -18
- package/src/components/moni-time-picker.ts +41 -10
- package/src/components/moni-toolbar.ts +43 -14
- package/src/components/moni-tooltip.ts +55 -24
- package/src/components/moni-typography.ts +43 -17
- package/src/index.ts +67 -3
- package/src/styles/tailwind.css +67 -0
- package/src/styles/tokens.css +111 -99
- package/src/types/svelte-runes.d.ts +64 -2
- package/src/utils/color.ts +286 -5
- package/src/utils/theme.svelte.ts +411 -2
- package/src/web-components.ts +31 -2
- package/dist/assets/shapes/arch.svg +0 -1
- package/dist/assets/shapes/arrow.svg +0 -1
- package/dist/assets/shapes/boom.svg +0 -1
- package/dist/assets/shapes/burst.svg +0 -1
- package/dist/assets/shapes/circle.svg +0 -1
- package/dist/assets/shapes/clamshell.svg +0 -1
- package/dist/assets/shapes/diamond.svg +0 -1
- package/dist/assets/shapes/fan.svg +0 -1
- package/dist/assets/shapes/flower.svg +0 -1
- package/dist/assets/shapes/gem.svg +0 -1
- package/dist/assets/shapes/ghost-ish.svg +0 -1
- package/dist/assets/shapes/heart.svg +0 -1
- package/dist/assets/shapes/leaf-clover4.svg +0 -1
- package/dist/assets/shapes/leaf-clover8.svg +0 -1
- package/dist/assets/shapes/loading-indicator.svg +0 -1
- package/dist/assets/shapes/oval.svg +0 -1
- package/dist/assets/shapes/pentagon.svg +0 -1
- package/dist/assets/shapes/pill.svg +0 -1
- package/dist/assets/shapes/pixel-circle.svg +0 -1
- package/dist/assets/shapes/pixel-triangle.svg +0 -1
- package/dist/assets/shapes/puffy-diamond.svg +0 -1
- package/dist/assets/shapes/puffy.svg +0 -1
- package/dist/assets/shapes/semicircle.svg +0 -1
- package/dist/assets/shapes/sided-cookie12.svg +0 -1
- package/dist/assets/shapes/sided-cookie4.svg +0 -1
- package/dist/assets/shapes/sided-cookie6.svg +0 -1
- package/dist/assets/shapes/sided-cookie7.svg +0 -1
- package/dist/assets/shapes/sided-cookie9.svg +0 -1
- package/dist/assets/shapes/slanted.svg +0 -1
- package/dist/assets/shapes/soft-boom.svg +0 -1
- package/dist/assets/shapes/soft-burst.svg +0 -1
- package/dist/assets/shapes/square.svg +0 -1
- package/dist/assets/shapes/sunny.svg +0 -1
- package/dist/assets/shapes/triangle.svg +0 -1
- package/dist/assets/shapes/very-sunny.svg +0 -1
- package/dist/assets/shapes/wavy-circle.svg +0 -1
- package/dist/assets/shapes/wavy.svg +0 -1
- package/src/assets/shapes/arch.svg +0 -1
- package/src/assets/shapes/arrow.svg +0 -1
- package/src/assets/shapes/boom.svg +0 -1
- package/src/assets/shapes/burst.svg +0 -1
- package/src/assets/shapes/circle.svg +0 -1
- package/src/assets/shapes/clamshell.svg +0 -1
- package/src/assets/shapes/diamond.svg +0 -1
- package/src/assets/shapes/fan.svg +0 -1
- package/src/assets/shapes/flower.svg +0 -1
- package/src/assets/shapes/gem.svg +0 -1
- package/src/assets/shapes/ghost-ish.svg +0 -1
- package/src/assets/shapes/heart.svg +0 -1
- package/src/assets/shapes/leaf-clover4.svg +0 -1
- package/src/assets/shapes/leaf-clover8.svg +0 -1
- package/src/assets/shapes/loading-indicator.svg +0 -1
- package/src/assets/shapes/oval.svg +0 -1
- package/src/assets/shapes/pentagon.svg +0 -1
- package/src/assets/shapes/pill.svg +0 -1
- package/src/assets/shapes/pixel-circle.svg +0 -1
- package/src/assets/shapes/pixel-triangle.svg +0 -1
- package/src/assets/shapes/puffy-diamond.svg +0 -1
- package/src/assets/shapes/puffy.svg +0 -1
- package/src/assets/shapes/semicircle.svg +0 -1
- package/src/assets/shapes/sided-cookie12.svg +0 -1
- package/src/assets/shapes/sided-cookie4.svg +0 -1
- package/src/assets/shapes/sided-cookie6.svg +0 -1
- package/src/assets/shapes/sided-cookie7.svg +0 -1
- package/src/assets/shapes/sided-cookie9.svg +0 -1
- package/src/assets/shapes/slanted.svg +0 -1
- package/src/assets/shapes/soft-boom.svg +0 -1
- package/src/assets/shapes/soft-burst.svg +0 -1
- package/src/assets/shapes/square.svg +0 -1
- package/src/assets/shapes/sunny.svg +0 -1
- package/src/assets/shapes/triangle.svg +0 -1
- package/src/assets/shapes/very-sunny.svg +0 -1
- package/src/assets/shapes/wavy-circle.svg +0 -1
- package/src/assets/shapes/wavy.svg +0 -1
|
@@ -1,36 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file components/_base/field-styles.ts
|
|
3
|
+
* @package @moni-labs/moni-ui
|
|
4
|
+
* @license MIT
|
|
5
|
+
* @contributors Moni Labs & Contributors
|
|
6
|
+
*/
|
|
7
|
+
|
|
1
8
|
import { css } from 'lit';
|
|
2
9
|
|
|
3
10
|
/**
|
|
4
|
-
* Shared visual rules for
|
|
11
|
+
* Shared visual rules for all field-like input components.
|
|
12
|
+
*
|
|
13
|
+
* This stylesheet provides the complete CSS foundation for the Moni input
|
|
14
|
+
* field pattern, ported and extended from the BeerCSS field system. It is
|
|
15
|
+
* consumed by: `moni-text-field`, `moni-textarea`, `moni-select`,
|
|
16
|
+
* `moni-color-field`, and `moni-file-field`.
|
|
17
|
+
*
|
|
18
|
+
* **Required DOM structure:**
|
|
19
|
+
* Each consumer must render this exact DOM hierarchy inside its shadow root for
|
|
20
|
+
* all selectors (especially the floating label) to function correctly:
|
|
21
|
+
*
|
|
22
|
+
* ```html
|
|
23
|
+
* <div class="field [label] [fill|border] [small|large|extra] [prefix|suffix|icon] [invalid] [round*]">
|
|
24
|
+
* <i class="leading-icon">...</i> <!-- optional leading icon -->
|
|
25
|
+
* <input | select | textarea> <!-- native form control -->
|
|
26
|
+
* <label>Label text</label> <!-- MUST be immediately after the control -->
|
|
27
|
+
* <i class="trailing-icon">...</i> <!-- optional trailing icon -->
|
|
28
|
+
* <span class="suffix-text">...</span> <!-- optional suffix text -->
|
|
29
|
+
* <slot name="trailing"></slot> <!-- optional trailing slot -->
|
|
30
|
+
* <output>Helper or error text</output> <!-- helper / validation message -->
|
|
31
|
+
* </div>
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* **Critical ordering rule:**
|
|
35
|
+
* The `<label>` element MUST be the immediate next sibling of the
|
|
36
|
+
* `<input|select|textarea>`. The CSS adjacent sibling combinator (`+ label`)
|
|
37
|
+
* and the `:focus + label` selector depend on this ordering to animate the
|
|
38
|
+
* floating label lift. Breaking the order will prevent the label from animating.
|
|
5
39
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
40
|
+
* **Modifier classes:**
|
|
41
|
+
* - `.label` — Activates the floating label behavior.
|
|
42
|
+
* - `.fill` — Uses `surface-container-highest` as the input background (filled style).
|
|
43
|
+
* - `.border` — Applies an `outline-variant` border (outlined style).
|
|
44
|
+
* - `.small` / `.large` / `.extra` — Adjusts height and padding.
|
|
45
|
+
* - `.prefix` / `.suffix` — Shifts input padding to make room for icons.
|
|
46
|
+
* - `.invalid` — Applies error color to borders, label, and helper text.
|
|
47
|
+
* - `.round` / `.round-*` — Applies pill-shaped border radius to the field.
|
|
48
|
+
* - `.square` — Removes all border-radius (overrides everything via `!important`).
|
|
9
49
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* <slot name="trailing"> ← optional slot
|
|
17
|
-
* <output> ← helper text or error
|
|
18
|
-
* </div>
|
|
50
|
+
* **Internal CSS custom properties:**
|
|
51
|
+
* | Property | Default | Description |
|
|
52
|
+
* |------------|---------|------------------------------------------|
|
|
53
|
+
* | `--_input` | `3rem` | Height of the input area. |
|
|
54
|
+
* | `--_start` | `1.2rem`| Block-start padding for label alignment. |
|
|
55
|
+
* | `--_middle`| computed| Vertical center of the input (for icons).|
|
|
19
56
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* label. If a component reorders the DOM, the label may not animate properly.
|
|
57
|
+
* @see {@link sharedStyles} — Token bridge consumed by this stylesheet.
|
|
58
|
+
* @see {@link interactionStyles} — State layer (not used directly in fields).
|
|
23
59
|
*/
|
|
24
60
|
export const fieldStyles = css`
|
|
25
61
|
:host {
|
|
26
62
|
display: block;
|
|
63
|
+
/* Fields are full-width by default; the parent layout controls sizing. */
|
|
27
64
|
inline-size: 100%;
|
|
28
65
|
}
|
|
29
66
|
|
|
67
|
+
/* ─── Base field container ───────────────────────────────────────────────── */
|
|
30
68
|
.field {
|
|
69
|
+
/* Internal height token — overridden by size modifiers (.small, .large, .extra). */
|
|
31
70
|
--_input: 3rem;
|
|
71
|
+
/* Vertical start offset used for textarea padding and label positioning. */
|
|
32
72
|
--_start: 1.2rem;
|
|
73
|
+
/* Computed vertical center — used to position absolutely-placed icons. */
|
|
33
74
|
--_middle: calc(var(--_input, 0) / 2);
|
|
75
|
+
|
|
76
|
+
/* Default field shape: bottom border only (BeerCSS / MD3 "filled" style). */
|
|
34
77
|
border-radius: 0.25rem 0.25rem 0 0;
|
|
35
78
|
min-block-size: var(--_input);
|
|
36
79
|
display: flex;
|
|
@@ -39,17 +82,22 @@ export const fieldStyles = css`
|
|
|
39
82
|
inline-size: 100%;
|
|
40
83
|
}
|
|
41
84
|
|
|
42
|
-
/*
|
|
85
|
+
/* ─── Shape overrides ────────────────────────────────────────────────────── */
|
|
86
|
+
|
|
87
|
+
/* Square: removes all border-radius regardless of other modifiers.
|
|
88
|
+
Uses !important to win specificity over .border and [class*='round']. */
|
|
43
89
|
.field.square,
|
|
44
90
|
.field.square.border,
|
|
45
91
|
.field.square[class*='round'] {
|
|
46
92
|
border-radius: 0 !important;
|
|
47
93
|
}
|
|
48
|
-
|
|
49
94
|
.field.square > :is(input, textarea, select) {
|
|
50
95
|
border-radius: 0 !important;
|
|
51
96
|
}
|
|
52
97
|
|
|
98
|
+
/* ─── Fill variant ───────────────────────────────────────────────────────── */
|
|
99
|
+
/* Unsets background/color on the container; the background is applied
|
|
100
|
+
directly to the <input> so that the floating label overlaps it correctly. */
|
|
53
101
|
.field.fill {
|
|
54
102
|
--_background: var(--surface-container-highest);
|
|
55
103
|
background-color: unset !important;
|
|
@@ -57,9 +105,11 @@ export const fieldStyles = css`
|
|
|
57
105
|
}
|
|
58
106
|
.field.fill > :is(input, select, textarea) {
|
|
59
107
|
background-color: var(--_background);
|
|
108
|
+
/* z-index: 0 ensures the background renders above the ::before layer. */
|
|
60
109
|
z-index: 0;
|
|
61
110
|
}
|
|
62
111
|
|
|
112
|
+
/* ─── Size variants ──────────────────────────────────────────────────────── */
|
|
63
113
|
.field.small {
|
|
64
114
|
--_input: 2.5rem;
|
|
65
115
|
--_start: 1rem;
|
|
@@ -73,10 +123,14 @@ export const fieldStyles = css`
|
|
|
73
123
|
--_start: 1.6rem;
|
|
74
124
|
}
|
|
75
125
|
|
|
126
|
+
/* ─── Border (outlined) variant ─────────────────────────────────────────── */
|
|
127
|
+
/* Adds full border-radius and outline-variant stroke on all four sides. */
|
|
76
128
|
.field.border {
|
|
77
129
|
border-radius: 0.25rem;
|
|
78
130
|
}
|
|
79
131
|
|
|
132
|
+
/* ─── Round / pill variants ──────────────────────────────────────────────── */
|
|
133
|
+
/* Applied when class matches the 'round' substring (e.g. .round, .round-sm). */
|
|
80
134
|
.field[class*='round'].small {
|
|
81
135
|
border-radius: 1.25rem;
|
|
82
136
|
}
|
|
@@ -90,10 +144,8 @@ export const fieldStyles = css`
|
|
|
90
144
|
border-radius: 2rem;
|
|
91
145
|
}
|
|
92
146
|
|
|
93
|
-
/*
|
|
94
|
-
|
|
95
|
-
the position-suffix selectors and guarantee correct placement even when
|
|
96
|
-
the icon is wrapped in a custom element (e.g. <moni-icon>). */
|
|
147
|
+
/* ─── Icon positioning ───────────────────────────────────────────────────── */
|
|
148
|
+
/* Generic rule: absolutely positions any icon/image/svg inside the field. */
|
|
97
149
|
.field > :is(i, img, svg) {
|
|
98
150
|
position: absolute;
|
|
99
151
|
inset: calc((var(--_input, 0) / 2) - 0.75rem) auto auto auto;
|
|
@@ -104,31 +156,37 @@ export const fieldStyles = css`
|
|
|
104
156
|
margin: auto 0;
|
|
105
157
|
pointer-events: none;
|
|
106
158
|
}
|
|
159
|
+
/* Leading icon: explicit class wins over :first-child heuristic. */
|
|
107
160
|
.field > :is(i, img, svg):first-child,
|
|
108
161
|
.field > .leading-icon {
|
|
109
162
|
inset: calc(var(--_middle, 0) - 0.75rem) auto auto 1rem;
|
|
110
163
|
}
|
|
111
164
|
|
|
112
|
-
/* Trailing icon: BeerCSS uses :last-child:not(:first-child) which fails
|
|
113
|
-
|
|
114
|
-
|
|
165
|
+
/* Trailing icon: BeerCSS uses :last-child:not(:first-child) which fails when
|
|
166
|
+
an <output> follows the icon. The explicit class always wins and places
|
|
167
|
+
the icon on the right edge regardless of sibling count. */
|
|
115
168
|
.field > :is(i, img, svg):last-child:not(:first-child),
|
|
116
169
|
.field > .trailing-icon {
|
|
117
170
|
inset: calc(var(--_middle, 0) - 0.75rem) 1rem auto auto;
|
|
171
|
+
/* Prevent the inline-start override from the generic rule above. */
|
|
118
172
|
inset-inline-start: auto !important;
|
|
119
173
|
}
|
|
120
174
|
|
|
175
|
+
/* Error state: trailing icons inherit the error color. */
|
|
121
176
|
.field.invalid > i {
|
|
122
177
|
color: var(--error);
|
|
123
178
|
}
|
|
124
179
|
|
|
125
|
-
/*
|
|
180
|
+
/* ─── Native form element reset ──────────────────────────────────────────── */
|
|
181
|
+
/* 'all: unset' strips browser-default styles (appearance, border, font, etc.)
|
|
182
|
+
so the field's visual design is fully controlled by Moni's CSS. */
|
|
126
183
|
.field > :is(input, textarea, select) {
|
|
127
184
|
all: unset;
|
|
128
185
|
position: relative;
|
|
129
186
|
display: block;
|
|
130
187
|
box-sizing: border-box;
|
|
131
188
|
border-radius: inherit;
|
|
189
|
+
/* Default border is transparent; visible only in .border and focus states. */
|
|
132
190
|
border: 0.0625rem solid transparent;
|
|
133
191
|
padding: 0 0.9375rem;
|
|
134
192
|
font-family: inherit;
|
|
@@ -137,30 +195,42 @@ export const fieldStyles = css`
|
|
|
137
195
|
outline: none;
|
|
138
196
|
z-index: 1;
|
|
139
197
|
background: none;
|
|
140
|
-
resize: none;
|
|
198
|
+
resize: none; /* Textareas use field-sizing:content instead of manual resize. */
|
|
141
199
|
text-align: start;
|
|
142
200
|
cursor: text;
|
|
143
201
|
color: var(--on-surface);
|
|
144
202
|
}
|
|
145
203
|
|
|
204
|
+
/* Ensure date/time input values align to start (browser quirk on some platforms). */
|
|
146
205
|
input::-webkit-date-and-time-value {
|
|
147
206
|
text-align: start;
|
|
148
207
|
}
|
|
208
|
+
|
|
209
|
+
/* Autofill: preserve text color when the browser applies its autofill highlight.
|
|
210
|
+
-webkit-background-clip + -webkit-text-fill-color override the yellow tint. */
|
|
149
211
|
:is(input, select, textarea):is(:-webkit-autofill, :autofill) {
|
|
150
212
|
-webkit-background-clip: text;
|
|
151
213
|
-webkit-text-fill-color: var(--on-surface);
|
|
152
214
|
}
|
|
153
215
|
|
|
216
|
+
/* On focus, increase border width by 1px — shift padding inward by 1px
|
|
217
|
+
to prevent layout shift from the border width change. */
|
|
154
218
|
.field > :is(input, textarea, select):focus {
|
|
155
219
|
border: 0.125rem solid transparent;
|
|
156
220
|
padding-inline: 0.875rem;
|
|
157
221
|
}
|
|
158
222
|
|
|
223
|
+
/* Textareas without explicit rows grow automatically using field-sizing:content.
|
|
224
|
+
A max-height of 12rem (~8 lines) prevents uncontrolled page growth. */
|
|
159
225
|
.field > textarea:not([rows]) {
|
|
160
226
|
field-sizing: content;
|
|
161
227
|
max-block-size: 12rem;
|
|
162
228
|
}
|
|
163
229
|
|
|
230
|
+
/* ─── Transparent native picker controls ─────────────────────────────────── */
|
|
231
|
+
/* File and color inputs, and date/time picker indicators are hidden so the
|
|
232
|
+
component can render its own UI. The native controls are still active for
|
|
233
|
+
accessibility (click propagates through the transparent overlay). */
|
|
164
234
|
input[type='file'],
|
|
165
235
|
input[type='color'],
|
|
166
236
|
:not(.field) > input:is([type^='date'], [type^='time'], [type='month'], [type='week']),
|
|
@@ -177,12 +247,15 @@ export const fieldStyles = css`
|
|
|
177
247
|
z-index: 2 !important;
|
|
178
248
|
}
|
|
179
249
|
|
|
250
|
+
/* On fine-pointer (mouse) devices, push the calendar picker indicator behind
|
|
251
|
+
the field content so it doesn't interfere with other clickable elements. */
|
|
180
252
|
@media (pointer: fine) {
|
|
181
253
|
.field > input::-webkit-calendar-picker-indicator {
|
|
182
254
|
z-index: -1 !important;
|
|
183
255
|
}
|
|
184
256
|
}
|
|
185
257
|
|
|
258
|
+
/* Remove browser-native search field decorations. */
|
|
186
259
|
input::-webkit-search-decoration,
|
|
187
260
|
input::-webkit-search-cancel-button,
|
|
188
261
|
input::-webkit-search-results-button,
|
|
@@ -192,10 +265,12 @@ export const fieldStyles = css`
|
|
|
192
265
|
display: none;
|
|
193
266
|
}
|
|
194
267
|
|
|
268
|
+
/* Remove the browser spinner on number inputs — use explicit stepper UI instead. */
|
|
195
269
|
input[type='number'] {
|
|
196
270
|
appearance: textfield;
|
|
197
271
|
}
|
|
198
272
|
|
|
273
|
+
/* ─── Border variant: field-level border colors ──────────────────────────── */
|
|
199
274
|
.field.border > :is(input, textarea, select) {
|
|
200
275
|
border-color: var(--outline);
|
|
201
276
|
}
|
|
@@ -203,6 +278,7 @@ export const fieldStyles = css`
|
|
|
203
278
|
border-color: var(--primary);
|
|
204
279
|
}
|
|
205
280
|
|
|
281
|
+
/* Round variants add extra inline padding to clear the curved edges. */
|
|
206
282
|
.field[class*='round'] > :is(input, textarea, select) {
|
|
207
283
|
padding-inline: 1.4376rem;
|
|
208
284
|
}
|
|
@@ -210,13 +286,14 @@ export const fieldStyles = css`
|
|
|
210
286
|
padding-inline: 1.375rem;
|
|
211
287
|
}
|
|
212
288
|
|
|
289
|
+
/* ─── Icon padding accommodation ─────────────────────────────────────────── */
|
|
290
|
+
/* .prefix / .suffix shift the input's inline padding to make room for icons. */
|
|
213
291
|
.field.prefix > :is(input, textarea, select) {
|
|
214
292
|
padding-inline-start: 2.9375rem;
|
|
215
293
|
}
|
|
216
294
|
.field.prefix > :is(input, textarea, select):focus {
|
|
217
295
|
padding-inline-start: 2.875rem;
|
|
218
296
|
}
|
|
219
|
-
|
|
220
297
|
.field.suffix > :is(input, textarea, select) {
|
|
221
298
|
padding-inline-end: 2.9375rem;
|
|
222
299
|
}
|
|
@@ -224,6 +301,8 @@ export const fieldStyles = css`
|
|
|
224
301
|
padding-inline-end: 2.875rem;
|
|
225
302
|
}
|
|
226
303
|
|
|
304
|
+
/* ─── Underline (non-border, non-round) bottom border ─────────────────────── */
|
|
305
|
+
/* Default M3 filled field style: only the bottom border is visible. */
|
|
227
306
|
.field:not(.border, [class*='round']) > :is(input, textarea, select) {
|
|
228
307
|
border-block-end-color: var(--outline);
|
|
229
308
|
}
|
|
@@ -231,6 +310,7 @@ export const fieldStyles = css`
|
|
|
231
310
|
border-block-end-color: var(--primary);
|
|
232
311
|
}
|
|
233
312
|
|
|
313
|
+
/* Round non-bordered fields get a subtle elevation shadow instead of a border. */
|
|
234
314
|
.field[class*='round']:not(.border, .fill) > :is(input, textarea, select),
|
|
235
315
|
.field[class*='round']:not(.border) > :is(input, textarea, select):focus {
|
|
236
316
|
box-shadow: var(--elevate1);
|
|
@@ -239,6 +319,7 @@ export const fieldStyles = css`
|
|
|
239
319
|
box-shadow: var(--elevate2);
|
|
240
320
|
}
|
|
241
321
|
|
|
322
|
+
/* ─── Invalid / error state borders ─────────────────────────────────────── */
|
|
242
323
|
.field.invalid:not(.border, [class*='round']) > :is(input, textarea, select),
|
|
243
324
|
.field.invalid:not(.border, [class*='round']) > :is(input, textarea, select):focus {
|
|
244
325
|
border-block-end-color: var(--error);
|
|
@@ -248,6 +329,9 @@ export const fieldStyles = css`
|
|
|
248
329
|
border-color: var(--error);
|
|
249
330
|
}
|
|
250
331
|
|
|
332
|
+
/* ─── Disabled state ─────────────────────────────────────────────────────── */
|
|
333
|
+
/* Reduces opacity on the entire field container when the native control is
|
|
334
|
+
disabled, rather than applying separate rules to each child. */
|
|
251
335
|
.field:has(> :disabled) {
|
|
252
336
|
opacity: 0.5;
|
|
253
337
|
cursor: not-allowed;
|
|
@@ -256,6 +340,8 @@ export const fieldStyles = css`
|
|
|
256
340
|
cursor: not-allowed;
|
|
257
341
|
}
|
|
258
342
|
|
|
343
|
+
/* ─── Select element ─────────────────────────────────────────────────────── */
|
|
344
|
+
/* Remove browser-native select appearance; the component renders its own dropdown. */
|
|
259
345
|
.field > select {
|
|
260
346
|
user-select: none;
|
|
261
347
|
appearance: none;
|
|
@@ -263,17 +349,23 @@ export const fieldStyles = css`
|
|
|
263
349
|
background-image: none;
|
|
264
350
|
}
|
|
265
351
|
|
|
352
|
+
/* ─── Block-start padding for label accommodation ────────────────────────── */
|
|
353
|
+
/* Inputs with a floating label need top padding to create space for the
|
|
354
|
+
label when it lifts above the input. Selects always lift their label. */
|
|
266
355
|
.field > :is(input, select) {
|
|
267
356
|
padding-block-start: 1rem;
|
|
268
357
|
}
|
|
358
|
+
/* No-label and border+fill fields: remove the top padding offset. */
|
|
269
359
|
.field:not(.label) > :is(input, select),
|
|
270
360
|
.field.border:not(.fill) > :is(input, select) {
|
|
271
361
|
padding-block-start: 0;
|
|
272
362
|
}
|
|
363
|
+
/* Textareas use the --_start token to align with the label baseline. */
|
|
273
364
|
.field > textarea {
|
|
274
365
|
padding-block-start: var(--_start) !important;
|
|
275
366
|
}
|
|
276
367
|
.field > textarea:focus {
|
|
368
|
+
/* 0.01rem compensates for the border width increase on focus. */
|
|
277
369
|
padding-block-start: calc(var(--_start, 0) - 0.01rem) !important;
|
|
278
370
|
}
|
|
279
371
|
.field:not(.label) > textarea,
|
|
@@ -285,29 +377,42 @@ export const fieldStyles = css`
|
|
|
285
377
|
padding-block-start: calc(var(--_start, 0) - 0.51rem) !important;
|
|
286
378
|
}
|
|
287
379
|
|
|
288
|
-
/* Floating label */
|
|
380
|
+
/* ─── Floating label ─────────────────────────────────────────────────────── */
|
|
381
|
+
/* The label starts at full font-size (1rem) vertically centered in the field.
|
|
382
|
+
On focus or when value is present, it scales down to 0.75rem and lifts
|
|
383
|
+
to the top of the field container. */
|
|
289
384
|
.field.label > label {
|
|
290
385
|
--_start: 1rem;
|
|
291
386
|
position: absolute;
|
|
292
387
|
inset: -0.5rem 0.9375rem 0 var(--_start);
|
|
293
388
|
display: flex;
|
|
389
|
+
/* Full height + 1rem (for label overhang) centers the label vertically. */
|
|
294
390
|
block-size: calc(var(--_input, 0) + 1rem);
|
|
295
391
|
line-height: calc(var(--_input, 0) + 1rem);
|
|
296
392
|
font-size: 1rem;
|
|
297
393
|
transition: all 0.2s;
|
|
298
394
|
gap: 0.25rem;
|
|
299
395
|
white-space: nowrap;
|
|
396
|
+
/* The label is purely decorative from a layout perspective; it must never
|
|
397
|
+
intercept pointer events meant for the underlying input. */
|
|
300
398
|
pointer-events: none;
|
|
301
399
|
color: var(--on-surface-variant);
|
|
302
400
|
}
|
|
303
401
|
|
|
402
|
+
/* Round fields: label aligns with the increased inline padding. */
|
|
304
403
|
.field.label[class*='round'] > label {
|
|
305
404
|
inset: -0.5rem 1.9375rem 0 var(--_start);
|
|
306
405
|
}
|
|
307
406
|
|
|
308
|
-
/* Label lift
|
|
309
|
-
|
|
310
|
-
the
|
|
407
|
+
/* ─── Label lift selector group ──────────────────────────────────────────── */
|
|
408
|
+
/* The label lifts (scales down + moves up) in four conditions:
|
|
409
|
+
1. label.active — the component sets this class directly (readonly inputs).
|
|
410
|
+
2. :focus + label — when the native control is focused.
|
|
411
|
+
3. [placeholder]:not(:placeholder-shown) + label — when a value is present.
|
|
412
|
+
4. select + label — selects always show their label lifted.
|
|
413
|
+
5. input.active + label — for programmatically activated inputs. */
|
|
414
|
+
|
|
415
|
+
/* Border + prefix + no-fill variant needs a reduced --_start offset. */
|
|
311
416
|
.field.label.border.prefix:not(.fill)
|
|
312
417
|
> :is(
|
|
313
418
|
label.active,
|
|
@@ -319,6 +424,7 @@ export const fieldStyles = css`
|
|
|
319
424
|
--_start: 1rem;
|
|
320
425
|
}
|
|
321
426
|
|
|
427
|
+
/* Round field label and round border prefix field label override. */
|
|
322
428
|
.field.label[class*='round'] > label,
|
|
323
429
|
.field.label.border.prefix[class*='round']:not(.fill)
|
|
324
430
|
> :is(
|
|
@@ -331,10 +437,12 @@ export const fieldStyles = css`
|
|
|
331
437
|
--_start: 1.5rem;
|
|
332
438
|
}
|
|
333
439
|
|
|
440
|
+
/* Prefix fields: shift the label's inline-start to clear the leading icon. */
|
|
334
441
|
.field.label.prefix > label {
|
|
335
442
|
--_start: 3rem;
|
|
336
443
|
}
|
|
337
444
|
|
|
445
|
+
/* Lifted label: shrinks to 0.75rem and collapses to the top of the field. */
|
|
338
446
|
.field.label
|
|
339
447
|
> :is(
|
|
340
448
|
label.active,
|
|
@@ -348,6 +456,7 @@ export const fieldStyles = css`
|
|
|
348
456
|
font-size: 0.75rem;
|
|
349
457
|
}
|
|
350
458
|
|
|
459
|
+
/* Border variant: label collapses to 1rem height with a notch cut effect. */
|
|
351
460
|
.field.label.border:not(.fill)
|
|
352
461
|
> :is(
|
|
353
462
|
label.active,
|
|
@@ -360,6 +469,9 @@ export const fieldStyles = css`
|
|
|
360
469
|
line-height: 1rem;
|
|
361
470
|
}
|
|
362
471
|
|
|
472
|
+
/* ─── Border notch (label gap in the top border) ─────────────────────────── */
|
|
473
|
+
/* The ::after pseudo creates the horizontal line to the right of the lifted
|
|
474
|
+
label, visually cutting a notch into the top border of .field.border. */
|
|
363
475
|
.field.label.border:not(.fill) > label::after {
|
|
364
476
|
content: '';
|
|
365
477
|
display: block;
|
|
@@ -371,9 +483,14 @@ export const fieldStyles = css`
|
|
|
371
483
|
}
|
|
372
484
|
.field.label.border:not(.fill) > :focus + label::after,
|
|
373
485
|
.field.label.border:not(.fill) > input.active + label::after {
|
|
486
|
+
/* On focus, the notch line becomes primary-colored. */
|
|
374
487
|
border-block-start: 0.125rem solid var(--primary);
|
|
375
488
|
}
|
|
376
489
|
|
|
490
|
+
/* ─── Border notch clipping (clip-path) ──────────────────────────────────── */
|
|
491
|
+
/* When the label is lifted, a clip-path cuts a gap in the top border of the
|
|
492
|
+
input element itself, creating the appearance of the label floating within
|
|
493
|
+
the border's top edge. The clip-path dimensions account for label width. */
|
|
377
494
|
.field.label.border:not(.fill)
|
|
378
495
|
> :is(input, textarea):is(:focus, [placeholder]:not(:placeholder-shown), .active),
|
|
379
496
|
.field.label.border:not(.fill) > select,
|
|
@@ -391,6 +508,7 @@ export const fieldStyles = css`
|
|
|
391
508
|
);
|
|
392
509
|
}
|
|
393
510
|
|
|
511
|
+
/* Prefix variant: clip starts further right to clear the leading icon text. */
|
|
394
512
|
.field.label.border.prefix:not(.fill)
|
|
395
513
|
> :is(input, textarea):is(:focus, [placeholder]:not(:placeholder-shown), .active),
|
|
396
514
|
.field.label.border.prefix:not(.fill) > select,
|
|
@@ -408,6 +526,7 @@ export const fieldStyles = css`
|
|
|
408
526
|
);
|
|
409
527
|
}
|
|
410
528
|
|
|
529
|
+
/* Round and square border fields use a wider notch to clear the curved border. */
|
|
411
530
|
.field.label.border[class*='round']:not(.fill)
|
|
412
531
|
> :is(input, textarea):is(:focus, [placeholder]:not(:placeholder-shown), .active),
|
|
413
532
|
.field.label.border[class*='round']:not(.fill) > select,
|
|
@@ -435,18 +554,22 @@ export const fieldStyles = css`
|
|
|
435
554
|
clip-path: polygon(-2% -2%, 1.25rem -2%, 1.25rem 0.5rem, calc(100% - 2rem) 0.5rem, calc(100% - 2rem) -2%, 102% -2%, 102% 102%, -2% 102%);
|
|
436
555
|
}
|
|
437
556
|
|
|
557
|
+
/* ─── Label color changes ─────────────────────────────────────────────────── */
|
|
558
|
+
/* On focus: label turns primary-colored to draw attention. */
|
|
438
559
|
.field.label > :focus + label,
|
|
439
560
|
.field.label > input.active + label {
|
|
440
561
|
color: var(--primary);
|
|
441
562
|
}
|
|
442
563
|
|
|
564
|
+
/* On error: label and notch line turn error-colored. */
|
|
443
565
|
.field.label.invalid > label,
|
|
444
566
|
.field.label.invalid > label::after {
|
|
445
567
|
color: var(--error) !important;
|
|
446
568
|
border-color: var(--error) !important;
|
|
447
569
|
}
|
|
448
570
|
|
|
449
|
-
/* Helper / error output */
|
|
571
|
+
/* ─── Helper / error output ──────────────────────────────────────────────── */
|
|
572
|
+
/* The <output> element below the field shows helper text or validation errors. */
|
|
450
573
|
.field > output {
|
|
451
574
|
display: inline-block;
|
|
452
575
|
font-size: 0.75rem;
|
|
@@ -456,20 +579,23 @@ export const fieldStyles = css`
|
|
|
456
579
|
align-self: start;
|
|
457
580
|
color: var(--on-surface-variant);
|
|
458
581
|
}
|
|
582
|
+
/* Error output overrides the neutral helper color. */
|
|
459
583
|
.field > output.invalid {
|
|
460
584
|
color: var(--error) !important;
|
|
461
585
|
}
|
|
586
|
+
/* Round fields: increase horizontal padding to align with the curved edge. */
|
|
462
587
|
.field[class*='round'] > output {
|
|
463
588
|
padding: 0.25rem 1.5rem;
|
|
464
589
|
}
|
|
590
|
+
/* Show only one output at a time: helper OR error, never both. */
|
|
465
591
|
.field.invalid > output:not(.invalid),
|
|
466
592
|
.field:not(.invalid) > output.invalid {
|
|
467
593
|
display: none;
|
|
468
594
|
}
|
|
469
595
|
|
|
470
|
-
/* Footer wrapper
|
|
471
|
-
|
|
472
|
-
|
|
596
|
+
/* ─── Footer wrapper (textarea & multi-line fields) ───────────────────────── */
|
|
597
|
+
/* Lays out helper text (left) and character counter (right) on the same row,
|
|
598
|
+
matching the M3 spec for supporting-text + character-counter pairs. */
|
|
473
599
|
.field > .footer {
|
|
474
600
|
display: flex;
|
|
475
601
|
align-items: center;
|
|
@@ -490,13 +616,16 @@ export const fieldStyles = css`
|
|
|
490
616
|
.field > .footer > output.invalid {
|
|
491
617
|
color: var(--error) !important;
|
|
492
618
|
}
|
|
619
|
+
/* Character counter — right-aligned, same typographic style as the helper. */
|
|
493
620
|
.field > .footer > .counter {
|
|
494
621
|
padding: 0.25rem 1rem;
|
|
495
622
|
color: var(--on-surface-variant);
|
|
496
623
|
}
|
|
624
|
+
/* Spacer pushes counter to the right when there is no helper text. */
|
|
497
625
|
.field > .footer > .spacer {
|
|
498
626
|
flex: 1;
|
|
499
627
|
}
|
|
628
|
+
/* Same exclusive show logic as direct <output> elements. */
|
|
500
629
|
.field.invalid > .footer > output:not(.invalid),
|
|
501
630
|
.field:not(.invalid) > .footer > output.invalid {
|
|
502
631
|
display: none;
|
|
@@ -504,4 +633,3 @@ export const fieldStyles = css`
|
|
|
504
633
|
`;
|
|
505
634
|
|
|
506
635
|
export default fieldStyles;
|
|
507
|
-
|
|
@@ -1,3 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file components/_base/index.ts
|
|
3
|
+
* @package @moni-labs/moni-ui
|
|
4
|
+
* @license MIT
|
|
5
|
+
* @contributors Moni Labs & Contributors
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @module _base
|
|
10
|
+
*
|
|
11
|
+
* Re-exports the foundational building blocks shared by all Moni Web Components.
|
|
12
|
+
*
|
|
13
|
+
* **Exports:**
|
|
14
|
+
* - {@link MoniElement} — Abstract LitElement base class every component extends.
|
|
15
|
+
* - {@link sharedStyles} — Baseline CSS: box-sizing, token bridge, utility classes.
|
|
16
|
+
* - {@link fieldStyles} — CSS for field-like input components (text-field, select, etc.).
|
|
17
|
+
*
|
|
18
|
+
* `interactionStyles` is intentionally **not** re-exported from this barrel —
|
|
19
|
+
* it should be imported directly by components that need state layers to avoid
|
|
20
|
+
* adding its CSS to components that don't use `.interactive`.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* import { MoniElement, sharedStyles, fieldStyles } from './_base/index.js';
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
|
|
1
28
|
export { MoniElement } from './moni-element.js';
|
|
2
29
|
export { sharedStyles } from './shared-styles.js';
|
|
3
30
|
export { fieldStyles } from './field-styles.js';
|