lism-css 0.22.2 → 0.23.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 (66) hide show
  1. package/dist/config/default-config.d.ts +137 -49
  2. package/dist/config/default-config.js +8 -6
  3. package/dist/config/defaults/breakpoints.d.ts +15 -0
  4. package/dist/config/defaults/breakpoints.js +10 -0
  5. package/dist/config/defaults/props.d.ts +21 -30
  6. package/dist/config/defaults/props.js +33 -29
  7. package/dist/config/defaults/token-scope.d.ts +9 -0
  8. package/dist/config/defaults/token-scope.js +7 -0
  9. package/dist/config/defaults/token-var-prefix.d.ts +11 -0
  10. package/dist/config/defaults/token-var-prefix.js +11 -0
  11. package/dist/config/defaults/tokens.d.ts +118 -21
  12. package/dist/config/defaults/tokens.js +112 -24
  13. package/dist/config/index.d.ts +285 -105
  14. package/dist/config/index.js +18 -15
  15. package/dist/config/presets/props-full.d.ts +20 -0
  16. package/dist/config/presets/props-full.js +28 -0
  17. package/dist/css/base/set.css +1 -1
  18. package/dist/css/base.css +1 -1
  19. package/dist/css/full.css +1 -0
  20. package/dist/css/full_no_layer.css +1 -0
  21. package/dist/css/main.css +1 -1
  22. package/dist/css/main_no_layer.css +1 -1
  23. package/dist/css/props.css +1 -1
  24. package/dist/index.d.ts +4 -0
  25. package/dist/index.js +1 -0
  26. package/dist/lib/getBpData.d.ts +2 -2
  27. package/dist/lib/getBpData.js +7 -7
  28. package/dist/lib/getLismProps.d.ts +5 -3
  29. package/dist/lib/getLismProps.js +59 -54
  30. package/dist/lib/getMaybeTokenValue.d.ts +1 -7
  31. package/dist/lib/getMaybeTokenValue.js +10 -22
  32. package/dist/lib/getTokenVarName.d.ts +13 -0
  33. package/dist/lib/getTokenVarName.js +8 -0
  34. package/dist/lib/getTokenVarName.test.d.ts +1 -0
  35. package/dist/lib/isTokenValue.js +11 -22
  36. package/dist/lib/types/CustomPropRegistry.d.ts +9 -0
  37. package/dist/lib/types/CustomTraitRegistry.d.ts +9 -0
  38. package/dist/lib/types/FullModeRegistry.d.ts +26 -0
  39. package/dist/lib/types/PropValueTypes.d.ts +45 -13
  40. package/dist/lib/types/ResponsiveProps.d.ts +57 -13
  41. package/dist/lib/types/ResponsiveProps.module-augmentation.test.d.ts +1 -0
  42. package/dist/lib/warnUnsupportedBp.js +1 -1
  43. package/dist/scss/auto_output.test.d.ts +1 -0
  44. package/package.json +23 -33
  45. package/src/scss/_auto_output.scss +54 -42
  46. package/src/scss/_prop-config-full.gen.scss +1317 -0
  47. package/src/scss/{_prop-config.scss → _prop-config.gen.scss} +37 -13
  48. package/src/scss/_setting.scss +6 -11
  49. package/src/scss/auto_output.test.ts +91 -0
  50. package/src/scss/base/index.scss +1 -3
  51. package/src/scss/base/set/index.scss +5 -0
  52. package/src/scss/base/tokens/_tokens.gen.scss +69 -0
  53. package/src/scss/base/tokens/_tokens.scss +31 -30
  54. package/src/scss/full.scss +12 -0
  55. package/src/scss/full_no_layer.scss +32 -0
  56. package/src/scss/props/index.scss +0 -1
  57. package/src/scss/trait/is/_wrapper.scss +1 -1
  58. package/bin/__build-css.cjs +0 -92
  59. package/bin/build-config.js +0 -155
  60. package/bin/build-css.js +0 -90
  61. package/bin/cli.mjs +0 -79
  62. package/bin/script-build-css.js +0 -6
  63. package/src/scss/base/tokens/_shadow.scss +0 -23
  64. package/src/scss/base/tokens/_space.scss +0 -30
  65. package/src/scss/base/tokens/_typography.scss +0 -69
  66. package/src/scss/props/_lh.scss +0 -16
