Skip to content

Commit c612cf5

Browse files
committed
fix(web): export UnoCSS icon safelist
- add package-owned MDI icon safelist to the design preset - expose typed ./uno safelist exports for consumers - document the consumer contract and refresh generated skill references
1 parent 761df2c commit c612cf5

10 files changed

Lines changed: 118 additions & 0 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@partner-up-dev/design-web": patch
3+
---
4+
5+
Export PartnerUp design UnoCSS safelist constants and include the package-owned built-in icon safelist in the default design preset.

docs/20-product-tdd/release-surface.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ Public component values and component-specific TypeScript helper types are
3030
imported from the package root. The web package does not expose
3131
`src/components/*` or `./components/*` as downstream consumer API.
3232

33+
The `./uno` export exposes the default PartnerUp UnoCSS preset plus named
34+
package-owned safelist constants. The default preset includes the package-owned
35+
icon safelist so downstream apps that use `partnerUpDesignPreset()` generate
36+
CSS for built-in component `i-mdi-*` icons even when the icon class only appears
37+
inside the published design package. Consumers that do not use the preset may
38+
merge the exported safelist manually.
39+
3340
## UniApp Package
3441

3542
Release identity:

docs/30-unit-tdd/web/composition-principles.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ Use these principles when building application UI with
6262
- Use public props, slots, events, and exported types from component references.
6363
- Do not depend on `src/components/*`, generated registry internals, or story
6464
implementation details.
65+
- When using UnoCSS, use the package `./uno` preset or safelist export for
66+
package-owned built-in icons instead of duplicating design package internal
67+
`i-mdi-*` class names in app code.
6568
<!-- agent-skill:end -->
6669

6770
## Maintainer Notes

docs/30-unit-tdd/web/type-support.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ component-related TypeScript types in downstream Vue apps.
1818
`import { PuButton } from '@partner-up-dev/design-web'`.
1919
- Import shared and component-specific TypeScript types from the package root:
2020
`import type { PuButtonFeedback, PuAction } from '@partner-up-dev/design-web'`.
21+
- Import the UnoCSS preset and safelist constants from
22+
`@partner-up-dev/design-web/uno`.
2123
- Do not import from `@partner-up-dev/design-web/components/*`,
2224
`@partner-up-dev/design-web/src/*`, generated registry internals, or raw
2325
implementation files.
@@ -38,6 +40,16 @@ component-related TypeScript types in downstream Vue apps.
3840
the package.
3941
- Treat styles and Sass as styling entries only; do not use them to reach
4042
component implementation files.
43+
44+
## UnoCSS
45+
46+
- Use `partnerUpDesignPreset()` from `@partner-up-dev/design-web/uno` when the
47+
consuming app uses UnoCSS.
48+
- The preset includes the package-owned safelist for built-in component
49+
`i-mdi-*` icons; consumers that cannot use the preset may merge
50+
`partnerUpDesignSafelist` manually.
51+
- Keep consumer-provided icon classes, such as `PuInput` prefix or suffix icon
52+
values, in the consuming app's own UnoCSS scan scope or safelist.
4153
<!-- agent-skill:end -->
4254

4355
## Maintainer Notes

packages/web/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,21 @@ or `@partner-up-dev/design-web/src/*`; those paths are not consumer API.
2626
## UnoCSS
2727

2828
```ts
29+
import { defineConfig, presetIcons } from 'unocss'
2930
import partnerUpDesignPreset from '@partner-up-dev/design-web/uno'
31+
32+
export default defineConfig({
33+
presets: [
34+
partnerUpDesignPreset(),
35+
presetIcons(),
36+
],
37+
})
38+
```
39+
40+
`partnerUpDesignPreset()` includes the package-owned icon safelist used by
41+
default component UI. Consumers that compose a custom UnoCSS config without the
42+
preset can merge `partnerUpDesignSafelist` manually.
43+
44+
```ts
45+
import { partnerUpDesignSafelist } from '@partner-up-dev/design-web/uno'
3046
```

