@codenhub/styles 0.1.0 → 0.2.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 +8 -69
- package/dist/aesthetics/chunky-tile.css +1 -1
- package/dist/aesthetics/index.css +1 -1
- package/dist/components.css +1 -1
- package/dist/index.css +1 -1
- package/dist/native.css +1 -1
- package/dist/theme.css +1 -1
- package/dist/tw/aesthetics/chunky-tile.css +20 -2
- package/dist/tw/box.css +45 -2
- package/dist/tw/components/button.css +38 -29
- package/dist/tw/components/feedback.css +58 -41
- package/dist/tw/components/form.css +139 -47
- package/dist/tw/components/index.css +16 -6
- package/dist/tw/components/loader.css +2 -16
- package/dist/tw/components/surface.css +122 -5
- package/dist/tw/components/tooltip.css +102 -91
- package/dist/tw/elevation.css +57 -14
- package/dist/tw/index.css +23 -5
- package/dist/tw/intent.css +36 -12
- package/dist/tw/native.css +4 -20
- package/dist/tw/reset.css +40 -32
- package/dist/tw/theme.css +46 -8
- package/dist/tw/utilities/content.css +104 -18
- package/dist/tw/utilities/index.css +1 -1
- package/dist/tw/utilities/layout.css +33 -0
- package/docs/accessibility.md +68 -48
- package/docs/changelog/0.1.0.md +37 -0
- package/docs/changelog/0.1.1.md +10 -0
- package/docs/changelog/0.2.0.md +41 -0
- package/docs/changelog/index.md +11 -0
- package/docs/concepts.md +21 -46
- package/docs/index.md +18 -45
- package/docs/integrating/astro.md +13 -7
- package/docs/integrating/index.md +25 -16
- package/docs/integrating/nextjs.md +31 -8
- package/docs/integrating/svelte.md +14 -8
- package/docs/integrating/tailwind.md +31 -15
- package/docs/integrating/vue.md +13 -7
- package/docs/setup.md +31 -32
- package/docs/usage/aesthetics.md +31 -107
- package/docs/usage/buttons.md +24 -36
- package/docs/usage/composing.md +31 -102
- package/docs/usage/content-and-layout.md +65 -83
- package/docs/usage/customizing.md +25 -90
- package/docs/usage/feedback.md +25 -56
- package/docs/usage/forms.md +48 -80
- package/docs/usage/index.md +9 -17
- package/docs/usage/theming.md +25 -81
- package/docs/usage/tooltips.md +55 -35
- package/llms-full.txt +1193 -1510
- package/package.json +121 -44
package/docs/usage/forms.md
CHANGED
|
@@ -1,43 +1,36 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Forms
|
|
3
3
|
description: Field, text control, and toggle class reference.
|
|
4
|
+
order: 6
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# Forms
|
|
7
8
|
|
|
8
|
-
| Class or Selector | Purpose
|
|
9
|
-
| --------------------------------------------------------------------- |
|
|
10
|
-
| `.field` | Vertical field wrapper.
|
|
11
|
-
| `.label` | Form label text.
|
|
12
|
-
| `.hint` | Secondary helper text.
|
|
13
|
-
| `.hint.error` | Helper text with destructive intent.
|
|
14
|
-
| `.surface` | Shared public container composition utility.
|
|
15
|
-
| `.text-control` | Shared public text-control composition utility.
|
|
16
|
-
| `.ipt` | Input control styling.
|
|
17
|
-
| `.input-group` | Wrapper that owns the field box so a control can carry
|
|
18
|
-
| `.textarea` | Textarea control styling.
|
|
19
|
-
| `.select` | Select control styling.
|
|
20
|
-
| `input[type="checkbox"].checkbox` | Custom checkbox control styling.
|
|
21
|
-
| `input[type="radio"].radio` | Custom radio control styling.
|
|
22
|
-
| `input[type="checkbox"].switch` | Custom switch control styling.
|
|
23
|
-
| `[aria-invalid="true"]` on controls | Destructive border and focus color.
|
|
24
|
-
| `[disabled]`, `[aria-disabled="true"]`, `[data-disabled]` on controls | Disabled styling.
|
|
9
|
+
| Class or Selector | Purpose |
|
|
10
|
+
| --------------------------------------------------------------------- | ------------------------------------------------------------------------ |
|
|
11
|
+
| `.field` | Vertical field wrapper. |
|
|
12
|
+
| `.label` | Form label text. |
|
|
13
|
+
| `.hint` | Secondary helper text. |
|
|
14
|
+
| `.hint.error` | Helper text with destructive intent. |
|
|
15
|
+
| `.surface` | Shared public container composition utility. |
|
|
16
|
+
| `.text-control` | Shared public text-control composition utility. |
|
|
17
|
+
| `.ipt` | Input control styling. |
|
|
18
|
+
| `.input-group` | Wrapper that owns the field box so a control can carry an icon or affix. |
|
|
19
|
+
| `.textarea` | Textarea control styling. |
|
|
20
|
+
| `.select` | Select control styling. |
|
|
21
|
+
| `input[type="checkbox"].checkbox` | Custom checkbox control styling. |
|
|
22
|
+
| `input[type="radio"].radio` | Custom radio control styling. |
|
|
23
|
+
| `input[type="checkbox"].switch` | Custom switch control styling. |
|
|
24
|
+
| `[aria-invalid="true"]` on controls | Destructive border and focus color. |
|
|
25
|
+
| `[disabled]`, `[aria-disabled="true"]`, `[data-disabled]` on controls | Disabled styling. |
|
|
25
26
|
|
|
26
27
|
## Icons
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
`background-image` — a `data:` URI, which cannot read `currentColor` or a
|
|
30
|
-
custom property, so every glyph shipped a light and a dark copy and a theme
|
|
31
|
-
selector chose between them. That put icon artwork, and the package's only
|
|
32
|
-
theme-by-selector branch, inside a CSS-only design system whose glyphs did
|
|
33
|
-
not fit every aesthetic. Icons are the consumer's to choose now.
|
|
29
|
+
No icon is shipped for text inputs — that's what this section covers. It used to paint one per input type as a `background-image` — a `data:` URI, which cannot read `currentColor` or a custom property, so every glyph shipped a light and a dark copy and a theme selector chose between them. That put icon artwork, and the package's only theme-by-selector branch, inside a CSS-only design system whose glyphs did not fit every aesthetic. Icons for `.input-group` are the consumer's to choose now.
|
|
34
30
|
|
|
35
|
-
`.
|
|
36
|
-
|
|
37
|
-
and the control inside it goes flush, so the boundary is drawn once. Any
|
|
38
|
-
icon element works, placed before the control for a leading icon or after it
|
|
39
|
-
for a trailing one: an inline `<svg>`, an `<img>`, or a class from an icon
|
|
40
|
-
set such as `@codenhub/icons`.
|
|
31
|
+
This is separate from the toggle marks below, which stay small, fixed, built-in glyphs. `.alert`'s icon followed the same path since — see [Feedback → Icon](./feedback.md#example) — the package no longer paints one there either.
|
|
32
|
+
|
|
33
|
+
`.input-group` is the wrapper for a control that carries one. It owns the field box — border, radius, fill, focus ring, invalid and disabled state — and the control inside it goes flush, so the boundary is drawn once. Any icon element works, placed before the control for a leading icon or after it for a trailing one: an inline `<svg>`, an `<img>`, or a class from an icon set such as `@codenhub/icons`.
|
|
41
34
|
|
|
42
35
|
```html
|
|
43
36
|
<label class="field">
|
|
@@ -59,22 +52,24 @@ set such as `@codenhub/icons`.
|
|
|
59
52
|
</label>
|
|
60
53
|
```
|
|
61
54
|
|
|
62
|
-
The group reads intent and both [presentation](./composing.md#presentation)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
55
|
+
The group reads intent and both [presentation](./composing.md#presentation) axes the same way a lone `.ipt` does — `.input-group.soft.edgeless` is the sunk variant, `.input-group.primary` colors the boundary — and follows whichever [aesthetic](./aesthetics.md) is in scope. `aria-invalid` or `disabled` on the control inside propagates to the group; so does either on the group itself. Focus is shown with `:focus-within`, so unlike a lone field the ring also appears on a mouse click.
|
|
56
|
+
|
|
57
|
+
Non-icon input types keep the browser's native `date` and `datetime-local` pickers. WebKit's native `search` decorations are still suppressed on `.text-control` to keep them from overlapping the value.
|
|
58
|
+
|
|
59
|
+
The slot works the same way for a text affix — a URL host, a currency symbol, a unit — not just an icon:
|
|
60
|
+
|
|
61
|
+
```html
|
|
62
|
+
<div class="input-group">
|
|
63
|
+
<span>example.com/</span>
|
|
64
|
+
<input class="ipt" type="text" />
|
|
65
|
+
</div>
|
|
66
|
+
```
|
|
69
67
|
|
|
70
|
-
|
|
71
|
-
pickers. WebKit's native `search` decorations are still suppressed on
|
|
72
|
-
`.text-control` to keep them from overlapping the value.
|
|
68
|
+
The gap between the control and its adornment is `--input-group-gap`, `0.5rem` by default: the right amount of breathing room for a distinct icon glyph, and too much for text meant to read as glued to the value — `example.com/` followed by a gap reads as a stray space breaking the path apart. Set `--input-group-gap: 0` on the group for a flush affix; icon compositions keep the default unchanged.
|
|
73
69
|
|
|
74
70
|
## Toggles
|
|
75
71
|
|
|
76
|
-
`.checkbox`, `.radio`, and `.switch` accept the same intent classes as
|
|
77
|
-
buttons to set the checked color:
|
|
72
|
+
`.checkbox`, `.radio`, and `.switch` accept the same intent classes as buttons to set the checked color:
|
|
78
73
|
|
|
79
74
|
| Class | Meaning |
|
|
80
75
|
| ----------------------------------- | ----------------------- |
|
|
@@ -86,39 +81,21 @@ buttons to set the checked color:
|
|
|
86
81
|
| `.destructive`, `.danger`, `.error` | Destructive color. |
|
|
87
82
|
| `.info` | Info color. |
|
|
88
83
|
|
|
89
|
-
All three toggles rest at `.
|
|
90
|
-
them.** An unchecked ghost toggle is the silhouette every toggle already
|
|
91
|
-
has, and a checked one is a mark on nothing — a tick floating on the page, a
|
|
92
|
-
dot with no ring around it. A container that cascades `.ghost` onto a
|
|
93
|
-
toggle is floored rather than obeyed.
|
|
94
|
-
|
|
95
|
-
Presentation decides the fill in both states. Being checked lifts the cap
|
|
96
|
-
rather than pinning a fill, so the class still chooses:
|
|
84
|
+
All three toggles rest at `.soft`. Presentation decides the _unchecked_ plate; checked is pinned to one look regardless of which class is on the element, so a checkbox, a radio, and a switch each have a single "on" identity rather than one per presentation:
|
|
97
85
|
|
|
98
|
-
| Toggle
|
|
99
|
-
|
|
|
100
|
-
| `.
|
|
101
|
-
| `.soft
|
|
86
|
+
| Toggle | unchecked | checked |
|
|
87
|
+
| ---------------- | --------- | ---------------------------------------- |
|
|
88
|
+
| `.ghost` | 0% | 100%, mark in the contrast tone (pinned) |
|
|
89
|
+
| `.soft`, default | 12% | 100%, mark in the contrast tone (pinned) |
|
|
90
|
+
| `.solid` | 40% | 100%, mark in the contrast tone (pinned) |
|
|
102
91
|
|
|
103
|
-
A checked checkbox and a checked switch cut their mark out of that plate. A
|
|
104
|
-
checked radio thickens its ring to twice the resting line and takes the
|
|
105
|
-
intent whole on it, so `.radio.soft` is the classic ring-and-dot radio and
|
|
106
|
-
`.radio.solid` is a filled circle whose dot stays readable — the mark
|
|
107
|
-
follows the plate rather than being pinned to the intent color.
|
|
92
|
+
A checked checkbox and a checked switch cut their mark out of that pinned plate. A checked radio thickens its ring to twice the resting line and takes the intent whole on it, and the dot follows the same pinned plate, so `.radio.soft` and `.radio.solid` render the same filled circle once checked — presentation only changes what the radio looks like before it's picked.
|
|
108
93
|
|
|
109
94
|
## Text controls
|
|
110
95
|
|
|
111
|
-
Text controls also take intent, which colors the resting border and the
|
|
112
|
-
focus-visible border, and both [presentation](./composing.md#presentation)
|
|
113
|
-
axes. `.ghost` fills nothing, `.soft` takes `12%`, and `.solid` takes `20%`
|
|
114
|
-
— quiet enough that typed text still reads on it, and ordered so the louder
|
|
115
|
-
name draws the stronger tint. None of them touches the line.
|
|
96
|
+
Text controls also take intent, which colors the resting border and the focus-visible border, and both [presentation](./composing.md#presentation) axes. `.ghost` fills nothing, `.soft` takes `12%`, and `.solid` takes `20%` — quiet enough that typed text still reads on it, and ordered so the louder name draws the stronger tint. None of them touches the line.
|
|
116
97
|
|
|
117
|
-
The boundary is the edge axis's, and it splits the same way. A container's
|
|
118
|
-
`.edgeless` is floored, so a toolbar cannot leave a field with no mark of
|
|
119
|
-
where typing goes. `.edgeless` on the control itself is honoured, which is
|
|
120
|
-
how the borderless field is spelled — it does not meet WCAG 1.4.11 at rest,
|
|
121
|
-
so it is opt-in and never a default, and the focus ring still shows.
|
|
98
|
+
The boundary is the edge axis's, and it splits the same way. A container's `.edgeless` is floored, so a toolbar cannot leave a field with no mark of where typing goes. `.edgeless` on the control itself is honoured, which is how the borderless field is spelled — it does not meet WCAG 1.4.11 at rest, so it is opt-in and never a default, and the focus ring still shows.
|
|
122
99
|
|
|
123
100
|
```html
|
|
124
101
|
<input class="ipt success" placeholder="Valid" />
|
|
@@ -133,11 +110,7 @@ so it is opt-in and never a default, and the focus ring still shows.
|
|
|
133
110
|
</div>
|
|
134
111
|
```
|
|
135
112
|
|
|
136
|
-
`.surface` is a public low-level utility. It is the box every container in
|
|
137
|
-
the package composes: ghost, edged, surface radius, and the two slots only
|
|
138
|
-
a surface resolves — the backdrop filter and the complete surface shadow.
|
|
139
|
-
Use it to paint a container the package does not ship, under whichever
|
|
140
|
-
aesthetic is in scope. Prefer `.card` or `.panel` when they fit.
|
|
113
|
+
`.surface` is a public low-level utility. It is the box every container in the package composes: ghost, edged, surface radius, and the two slots only a surface resolves — the backdrop filter and the complete surface shadow. Use it to paint a container the package does not ship, under whichever aesthetic is in scope. Prefer `.card` or `.panel` when they fit.
|
|
141
114
|
|
|
142
115
|
```html
|
|
143
116
|
<div class="surface glass">Blurred, translucent, glass corners</div>
|
|
@@ -145,11 +118,7 @@ aesthetic is in scope. Prefer `.card` or `.panel` when they fit.
|
|
|
145
118
|
<div class="surface primary solid">Any intent, any presentation</div>
|
|
146
119
|
```
|
|
147
120
|
|
|
148
|
-
`.text-control` is a public low-level utility from the form entrypoint. It
|
|
149
|
-
provides the shared control dimensions, border, placeholder, focus-visible,
|
|
150
|
-
invalid, and disabled styles composed by `ipt`, `textarea`, and `select`.
|
|
151
|
-
Use it for custom text-like controls; prefer those higher-level utilities
|
|
152
|
-
when they fit.
|
|
121
|
+
`.text-control` is a public low-level utility from the form entrypoint. It provides the shared control dimensions, border, placeholder, focus-visible, invalid, and disabled styles composed by `ipt`, `textarea`, and `select`. Use it for custom text-like controls; prefer those higher-level utilities when they fit.
|
|
153
122
|
|
|
154
123
|
## Example
|
|
155
124
|
|
|
@@ -173,5 +142,4 @@ when they fit.
|
|
|
173
142
|
</label>
|
|
174
143
|
```
|
|
175
144
|
|
|
176
|
-
Use labels, `type`, validation logic, `aria-describedby`, and error message
|
|
177
|
-
relationships; see [Accessibility](../accessibility.md).
|
|
145
|
+
Use labels, `type`, validation logic, `aria-describedby`, and error message relationships; see [Accessibility](../accessibility.md).
|
package/docs/usage/index.md
CHANGED
|
@@ -1,32 +1,24 @@
|
|
|
1
1
|
---
|
|
2
|
-
title:
|
|
2
|
+
title: Overview
|
|
3
3
|
description: Guides for composing axes, theming, customizing, aesthetics, and each component family.
|
|
4
|
+
group: Usage
|
|
5
|
+
order: 3
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Usage
|
|
7
9
|
|
|
8
|
-
These guides assume the [Concepts](../concepts.md) mental model: intent,
|
|
9
|
-
presentation, and aesthetic as three independent axes, resolved through
|
|
10
|
-
tokens a component reads.
|
|
10
|
+
These guides assume the [Concepts](../concepts.md) mental model: intent, presentation, and aesthetic as three independent axes, resolved through tokens a component reads.
|
|
11
11
|
|
|
12
|
-
- [Composing](./composing.md): Combining the three axes on a component, the
|
|
13
|
-
axis-support matrix, and elevation modifiers.
|
|
12
|
+
- [Composing](./composing.md): Combining the three axes on a component, the axis-support matrix, and elevation modifiers.
|
|
14
13
|
- [Theming](./theming.md): The color, intent, and foundation token reference.
|
|
15
|
-
- [Customizing](./customizing.md): The presentation and material token
|
|
16
|
-
|
|
17
|
-
- [Aesthetics](./aesthetics.md): Each shipped aesthetic in depth, including
|
|
18
|
-
its documented exceptions.
|
|
14
|
+
- [Customizing](./customizing.md): The presentation and material token reference, aesthetic knobs, and defining a custom intent.
|
|
15
|
+
- [Aesthetics](./aesthetics.md): Each shipped aesthetic in depth, including its documented exceptions.
|
|
19
16
|
- [Buttons](./buttons.md)
|
|
20
17
|
- [Forms](./forms.md)
|
|
21
18
|
- [Feedback](./feedback.md)
|
|
22
19
|
- [Tooltips](./tooltips.md)
|
|
23
|
-
- [Content and layout](./content-and-layout.md): Layout helpers, tables,
|
|
24
|
-
quotes, code, surfaces, and typography utilities.
|
|
20
|
+
- [Content and layout](./content-and-layout.md): Layout helpers, tables, quotes, code, surfaces, and typography utilities.
|
|
25
21
|
|
|
26
22
|
## Supported surface
|
|
27
23
|
|
|
28
|
-
A class, component, and axis combination is supported when this documentation
|
|
29
|
-
describes it and the package playground demonstrates it. Undocumented and
|
|
30
|
-
undemonstrated combinations may still produce CSS, but are not maintained
|
|
31
|
-
behavior. Playground variant matrices are the exhaustive demonstrations; small
|
|
32
|
-
examples elsewhere illustrate usage without widening that contract.
|
|
24
|
+
A class, component, and axis combination is supported when this documentation describes it and the package playground demonstrates it. Undocumented and undemonstrated combinations may still produce CSS, but are not maintained behavior. Playground variant matrices are the exhaustive demonstrations; small examples elsewhere illustrate usage without widening that contract.
|
package/docs/usage/theming.md
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Theming
|
|
3
3
|
description: The color, intent, and foundation token reference.
|
|
4
|
+
order: 2
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# Theming
|
|
7
8
|
|
|
8
|
-
Color tokens are how you restyle the palette; see
|
|
9
|
-
[Concepts → Theme selection](../concepts.md#theme-selection) for how a theme
|
|
10
|
-
is chosen. Intent tokens are how a component reads that palette once an
|
|
11
|
-
intent class is applied. Foundation tokens are the shared layout, shape, and
|
|
12
|
-
motion defaults underneath everything.
|
|
9
|
+
Color tokens are how you restyle the palette; see [Concepts → Theme selection](../concepts.md#theme-selection) for how a theme is chosen. Intent tokens are how a component reads that palette once an intent class is applied. Foundation tokens are the shared layout, shape, and motion defaults underneath everything.
|
|
13
10
|
|
|
14
11
|
## Color tokens
|
|
15
12
|
|
|
16
|
-
Each color token holds both of its theme values at once through
|
|
17
|
-
|
|
13
|
+
Each color token holds both of its theme values at once through `light-dark()`, and the element's `color-scheme` picks one.
|
|
14
|
+
|
|
15
|
+
Every row is an override point: set it on `:root` to retheme globally, or on any element to retheme that subtree. The `-hover`, `-subtle`, `-strong`, and `-contrast` rows are companion tones wired into the intent slots, so overriding a base color such as `--color-primary` on its own does not shift its companions — retheme the whole family. The `text` family has no `-subtle` row: the neutral intent draws its subtle tone from `--color-surface`.
|
|
18
16
|
|
|
19
17
|
```html
|
|
20
18
|
<section data-theme="dark">
|
|
@@ -44,7 +42,6 @@ Each color token holds both of its theme values at once through
|
|
|
44
42
|
| `--color-text-secondary` | Secondary text color. |
|
|
45
43
|
| `--color-text-contrast` | Readable color on top of a full fill of `--color-text`. A checked toggle prints it. |
|
|
46
44
|
| `--color-text-hover` | Text hover state. |
|
|
47
|
-
| `--color-text-subtle` | Low-emphasis companion tone for text. Use as soft surface or subtle background. |
|
|
48
45
|
| `--color-text-strong` | High-emphasis companion tone for text. Use as readable text, icon, or border on subtle surfaces. |
|
|
49
46
|
| `--color-tooltip` | Tooltip bubble plate with no intent. Chosen per theme rather than derived: near-white in light, mid grey in dark. |
|
|
50
47
|
| `--color-tooltip-contrast` | Ink on `--color-tooltip`. |
|
|
@@ -69,20 +66,11 @@ Each color token holds both of its theme values at once through
|
|
|
69
66
|
| `--color-info-subtle` | Low-emphasis companion tone for info. |
|
|
70
67
|
| `--color-info-strong` | High-emphasis companion tone for info. |
|
|
71
68
|
|
|
72
|
-
> **Intent token contract**: color intent tokens own meaning and tone
|
|
73
|
-
> variants. Intent classes map one family onto the shared intent slots below,
|
|
74
|
-
> and presentation classes decide how much of it a component shows. Theme
|
|
75
|
-
> changes belong in token values, not broad component-level theme checks.
|
|
76
|
-
> Component-level theme handling should exist only when a component has an
|
|
77
|
-
> internal structure that cannot be expressed through the token palette
|
|
78
|
-
> alone.
|
|
69
|
+
> **Intent token contract**: color intent tokens own meaning and tone variants. Intent classes map one family onto the shared intent slots below, and presentation classes decide how much of it a component shows. Theme changes belong in token values, not broad component-level theme checks. Component-level theme handling should exist only when a component has an internal structure that cannot be expressed through the token palette alone.
|
|
79
70
|
|
|
80
71
|
## Intent tokens
|
|
81
72
|
|
|
82
|
-
Intent classes set these seven slots; components read them. Because every
|
|
83
|
-
supporting component reads the same seven names, an intent works on every
|
|
84
|
-
component that supports intent, and a custom intent needs no component
|
|
85
|
-
changes.
|
|
73
|
+
Intent classes set these seven slots; components read them. Because every supporting component reads the same seven names, an intent works on every component that supports intent, and a custom intent needs no component changes.
|
|
86
74
|
|
|
87
75
|
| Token | Purpose |
|
|
88
76
|
| ------------------- | ------------------------------------------------------------------------------------- |
|
|
@@ -94,49 +82,19 @@ changes.
|
|
|
94
82
|
| `--intent-border` | Line color. Resolves to `--color-border` when no intent is set. |
|
|
95
83
|
| `--intent-fill-max` | How far a fill of this intent is allowed to go. `100%` for every intent but neutral. |
|
|
96
84
|
|
|
97
|
-
`--intent-color` and `--intent-strong` are two ends of the same family and not
|
|
98
|
-
|
|
99
|
-
tone is
|
|
100
|
-
|
|
101
|
-
rather than the
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
the
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
`--intent-border` exists because a neutral border must stay the quiet border
|
|
112
|
-
gray rather than the text color. Everything that draws a line reads it:
|
|
113
|
-
control borders, table rules, dividers, key caps, and quote bars.
|
|
114
|
-
|
|
115
|
-
`--intent-fill-max` exists for the neutral intent, whose color is the page's
|
|
116
|
-
own ink. Every other intent is a hue, legible pale at 12% and saturated at
|
|
117
|
-
100%; a grey filled to 100% is a black or white slab, which is the loudest
|
|
118
|
-
thing on the page and the wrong look for the intent that means _nothing in
|
|
119
|
-
particular_. Neutral stops at `20%`, so `.solid` gives it a quiet plate that
|
|
120
|
-
still reads as a step past `.soft`. Hover adds its step on top of the cap, so
|
|
121
|
-
a capped fill still deepens under the pointer.
|
|
122
|
-
|
|
123
|
-
The foreground is gated by the plate rather than tied to the fill.
|
|
124
|
-
`--intent-contrast` is the ink for a _full_ fill, so printing it at full
|
|
125
|
-
strength on a fifth of one puts white on light grey. Contrast ink therefore
|
|
126
|
-
appears only once the fill is past halfway and reaches full at a full fill;
|
|
127
|
-
below that a component prints `--intent-strong`, the tone chosen to be read.
|
|
128
|
-
|
|
129
|
-
That means a capped neutral takes the strong tone whole rather than a
|
|
130
|
-
fraction of the way toward the page. Tying it to the fill instead cost a
|
|
131
|
-
neutral `.solid` button four points of contrast and a neutral tooltip nearly
|
|
132
|
-
ten. A state that lifts the cap on purpose — a checked checkbox is filled
|
|
133
|
-
with its own intent by definition — reaches a full fill and gets the contrast
|
|
134
|
-
whole.
|
|
135
|
-
|
|
136
|
-
Set them directly to define an intent this package does not ship. **State
|
|
137
|
-
every slot**, including `--intent-fill-max`: components reset all seven to
|
|
138
|
-
the neutral values, so a slot your intent leaves out keeps neutral's — and an
|
|
139
|
-
intent that omits the cap fills to 20% of its color instead of 100%.
|
|
85
|
+
`--intent-color` and `--intent-strong` are two ends of the same family and not interchangeable. The base is a ground, chosen to be filled with; the strong tone is chosen to be read against a page. A `.soft` or `.ghost` component prints the strong one, which is why an unfilled warning reads in amber-800 rather than the amber-600 its solid sibling is filled with.
|
|
86
|
+
|
|
87
|
+
The strong tone has to stay recognisably its own hue, not just readable. On a dark page the `-100` shade of every family is a pale tint that carries almost no chroma at small sizes: a soft success badge and a soft destructive one printed labels that both read white, and a soft radio's dot stopped matching the ring around it. The dark tones are `-300` for that reason, and the tinted grounds under them are `-900` so there is room — measured at 5.0:1 or better everywhere a partial fill prints text, and past 9:1 on the page.
|
|
88
|
+
|
|
89
|
+
`--intent-border` exists because a neutral border must stay the quiet border gray rather than the text color. Everything that draws a line reads it: control borders, table rules, dividers, key caps, and quote bars.
|
|
90
|
+
|
|
91
|
+
`--intent-fill-max` exists for the neutral intent, whose color is the page's own ink. Every other intent is a hue, legible pale at 12% and saturated at 100%; a grey filled to 100% is a black or white slab, which is the loudest thing on the page and the wrong look for the intent that means _nothing in particular_. Neutral stops at `20%`, so `.solid` gives it a quiet plate that still reads as a step past `.soft`. Hover adds its step on top of the cap, so a capped fill still deepens under the pointer.
|
|
92
|
+
|
|
93
|
+
The foreground is gated by the plate rather than tied to the fill. `--intent-contrast` is the ink for a _full_ fill, so printing it at full strength on a fifth of one puts white on light grey. Contrast ink therefore appears only once the fill is past halfway and reaches full at a full fill; below that a component prints `--intent-strong`, the tone chosen to be read.
|
|
94
|
+
|
|
95
|
+
That means a capped neutral takes the strong tone whole rather than a fraction of the way toward the page. Tying it to the fill instead cost a neutral `.solid` button four points of contrast and a neutral tooltip nearly ten. A state that lifts the cap on purpose — a checked checkbox is filled with its own intent by definition — reaches a full fill and gets the contrast whole.
|
|
96
|
+
|
|
97
|
+
Set them directly to define an intent this package does not ship. **State every slot**, including `--intent-fill-max`: components reset all seven to the neutral values, so a slot your intent leaves out keeps neutral's — and an intent that omits the cap fills to 20% of its color instead of 100%.
|
|
140
98
|
|
|
141
99
|
```css
|
|
142
100
|
.brand {
|
|
@@ -151,29 +109,16 @@ intent that omits the cap fills to 20% of its color instead of 100%.
|
|
|
151
109
|
```
|
|
152
110
|
|
|
153
111
|
```html
|
|
154
|
-
<button class="btn brand">Custom intent</button>
|
|
155
|
-
<span class="badge brand soft">Works everywhere</span>
|
|
112
|
+
<button class="btn brand">Custom intent</button> <span class="badge brand soft">Works everywhere</span>
|
|
156
113
|
```
|
|
157
114
|
|
|
158
|
-
> **Intent does not cascade.** Components reset these slots to the text
|
|
159
|
-
> palette at their own root, so a `.success` container never recolors a
|
|
160
|
-
> nested destructive button. Put the intent class on the element that shows
|
|
161
|
-
> the intent.
|
|
115
|
+
> **Intent does not cascade.** Components reset these slots to the text palette at their own root, so a `.success` container never recolors a nested destructive button. Put the intent class on the element that shows the intent.
|
|
162
116
|
|
|
163
117
|
## Foundation tokens
|
|
164
118
|
|
|
165
|
-
Foundation tokens are not aliases for one color. They define layout, shape,
|
|
166
|
-
motion, focus, depth, and layering behavior used by helper classes.
|
|
119
|
+
Foundation tokens are not aliases for one color. They define layout, shape, motion, focus, depth, and layering behavior used by helper classes.
|
|
167
120
|
|
|
168
|
-
The four `--elevation-*` values below are raw shadows for elements you style
|
|
169
|
-
yourself. They are a separate thing from `.elevation-none`/`.elevation-sm`/
|
|
170
|
-
`.elevation-md` (aliased as `.flat`/`.raised`/`.floating`), which scale a
|
|
171
|
-
_component's own_ shadow geometry and default to no shadow at all until an
|
|
172
|
-
aesthetic or one of those classes asks for depth — see
|
|
173
|
-
[Composing → Elevation](./composing.md#elevation) for that system. The two
|
|
174
|
-
share `none`/`sm`/`md`/`lg` naming for the same weight of depth, but one is a
|
|
175
|
-
fixed value and the other multiplies shadow parts, so they will not always
|
|
176
|
-
paint identically.
|
|
121
|
+
The four `--elevation-*` values below are raw shadows for elements you style yourself. They are a separate thing from `.elevation-none`/`.elevation-sm`/ `.elevation-md` (aliased as `.flat`/`.raised`/`.floating`), which scale a _component's own_ shadow geometry and default to no shadow at all until an aesthetic or one of those classes asks for depth — see [Composing → Elevation](./composing.md#elevation) for that system. The two share `none`/`sm`/`md`/`lg` naming for the same weight of depth, but one is a fixed value and the other multiplies shadow parts, so they will not always paint identically.
|
|
177
122
|
|
|
178
123
|
| Token | Purpose |
|
|
179
124
|
| -------------------------- | ----------------------------------------------------------------------- |
|
|
@@ -206,5 +151,4 @@ paint identically.
|
|
|
206
151
|
| `--breakpoint-xs` | Extra-small Tailwind responsive breakpoint. |
|
|
207
152
|
| `--breakpoint-2xl` | Extended large Tailwind responsive breakpoint. |
|
|
208
153
|
|
|
209
|
-
Next: [Customizing](./customizing.md) covers presentation and material
|
|
210
|
-
tokens — how much of an intent shows, and what a component is made of.
|
|
154
|
+
Next: [Customizing](./customizing.md) covers presentation and material tokens — how much of an intent shows, and what a component is made of.
|
package/docs/usage/tooltips.md
CHANGED
|
@@ -1,45 +1,65 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Tooltips
|
|
3
|
-
description: Tooltip
|
|
3
|
+
description: Tooltip composition classes and positioning attributes.
|
|
4
|
+
order: 8
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# Tooltips
|
|
7
8
|
|
|
8
|
-
| Class or Attribute
|
|
9
|
-
|
|
|
10
|
-
| `.tooltip`
|
|
11
|
-
| `.tooltip
|
|
12
|
-
|
|
|
13
|
-
| `[data-tooltip-position="
|
|
14
|
-
| `[data-tooltip-position="
|
|
15
|
-
| `[data-tooltip-position="
|
|
16
|
-
|
|
|
17
|
-
| `
|
|
18
|
-
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
The bubble rests flat. It draws no shadow of its own on a plain page, and
|
|
26
|
-
|
|
27
|
-
same way `.
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
still reaches the bubble as it reaches any surface.
|
|
9
|
+
| Class or Attribute | Purpose |
|
|
10
|
+
| -------------------------------------- | ------------------------------------------------------------------------ |
|
|
11
|
+
| `.tooltip` | Wrapper around a trigger and a bubble. Paints nothing itself. |
|
|
12
|
+
| `.tooltip-bubble` | The message. A real element, styled like any other surface. |
|
|
13
|
+
| `.tooltip-icon` | Circular icon-style trigger, for a message with nothing else to hang on. |
|
|
14
|
+
| `[data-tooltip-position="top"]` | Positions the bubble above the trigger, on `.tooltip`. |
|
|
15
|
+
| `[data-tooltip-position="bottom"]` | Positions the bubble below the trigger, on `.tooltip`. |
|
|
16
|
+
| `[data-tooltip-position="left"]` | Positions the bubble left of the trigger, on `.tooltip`. |
|
|
17
|
+
| `[data-tooltip-position="right"]` | Positions the bubble right of the trigger, on `.tooltip`. |
|
|
18
|
+
| No `data-tooltip-position` | Defaults to top placement. |
|
|
19
|
+
| `[data-state="open"]` | Shows the bubble without hover, on `.tooltip`. |
|
|
20
|
+
| `.tooltip-bubble.raised` / `.floating` | Adds one or two units of depth. The bubble is flat by default. |
|
|
21
|
+
|
|
22
|
+
A tooltip is composition, not a single class: `.tooltip` wraps a trigger element and a `.tooltip-bubble`, and shows the bubble on hover or focus within the wrapper. This replaced a `::after` pseudo-element that carried the message as `content: attr(data-tooltip)` — CSS generated content is not reliably exposed to assistive tech, and cannot be the target of an `aria-describedby`, since that needs a real element with a real `id`. A real bubble can be. Wire the association yourself: give the bubble an `id`, give the trigger `aria-describedby` pointing at it, and put `role="tooltip"` on the bubble.
|
|
23
|
+
|
|
24
|
+
A tooltip bubble's fill, ground color, and floor behavior are covered in [Composing → Presentation](./composing.md#presentation), and its material follows whichever [aesthetic](./aesthetics.md) is in scope. Intent, presentation, aesthetic, and elevation classes go on `.tooltip-bubble` — the element that actually paints — not on `.tooltip`, the same rule every component in this package follows: put the class on the element that shows it.
|
|
25
|
+
|
|
26
|
+
The bubble rests flat. It draws no shadow of its own on a plain page, and zeroes an aesthetic's part-based depth (such as `.neobrutalism`'s slab) the same way `.flat` does elsewhere. Add [`.raised` or `.floating`](./composing.md#elevation) to lift it, on the bubble itself — `.tooltip-bubble.floating` is the pre-0.1.0 look. An aesthetic whose shadow is a complete value, like `.glass`, still reaches the bubble as it reaches any surface.
|
|
27
|
+
|
|
28
|
+
Intent works on a tooltip bubble the same way it works on a filled component: `.tooltip-bubble.primary` fills the bubble with the primary color, black text on a light page and white on a dark one; `.tooltip-bubble.destructive` is a red bubble with the same logic. With no intent, the bubble uses `--color-tooltip`, a plate chosen per theme rather than derived from an intent; see [Composing → Presentation](./composing.md#presentation) for why.
|
|
29
|
+
|
|
30
|
+
## Example
|
|
31
31
|
|
|
32
32
|
```html
|
|
33
|
-
<
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
>
|
|
39
|
-
|
|
40
|
-
</
|
|
33
|
+
<span class="tooltip">
|
|
34
|
+
<button aria-describedby="status-bubble">Status</button>
|
|
35
|
+
<span class="tooltip-bubble" role="tooltip" id="status-bubble">Saved 2 minutes ago</span>
|
|
36
|
+
</span>
|
|
37
|
+
|
|
38
|
+
<span class="tooltip" data-tooltip-position="bottom">
|
|
39
|
+
<button aria-describedby="docs-bubble">Docs</button>
|
|
40
|
+
<span class="tooltip-bubble" role="tooltip" id="docs-bubble">Opens in a new tab</span>
|
|
41
|
+
</span>
|
|
42
|
+
|
|
43
|
+
<span class="tooltip">
|
|
44
|
+
<button class="btn primary" aria-describedby="deploy-bubble">Deploy</button>
|
|
45
|
+
<span class="tooltip-bubble raised primary" role="tooltip" id="deploy-bubble">Primary intent, lifted a step</span>
|
|
46
|
+
</span>
|
|
47
|
+
|
|
48
|
+
<span class="tooltip" data-state="open">
|
|
49
|
+
<span aria-describedby="pinned-bubble">Pinned</span>
|
|
50
|
+
<span class="tooltip-bubble" role="tooltip" id="pinned-bubble">Always visible, no hover needed</span>
|
|
51
|
+
</span>
|
|
52
|
+
|
|
53
|
+
<span class="tooltip" data-tooltip-position="right">
|
|
54
|
+
<span class="tooltip-icon" tabindex="0" aria-label="More details" aria-describedby="icon-bubble">?</span>
|
|
55
|
+
<span class="tooltip-bubble" role="tooltip" id="icon-bubble">More details</span>
|
|
56
|
+
</span>
|
|
41
57
|
```
|
|
42
58
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
59
|
+
The first two show plain triggers with default (top) and explicit bottom placement. The third combines an intent with `.raised` on the bubble to show they compose freely — the intent decides the bubble's fill, `.raised` decides whether it casts depth. The fourth uses `data-state="open"` on the wrapper to keep a tooltip visible without a hover or focus interaction, useful for a tooltip that should be demonstrated or tested without simulating pointer input. The fifth uses `.tooltip-icon` as the trigger, for a message with no other element to hang it on.
|
|
60
|
+
|
|
61
|
+
`.tooltip` composes with any trigger: wrap an existing `.btn` or `.badge` in it and both keep their own look, gaining a bubble beside them. `.tooltip-icon` is only the circular chip for the case where there is nothing else to be the trigger.
|
|
62
|
+
|
|
63
|
+
Showing and hiding the bubble is CSS-only — `:hover` and `:focus-within` on `.tooltip` — but that is presentational. It is not a complete accessible tooltip implementation by itself: provide the `id`/`aria-describedby`/`role="tooltip"` association outside the CSS; see [Accessibility](../accessibility.md).
|
|
64
|
+
|
|
65
|
+
Next: [Content and layout](./content-and-layout.md) covers layout helpers, content chips and tables, surfaces, and typography utilities.
|