ranui 0.1.10-alpha.9 → 0.2.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/README.md +397 -0
- package/README.zh-CN.md +216 -37
- package/dist/assets/image/failImage.d.ts +2 -0
- package/dist/bin/generate-component-api.d.ts +1 -0
- package/dist/bin/generate-style-docs.d.ts +1 -0
- package/dist/build/config.bundle.d.ts +2 -0
- package/dist/build/config.d.ts +3 -0
- package/dist/build/config.es.d.ts +2 -0
- package/dist/build/config.umd.d.ts +1 -0
- package/dist/builder.d.ts +11 -0
- package/dist/builder.js +39 -0
- package/dist/button-DukaD6uL.js +117 -0
- package/dist/button.js +3 -5
- package/dist/card-DQUJoDUQ.js +60 -0
- package/dist/card.js +5 -0
- package/dist/checkbox-iHZQb-yQ.js +94 -0
- package/dist/checkbox.js +3 -5
- package/dist/colorpicker-Ch67dWa_.js +302 -0
- package/dist/colorpicker.js +3 -9
- package/dist/components/button/index.d.ts +44 -0
- package/dist/components/card/index.d.ts +21 -0
- package/dist/components/checkbox/index.d.ts +35 -0
- package/dist/components/colorpicker/index.d.ts +88 -0
- package/dist/components/dropdown/index.d.ts +32 -0
- package/dist/components/form/index.d.ts +15 -0
- package/dist/components/icon/index.d.ts +58 -0
- package/dist/components/image/index.d.ts +25 -0
- package/dist/components/input/index.d.ts +229 -0
- package/dist/components/link/index.d.ts +21 -0
- package/dist/components/loading/index.d.ts +76 -0
- package/dist/components/math/index.d.ts +16 -0
- package/dist/components/message/container.d.ts +8 -0
- package/dist/components/message/index.d.ts +32 -0
- package/dist/components/modal/index.d.ts +100 -0
- package/dist/components/player/core/constants.d.ts +5 -0
- package/dist/components/player/core/controller.d.ts +33 -0
- package/dist/components/player/core/events.d.ts +10 -0
- package/dist/components/player/core/fullscreen.d.ts +5 -0
- package/dist/components/player/core/levels.d.ts +20 -0
- package/dist/components/player/core/media.d.ts +50 -0
- package/dist/components/player/core/playback.d.ts +14 -0
- package/dist/components/player/core/progress.d.ts +2 -0
- package/dist/components/player/core/state.d.ts +27 -0
- package/dist/components/player/core/view.d.ts +39 -0
- package/dist/components/player/index.d.ts +277 -0
- package/dist/components/popover/content/index.d.ts +12 -0
- package/dist/components/popover/index.d.ts +95 -0
- package/dist/components/progress/index.d.ts +40 -0
- package/dist/components/radar/index.d.ts +52 -0
- package/dist/components/route/index.d.ts +26 -0
- package/dist/components/router/index.d.ts +24 -0
- package/dist/components/scratch/index.d.ts +19 -0
- package/dist/components/section/index.d.ts +23 -0
- package/dist/components/select/dropdown-item/index.d.ts +21 -0
- package/dist/components/select/index.d.ts +135 -0
- package/dist/components/select/option/index.d.ts +19 -0
- package/dist/components/skeleton/index.d.ts +13 -0
- package/dist/components/tab/index.d.ts +58 -0
- package/dist/components/tabpane/index.d.ts +33 -0
- package/dist/demo/i18n.d.ts +4 -0
- package/dist/demo/index.d.ts +3 -0
- package/dist/demo/register-icons.d.ts +1 -0
- package/dist/dropdown-C5362qTy.js +82 -0
- package/dist/dropdown.js +6 -0
- package/dist/events-C59wGdni.js +30 -0
- package/dist/factory-BdsO0dEW.js +165 -0
- package/dist/form-05Lxxl3D.js +44 -0
- package/dist/form.js +5 -0
- package/dist/icon-DmoEnao5.js +165 -0
- package/dist/icon.js +4 -4
- package/dist/{index-KS2nvVcO.js → image-6GayFDqX.js} +58 -71
- package/dist/image.js +3 -2
- package/dist/index.cjs +35 -0
- package/dist/index.d.ts +277 -114
- package/dist/index.iife.js +306 -0
- package/dist/index.js +78 -38
- package/dist/input-DoraIb3x.js +198 -0
- package/dist/input.js +2 -3
- package/dist/katex-es-Bpesphgp.js +23682 -0
- package/dist/katex-es-Cnq5Pk8K.cjs +261 -0
- package/dist/link-BW-gvrpN.js +77 -0
- package/dist/link.js +6 -0
- package/dist/loading-Mko22ncl.js +206 -0
- package/dist/loading.js +4 -6
- package/dist/math-B5PpSnFR.js +52 -0
- package/dist/math.js +2 -4
- package/dist/message-CQENvkoi.js +137 -0
- package/dist/message.js +3 -4
- package/dist/mocks-CMGoftIc.js +179 -0
- package/dist/modal-DruDj3AB.js +350 -0
- package/dist/modal.js +3 -2
- package/dist/player-CvfmwWUa.js +13536 -0
- package/dist/player.js +3 -6
- package/dist/playwright.config.d.ts +2 -0
- package/dist/plugins/load-svg.d.ts +9 -0
- package/dist/popover-BCvHwLZb.js +213 -0
- package/dist/popover.js +3 -5
- package/dist/progress-BWkNf2J5.js +123 -0
- package/dist/progress.js +3 -5
- package/dist/radar-CWsawt2g.js +181 -0
- package/dist/radar.js +3 -4
- package/dist/ranui.css +1 -0
- package/dist/route-BY_E6-2C.js +88 -0
- package/dist/route.js +6 -0
- package/dist/router-BDcv4F-2.js +79 -0
- package/dist/router.js +6 -0
- package/dist/scratch-Dbd9G6Q6.js +60 -0
- package/dist/scratch.js +4 -0
- package/dist/section-CNTvgdQ-.js +63 -0
- package/dist/section.js +5 -0
- package/dist/select-BmhCUTLb.js +433 -0
- package/dist/select.js +3 -8
- package/dist/signal-XHfNsQNW.js +57 -0
- package/dist/skeleton-DPv9nFhL.js +32 -0
- package/dist/skeleton.js +3 -2
- package/dist/ssg.js +21 -0
- package/dist/ssr-DSGwPtEd.js +34 -0
- package/dist/ssr-stream.d.ts +1 -0
- package/dist/ssr-stream.js +87 -0
- package/dist/ssr.d.ts +1 -0
- package/dist/ssr.js +7 -0
- package/dist/style.d.ts +1 -0
- package/dist/style.js +0 -0
- package/dist/tab-C9swK-hm.js +185 -0
- package/dist/tab.js +3 -4
- package/dist/tabpane-B_M-Jokw.js +87 -0
- package/dist/tabpane.js +3 -2
- package/dist/test/e2e/button.spec.d.ts +1 -0
- package/dist/test/e2e/checkbox.spec.d.ts +1 -0
- package/dist/test/e2e/helpers.d.ts +13 -0
- package/dist/test/e2e/icon.spec.d.ts +1 -0
- package/dist/test/e2e/image.spec.d.ts +1 -0
- package/dist/test/e2e/input.spec.d.ts +1 -0
- package/dist/test/e2e/loading.spec.d.ts +1 -0
- package/dist/test/e2e/message.spec.d.ts +1 -0
- package/dist/test/e2e/modal.spec.d.ts +1 -0
- package/dist/test/e2e/popover.spec.d.ts +1 -0
- package/dist/test/e2e/progress.spec.d.ts +1 -0
- package/dist/test/e2e/radar.spec.d.ts +1 -0
- package/dist/test/e2e/select.spec.d.ts +1 -0
- package/dist/test/e2e/skeleton.spec.d.ts +1 -0
- package/dist/test/e2e/tab.spec.d.ts +1 -0
- package/dist/test/e2e/visual/colorpicker.spec.d.ts +1 -0
- package/dist/test/e2e/visual/components.spec.d.ts +1 -0
- package/dist/test/e2e/visual/player.spec.d.ts +1 -0
- package/dist/test/integration/composition.test.d.ts +23 -0
- package/dist/test/setup.d.ts +0 -0
- package/dist/test/ssr/builder.core.ssr.test.d.ts +1 -0
- package/dist/test/ssr/builder.factory.ssr.test.d.ts +1 -0
- package/dist/test/ssr/builder.mocks.test.d.ts +1 -0
- package/dist/test/ssr/components/button.test.d.ts +1 -0
- package/dist/test/ssr/css-vars.test.d.ts +1 -0
- package/dist/test/ssr/registry.test.d.ts +1 -0
- package/dist/test/ssr/router.ssg.test.d.ts +2 -0
- package/dist/test/ssr/snapshots/button.test.d.ts +1 -0
- package/dist/test/ssr/stream.test.d.ts +2 -0
- package/dist/test/ssr/theme.tokens.ssr.test.d.ts +1 -0
- package/dist/test/unit/builder.core.browser.test.d.ts +1 -0
- package/dist/test/unit/builder.escape.test.d.ts +1 -0
- package/dist/test/unit/builder.selectors.test.d.ts +1 -0
- package/dist/test/unit/button.contract.test.d.ts +1 -0
- package/dist/test/unit/card.contract.test.d.ts +1 -0
- package/dist/test/unit/checkbox.contract.test.d.ts +1 -0
- package/dist/test/unit/colorpicker.color.utils.test.d.ts +1 -0
- package/dist/test/unit/colorpicker.contract.test.d.ts +1 -0
- package/dist/test/unit/colorpicker.methods.test.d.ts +1 -0
- package/dist/test/unit/component.helpers.test.d.ts +1 -0
- package/dist/test/unit/dropdown-item.contract.test.d.ts +1 -0
- package/dist/test/unit/dropdown.contract.test.d.ts +1 -0
- package/dist/test/unit/form.contract.test.d.ts +1 -0
- package/dist/test/unit/helpers/component.d.ts +3 -0
- package/dist/test/unit/helpers/dom.d.ts +2 -0
- package/dist/test/unit/icon.contract.test.d.ts +1 -0
- package/dist/test/unit/image.contract.test.d.ts +1 -0
- package/dist/test/unit/input.contract.test.d.ts +1 -0
- package/dist/test/unit/link.contract.test.d.ts +1 -0
- package/dist/test/unit/loading.contract.test.d.ts +1 -0
- package/dist/test/unit/math.contract.test.d.ts +1 -0
- package/dist/test/unit/message.component.test.d.ts +1 -0
- package/dist/test/unit/message.container.test.d.ts +1 -0
- package/dist/test/unit/modal.contract.test.d.ts +1 -0
- package/dist/test/unit/option.contract.test.d.ts +1 -0
- package/dist/test/unit/package-exports.source.test.d.ts +1 -0
- package/dist/test/unit/player-controls.test.d.ts +1 -0
- package/dist/test/unit/player-core.test.d.ts +1 -0
- package/dist/test/unit/player-event-handlers.test.d.ts +1 -0
- package/dist/test/unit/player-events.test.d.ts +1 -0
- package/dist/test/unit/player-fullscreen.test.d.ts +1 -0
- package/dist/test/unit/player-interactions.test.d.ts +1 -0
- package/dist/test/unit/player-levels.test.d.ts +1 -0
- package/dist/test/unit/player-media.test.d.ts +1 -0
- package/dist/test/unit/player-playback.test.d.ts +1 -0
- package/dist/test/unit/player.contract.test.d.ts +1 -0
- package/dist/test/unit/popover-accessibility.test.d.ts +1 -0
- package/dist/test/unit/popover.contract.test.d.ts +2 -0
- package/dist/test/unit/progress.contract.test.d.ts +1 -0
- package/dist/test/unit/radar.contract.test.d.ts +1 -0
- package/dist/test/unit/route.contract.test.d.ts +1 -0
- package/dist/test/unit/router.contract.test.d.ts +2 -0
- package/dist/test/unit/scratch.contract.test.d.ts +1 -0
- package/dist/test/unit/select-accessibility.test.d.ts +1 -0
- package/dist/test/unit/select-option.contract.test.d.ts +1 -0
- package/dist/test/unit/select.contract.test.d.ts +1 -0
- package/dist/test/unit/skeleton.contract.test.d.ts +1 -0
- package/dist/test/unit/ssr.test.d.ts +1 -0
- package/dist/test/unit/tab.contract.test.d.ts +2 -0
- package/dist/test/unit/theme.semantic-tokens.test.d.ts +1 -0
- package/dist/test/unit/theme.skin-tokens.test.d.ts +1 -0
- package/dist/test/unit/utils.dom.test.d.ts +1 -0
- package/dist/test/unit/utils.error.test.d.ts +1 -0
- package/dist/test/unit/utils.i18n.test.d.ts +1 -0
- package/dist/test/unit/utils.image.test.d.ts +1 -0
- package/dist/test/unit/utils.math.test.d.ts +1 -0
- package/dist/test/unit/utils.router.test.d.ts +1 -0
- package/dist/test/unit/utils.signal.test.d.ts +1 -0
- package/dist/test/unit/utils.ssr-stream.test.d.ts +1 -0
- package/dist/test/unit/utils.style.test.d.ts +1 -0
- package/dist/test/unit/utils.theme.test.d.ts +1 -0
- package/dist/test/unit/utils.tween.test.d.ts +1 -0
- package/dist/tsconfig.json +8 -8
- package/dist/typings.d.ts +163 -114
- package/dist/utils/builder/core.d.ts +70 -0
- package/dist/utils/builder/env.d.ts +1 -0
- package/dist/utils/builder/escape.d.ts +2 -0
- package/dist/utils/builder/events.d.ts +55 -0
- package/dist/utils/builder/factory.d.ts +18 -0
- package/dist/utils/builder/index.d.ts +9 -0
- package/dist/utils/builder/mocks.d.ts +62 -0
- package/dist/utils/builder/selectors.d.ts +4 -0
- package/dist/utils/builder/signal.d.ts +87 -0
- package/dist/utils/color.d.ts +52 -0
- package/dist/utils/component.d.ts +16 -0
- package/dist/utils/dom.d.ts +39 -0
- package/dist/utils/error.d.ts +6 -0
- package/dist/utils/i18n/index.d.ts +53 -0
- package/dist/utils/i18n.js +88 -0
- package/dist/utils/image.d.ts +39 -0
- package/dist/utils/index.d.ts +8 -0
- package/dist/utils/math.d.ts +26 -0
- package/dist/utils/router/index.d.ts +128 -0
- package/dist/utils/router.js +197 -0
- package/dist/utils/ssg.d.ts +49 -0
- package/dist/utils/ssr-registry.d.ts +8 -0
- package/dist/utils/ssr-stream.d.ts +23 -0
- package/dist/utils/ssr.d.ts +17 -0
- package/dist/utils/style.d.ts +12 -0
- package/dist/utils/theme.d.ts +9 -0
- package/dist/utils/tween.d.ts +21 -0
- package/dist/utils/video.d.ts +40 -0
- package/dist/utils-D4pPF77E.js +689 -0
- package/dist/vite.config.d.ts +6 -0
- package/dist/vitest.config.d.ts +2 -0
- package/dist/vitest.config.ssr.d.ts +2 -0
- package/docs/COMPONENTS.md +326 -0
- package/docs/DESIGN.md +182 -0
- package/docs/style-tokens-public.md +880 -0
- package/package.json +136 -77
- package/typings.d.ts +163 -114
- package/dist/_commonjs-dynamic-modules-DLbDWi6a.js +0 -12
- package/dist/add-user-BN1JlY7e.js +0 -4
- package/dist/arrow-down-B_hCY3Wt.js +0 -662
- package/dist/book-nTEFXU2x.js +0 -4
- package/dist/check-circle-fill-B_pd8ZSs.js +0 -4
- package/dist/check-circle-szyAJiap.js +0 -4
- package/dist/close-CFnkhudp.js +0 -4
- package/dist/close-circle-CwmuN2C6.js +0 -4
- package/dist/close-circle-fill-jSqPPw9i.js +0 -4
- package/dist/colz-DJZvo_8B.js +0 -232
- package/dist/docx-CHkPTdGU.js +0 -3665
- package/dist/drop-4j4abxje.js +0 -36
- package/dist/eye-D_mEt17f.js +0 -4
- package/dist/eye-close-BVr3NJtg.js +0 -4
- package/dist/home-BUQ4USMk.js +0 -4
- package/dist/iconShadowless.js +0 -6
- package/dist/index-15M0olqa.js +0 -204
- package/dist/index-1v568_nq.js +0 -140
- package/dist/index-B897keW5.js +0 -279
- package/dist/index-BZR0HaP2.js +0 -40
- package/dist/index-B_GuEcTd.js +0 -9575
- package/dist/index-Bc2Bcl8D.js +0 -63701
- package/dist/index-C4Sv0T51.js +0 -495
- package/dist/index-C6RcMHoH.js +0 -187
- package/dist/index-C9z10IgG.js +0 -103
- package/dist/index-CFjEuvBW.js +0 -308
- package/dist/index-CGEx9VOA.js +0 -17106
- package/dist/index-CGYfjKUV.js +0 -72
- package/dist/index-CQTJoWhb.js +0 -19
- package/dist/index-CiWwvEMM.js +0 -511
- package/dist/index-CkM9ENTf.js +0 -496
- package/dist/index-CtVOgBDk.js +0 -659
- package/dist/index-D4qUro5V.js +0 -279
- package/dist/index-D4y9c1Dj.js +0 -310
- package/dist/index-DAxs7Dd2.js +0 -119
- package/dist/index-DC5EA657.js +0 -91
- package/dist/index-DJZmDHz-.js +0 -146
- package/dist/index-D_CA5VDZ.js +0 -158
- package/dist/index-WfFw4LJT.js +0 -490
- package/dist/index-mhFL9MJp.js +0 -320
- package/dist/info-circle-COnL5bTJ.js +0 -4
- package/dist/info-circle-fill-CFeVMdci.js +0 -4
- package/dist/inputShadowless.js +0 -6
- package/dist/jszip.min-Dhs3nUkD.js +0 -2346
- package/dist/katex-es-B5r5vt3m.js +0 -14628
- package/dist/loading-Dcc5RApI.js +0 -4
- package/dist/loading-scene-BMc2wqKm.js +0 -4
- package/dist/lock-Cr7BnmWN.js +0 -4
- package/dist/message-D36_Zo2l.js +0 -4
- package/dist/pdf-Cx0VWKFo.js +0 -118
- package/dist/power-off-lQRbiBak.js +0 -4
- package/dist/preview-CJbz9GjO.js +0 -4
- package/dist/preview.js +0 -7
- package/dist/selectShadowless.js +0 -564
- package/dist/setting-DemlgzVC.js +0 -4
- package/dist/shadowless.js +0 -8
- package/dist/sprite-CH2zLtZy.js +0 -141
- package/dist/style.css +0 -1
- package/dist/team-tl4NJXPC.js +0 -4
- package/dist/umd/index.umd.cjs +0 -60
- package/dist/umd/shadowless/shadowless.umd.cjs +0 -1
- package/dist/umd/shadowless/style.css +0 -1
- package/dist/umd/style.css +0 -1
- package/dist/unlock-CeU74z9n.js +0 -4
- package/dist/user-B-eVXwuk.js +0 -4
- package/dist/warning-circle-DDUgEDIv.js +0 -4
- package/dist/warning-circle-fill-lODUKz0i.js +0 -4
- package/readme.md +0 -195
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
# ranui Component API (Generated)
|
|
2
|
+
|
|
3
|
+
Auto-generated by `bin/generate-component-api.ts` (`npm run doc:api`).
|
|
4
|
+
Per-element reference of attributes, typed properties, events (with `detail`
|
|
5
|
+
shape), slots, and `::part()` names — extracted from source. For CSS variables
|
|
6
|
+
(theming tokens) see [style-tokens-public.md](./style-tokens-public.md); for
|
|
7
|
+
design rules see [DESIGN.md](./DESIGN.md).
|
|
8
|
+
|
|
9
|
+
Generated at: 2026-07-04T08:44:03.975Z
|
|
10
|
+
|
|
11
|
+
29 custom elements.
|
|
12
|
+
|
|
13
|
+
## `<r-button>`
|
|
14
|
+
|
|
15
|
+
Source: `components/button/index.ts`
|
|
16
|
+
|
|
17
|
+
- **Attributes**: `disabled: boolean | string`, `effect: string`, `icon: string`, `iconSize: string`, `sheet: string`, `type: string`
|
|
18
|
+
- **Properties**:
|
|
19
|
+
- `disabled: boolean | string`
|
|
20
|
+
- `effect: string`
|
|
21
|
+
- `icon: string`
|
|
22
|
+
- `iconSize: string`
|
|
23
|
+
- `sheet: string`
|
|
24
|
+
- `type: string` — Visual variant: `''` (default) | `'primary'` | `'warning'` | `'text'`. Drives the `:host([type=...])` styles.
|
|
25
|
+
- **Events**: —
|
|
26
|
+
- **Slots**: `default`
|
|
27
|
+
- **Parts**: `button`, `content`
|
|
28
|
+
|
|
29
|
+
## `<r-card>`
|
|
30
|
+
|
|
31
|
+
Source: `components/card/index.ts`
|
|
32
|
+
|
|
33
|
+
- **Attributes**: `description: string`, `sheet: string`, `title: string`
|
|
34
|
+
- **Properties**: `description: string`, `sheet: string`, `title: string`
|
|
35
|
+
- **Events**: —
|
|
36
|
+
- **Slots**: `default`, `extra (named)`, `footer (named)`
|
|
37
|
+
- **Parts**: `body`, `card`, `description`, `extra`, `footer`, `header`, `title`
|
|
38
|
+
|
|
39
|
+
## `<r-checkbox>`
|
|
40
|
+
|
|
41
|
+
Source: `components/checkbox/index.ts`
|
|
42
|
+
|
|
43
|
+
- **Attributes**: `checked: boolean`, `disabled: boolean`, `sheet: string`, `value: string`
|
|
44
|
+
- **Properties**: `checked: boolean`, `disabled: boolean`, `sheet: string`, `value: string`
|
|
45
|
+
- **Events**: `change` → detail `{ checked }`
|
|
46
|
+
- **Slots**: `default`
|
|
47
|
+
- **Parts**: `checkbox`, `inner`, `input`, `label`, `wrapper`
|
|
48
|
+
|
|
49
|
+
## `<r-colorpicker>`
|
|
50
|
+
|
|
51
|
+
Source: `components/colorpicker/index.ts`
|
|
52
|
+
|
|
53
|
+
- **Attributes**: `disabled`, `sheet: string`, `value: string`
|
|
54
|
+
- **Properties**: `sheet: string`, `value: string`
|
|
55
|
+
- **Events**: `change`
|
|
56
|
+
- **Slots**: —
|
|
57
|
+
- **Parts**: `block`, `swatch`
|
|
58
|
+
|
|
59
|
+
## `<r-content>`
|
|
60
|
+
|
|
61
|
+
Source: `components/popover/content/index.ts`
|
|
62
|
+
|
|
63
|
+
- **Attributes**: —
|
|
64
|
+
- **Properties**: —
|
|
65
|
+
- **Events**: `change`
|
|
66
|
+
- **Slots**: `default`
|
|
67
|
+
- **Parts**: —
|
|
68
|
+
|
|
69
|
+
## `<r-dropdown>`
|
|
70
|
+
|
|
71
|
+
Source: `components/dropdown/index.ts`
|
|
72
|
+
|
|
73
|
+
- **Attributes**: `arrow: string`, `sheet: string`, `transit: string`
|
|
74
|
+
- **Properties**: `arrow: string`, `sheet: string`, `show: string`, `transit: string`
|
|
75
|
+
- **Events**: —
|
|
76
|
+
- **Slots**: `default`
|
|
77
|
+
- **Parts**: `dropdown`
|
|
78
|
+
|
|
79
|
+
## `<r-dropdown-item>`
|
|
80
|
+
|
|
81
|
+
Source: `components/select/dropdown-item/index.ts`
|
|
82
|
+
|
|
83
|
+
- **Attributes**: `active: string`, `sheet: string`, `title: string`, `value: string`
|
|
84
|
+
- **Properties**: `active: string`, `sheet: string`, `title: string`, `value: string`
|
|
85
|
+
- **Events**: —
|
|
86
|
+
- **Slots**: `default`
|
|
87
|
+
- **Parts**: `content`, `item`
|
|
88
|
+
|
|
89
|
+
## `<r-form>`
|
|
90
|
+
|
|
91
|
+
Source: `components/form/index.ts`
|
|
92
|
+
|
|
93
|
+
- **Attributes**: `sheet: string`
|
|
94
|
+
- **Properties**: `sheet: string`, `value: string | null`
|
|
95
|
+
- **Events**: —
|
|
96
|
+
- **Slots**: `default`, `r-form_content (named)`
|
|
97
|
+
- **Parts**: —
|
|
98
|
+
|
|
99
|
+
## `<r-icon>`
|
|
100
|
+
|
|
101
|
+
Source: `components/icon/index.ts`
|
|
102
|
+
|
|
103
|
+
- **Attributes**: `aria-label`, `color: string`, `decorative: boolean`, `name: string`, `sheet: string`, `size: string`, `spin: boolean`
|
|
104
|
+
- **Properties**: `ariaLabel: string`, `color: string`, `decorative: boolean`, `name: string`, `sheet: string`, `size: string`, `spin: boolean`
|
|
105
|
+
- **Events**: `ranui-icon-registered` → detail `{ name }`
|
|
106
|
+
- **Slots**: —
|
|
107
|
+
- **Parts**: `ran-icon`
|
|
108
|
+
|
|
109
|
+
## `<r-img>`
|
|
110
|
+
|
|
111
|
+
Source: `components/image/index.ts`
|
|
112
|
+
|
|
113
|
+
- **Attributes**: —
|
|
114
|
+
- **Properties**:
|
|
115
|
+
- `alt` — Alternative text forwarded to the inner `<img>`. Defaults to `''` (empty),
|
|
116
|
+
- `fallback`
|
|
117
|
+
- `sheet`
|
|
118
|
+
- **Events**: —
|
|
119
|
+
- **Slots**: —
|
|
120
|
+
- **Parts**: —
|
|
121
|
+
|
|
122
|
+
## `<r-input>`
|
|
123
|
+
|
|
124
|
+
Source: `components/input/index.ts`
|
|
125
|
+
|
|
126
|
+
- **Attributes**: `allowclear`, `count`, `disabled: boolean`, `icon: string`, `label: string`, `maxlength`, `maxrows`, `message: string`, `minrows`, `name: string`, `onPressEnter`, `placeholder: string`, `prefix: string`, `sheet: string`, `showcount`, `status: string`, `suffix: string`, `type: string`, `value: string`, `variant`
|
|
127
|
+
- **Properties**:
|
|
128
|
+
- `disabled: boolean` — input 上 disabled 属性
|
|
129
|
+
- `icon: string` — 一个 icon
|
|
130
|
+
- `label: string` — 类似于 Metiral Design 的输入体验。
|
|
131
|
+
- `max: string` — 当 input 类型为 number 类型时,可以获取 max 属性
|
|
132
|
+
- `message: string` — 下方的提示/校验文案
|
|
133
|
+
- `min: string` — 当 input 类型为 number 类型时,可以获取 min 属性
|
|
134
|
+
- `name: string` — 与 form 组件联动时,收集的属性名
|
|
135
|
+
- `placeholder: string` — input 的占位字符
|
|
136
|
+
- `prefix: string` — 前面的 icon
|
|
137
|
+
- `required: boolean` — input 是否为必选
|
|
138
|
+
- `sheet: string`
|
|
139
|
+
- `status: string` — input 框的状态
|
|
140
|
+
- `step: string` — 当 input 类型为 number 类型时,可以获取 step 属性
|
|
141
|
+
- `suffix: string` — 后面的 icon
|
|
142
|
+
- `type: string` — input 的类型
|
|
143
|
+
- `value: string` — input 的值
|
|
144
|
+
- **Events**: `change` → detail `{ value }` · `input` → detail `{ value }`
|
|
145
|
+
- **Slots**: —
|
|
146
|
+
- **Parts**: `content`, `input`, `label`, `message`
|
|
147
|
+
|
|
148
|
+
## `<r-link>`
|
|
149
|
+
|
|
150
|
+
Source: `components/link/index.ts`
|
|
151
|
+
|
|
152
|
+
- **Attributes**: `href: string`, `replace: boolean`, `sheet: string`
|
|
153
|
+
- **Properties**: `href: string`, `replace: boolean`, `sheet: string`
|
|
154
|
+
- **Events**: `ran-navigate` → detail `{ path, replace }`
|
|
155
|
+
- **Slots**: —
|
|
156
|
+
- **Parts**: —
|
|
157
|
+
|
|
158
|
+
## `<r-loading>`
|
|
159
|
+
|
|
160
|
+
Source: `components/loading/index.ts`
|
|
161
|
+
|
|
162
|
+
- **Attributes**: `name: 'double-bounce' | 'rotate' | 'stretch' | 'cube' | 'dot' | 'triple-bounce' | 'scale-out' | 'circle' | 'circle-line' | 'square' | 'pulse' | 'solar' | 'cube-fold' | 'circle-fold' | 'cube-grid' | 'circle-turn' | 'circle-rotate' | 'circle-spin' | 'dot-bar' | 'dot-circle' | 'line' | 'dot-pulse' | 'line-scale' | 'text' | 'cube-dim' | 'dot-line' | 'arc' | 'drop' | 'pacman'`, `sheet: string`
|
|
163
|
+
- **Properties**: `name: 'double-bounce' | 'rotate' | 'stretch' | 'cube' | 'dot' | 'triple-bounce' | 'scale-out' | 'circle' | 'circle-line' | 'square' | 'pulse' | 'solar' | 'cube-fold' | 'circle-fold' | 'cube-grid' | 'circle-turn' | 'circle-rotate' | 'circle-spin' | 'dot-bar' | 'dot-circle' | 'line' | 'dot-pulse' | 'line-scale' | 'text' | 'cube-dim' | 'dot-line' | 'arc' | 'drop' | 'pacman'`, `sheet: string`
|
|
164
|
+
- **Events**: —
|
|
165
|
+
- **Slots**: —
|
|
166
|
+
- **Parts**: `sun`
|
|
167
|
+
|
|
168
|
+
## `<r-math>`
|
|
169
|
+
|
|
170
|
+
Source: `components/math/index.ts`
|
|
171
|
+
|
|
172
|
+
- **Attributes**: `latex: string`, `sheet: string`
|
|
173
|
+
- **Properties**: `latex: string`, `sheet: string`
|
|
174
|
+
- **Events**: —
|
|
175
|
+
- **Slots**: —
|
|
176
|
+
- **Parts**: —
|
|
177
|
+
|
|
178
|
+
## `<r-message>`
|
|
179
|
+
|
|
180
|
+
Source: `components/message/index.ts`
|
|
181
|
+
|
|
182
|
+
- **Attributes**: —
|
|
183
|
+
- **Properties**: `content: string | null`, `sheet: string`, `type: string | null`
|
|
184
|
+
- **Events**: —
|
|
185
|
+
- **Slots**: —
|
|
186
|
+
- **Parts**: —
|
|
187
|
+
|
|
188
|
+
## `<r-modal>`
|
|
189
|
+
|
|
190
|
+
Source: `components/modal/index.ts`
|
|
191
|
+
|
|
192
|
+
- **Attributes**: `autoFocus: boolean`, `closable: boolean`, `closeOnEsc: boolean`, `lockScroll: boolean`, `maskClosable: boolean`, `open: boolean`, `sheet: string`, `title: string`
|
|
193
|
+
- **Properties**: `autoFocus: boolean`, `closable: boolean`, `closeOnEsc: boolean`, `lockScroll: boolean`, `maskClosable: boolean`, `open: boolean`, `sheet: string`, `title: string`
|
|
194
|
+
- **Events**: `afterclose` → detail `{ trigger }` · `afteropen` · `beforeclose` → detail `{ trigger }` · `beforeopen` · `close` → detail `{ trigger }` · `open`
|
|
195
|
+
- **Slots**: `default`, `footer (named)`
|
|
196
|
+
- **Parts**: `body`, `close`, `dialog`, `footer`, `header`, `mask`, `root`, `title`
|
|
197
|
+
|
|
198
|
+
## `<r-option>`
|
|
199
|
+
|
|
200
|
+
Source: `components/select/option/index.ts`
|
|
201
|
+
|
|
202
|
+
- **Attributes**: —
|
|
203
|
+
- **Properties**: `disabled: boolean | string | undefined | null`, `sheet`, `value`
|
|
204
|
+
- **Events**: —
|
|
205
|
+
- **Slots**: `default`
|
|
206
|
+
- **Parts**: —
|
|
207
|
+
|
|
208
|
+
## `<r-player>`
|
|
209
|
+
|
|
210
|
+
Source: `components/player/index.ts`
|
|
211
|
+
|
|
212
|
+
- **Attributes**: `currenttime`, `currentTime: string`, `debug: string`, `playbackrate`, `playbackRate: string`, `sheet: string`, `src: string`, `volume: string`
|
|
213
|
+
- **Properties**: `currentTime: string`, `debug: string`, `playbackRate: string`, `sheet: string`, `src: string`, `volume: string`
|
|
214
|
+
- **Events**: `change` → detail `{ currentTime, data, duration, tag, type }`
|
|
215
|
+
- **Slots**: —
|
|
216
|
+
- **Parts**: —
|
|
217
|
+
|
|
218
|
+
## `<r-popover>`
|
|
219
|
+
|
|
220
|
+
Source: `components/popover/index.ts`
|
|
221
|
+
|
|
222
|
+
- **Attributes**: `arrow: string`, `placement: string`, `sheet: string`, `trigger: string`
|
|
223
|
+
- **Properties**: `arrow: string`, `getPopupContainerId: string`, `placement: string`, `sheet: string`, `trigger: string`
|
|
224
|
+
- **Events**: —
|
|
225
|
+
- **Slots**: `default`
|
|
226
|
+
- **Parts**: —
|
|
227
|
+
|
|
228
|
+
## `<r-progress>`
|
|
229
|
+
|
|
230
|
+
Source: `components/progress/index.ts`
|
|
231
|
+
|
|
232
|
+
- **Attributes**: `drag`, `primary`
|
|
233
|
+
- **Properties**: `dot: string`, `percent: string`, `sheet: string`, `total: string`, `type: string`
|
|
234
|
+
- **Events**: `change` → detail `{ percent, total, value }`
|
|
235
|
+
- **Slots**: —
|
|
236
|
+
- **Parts**: `dot`, `fill`, `track`
|
|
237
|
+
|
|
238
|
+
## `<r-radar>`
|
|
239
|
+
|
|
240
|
+
Source: `components/radar/index.ts`
|
|
241
|
+
|
|
242
|
+
- **Attributes**: —
|
|
243
|
+
- **Properties**: `abilitys`, `colorLine`, `colorPolygon`, `fillColor`, `fontColor`, `sheet`, `strokeColor`
|
|
244
|
+
- **Events**: —
|
|
245
|
+
- **Slots**: —
|
|
246
|
+
- **Parts**: —
|
|
247
|
+
|
|
248
|
+
## `<r-route>`
|
|
249
|
+
|
|
250
|
+
Source: `components/route/index.ts`
|
|
251
|
+
|
|
252
|
+
- **Attributes**: `exact: boolean`, `path: string`, `sheet: string`
|
|
253
|
+
- **Properties**: `exact: boolean`, `params: Record<string, string>`, `path: string`, `sheet: string`
|
|
254
|
+
- **Events**: `routematch` → detail `{ params, path }`
|
|
255
|
+
- **Slots**: `default`
|
|
256
|
+
- **Parts**: —
|
|
257
|
+
|
|
258
|
+
## `<r-router>`
|
|
259
|
+
|
|
260
|
+
Source: `components/router/index.ts`
|
|
261
|
+
|
|
262
|
+
- **Attributes**: `base: string`, `mode: 'history' | 'hash'`, `sheet: string`
|
|
263
|
+
- **Properties**: `base: string`, `mode: 'history' | 'hash'`, `sheet: string`
|
|
264
|
+
- **Events**: `routechange` → detail `{ path }`
|
|
265
|
+
- **Slots**: `default`
|
|
266
|
+
- **Parts**: —
|
|
267
|
+
|
|
268
|
+
## `<r-scratch>`
|
|
269
|
+
|
|
270
|
+
Source: `components/scratch/index.ts`
|
|
271
|
+
|
|
272
|
+
- **Attributes**: `disabled`, `effect`, `icon`, `iconSize`, `sheet`
|
|
273
|
+
- **Properties**: —
|
|
274
|
+
- **Events**: —
|
|
275
|
+
- **Slots**: —
|
|
276
|
+
- **Parts**: —
|
|
277
|
+
|
|
278
|
+
## `<r-section>`
|
|
279
|
+
|
|
280
|
+
Source: `components/section/index.ts`
|
|
281
|
+
|
|
282
|
+
- **Attributes**: `heading: string`, `sheet: string`, `subtitle: string`
|
|
283
|
+
- **Properties**: `heading: string`, `sheet: string`, `subtitle: string`
|
|
284
|
+
- **Events**: —
|
|
285
|
+
- **Slots**: `default`
|
|
286
|
+
- **Parts**: `body`, `header`, `heading`, `subtitle`
|
|
287
|
+
|
|
288
|
+
## `<r-select>`
|
|
289
|
+
|
|
290
|
+
Source: `components/select/index.ts`
|
|
291
|
+
|
|
292
|
+
- **Attributes**: `clear`, `defaultValue: string`, `disabled: boolean`, `dropdownclass: string`, `getPopupContainerId: string`, `placement: string`, `sheet: string`, `showSearch: string`, `trigger: string`, `type: string`, `value: string`
|
|
293
|
+
- **Properties**: `defaultValue: string`, `disabled: boolean`, `dropdownclass: string`, `getPopupContainerId: string`, `placement: string`, `sheet: string`, `showSearch: string`, `trigger: string`, `type: string`, `value: string`
|
|
294
|
+
- **Events**: `change` → detail `{ label, value }` · `search` → detail `{ value }`
|
|
295
|
+
- **Slots**: `default`
|
|
296
|
+
- **Parts**: `icon`, `search`, `select`, `selection`, `selection-item`
|
|
297
|
+
|
|
298
|
+
## `<r-skeleton>`
|
|
299
|
+
|
|
300
|
+
Source: `components/skeleton/index.ts`
|
|
301
|
+
|
|
302
|
+
- **Attributes**: `disabled`, `sheet: string`
|
|
303
|
+
- **Properties**: `sheet: string`
|
|
304
|
+
- **Events**: —
|
|
305
|
+
- **Slots**: —
|
|
306
|
+
- **Parts**: —
|
|
307
|
+
|
|
308
|
+
## `<r-tab>`
|
|
309
|
+
|
|
310
|
+
Source: `components/tabpane/index.ts`
|
|
311
|
+
|
|
312
|
+
- **Attributes**: —
|
|
313
|
+
- **Properties**: `disabled`, `effect`, `icon`, `iconSize`, `key`, `label`, `sheet`
|
|
314
|
+
- **Events**: —
|
|
315
|
+
- **Slots**: `default`
|
|
316
|
+
- **Parts**: `content`
|
|
317
|
+
|
|
318
|
+
## `<r-tabs>`
|
|
319
|
+
|
|
320
|
+
Source: `components/tab/index.ts`
|
|
321
|
+
|
|
322
|
+
- **Attributes**: `active: string | null`, `align: string`, `effect: string | null`, `forceRender`, `sheet: string`, `type: string`
|
|
323
|
+
- **Properties**: `active: string | null`, `align: string`, `effect: string | null`, `sheet: string`, `type: string`
|
|
324
|
+
- **Events**: `change` → detail `{ active }`
|
|
325
|
+
- **Slots**: `default`
|
|
326
|
+
- **Parts**: `content`, `content-wrap`, `header`, `indicator`, `nav`, `tabs`
|
package/docs/DESIGN.md
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# ranui DESIGN.md
|
|
2
|
+
|
|
3
|
+
> An executable design specification — written for humans **and** AI agents.
|
|
4
|
+
> When generating or editing ranui UI, follow these rules so output is consistent
|
|
5
|
+
> instead of drifting in style. Based on the [Geist design system](https://vercel.com/design)
|
|
6
|
+
> ([design.md](https://vercel.com/design.md) / [design.dark.md](https://vercel.com/design.dark.md)).
|
|
7
|
+
|
|
8
|
+
## How to use this file
|
|
9
|
+
|
|
10
|
+
- Prefer **semantic tokens** (`--ran-color-*`, `--ran-space-*`, …) over raw scales or hex.
|
|
11
|
+
- Decide by **role/state**, not by eyeballing a value. The value is chosen for you.
|
|
12
|
+
- When a choice is unresolved, mark it explicitly — don't bury a guess in code.
|
|
13
|
+
- Design **all reachable states** (default, hover, active, focus, disabled, loading, empty, error), not just the happy path.
|
|
14
|
+
- **Verify the rendered result**, in light and dark, at narrow and wide widths — code review alone is not enough.
|
|
15
|
+
|
|
16
|
+
Conflict resolution order: **user goals → verified evidence → this file → repo guidance (`CLAUDE.md`) → shipped patterns → general heuristics.**
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 1. Color — a state ladder, not a palette
|
|
21
|
+
|
|
22
|
+
Each hue is a **10-step scale** (`100`–`1000`). Every step has **one fixed job**, so interaction states are decided up front:
|
|
23
|
+
|
|
24
|
+
| Step | Role |
|
|
25
|
+
| ---- | --------------------------- |
|
|
26
|
+
| 100 | Default background |
|
|
27
|
+
| 200 | Hover background |
|
|
28
|
+
| 300 | Active (pressed) background |
|
|
29
|
+
| 400 | Default border |
|
|
30
|
+
| 500 | Hover border |
|
|
31
|
+
| 600 | Active border |
|
|
32
|
+
| 700 | Solid fill (button/badge) |
|
|
33
|
+
| 800 | Solid fill — hover |
|
|
34
|
+
| 900 | Secondary text & icons |
|
|
35
|
+
| 1000 | Primary text & icons |
|
|
36
|
+
|
|
37
|
+
Scales: `--ran-gray-100..1000`, `--ran-gray-alpha-100..1000` (translucent, layers over any surface), `--ran-blue-*`, `--ran-red-*`, `--ran-amber-*`, `--ran-green-*`, plus `--ran-background-100/200`.
|
|
38
|
+
|
|
39
|
+
**Use the semantic layer, not the scale, in components:**
|
|
40
|
+
|
|
41
|
+
| Token | Maps to | Use for |
|
|
42
|
+
| -------------------------------------------- | ------------------------------- | ------------------- |
|
|
43
|
+
| `--ran-color-bg` | background-100 | Page background |
|
|
44
|
+
| `--ran-color-bg-subtle` | background-200 | Subtle page zones |
|
|
45
|
+
| `--ran-color-bg-elevated` | bg-100 / gray-100 (dark) | Cards, surfaces |
|
|
46
|
+
| `--ran-color-bg-muted` | gray-100 | Inset / muted fills |
|
|
47
|
+
| `--ran-color-bg-hover` | gray-200 | Hover background |
|
|
48
|
+
| `--ran-color-bg-active` | gray-300 | Active background |
|
|
49
|
+
| `--ran-color-text` | gray-1000 | Primary text |
|
|
50
|
+
| `--ran-color-text-secondary` | gray-900 | Secondary text |
|
|
51
|
+
| `--ran-color-text-disabled` | gray-700 | Disabled text |
|
|
52
|
+
| `--ran-color-border` | gray-400 | Default border |
|
|
53
|
+
| `--ran-color-border-hover` | gray-500 | Hover border |
|
|
54
|
+
| `--ran-color-border-active` | gray-600 | Active border |
|
|
55
|
+
| `--ran-color-primary` / `-hover` / `-active` | blue-700 / 800 / 900 | Primary action |
|
|
56
|
+
| `--ran-color-success` / `warning` / `danger` | green-700 / amber-700 / red-700 | Status |
|
|
57
|
+
| `--ran-color-link` | blue-700 | Links |
|
|
58
|
+
|
|
59
|
+
**Accent meaning:** blue = primary & links · green = success · amber = warning · red = danger/error.
|
|
60
|
+
|
|
61
|
+
**Light & dark:** same token name, different value. `gray-1000` is `#171717` in light and `#ededed` in dark. Components reference the _semantic name_; dark mode only redefines the base scale (one mixin), and everything re-resolves.
|
|
62
|
+
|
|
63
|
+
**Rules**
|
|
64
|
+
|
|
65
|
+
- Never hard-code a hex/rgb in a component for a value that should follow the theme.
|
|
66
|
+
- A component token's fallback must point at a **token that flips** (`var(--ran-gray-alpha-100, …)`, `var(--ran-blue-100, …)`, `var(--ran-color-text, …)`), never a light-only literal — otherwise it breaks in dark mode.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## 2. Spacing — a limited, rhythmic scale
|
|
71
|
+
|
|
72
|
+
A **4px base unit** with **nine values** only: `--ran-space-1..24` → `4, 8, 12, 16, 24, 32, 40, 64, 96`px.
|
|
73
|
+
|
|
74
|
+
**Rhythm**
|
|
75
|
+
|
|
76
|
+
- `8px` between elements inside a group.
|
|
77
|
+
- `16px` between groups.
|
|
78
|
+
- `32–40px` between sections.
|
|
79
|
+
|
|
80
|
+
**Rule:** pick a value from the scale. Don't invent `20px`/`28px` — a limited set is what creates the page's rhythm.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## 3. Typography — choose a role, not a size
|
|
85
|
+
|
|
86
|
+
Fonts: `--ran-font-family` (Geist Sans, UI & prose), `--ran-font-mono` (Geist Mono, code, data, and eyebrow/labels). Base: `--ran-font-size: 14px`, `--ran-line-height: 1.5715`.
|
|
87
|
+
|
|
88
|
+
Decide by **role**; the role fixes font, size, weight, line-height:
|
|
89
|
+
|
|
90
|
+
| Role | Use | Weight | Notes |
|
|
91
|
+
| ------- | ---------------------- | ------- | ----------------------------------------------------- |
|
|
92
|
+
| heading | Titles | 600 | Tight letter-spacing (≈ -0.03em); 32 / 24 / 20 / 16px |
|
|
93
|
+
| label | Single-line, scannable | 500 | 14 / 13 / 12px; no wrapping |
|
|
94
|
+
| copy | Multi-line body | 400 | line-height ~1.55; 16 / 14px |
|
|
95
|
+
| button | Button text | 500 | 14px; `line-height: 1` for crisp vertical centering |
|
|
96
|
+
| mono | Code, data, eyebrows | 400/500 | `--ran-font-mono` |
|
|
97
|
+
|
|
98
|
+
**Rule:** ask "what role is this text?" (heading / label / copy / button) — the style follows. Don't pick raw px per instance.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## 4. Radius & elevation
|
|
103
|
+
|
|
104
|
+
Radius: `--ran-radius-sm` 6 · `--ran-radius-md` 12 · `--ran-radius-lg` 16 · `--ran-radius-full` 9999.
|
|
105
|
+
|
|
106
|
+
- Controls (button, input, select) → `sm`. Cards / dialogs → `md`. Large surfaces → `lg`. Pills / avatars → `full`.
|
|
107
|
+
|
|
108
|
+
**Elevation is a role, not decoration.** Pick the shadow by _what the element is_, and make sure the tier is actually perceptible — a shadow you can't see fails its job.
|
|
109
|
+
|
|
110
|
+
| Tier | Token | Use for |
|
|
111
|
+
| ------- | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
112
|
+
| Raised | `--ran-shadow-elevated` | In-flow surfaces that also have a border — `r-card`, `r-section`. Subtle on purpose. |
|
|
113
|
+
| Overlay | `--ran-shadow-menu` | Transient layers floating **over** content — `r-dropdown`, `r-select` menu, `r-popover`, tooltips, `r-message`/toast. Must clearly lift off the page. |
|
|
114
|
+
| Modal | `--ran-shadow-modal` | Blocking dialogs — `r-modal`. Strongest. |
|
|
115
|
+
|
|
116
|
+
A floating overlay must **never** fall back to `--ran-shadow-elevated` (the card tier) — it will look flat. Borderless overlays (dropdown, toast) rely on the shadow alone for separation, so the overlay tiers carry real weight.
|
|
117
|
+
|
|
118
|
+
**Stacking follows the same roles (z-index ladder).** Floating overlays portal to `<body>`, so they need an explicit stacking tier. The z-index must sit on the element that is **positioned and portaled** (the host) — a z-index on an inner shadow node is trapped in the host's stacking context and does nothing against page content.
|
|
119
|
+
|
|
120
|
+
| Tier | Token | Default | Use for |
|
|
121
|
+
| -------- | ------------------ | ------- | --------------------------------------------------------------------------------------------------- |
|
|
122
|
+
| Modal | `--ran-z-modal` | `1000` | Blocking dialogs (`r-modal`) and their mask. |
|
|
123
|
+
| Dropdown | `--ran-z-dropdown` | `1100` | Dropdown / select menu / popover. **Above** modal, so a select opened inside a modal stays visible. |
|
|
124
|
+
| Message | `--ran-z-message` | `1200` | Toasts / notifications. Always on top. |
|
|
125
|
+
|
|
126
|
+
Override a tier globally (set `--ran-z-dropdown` on `:root`) or per component (`--ran-dropdown-host-z-index`, `--ran-modal-root-z-index`, `--ran-message-z-index`) — never reach for `!important`. An overlay open while the page scrolls must re-run its placement on `scroll`/`resize` so it tracks its trigger (e.g. inside a sticky header).
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## 5. Motion — prefer none
|
|
131
|
+
|
|
132
|
+
Durations: `--ran-motion-duration-fast` `0.15s`, `--ran-motion-duration-base` `0.2s`.
|
|
133
|
+
|
|
134
|
+
| Duration | Use |
|
|
135
|
+
| -------- | -------------------------------------------------- |
|
|
136
|
+
| 0ms | A change that is already obvious — apply instantly |
|
|
137
|
+
| ~150ms | Hover / active state transitions |
|
|
138
|
+
| ~200ms | Popovers & menus appearing |
|
|
139
|
+
| ~300ms | Modals & dialogs |
|
|
140
|
+
|
|
141
|
+
**Principle:** the bigger the change, the more time it earns. Otherwise: don't animate. Keep motion quick, light, and restrained. Respect `prefers-reduced-motion`.
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## 6. Content — copy is part of the system
|
|
146
|
+
|
|
147
|
+
- **Buttons:** an action **plus** an object. ✅ "Deploy project", "Delete member". ❌ "Deploy", "OK", "Delete".
|
|
148
|
+
- **Errors:** say **what happened**, then **how to fix it**. ✅ "Build failed: the bundle exceeds the size limit. Reduce it or raise the limit." ❌ "Operation failed, please try again."
|
|
149
|
+
- **Confirmations / toasts:** state the **change**, not "success". ✅ "Project deleted". ❌ "Successfully deleted" (the toast appearing already implies success).
|
|
150
|
+
- Be specific; every sentence should remove guesswork, not add it.
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## 7. Accessibility — the system serves everyone
|
|
155
|
+
|
|
156
|
+
- Maintain sufficient text-to-background contrast (**WCAG AA**).
|
|
157
|
+
- **Never signal state with color alone** — pair it with an icon or text (e.g. ✓ / ✕ labels, not just green/red).
|
|
158
|
+
- Every interactive element has a **visible focus ring** — `--ran-focus-ring`, or `outline: 2px solid var(--ran-color-primary); outline-offset: 2px`. Never remove it for "cleanliness".
|
|
159
|
+
- **Full keyboard navigation** — nothing is mouse-only.
|
|
160
|
+
- Respect `prefers-reduced-motion` and `prefers-color-scheme`.
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## 8. Components — how to apply the system
|
|
165
|
+
|
|
166
|
+
- Use the semantic ranui components (`r-button`, `r-input`, `r-select`, `r-card`, `r-modal`, …) rather than re-building primitives.
|
|
167
|
+
- Theme through **CSS variables**, **`::part()`**, or the **`sheet`** attribute (escape hatch). CSS variables cross Shadow DOM; selectors do not.
|
|
168
|
+
- Component tokens default to semantic tokens: `var(--ran-btn-content-background-color, var(--ran-color-primary, #006bff))`.
|
|
169
|
+
- Map states to the color ladder: default → `bg`/`text`; hover → `bg-hover` / `border-hover` / `primary-hover`; active → `bg-active` / `primary-active`; disabled → `text-disabled` + reduced opacity; focus → focus ring.
|
|
170
|
+
- See [THEME_STYLE_SYSTEM_DESIGN.md](./THEME_STYLE_SYSTEM_DESIGN.md) for the token architecture and [style-tokens-public.md](./style-tokens-public.md) for the generated per-component token list.
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## Verification checklist (before shipping UI)
|
|
175
|
+
|
|
176
|
+
- [ ] Primary task and primary action are unmistakable.
|
|
177
|
+
- [ ] Works in **light and dark**, at **narrow and wide** widths.
|
|
178
|
+
- [ ] All changed **states** exercised (hover, active, focus, disabled, loading, empty, error).
|
|
179
|
+
- [ ] **Keyboard / focus** behavior verified; visible focus everywhere.
|
|
180
|
+
- [ ] Edge cases: long text, large numbers, both locales (en / zh).
|
|
181
|
+
- [ ] Spacing comes from the scale; type uses a role; color uses semantic tokens.
|
|
182
|
+
- [ ] Copy follows §6; nothing signals state by color alone (§7).
|