@@ -0,0 +1,9 @@
1
+ /**
2
+ * lism.config.js の traits で追加した trait キーを型側へ解禁するための拡張ポイント。
3
+ *
4
+ * プロジェクト直下の lism-env.d.ts から `declare module 'lism-css'` で拡張される。
5
+ * trait は presence ベース(真偽でクラス付与を制御)なので値は boolean(既定 trait の `ExtractTraitValue<string>` に一致)。
6
+ */
7
+ export type CustomTraitValue = boolean;
8
+ export interface CustomTraitRegistry {
9
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * lism.config.js の `isFullMode: true`(full preset をコンポーネント側にも適用するモード)を
3
+ * 型側へ反映するための拡張ポイント。
4
+ *
5
+ * full モードでは isVar 系を除く全 props が responsive になる(`props-full.ts` のランタイム挙動と一致)が、
6
+ * 静的型は lism.config.js の `.js` の値を読めないため、デフォルトでは defaults 由来のまま追従しない。
7
+ * このレジストリを `declare module 'lism-css'` で拡張(= 何らかのキーを1つ以上付与)すると、
8
+ * {@link import('./PropValueTypes').PropValueTypes} が full 版に切り替わり、
9
+ * `pl` 等の本来 bp:0 の props でも BP 指定(配列・オブジェクト記法)が型エラーにならなくなる。
10
+ *
11
+ * ランタイム側の有効化はあくまで lism.config.js の `isFullMode` で行う。ここで切り替えるのは
12
+ * 「型が提示・許可する範囲」だけで、両者を一致させるのはユーザーの責務(`BreakpointRegistry` と同じ設計)。
13
+ *
14
+ * @example プロジェクト直下の型定義ファイル(例: `src/lism-env.d.ts`)で full モードを型に反映する
15
+ * ```ts
16
+ * import 'lism-css';
17
+ *
18
+ * declare module 'lism-css' {
19
+ * interface FullModeRegistry {
20
+ * enabled: true; // キー名は任意。1つでもキーがあれば full 版の型に切り替わる
21
+ * }
22
+ * }
23
+ * ```
24
+ */
25
+ export interface FullModeRegistry {
26
+ }
@@ -1,23 +1,24 @@
1
- import { TOKENS, PROPS, BREAK_POINTS } from '../../../config/index';
1
+ import { TOKENS, PROPS } from '../../../config/index';
2
2
  import { WithArbitraryString, ArrayElement, ExtractArrayValues, ExtractObjectKeys, ExtractPropertyValue } from './utils';
3
3
  import { MakeResponsive } from './ResponsiveProps';
4
+ import { FullModeRegistry } from './FullModeRegistry';
4
5
  type PropsConfig = typeof PROPS;
5
6
  type TokensConfig = typeof TOKENS;
6
7
  /**
7
- * TOKENS のキーから対応する値の型を取得
8
- * - 配列形式: TOKENS[K] が配列の場合、その要素の型
9
- * - オブジェクト形式: TOKENS[K].values が配列の場合、その要素の型
8
+ * TOKENS のキーから対応する値の型(= トークンのキー集合)を取得
9
+ * - 配列 / Set 形式: その要素の型
10
+ * - 値付きフラットマップ({ key: value }): その keyof(トークンのキー集合)
10
11
  *
11
12
  * @example
12
13
  * ```ts
13
14
  * type FzValues = TokenConfigValues<'fz'>;
14
- * // 結果: 'root' | 'base' | '5xl' | ...
15
+ * // 結果: 'base' | '5xl' | ...
15
16
  *
16
17
  * type SpaceValues = TokenConfigValues<'space'>;
17
18
  * // 結果: '5' | '10' | '15' | ...
18
19
  * ```
19
20
  */
20
- type TokenConfigValues<K extends keyof TokensConfig> = TokensConfig[K] extends readonly unknown[] ? ArrayElement<TokensConfig[K]> : ExtractArrayValues<TokensConfig[K], 'values'>;
21
+ type TokenConfigValues<K extends keyof TokensConfig> = TokensConfig[K] extends readonly unknown[] ? ArrayElement<TokensConfig[K]> : TokensConfig[K] extends object ? keyof TokensConfig[K] & string : never;
21
22
  /**
22
23
  * token プロパティから対応する TOKENS の値を抽出
23
24
  */
@@ -33,15 +34,13 @@ type ExtractPropValues<T> = ExtractArrayValues<T, 'presets'> | ExtractObjectKeys
33
34
  * - ない場合: string | number(フォールバック)
34
35
  */
35
36
  type PropValueType<T> = ExtractPropValues<T> extends never ? string | number | boolean : WithArbitraryString<ExtractPropValues<T>> | number | boolean | null;
36
- /** bp で指定できるブレークポイント名('lg' など個別指定用) */
37
- type BreakpointName = (typeof BREAK_POINTS)[number];
38
37
  /**
39
38
  * bp プロパティでレスポンシブ(配列・オブジェクト形式)が有効かを判定
40
39
  * - bp 未設定 / bp: 0 → false
41
- * - bp: 1 → BP からユーティリティクラス生成
42
- * - bp: 'lg' 指定 BP 以降のみ(配列形式の型は bp: 1 と同様に許可)
40
+ * - bp: 1 → 有効 BP すべてからユーティリティクラス生成
41
+ * - bp: ['sm', 'md'] 等のリスト形式 列挙した BP のみ出力(型は bp: 1 と同様に許可)
43
42
  */
44
- type HasBreakpointSupport<T> = [ExtractPropertyValue<T, 'bp'>] extends [never] ? false : ExtractPropertyValue<T, 'bp'> extends 0 ? false : ExtractPropertyValue<T, 'bp'> extends 1 | BreakpointName ? true : false;
43
+ type HasBreakpointSupport<T> = [ExtractPropertyValue<T, 'bp'>] extends [never] ? false : ExtractPropertyValue<T, 'bp'> extends 0 ? false : ExtractPropertyValue<T, 'bp'> extends 1 | readonly unknown[] ? true : false;
45
44
  type AllPropKeys = keyof PropsConfig;
46
45
  /**
47
46
  * bp が有効(1 またはブレークポイント名)なプロパティのキーを抽出
@@ -65,16 +64,49 @@ export type ResponsivePropValueTypes = {
65
64
  export type NonResponsivePropValueTypes = {
66
65
  [K in PropsWithoutBreakpoint]?: PropValueType<PropsConfig[K]>;
67
66
  };
67
+ /** defaults 由来の Props 型(full モード未適用時のデフォルト) */
68
+ type DefaultPropValueTypes = MakeResponsive<ResponsivePropValueTypes> & NonResponsivePropValueTypes;
69
+ /**
70
+ * isVar 系(state 変数扱い・full preset の対象外)の prop かを判定。
71
+ * isVar 未設定の prop は `ExtractPropertyValue` が never を返す。`1 extends X` の向きで
72
+ * 判定することで、X が never でも 1 でもない(= false)になり、tuple ラップ時の
73
+ * `[never] extends [1]` が true に化ける罠を避ける。
74
+ */
75
+ type IsVarProp<T> = 1 extends ExtractPropertyValue<T, 'isVar'> ? true : false;
76
+ /**
77
+ * full モードでレスポンシブになる prop のキー。
78
+ * - isVar 系以外: full preset が bp:1 にするため常にレスポンシブ
79
+ * - isVar 系: props-full.ts の対象外なのでデフォルトの bp 判定のまま
80
+ */
81
+ type FullPropsWithBreakpoint = {
82
+ [K in AllPropKeys]: IsVarProp<PropsConfig[K]> extends true ? (HasBreakpointSupport<PropsConfig[K]> extends true ? K : never) : K;
83
+ }[AllPropKeys];
84
+ type FullPropsWithoutBreakpoint = Exclude<AllPropKeys, FullPropsWithBreakpoint>;
85
+ /** full モード適用時の Props 型(isVar 系を除く全 props がレスポンシブ) */
86
+ type FullPropValueTypes = MakeResponsive<{
87
+ [K in FullPropsWithBreakpoint]?: PropValueType<PropsConfig[K]>;
88
+ }> & {
89
+ [K in FullPropsWithoutBreakpoint]?: PropValueType<PropsConfig[K]>;
90
+ };
91
+ /**
92
+ * FullModeRegistry が module augmentation で拡張されている(= キーが1つ以上ある)か。
93
+ * 空 interface の `keyof` は never。`[never] extends [never]` の tuple ラップで
94
+ * naked never の分配(条件型が never に潰れる)を回避している(HasBreakpointSupport と同手法)。
95
+ */
96
+ type IsFullModeAdvertised = [keyof FullModeRegistry] extends [never] ? false : true;
68
97
  /**
69
98
  * PROPS 設定から生成される Props 型(レスポンシブ対応含む)
70
99
  * - bp が有効なプロパティ: レスポンシブ対応(配列・オブジェクト形式可)
71
100
  * - bp なしのプロパティ: 単一値のみ
72
101
  * - presets/utils/token なしのプロパティ: string | number(フォールバック)
73
102
  *
103
+ * {@link FullModeRegistry} が拡張されている場合は full 版に切り替わり、isVar 系を除く
104
+ * 全 props がレスポンシブになる(lism.config.js の isFullMode に型を追従させるための opt-in)。
105
+ *
74
106
  * @example
75
107
  * ```ts
76
108
  * // bp が有効なプロパティ(fz など)
77
- * fz?: 'root' | 'base' | ... | ['root', 'base'] | { base: 'root', md: 'base' }
109
+ * fz?: 'base' | 'l' | ... | ['base', 'l'] | { base: 'base', md: 'l' }
78
110
  *
79
111
  * // bp なしのプロパティ(fw など)
80
112
  * fw?: 'thin' | 'light' | 'normal' | ...
@@ -83,5 +115,5 @@ export type NonResponsivePropValueTypes = {
83
115
  * bg?: Responsive<string | number>
84
116
  * ```
85
117
  */
86
- export type PropValueTypes = MakeResponsive<ResponsivePropValueTypes> & NonResponsivePropValueTypes;
118
+ export type PropValueTypes = IsFullModeAdvertised extends true ? FullPropValueTypes : DefaultPropValueTypes;
87
119
  export {};
@@ -1,31 +1,75 @@
1
- import { BREAK_POINTS_ALL } from '../../../config/index';
2
1
  import { LimitedArray } from './utils';
3
- /** 全ブレイクポイントキー('base' を含む) */
4
- type BreakpointKey = (typeof BREAK_POINTS_ALL)[number];
5
- /** ブレイクポイント数(5: base, sm, md, lg, xl) */
6
- type BreakpointCount = (typeof BREAK_POINTS_ALL)['length'];
7
- /** ブレイクポイント数を上限とする配列型(1〜5要素) */
8
- type ResponsiveArray<T> = LimitedArray<T | null, BreakpointCount>;
2
+ /**
3
+ * 型が「広告する(補完・許可する)」ブレイクポイントのレジストリ。
4
+ *
5
+ * パッケージのデフォルト広告は `sm` / `md` / `lg` のみ。
6
+ * `xl` / `xs` を使うプロジェクトは、自前の `.d.ts` で `declare module 'lism-css'` により
7
+ * この interface を拡張すると、`Responsive<T>`
8
+ * オブジェクトキー(`{ xl: ... }` など)と配列記法の最大長が連動して広がる。
9
+ *
10
+ * ランタイム(`getBpData` の解釈・配列記法の位置)は `base/sm/md/lg/xl` を
11
+ * 固定で保持しており、ここで切り替えるのは「型が提示・許可するキーの範囲」だけ。
12
+ * これにより「CSS は出力されないのに型では常に許される」xl の非対称を解消する。
13
+ *
14
+ * @example プロジェクト側の型定義ファイル(例: `src/lism.d.ts`)で xl / xs を解禁する
15
+ * ```ts
16
+ * import 'lism-css';
17
+ *
18
+ * declare module 'lism-css' {
19
+ * interface BreakpointRegistry {
20
+ * xl: true; // 配列の5要素目 [.., xl] と { xl: ... } を解禁
21
+ * xs: true; // { xs: ... } を解禁(xs は配列記法では書けない)
22
+ * }
23
+ * }
24
+ * ```
25
+ */
26
+ export interface BreakpointRegistry {
27
+ sm: true;
28
+ md: true;
29
+ lg: true;
30
+ }
31
+ /** 広告するブレイクポイントキー(`base` を除く。文字列キーのみ抽出して string 制約を満たす) */
32
+ type AdvertisedBpKey = Extract<keyof BreakpointRegistry, string>;
33
+ /**
34
+ * 配列記法の位置順(`base` を除く)。位置は固定の契約(変更しない)。
35
+ * `xs` はこの並びに含めない(= 配列記法では書けず、オブジェクト記法のみ)。
36
+ */
37
+ type ArrayBpSequence = ['sm', 'md', 'lg', 'xl'];
38
+ /** タプルのうち `Keys` に含まれる要素だけを残す */
39
+ type FilterByKeys<Tuple extends readonly unknown[], Keys, Acc extends unknown[] = []> = Tuple extends readonly [infer Head, ...infer Rest] ? FilterByKeys<Rest, Keys, Head extends Keys ? [...Acc, Head] : Acc> : Acc;
40
+ /**
41
+ * 広告する配列の最大長 = base(1) + 配列対象 BP のうち広告されている数。
42
+ * `extends infer N extends number` で number へ制約し、LimitedArray の N 制約を満たす。
43
+ */
44
+ type ArrayMaxLength<Bp extends string> = [unknown, ...FilterByKeys<ArrayBpSequence, Bp>]['length'] extends infer N extends number ? N : never;
45
+ /**
46
+ * 広告キーを明示的に受け取るレスポンシブ型のコア。
47
+ * 公開用の {@link Responsive} は `Bp` に `keyof BreakpointRegistry` を差し込む。
48
+ * (型テストで「デフォルト / +xl / +xs」をmodule augmentationなしに検証するためにエクスポートしている)
49
+ */
50
+ export type ResponsiveFor<T, Bp extends string> = T | LimitedArray<T | null, ArrayMaxLength<Bp>> | Partial<Record<'base' | Bp, T>>;
9
51
  /**
10
52
  * プロパティ値をレスポンシブ対応の型に変換するユーティリティ型
11
53
  *
12
- * 単一の値、配列形式(最大5要素)、ブレイクポイントオブジェクト形式のいずれかを受け付ける
54
+ * 単一の値、配列形式(位置は `[base, sm, md, lg, xl]` で固定)、
55
+ * ブレイクポイントオブジェクト形式のいずれかを受け付ける。
56
+ * 許可されるキー・配列長はデフォルトで `base/sm/md/lg`(xl/xs は {@link BreakpointRegistry} の拡張で解禁)。
13
57
  *
14
58
  * @example
15
59
  * ```ts
16
60
  * type FzProp = Responsive<'s' | 'm' | 'l'>;
17
- * // 結果:
61
+ * // 結果(デフォルト広告 sm/md/lg のとき):
18
62
  * // | 's' | 'm' | 'l'
19
- * // | ['s' | 'm' | 'l'] | ['s' | 'm' | 'l', 's' | 'm' | 'l'] | ... (最大5要素)
20
- * // | { base?: 's' | 'm' | 'l'; sm?: 's' | 'm' | 'l'; md?: ...; lg?: ...; xl?: ... }
63
+ * // | ['s' | 'm' | 'l'] | ... (最大4要素 [base, sm, md, lg])
64
+ * // | { base?: ...; sm?: ...; md?: ...; lg?: ... }
21
65
  *
22
66
  * // 使用例
23
67
  * const a: FzProp = 'm'; // 単一値
24
- * const b: FzProp = ['s', 'm', 'l']; // 配列形式(最大5要素)
68
+ * const b: FzProp = ['s', 'm', 'l']; // 配列形式
25
69
  * const c: FzProp = { base: 's', md: 'l' }; // オブジェクト形式
26
70
  * ```
27
71
  */
28
- export type Responsive<T> = T | ResponsiveArray<T> | Partial<Record<BreakpointKey, T>>;
72
+ export type Responsive<T> = ResponsiveFor<T, AdvertisedBpKey>;
29
73
  /**
30
74
  * オブジェクト型の各プロパティをレスポンシブ対応に変換するユーティリティ型
31
75
  *
@@ -12,7 +12,7 @@ function i(s) {
12
12
  if (n.has(s)) return;
13
13
  n.add(s);
14
14
  const e = o[s], t = [`[lism-css] \`${s}\` does not support breakpoint values by default.`];
15
- e && t.push(` - Use the logical property \`${e}\` instead`), t.push(` - ${e ? "Or e" : "E"}nable it via SCSS $props: \`'${s}': ( bp: 1 )\``), t.push(" Docs: https://lism-css.com/en/docs/customize/"), t.push(" * If you've already customized this via SCSS, you can ignore this warning."), console.warn(t.join(`
15
+ e && t.push(` - Use the logical property \`${e}\` instead`), t.push(` - ${e ? "Or e" : "E"}nable it via SCSS $props: \`'${s}': ( bp: 1 )\``), t.push(" Docs: https://lism-css.com/en/docs/customize/scss/"), t.push(" * If you've already customized this via SCSS, you can ignore this warning."), console.warn(t.join(`
16
16
  `));
17
17
  }
18
18
  export {
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lism-css",
3
- "version": "0.22.2",
3
+ "version": "0.23.0",
4
4
  "description": "Lism CSS is a layout-first CSS framework for websites.",
5
5
  "author": {
6
6
  "name": "ddryo",
@@ -12,22 +12,21 @@
12
12
  "astro-component",
13
13
  "react-component"
14
14
  ],
15
- "bin": {
16
- "lism-css": "./bin/cli.mjs"
17
- },
18
15
  "files": [
19
16
  "dist",
20
17
  "config.js",
21
18
  "config.d.ts",
22
- "vite-plugin.js",
23
- "bin",
24
19
  "packages",
25
20
  "src/scss"
26
21
  ],
27
22
  "type": "module",
28
23
  "main": "./dist/index.js",
24
+ "types": "./dist/index.d.ts",
29
25
  "exports": {
30
- ".": "./dist/index.js",
26
+ ".": {
27
+ "types": "./dist/index.d.ts",
28
+ "import": "./dist/index.js"
29
+ },
31
30
  "./config.js": "./config.js",
32
31
  "./config": {
33
32
  "import": "./dist/config/index.js",
@@ -37,12 +36,22 @@
37
36
  "import": "./dist/config/default-config.js",
38
37
  "types": "./dist/config/default-config.d.ts"
39
38
  },
40
- "./vite-plugin": "./vite-plugin.mjs",
39
+ "./config/helper": {
40
+ "import": "./dist/config/helper.js",
41
+ "types": "./dist/config/helper.d.ts"
42
+ },
43
+ "./config/defaults/*": {
44
+ "import": "./dist/config/defaults/*.js",
45
+ "types": "./dist/config/defaults/*.d.ts"
46
+ },
47
+ "./config/presets/*": {
48
+ "import": "./dist/config/presets/*.js",
49
+ "types": "./dist/config/presets/*.d.ts"
50
+ },
41
51
  "./lib/*": {
42
- "import": "./dist/lib/*",
52
+ "import": "./dist/lib/*.js",
43
53
  "types": "./dist/lib/*.d.ts"
44
54
  },
45
- "./bin/*": "./bin/*",
46
55
  "./react": {
47
56
  "import": "./dist/components/index.js",
48
57
  "types": "./dist/components/index.d.ts"
@@ -96,13 +105,8 @@
96
105
  "peerDependencies": {
97
106
  "@types/react": "*",
98
107
  "@types/react-dom": "*",
99
- "autoprefixer": "^10.4.0",
100
- "cssnano": "^7.0.0",
101
- "glob": "^11.0.0 || ^13.0.0",
102
- "postcss": "^8.4.0",
103
108
  "react": "^18 || ^19",
104
- "react-dom": "^18 || ^19",
105
- "sass": "^1.70.0"
109
+ "react-dom": "^18 || ^19"
106
110
  },
107
111
  "peerDependenciesMeta": {
108
112
  "@types/react": {
@@ -110,21 +114,6 @@
110
114
  },
111
115
  "@types/react-dom": {
112
116
  "optional": true
113
- },
114
- "autoprefixer": {
115
- "optional": true
116
- },
117
- "cssnano": {
118
- "optional": true
119
- },
120
- "glob": {
121
- "optional": true
122
- },
123
- "postcss": {
124
- "optional": true
125
- },
126
- "sass": {
127
- "optional": true
128
117
  }
129
118
  },
130
119
  "sideEffects": false,
@@ -133,9 +122,10 @@
133
122
  "test": "pnpm vitest",
134
123
  "vitest": "vitest run",
135
124
  "typecheck": "tsc --noEmit && astro check --tsconfig packages/astro/tsconfig.json",
136
- "build": "pnpm build:js && pnpm build:css",
125
+ "build": "pnpm build:js && pnpm build:css:only",
137
126
  "build:js": "vite build && pnpm exec tsc -p config/tsconfig.json",
138
- "build:css": "tsx bin/script-build-css.js",
127
+ "build:css": "pnpm build:js && pnpm build:css:only",
128
+ "build:css:only": "tsx bin/script-build-css.js",
139
129
  "format": "prettier --write . --ignore-path ../../.prettierignore",
140
130
  "lint": "pnpm lint:eslint && pnpm lint:style",
141
131
  "lint:eslint": "eslint '**/*.{js,mjs,ts,tsx,astro}'",
@@ -94,9 +94,9 @@ $bp_support_list: (); // list
94
94
 
95
95
  // 基本的なbaseセレクタタイプ: 基本は0, BPサポートオンなら 1.
96
96
  $base_type: 0;
97
+ $has_bp_support: $bp_support == 1 or meta.type-of($bp_support) == list;
97
98
 
98
- // Memo: == 1 ではないのは、'sm' や 'md' などの指定も入ってくる可能性があるから
99
- @if $bp_support != 0 {
99
+ @if $has_bp_support {
100
100
  $base_type: 1;
101
101
  }
102
102
 
@@ -145,10 +145,11 @@ $bp_support_list: (); // list
145
145
 
146
146
  // BPクラスを出力するプロパティのリストを作成
147
147
 
148
- // $bp_support が 1 または 文字列('sm','md','lg'などかどうか)
149
- // Memo: 文字列がくるのは、ユーザーカスタマイズでプロパティ個別にサポートするブレイクポイントを変更したい時。
150
- @if $bp_support == 1 or meta.type-of($bp_support) == string {
148
+ // $bp_support が 1(有効BPすべて)/ リスト(出力BPの明示指定)かどうか
149
+ @if $has_bp_support {
151
150
  $bp_support_list: list.append($bp_support_list, $key);
151
+ } @else if $bp_support != 0 {
152
+ @warn "[lism-css] prop '#{$key}': bp must be 0, 1, or a breakpoint list; skipped.";
152
153
  }
153
154
  }
154
155
  // @debug $bp_support_list;
@@ -160,49 +161,61 @@ $bp_support_list: (); // list
160
161
  */
161
162
  // setting.$breakpoints のキーだけを抽出したリストを取得
162
163
  $bp_names: map.keys(setting.$breakpoints);
163
- $bp_outputs: (
164
- 'sm': [],
165
- 'md': [],
166
- 'lg': [],
167
- 'xl': [],
168
- );
164
+ // min-width カスケード順は $breakpoints の正準順序(xs, sm, md, lg, xl)に従う。
165
+ // 無効BP(サイズ0)は Step3 の query.bp-up でスキップされる。
166
+ $bp_outputs: ();
167
+ @each $bp in $bp_names {
168
+ $bp_outputs: map.merge(
169
+ $bp_outputs,
170
+ (
171
+ $bp: [],
172
+ )
173
+ );
174
+ }
169
175
  /* __stylelint-disable */
170
176
  // BPサポートしてるプロパティのリストをループ
171
177
  @each $key in $bp_support_list {
172
178
  $prop_data: map.get(setting.$props, $key);
173
179
  $prop_bp_data: map.get($prop_data, bp);
174
- $support_bp: setting.$common_support_bp;
175
180
 
176
- @if (meta.type-of($prop_bp_data) == string) {
177
- // サポートするブレイクポイントの上書き指定があればそれをセット
178
- $support_bp: $prop_bp_data;
179
- }
180
- // @else if ($prop_bp_data == 0) {
181
- // // 0 が渡されれば、BPサポートを無効にする
182
- // $output_bps: 0;
183
- // }
184
-
185
- $flag: true;
186
- $i: 1;
187
- @while $flag {
188
- $bp: list.nth($bp_names, $i);
189
-
190
- // mapから現在のリストを取得→リスト追加→更新されたリストを再びマージ
191
- $_bp_list: map.get($bp_outputs, $bp);
192
- $_bp_list: list.join($_bp_list, $key);
193
- $bp_outputs: map.merge(
194
- $bp_outputs,
195
- (
196
- $bp: $_bp_list,
197
- )
198
- );
199
-
200
- // サポートするBPまで辿り着いたら終了
201
- @if $bp == $support_bp or $i == list.length($bp_names) {
202
- $flag: false;
181
+ @if (meta.type-of($prop_bp_data) == list) {
182
+ // ── リスト形式: 列挙された BP のみを exact 出力(範囲ではなく明示指定)──
183
+ $_prop_bp_list: $prop_bp_data;
184
+ @each $bp in $_prop_bp_list {
185
+ @if not map.has-key($bp_outputs, $bp) {
186
+ @warn "[lism-css] prop '#{$key}': bp '#{$bp}' is not a known breakpoint key; skipped.";
187
+ } @else {
188
+ // サイズ0(=$breakpoints で無効)の BP を明示指定しても出力されないため警告する
189
+ $_bp_size: map.get(setting.$breakpoints, $bp);
190
+ @if (not $_bp_size) or ($_bp_size == 0) {
191
+ @warn "[lism-css] prop '#{$key}': bp '#{$bp}' has no breakpoint size (disabled in $breakpoints); skipped.";
192
+ } @else {
193
+ $_bp_list: map.get($bp_outputs, $bp);
194
+ $_bp_list: list.join($_bp_list, $key);
195
+ $bp_outputs: map.merge(
196
+ $bp_outputs,
197
+ (
198
+ $bp: $_bp_list,
199
+ )
200
+ );
201
+ }
202
+ }
203
+ }
204
+ } @else {
205
+ // ── 範囲形式(1)──
206
+ // セマンティクス: $breakpoints にサイズが定義された有効BPすべてへ出力する。
207
+ // 無効BP(サイズ0)は Step3 の query.bp-up でスキップされる。
208
+ @each $bp in $bp_names {
209
+ // mapから現在のリストを取得→リスト追加→更新されたリストを再びマージ
210
+ $_bp_list: map.get($bp_outputs, $bp);
211
+ $_bp_list: list.join($_bp_list, $key);
212
+ $bp_outputs: map.merge(
213
+ $bp_outputs,
214
+ (
215
+ $bp: $_bp_list,
216
+ )
217
+ );
203
218
  }
204
-
205
- $i: $i + 1;
206
219
  }
207
220
  }
208
221
  // @debug $bp_outputs;
@@ -227,7 +240,6 @@ $bp_outputs: (
227
240
 
228
241
  .-#{$key}_#{$bp} {
229
242
  @if $alwaysVar == 1 {
230
- // state 変数扱い: --prop を単一情報源にし、--prop を上書きして property は var(--prop) を読む
231
243
  #{$prop_name}: var(--#{$key}) #{get_important_str($important)};
232
244
  --#{$key}: var(--#{$key}_#{$bp}) !important;
233
245
  } @else {