From bb906249935cafb5967646ca1e04813fe7155f83 Mon Sep 17 00:00:00 2001 From: Katorly Date: Mon, 24 Aug 2026 03:52:46 +0000 Subject: [PATCH 1/8] chore: prepare for 0.1.0 refactor --- package.json | 4 +- packages/react/package.json | 2 +- packages/solid/package.json | 2 +- packages/svelte/package.json | 4 +- packages/vue/package.json | 2 +- pnpm-lock.yaml | 72 ++++++++++++++++++------------------ vite.config.ts | 12 ++++++ 7 files changed, 55 insertions(+), 43 deletions(-) diff --git a/package.json b/package.json index 4ca3817..b5e51ef 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "oreui-web", - "version": "0.0.1-beta.1", + "version": "0.1.0-beta.1", "description": "An unofficial Ore UI cross-framework component library.", "type": "module", "repository": { @@ -77,7 +77,7 @@ "react": "^19.2.8", "react-dom": "^19.2.8", "solid-js": "^1.9.15", - "svelte": "^5.56.9", + "svelte": "^5.56.10", "typescript": "^7.0.2", "vite": "^8.2.2", "vite-plugin-solid": "^2.11.14", diff --git a/packages/react/package.json b/packages/react/package.json index e42270f..9f1a726 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@oreui-web/react", - "version": "0.0.1-beta.1", + "version": "0.1.0-beta.1", "description": "Unofficial Ore UI component library for React applications.", "type": "module", "repository": { diff --git a/packages/solid/package.json b/packages/solid/package.json index 0c1c634..c0bfdc8 100644 --- a/packages/solid/package.json +++ b/packages/solid/package.json @@ -1,6 +1,6 @@ { "name": "@oreui-web/solid", - "version": "0.0.1-beta.1", + "version": "0.1.0-beta.1", "description": "Unofficial Ore UI component library for SolidJS applications.", "type": "module", "repository": { diff --git a/packages/svelte/package.json b/packages/svelte/package.json index 4bdb8db..5afb780 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@oreui-web/svelte", - "version": "0.0.1-beta.1", + "version": "0.1.0-beta.1", "description": "Unofficial Ore UI component library for Svelte applications.", "type": "module", "repository": { @@ -66,7 +66,7 @@ "devDependencies": { "@sveltejs/package": "^2.5.8", "@typescript/native": "npm:typescript@^7.0.2", - "svelte": "^5.56.9", + "svelte": "^5.56.10", "svelte-check": "^4.7.6", "typescript": "~5.9.3" }, diff --git a/packages/vue/package.json b/packages/vue/package.json index 8e93219..7ec7539 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@oreui-web/vue", - "version": "0.0.1-beta.1", + "version": "0.1.0-beta.1", "description": "Unofficial Ore UI component library for Vue applications.", "type": "module", "repository": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e40483c..28b1739 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16,7 +16,7 @@ importers: devDependencies: '@sveltejs/vite-plugin-svelte': specifier: ^7.3.0 - version: 7.3.0(svelte@5.56.9)(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0)) + version: 7.3.0(svelte@5.56.10)(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0)) '@types/node': specifier: ^24.13.3 version: 24.13.3 @@ -39,8 +39,8 @@ importers: specifier: ^1.9.15 version: 1.9.15 svelte: - specifier: ^5.56.9 - version: 5.56.9 + specifier: ^5.56.10 + version: 5.56.10 typescript: specifier: ^7.0.2 version: 7.0.2 @@ -176,16 +176,16 @@ importers: devDependencies: '@sveltejs/package': specifier: ^2.5.8 - version: 2.5.8(svelte@5.56.9) + version: 2.5.8(svelte@5.56.10) '@typescript/native': specifier: npm:typescript@^7.0.2 version: typescript@7.0.2 svelte: - specifier: ^5.56.9 - version: 5.56.9 + specifier: ^5.56.10 + version: 5.56.10 svelte-check: specifier: ^4.7.6 - version: 4.7.6(picomatch@4.0.5)(svelte@5.56.9)(typescript@5.9.3) + version: 4.7.6(picomatch@4.0.5)(svelte@5.56.10)(typescript@5.9.3) typescript: specifier: ~5.9.3 version: 5.9.3 @@ -1388,8 +1388,8 @@ packages: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} - baseline-browser-mapping@2.11.15: - resolution: {integrity: sha512-FwMjJJ7HnyZpWe+oWxegG0fezZyBZUagI5LZEoO3GCbtbKNwRfMH9Ue5d5v01PNePBy1QSfPSDTTeVL0Hb9EzA==} + baseline-browser-mapping@2.11.17: + resolution: {integrity: sha512-KAUDn1OSS0fmPlGO+NOUMRcOQ/b/shUBH3OgkG73mPgdf+JD/BQ6fHboGxNOxnUmlwcq+lLq3dTkayRPuSfXwg==} engines: {node: '>=6.0.0'} hasBin: true @@ -1490,8 +1490,8 @@ packages: detect-node-es@1.1.0: resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} - devalue@5.9.0: - resolution: {integrity: sha512-RWrqdArjvPbsATEhOPUo6Wndc/iWnkWKlhIrdlF3zMMYo/c3CVtoaVAyLtWxz5h8nSlkHzxnzV2uLydPXmtF+A==} + devalue@5.9.1: + resolution: {integrity: sha512-+17vil3EVQRzvtDJSFuTWEb8XJRvXqAiV3qZyQWD398QeXUa6CxsUyMdD1fxzEhUrd4FojitFz7lhIHBTlV4fw==} devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} @@ -1533,8 +1533,8 @@ packages: esm-env@1.2.2: resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==} - esrap@2.3.5: - resolution: {integrity: sha512-KciPkeZZX8srrh6xELzLR2cBaWOzgBQ4CwggO6Dh/KMlrfOcIcfyXCVy/Vvc3/OlS5gvFOd5tcxUYuaGM8o45A==} + esrap@2.3.6: + resolution: {integrity: sha512-yc0OC12UjPqLoc+fe+v5GNs4TOjAigUw3sTikfC+xeBPGUw7gDRz3DtYaqEhxyMVJojcSWJw7jT0QWR+CbuE/A==} peerDependencies: '@typescript-eslint/types': ^8.2.0 peerDependenciesMeta: @@ -2337,8 +2337,8 @@ packages: remark@15.0.1: resolution: {integrity: sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A==} - reselect@5.2.0: - resolution: {integrity: sha512-AgZ3UOZm3YndfrJ4OYjgrT7bmCm/1iqkjvEfH/oYjzh6PD2qw4QuT3jjnXIrpdt4MTpMXclMT3lXbmRY+XRakw==} + reselect@5.3.0: + resolution: {integrity: sha512-XGoLeRAVzUTcJ1qkxPQhDJyIZ5d6zzZD9nT7AEZOaaU9UbWclhycElmhO+VD5bFeLuzhPBaOV2oXC8uG35ZSpg==} rolldown@1.2.5: resolution: {integrity: sha512-VD2IE5PUG4Oj8zz2VGykiYd5wbnjdIiSsNQb8Qu5B+noEp+A78mu2iVvpp27g8es14Tk9rofNs5Tku9iQCS4fA==} @@ -2440,8 +2440,8 @@ packages: svelte: ^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0 typescript: ^4.9.4 || ^5.0.0 || ^6.0.0 - svelte@5.56.9: - resolution: {integrity: sha512-VT8kSnlEg8069w7AiCcAk3Yf5xvMnrGTagVOmU/OpOLHaHnNqXhWZCH/4EVga/bT/HtWhvE6/fHrXLErx7OnJA==} + svelte@5.56.10: + resolution: {integrity: sha512-Lcxbj8I/KAbpY+VjtY4ENQBV0dDCipfGAhqb51XQZ67CIQqXgsv/8dPkbILaj4Fb6/b6JAEM/PIVbILXgDQy2g==} engines: {node: '>=18'} tailwindcss@4.3.3: @@ -2781,7 +2781,7 @@ snapshots: '@floating-ui/utils': 0.2.12 react: 19.2.8 react-dom: 19.2.8(react@19.2.8) - reselect: 5.2.0 + reselect: 5.3.0 use-sync-external-store: 1.6.0(react@19.2.8) optionalDependencies: '@types/react': 19.2.18 @@ -3240,22 +3240,22 @@ snapshots: '@sveltejs/load-config@0.2.3': {} - '@sveltejs/package@2.5.8(svelte@5.56.9)': + '@sveltejs/package@2.5.8(svelte@5.56.10)': dependencies: chokidar: 5.0.0 kleur: 4.1.5 sade: 1.8.1 semver: 7.8.5 - svelte: 5.56.9 - svelte2tsx: 0.7.61(svelte@5.56.9)(typescript@5.9.3) + svelte: 5.56.10 + svelte2tsx: 0.7.61(svelte@5.56.10)(typescript@5.9.3) typescript: 5.9.3 - '@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.9)(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0))': + '@sveltejs/vite-plugin-svelte@7.3.0(svelte@5.56.10)(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0))': dependencies: deepmerge: 4.3.1 magic-string: 1.2.2 obug: 2.1.4 - svelte: 5.56.9 + svelte: 5.56.10 vite: 8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0) vitefu: 1.1.3(vite@8.2.2(@types/node@24.13.3)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0)) @@ -3588,7 +3588,7 @@ snapshots: balanced-match@4.0.4: {} - baseline-browser-mapping@2.11.15: {} + baseline-browser-mapping@2.11.17: {} brace-expansion@5.0.9: dependencies: @@ -3596,7 +3596,7 @@ snapshots: browserslist@4.28.8: dependencies: - baseline-browser-mapping: 2.11.15 + baseline-browser-mapping: 2.11.17 caniuse-lite: 1.0.30001809 electron-to-chromium: 1.5.407 node-releases: 2.0.53 @@ -3662,7 +3662,7 @@ snapshots: detect-node-es@1.1.0: {} - devalue@5.9.0: {} + devalue@5.9.1: {} devlop@1.1.0: dependencies: @@ -3728,7 +3728,7 @@ snapshots: esm-env@1.2.2: {} - esrap@2.3.5: + esrap@2.3.6: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -4609,7 +4609,7 @@ snapshots: dependencies: '@next/env': 16.2.12 '@swc/helpers': 0.5.15 - baseline-browser-mapping: 2.11.15 + baseline-browser-mapping: 2.11.17 caniuse-lite: 1.0.30001809 postcss: 8.4.31 react: 19.2.8 @@ -4820,7 +4820,7 @@ snapshots: transitivePeerDependencies: - supports-color - reselect@5.2.0: {} + reselect@5.3.0: {} rolldown@1.2.5: dependencies: @@ -4949,7 +4949,7 @@ snapshots: optionalDependencies: '@babel/core': 7.29.7 - svelte-check@4.7.6(picomatch@4.0.5)(svelte@5.56.9)(typescript@5.9.3): + svelte-check@4.7.6(picomatch@4.0.5)(svelte@5.56.10)(typescript@5.9.3): dependencies: '@jridgewell/trace-mapping': 0.3.31 '@sveltejs/load-config': 0.2.3 @@ -4957,19 +4957,19 @@ snapshots: fdir: 6.5.0(picomatch@4.0.5) picocolors: 1.1.1 sade: 1.8.1 - svelte: 5.56.9 + svelte: 5.56.10 typescript: 5.9.3 transitivePeerDependencies: - picomatch - svelte2tsx@0.7.61(svelte@5.56.9)(typescript@5.9.3): + svelte2tsx@0.7.61(svelte@5.56.10)(typescript@5.9.3): dependencies: dedent-js: 1.0.1 scule: 1.3.0 - svelte: 5.56.9 + svelte: 5.56.10 typescript: 5.9.3 - svelte@5.56.9: + svelte@5.56.10: dependencies: '@jridgewell/remapping': 2.3.5 '@jridgewell/sourcemap-codec': 1.5.5 @@ -4980,9 +4980,9 @@ snapshots: aria-query: 5.3.1 axobject-query: 4.1.0 clsx: 2.1.1 - devalue: 5.9.0 + devalue: 5.9.1 esm-env: 1.2.2 - esrap: 2.3.5 + esrap: 2.3.6 is-reference: 3.0.3 locate-character: 3.0.0 magic-string: 0.30.21 diff --git a/vite.config.ts b/vite.config.ts index a038542..d8d21b3 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -16,6 +16,18 @@ const components = Object.fromEntries( export default defineConfig({ root: "demo", + resolve: { + alias: [ + { + find: /^oreui-web\/(.+)$/, + replacement: `${root}/src/components/$1/$1.ts`, + }, + { + find: "oreui-web", + replacement: `${root}/src/index.ts`, + }, + ], + }, plugins: [ svelte(), solid({ From aa46384a0922905962ccf7c759620937c2fd069e Mon Sep 17 00:00:00 2001 From: Katorly Date: Tue, 25 Aug 2026 11:48:29 +0000 Subject: [PATCH 2/8] chore(release): bump version to 0.0.1 and add v0.0.1 changelog --- docs/content/docs/changelog.mdx | 20 ++++++++++++++++++++ docs/content/docs/changelog.zh-CN.mdx | 20 ++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/docs/content/docs/changelog.mdx b/docs/content/docs/changelog.mdx index 7514cf7..8c40c1f 100644 --- a/docs/content/docs/changelog.mdx +++ b/docs/content/docs/changelog.mdx @@ -6,6 +6,26 @@ icon: RotateCcwClock ## 0.x +### 0.0.1 + +#### Added + +- Button: add more native arguments, including link, href, target, rel, download props, loading state, prefix/suffix slots +- Textarea: add textarea component: + - based on textfield, but supports multiple lines of content + - supports auto complete, text wrap, rows, spellcheck, etc.add docs for textarea + +```html + +``` + +- Slider: add range mode with two arguments: value-start (number) & range (boolean) + ### 0.0.0 The first public release. diff --git a/docs/content/docs/changelog.zh-CN.mdx b/docs/content/docs/changelog.zh-CN.mdx index cf94696..b0ecc51 100644 --- a/docs/content/docs/changelog.zh-CN.mdx +++ b/docs/content/docs/changelog.zh-CN.mdx @@ -6,6 +6,26 @@ icon: RotateCcwClock ## 0.x +### 0.0.1 + +#### 新增 + +- Button:增加更多原生属性,包括 link、href、target、rel、download 属性,以及 loading 状态、prefix/suffix 插槽 +- Textarea:新增 textarea 组件: + - 基于 textfield,支持多行内容 + - 支持自动补全、文本换行、行数、拼写检查等;新增 textarea 文档 + +```html + +``` + +- Slider:新增范围模式,包含两个参数:value-start (number) 和 range (boolean) + ### 0.0.0 首个公开版本。 From b39b131d0a3ab453568400ed09f5ced8c81bd684 Mon Sep 17 00:00:00 2001 From: Katorly Date: Tue, 25 Aug 2026 12:40:08 +0000 Subject: [PATCH 3/8] refactor(core): replace custom elements with native HTML elements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - refactor button, checkbox, radio, radiogroup, switch, slider, textfield, textarea components - update wrappers & docs 🤖Some parts of this change were assisted by AI. Co-authored-by: Codex --- docs/components/home-showcase.tsx | 10 +- docs/components/stories/button.story.tsx | 5 +- docs/components/stories/radio-group.story.tsx | 3 +- docs/components/stories/slider.story.tsx | 20 +- docs/components/stories/switch.story.tsx | 17 +- docs/components/stories/textarea.story.tsx | 19 +- docs/components/stories/textfield.story.tsx | 123 +++++- docs/content/docs/buttons/button.mdx | 76 ++-- docs/content/docs/buttons/button.zh-CN.mdx | 76 ++-- docs/content/docs/controls/checkbox.mdx | 72 ++-- docs/content/docs/controls/checkbox.zh-CN.mdx | 72 ++-- docs/content/docs/controls/radio-group.mdx | 55 +-- .../docs/controls/radio-group.zh-CN.mdx | 57 +-- docs/content/docs/controls/radio.mdx | 39 +- docs/content/docs/controls/radio.zh-CN.mdx | 39 +- docs/content/docs/controls/slider.mdx | 108 +++--- docs/content/docs/controls/slider.zh-CN.mdx | 108 +++--- docs/content/docs/controls/switch.mdx | 73 ++-- docs/content/docs/controls/switch.zh-CN.mdx | 73 ++-- docs/content/docs/controls/textarea.mdx | 51 +-- docs/content/docs/controls/textarea.zh-CN.mdx | 51 +-- docs/content/docs/controls/textfield.mdx | 125 ++++-- .../content/docs/controls/textfield.zh-CN.mdx | 110 ++++-- docs/content/docs/getting-started/astro.mdx | 2 +- .../docs/getting-started/astro.zh-CN.mdx | 2 +- docs/content/docs/getting-started/vanilla.mdx | 2 +- .../docs/getting-started/vanilla.zh-CN.mdx | 2 +- docs/content/docs/guides/forms-and-events.mdx | 5 +- .../docs/guides/forms-and-events.zh-CN.mdx | 5 +- docs/content/docs/messages/modal.mdx | 28 +- docs/content/docs/messages/modal.zh-CN.mdx | 28 +- docs/package.json | 4 +- package.json | 2 +- packages/react/package.json | 2 +- packages/react/src/components/button.ts | 34 +- packages/react/src/components/checkbox.ts | 38 +- packages/react/src/components/radio-group.ts | 20 +- packages/react/src/components/radio.ts | 38 +- packages/react/src/components/slider.ts | 53 ++- packages/react/src/components/switch.ts | 41 +- packages/react/src/components/textarea.ts | 16 - packages/react/src/components/textarea.tsx | 69 ++++ packages/react/src/components/textfield.ts | 16 - packages/react/src/components/textfield.tsx | 69 ++++ packages/solid/src/components/button.tsx | 64 +--- packages/solid/src/components/checkbox.tsx | 49 ++- packages/solid/src/components/radio-group.tsx | 19 +- packages/solid/src/components/radio.tsx | 46 ++- packages/solid/src/components/slider.tsx | 91 +++-- packages/solid/src/components/switch.tsx | 57 +-- packages/solid/src/components/textarea.tsx | 124 +++--- packages/solid/src/components/textfield.tsx | 128 ++++--- packages/svelte/src/components/button.svelte | 38 +- .../svelte/src/components/checkbox.svelte | 42 +- .../svelte/src/components/radio-group.svelte | 19 +- packages/svelte/src/components/radio.svelte | 37 +- packages/svelte/src/components/slider.svelte | 87 ++--- packages/svelte/src/components/switch.svelte | 64 ++-- .../svelte/src/components/textarea.svelte | 85 +++-- .../svelte/src/components/textfield.svelte | 87 +++-- packages/svelte/src/elements.d.ts | 10 - packages/vue/src/components/button.ts | 29 +- packages/vue/src/components/checkbox.ts | 48 ++- packages/vue/src/components/radio-group.ts | 25 +- packages/vue/src/components/radio.ts | 30 +- packages/vue/src/components/slider.ts | 61 ++- packages/vue/src/components/switch.ts | 51 ++- packages/vue/src/components/textarea.ts | 99 ++++- packages/vue/src/components/textfield.ts | 99 ++++- pnpm-lock.yaml | 67 ++-- src/behaviors/legacy-button.ts | 167 ++++++++ src/components/button/button.css | 148 +++++++- src/components/button/button.ts | 314 --------------- src/components/checkbox/checkbox.css | 105 ++--- src/components/checkbox/checkbox.ts | 204 ---------- src/components/icon-button/icon-button.ts | 4 +- src/components/radio-group/radio-group.css | 6 +- src/components/radio-group/radio-group.ts | 25 +- src/components/radio/radio.css | 96 +++-- src/components/radio/radio.ts | 245 ------------ src/components/slider/slider.css | 279 ++++---------- src/components/slider/slider.ts | 310 ++++----------- src/components/switch/switch.css | 130 ++++--- src/components/switch/switch.ts | 220 ----------- src/components/tab-button/tab-button.ts | 6 +- src/components/textarea/textarea.css | 24 +- src/components/textarea/textarea.ts | 359 ------------------ src/components/textfield/textfield.css | 40 +- src/components/textfield/textfield.ts | 322 ---------------- src/index.ts | 19 +- src/styles/reset.css | 17 +- 91 files changed, 2743 insertions(+), 3711 deletions(-) delete mode 100644 packages/react/src/components/textarea.ts create mode 100644 packages/react/src/components/textarea.tsx delete mode 100644 packages/react/src/components/textfield.ts create mode 100644 packages/react/src/components/textfield.tsx create mode 100644 src/behaviors/legacy-button.ts delete mode 100644 src/components/textfield/textfield.ts diff --git a/docs/components/home-showcase.tsx b/docs/components/home-showcase.tsx index 35b0b0c..14f6ebd 100644 --- a/docs/components/home-showcase.tsx +++ b/docs/components/home-showcase.tsx @@ -147,10 +147,7 @@ export function HomeShowcase() { max={16} aria-label="Render distance" onInput={(event) => - setDistance( - (event.currentTarget as HTMLElement & { value: number }) - .value, - ) + setDistance(event.currentTarget.valueAsNumber) } /> - setDistance( - (event.currentTarget as HTMLElement & { value: number }) - .value, - ) + setDistance(event.currentTarget.valueAsNumber) } /> diff --git a/docs/components/stories/button.story.tsx b/docs/components/stories/button.story.tsx index 00df8a8..9f9fe67 100644 --- a/docs/components/stories/button.story.tsx +++ b/docs/components/stories/button.story.tsx @@ -49,13 +49,14 @@ function ButtonPreview({ export function LinkButtonPreview() { return ( - + ); } diff --git a/docs/components/stories/radio-group.story.tsx b/docs/components/stories/radio-group.story.tsx index 6210490..891df9c 100644 --- a/docs/components/stories/radio-group.story.tsx +++ b/docs/components/stories/radio-group.story.tsx @@ -38,7 +38,8 @@ function RadioGroupPreview({ return (
- + + {label} {options.map((option) => { const optionValue = option.toLowerCase(); return ( diff --git a/docs/components/stories/slider.story.tsx b/docs/components/stories/slider.story.tsx index 25b7bb6..cb31e8d 100644 --- a/docs/components/stories/slider.story.tsx +++ b/docs/components/stories/slider.story.tsx @@ -15,11 +15,9 @@ interface SliderPreviewProps { | "gold"; disabled: boolean; initialValue: number; - initialValueStart: number; max: number; min: number; orientation: "horizontal" | "vertical"; - range: boolean; step: number; variant: "default" | "segmented"; } @@ -28,17 +26,14 @@ function SliderPreview({ color, disabled, initialValue, - initialValueStart, max, min, orientation, - range, step, variant, }: SliderPreviewProps) { const [mounted, setMounted] = useState(false); const [value, setValue] = useState(initialValue); - const [valueStart, setValueStart] = useState(initialValueStart); useEffect(() => { setMounted(true); @@ -57,23 +52,14 @@ function SliderPreview({ max={max} min={min} orientation={orientation} - range={range} step={step} value={value} - valueStart={valueStart} variant={variant} onInput={(event) => { - const slider = event.target as HTMLElement & { - value: number; - valueStart: number; - }; - setValue(slider.value); - setValueStart(slider.valueStart); + setValue((event.currentTarget as HTMLInputElement).valueAsNumber); }} /> - - Render distance: {range ? `${valueStart}-${value}` : value} - + Render distance: {value}
); } @@ -88,11 +74,9 @@ export const sliderStory = defineStory({ color: "primary", disabled: false, initialValue: 12, - initialValueStart: 4, max: 32, min: 2, orientation: "horizontal", - range: false, step: 1, variant: "segmented", }, diff --git a/docs/components/stories/switch.story.tsx b/docs/components/stories/switch.story.tsx index 1497b50..b0319e0 100644 --- a/docs/components/stories/switch.story.tsx +++ b/docs/components/stories/switch.story.tsx @@ -2,7 +2,8 @@ import { defineStoryFactory } from "@fumadocs/story/next/client"; import { Switch } from "@oreui-web/react/switch"; -import { useEffect, useState } from "react"; +import type { ChangeEvent } from "react"; +import { useState } from "react"; interface SwitchPreviewProps { color: @@ -26,17 +27,8 @@ function SwitchPreview({ label, variant, }: SwitchPreviewProps) { - const [mounted, setMounted] = useState(false); const [checked, setChecked] = useState(initialChecked); - useEffect(() => { - setMounted(true); - }, []); - - if (!mounted) { - return null; - } - return (
{ - const control = event.target as HTMLElement & { checked: boolean }; - setChecked(control.checked); + onChange={(event: ChangeEvent) => { + setChecked(event.currentTarget.checked); }} > {label} diff --git a/docs/components/stories/textarea.story.tsx b/docs/components/stories/textarea.story.tsx index 0aca438..f51fbbb 100644 --- a/docs/components/stories/textarea.story.tsx +++ b/docs/components/stories/textarea.story.tsx @@ -2,7 +2,12 @@ import { defineStoryFactory } from "@fumadocs/story/next/client"; import { Textarea } from "@oreui-web/react/textarea"; -import { type CSSProperties, useEffect, useState } from "react"; +import { + type CSSProperties, + type FormEvent, + useEffect, + useState, +} from "react"; interface TextareaPreviewProps { description: string; @@ -10,7 +15,7 @@ interface TextareaPreviewProps { error: string; label: string; placeholder: string; - readonly: boolean; + readOnly: boolean; required: boolean; rows: number; spellcheck: boolean; @@ -23,7 +28,7 @@ function TextareaPreview({ error, label, placeholder, - readonly, + readOnly, required, rows, spellcheck, @@ -48,7 +53,7 @@ function TextareaPreview({ error={error} label={label} placeholder={placeholder} - readonly={readonly} + readOnly={readOnly} required={required} rows={rows} spellCheck={spellcheck} @@ -60,8 +65,8 @@ function TextareaPreview({ "--ore-textarea-foreground": "var(--color-fd-foreground)", } as CSSProperties } - onInput={(event) => { - const textarea = event.target as HTMLElement & { value: string }; + onInput={(event: FormEvent) => { + const textarea = event.currentTarget; setValue(textarea.value); }} /> @@ -82,7 +87,7 @@ export const textareaStory = defineStory({ error: "", label: "World description", placeholder: "Describe your world", - readonly: false, + readOnly: false, required: false, rows: 3, spellcheck: true, diff --git a/docs/components/stories/textfield.story.tsx b/docs/components/stories/textfield.story.tsx index 80afb9d..34a382c 100644 --- a/docs/components/stories/textfield.story.tsx +++ b/docs/components/stories/textfield.story.tsx @@ -14,6 +14,11 @@ interface TextfieldPreviewProps { type: string; } +const textfieldStyle = { + "--ore-textfield-description": "var(--color-fd-muted-foreground)", + "--ore-textfield-foreground": "var(--color-fd-foreground)", +} as CSSProperties; + function TextfieldPreview({ description, disabled, @@ -35,28 +40,104 @@ function TextfieldPreview({ } return ( -
- { - const field = event.target as HTMLElement & { value: string }; - setValue(field.value); +
+
- Value: {value || "empty"} + > +
+

default

+ +
+
+

hover

+ +
+
+

focus

+ +
+
+

pressed

+ +
+
+

disabled

+ +
+
+ +
+ { + const field = event.currentTarget as HTMLInputElement; + setValue(field.value); + }} + /> + +
setValue("")} + onSubmit={(event) => event.preventDefault()} + style={{ display: "flex", gap: "0.5rem", flexWrap: "wrap" }} + > + + + Value: {value || "empty"} +
+
); } diff --git a/docs/content/docs/buttons/button.mdx b/docs/content/docs/buttons/button.mdx index 0940d1c..ca2db69 100644 --- a/docs/content/docs/buttons/button.mdx +++ b/docs/content/docs/buttons/button.mdx @@ -18,11 +18,11 @@ Use buttons for actions such as confirming a choice, opening a screen, or submit ```js -import "oreui-web/button"; +import "oreui-web/styles.css"; ``` ```html -Create new world + ``` @@ -75,11 +75,7 @@ export function App() { ```astro -Create new world - - + ``` @@ -89,34 +85,34 @@ export function App() { ## Variants ```html -Default -Hero + + ``` ## Colors ```html -Primary -Secondary -Delete -Dungeons -Legends -Gold -Realms + + + + + + + ``` ## Disabled ```html -Unavailable + ``` ## Loading -Set `loading` while an action is in progress. The button keeps its width, shows a spinner, exposes `aria-busy="true"`, and prevents repeated activation. +Set `data-loading` while an action is in progress, and keep the native button disabled with `aria-busy="true"`. Framework bindings do this mapping when their `loading` prop is set. ```html -Saving + ``` ## Prefix and suffix @@ -126,30 +122,30 @@ Use the public `.ore-button-prefix` and `.ore-button-suffix` classes to place pr ```html - + - + ``` ## Links -Set `href` to use the component for navigation. Link buttons use a native anchor and support browser behaviors such as opening in a new tab, copying the link, and downloading a resource. +Use a native anchor with `class="button"` for navigation. It preserves browser behaviors such as opening in a new tab, copying the link, and downloading a resource. ```html - + Open website - + ``` -Use a link button for navigation and a regular button for actions. A disabled link is removed from the tab order and does not navigate. +Use a link button for navigation and a regular button for actions. Anchors do not support `disabled`; omit `href` or remove the link when navigation is unavailable. ## Forms @@ -157,32 +153,18 @@ The default `type` is `button`. Set `type="submit"` explicitly for a submit butt ```html
- Save - Reset + +
- + ``` ## API -| Property | Attribute | Type | Default | -| ---------- | ---------- | -------------------------------------------------------------------------------------------- | ----------- | -| `color` | `color` | `"destructive" \| "dungeons" \| "gold" \| "legends" \| "primary" \| "realms" \| "secondary"` | `"primary"` | -| `disabled` | `disabled` | `boolean` | `false` | -| `download` | `download` | `string \| undefined` | `undefined` | -| `href` | `href` | `string \| undefined` | `undefined` | -| `loading` | `loading` | `boolean` | `false` | -| `name` | `name` | `string` | `""` | -| `rel` | `rel` | `string \| undefined` | `undefined` | -| `target` | `target` | `string \| undefined` | `undefined` | -| `type` | `type` | `"button" \| "reset" \| "submit"` | `"button"` | -| `value` | `value` | `string` | `""` | -| `variant` | `variant` | `"default" \| "hero"` | `"default"` | - -The read-only `form` property returns the associated `HTMLFormElement`, or `null`. The `form` attribute accepts a form ID. +Button uses the native `HTMLButtonElement` API. Use native attributes such as `disabled`, `form`, `name`, `type`, and `value`; use `data-color`, `data-variant`, and `data-loading` only for OreUI visual configuration. ## CSS variables @@ -204,4 +186,4 @@ The read-only `form` property returns the associated `HTMLFormElement`, or `null ## Accessibility -Without `href`, the component uses button semantics and supports `Enter` and `Space`. With `href`, a native anchor provides link semantics and standard browser navigation. Disabled buttons and links are removed from the tab order and expose `aria-disabled="true"`. Loading buttons expose `aria-busy="true"` and prevent repeated activation. +Native buttons provide form participation, validation, focus, `Enter`, and `Space` behavior without a controller. Native anchors provide standard link semantics and navigation. Loading buttons remain disabled and expose `aria-busy="true"`. diff --git a/docs/content/docs/buttons/button.zh-CN.mdx b/docs/content/docs/buttons/button.zh-CN.mdx index af660ea..99202fc 100644 --- a/docs/content/docs/buttons/button.zh-CN.mdx +++ b/docs/content/docs/buttons/button.zh-CN.mdx @@ -18,11 +18,11 @@ Button 用于确认选择、打开页面、提交表单等操作。 ```js -import "oreui-web/button"; +import "oreui-web/styles.css"; ``` ```html -Create new world + ``` @@ -75,11 +75,7 @@ export function App() { ```astro -Create new world - - + ``` @@ -89,34 +85,34 @@ export function App() { ## 变体 ```html -Default -Hero + + ``` ## 颜色 ```html -Primary -Secondary -Delete -Dungeons -Legends -Gold -Realms + + + + + + + ``` ## Disabled ```html -Unavailable + ``` ## 加载中 -操作进行时可设置 `loading`。按钮会保持原宽度、显示 Spinner、提供 `aria-busy="true"`,并阻止重复触发。 +操作进行时设置 `data-loading`,并同时保留原生 `disabled` 和 `aria-busy="true"`。框架 wrapper 会在设置 `loading` prop 时完成这些映射。 ```html -Saving + ``` ## 前后缀 @@ -126,30 +122,30 @@ export function App() { ```html - + - + ``` ## 链接 -设置 `href` 后,组件可用于页面导航。链接按钮使用原生锚点,支持在新标签页打开、复制链接和下载资源等浏览器行为。 +页面导航使用带 `class="button"` 的原生锚点,并保留在新标签页打开、复制链接和下载资源等浏览器行为。 ```html - + Open website - + ``` -页面导航应使用链接按钮,触发操作则使用普通按钮。禁用的链接会移出 Tab 顺序,并且不会发生导航。 +页面导航应使用链接按钮,触发操作则使用普通按钮。锚点不支持 `disabled`;导航不可用时应移除 `href` 或移除该链接。 ## 表单 @@ -157,32 +153,18 @@ export function App() { ```html
- Save - Reset + +
- + ``` ## API -| Prop | 属性 | 类型 | 默认值 | -| ---------- | ---------- | -------------------------------------------------------------------------------------------- | ----------- | -| `color` | `color` | `"destructive" \| "dungeons" \| "gold" \| "legends" \| "primary" \| "realms" \| "secondary"` | `"primary"` | -| `disabled` | `disabled` | `boolean` | `false` | -| `download` | `download` | `string \| undefined` | `undefined` | -| `href` | `href` | `string \| undefined` | `undefined` | -| `loading` | `loading` | `boolean` | `false` | -| `name` | `name` | `string` | `""` | -| `rel` | `rel` | `string \| undefined` | `undefined` | -| `target` | `target` | `string \| undefined` | `undefined` | -| `type` | `type` | `"button" \| "reset" \| "submit"` | `"button"` | -| `value` | `value` | `string` | `""` | -| `variant` | `variant` | `"default" \| "hero"` | `"default"` | - -只读的 `form` property 会返回关联的 `HTMLFormElement`,没有关联表单时返回 `null`。`form` 属性接受表单 ID。 +Button 直接使用原生 `HTMLButtonElement` API。`disabled`、`form`、`name`、`type`、`value` 等使用原生属性;只有 OreUI 视觉配置使用 `data-color`、`data-variant` 和 `data-loading`。 ## CSS 变量 @@ -204,4 +186,4 @@ export function App() { ## 无障碍 -未设置 `href` 时,组件使用按钮语义,并支持 `Enter` 和 `Space` 键。设置 `href` 后,原生锚点会提供链接语义和标准浏览器导航行为。禁用的按钮和链接不会被 Tab 键选中,并带有 `aria-disabled="true"`。加载中的按钮提供 `aria-busy="true"` 并阻止重复触发。 +原生按钮无需 controller 即可提供表单参与、校验、焦点、`Enter` 和 `Space` 行为。原生锚点提供标准链接语义和导航。加载中的按钮保持禁用,并提供 `aria-busy="true"`。 diff --git a/docs/content/docs/controls/checkbox.mdx b/docs/content/docs/controls/checkbox.mdx index 449a9a0..a5a992b 100644 --- a/docs/content/docs/controls/checkbox.mdx +++ b/docs/content/docs/controls/checkbox.mdx @@ -12,11 +12,14 @@ import { CheckboxStory } from "@/components/stories/checkbox.story"; ```js -import "oreui-web/checkbox"; +import "oreui-web/styles.css"; ``` ```html - Receive updates + ``` @@ -35,8 +38,7 @@ export function UpdatesCheckbox() { name="updates" value="yes" onChange={(event) => { - const checkbox = event.target as HTMLElement & { checked: boolean }; - setChecked(checkbox.checked); + setChecked(event.currentTarget.checked); }} > Receive updates @@ -105,13 +107,14 @@ export function UpdatesCheckbox() { ```astro - - Receive updates - + - + ``` @@ -121,21 +124,23 @@ export function UpdatesCheckbox() { ## Colors ```html -Primary -Secondary -Destructive -Dungeons -Legends -Realms -Gold + + + + + + + ``` ## States ```html -Enabled -Unavailable -Required agreement + + + ``` ## Forms @@ -144,33 +149,22 @@ Checked values are included in `FormData`. Reset restores the initial `checked` ```html
- + - Continue - Reset + + +
``` ## Events -Checkbox dispatches native `input` and `change` events after its value changes. +The native checkbox dispatches `input` and `change` events when its value changes. ## API -| Property | Attribute | Type | Default | -| ---------- | ---------- | -------------------------------------------------------------------------------------------- | ----------- | -| `checked` | `checked` | `boolean` | `false` | -| `color` | `color` | `"primary" \| "secondary" \| "destructive" \| "dungeons" \| "legends" \| "realms" \| "gold"` | `"primary"` | -| `disabled` | `disabled` | `boolean` | `false` | -| `name` | `name` | `string` | `""` | -| `required` | `required` | `boolean` | `false` | -| `value` | `value` | `string` | `"on"` | - -| Method | Description | -| ------------------ | ---------------------------------- | -| `checkValidity()` | Check the current validity | -| `reportValidity()` | Check validity and report an error | +Checkbox uses the native `HTMLInputElement` API. Use `checked`, `disabled`, `name`, `required`, and `value` directly; use `data-color` only for the OreUI palette. Native methods such as `checkValidity()` and `reportValidity()` remain available. ## CSS variables @@ -190,4 +184,4 @@ Checkbox dispatches native `input` and `change` events after its value changes. ## Accessibility -Checkbox provides checkbox semantics and supports Space. +The native input provides checkbox semantics, label activation, Space key behavior, form participation, validation, and reset behavior without JavaScript. diff --git a/docs/content/docs/controls/checkbox.zh-CN.mdx b/docs/content/docs/controls/checkbox.zh-CN.mdx index d798b23..5f8dd33 100644 --- a/docs/content/docs/controls/checkbox.zh-CN.mdx +++ b/docs/content/docs/controls/checkbox.zh-CN.mdx @@ -12,11 +12,14 @@ import { CheckboxStory } from "@/components/stories/checkbox.story"; ```js -import "oreui-web/checkbox"; +import "oreui-web/styles.css"; ``` ```html - Receive updates + ``` @@ -35,8 +38,7 @@ export function UpdatesCheckbox() { name="updates" value="yes" onChange={(event) => { - const checkbox = event.target as HTMLElement & { checked: boolean }; - setChecked(checkbox.checked); + setChecked(event.currentTarget.checked); }} > Receive updates @@ -104,13 +106,14 @@ export function UpdatesCheckbox() { ```astro - - Receive updates - + - + ``` @@ -120,21 +123,23 @@ export function UpdatesCheckbox() { ## 颜色 ```html -Primary -Secondary -Destructive -Dungeons -Legends -Realms -Gold + + + + + + + ``` ## 状态 ```html -Enabled -Unavailable -Required agreement + + + ``` ## 表单 @@ -143,33 +148,22 @@ export function UpdatesCheckbox() { ```html
- + - Continue - Reset + + +
``` ## 事件 -Checkbox 的值发生变化后,会触发原生 `input` 和 `change` 事件。 +原生 Checkbox 的值发生变化后会触发 `input` 和 `change` 事件。 ## API -| Prop | 属性 | 类型 | 默认值 | -| ---------- | ---------- | -------------------------------------------------------------------------------------------- | ----------- | -| `checked` | `checked` | `boolean` | `false` | -| `color` | `color` | `"primary" \| "secondary" \| "destructive" \| "dungeons" \| "legends" \| "realms" \| "gold"` | `"primary"` | -| `disabled` | `disabled` | `boolean` | `false` | -| `name` | `name` | `string` | `""` | -| `required` | `required` | `boolean` | `false` | -| `value` | `value` | `string` | `"on"` | - -| 方法 | 描述 | -| ------------------ | -------------------- | -| `checkValidity()` | 检查当前有效性 | -| `reportValidity()` | 检查有效性并报告错误 | +Checkbox 直接使用原生 `HTMLInputElement` API。`checked`、`disabled`、`name`、`required` 和 `value` 使用原生属性;只有 OreUI 配色使用 `data-color`。`checkValidity()`、`reportValidity()` 等原生方法保持可用。 ## CSS 变量 @@ -189,4 +183,4 @@ Checkbox 的值发生变化后,会触发原生 `input` 和 `change` 事件。 ## 无障碍 -Checkbox 提供相应的无障碍语义,并支持空格键。 +原生 input 无需 JavaScript 就能提供 Checkbox 语义、label 激活、空格键操作、表单参与、校验和重置行为。 diff --git a/docs/content/docs/controls/radio-group.mdx b/docs/content/docs/controls/radio-group.mdx index 6196013..9714055 100644 --- a/docs/content/docs/controls/radio-group.mdx +++ b/docs/content/docs/controls/radio-group.mdx @@ -11,16 +11,22 @@ import { RadioGroupStory } from "@/components/stories/radio-group.story"; -```js -import "oreui-web/radio-group"; -``` - ```html - - Survival - Creative - Hardcore - +
+ World type + + + +
```
@@ -31,7 +37,8 @@ import { Radio, RadioGroup } from "@oreui-web/react/radio-group"; export function WorldType() { return ( - + + World type Survival @@ -55,7 +62,8 @@ import { Radio, RadioGroup } from "@oreui-web/vue";