@markuplint/react-spec 4.5.22 → 5.0.0-alpha.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/ARCHITECTURE.ja.md +88 -0
- package/ARCHITECTURE.md +88 -0
- package/CHANGELOG.md +8 -2
- package/SKILL.md +100 -0
- package/docs/maintenance.ja.md +114 -0
- package/docs/maintenance.md +114 -0
- package/lib/index.d.ts +18 -0
- package/lib/index.js +19 -0
- package/package.json +6 -3
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# @markuplint/react-spec
|
|
2
|
+
|
|
3
|
+
## 概要
|
|
4
|
+
|
|
5
|
+
`@markuplint/react-spec` は、markuplint に React 固有の JSX 属性定義を提供する仕様拡張パッケージです。グローバル JSX 属性(`key`、`ref`、`dangerouslySetInnerHTML`、ハイドレーション/contentEditable 警告抑制フラグなど)と、React の制御/非制御フォームコンポーネント(`input`、`select`、`textarea`)の要素レベル属性オーバーライドを登録する単一の `ExtendedSpec` オブジェクトをエクスポートします。
|
|
6
|
+
|
|
7
|
+
このパッケージにはパースロジックは含まれません。純粋なデータ定義であり、`@markuplint/ml-spec` が基本 HTML 仕様を React 固有の属性で拡張するために使用されます。
|
|
8
|
+
|
|
9
|
+
## ExtendedSpec の内容
|
|
10
|
+
|
|
11
|
+
### `useIDLAttributeNames`
|
|
12
|
+
|
|
13
|
+
この spec は `useIDLAttributeNames: true` を設定しており、`@markuplint/ml-core` の `MLAttr` コンストラクタに IDL 属性名を HTML コンテンツ属性名に解決するよう指示します(例: `className` -> `class`、`htmlFor` -> `for`)。この解決はパーサーではなくコアレベルで行われます。
|
|
14
|
+
|
|
15
|
+
### グローバル属性
|
|
16
|
+
|
|
17
|
+
グローバル属性は `def['#globalAttrs']['#extends']` の下に定義され、すべての JSX 要素で利用可能です:
|
|
18
|
+
|
|
19
|
+
| 属性名 | 型 | 説明 |
|
|
20
|
+
| -------------------------------- | --------- | ------------------------------------------------------------------------ |
|
|
21
|
+
| `key` | `Any` | リストレンダリング用の特殊属性。React が変更された項目を識別するのに使用 |
|
|
22
|
+
| `ref` | `Any` | 子コンポーネントのインスタンスや DOM 要素にアクセスするための属性 |
|
|
23
|
+
| `dangerouslySetInnerHTML` | `Any` | ブラウザ DOM で `innerHTML` を使用する代わりの React の手段 |
|
|
24
|
+
| `suppressContentEditableWarning` | `Boolean` | 子要素を持つ要素が `contentEditable` の場合の警告を抑制 |
|
|
25
|
+
| `suppressHydrationWarning` | `Boolean` | React のハイドレーションミスマッチ警告を抑制 |
|
|
26
|
+
|
|
27
|
+
### 要素固有のオーバーライド
|
|
28
|
+
|
|
29
|
+
要素固有の属性は `specs[]` 配列に定義されます。各エントリは特定の HTML 要素を名前で指定します:
|
|
30
|
+
|
|
31
|
+
| 要素 | 属性名 | 型 | 条件 | 説明 |
|
|
32
|
+
| ---------- | ---------------- | --------- | --------------------------------- | ---------------------------------------- |
|
|
33
|
+
| `input` | `defaultChecked` | `Boolean` | `[type=checkbox]`, `[type=radio]` | 初期チェック状態の非制御コンポーネント版 |
|
|
34
|
+
| `input` | `defaultValue` | `Any` | -- | 初期値の非制御コンポーネント版 |
|
|
35
|
+
| `select` | `value` | `Any` | -- | 制御コンポーネントの値 |
|
|
36
|
+
| `select` | `defaultValue` | `Any` | -- | 初期値の非制御コンポーネント版 |
|
|
37
|
+
| `textarea` | `value` | `Any` | -- | 制御コンポーネントの値 |
|
|
38
|
+
| `textarea` | `defaultValue` | `Any` | -- | 初期値の非制御コンポーネント版 |
|
|
39
|
+
|
|
40
|
+
`caseSensitive: true` を持つ属性は大文字小文字の完全一致が必要です(例: `defaultchecked` ではなく `defaultChecked`)。`condition` フィールドは CSS セレクタ構文を使用して、属性が有効な場合を制限します。
|
|
41
|
+
|
|
42
|
+
## ディレクトリ構成
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
src/
|
|
46
|
+
└── index.ts — React 固有の属性を持つ ExtendedSpec オブジェクトをエクスポート
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## 主要ソースファイル
|
|
50
|
+
|
|
51
|
+
| ファイル | 用途 |
|
|
52
|
+
| ---------- | ------------------------------------------------------------- |
|
|
53
|
+
| `index.ts` | `ExtendedSpec` オブジェクトをデフォルトエクスポートとして定義 |
|
|
54
|
+
|
|
55
|
+
## 統合ポイント
|
|
56
|
+
|
|
57
|
+
```mermaid
|
|
58
|
+
flowchart LR
|
|
59
|
+
subgraph upstream ["上流"]
|
|
60
|
+
htmlSpec["@markuplint/html-spec\n(基本 HTML 仕様)"]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
subgraph pkg ["@markuplint/react-spec"]
|
|
64
|
+
spec["ExtendedSpec\n(React 属性)"]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
subgraph downstream ["下流"]
|
|
68
|
+
mlSpec["@markuplint/ml-spec\n(仕様解決)"]
|
|
69
|
+
mlCore["@markuplint/ml-core\n(リントエンジン)"]
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
htmlSpec -->|"基本仕様"| mlSpec
|
|
73
|
+
spec -->|"拡張"| mlSpec
|
|
74
|
+
mlSpec -->|"解決済み仕様"| mlCore
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 上流
|
|
78
|
+
|
|
79
|
+
- **`@markuplint/ml-spec`** -- このパッケージが実装する `ExtendedSpec` 型を提供
|
|
80
|
+
|
|
81
|
+
### 下流
|
|
82
|
+
|
|
83
|
+
- **`@markuplint/ml-spec`** -- `ExtendedSpec` オブジェクトを使用して、React 固有の属性を解決済み仕様にマージ
|
|
84
|
+
- **`@markuplint/ml-core`** -- リント時に解決済み仕様(React 拡張を含む)を使用
|
|
85
|
+
|
|
86
|
+
## ドキュメントマップ
|
|
87
|
+
|
|
88
|
+
- [メンテナンスガイド](docs/maintenance.ja.md) -- コマンド、レシピ、ExtendedSpec 型リファレンス
|
package/ARCHITECTURE.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# @markuplint/react-spec
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
`@markuplint/react-spec` is a spec extension package that provides React-specific JSX attribute definitions for markuplint. It exports a single `ExtendedSpec` object that registers global JSX attributes (such as `key`, `ref`, `dangerouslySetInnerHTML`, and hydration/contentEditable warning suppression flags) and element-level attribute overrides for React's controlled and uncontrolled form components (`input`, `select`, `textarea`).
|
|
6
|
+
|
|
7
|
+
This package contains no parsing logic -- it is purely a data definition consumed by `@markuplint/ml-spec` to extend the base HTML specification with React-specific attributes.
|
|
8
|
+
|
|
9
|
+
## ExtendedSpec Content
|
|
10
|
+
|
|
11
|
+
### `useIDLAttributeNames`
|
|
12
|
+
|
|
13
|
+
The spec sets `useIDLAttributeNames: true`, which instructs `@markuplint/ml-core`'s `MLAttr` constructor to resolve IDL attribute names to their HTML content attribute equivalents (e.g., `className` -> `class`, `htmlFor` -> `for`). This resolution is performed at the core level, not in the parser.
|
|
14
|
+
|
|
15
|
+
### Global Attributes
|
|
16
|
+
|
|
17
|
+
Global attributes are defined under `def['#globalAttrs']['#extends']` and are available on every JSX element:
|
|
18
|
+
|
|
19
|
+
| Attribute | Type | Description |
|
|
20
|
+
| -------------------------------- | --------- | ------------------------------------------------------------------------- |
|
|
21
|
+
| `key` | `Any` | Special attribute for list rendering to help React identify changed items |
|
|
22
|
+
| `ref` | `Any` | Attribute for accessing child component instances and DOM elements |
|
|
23
|
+
| `dangerouslySetInnerHTML` | `Any` | React's replacement for using `innerHTML` in the browser DOM |
|
|
24
|
+
| `suppressContentEditableWarning` | `Boolean` | Suppresses the warning when an element with children is `contentEditable` |
|
|
25
|
+
| `suppressHydrationWarning` | `Boolean` | Suppresses React hydration mismatch warnings for attributes and content |
|
|
26
|
+
|
|
27
|
+
### Element-Specific Overrides
|
|
28
|
+
|
|
29
|
+
Element-specific attributes are defined in the `specs[]` array. Each entry targets a specific HTML element by name:
|
|
30
|
+
|
|
31
|
+
| Element | Attribute | Type | Condition | Description |
|
|
32
|
+
| ---------- | ---------------- | --------- | --------------------------------- | ------------------------------------------------- |
|
|
33
|
+
| `input` | `defaultChecked` | `Boolean` | `[type=checkbox]`, `[type=radio]` | Uncontrolled equivalent for initial checked state |
|
|
34
|
+
| `input` | `defaultValue` | `Any` | -- | Uncontrolled equivalent for initial value |
|
|
35
|
+
| `select` | `value` | `Any` | -- | Controlled component value |
|
|
36
|
+
| `select` | `defaultValue` | `Any` | -- | Uncontrolled equivalent for initial value |
|
|
37
|
+
| `textarea` | `value` | `Any` | -- | Controlled component value |
|
|
38
|
+
| `textarea` | `defaultValue` | `Any` | -- | Uncontrolled equivalent for initial value |
|
|
39
|
+
|
|
40
|
+
Attributes with `caseSensitive: true` require exact case matching (e.g., `defaultChecked` not `defaultchecked`). The `condition` field uses CSS selector syntax to restrict when the attribute is valid.
|
|
41
|
+
|
|
42
|
+
## Directory Structure
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
src/
|
|
46
|
+
└── index.ts — Exports the ExtendedSpec object with React-specific attributes
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Key Source Files
|
|
50
|
+
|
|
51
|
+
| File | Purpose |
|
|
52
|
+
| ---------- | ------------------------------------------------------------------- |
|
|
53
|
+
| `index.ts` | Defines and exports the `ExtendedSpec` object as the default export |
|
|
54
|
+
|
|
55
|
+
## Integration Points
|
|
56
|
+
|
|
57
|
+
```mermaid
|
|
58
|
+
flowchart LR
|
|
59
|
+
subgraph upstream ["Upstream"]
|
|
60
|
+
htmlSpec["@markuplint/html-spec\n(Base HTML spec)"]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
subgraph pkg ["@markuplint/react-spec"]
|
|
64
|
+
spec["ExtendedSpec\n(React attributes)"]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
subgraph downstream ["Downstream"]
|
|
68
|
+
mlSpec["@markuplint/ml-spec\n(Spec resolution)"]
|
|
69
|
+
mlCore["@markuplint/ml-core\n(Linting engine)"]
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
htmlSpec -->|"Base spec"| mlSpec
|
|
73
|
+
spec -->|"Extends"| mlSpec
|
|
74
|
+
mlSpec -->|"Resolved spec"| mlCore
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Upstream
|
|
78
|
+
|
|
79
|
+
- **`@markuplint/ml-spec`** -- Provides the `ExtendedSpec` type that this package implements
|
|
80
|
+
|
|
81
|
+
### Downstream
|
|
82
|
+
|
|
83
|
+
- **`@markuplint/ml-spec`** -- Consumes the `ExtendedSpec` object to merge React-specific attributes into the resolved specification
|
|
84
|
+
- **`@markuplint/ml-core`** -- Uses the resolved spec (including React extensions) during linting
|
|
85
|
+
|
|
86
|
+
## Documentation Map
|
|
87
|
+
|
|
88
|
+
- [Maintenance Guide](docs/maintenance.md) -- Commands, recipes, and ExtendedSpec type reference
|
package/CHANGELOG.md
CHANGED
|
@@ -3,13 +3,19 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
# [5.0.0-alpha.0](https://github.com/markuplint/markuplint/compare/v4.14.1...v5.0.0-alpha.0) (2026-02-20)
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- **react-spec:** add useIDLAttributeNames flag for IDL attribute resolution ([8d19c0c](https://github.com/markuplint/markuplint/commit/8d19c0cff75b5f0ee9703df08591642a8bd4fa47))
|
|
9
11
|
|
|
12
|
+
## [4.5.23](https://github.com/markuplint/markuplint/compare/@markuplint/react-spec@4.5.22...@markuplint/react-spec@4.5.23) (2026-02-10)
|
|
10
13
|
|
|
14
|
+
**Note:** Version bump only for package @markuplint/react-spec
|
|
11
15
|
|
|
16
|
+
## [4.5.22](https://github.com/markuplint/markuplint/compare/@markuplint/react-spec@4.5.21...@markuplint/react-spec@4.5.22) (2025-11-05)
|
|
12
17
|
|
|
18
|
+
**Note:** Version bump only for package @markuplint/react-spec
|
|
13
19
|
|
|
14
20
|
## [4.5.21](https://github.com/markuplint/markuplint/compare/@markuplint/react-spec@4.5.20...@markuplint/react-spec@4.5.21) (2025-08-24)
|
|
15
21
|
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Maintenance tasks for @markuplint/react-spec
|
|
3
|
+
globs:
|
|
4
|
+
- packages/@markuplint/react-spec/src/**/*.ts
|
|
5
|
+
alwaysApply: false
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# react-spec-maintenance
|
|
9
|
+
|
|
10
|
+
Perform maintenance tasks for `@markuplint/react-spec`: add global attributes,
|
|
11
|
+
add element-specific overrides, and modify the ExtendedSpec object.
|
|
12
|
+
|
|
13
|
+
## Input
|
|
14
|
+
|
|
15
|
+
`$ARGUMENTS` specifies the task. Supported tasks:
|
|
16
|
+
|
|
17
|
+
| Task | Description |
|
|
18
|
+
| ---------------------- | ---------------------------------------------- |
|
|
19
|
+
| `add-global-attribute` | Add a new global attribute to the ExtendedSpec |
|
|
20
|
+
| `add-element-override` | Add an element-specific attribute override |
|
|
21
|
+
|
|
22
|
+
If omitted, defaults to `add-global-attribute`.
|
|
23
|
+
|
|
24
|
+
## Reference
|
|
25
|
+
|
|
26
|
+
Before executing any task, read `docs/maintenance.md` (or `docs/maintenance.ja.md`)
|
|
27
|
+
for the full guide. The recipes there are the source of truth for procedures.
|
|
28
|
+
|
|
29
|
+
Also read:
|
|
30
|
+
|
|
31
|
+
- `ARCHITECTURE.md` -- Package overview, ExtendedSpec content, and integration points
|
|
32
|
+
- `src/index.ts` -- ExtendedSpec object definition (source of truth)
|
|
33
|
+
|
|
34
|
+
## Task: add-global-attribute
|
|
35
|
+
|
|
36
|
+
Add a new global attribute available on every JSX element. Follow recipe #1 in `docs/maintenance.md`.
|
|
37
|
+
|
|
38
|
+
### Step 1: Identify the attribute
|
|
39
|
+
|
|
40
|
+
1. Determine the attribute name, type (`Any`, `Boolean`, or a specific type), and description
|
|
41
|
+
2. Check the React documentation to confirm the attribute is a valid global JSX attribute
|
|
42
|
+
|
|
43
|
+
### Step 2: Add the attribute
|
|
44
|
+
|
|
45
|
+
1. Read `src/index.ts`
|
|
46
|
+
2. Add a new entry under `def['#globalAttrs']['#extends']`:
|
|
47
|
+
```ts
|
|
48
|
+
attributeName: {
|
|
49
|
+
type: 'Any', // or 'Boolean'
|
|
50
|
+
},
|
|
51
|
+
```
|
|
52
|
+
3. Add a JSDoc comment above the entry describing its purpose
|
|
53
|
+
|
|
54
|
+
### Step 3: Verify
|
|
55
|
+
|
|
56
|
+
1. Build: `yarn build --scope @markuplint/react-spec`
|
|
57
|
+
2. Confirm the attribute appears in the exported spec object
|
|
58
|
+
|
|
59
|
+
## Task: add-element-override
|
|
60
|
+
|
|
61
|
+
Add an element-specific attribute override. Follow recipe #2 in `docs/maintenance.md`.
|
|
62
|
+
|
|
63
|
+
### Step 1: Identify the element and attribute
|
|
64
|
+
|
|
65
|
+
1. Determine the target element name (e.g., `input`, `select`, `textarea`)
|
|
66
|
+
2. Determine the attribute name, type, and optional conditions
|
|
67
|
+
|
|
68
|
+
### Step 2: Add the override
|
|
69
|
+
|
|
70
|
+
1. Read `src/index.ts`
|
|
71
|
+
2. Find the element in the `specs[]` array, or add a new entry:
|
|
72
|
+
```ts
|
|
73
|
+
{
|
|
74
|
+
name: 'elementName',
|
|
75
|
+
attributes: {
|
|
76
|
+
attributeName: {
|
|
77
|
+
type: 'Any',
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
```
|
|
82
|
+
3. If the attribute has conditions (e.g., only for certain input types), add a `condition` array:
|
|
83
|
+
```ts
|
|
84
|
+
condition: ['[type=checkbox]', '[type=radio]'],
|
|
85
|
+
```
|
|
86
|
+
4. If the attribute is case-sensitive, add `caseSensitive: true`
|
|
87
|
+
5. Add a JSDoc comment above the entry describing its purpose
|
|
88
|
+
|
|
89
|
+
### Step 3: Verify
|
|
90
|
+
|
|
91
|
+
1. Build: `yarn build --scope @markuplint/react-spec`
|
|
92
|
+
2. Confirm the attribute appears in the exported spec object
|
|
93
|
+
|
|
94
|
+
## Rules
|
|
95
|
+
|
|
96
|
+
1. **Only export an ExtendedSpec object** -- this package contains no parsing logic.
|
|
97
|
+
2. **Global attributes go under `def['#globalAttrs']['#extends']`** -- they apply to all elements.
|
|
98
|
+
3. **Element overrides go under `specs[]` array** -- each entry targets a specific HTML element by name.
|
|
99
|
+
4. **Each attribute needs at minimum a `type` field** -- valid types include `Any`, `Boolean`, and specific type strings.
|
|
100
|
+
5. **Add JSDoc comments** to all new attribute entries describing their purpose.
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# メンテナンスガイド
|
|
2
|
+
|
|
3
|
+
## コマンド
|
|
4
|
+
|
|
5
|
+
| コマンド | 説明 |
|
|
6
|
+
| ------------------------------------------- | ---------------------- |
|
|
7
|
+
| `yarn build --scope @markuplint/react-spec` | このパッケージをビルド |
|
|
8
|
+
| `yarn dev --scope @markuplint/react-spec` | ウォッチモードでビルド |
|
|
9
|
+
| `yarn clean --scope @markuplint/react-spec` | ビルド成果物を削除 |
|
|
10
|
+
|
|
11
|
+
## テスト
|
|
12
|
+
|
|
13
|
+
このパッケージには専用のテストスイートはありません。`ExtendedSpec` オブジェクトは、`@markuplint/ml-spec` の `ExtendedSpec` 型に対する TypeScript 型チェックにより、ビルド時に検証されます。エクスポートされたオブジェクトが型に適合しない場合、ビルドが失敗します。
|
|
14
|
+
|
|
15
|
+
統合テストは下流で行われます:
|
|
16
|
+
|
|
17
|
+
- `@markuplint/ml-spec` が拡張仕様を解決し、基本 HTML 仕様とマージ
|
|
18
|
+
- `@markuplint/ml-core` がリント時に解決済み仕様を使用し、属性定義を実行
|
|
19
|
+
|
|
20
|
+
変更を検証するには、パッケージをビルドして下流のテストを実行します:
|
|
21
|
+
|
|
22
|
+
```shell
|
|
23
|
+
yarn build --scope @markuplint/react-spec
|
|
24
|
+
yarn test --scope @markuplint/ml-spec --scope @markuplint/ml-core
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## レシピ
|
|
28
|
+
|
|
29
|
+
### 1. グローバル属性の追加
|
|
30
|
+
|
|
31
|
+
グローバル属性はすべての JSX 要素で利用可能です。
|
|
32
|
+
|
|
33
|
+
1. `src/index.ts` を開く
|
|
34
|
+
2. `def['#globalAttrs']['#extends']` の下に新しいエントリを追加:
|
|
35
|
+
```ts
|
|
36
|
+
/** 属性の説明 */
|
|
37
|
+
attributeName: {
|
|
38
|
+
type: 'Any', // または 'Boolean'
|
|
39
|
+
},
|
|
40
|
+
```
|
|
41
|
+
3. 適切な型を選択:
|
|
42
|
+
- `'Any'` -- 任意の値を受け付ける(文字列、式など)
|
|
43
|
+
- `'Boolean'` -- ブール属性(存在が `true` を意味する)
|
|
44
|
+
4. ビルド: `yarn build --scope @markuplint/react-spec`
|
|
45
|
+
|
|
46
|
+
### 2. 要素固有のオーバーライドの追加
|
|
47
|
+
|
|
48
|
+
要素オーバーライドは、特定の HTML 要素でのみ利用可能な属性を定義します。
|
|
49
|
+
|
|
50
|
+
1. `src/index.ts` を開く
|
|
51
|
+
2. `specs[]` 配列で対象の要素を探す。存在しない場合は新しいエントリを追加:
|
|
52
|
+
```ts
|
|
53
|
+
{
|
|
54
|
+
name: 'elementName',
|
|
55
|
+
attributes: {
|
|
56
|
+
/** 属性の説明 */
|
|
57
|
+
attributeName: {
|
|
58
|
+
type: 'Any',
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
```
|
|
63
|
+
3. 要素が既に存在する場合は、その `attributes` オブジェクトに新しい属性を追加
|
|
64
|
+
4. ビルド: `yarn build --scope @markuplint/react-spec`
|
|
65
|
+
|
|
66
|
+
### 3. 条件付き属性の追加
|
|
67
|
+
|
|
68
|
+
条件付き属性は、要素が CSS セレクタ条件に一致する場合にのみ有効です。
|
|
69
|
+
|
|
70
|
+
1. `src/index.ts` を開く
|
|
71
|
+
2. `specs[]` 配列で要素エントリを見つけるか作成
|
|
72
|
+
3. `condition` 配列を持つ属性を追加:
|
|
73
|
+
```ts
|
|
74
|
+
attributeName: {
|
|
75
|
+
type: 'Boolean',
|
|
76
|
+
caseSensitive: true,
|
|
77
|
+
condition: ['[type=checkbox]', '[type=radio]'],
|
|
78
|
+
},
|
|
79
|
+
```
|
|
80
|
+
4. `condition` 配列は CSS 属性セレクタ構文を使用
|
|
81
|
+
5. 複数の条件は OR として扱われる -- いずれかの条件に一致すれば属性は有効
|
|
82
|
+
6. 属性名の大文字小文字を区別する必要がある場合は `caseSensitive: true` を設定(React JSX 属性では一般的)
|
|
83
|
+
7. ビルド: `yarn build --scope @markuplint/react-spec`
|
|
84
|
+
|
|
85
|
+
## ExtendedSpec 型リファレンス
|
|
86
|
+
|
|
87
|
+
`ExtendedSpec` 型(`@markuplint/ml-spec` から)は、このパッケージに関連する以下の構造を持ちます:
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
interface ExtendedSpec {
|
|
91
|
+
def?: {
|
|
92
|
+
'#globalAttrs'?: {
|
|
93
|
+
'#extends': Record<string, AttributeSpec>;
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
specs?: Array<{
|
|
97
|
+
name: string;
|
|
98
|
+
attributes: Record<string, AttributeSpec>;
|
|
99
|
+
}>;
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### AttributeSpec のフィールド
|
|
104
|
+
|
|
105
|
+
| フィールド | 型 | 必須 | 説明 |
|
|
106
|
+
| --------------- | ---------- | ------ | --------------------------------------- |
|
|
107
|
+
| `type` | `string` | はい | 属性値の型(`'Any'`、`'Boolean'` など) |
|
|
108
|
+
| `caseSensitive` | `boolean` | いいえ | 属性名の大文字小文字を区別するかどうか |
|
|
109
|
+
| `condition` | `string[]` | いいえ | 属性が適用される CSS セレクタ条件 |
|
|
110
|
+
|
|
111
|
+
### 型の値
|
|
112
|
+
|
|
113
|
+
- `'Any'` -- 属性は任意の値を受け付ける
|
|
114
|
+
- `'Boolean'` -- 属性はブール値(存在が `true` を示す)
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Maintenance Guide
|
|
2
|
+
|
|
3
|
+
## Commands
|
|
4
|
+
|
|
5
|
+
| Command | Description |
|
|
6
|
+
| ------------------------------------------- | ---------------------- |
|
|
7
|
+
| `yarn build --scope @markuplint/react-spec` | Build this package |
|
|
8
|
+
| `yarn dev --scope @markuplint/react-spec` | Watch mode build |
|
|
9
|
+
| `yarn clean --scope @markuplint/react-spec` | Remove build artifacts |
|
|
10
|
+
|
|
11
|
+
## Testing
|
|
12
|
+
|
|
13
|
+
This package has no dedicated test suite. The `ExtendedSpec` object is validated at build time through TypeScript type checking against the `ExtendedSpec` type from `@markuplint/ml-spec`. If the exported object does not conform to the type, the build will fail.
|
|
14
|
+
|
|
15
|
+
Integration testing occurs downstream:
|
|
16
|
+
|
|
17
|
+
- `@markuplint/ml-spec` resolves the extended spec and merges it with the base HTML spec
|
|
18
|
+
- `@markuplint/ml-core` uses the resolved spec during linting, which exercises the attribute definitions
|
|
19
|
+
|
|
20
|
+
To verify changes, build the package and run downstream tests:
|
|
21
|
+
|
|
22
|
+
```shell
|
|
23
|
+
yarn build --scope @markuplint/react-spec
|
|
24
|
+
yarn test --scope @markuplint/ml-spec --scope @markuplint/ml-core
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Recipes
|
|
28
|
+
|
|
29
|
+
### 1. Adding a Global Attribute
|
|
30
|
+
|
|
31
|
+
Global attributes are available on every JSX element.
|
|
32
|
+
|
|
33
|
+
1. Open `src/index.ts`
|
|
34
|
+
2. Add a new entry under `def['#globalAttrs']['#extends']`:
|
|
35
|
+
```ts
|
|
36
|
+
/** Description of the attribute */
|
|
37
|
+
attributeName: {
|
|
38
|
+
type: 'Any', // or 'Boolean'
|
|
39
|
+
},
|
|
40
|
+
```
|
|
41
|
+
3. Choose the appropriate type:
|
|
42
|
+
- `'Any'` -- accepts any value (strings, expressions, etc.)
|
|
43
|
+
- `'Boolean'` -- boolean attribute (presence means `true`)
|
|
44
|
+
4. Build: `yarn build --scope @markuplint/react-spec`
|
|
45
|
+
|
|
46
|
+
### 2. Adding an Element-Specific Override
|
|
47
|
+
|
|
48
|
+
Element overrides define attributes available only on specific HTML elements.
|
|
49
|
+
|
|
50
|
+
1. Open `src/index.ts`
|
|
51
|
+
2. Find the target element in the `specs[]` array. If it does not exist, add a new entry:
|
|
52
|
+
```ts
|
|
53
|
+
{
|
|
54
|
+
name: 'elementName',
|
|
55
|
+
attributes: {
|
|
56
|
+
/** Description of the attribute */
|
|
57
|
+
attributeName: {
|
|
58
|
+
type: 'Any',
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
```
|
|
63
|
+
3. If the element already exists, add the new attribute to its `attributes` object
|
|
64
|
+
4. Build: `yarn build --scope @markuplint/react-spec`
|
|
65
|
+
|
|
66
|
+
### 3. Adding a Conditional Attribute
|
|
67
|
+
|
|
68
|
+
Conditional attributes are only valid when the element matches a CSS selector condition.
|
|
69
|
+
|
|
70
|
+
1. Open `src/index.ts`
|
|
71
|
+
2. Find or create the element entry in the `specs[]` array
|
|
72
|
+
3. Add the attribute with a `condition` array:
|
|
73
|
+
```ts
|
|
74
|
+
attributeName: {
|
|
75
|
+
type: 'Boolean',
|
|
76
|
+
caseSensitive: true,
|
|
77
|
+
condition: ['[type=checkbox]', '[type=radio]'],
|
|
78
|
+
},
|
|
79
|
+
```
|
|
80
|
+
4. The `condition` array uses CSS attribute selector syntax
|
|
81
|
+
5. Multiple conditions are treated as an OR -- the attribute is valid if any condition matches
|
|
82
|
+
6. Set `caseSensitive: true` if the attribute name must be case-sensitive (typical for React JSX attributes)
|
|
83
|
+
7. Build: `yarn build --scope @markuplint/react-spec`
|
|
84
|
+
|
|
85
|
+
## ExtendedSpec Type Reference
|
|
86
|
+
|
|
87
|
+
The `ExtendedSpec` type (from `@markuplint/ml-spec`) has the following structure relevant to this package:
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
interface ExtendedSpec {
|
|
91
|
+
def?: {
|
|
92
|
+
'#globalAttrs'?: {
|
|
93
|
+
'#extends': Record<string, AttributeSpec>;
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
specs?: Array<{
|
|
97
|
+
name: string;
|
|
98
|
+
attributes: Record<string, AttributeSpec>;
|
|
99
|
+
}>;
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### AttributeSpec Fields
|
|
104
|
+
|
|
105
|
+
| Field | Type | Required | Description |
|
|
106
|
+
| --------------- | ---------- | -------- | ------------------------------------------------------ |
|
|
107
|
+
| `type` | `string` | Yes | The attribute value type (`'Any'`, `'Boolean'`, etc.) |
|
|
108
|
+
| `caseSensitive` | `boolean` | No | Whether the attribute name is case-sensitive |
|
|
109
|
+
| `condition` | `string[]` | No | CSS selector conditions for when the attribute applies |
|
|
110
|
+
|
|
111
|
+
### Type Values
|
|
112
|
+
|
|
113
|
+
- `'Any'` -- The attribute accepts any value
|
|
114
|
+
- `'Boolean'` -- The attribute is a boolean (presence indicates `true`)
|
package/lib/index.d.ts
CHANGED
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module @markuplint/react-spec
|
|
3
|
+
*
|
|
4
|
+
* Provides React-specific extended specifications for markuplint.
|
|
5
|
+
* Defines React's JSX global attributes (such as `key`, `ref`,
|
|
6
|
+
* `dangerouslySetInnerHTML`, and hydration/contentEditable warning
|
|
7
|
+
* suppression flags) as well as element-level attribute overrides
|
|
8
|
+
* for controlled and uncontrolled form components (`input`, `select`,
|
|
9
|
+
* `textarea`).
|
|
10
|
+
*/
|
|
1
11
|
import type { ExtendedSpec } from '@markuplint/ml-spec';
|
|
12
|
+
/**
|
|
13
|
+
* The React framework extended specification.
|
|
14
|
+
*
|
|
15
|
+
* Registers global JSX attributes available on every element and
|
|
16
|
+
* provides per-element attribute definitions for React's controlled
|
|
17
|
+
* and uncontrolled form component patterns (`defaultChecked`,
|
|
18
|
+
* `defaultValue`, `value`).
|
|
19
|
+
*/
|
|
2
20
|
declare const spec: ExtendedSpec;
|
|
3
21
|
export default spec;
|
package/lib/index.js
CHANGED
|
@@ -1,4 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module @markuplint/react-spec
|
|
3
|
+
*
|
|
4
|
+
* Provides React-specific extended specifications for markuplint.
|
|
5
|
+
* Defines React's JSX global attributes (such as `key`, `ref`,
|
|
6
|
+
* `dangerouslySetInnerHTML`, and hydration/contentEditable warning
|
|
7
|
+
* suppression flags) as well as element-level attribute overrides
|
|
8
|
+
* for controlled and uncontrolled form components (`input`, `select`,
|
|
9
|
+
* `textarea`).
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* The React framework extended specification.
|
|
13
|
+
*
|
|
14
|
+
* Registers global JSX attributes available on every element and
|
|
15
|
+
* provides per-element attribute definitions for React's controlled
|
|
16
|
+
* and uncontrolled form component patterns (`defaultChecked`,
|
|
17
|
+
* `defaultValue`, `value`).
|
|
18
|
+
*/
|
|
1
19
|
const spec = {
|
|
20
|
+
useIDLAttributeNames: true,
|
|
2
21
|
def: {
|
|
3
22
|
'#globalAttrs': {
|
|
4
23
|
'#extends': {
|
package/package.json
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markuplint/react-spec",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0-alpha.0",
|
|
4
4
|
"description": "Extended specification for tags and attributes in React",
|
|
5
5
|
"repository": "git@github.com:markuplint/markuplint.git",
|
|
6
6
|
"author": "Yusuke Hirao <yusukehirao@me.com>",
|
|
7
7
|
"license": "MIT",
|
|
8
|
+
"engines": {
|
|
9
|
+
"node": ">=22"
|
|
10
|
+
},
|
|
8
11
|
"type": "module",
|
|
9
12
|
"exports": {
|
|
10
13
|
".": {
|
|
@@ -21,7 +24,7 @@
|
|
|
21
24
|
"clean": "tsc --build --clean tsconfig.build.json"
|
|
22
25
|
},
|
|
23
26
|
"dependencies": {
|
|
24
|
-
"@markuplint/ml-spec": "
|
|
27
|
+
"@markuplint/ml-spec": "5.0.0-alpha.0"
|
|
25
28
|
},
|
|
26
|
-
"gitHead": "
|
|
29
|
+
"gitHead": "13dcfc84ec83d87360c720e253383b60767e1b56"
|
|
27
30
|
}
|