@codenhub/styles 0.6.0 → 0.7.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/NOTICE +18 -16
- package/README.es.md +61 -0
- package/README.md +21 -16
- package/README.pt-BR.md +61 -0
- package/dist/aesthetics/chunky-tile.css +1 -1
- package/dist/aesthetics/cyber.css +1 -1
- package/dist/aesthetics/glass.css +1 -1
- package/dist/aesthetics/index.css +2 -2
- package/dist/aesthetics/neobrutalism.css +1 -1
- package/dist/aesthetics/pixel.css +1 -1
- package/dist/aesthetics/sketch.css +1 -1
- package/dist/components.css +2 -2
- package/dist/index.css +2 -2
- package/dist/native.css +2 -2
- package/dist/palette.css +1 -1
- package/dist/theme.css +2 -2
- package/dist/tw/aesthetics/chunky-tile.css +81 -23
- package/dist/tw/aesthetics/cyber.css +86 -29
- package/dist/tw/aesthetics/glass.css +177 -50
- package/dist/tw/aesthetics/neobrutalism.css +98 -22
- package/dist/tw/aesthetics/pixel.css +93 -8
- package/dist/tw/aesthetics/sketch.css +87 -22
- package/dist/tw/box.css +21 -2
- package/dist/tw/components/feedback.css +2 -2
- package/dist/tw/components/form.css +58 -19
- package/dist/tw/components/index.css +3 -4
- package/dist/tw/components/surface.css +15 -6
- package/dist/tw/index.css +1 -1
- package/dist/tw/intent.css +6 -5
- package/dist/tw/native.css +8 -8
- package/dist/tw/palette.css +6 -6
- package/dist/tw/reset.css +15 -15
- package/dist/tw/theme.css +29 -17
- package/dist/tw/utilities/content.css +43 -1
- package/dist/tw/utilities/layout.css +26 -12
- package/docs/accessibility.md +89 -60
- package/docs/changelog/0.1.1.md +1 -0
- package/docs/changelog/0.2.0.md +1 -0
- package/docs/changelog/0.3.0.md +1 -0
- package/docs/changelog/0.4.0.md +1 -0
- package/docs/changelog/0.5.0.md +8 -3
- package/docs/changelog/0.6.0.md +2 -1
- package/docs/changelog/0.7.0.md +50 -0
- package/docs/changelog/index.md +1 -0
- package/docs/concepts.md +188 -46
- package/docs/es/accessibility.md +150 -0
- package/docs/es/concepts.md +212 -0
- package/docs/es/index.md +104 -0
- package/docs/es/integrating/astro.md +35 -0
- package/docs/es/integrating/index.md +47 -0
- package/docs/es/integrating/nextjs.md +67 -0
- package/docs/es/integrating/svelte.md +45 -0
- package/docs/es/integrating/tailwind.md +78 -0
- package/docs/es/integrating/vue.md +31 -0
- package/docs/es/integrating/without-a-bundler.md +115 -0
- package/docs/es/setup.md +180 -0
- package/docs/es/usage/aesthetics.md +276 -0
- package/docs/es/usage/buttons.md +131 -0
- package/docs/es/usage/composing.md +164 -0
- package/docs/es/usage/content-and-layout.md +215 -0
- package/docs/es/usage/customizing.md +298 -0
- package/docs/es/usage/feedback.md +153 -0
- package/docs/es/usage/forms.md +231 -0
- package/docs/es/usage/index.md +29 -0
- package/docs/es/usage/solo.md +84 -0
- package/docs/es/usage/theming.md +296 -0
- package/docs/es/usage/tooltips.md +127 -0
- package/docs/index.md +85 -26
- package/docs/integrating/astro.md +3 -4
- package/docs/integrating/index.md +18 -13
- package/docs/integrating/nextjs.md +3 -4
- package/docs/integrating/svelte.md +5 -4
- package/docs/integrating/tailwind.md +16 -3
- package/docs/integrating/vue.md +3 -4
- package/docs/integrating/without-a-bundler.md +114 -0
- package/docs/pt-BR/accessibility.md +150 -0
- package/docs/pt-BR/concepts.md +212 -0
- package/docs/pt-BR/index.md +104 -0
- package/docs/pt-BR/integrating/astro.md +35 -0
- package/docs/pt-BR/integrating/index.md +47 -0
- package/docs/pt-BR/integrating/nextjs.md +67 -0
- package/docs/pt-BR/integrating/svelte.md +45 -0
- package/docs/pt-BR/integrating/tailwind.md +78 -0
- package/docs/pt-BR/integrating/vue.md +31 -0
- package/docs/pt-BR/integrating/without-a-bundler.md +115 -0
- package/docs/pt-BR/setup.md +180 -0
- package/docs/pt-BR/usage/aesthetics.md +276 -0
- package/docs/pt-BR/usage/buttons.md +131 -0
- package/docs/pt-BR/usage/composing.md +164 -0
- package/docs/pt-BR/usage/content-and-layout.md +215 -0
- package/docs/pt-BR/usage/customizing.md +298 -0
- package/docs/pt-BR/usage/feedback.md +153 -0
- package/docs/pt-BR/usage/forms.md +231 -0
- package/docs/pt-BR/usage/index.md +29 -0
- package/docs/pt-BR/usage/solo.md +84 -0
- package/docs/pt-BR/usage/theming.md +296 -0
- package/docs/pt-BR/usage/tooltips.md +127 -0
- package/docs/setup.md +134 -91
- package/docs/usage/aesthetics.md +76 -66
- package/docs/usage/buttons.md +108 -40
- package/docs/usage/composing.md +105 -92
- package/docs/usage/content-and-layout.md +157 -126
- package/docs/usage/customizing.md +107 -37
- package/docs/usage/feedback.md +134 -71
- package/docs/usage/forms.md +176 -107
- package/docs/usage/index.md +18 -14
- package/docs/usage/solo.md +83 -0
- package/docs/usage/theming.md +260 -118
- package/docs/usage/tooltips.md +90 -49
- package/llms-full.txt +2358 -1313
- package/llms.txt +24 -22
- package/package.json +25 -32
- package/dist/tw/components/loader.css +0 -116
|
@@ -2,40 +2,45 @@
|
|
|
2
2
|
title: Overview
|
|
3
3
|
description: How the stylesheet loads in a framework build, and which guide to follow.
|
|
4
4
|
group: Integrating
|
|
5
|
-
order:
|
|
5
|
+
order: 2
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Integrating
|
|
9
9
|
|
|
10
|
-
This package has no JavaScript and no framework bindings
|
|
10
|
+
This section is a detour from the main reading path, for projects whose framework decides where global CSS may go. The package has no JavaScript and no framework bindings (see [Introduction](../index.md#what-it-does-not-do)), so integrating it is only about two things: where your framework lets you load a global stylesheet, and whether the project runs Tailwind CSS v4. Follow the one guide that matches your stack, then return to [Building a screen](../concepts.md).
|
|
11
11
|
|
|
12
12
|
## The shared model
|
|
13
13
|
|
|
14
14
|
Every stack does the same two imports, from the same kind of place — a root layout, an app entry file, or a global CSS file, never a page or a component further down the tree:
|
|
15
15
|
|
|
16
|
-
1. One [entrypoint](../setup.md#
|
|
16
|
+
1. One [entrypoint](../setup.md#all-entrypoints) — the compiled `@codenhub/styles` for any build, or `@codenhub/styles/tw` when the project already runs Tailwind CSS v4.
|
|
17
17
|
2. `@codenhub/styles/aesthetics` (or `/tw/aesthetics`) after it, only if the project uses an [aesthetic](../usage/aesthetics.md).
|
|
18
18
|
|
|
19
19
|
Importing from one place matters for two reasons. Some frameworks only _allow_ global CSS from a designated root file and fail the build otherwise — Next.js's Pages Router is one, see [Next.js → Troubleshooting](./nextjs.md#troubleshooting). Where a framework allows it more broadly, as Next.js's App Router does, importing from the root remains the recommended choice for predictable CSS ordering — and importing per-component instead would load the same reset and token rules once per component rather than once per app.
|
|
20
20
|
|
|
21
21
|
## Which guide to follow
|
|
22
22
|
|
|
23
|
-
| Stack
|
|
24
|
-
|
|
|
25
|
-
| A Tailwind CSS v4 project on any bundler
|
|
26
|
-
| Next.js / React
|
|
27
|
-
| Vue
|
|
28
|
-
| Svelte / SvelteKit
|
|
29
|
-
| Astro
|
|
23
|
+
| Stack | Guide |
|
|
24
|
+
| ------------------------------------------------------------ | ------------------------------------------- |
|
|
25
|
+
| A Tailwind CSS v4 project on any bundler | [Tailwind CSS v4](./tailwind.md) |
|
|
26
|
+
| Next.js / React | [Next.js](./nextjs.md) |
|
|
27
|
+
| Vue | [Vue](./vue.md) |
|
|
28
|
+
| Svelte / SvelteKit | [Svelte](./svelte.md) |
|
|
29
|
+
| Astro | [Astro](./astro.md) |
|
|
30
|
+
| Plain HTML, Rails, Django, or any app with no CSS build step | [Without a bundler](./without-a-bundler.md) |
|
|
30
31
|
|
|
31
|
-
A project with no framework — a plain Vite, webpack, or Parcel build — needs nothing beyond [Setup →
|
|
32
|
+
A project with no framework — a plain Vite, webpack, or Parcel build — needs nothing beyond [Setup → Import the stylesheet](../setup.md#import-the-stylesheet): import the compiled stylesheet from the project's existing global CSS entry.
|
|
32
33
|
|
|
33
34
|
## Verifying it worked
|
|
34
35
|
|
|
35
36
|
After the import, render one styled element and confirm it picked up the package's tokens rather than the browser default:
|
|
36
37
|
|
|
37
38
|
```html
|
|
38
|
-
<button class="btn primary">
|
|
39
|
+
<button class="btn primary">Save changes</button>
|
|
39
40
|
```
|
|
40
41
|
|
|
41
|
-
A rounded
|
|
42
|
+
A rounded button filled with the primary color (near-black on a light page, near-white on a dark one) means the stylesheet loaded. Unstyled browser-default text most often means the import specifier didn't resolve — check the [entrypoint table](../setup.md#all-entrypoints) for the exact specifier to import, and confirm your build tooling resolves package CSS imports at all, see [Setup → Requirements](../setup.md#requirements). With no build tool, link the file by its path instead; see [Without a bundler](./without-a-bundler.md). [Setup → When nothing is styled](../setup.md#when-nothing-is-styled) lists the other common causes.
|
|
43
|
+
|
|
44
|
+
## Next
|
|
45
|
+
|
|
46
|
+
Once the button renders, go back to the main path: [Building a screen](../concepts.md) adds the first card and form to the settings page.
|
|
@@ -47,7 +47,7 @@ Running Tailwind CSS v4? `@import "@codenhub/styles/tw"` is a CSS directive, so
|
|
|
47
47
|
|
|
48
48
|
## Force a theme
|
|
49
49
|
|
|
50
|
-
Apply `.dark` or `.light` on `<html>` to force a theme instead of following the system preference; see [
|
|
50
|
+
Apply `.dark` or `.light` on `<html>` to force a theme instead of following the system preference; see [Theming → Light and dark](../usage/theming.md#light-and-dark).
|
|
51
51
|
|
|
52
52
|
```tsx
|
|
53
53
|
<html lang="en" className="dark">
|
|
@@ -61,7 +61,6 @@ Apply `.dark` or `.light` on `<html>` to force a theme instead of following the
|
|
|
61
61
|
- **Why:** the Pages Router has no per-route CSS boundary the way the App Router does, so Next.js requires one predictable file for global stylesheets to avoid ordering conflicts between pages.
|
|
62
62
|
- **Fix:** move the `import "@codenhub/styles"` line to `pages/_app.tsx`, and remove it from wherever it currently is.
|
|
63
63
|
|
|
64
|
-
##
|
|
64
|
+
## Next
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
- [Usage](../usage/index.md): component classes to compose once the stylesheet is loaded.
|
|
66
|
+
Return to the main path: [Building a screen](../concepts.md) adds the first card and form to the settings page. [Setup → All entrypoints](../setup.md#all-entrypoints) lists every other stylesheet you can import.
|
|
@@ -6,6 +6,8 @@ order: 4
|
|
|
6
6
|
|
|
7
7
|
# Svelte
|
|
8
8
|
|
|
9
|
+
Svelte and SvelteKit let you import CSS from any component, but the package's reset and tokens should load once, before any component renders. This page shows where that one import goes in SvelteKit and in a plain Svelte app.
|
|
10
|
+
|
|
9
11
|
## Import the stylesheet
|
|
10
12
|
|
|
11
13
|
**SvelteKit** — import from the root layout so it loads once for every route:
|
|
@@ -35,9 +37,8 @@ Running Tailwind CSS v4? Import `@codenhub/styles/tw` from the app's CSS entry i
|
|
|
35
37
|
|
|
36
38
|
## Force a theme
|
|
37
39
|
|
|
38
|
-
Apply `.dark` or `.light` on `<html>` (edit `src/app.html` in SvelteKit) to force a theme instead of following the system preference; see [
|
|
40
|
+
Apply `.dark` or `.light` on `<html>` (edit `src/app.html` in SvelteKit) to force a theme instead of following the system preference; see [Theming → Light and dark](../usage/theming.md#light-and-dark).
|
|
39
41
|
|
|
40
|
-
##
|
|
42
|
+
## Next
|
|
41
43
|
|
|
42
|
-
|
|
43
|
-
- [Usage](../usage/index.md): component classes to compose once the stylesheet is loaded.
|
|
44
|
+
Return to the main path: [Building a screen](../concepts.md) adds the first card and form to the settings page. [Setup → All entrypoints](../setup.md#all-entrypoints) lists every other stylesheet you can import.
|
|
@@ -6,7 +6,7 @@ order: 1
|
|
|
6
6
|
|
|
7
7
|
# Tailwind CSS v4
|
|
8
8
|
|
|
9
|
-
A project that already runs Tailwind CSS v4 can
|
|
9
|
+
A project that already runs Tailwind CSS v4 can compile this package's source instead of loading its compiled output. Your app's utilities and the package's classes then come out of one build, share one theme, and use one `dark:` variant. This page covers the import, aesthetics, the focused entrypoints, and the build problems you are likely to meet.
|
|
10
10
|
|
|
11
11
|
## Why source instead of compiled
|
|
12
12
|
|
|
@@ -37,14 +37,13 @@ Add an aesthetic from the source entrypoint the same way as the compiled one, af
|
|
|
37
37
|
|
|
38
38
|
## Using a focused entrypoint
|
|
39
39
|
|
|
40
|
-
Import a focused `/tw/*` entrypoint instead of the combined one — such as `/tw/button` or `/tw/form` — when a build only needs one component family; see the full [
|
|
40
|
+
Import a focused `/tw/*` entrypoint instead of the combined one — such as `/tw/button` or `/tw/form` — when a build only needs one component family; see the full [entrypoint table](../setup.md#all-entrypoints) for what each one composes.
|
|
41
41
|
|
|
42
42
|
Unlike `/tw`, the focused entrypoints and `/tw/native` do not import Tailwind, so keep your own import first:
|
|
43
43
|
|
|
44
44
|
```css
|
|
45
45
|
@import "tailwindcss";
|
|
46
46
|
@import "@codenhub/styles/tw/button";
|
|
47
|
-
@import "@codenhub/styles/tw/loader";
|
|
48
47
|
```
|
|
49
48
|
|
|
50
49
|
## Troubleshooting
|
|
@@ -61,4 +60,18 @@ Unlike `/tw`, the focused entrypoints and `/tw/native` do not import Tailwind, s
|
|
|
61
60
|
- **Why:** one of two things. Importing both a compiled entrypoint (`@codenhub/styles`) and a `/tw` entrypoint (`@codenhub/styles/tw`) in the same build compiles the same tokens and reset from two independent sources; Tailwind's build has no way to know they describe the same package. Or your stylesheet imports `tailwindcss` beside `/tw`, which already imports it, so Preflight is emitted twice.
|
|
62
61
|
- **Fix:** pick one path per project — `/tw` entrypoints for a project running Tailwind CSS v4, compiled entrypoints everywhere else — and drop your own `@import "tailwindcss"` when you import `/tw`.
|
|
63
62
|
|
|
63
|
+
**A class built at runtime has no styling**
|
|
64
|
+
|
|
65
|
+
- **What happened:** `<button class="btn primary">` is styled, but a button whose intent comes from a variable, such as `` `btn ${tone}` ``, is not.
|
|
66
|
+
- **Why:** Tailwind generates a class only when it finds the complete name in your source files. The package's own component and axis classes are always generated, but your own utilities are not, and a name assembled from strings is invisible to the scan.
|
|
67
|
+
- **Fix:** write complete class names in your source, for example in a lookup object (`{ save: "btn primary", remove: "btn destructive" }`), or list the names your code can produce with `@source inline("...")` in your stylesheet.
|
|
68
|
+
|
|
64
69
|
Every `/tw` entrypoint requires Tailwind CSS 4.3.2 or newer, below 5: the source uses `@source not` and `@source inline()`, which arrived in 4.1, and it is tested against 4.3.2.
|
|
70
|
+
|
|
71
|
+
## The `dark:` variant
|
|
72
|
+
|
|
73
|
+
The `/tw` entrypoints define their own `dark:` variant, so your utilities switch with the same light and dark selectors the package's tokens use. It has one known difference from the tokens when themes are nested; see [Theming → The dark: variant](../usage/theming.md#the-dark-variant).
|
|
74
|
+
|
|
75
|
+
## Next
|
|
76
|
+
|
|
77
|
+
Return to the main path: [Building a screen](../concepts.md) adds the first card and form to the settings page. Everything it shows works the same on `/tw`.
|
package/docs/integrating/vue.md
CHANGED
|
@@ -23,9 +23,8 @@ Running Tailwind CSS v4? Import `@codenhub/styles/tw` from a CSS entry file inst
|
|
|
23
23
|
|
|
24
24
|
## Force a theme
|
|
25
25
|
|
|
26
|
-
Apply `.dark` or `.light` on the root element to force a theme instead of following the system preference; see [
|
|
26
|
+
Apply `.dark` or `.light` on the root element to force a theme instead of following the system preference; see [Theming → Light and dark](../usage/theming.md#light-and-dark).
|
|
27
27
|
|
|
28
|
-
##
|
|
28
|
+
## Next
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
- [Usage](../usage/index.md): component classes to compose once the stylesheet is loaded.
|
|
30
|
+
Return to the main path: [Building a screen](../concepts.md) adds the first card and form to the settings page. [Setup → All entrypoints](../setup.md#all-entrypoints) lists every other stylesheet you can import.
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Without a bundler
|
|
3
|
+
description: Linking the compiled stylesheets from plain HTML, Rails, Django, or any server-rendered app.
|
|
4
|
+
order: 6
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Without a bundler
|
|
8
|
+
|
|
9
|
+
The compiled stylesheets are finished CSS: each one is a single file with no `@import` and no reference to another file, and every image it draws is embedded as a `data:` URL: the checkbox tick and dash masks, and the SVG lens filters `.glass-liquid` uses. A page can load one with a plain `<link>` tag, from any server, with no build step, and the stylesheet makes no further requests.
|
|
10
|
+
|
|
11
|
+
What needs a build tool is the import _name_. `@import "@codenhub/styles"` names a package, and finding the file behind that name — `node_modules/@codenhub/styles/dist/index.css` — is done by Node-aware tooling such as Vite, webpack, or the Tailwind CLI, which read the package's `exports` map. A browser does not: it resolves an `@import` URL against the stylesheet that contains it and a `<link href>` against the page, so a bare package name becomes a request for a path that does not exist. Without a bundler, link the file by its path instead.
|
|
12
|
+
|
|
13
|
+
The `/tw` entrypoints are Tailwind source and need a Tailwind build. `/tw/aesthetics` is the exception, plain CSS with nothing for Tailwind to process, but without a bundler link the compiled `dist/aesthetics/` files instead, as below. This page covers the compiled entrypoints only, for a page that has no CSS build at all: plain HTML, Rails, Django, or any server-rendered app.
|
|
14
|
+
|
|
15
|
+
## Which file to link
|
|
16
|
+
|
|
17
|
+
Each compiled import path is one file in the package's `dist/` folder:
|
|
18
|
+
|
|
19
|
+
| Import path | File |
|
|
20
|
+
| ------------------------------- | ----------------------------------------------------------------- |
|
|
21
|
+
| `@codenhub/styles` | `dist/index.css` |
|
|
22
|
+
| `@codenhub/styles/theme` | `dist/theme.css` |
|
|
23
|
+
| `@codenhub/styles/components` | `dist/components.css` |
|
|
24
|
+
| `@codenhub/styles/native` | `dist/native.css` |
|
|
25
|
+
| `@codenhub/styles/palette` | `dist/palette.css` |
|
|
26
|
+
| `@codenhub/styles/aesthetics` | `dist/aesthetics/index.css` |
|
|
27
|
+
| `@codenhub/styles/aesthetics/*` | `dist/aesthetics/<name>.css`, such as `dist/aesthetics/pixel.css` |
|
|
28
|
+
|
|
29
|
+
Link the base file first and an aesthetic after it. [Setup → All entrypoints](../setup.md#all-entrypoints) explains what each one contains; link one base file, not several, since they overlap.
|
|
30
|
+
|
|
31
|
+
## From a CDN
|
|
32
|
+
|
|
33
|
+
jsDelivr and unpkg serve every file of every published npm version, so a page can link one with nothing installed:
|
|
34
|
+
|
|
35
|
+
```html
|
|
36
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@codenhub/styles@0.7.0/dist/index.css" /> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@codenhub/styles@0.7.0/dist/aesthetics/pixel.css" />
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Put the exact version in the URL. Without one, the CDN serves the latest release, and below 1.0 a minor release may rename or remove a class; see [Versioning](../index.md#versioning).
|
|
40
|
+
|
|
41
|
+
## From your own server
|
|
42
|
+
|
|
43
|
+
Install the package, then serve its `dist/` folder as static files:
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
npm install @codenhub/styles
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
How a framework serves a folder from `node_modules` differs, so each one is below. Where the framework reads the folder in place, as Rails and Django do, upgrading the package and redeploying is all an update takes.
|
|
50
|
+
|
|
51
|
+
### Plain HTML
|
|
52
|
+
|
|
53
|
+
Copy `node_modules/@codenhub/styles/dist` into the folder your server publishes, then link it:
|
|
54
|
+
|
|
55
|
+
```html
|
|
56
|
+
<link rel="stylesheet" href="/vendor/codenhub-styles/index.css" />
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Repeat the copy after each upgrade, for example from an npm `postinstall` script.
|
|
60
|
+
|
|
61
|
+
### Ruby on Rails
|
|
62
|
+
|
|
63
|
+
A Rails app built with `cssbundling-rails` already runs a bundler: import the package from `app/assets/stylesheets/application.css` as in [Setup → Import the stylesheet](../setup.md#import-the-stylesheet).
|
|
64
|
+
|
|
65
|
+
With Propshaft and no CSS bundler, add the package's folder to the asset paths:
|
|
66
|
+
|
|
67
|
+
```ruby
|
|
68
|
+
# config/initializers/assets.rb
|
|
69
|
+
Rails.application.config.assets.paths << Rails.root.join("node_modules/@codenhub")
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Then link it from the layout, by its path below that folder:
|
|
73
|
+
|
|
74
|
+
```erb
|
|
75
|
+
<%# app/views/layouts/application.html.erb %>
|
|
76
|
+
<%= stylesheet_link_tag "styles/dist/index" %>
|
|
77
|
+
<%= stylesheet_link_tag "styles/dist/aesthetics/pixel" %>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Point the path at `node_modules/@codenhub` rather than at `dist/` itself. Propshaft serves files by their path below each asset folder, so adding `dist/` directly would publish a bare `index.css` that collides with any `index.css` of your own.
|
|
81
|
+
|
|
82
|
+
### Django
|
|
83
|
+
|
|
84
|
+
Add the folder to `STATICFILES_DIRS` under a prefix, which keeps its file names apart from your own static files:
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
# settings.py
|
|
88
|
+
STATICFILES_DIRS = [
|
|
89
|
+
("codenhub-styles", BASE_DIR / "node_modules/@codenhub/styles/dist"),
|
|
90
|
+
]
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
```django
|
|
94
|
+
{% load static %}
|
|
95
|
+
<link rel="stylesheet" href="{% static 'codenhub-styles/index.css' %}" />
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Laravel
|
|
99
|
+
|
|
100
|
+
A Laravel app runs Vite by default, so it has a bundler: import the package from `resources/css/app.css` as in [Setup → Import the stylesheet](../setup.md#import-the-stylesheet), and load that file with the `@vite` directive as usual.
|
|
101
|
+
|
|
102
|
+
## Verifying it worked
|
|
103
|
+
|
|
104
|
+
Render one styled element, as in [Integrating → Verifying it worked](./index.md#verifying-it-worked):
|
|
105
|
+
|
|
106
|
+
```html
|
|
107
|
+
<button class="btn primary">Save changes</button>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
A rounded button filled with the primary color means the stylesheet loaded. If the button looks like the browser default, open the browser's network panel: a `404` on the stylesheet means the path or the static-file setup is wrong.
|
|
111
|
+
|
|
112
|
+
## Next
|
|
113
|
+
|
|
114
|
+
Return to the main path: [Building a screen](../concepts.md) adds the first card and form to the settings page. [Setup → All entrypoints](../setup.md#all-entrypoints) lists every other stylesheet you can import.
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Acessibilidade
|
|
3
|
+
description: O que o CSS faz por foco, estados, movimento, contraste, cores forçadas e texto da direita para a esquerda, e o que a sua aplicação ainda deve aos seus usuários.
|
|
4
|
+
order: 5
|
|
5
|
+
source: dc1a745e9e6853a31ca4a8cf7a334031bab1ec7d
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Acessibilidade
|
|
9
|
+
|
|
10
|
+
A tela de configurações está pronta, e o CSS fez a sua parte no caminho: todo campo mostra onde está o foco, um email inválido fica vermelho e o spinner para para usuários que pedem menos movimento. O resto depende do seu HTML e JavaScript. Este pacote estiliza estados; ele não fornece elementos semânticos, atributos ARIA, comportamento de teclado, gerenciamento de foco, validação nem o momento dos anúncios.
|
|
11
|
+
|
|
12
|
+
Esta página lista as duas metades: o que o CSS fornece e o que a sua aplicação precisa adicionar.
|
|
13
|
+
|
|
14
|
+
## Fornecido pelo CSS
|
|
15
|
+
|
|
16
|
+
### Foco e estado
|
|
17
|
+
|
|
18
|
+
| Recurso | Comportamento |
|
|
19
|
+
| ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
20
|
+
| `:focus-visible` | Um outline de foco em todo elemento, desenhado com `--focus-ring`, `--focus-ring-width` e `--focus-ring-offset`. |
|
|
21
|
+
| Foco em controles de formulário | `.ipt`, `.textarea` e `.select` desenham o outline de foco e mudam a borda para a cor da intenção. O texto digitado num campo com classe de intenção fica no tom legível da intenção, `--intent-strong`. |
|
|
22
|
+
| Controles inválidos | `aria-invalid="true"` num controle de formulário deixa a borda, a cor de foco e o texto digitado na cor destrutiva, com o texto no tom legível destrutivo. |
|
|
23
|
+
| Controles desabilitados | `disabled`, `aria-disabled="true"`, `data-disabled` e `.disabled` mostram o cursor e a opacidade de desabilitado, e um controle desabilitado não reage ao hover, inclusive dentro de um `.input-group`. |
|
|
24
|
+
| Estado aberto | `data-state="open"` num `.tooltip` mostra o balão sem hover nem foco, e `data-state="closed"` o esconde durante o hover ou o foco. Nenhum outro componente lê nenhum dos dois. |
|
|
25
|
+
| `<dialog>` nativo | Um `<dialog>` com `.card`, `.panel` ou `.surface` fica escondido até ser aberto, e abre centralizado. Uma margem que você define no dialog, como utilitário ou no seu próprio CSS, ainda substitui a centralização. Outros dialogs não são afetados. Prender o foco, fechar com Escape e tornar inerte a página por trás ficam por conta da sua aplicação. |
|
|
26
|
+
|
|
27
|
+
### Conteúdo visualmente oculto
|
|
28
|
+
|
|
29
|
+
`.visually-hidden` esconde o conteúdo na tela e o mantém para leitores de tela, como faz a `<caption>` da tabela de chaves de API em [Conteúdo e layout → Tabelas](./usage/content-and-layout.md#tabelas). Ela vem com os utilitários de layout: em `.`, `./native`, `./tw`, `./tw/native` e `./tw/utilities`. Ela não está em `./components` nem nos entrypoints de componentes `./tw/components` e `./tw/*`.
|
|
30
|
+
|
|
31
|
+
### Limites dos controles
|
|
32
|
+
|
|
33
|
+
O WCAG 1.4.11 pede que o limite de um controle que você precisa ver para usá-lo tenha um contraste de pelo menos 3:1 em relação ao que está ao lado dele.
|
|
34
|
+
|
|
35
|
+
| Recurso | Comportamento |
|
|
36
|
+
| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
37
|
+
| Controles de texto em repouso | A borda de um controle de texto fica, em repouso, mais clara que a borda cheia da sua intenção, abaixo de 3:1 por escolha, para que o hover e o foco tenham um tom mais forte para onde mudar. |
|
|
38
|
+
| Toggles | `.checkbox`, `.radio` e `.switch` desenham a borda cheia, porque a borda é a única coisa que mostra uma caixa desmarcada. Um `.switch` com o seu próprio `.edgeless` é a exceção, abaixo. |
|
|
39
|
+
| `.edgeless` vindo de um contêiner | Ignorado por todo controle de texto e toggle: um contêiner não pode remover a borda de um campo ou toggle dentro dele. |
|
|
40
|
+
| `.edgeless` no próprio controle | `.ipt`, `.textarea`, `.select` e `.switch` perdem a borda e deixam de atender ao 1.4.11 em repouso. `.switch.ghost` mantém a borda mesmo assim, porque, sem preenchimento e sem borda, nada mostraria o trilho. |
|
|
41
|
+
| `.checkbox`, `.radio` | Sempre desenham a borda, venha o `.edgeless` de um contêiner ou deles mesmos. `.edgeless` neles não é suportado. |
|
|
42
|
+
| Trilho de progresso | Por escolha, a parte preenchida carrega o valor e o trilho é um fundo discreto. O trilho padrão, `.soft.edgeless`, mede cerca de 1.1:1 a 1.3:1 em relação à página. A parte preenchida mede pelo menos 3:1 em relação a esse trilho em todas as intenções, exceto warning no claro (cerca de 2.7:1) e info no escuro (cerca de 2.9:1). Onde o próprio trilho precisa atender ao 1.4.11, use `.ghost.edged` com uma classe de intenção; veja [Contornos de progresso](#contornos-de-progresso) abaixo. |
|
|
43
|
+
|
|
44
|
+
### Contornos de progresso
|
|
45
|
+
|
|
46
|
+
Num `.progress.ghost.edged`, o trilho é a página, e o seu contorno e a parte preenchida são desenhados na cor da intenção. Medido em relação à página, sem estética:
|
|
47
|
+
|
|
48
|
+
| Intenção | Página clara | Página escura | Atende a 3:1 |
|
|
49
|
+
| -------------- | ------------ | ------------- | ------------------------------------------------------------------------ |
|
|
50
|
+
| `.primary` | 18.96:1 | 18.96:1 | Sim |
|
|
51
|
+
| `.secondary` | 7.47:1 | 7.63:1 | Sim |
|
|
52
|
+
| `.success` | 5.14:1 | 3.69:1 | Sim |
|
|
53
|
+
| `.warning` | 3.06:1 | 6.20:1 | Sim |
|
|
54
|
+
| `.destructive` | 5.80:1 | 3.27:1 | Sim |
|
|
55
|
+
| `.info` | 6.17:1 | 3.07:1 | Sim |
|
|
56
|
+
| Sem intenção | 2.48:1 | 1.91:1 | Não: o contorno falha, embora a parte preenchida, na cor do texto, passe |
|
|
57
|
+
|
|
58
|
+
Sem classe de intenção, o contorno é o cinza de borda discreto, `--color-border`. Para que um trilho neutro atenda ao 1.4.11, dê uma classe de intenção à barra, ou defina `--progress-edge` com uma cor mais forte, como `var(--color-accent)`, que mede 7.47:1 numa página clara e 7.63:1 numa escura. Warning numa página clara e info numa escura passam de 3:1 por pouco, então meça de novo se você mudar essas cores.
|
|
59
|
+
|
|
60
|
+
### Movimento e transparência
|
|
61
|
+
|
|
62
|
+
| Recurso | Comportamento |
|
|
63
|
+
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
64
|
+
| Movimento reduzido, componentes | Com `prefers-reduced-motion: reduce`, todo componente para as suas próprias transições e animações: o brilho do skeleton e do progresso, a barra indeterminada, o tooltip, as marcas dos toggles e o clique. |
|
|
65
|
+
| Movimento reduzido, página inteira | O reset também encurta todas as outras animações e transições da página. |
|
|
66
|
+
| Transparência reduzida | Com `prefers-reduced-transparency: reduce`, `.glass` e `.glass-liquid` perdem o desfoque e a lente e ficam opacos. |
|
|
67
|
+
|
|
68
|
+
A regra de movimento reduzido de cada componente vem com o componente, então todo entrypoint que o inclui respeita o movimento reduzido sem o reset, incluindo `@codenhub/styles/components`, `@codenhub/styles/tw/components` e cada entrypoint de componente `/tw/*`. Os entrypoints completos e nativos adicionam a regra do reset para a página inteira.
|
|
69
|
+
|
|
70
|
+
A regra do reset é `!important` dentro da camada `base`, e um `!important` com camada vence um sem camada, então o seu próprio `!important` não consegue religar uma animação. Para manter uma rodando para usuários que pedem movimento reduzido, como um spinner de upload que você considera essencial, declare-a `!important` numa camada ordenada antes de `base`. A primeira declaração `@layer` que o navegador lê define a ordem, então a sua vem antes do pacote:
|
|
71
|
+
|
|
72
|
+
```css
|
|
73
|
+
@layer essential-motion, theme, base, components, utilities;
|
|
74
|
+
@import "@codenhub/styles";
|
|
75
|
+
|
|
76
|
+
@layer essential-motion {
|
|
77
|
+
@media (prefers-reduced-motion: reduce) {
|
|
78
|
+
.upload-spinner {
|
|
79
|
+
animation-duration: 1s !important;
|
|
80
|
+
animation-iteration-count: infinite !important;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Respeitar o movimento reduzido não é o requisito inteiro. Um movimento que continua ao lado do conteúdo, como um brilho deixado num card depois que ele carregou, precisa de uma forma de ser parado por qualquer usuário; veja [Feedback → Animação que não para](./usage/feedback.md#animação-que-não-para).
|
|
87
|
+
|
|
88
|
+
### Cor e contraste
|
|
89
|
+
|
|
90
|
+
As medições abaixo são das cores entregues. Assim que você mudar um token de cor, meça de novo os seus próprios pares; [Temas → Mude a cor da marca](./usage/theming.md#mude-a-cor-da-marca) mostra quais pares conferir.
|
|
91
|
+
|
|
92
|
+
| Recurso | Comportamento |
|
|
93
|
+
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
94
|
+
| Rótulos preenchidos | O rótulo `.solid` de toda intenção atende a 4.5:1 (WCAG 1.4.3) como texto normal, nos dois temas. O menor é success, com 5.14:1. |
|
|
95
|
+
| Texto em warning | `--color-warning-contrast` é quase preto, e não a cor da página, porque um âmbar escuro o bastante para carregar texto branco deixa de parecer âmbar. |
|
|
96
|
+
| Preenchimentos parciais | A cor de texto de contraste só aparece em preenchimentos acima da metade da força, então o preenchimento limitado de um controle de texto mantém a cor de texto da própria intenção. |
|
|
97
|
+
| Cor da intenção no escuro | No modo escuro, um rótulo `.soft` ou `.ghost` usa o tom `-300` da sua intenção, para manter o matiz em vez de ficar branco. |
|
|
98
|
+
| Marcas dos toggles | Uma marca de marcado mede pelo menos 3:1 em relação a todo preenchimento que a sua apresentação pode dar a ela, nos dois temas. |
|
|
99
|
+
| Preenchimentos soft com borda | `.edged` num `.alert`, `.panel`, `.badge`, `.kbd`, `.code` ou `.pre` `.soft` desenha uma borda que mede menos de 3:1 em relação ao preenchimento de 12% em algumas intenções, que variam conforme o tema. Meça o par antes de contar com essa borda como limite de um controle. |
|
|
100
|
+
|
|
101
|
+
### Cores forçadas e direção
|
|
102
|
+
|
|
103
|
+
| Recurso | Comportamento |
|
|
104
|
+
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
105
|
+
| Cores forçadas | Com `forced-colors: active`, as bordas, os estados marcados e a seta de um `.select` continuam visíveis, desenhados nas cores do sistema, sob todas as estéticas. Uma estética que desenha a borda como sombra interna, como `.pixel`, desenha uma borda real no lugar. |
|
|
106
|
+
| Direção do texto | Sob `dir="rtl"`, a barra da citação, o ícone do alerta, o preenchimento do progresso, o divisor vertical, o botão do switch, o alinhamento das tabelas e a seta de um select trocam de lado. Nenhuma classe é necessária. |
|
|
107
|
+
|
|
108
|
+
Em cores forçadas, `.text-control`, `.ipt`, `.textarea`, `.select` e os toggles mostram um outline de foco `Highlight` de 2px. O entrypoint nativo dá o mesmo outline a campos de texto, selects, textareas, checkboxes e radios sem classe.
|
|
109
|
+
|
|
110
|
+
Checkboxes, radios e switches usam as cores do sistema `Canvas`, `CanvasText`, `Highlight` e `HighlightText`, para que marcado e desmarcado continuem distintos: um toggle marcado é preenchido com `Highlight` e a sua marca é `HighlightText`, tanto nas classes quanto no entrypoint nativo. Formato, tamanho e espaçamento não mudam.
|
|
111
|
+
|
|
112
|
+
## O que fica fora do CSS
|
|
113
|
+
|
|
114
|
+
Use o elemento HTML que corresponde ao que o componente faz e adicione o comportamento que o CSS não consegue.
|
|
115
|
+
|
|
116
|
+
| Interface | O que a sua aplicação adiciona |
|
|
117
|
+
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
118
|
+
| Botões | `<button>` para ações e `<a href>` para navegação. Um nome acessível, como `aria-label`, em todo `.btn.icon`. |
|
|
119
|
+
| Formulários | Um `<label>` para cada controle, o `type` certo, validação e `aria-describedby` ligando dicas e erros. Mantenha dicas e erros fora do `<label>` e dê `role="switch"` a um `.switch`. |
|
|
120
|
+
| Alertas | `role="status"` para uma confirmação como "Profile saved", ou `role="alert"` para um erro que precisa de atenção imediata. |
|
|
121
|
+
| Toasts | Uma live region, uma forma de dispensá-lo, regras de foco e uma pausa em qualquer tempo limite. |
|
|
122
|
+
| Tooltips | Um `id` real e `role="tooltip"` no balão, referenciado pelo `aria-describedby` do gatilho. Dispensa com Escape escrevendo `data-state="closed"`; veja [Tooltips](./usage/tooltips.md#hover-permanência-e-escape). O balão já aceita hover. |
|
|
123
|
+
| Progresso | Um elemento `<progress>`, ou `role="progressbar"` ou `role="meter"` com valores ARIA, quando o valor precisa ser anunciado. |
|
|
124
|
+
| Skeletons | `aria-hidden="true"` nos visuais de carregamento, incluindo um spinner que você traga, e o estado de carregamento anunciado de outra forma quando necessário. |
|
|
125
|
+
| Movimento contínuo | Uma forma de pausar, parar ou esconder o movimento que não é essencial; veja [Feedback → Animação que não para](./usage/feedback.md#animação-que-não-para). |
|
|
126
|
+
| Popovers, modais | Prender o foco, fechar com Escape, um fundo inerte, rótulos e roles. |
|
|
127
|
+
|
|
128
|
+
## Atributos de estado
|
|
129
|
+
|
|
130
|
+
Prefira os atributos nativos:
|
|
131
|
+
|
|
132
|
+
```html
|
|
133
|
+
<button class="btn primary" disabled>Saving…</button> <input class="ipt" type="email" aria-invalid="true" aria-describedby="email-error" />
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Use atributos ARIA ou data onde o elemento ou a sua biblioteca de componentes não tem um nativo:
|
|
137
|
+
|
|
138
|
+
```html
|
|
139
|
+
<a class="btn secondary" aria-disabled="true">Export data</a>
|
|
140
|
+
<span class="tooltip" data-state="open">
|
|
141
|
+
<button type="button" class="tooltip-icon" aria-label="About public profiles" aria-describedby="public-profile-help">?</button>
|
|
142
|
+
<span class="tooltip-bubble" role="tooltip" id="public-profile-help">Anyone with the link can see your name and photo.</span>
|
|
143
|
+
</span>
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
`aria-disabled="true"` informa às tecnologias assistivas que o controle está desabilitado, mas não impede um clique nem o pressionar de uma tecla. Use o atributo `disabled`, ou interrompa a ação no JavaScript.
|
|
147
|
+
|
|
148
|
+
## A seguir
|
|
149
|
+
|
|
150
|
+
Isso completa a ordem de leitura. A [Introdução](./index.md) tem links para todas as páginas, e [Composição](./usage/composing.md), [Personalização](./usage/customizing.md) e [Conteúdo e layout](./usage/content-and-layout.md) são as páginas de consulta para depois.
|