diff --git a/README.md b/README.md
index ba79881..536fd4c 100644
--- a/README.md
+++ b/README.md
@@ -24,36 +24,39 @@ npm install react react-dom react-aria-components
## 使い方
-アプリのルートで `FlavorProvider` を配置し、全フレーバー同梱の CSS を読み込みます。`flavor` prop は省略時 `pepper` が適用されます。
+CSS をインポートするだけで、デフォルトの `pepper` フレーバーでコンポーネントが描画されます。
+
+```tsx
+import { Button } from 'wip-ui'
+import 'wip-ui/styles.css'
+
+export const App = () =>
+```
+
+別のフレーバーを適用したい場合、あるいは領域ごとに異なるフレーバーを切り替えたい場合は `FlavorProvider` で対象領域を囲みます。
```tsx
import { FlavorProvider, Button } from 'wip-ui'
-import 'wip-ui/css/all.css'
+import 'wip-ui/styles.css'
export const App = () => (
-
+
)
```
-別のフレーバーに切り替える場合は `flavor` prop を指定します。ネストして領域ごとに異なるフレーバーを適用することもできます。
-
-```tsx
-
-
-
-```
-
コンポーネント単位でのインポートも可能です。
```tsx
import { Button } from 'wip-ui/Button'
```
+> **中の `FlavorProvider` で切り替える場合の注意**: フレーバーを入れ子にしたとき、CSS の詳細度が同じためソース順序が後ろ(`pepper` < `minne` < `apollo` < `nachiguro` < `flippers` < `kung-pu` < `lolipop` の順)のフレーバーが勝ちます。「外側 `lolipop` + 内側 `pepper`」のような組み合わせでは、内側が外側を上書きできない点にご注意ください。
+
### 利用可能なフレーバー
-`wip-ui/css/all.css` は以下の全フレーバーを含みます。
+`wip-ui/styles.css` は以下の全フレーバーを含みます。
- `pepper`(デフォルト)
- `minne`
diff --git a/package.json b/package.json
index fa098b8..2cbcd66 100644
--- a/package.json
+++ b/package.json
@@ -44,6 +44,7 @@
},
"./types": null,
"./utils": null,
+ "./styles.css": "./dist/styles.css",
"./css/*.css": "./dist/css/*.css"
},
"files": [
diff --git a/scripts/build-flavor-css.mjs b/scripts/build-flavor-css.mjs
index 75b2bbb..5022b7e 100644
--- a/scripts/build-flavor-css.mjs
+++ b/scripts/build-flavor-css.mjs
@@ -9,6 +9,7 @@ const NODE_MODULES = path.join(ROOT, 'node_modules')
const ENTRY_SCSS = path.join(ROOT, 'src', '_all.scss')
const OUTPUT_DIR = path.join(ROOT, '.storybook', 'flavors')
const DIST_DIR = path.join(ROOT, 'dist', 'css')
+const DIST_ROOT = path.join(ROOT, 'dist')
const ICON_FONT_PATH = path.join(
NODE_MODULES,
'@pepabo-inhouse',
@@ -34,6 +35,9 @@ const iconFontFace = (() => {
// token declarations no longer live at document level. Required for the
// combined (`all.css`) build to avoid the last-flavor-wins cascade conflict
// when multiple flavors' `:root { --token: ... }` blocks are concatenated.
+// When `prefix` is an empty string, non-:root selectors are left unchanged
+// so the output acts as an unscoped baseline (used to give consumers
+// styling even without ).
function prefixPlugin(prefix, { scopeRoot = false } = {}) {
return {
postcssPlugin: 'prefix-flavor',
@@ -52,15 +56,20 @@ function prefixPlugin(prefix, { scopeRoot = false } = {}) {
if (sel.startsWith(':root')) {
return scopeRoot ? prefix + sel.slice(':root'.length) : sel
}
- return `${prefix} ${sel}`
+ return prefix ? `${prefix} ${sel}` : sel
})
},
}
}
prefixPlugin.postcss = true
+// Clean stale CSS outputs so renames/removals don't leave leftovers in dist/
+fs.rmSync(DIST_DIR, { recursive: true, force: true })
+fs.rmSync(path.join(DIST_ROOT, 'styles.css'), { force: true })
+
fs.mkdirSync(OUTPUT_DIR, { recursive: true })
fs.mkdirSync(DIST_DIR, { recursive: true })
+fs.mkdirSync(DIST_ROOT, { recursive: true })
console.log(`Building flavor CSS for ${FLAVORS.length} flavors...`)
@@ -136,6 +145,17 @@ for (const flavor of FLAVORS) {
]).process(css, { from: undefined })
combinedParts.push(combined.css)
+ // Baseline: emit pepper with no prefix at the top of all.css so consumers
+ // get styled components even without wrapping with .
+ // Specificity of `[data-flavor="xxx"] .foo` (0,0,1,1) beats `.foo`
+ // (0,0,1,0), so an explicit FlavorProvider still overrides the baseline.
+ if (flavor === 'pepper') {
+ const baseline = postcss([prefixPlugin('')]).process(css, {
+ from: undefined,
+ })
+ combinedParts.unshift(baseline.css)
+ }
+
console.log(` ✓ ${flavor}.css`)
} catch (err) {
console.error(` ✗ ${flavor}: ${err.message}`)
@@ -143,11 +163,16 @@ for (const flavor of FLAVORS) {
}
}
-// Combined CSS: single @font-face at the top, then all 7 flavors
+// Combined CSS: @font-face + pepper baseline (unscoped) + 7 flavors scoped.
+// Emitted at dist/styles.css to match modern convention
+// (e.g. Mantine's `@mantine/core/styles.css`, Radix Themes' `@radix-ui/themes/styles.css`)
+// and to signal "this is the default stylesheet consumers should import".
fs.writeFileSync(
- path.join(DIST_DIR, 'all.css'),
+ path.join(DIST_ROOT, 'styles.css'),
iconFontFace + combinedParts.join('\n')
)
-console.log(` ✓ all.css (combined, ${FLAVORS.length} flavors)`)
+console.log(
+ ` ✓ styles.css (pepper baseline + ${FLAVORS.length} flavors scoped)`
+)
console.log('Done!')
diff --git a/src/FlavorProvider/FlavorProvider.tsx b/src/FlavorProvider/FlavorProvider.tsx
index 078e3bc..58e4320 100644
--- a/src/FlavorProvider/FlavorProvider.tsx
+++ b/src/FlavorProvider/FlavorProvider.tsx
@@ -18,8 +18,9 @@ export interface Props {
/**
* 配下の wip-ui コンポーネントに適用するフレーバー(デザイントークンのテーマ)を切り替えるための Provider。
- * 単一フレーバーを root で固定する用途のほか、ネストして領域ごとに異なるフレーバーを適用することもできる。
- * 利用前に `wip-ui/css/all.css`(全フレーバー同梱)または `wip-ui/css/{flavor}.css`(単一フレーバー)の import が必要。
+ * `wip-ui/styles.css` をインポートするだけで pepper がデフォルト適用されるため、
+ * この Provider はフレーバーを切り替えたい場合(別フレーバーの明示指定・領域別ネスト等)にのみ使用する。
+ * 利用前に `wip-ui/styles.css`(全フレーバー同梱)または `wip-ui/css/{flavor}.css`(単一フレーバー)の import が必要。
*
* @summary フレーバー(デザイントークンのテーマ)を切り替えるProvider
*/