@expressivecss/expressive 0.9.0 → 0.10.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/CHANGELOG.md +174 -1
- package/README.md +178 -25
- package/dist/css/expressive.css +365 -1222
- package/dist/css/expressive.css.map +1 -1
- package/dist/css/expressive.min.css +1 -1
- package/dist/css/expressive.min.css.map +1 -1
- package/dist/fonts/material-symbols-outlined.woff2 +0 -0
- package/dist/fonts/material-symbols-rounded.woff2 +0 -0
- package/dist/fonts/material-symbols-sharp.woff2 +0 -0
- package/dist/js/chunks/chunk-7MM4VJJO.mjs +509 -0
- package/dist/js/chunks/chunk-7MM4VJJO.mjs.map +7 -0
- package/dist/js/chunks/chunk-7UXHSYIA.mjs +183 -0
- package/dist/js/chunks/chunk-7UXHSYIA.mjs.map +7 -0
- package/dist/js/chunks/chunk-A3BJA7V4.mjs +28 -0
- package/dist/js/chunks/chunk-A3BJA7V4.mjs.map +7 -0
- package/dist/js/chunks/chunk-AOGFNMXS.mjs +691 -0
- package/dist/js/chunks/chunk-AOGFNMXS.mjs.map +7 -0
- package/dist/js/chunks/chunk-D4UZ4HFN.mjs +560 -0
- package/dist/js/chunks/chunk-D4UZ4HFN.mjs.map +7 -0
- package/dist/js/chunks/chunk-EP3CVKB5.mjs +88 -0
- package/dist/js/chunks/chunk-EP3CVKB5.mjs.map +7 -0
- package/dist/js/chunks/chunk-G576EP5O.mjs +459 -0
- package/dist/js/chunks/chunk-G576EP5O.mjs.map +7 -0
- package/dist/js/chunks/chunk-GY2Z5CJ2.mjs +320 -0
- package/dist/js/chunks/chunk-GY2Z5CJ2.mjs.map +7 -0
- package/dist/js/chunks/chunk-JKNPQQWY.mjs +191 -0
- package/dist/js/chunks/chunk-JKNPQQWY.mjs.map +7 -0
- package/dist/js/chunks/chunk-JNPIWFJT.mjs +365 -0
- package/dist/js/chunks/chunk-JNPIWFJT.mjs.map +7 -0
- package/dist/js/chunks/chunk-JODJAGFS.mjs +267 -0
- package/dist/js/chunks/chunk-JODJAGFS.mjs.map +7 -0
- package/dist/js/chunks/chunk-JR24UB4X.mjs +100 -0
- package/dist/js/chunks/chunk-JR24UB4X.mjs.map +7 -0
- package/dist/js/chunks/chunk-KR44BSYQ.mjs +55 -0
- package/dist/js/chunks/chunk-KR44BSYQ.mjs.map +7 -0
- package/dist/js/chunks/chunk-LZVBJ33S.mjs +102 -0
- package/dist/js/chunks/chunk-LZVBJ33S.mjs.map +7 -0
- package/dist/js/chunks/chunk-MISGHDUU.mjs +326 -0
- package/dist/js/chunks/chunk-MISGHDUU.mjs.map +7 -0
- package/dist/js/chunks/chunk-N3UHGN3N.mjs +175 -0
- package/dist/js/chunks/chunk-N3UHGN3N.mjs.map +7 -0
- package/dist/js/chunks/chunk-PB5L3EXF.mjs +7 -0
- package/dist/js/chunks/chunk-PB5L3EXF.mjs.map +7 -0
- package/dist/js/chunks/chunk-PIIAEYAJ.mjs +85 -0
- package/dist/js/chunks/chunk-PIIAEYAJ.mjs.map +7 -0
- package/dist/js/chunks/chunk-QSQ24FYT.mjs +59 -0
- package/dist/js/chunks/chunk-QSQ24FYT.mjs.map +7 -0
- package/dist/js/chunks/chunk-QYCYP443.mjs +1111 -0
- package/dist/js/chunks/chunk-QYCYP443.mjs.map +7 -0
- package/dist/js/chunks/chunk-SLFNPY5M.mjs +78 -0
- package/dist/js/chunks/chunk-SLFNPY5M.mjs.map +7 -0
- package/dist/js/chunks/chunk-TK6PX2GC.mjs +663 -0
- package/dist/js/chunks/chunk-TK6PX2GC.mjs.map +7 -0
- package/dist/js/chunks/chunk-TYM6U5DY.mjs +76 -0
- package/dist/js/chunks/chunk-TYM6U5DY.mjs.map +7 -0
- package/dist/js/chunks/chunk-TZZ24ZQS.mjs +154 -0
- package/dist/js/chunks/chunk-TZZ24ZQS.mjs.map +7 -0
- package/dist/js/chunks/chunk-VAS6JQ6P.mjs +94 -0
- package/dist/js/chunks/chunk-VAS6JQ6P.mjs.map +7 -0
- package/dist/js/chunks/chunk-WWPAPHMA.mjs +1 -0
- package/dist/js/chunks/chunk-WWPAPHMA.mjs.map +7 -0
- package/dist/js/chunks/chunk-XDB3G6RL.mjs +114 -0
- package/dist/js/chunks/chunk-XDB3G6RL.mjs.map +7 -0
- package/dist/js/chunks/chunk-XO5WX3TK.mjs +226 -0
- package/dist/js/chunks/chunk-XO5WX3TK.mjs.map +7 -0
- package/dist/js/chunks/chunk-YFXEJ7GR.mjs +286 -0
- package/dist/js/chunks/chunk-YFXEJ7GR.mjs.map +7 -0
- package/dist/js/chunks/chunk-ZIZVUWRL.mjs +120 -0
- package/dist/js/chunks/chunk-ZIZVUWRL.mjs.map +7 -0
- package/dist/js/chunks/chunk-ZZBZI2XN.mjs +338 -0
- package/dist/js/chunks/chunk-ZZBZI2XN.mjs.map +7 -0
- package/dist/js/expressive.cjs +801 -761
- package/dist/js/expressive.cjs.map +4 -4
- package/dist/js/expressive.js +801 -761
- package/dist/js/expressive.js.map +4 -4
- package/dist/js/expressive.min.js +11 -15
- package/dist/js/expressive.min.js.map +4 -4
- package/dist/js/expressive.mjs +83 -7443
- package/dist/js/expressive.mjs.map +4 -4
- package/dist/js/internal/behaviors/bottomSheets.mjs +9 -0
- package/dist/js/internal/behaviors/bottomSheets.mjs.map +7 -0
- package/dist/js/internal/behaviors/dialogs.mjs +8 -0
- package/dist/js/internal/behaviors/dialogs.mjs.map +7 -0
- package/dist/js/internal/behaviors/forms.mjs +8 -0
- package/dist/js/internal/behaviors/forms.mjs.map +7 -0
- package/dist/js/internal/behaviors/sheetDrag.mjs +8 -0
- package/dist/js/internal/behaviors/sheetDrag.mjs.map +7 -0
- package/dist/js/internal/behaviors/sideSheets.mjs +9 -0
- package/dist/js/internal/behaviors/sideSheets.mjs.map +7 -0
- package/dist/js/internal/components/appBar.mjs +8 -0
- package/dist/js/internal/components/appBar.mjs.map +7 -0
- package/dist/js/internal/components/autocomplete.mjs +10 -0
- package/dist/js/internal/components/autocomplete.mjs.map +7 -0
- package/dist/js/internal/components/buttonGroup.mjs +8 -0
- package/dist/js/internal/components/buttonGroup.mjs.map +7 -0
- package/dist/js/internal/components/buttons.mjs +9 -0
- package/dist/js/internal/components/buttons.mjs.map +7 -0
- package/dist/js/internal/components/cards.mjs +13 -0
- package/dist/js/internal/components/cards.mjs.map +7 -0
- package/dist/js/internal/components/carousel.mjs +9 -0
- package/dist/js/internal/components/carousel.mjs.map +7 -0
- package/dist/js/internal/components/characterCounter.mjs +8 -0
- package/dist/js/internal/components/characterCounter.mjs.map +7 -0
- package/dist/js/internal/components/chips.mjs +11 -0
- package/dist/js/internal/components/chips.mjs.map +7 -0
- package/dist/js/internal/components/datepicker.mjs +12 -0
- package/dist/js/internal/components/datepicker.mjs.map +7 -0
- package/dist/js/internal/components/expandingCard.mjs +11 -0
- package/dist/js/internal/components/expandingCard.mjs.map +7 -0
- package/dist/js/internal/components/index.mjs +88 -0
- package/dist/js/internal/components/index.mjs.map +7 -0
- package/dist/js/internal/components/lightbox.mjs +9 -0
- package/dist/js/internal/components/lightbox.mjs.map +7 -0
- package/dist/js/internal/components/menu.mjs +9 -0
- package/dist/js/internal/components/menu.mjs.map +7 -0
- package/dist/js/internal/components/navigationRail.mjs +8 -0
- package/dist/js/internal/components/navigationRail.mjs.map +7 -0
- package/dist/js/internal/components/registry.mjs +33 -0
- package/dist/js/internal/components/registry.mjs.map +7 -0
- package/dist/js/internal/components/scrollspy.mjs +8 -0
- package/dist/js/internal/components/scrollspy.mjs.map +7 -0
- package/dist/js/internal/components/select.mjs +10 -0
- package/dist/js/internal/components/select.mjs.map +7 -0
- package/dist/js/internal/components/slider.mjs +9 -0
- package/dist/js/internal/components/slider.mjs.map +7 -0
- package/dist/js/internal/components/snackbar.mjs +8 -0
- package/dist/js/internal/components/snackbar.mjs.map +7 -0
- package/dist/js/internal/components/tabs.mjs +10 -0
- package/dist/js/internal/components/tabs.mjs.map +7 -0
- package/dist/js/internal/components/timepicker.mjs +10 -0
- package/dist/js/internal/components/timepicker.mjs.map +7 -0
- package/dist/js/internal/components/tooltip.mjs +9 -0
- package/dist/js/internal/components/tooltip.mjs.map +7 -0
- package/dist/js/internal/core/component.mjs +7 -0
- package/dist/js/internal/core/component.mjs.map +7 -0
- package/dist/js/internal/core/utils.mjs +7 -0
- package/dist/js/internal/core/utils.mjs.map +7 -0
- package/dist/js/internal/plugins/dockedDisplayPlugin.mjs +8 -0
- package/dist/js/internal/plugins/dockedDisplayPlugin.mjs.map +7 -0
- package/dist/js/modular.mjs +113 -0
- package/dist/js/modular.mjs.map +7 -0
- package/dist/types/behaviors/sheetDrag.d.ts +1 -1
- package/dist/types/components/appBar.d.ts +1 -1
- package/dist/types/components/autocomplete.d.ts +9 -0
- package/dist/types/components/buttons.d.ts +4 -39
- package/dist/types/components/carousel.d.ts +10 -1
- package/dist/types/components/chips.d.ts +1 -0
- package/dist/types/components/datepicker.d.ts +11 -0
- package/dist/types/components/index.d.ts +0 -2
- package/dist/types/components/lightbox.d.ts +12 -0
- package/dist/types/components/menu.d.ts +3 -0
- package/dist/types/components/registry.d.ts +0 -4
- package/dist/types/components/select.d.ts +4 -0
- package/dist/types/components/slider.d.ts +2 -1
- package/dist/types/components/snackbar.d.ts +4 -2
- package/dist/types/components/tabs.d.ts +2 -1
- package/dist/types/components/timepicker.d.ts +5 -3
- package/dist/types/components/tooltip.d.ts +5 -3
- package/dist/types/index.d.ts +1 -8
- package/dist/types/modular.d.ts +28 -0
- package/package.json +16 -4
- package/src/sass/README.md +8 -0
- package/src/sass/components/_badges.scss +1 -6
- package/src/sass/components/_button-groups.scss +5 -1
- package/src/sass/components/_buttons.scss +8 -287
- package/src/sass/components/_chips.scss +17 -2
- package/src/sass/components/_dialog.scss +9 -4
- package/src/sass/components/_fab-menu.scss +11 -9
- package/src/sass/components/_icon-buttons.scss +0 -5
- package/src/sass/components/_index.scss +0 -5
- package/src/sass/components/_menu.scss +2 -2
- package/src/sass/components/_navigation-rail.scss +1 -1
- package/src/sass/components/_panes.scss +50 -78
- package/src/sass/components/_progress.scss +73 -13
- package/src/sass/components/_scrim.scss +4 -4
- package/src/sass/components/_side-sheet.scss +22 -12
- package/src/sass/components/_toolbar.scss +1 -4
- package/src/sass/components/_tooltip.scss +20 -2
- package/src/sass/components/forms/_input-fields.scss +5 -1
- package/src/sass/components/forms/_select.scss +1 -0
- package/src/sass/components/forms/_slider.scss +81 -25
- package/src/sass/custom.scss +38 -0
- package/dist/types/components/navigationDrawer.d.ts +0 -110
- package/src/sass/components/_banners.scss +0 -298
- package/src/sass/components/_bottom-app-bar.scss +0 -180
- package/src/sass/components/_floating-sheet.scss +0 -86
- package/src/sass/components/_navigation-drawer.scss +0 -476
- package/src/sass/components/_segmented-buttons.scss +0 -188
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,177 @@ the format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [0.10.0] - 2026-09-18
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- Connected button groups preserve equal-width items when translated labels
|
|
13
|
+
exceed the available width. The group expands inside an overflow container
|
|
14
|
+
instead of letting labels overlap adjacent controls.
|
|
15
|
+
|
|
16
|
+
- Bottom and floating sheets keep long bodies scrollable and action rows reachable
|
|
17
|
+
at compact widths with enlarged text. Shared dialog headings and action labels
|
|
18
|
+
wrap instead of overflowing their inset container without resizing icon buttons
|
|
19
|
+
or FABs.
|
|
20
|
+
|
|
21
|
+
- Datepicker initializes multiple-date defaults safely, keeps generated inputs
|
|
22
|
+
synchronized when selections shrink or grow, and preserves the original input
|
|
23
|
+
when cleared. Range-end inputs supplied by applications receive input and
|
|
24
|
+
keyboard handlers. Teardown removes generated fields and their listeners.
|
|
25
|
+
|
|
26
|
+
- Timepicker digital fields synchronize native input events, including paste,
|
|
27
|
+
without depending on keyup. Invalid edits restore the last valid value on blur;
|
|
28
|
+
empty fields display the same fallback values they submit. Twelve-hour defaults
|
|
29
|
+
handle midnight, noon, 24-hour input strings and lowercase AM/PM consistently.
|
|
30
|
+
|
|
31
|
+
- Lightbox cancels interrupted transitions, honors mounted reduced-motion changes,
|
|
32
|
+
preserves teardown focus and releases shared ancestor overflow after the last
|
|
33
|
+
open instance closes. Canceled transitions no longer report completion.
|
|
34
|
+
Overlay dismissal stays closed inside button triggers, and shadow-root teardown
|
|
35
|
+
respects focus moved outside the root by application handlers.
|
|
36
|
+
|
|
37
|
+
- Enhanced selects synchronize native form resets, selection semantics and
|
|
38
|
+
refreshed disabled states. Disabled optgroups cannot be selected, and refresh
|
|
39
|
+
preserves focus on a surviving option in an open menu and rebinds reset handling
|
|
40
|
+
after form-owner changes.
|
|
41
|
+
|
|
42
|
+
- Pane layouts use the nearest ancestor query-container width, with viewport
|
|
43
|
+
fallback, for columns, compact visibility, margins and dividers. Long footer
|
|
44
|
+
actions wrap without changing application-owned pane selection or icon-button sizes.
|
|
45
|
+
|
|
46
|
+
- App-bar search dialogs stay closed during native focus restoration and reopen
|
|
47
|
+
on a fresh focus or click. Teardown removes the search activation listeners.
|
|
48
|
+
|
|
49
|
+
- Tabs keep swipe selection, `aria-current`, and the `onShow` panel synchronized
|
|
50
|
+
without duplicate callbacks. Swipeable teardown restores panel positions and
|
|
51
|
+
owned state; initialization above `responsiveThreshold` uses ordinary panels.
|
|
52
|
+
Initial hash selection takes precedence over stale authored panel state.
|
|
53
|
+
|
|
54
|
+
- Side sheets mirror dragging, entry motion and modal corners in RTL while
|
|
55
|
+
preserving logical start/end aliases. Long headings and action rows wrap.
|
|
56
|
+
Side and bottom sheets ignore secondary-pointer cancellation and clear drag
|
|
57
|
+
state when closed, removed, or interrupted by another primary press, including
|
|
58
|
+
close/reopen and remove/reattach sequences within one JavaScript task.
|
|
59
|
+
|
|
60
|
+
- Carousel mirrors horizontal navigation and scroll placement in RTL, leaves
|
|
61
|
+
editable keys alone, and keeps auto-advance suspended during internal focus
|
|
62
|
+
moves. Mounted reduced-motion changes preserve explicit pause and stop
|
|
63
|
+
in-flight smooth scrolling. Native gestures cancel deferred recentering. Teardown
|
|
64
|
+
cancels scroll-completion timers and listeners. The docs demonstrate an
|
|
65
|
+
application-owned pause/resume button using the existing methods.
|
|
66
|
+
|
|
67
|
+
- Slider labels and track gaps account for native handle travel in LTR, RTL and
|
|
68
|
+
vertical layouts. Paired inputs accept native track clicks and their vertical
|
|
69
|
+
track resizes with the inputs. Application input events update values without
|
|
70
|
+
dragging, and forced-colors tracks use system colors.
|
|
71
|
+
|
|
72
|
+
- Chips delete the focused token with Backspace/Delete and recover focus without
|
|
73
|
+
overriding deletion callbacks. Destroying one instance preserves other instances'
|
|
74
|
+
keyboard handlers. Input chips no longer inherit floating-label positioning;
|
|
75
|
+
long labels wrap without shrinking their delete controls.
|
|
76
|
+
|
|
77
|
+
- Closing menus immediately exclude their content from keyboard focus and
|
|
78
|
+
preserve focus moved by close callbacks. Nested keyboard navigation and
|
|
79
|
+
typeahead stay in their active menu; RTL flyouts mirror their keys and avoid
|
|
80
|
+
either viewport edge. Returning focus to a parent no longer reopens a flyout.
|
|
81
|
+
|
|
82
|
+
- Native and custom progress indicators use system colors in forced-colors mode.
|
|
83
|
+
Empty linear tracks remain outlined, circular values retain a visible track,
|
|
84
|
+
and the legacy preloader stops rotating under reduced motion.
|
|
85
|
+
|
|
86
|
+
- Custom linear progress fills and indeterminate motion follow the inherited
|
|
87
|
+
text direction, including RTL and nested direction overrides. Reduced-motion
|
|
88
|
+
static fills use the same starting edge.
|
|
89
|
+
|
|
90
|
+
- Autocomplete exposes localized loading, result and multi-selection updates
|
|
91
|
+
through a polite live region. Teardown removes owned status elements and Menu
|
|
92
|
+
listeners, and late results after destruction are ignored.
|
|
93
|
+
|
|
94
|
+
- Date picker calendars support a single Tab stop, arrow keys, Home/End,
|
|
95
|
+
PageUp/PageDown and Shift for year navigation. Redraws preserve calendar focus,
|
|
96
|
+
and disabled days expose their unavailable state without allowing selection.
|
|
97
|
+
|
|
98
|
+
- Time picker hour/minute inputs have localized accessible names. Native AM/PM
|
|
99
|
+
buttons expose selected state and support Enter and Space without submitting
|
|
100
|
+
forms. Docked opening focuses the visible hour input; 24-hour entry accepts 00.
|
|
101
|
+
|
|
102
|
+
### Migration
|
|
103
|
+
|
|
104
|
+
- Snackbars with `action` now default to `displayLength: Infinity` and
|
|
105
|
+
`dismissible: true`. Explicit options still override these defaults. Custom
|
|
106
|
+
template controls need these options explicitly. Timed feedback needs an
|
|
107
|
+
equivalent persistent message in the application.
|
|
108
|
+
|
|
109
|
+
- Replace `circle extra small` with `circle extra` for the 56dp FAB.
|
|
110
|
+
Extended FABs require an explicit size: replace sizeless `extend` with
|
|
111
|
+
`extend small`, or choose `extend medium` or `extend large`.
|
|
112
|
+
Use primary, secondary or tertiary container colors instead of surface-colored
|
|
113
|
+
FABs. General surface utilities remain available for other components.
|
|
114
|
+
|
|
115
|
+
- Replace FAB speed-dial wrappers `.fab` and `.fixed-action-btn` with
|
|
116
|
+
`.fab-menu` and labelled actions. Remove `direction`, `hoverEnabled`,
|
|
117
|
+
`toolbarEnabled` and their markup switches. Use a toolbar for persistent
|
|
118
|
+
commands instead of FAB-to-toolbar expansion.
|
|
119
|
+
|
|
120
|
+
- Replace banners with native inline messages for persistent nonblocking issues,
|
|
121
|
+
snackbars for temporary feedback, or dialogs for blocking decisions.
|
|
122
|
+
Remove banner classes, tokens and custom Sass imports. The existing
|
|
123
|
+
`/banners.html` route now explains the migration.
|
|
124
|
+
|
|
125
|
+
- Replace `.floating-sheet` with a dialog for blocking work, a bottom sheet on
|
|
126
|
+
compact layouts, or a side sheet for optional content on wider layouts.
|
|
127
|
+
|
|
128
|
+
- Replace `.bottom-app-bar` with `.toolbar.docked` or `.toolbar.fixed`. Place an
|
|
129
|
+
adjacent FAB in `.toolbar-group` when the layout needs one.
|
|
130
|
+
- Replace `.navigation-drawer`, `.sidenav`, `NavigationDrawer`, and `Sidenav`
|
|
131
|
+
with `NavigationRail`. Use a navigation bar on compact layouts when the same
|
|
132
|
+
hierarchy fits; use a native full-screen dialog for a larger compact menu.
|
|
133
|
+
- Replace `.segmented-button` with `.button-group.connected`. Keep native radio
|
|
134
|
+
or checkbox inputs when form submission is required, and synchronize button
|
|
135
|
+
state with those inputs in application code.
|
|
136
|
+
|
|
137
|
+
### Changed
|
|
138
|
+
|
|
139
|
+
- Escape dismisses a focused snackbar without closing its parent dialog.
|
|
140
|
+
Dismissal and replacement recover focus when it remains inside the snackbar;
|
|
141
|
+
closing controls are inert, and application-directed focus is preserved.
|
|
142
|
+
|
|
143
|
+
- The documentation shell now uses a five-category rail with a page list on
|
|
144
|
+
wide layouts and a native full-screen navigation dialog on compact layouts.
|
|
145
|
+
Removed component URLs redirect to their replacement documentation.
|
|
146
|
+
|
|
147
|
+
### Removed
|
|
148
|
+
|
|
149
|
+
- The 40dp small FAB and baseline sizeless extended FAB styling. Current small
|
|
150
|
+
extended FABs, medium/large FABs and FAB menus remain supported.
|
|
151
|
+
|
|
152
|
+
- FAB speed-dial styling, hover/directional layouts, toolbar expansion, and
|
|
153
|
+
legacy AutoInit selectors. The `FloatingActionButton` API now serves FAB menus.
|
|
154
|
+
|
|
155
|
+
- Banner Sass, component semantics, generated component guides and variant tests.
|
|
156
|
+
|
|
157
|
+
- Floating sheet Sass, documentation, semantics, generated guides and tests.
|
|
158
|
+
|
|
159
|
+
- Bottom app bar Sass, navigation drawer Sass and runtime APIs, segmented
|
|
160
|
+
button Sass, their documentation pages, semantics, generated guides, and
|
|
161
|
+
component-specific tests.
|
|
162
|
+
|
|
163
|
+
## [0.9.1] - 2026-09-08
|
|
164
|
+
|
|
165
|
+
Includes the fixes from [#140](https://github.com/BaezFJ/ExpressiveCSS/pull/140).
|
|
166
|
+
|
|
167
|
+
### Migration from 0.9.0
|
|
168
|
+
|
|
169
|
+
Custom Datepicker row renderers must return calendar rows, cells, and day buttons
|
|
170
|
+
with supported attributes. Use `renderDay` to generate cells and set
|
|
171
|
+
`type="button"` on custom day buttons. Unsupported HTML now throws `TypeError`.
|
|
172
|
+
|
|
173
|
+
### Fixed
|
|
174
|
+
|
|
175
|
+
- Validate enhanced-select icon URLs and encode calendar identifiers and day values.
|
|
176
|
+
- Restrict Datepicker's low-level row renderers to calendar rows, cells, and day buttons. Custom renderers must use supported attributes and `type="button"`; unsupported HTML now throws `TypeError`.
|
|
177
|
+
- Preserve special characters in generated semantics tables and correct the documentation-script and floating-sheet test patterns.
|
|
178
|
+
|
|
8
179
|
## [0.9.0] - 2026-09-08
|
|
9
180
|
|
|
10
181
|
### Migration from 0.8.0
|
|
@@ -1493,7 +1664,9 @@ are no compatibility aliases.
|
|
|
1493
1664
|
- `.tabs` nested in a header or app bar as a secondary row. `.tabs` is a
|
|
1494
1665
|
standalone component; the `.tabs.transparent` app bar variant is gone with it.
|
|
1495
1666
|
|
|
1496
|
-
[Unreleased]: https://github.com/BaezFJ/ExpressiveCSS/compare/v0.
|
|
1667
|
+
[Unreleased]: https://github.com/BaezFJ/ExpressiveCSS/compare/v0.10.0...HEAD
|
|
1668
|
+
[0.10.0]: https://github.com/BaezFJ/ExpressiveCSS/compare/v0.9.1...v0.10.0
|
|
1669
|
+
[0.9.1]: https://github.com/BaezFJ/ExpressiveCSS/compare/v0.9.0...v0.9.1
|
|
1497
1670
|
[0.9.0]: https://github.com/BaezFJ/ExpressiveCSS/compare/v0.8.0...v0.9.0
|
|
1498
1671
|
[0.8.0]: https://github.com/BaezFJ/ExpressiveCSS/compare/v0.7.0...v0.8.0
|
|
1499
1672
|
[0.7.0]: https://github.com/BaezFJ/ExpressiveCSS/compare/v0.6.0...v0.7.0
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ ExpressiveCSS is a Material Design 3 front-end framework built with Sass and
|
|
|
4
4
|
TypeScript. It provides theme tokens, layout and utility classes, styled form
|
|
5
5
|
controls, and JavaScript components in browser, ES module, and CommonJS builds.
|
|
6
6
|
|
|
7
|
-
> ExpressiveCSS
|
|
7
|
+
> ExpressiveCSS version `0.10.0` is under active development.
|
|
8
8
|
|
|
9
9
|
Documentation: [www.expressivecss.com](https://www.expressivecss.com)
|
|
10
10
|
|
|
@@ -24,14 +24,14 @@ Documentation: [www.expressivecss.com](https://www.expressivecss.com)
|
|
|
24
24
|
- [Node.js](https://nodejs.org/) 20 or newer
|
|
25
25
|
- npm
|
|
26
26
|
|
|
27
|
-
Use Node 24 for repository development, selected by `.nvmrc`. The framework
|
|
28
|
-
runtime compatibility range
|
|
27
|
+
Use Node 24 for repository development, selected by `.nvmrc`. The framework still
|
|
28
|
+
supports its existing runtime compatibility range. See [CONTRIBUTING.md](CONTRIBUTING.md)
|
|
29
29
|
for setup, checks, and the community workflow.
|
|
30
30
|
|
|
31
31
|
## MCP server for AI workflows
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
A local MCP server at `mcp/expressivecss/` provides an ExpressiveCSS design-to-QA
|
|
34
|
+
workflow:
|
|
35
35
|
|
|
36
36
|
- Setup Expert
|
|
37
37
|
- Rules Enforcer
|
|
@@ -43,7 +43,7 @@ ExpressiveCSS design-to-QA workflow:
|
|
|
43
43
|
The MCP entry point is `mcp/expressivecss/server.js`, with sample config in
|
|
44
44
|
`mcp/expressivecss/mcp.json`.
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
Start the server:
|
|
47
47
|
|
|
48
48
|
```sh
|
|
49
49
|
cd mcp/expressivecss
|
|
@@ -51,7 +51,7 @@ npm ci
|
|
|
51
51
|
node server.js
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
Configure your MCP client with either command:
|
|
55
55
|
|
|
56
56
|
- `node mcp/expressivecss/server.js`
|
|
57
57
|
- or `node ./server.js` from `mcp/expressivecss` as the working directory.
|
|
@@ -65,7 +65,7 @@ npm ci
|
|
|
65
65
|
npm run build
|
|
66
66
|
```
|
|
67
67
|
|
|
68
|
-
The compiled assets
|
|
68
|
+
The build writes compiled assets to `dist/`:
|
|
69
69
|
|
|
70
70
|
```text
|
|
71
71
|
dist/
|
|
@@ -88,16 +88,15 @@ dist/
|
|
|
88
88
|
└── types/
|
|
89
89
|
```
|
|
90
90
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
`dist/css/`.
|
|
91
|
+
The build writes source maps beside the CSS and JavaScript bundles. The stylesheet
|
|
92
|
+
loads fonts from `../fonts/`, so keep `dist/fonts/` next to `dist/css/`.
|
|
94
93
|
|
|
95
94
|
## Usage
|
|
96
95
|
|
|
97
96
|
### Browser bundle
|
|
98
97
|
|
|
99
|
-
|
|
100
|
-
|
|
98
|
+
Load the compiled stylesheet and browser bundle, then initialize components after
|
|
99
|
+
the page loads:
|
|
101
100
|
|
|
102
101
|
```html
|
|
103
102
|
<link rel="stylesheet" href="dist/css/expressive.min.css">
|
|
@@ -127,9 +126,8 @@ const element = document.querySelector('.custom-tooltip');
|
|
|
127
126
|
Tooltip.init(element, { position: 'top' });
|
|
128
127
|
```
|
|
129
128
|
|
|
130
|
-
`AutoInit()` scans `document.body` by default. Pass a container to limit the
|
|
131
|
-
|
|
132
|
-
manually:
|
|
129
|
+
`AutoInit()` scans `document.body` by default. Pass a container to limit the scan.
|
|
130
|
+
Add the `no-autoinit` class to any element you want to initialize manually:
|
|
133
131
|
|
|
134
132
|
```js
|
|
135
133
|
AutoInit(document.querySelector('#app'), {
|
|
@@ -148,8 +146,164 @@ Use the framework's Sass entry point in another Sass project:
|
|
|
148
146
|
@use "@expressivecss/expressive/src/sass/expressive";
|
|
149
147
|
```
|
|
150
148
|
|
|
151
|
-
|
|
152
|
-
|
|
149
|
+
For work in this repository, the Sass entry point is `src/sass/expressive.scss`.
|
|
150
|
+
|
|
151
|
+
### Reduce page downloads
|
|
152
|
+
|
|
153
|
+
Use the optional ESM entry so a bundler can remove unused components:
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
import { Tabs } from '@expressivecss/expressive/modular';
|
|
157
|
+
import type { TabsOptions } from '@expressivecss/expressive/modular';
|
|
158
|
+
|
|
159
|
+
const tabs = Tabs.init(document.querySelector('.tabs'));
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
The type import supports TypeScript consumers. Initialize Tabs after its markup
|
|
163
|
+
exists, and call `tabs.destroy()` when removing it. The modular entry does not
|
|
164
|
+
initialize components on import. `AutoInit` remains available, but calling it
|
|
165
|
+
includes the full registry. The root entry retains the existing shared behaviors.
|
|
166
|
+
Both ESM entries share constructors. Copy the entire `dist/js` directory when
|
|
167
|
+
hosting ESM files directly. Direct browser imports do not remove unused exports.
|
|
168
|
+
The existing single-file IIFE and CommonJS builds remain available.
|
|
169
|
+
|
|
170
|
+
| Feature | Initialization with the modular entry |
|
|
171
|
+
| --- | --- |
|
|
172
|
+
| AppBar, Autocomplete, FloatingActionButton, ButtonGroup, Carousel, CharacterCounter, Datepicker, Menu, Lightbox, ScrollSpy, FormSelect, NavigationRail, Tabs, Timepicker, Tooltip | Call the component's `.init(element, options)` |
|
|
173
|
+
| Cards, ExpandingCard, Slider | Call `.init(element, options)` for owned elements, or `.Init()` once to discover matching document elements |
|
|
174
|
+
| Chips | Call `.init()` for managed chips; use `Chips.Init()` once for removal of static chips |
|
|
175
|
+
| Snackbar | Use the existing Snackbar constructor |
|
|
176
|
+
| Input validation, textarea resize, file input paths | Call `Forms.Init()` once after choosing these enhancements |
|
|
177
|
+
| Dialog light dismissal | Call `Dialogs.Init()` once |
|
|
178
|
+
| Bottom-sheet drag dismissal | Call `BottomSheets.Init()` once; add `Dialogs.Init()` for light dismissal |
|
|
179
|
+
| Side-sheet drag dismissal | Call `SideSheets.Init()` once; add `Dialogs.Init()` for light dismissal |
|
|
180
|
+
|
|
181
|
+
`Range` retains its Slider alias. Component initializers include internal
|
|
182
|
+
dependencies such as Menu in FormSelect, FormSelect in Datepicker, and Carousel in
|
|
183
|
+
swipeable Tabs. Do not initialize those instances separately. Document behaviors
|
|
184
|
+
apply to the whole page, so do not repeat their `.Init()` calls on route changes or
|
|
185
|
+
alongside the root entry.
|
|
186
|
+
|
|
187
|
+
Choose Sass partials with the custom entry. With Sass's Node package importer,
|
|
188
|
+
compile using `sass --pkg-importer=node app.scss app.css`:
|
|
189
|
+
|
|
190
|
+
```scss
|
|
191
|
+
@use "pkg:@expressivecss/expressive/scss/custom" with (
|
|
192
|
+
$components: ("icons-material-design", "tabs", "carousel"),
|
|
193
|
+
$utilities: ()
|
|
194
|
+
);
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
This Tabs recipe includes styling for the swipeable option. For FormSelect and
|
|
198
|
+
Datepicker, use this complete recipe instead:
|
|
199
|
+
|
|
200
|
+
```scss
|
|
201
|
+
@use "pkg:@expressivecss/expressive/scss/custom" with (
|
|
202
|
+
$components: ("icons-material-design", "buttons", "menu", "forms", "datepicker"),
|
|
203
|
+
$utilities: ()
|
|
204
|
+
);
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
```js
|
|
208
|
+
import { Forms, FormSelect, Datepicker } from '@expressivecss/expressive/modular';
|
|
209
|
+
|
|
210
|
+
Forms.Init();
|
|
211
|
+
const select = FormSelect.init(document.querySelector('#choice'));
|
|
212
|
+
const datepicker = Datepicker.init(document.querySelector('#date'), { openByDefault: true });
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Destroy both component instances when removing that view. Add `"docked-display"`
|
|
216
|
+
before `"forms"` if using the picker's optional docked display plugin.
|
|
217
|
+
|
|
218
|
+
Tokens and base styles are always included. Lists load in the order written within
|
|
219
|
+
the original cascade layers. Partial names are relative to `components/` or
|
|
220
|
+
`utilities/`, without underscores or extensions. Keep icons first and follow the
|
|
221
|
+
order in the corresponding `_index.scss` when combining recipes. Add the supporting
|
|
222
|
+
partials required by your markup. For example, `$utilities: ("spacing",
|
|
223
|
+
"visibility")` includes those helpers. A `null` list includes the complete group by
|
|
224
|
+
default; `()` omits it. An unknown partial fails compilation.
|
|
225
|
+
|
|
226
|
+
Bundlers that resolve Sass package paths can use
|
|
227
|
+
`@expressivecss/expressive/scss/custom`; plain Sass with a `node_modules` load path
|
|
228
|
+
can use `@expressivecss/expressive/src/sass/custom`. Import one framework Sass
|
|
229
|
+
entry per stylesheet. The original full entry and compiled CSS are unchanged.
|
|
230
|
+
|
|
231
|
+
#### Smaller icon fonts
|
|
232
|
+
|
|
233
|
+
Browsers fetch only the font families used on the page. Using outlined icons alone
|
|
234
|
+
avoids downloading the rounded and sharp fonts. To reduce the outlined font, create
|
|
235
|
+
a subset with your own font tooling and turn off the bundled font declarations:
|
|
236
|
+
|
|
237
|
+
```scss
|
|
238
|
+
@use "pkg:@expressivecss/expressive/scss/custom" with (
|
|
239
|
+
$components: ("icons-material-design", "tabs", "carousel"),
|
|
240
|
+
$utilities: (),
|
|
241
|
+
$expressive-include-fonts: false
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
@font-face {
|
|
245
|
+
font-family: "Material Symbols Outlined";
|
|
246
|
+
font-style: normal;
|
|
247
|
+
font-weight: 100 700;
|
|
248
|
+
font-display: block;
|
|
249
|
+
src: url("/assets/icons-outlined-subset.woff2") format("woff2");
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
@font-face {
|
|
253
|
+
font-family: "Roboto";
|
|
254
|
+
font-style: normal;
|
|
255
|
+
font-weight: 400;
|
|
256
|
+
font-display: swap;
|
|
257
|
+
src: url("/assets/roboto-latin-400.woff2") format("woff2");
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
@font-face {
|
|
261
|
+
font-family: "Roboto";
|
|
262
|
+
font-style: normal;
|
|
263
|
+
font-weight: 500;
|
|
264
|
+
font-display: swap;
|
|
265
|
+
src: url("/assets/roboto-latin-500.woff2") format("woff2");
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
@font-face {
|
|
269
|
+
font-family: "Noto Sans";
|
|
270
|
+
font-style: normal;
|
|
271
|
+
font-weight: 400;
|
|
272
|
+
font-display: swap;
|
|
273
|
+
src: url("/assets/noto-sans-latin-400.woff2") format("woff2");
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
@font-face {
|
|
277
|
+
font-family: "Noto Sans";
|
|
278
|
+
font-style: normal;
|
|
279
|
+
font-weight: 500;
|
|
280
|
+
font-display: swap;
|
|
281
|
+
src: url("/assets/noto-sans-latin-500.woff2") format("woff2");
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
Copy the four text fonts from `dist/fonts` into `/assets`, along with their license
|
|
286
|
+
notices. Turning off the bundled faces also disables the text fonts. The declarations
|
|
287
|
+
above restore their existing names and weights. Supply corresponding subset faces
|
|
288
|
+
for rounded or sharp icons if the site uses them. Retain ligature shaping and the
|
|
289
|
+
`opsz`, `wght`, `FILL`, and `GRAD` axes in each variable subset.
|
|
290
|
+
|
|
291
|
+
Include icon names from templates, dynamic content, and framework-generated UI:
|
|
292
|
+
|
|
293
|
+
| Source | Required icon name |
|
|
294
|
+
| --- | --- |
|
|
295
|
+
| Chips removal buttons | `close`, using the configurable `closeIconClass` family |
|
|
296
|
+
| Snackbar dismissal button | `close` when the dismissal button is enabled |
|
|
297
|
+
| Expandable navigation rail summaries | `expand_more`, generated by CSS |
|
|
298
|
+
|
|
299
|
+
FormSelect uses CSS masks for its caret and selection marks. Datepicker uses text
|
|
300
|
+
for its configurable previous/next labels. By default, neither requires an
|
|
301
|
+
icon-font glyph. Custom markup and option values may add requirements. Subsets do
|
|
302
|
+
not cover new icons automatically, so retain full fonts for unrestricted icon names.
|
|
303
|
+
|
|
304
|
+
After building, run `node --test tests/selective-builds.test.js`. It records raw,
|
|
305
|
+
gzip, and Brotli sizes in `.cache/selective-builds/sizes.json`. The browser suite
|
|
306
|
+
records font requests and full/selective screenshots separately in that directory.
|
|
153
307
|
|
|
154
308
|
### Themes
|
|
155
309
|
|
|
@@ -167,7 +321,7 @@ document.documentElement.setAttribute('theme', 'dark');
|
|
|
167
321
|
|
|
168
322
|
## Development
|
|
169
323
|
|
|
170
|
-
|
|
324
|
+
The repository provides these npm commands:
|
|
171
325
|
|
|
172
326
|
| Command | Purpose |
|
|
173
327
|
| --- | --- |
|
|
@@ -190,13 +344,12 @@ Run the documentation and smoke-test site:
|
|
|
190
344
|
npm run docs:dev
|
|
191
345
|
```
|
|
192
346
|
|
|
193
|
-
This builds the framework, then starts the Sass and esbuild watchers
|
|
194
|
-
the documentation server. Refresh the browser to see source changes. Astro
|
|
195
|
-
|
|
347
|
+
This command builds the framework, then starts the Sass and esbuild watchers with
|
|
348
|
+
the documentation server. Refresh the browser to see source changes. Astro prints
|
|
349
|
+
the server URL.
|
|
196
350
|
|
|
197
|
-
|
|
198
|
-
[www.expressivecss.com](https://www.expressivecss.com)
|
|
199
|
-
`docs/src/`.
|
|
351
|
+
The documentation source lives in `docs/src/` and is published at
|
|
352
|
+
[www.expressivecss.com](https://www.expressivecss.com).
|
|
200
353
|
|
|
201
354
|
## Project structure
|
|
202
355
|
|