packages/web/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
},
3535
"./utils/*": "./src/utils/*",
3636
"./uno": {
37+
"types": "./dist/styles/unocss-preset.d.ts",
3738
"import": "./src/styles/unocss-preset.ts"
3839
},
3940
"./types": {

packages/web/skills/design-web/references/composition-principles.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,6 @@ Use these principles when building application UI with
5353
- Use public props, slots, events, and exported types from component references.
5454
- Do not depend on `src/components/*`, generated registry internals, or story
5555
implementation details.
56+
- When using UnoCSS, use the package `./uno` preset or safelist export for
57+
package-owned built-in icons instead of duplicating design package internal
58+
`i-mdi-*` class names in app code.

packages/web/skills/design-web/references/type-support.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ component-related TypeScript types in downstream Vue apps.
1010
`import { PuButton } from '@partner-up-dev/design-web'`.
1111
- Import shared and component-specific TypeScript types from the package root:
1212
`import type { PuButtonFeedback, PuAction } from '@partner-up-dev/design-web'`.
13+
- Import the UnoCSS preset and safelist constants from
14+
`@partner-up-dev/design-web/uno`.
1315
- Do not import from `@partner-up-dev/design-web/components/*`,
1416
`@partner-up-dev/design-web/src/*`, generated registry internals, or raw
1517
implementation files.
@@ -30,3 +32,13 @@ component-related TypeScript types in downstream Vue apps.
3032
the package.
3133
- Treat styles and Sass as styling entries only; do not use them to reach
3234
component implementation files.
35+
36+
## UnoCSS
37+
38+
- Use `partnerUpDesignPreset()` from `@partner-up-dev/design-web/uno` when the
39+
consuming app uses UnoCSS.
40+
- The preset includes the package-owned safelist for built-in component
41+
`i-mdi-*` icons; consumers that cannot use the preset may merge
42+
`partnerUpDesignSafelist` manually.
43+
- Keep consumer-provided icon classes, such as `PuInput` prefix or suffix icon
44+
values, in the consuming app's own UnoCSS scan scope or safelist.

packages/web/src/styles/unocss-preset.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,31 @@ const marginPropertyMap: Record<string, string[]> = {
119119
lb: ["margin-left", "margin-bottom"],
120120
};
121121

122+
export const partnerUpDesignSafelist = [
123+
"i-mdi-alert-circle-outline",
124+
"i-mdi-alert-outline",
125+
"i-mdi-arrow-left",
126+
"i-mdi-check-bold",
127+
"i-mdi-check-circle-outline",
128+
"i-mdi-chevron-down",
129+
"i-mdi-chevron-right",
130+
"i-mdi-close",
131+
"i-mdi-close-circle",
132+
"i-mdi-eye",
133+
"i-mdi-eye-off",
134+
"i-mdi-file-multiple-outline",
135+
"i-mdi-file-outline",
136+
"i-mdi-information-outline",
137+
"i-mdi-link-variant",
138+
"i-mdi-loading",
139+
"i-mdi-tray-arrow-up",
140+
] as const;
141+
142+
export const partnerUpDesignIconSafelist = partnerUpDesignSafelist;
143+
122144
export default definePreset(() => ({
123145
name: "partner-up-design",
146+
safelist: [...partnerUpDesignSafelist],
124147
theme: {
125148
colors,
126149
spacing,

tasks/histoire-mdi-icons-diagnosis/README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,39 @@ http://localhost:6006/__sandbox.html?storyId=src-stories-display-pudescriptionli
137137
+-- i-mdi-chevron-right and i-mdi-content-copy had non-none mask-image
138138
+-- screenshot confirmed both icons visible
139139
```
140+
141+
## Consumer Package Safelist Follow-up
142+
143+
Date: 2026-06-19
144+
145+
Observed mismatch:
146+
147+
```text
148+
Histoire:
149+
- PuPageHeader default back icon span measured 18x18
150+
- computed mask-image was non-none
151+
- stylesheet contained .i-mdi-arrow-left
152+
153+
Consumer app /pr/34:
154+
- PuPageHeader back button existed
155+
- default back icon span measured 0x0
156+
- computed mask-image was none
157+
- stylesheet contained no .i-mdi-arrow-left rule
158+
```
159+
160+
Root cause:
161+
162+
The published design package uses package-owned `i-mdi-*` classes inside
163+
component defaults. Downstream UnoCSS can generate icon CSS only for classes it
164+
matches through its scan graph or safelist. A consumer can have `presetIcons()`
165+
configured and still miss an icon class that appears only inside the installed
166+
design package runtime output.
167+
168+
Fix direction:
169+
170+
- Export package-owned icon safelist constants from `@partner-up-dev/design-web/uno`.
171+
- Include that safelist in the default PartnerUp design UnoCSS preset so
172+
consumers that already call `partnerUpDesignPreset()` get built-in component
173+
icon CSS automatically.
174+
- Keep consumer-provided icon class props outside the package safelist; those
175+
remain the consuming app's scan or safelist responsibility.

0 commit comments

Comments
 (0)