@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.
Files changed (188) hide show
  1. package/CHANGELOG.md +174 -1
  2. package/README.md +178 -25
  3. package/dist/css/expressive.css +365 -1222
  4. package/dist/css/expressive.css.map +1 -1
  5. package/dist/css/expressive.min.css +1 -1
  6. package/dist/css/expressive.min.css.map +1 -1
  7. package/dist/fonts/material-symbols-outlined.woff2 +0 -0
  8. package/dist/fonts/material-symbols-rounded.woff2 +0 -0
  9. package/dist/fonts/material-symbols-sharp.woff2 +0 -0
  10. package/dist/js/chunks/chunk-7MM4VJJO.mjs +509 -0
  11. package/dist/js/chunks/chunk-7MM4VJJO.mjs.map +7 -0
  12. package/dist/js/chunks/chunk-7UXHSYIA.mjs +183 -0
  13. package/dist/js/chunks/chunk-7UXHSYIA.mjs.map +7 -0
  14. package/dist/js/chunks/chunk-A3BJA7V4.mjs +28 -0
  15. package/dist/js/chunks/chunk-A3BJA7V4.mjs.map +7 -0
  16. package/dist/js/chunks/chunk-AOGFNMXS.mjs +691 -0
  17. package/dist/js/chunks/chunk-AOGFNMXS.mjs.map +7 -0
  18. package/dist/js/chunks/chunk-D4UZ4HFN.mjs +560 -0
  19. package/dist/js/chunks/chunk-D4UZ4HFN.mjs.map +7 -0
  20. package/dist/js/chunks/chunk-EP3CVKB5.mjs +88 -0
  21. package/dist/js/chunks/chunk-EP3CVKB5.mjs.map +7 -0
  22. package/dist/js/chunks/chunk-G576EP5O.mjs +459 -0
  23. package/dist/js/chunks/chunk-G576EP5O.mjs.map +7 -0
  24. package/dist/js/chunks/chunk-GY2Z5CJ2.mjs +320 -0
  25. package/dist/js/chunks/chunk-GY2Z5CJ2.mjs.map +7 -0
  26. package/dist/js/chunks/chunk-JKNPQQWY.mjs +191 -0
  27. package/dist/js/chunks/chunk-JKNPQQWY.mjs.map +7 -0
  28. package/dist/js/chunks/chunk-JNPIWFJT.mjs +365 -0
  29. package/dist/js/chunks/chunk-JNPIWFJT.mjs.map +7 -0
  30. package/dist/js/chunks/chunk-JODJAGFS.mjs +267 -0
  31. package/dist/js/chunks/chunk-JODJAGFS.mjs.map +7 -0
  32. package/dist/js/chunks/chunk-JR24UB4X.mjs +100 -0
  33. package/dist/js/chunks/chunk-JR24UB4X.mjs.map +7 -0
  34. package/dist/js/chunks/chunk-KR44BSYQ.mjs +55 -0
  35. package/dist/js/chunks/chunk-KR44BSYQ.mjs.map +7 -0
  36. package/dist/js/chunks/chunk-LZVBJ33S.mjs +102 -0
  37. package/dist/js/chunks/chunk-LZVBJ33S.mjs.map +7 -0
  38. package/dist/js/chunks/chunk-MISGHDUU.mjs +326 -0
  39. package/dist/js/chunks/chunk-MISGHDUU.mjs.map +7 -0
  40. package/dist/js/chunks/chunk-N3UHGN3N.mjs +175 -0
  41. package/dist/js/chunks/chunk-N3UHGN3N.mjs.map +7 -0
  42. package/dist/js/chunks/chunk-PB5L3EXF.mjs +7 -0
  43. package/dist/js/chunks/chunk-PB5L3EXF.mjs.map +7 -0
  44. package/dist/js/chunks/chunk-PIIAEYAJ.mjs +85 -0
  45. package/dist/js/chunks/chunk-PIIAEYAJ.mjs.map +7 -0
  46. package/dist/js/chunks/chunk-QSQ24FYT.mjs +59 -0
  47. package/dist/js/chunks/chunk-QSQ24FYT.mjs.map +7 -0
  48. package/dist/js/chunks/chunk-QYCYP443.mjs +1111 -0
  49. package/dist/js/chunks/chunk-QYCYP443.mjs.map +7 -0
  50. package/dist/js/chunks/chunk-SLFNPY5M.mjs +78 -0
  51. package/dist/js/chunks/chunk-SLFNPY5M.mjs.map +7 -0
  52. package/dist/js/chunks/chunk-TK6PX2GC.mjs +663 -0
  53. package/dist/js/chunks/chunk-TK6PX2GC.mjs.map +7 -0
  54. package/dist/js/chunks/chunk-TYM6U5DY.mjs +76 -0
  55. package/dist/js/chunks/chunk-TYM6U5DY.mjs.map +7 -0
  56. package/dist/js/chunks/chunk-TZZ24ZQS.mjs +154 -0
  57. package/dist/js/chunks/chunk-TZZ24ZQS.mjs.map +7 -0
  58. package/dist/js/chunks/chunk-VAS6JQ6P.mjs +94 -0
  59. package/dist/js/chunks/chunk-VAS6JQ6P.mjs.map +7 -0
  60. package/dist/js/chunks/chunk-WWPAPHMA.mjs +1 -0
  61. package/dist/js/chunks/chunk-WWPAPHMA.mjs.map +7 -0
  62. package/dist/js/chunks/chunk-XDB3G6RL.mjs +114 -0
  63. package/dist/js/chunks/chunk-XDB3G6RL.mjs.map +7 -0
  64. package/dist/js/chunks/chunk-XO5WX3TK.mjs +226 -0
  65. package/dist/js/chunks/chunk-XO5WX3TK.mjs.map +7 -0
  66. package/dist/js/chunks/chunk-YFXEJ7GR.mjs +286 -0
  67. package/dist/js/chunks/chunk-YFXEJ7GR.mjs.map +7 -0
  68. package/dist/js/chunks/chunk-ZIZVUWRL.mjs +120 -0
  69. package/dist/js/chunks/chunk-ZIZVUWRL.mjs.map +7 -0
  70. package/dist/js/chunks/chunk-ZZBZI2XN.mjs +338 -0
  71. package/dist/js/chunks/chunk-ZZBZI2XN.mjs.map +7 -0
  72. package/dist/js/expressive.cjs +801 -761
  73. package/dist/js/expressive.cjs.map +4 -4
  74. package/dist/js/expressive.js +801 -761
  75. package/dist/js/expressive.js.map +4 -4
  76. package/dist/js/expressive.min.js +11 -15
  77. package/dist/js/expressive.min.js.map +4 -4
  78. package/dist/js/expressive.mjs +83 -7443
  79. package/dist/js/expressive.mjs.map +4 -4
  80. package/dist/js/internal/behaviors/bottomSheets.mjs +9 -0
  81. package/dist/js/internal/behaviors/bottomSheets.mjs.map +7 -0
  82. package/dist/js/internal/behaviors/dialogs.mjs +8 -0
  83. package/dist/js/internal/behaviors/dialogs.mjs.map +7 -0
  84. package/dist/js/internal/behaviors/forms.mjs +8 -0
  85. package/dist/js/internal/behaviors/forms.mjs.map +7 -0
  86. package/dist/js/internal/behaviors/sheetDrag.mjs +8 -0
  87. package/dist/js/internal/behaviors/sheetDrag.mjs.map +7 -0
  88. package/dist/js/internal/behaviors/sideSheets.mjs +9 -0
  89. package/dist/js/internal/behaviors/sideSheets.mjs.map +7 -0
  90. package/dist/js/internal/components/appBar.mjs +8 -0
  91. package/dist/js/internal/components/appBar.mjs.map +7 -0
  92. package/dist/js/internal/components/autocomplete.mjs +10 -0
  93. package/dist/js/internal/components/autocomplete.mjs.map +7 -0
  94. package/dist/js/internal/components/buttonGroup.mjs +8 -0
  95. package/dist/js/internal/components/buttonGroup.mjs.map +7 -0
  96. package/dist/js/internal/components/buttons.mjs +9 -0
  97. package/dist/js/internal/components/buttons.mjs.map +7 -0
  98. package/dist/js/internal/components/cards.mjs +13 -0
  99. package/dist/js/internal/components/cards.mjs.map +7 -0
  100. package/dist/js/internal/components/carousel.mjs +9 -0
  101. package/dist/js/internal/components/carousel.mjs.map +7 -0
  102. package/dist/js/internal/components/characterCounter.mjs +8 -0
  103. package/dist/js/internal/components/characterCounter.mjs.map +7 -0
  104. package/dist/js/internal/components/chips.mjs +11 -0
  105. package/dist/js/internal/components/chips.mjs.map +7 -0
  106. package/dist/js/internal/components/datepicker.mjs +12 -0
  107. package/dist/js/internal/components/datepicker.mjs.map +7 -0
  108. package/dist/js/internal/components/expandingCard.mjs +11 -0
  109. package/dist/js/internal/components/expandingCard.mjs.map +7 -0
  110. package/dist/js/internal/components/index.mjs +88 -0
  111. package/dist/js/internal/components/index.mjs.map +7 -0
  112. package/dist/js/internal/components/lightbox.mjs +9 -0
  113. package/dist/js/internal/components/lightbox.mjs.map +7 -0
  114. package/dist/js/internal/components/menu.mjs +9 -0
  115. package/dist/js/internal/components/menu.mjs.map +7 -0
  116. package/dist/js/internal/components/navigationRail.mjs +8 -0
  117. package/dist/js/internal/components/navigationRail.mjs.map +7 -0
  118. package/dist/js/internal/components/registry.mjs +33 -0
  119. package/dist/js/internal/components/registry.mjs.map +7 -0
  120. package/dist/js/internal/components/scrollspy.mjs +8 -0
  121. package/dist/js/internal/components/scrollspy.mjs.map +7 -0
  122. package/dist/js/internal/components/select.mjs +10 -0
  123. package/dist/js/internal/components/select.mjs.map +7 -0
  124. package/dist/js/internal/components/slider.mjs +9 -0
  125. package/dist/js/internal/components/slider.mjs.map +7 -0
  126. package/dist/js/internal/components/snackbar.mjs +8 -0
  127. package/dist/js/internal/components/snackbar.mjs.map +7 -0
  128. package/dist/js/internal/components/tabs.mjs +10 -0
  129. package/dist/js/internal/components/tabs.mjs.map +7 -0
  130. package/dist/js/internal/components/timepicker.mjs +10 -0
  131. package/dist/js/internal/components/timepicker.mjs.map +7 -0
  132. package/dist/js/internal/components/tooltip.mjs +9 -0
  133. package/dist/js/internal/components/tooltip.mjs.map +7 -0
  134. package/dist/js/internal/core/component.mjs +7 -0
  135. package/dist/js/internal/core/component.mjs.map +7 -0
  136. package/dist/js/internal/core/utils.mjs +7 -0
  137. package/dist/js/internal/core/utils.mjs.map +7 -0
  138. package/dist/js/internal/plugins/dockedDisplayPlugin.mjs +8 -0
  139. package/dist/js/internal/plugins/dockedDisplayPlugin.mjs.map +7 -0
  140. package/dist/js/modular.mjs +113 -0
  141. package/dist/js/modular.mjs.map +7 -0
  142. package/dist/types/behaviors/sheetDrag.d.ts +1 -1
  143. package/dist/types/components/appBar.d.ts +1 -1
  144. package/dist/types/components/autocomplete.d.ts +9 -0
  145. package/dist/types/components/buttons.d.ts +4 -39
  146. package/dist/types/components/carousel.d.ts +10 -1
  147. package/dist/types/components/chips.d.ts +1 -0
  148. package/dist/types/components/datepicker.d.ts +11 -0
  149. package/dist/types/components/index.d.ts +0 -2
  150. package/dist/types/components/lightbox.d.ts +12 -0
  151. package/dist/types/components/menu.d.ts +3 -0
  152. package/dist/types/components/registry.d.ts +0 -4
  153. package/dist/types/components/select.d.ts +4 -0
  154. package/dist/types/components/slider.d.ts +2 -1
  155. package/dist/types/components/snackbar.d.ts +4 -2
  156. package/dist/types/components/tabs.d.ts +2 -1
  157. package/dist/types/components/timepicker.d.ts +5 -3
  158. package/dist/types/components/tooltip.d.ts +5 -3
  159. package/dist/types/index.d.ts +1 -8
  160. package/dist/types/modular.d.ts +28 -0
  161. package/package.json +16 -4
  162. package/src/sass/README.md +8 -0
  163. package/src/sass/components/_badges.scss +1 -6
  164. package/src/sass/components/_button-groups.scss +5 -1
  165. package/src/sass/components/_buttons.scss +8 -287
  166. package/src/sass/components/_chips.scss +17 -2
  167. package/src/sass/components/_dialog.scss +9 -4
  168. package/src/sass/components/_fab-menu.scss +11 -9
  169. package/src/sass/components/_icon-buttons.scss +0 -5
  170. package/src/sass/components/_index.scss +0 -5
  171. package/src/sass/components/_menu.scss +2 -2
  172. package/src/sass/components/_navigation-rail.scss +1 -1
  173. package/src/sass/components/_panes.scss +50 -78
  174. package/src/sass/components/_progress.scss +73 -13
  175. package/src/sass/components/_scrim.scss +4 -4
  176. package/src/sass/components/_side-sheet.scss +22 -12
  177. package/src/sass/components/_toolbar.scss +1 -4
  178. package/src/sass/components/_tooltip.scss +20 -2
  179. package/src/sass/components/forms/_input-fields.scss +5 -1
  180. package/src/sass/components/forms/_select.scss +1 -0
  181. package/src/sass/components/forms/_slider.scss +81 -25
  182. package/src/sass/custom.scss +38 -0
  183. package/dist/types/components/navigationDrawer.d.ts +0 -110
  184. package/src/sass/components/_banners.scss +0 -298
  185. package/src/sass/components/_bottom-app-bar.scss +0 -180
  186. package/src/sass/components/_floating-sheet.scss +0 -86
  187. package/src/sass/components/_navigation-drawer.scss +0 -476
  188. 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.9.0...HEAD
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 is currently at version `0.9.0` and under active development.
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's
28
- runtime compatibility range remains unchanged. See [CONTRIBUTING.md](CONTRIBUTING.md)
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
- This repository includes a local MCP server at `mcp/expressivecss/` that exposes an
34
- ExpressiveCSS design-to-QA workflow:
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
- Quick start:
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
- To use it with your MCP client, point the command to:
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 are written to `dist/`:
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
- Source maps are produced alongside the CSS and JavaScript bundles. The
92
- stylesheet loads fonts from `../fonts/`, so keep `dist/fonts/` next to
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
- Include the compiled stylesheet and browser bundle, then initialize components
100
- after the page has loaded:
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
- scan, or add the `no-autoinit` class to an element that should be initialized
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
- When working directly in this repository, the entry point is
152
- `src/sass/expressive.scss`.
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
- Available npm commands include:
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 alongside
194
- the documentation server. Refresh the browser to see source changes. Astro
195
- prints the server URL.
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
- It is the same site published at
198
- [www.expressivecss.com](https://www.expressivecss.com), authored in
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