@webority/theme 0.13.5 → 0.15.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 CHANGED
@@ -24,12 +24,56 @@ load-bearing**:
24
24
  @import "@webority/theme/scss/wui-components";
25
25
  // Optional — marketing sites only (heroes, section-y, pill CTAs, reveal motion):
26
26
  // @import "@webority/theme/scss/marketing";
27
+ // Optional, only if the site renders the phone input or country picker (see Country flags):
28
+ // @import "@webority/theme/scss/flags";
27
29
  ```
28
30
 
29
31
  Importing part of the core chain is a bug: skipping `wui-aliases` leaves every
30
- `--color-*` reference unresolved. Country flags are pulled by `wui-components`
31
- for the phone control — do not import `flags` a second time (legacy `@import`
32
- does not dedupe).
32
+ `--color-*` reference unresolved.
33
+
34
+ ### Country flags are opt-in
35
+
36
+ The 245 `.wui-flag-*` rules are about 187 KB raw (38 KB Brotli) of inlined SVG, so
37
+ `wui-components` does not include them. A site that renders `AppPhoneNumberInput`,
38
+ `<app-phone-number-input>`, `AppCountrySelect` or `<app-country-select>` adds them once:
39
+
40
+ - **Your own SCSS:** `@import "@webority/theme/scss/flags";` after `wui-components`. Import it once;
41
+ legacy `@import` does not dedupe, so a second import doubles every flag rule.
42
+ - **Precompiled CSS:** link `@webority/theme/css/flags` (`dist/webority-flags.css`). The Razor
43
+ package serves the same file at `_content/Webority.Ui.Razor/css/webority-flags.css`.
44
+ - **Per page:** on a site with one phone field, link the flags stylesheet only on the pages that
45
+ render it. Without it every flag is an empty grey box, and nothing reports the cause.
46
+
47
+ ### Purging unused CSS (PurgeCSS)
48
+
49
+ A consuming site's PurgeCSS pass reads its own pages, but `Webority.Ui.Razor` ships as a DLL and the
50
+ React and elements packages ship as bundles, so the markup they render at runtime is invisible to it.
51
+ `@webority/theme` therefore ships `purge-safelist.json`, generated by `scripts/gen-purge-safelist.mjs`
52
+ at theme build time from the tag helpers, custom elements, React components and the compiled CSS:
53
+
54
+ - `classes`: every theme class the library's own markup names.
55
+ - `patterns`: regular-expression sources (`^btn-`, `^wui-flag-`, ...) for classes the library builds
56
+ from a prefix at runtime, where the tail is only known in the browser.
57
+
58
+ A Razor site already installs `@webority/theme` for its SCSS build, so the file is in its `node_modules`.
59
+ Wire it into PurgeCSS (`purgecss.config.cjs`, run after `sass` and before the file is committed):
60
+
61
+ ```js
62
+ const { classes, patterns } = require("@webority/theme/purge-safelist.json");
63
+
64
+ module.exports = {
65
+ content: ["Pages/**/*.cshtml", "wwwroot/js/**/*.js"],
66
+ css: ["wwwroot/css/site.css"],
67
+ safelist: {
68
+ standard: [...classes, ...patterns.map((p) => new RegExp(p))],
69
+ // Bootstrap state classes and attribute selectors the library toggles at runtime.
70
+ greedy: [/^data-bs-/, /^wui-/],
71
+ },
72
+ };
73
+ ```
74
+
75
+ Add your own safelist entries for classes your page scripts add. PurgeCSS failures are silent, so
76
+ compare every page before and after a purge.
33
77
 
34
78
  **`$secondary`** is quiet grey (de-emphasised text/buttons), not a second brand
35
79
  colour — intentional shared semantics (see `_variables.scss`).
@@ -158,8 +202,8 @@ Anti-over-correction checklist. When thinning the package (e.g. marketing extrac
158
202
 
159
203
  ### Hard interactive & portal patterns (packages outside this folder, same monorepo)
160
204
 
161
- - `@webority/ui-elements` + App\* wrappers: select, multiselect, autocomplete, phone, date, daterange, OTP
162
- - Portal: `AppShell`, `AppDataTable` / ledger, `AppModal` / `AppConfirmDialog`, toast contract, `AppSidebarMenu`
205
+ - `@webority/ui-elements` + App\* wrappers: select, multiselect, autocomplete, phone, date, daterange, OTP, command palette
206
+ - Portal: `AppShell`, `AppDataTable` / ledger, `AppModal` / `AppConfirmDialog` / `AppCommandPalette`, toast contract, `AppSidebarMenu`
163
207
  - React↔Razor parity gates and unit tests for catalogue components
164
208
 
165
209
  ### Marketing (opt-in — not default)
@@ -178,7 +222,7 @@ Keep shipping all of these; classify for **when to use**, not for removal:
178
222
  | Tier | Components | Library? | Notes |
179
223
  |---|---|---|---|
180
224
  | **Portal core** | Shell, DataTable, fields/selects, Modal, Confirm, Tabs, Card, Alert, Badge, StatusBadge, Stepper, File*, Date*, Phone, OTP, Toast, Empty/Skeleton/Spinner | **Yes — never product-fork** | Daily product UI |
181
- | **Portal display** | `AppKpiTile`, `AppInfoList`, `AppTimeline`, `AppCallout`, `AppSplash`, `AppBanner`, `AppBreadcrumbs`, `AppProgress`, `AppMeter` | **Yes** | Shared across portals |
225
+ | **Portal display** | `AppKpiTile`, `AppInfoList`, `AppTimeline`, `AppSplash`, `AppBanner`, `AppBreadcrumbs`, `AppProgress`, `AppMeter` | **Yes** | Shared across portals |
182
226
  | **Commercial / plan UI** | `AppPricingCard`, `AppCompareTable`, `AppResourceCard` | **Yes — keep** | Pricing pages **and** in-app plan/billing. Editorial shape, not a second design system. Moving them to products would break React↔Razor parity. |
183
227
  | **CSS marketing only** | section-y, btn-pill, reveal, marquee, … | **Opt-in partial** | Not App*; see marketing import above |
184
228