@codenhub/styles 0.7.0 → 0.9.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.es.md +9 -8
- package/README.md +8 -7
- package/README.pt-BR.md +9 -8
- 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/cli.js +358 -0
- package/dist/components.css +50 -2
- package/dist/index.css +50 -2
- package/dist/index.d.ts +1 -0
- package/dist/native.css +50 -2
- package/dist/palette.css +1 -1
- package/dist/purge/classes.json +1 -0
- package/dist/purge/index.css +50 -0
- package/dist/theme.css +2 -2
- package/docs/accessibility.md +46 -27
- package/docs/changelog/0.8.0.md +70 -0
- package/docs/changelog/0.9.0.md +40 -0
- package/docs/changelog/index.md +2 -0
- package/docs/es/accessibility.md +47 -28
- package/docs/es/index.md +4 -3
- package/docs/es/integrating/index.md +38 -10
- package/docs/es/integrating/tailwind.md +79 -8
- package/docs/es/integrating/without-a-bundler.md +157 -5
- package/docs/es/setup.md +43 -34
- package/docs/es/usage/aesthetics.md +20 -14
- package/docs/es/usage/buttons.md +6 -2
- package/docs/es/usage/composing.md +6 -2
- package/docs/es/usage/content-and-layout.md +10 -4
- package/docs/es/usage/customizing.md +46 -26
- package/docs/es/usage/feedback.md +5 -1
- package/docs/es/usage/forms.md +30 -5
- package/docs/es/usage/index.md +7 -3
- package/docs/es/usage/presets.md +92 -0
- package/docs/es/usage/solo.md +4 -2
- package/docs/es/usage/theming.md +29 -16
- package/docs/es/usage/tooltips.md +2 -2
- package/docs/index.md +3 -2
- package/docs/integrating/index.md +38 -10
- package/docs/integrating/tailwind.md +78 -7
- package/docs/integrating/without-a-bundler.md +156 -4
- package/docs/pt-BR/accessibility.md +47 -28
- package/docs/pt-BR/index.md +4 -3
- package/docs/pt-BR/integrating/index.md +38 -10
- package/docs/pt-BR/integrating/tailwind.md +79 -8
- package/docs/pt-BR/integrating/without-a-bundler.md +157 -5
- package/docs/pt-BR/setup.md +43 -34
- package/docs/pt-BR/usage/aesthetics.md +20 -14
- package/docs/pt-BR/usage/buttons.md +6 -2
- package/docs/pt-BR/usage/composing.md +6 -2
- package/docs/pt-BR/usage/content-and-layout.md +10 -4
- package/docs/pt-BR/usage/customizing.md +46 -26
- package/docs/pt-BR/usage/feedback.md +5 -1
- package/docs/pt-BR/usage/forms.md +30 -5
- package/docs/pt-BR/usage/index.md +7 -3
- package/docs/pt-BR/usage/presets.md +92 -0
- package/docs/pt-BR/usage/solo.md +4 -2
- package/docs/pt-BR/usage/theming.md +22 -9
- package/docs/pt-BR/usage/tooltips.md +2 -2
- package/docs/setup.md +31 -22
- package/docs/usage/aesthetics.md +19 -13
- package/docs/usage/buttons.md +5 -1
- package/docs/usage/composing.md +5 -1
- package/docs/usage/content-and-layout.md +9 -3
- package/docs/usage/customizing.md +45 -25
- package/docs/usage/feedback.md +4 -0
- package/docs/usage/forms.md +29 -4
- package/docs/usage/index.md +6 -2
- package/docs/usage/presets.md +91 -0
- package/docs/usage/solo.md +3 -1
- package/docs/usage/theming.md +21 -8
- package/docs/usage/tooltips.md +1 -1
- package/llms-full.txt +695 -134
- package/llms.txt +3 -2
- package/package.json +117 -65
- package/{dist/tw → tw}/aesthetics/chunky-tile.css +43 -20
- package/{dist/tw → tw}/aesthetics/cyber.css +19 -25
- package/{dist/tw → tw}/aesthetics/glass.css +110 -36
- package/{dist/tw → tw}/aesthetics/neobrutalism.css +41 -21
- package/{dist/tw → tw}/aesthetics/pixel.css +3 -0
- package/tw/aesthetics/sketch.css +435 -0
- package/{dist/tw → tw}/box.css +109 -26
- package/tw/components/button.css +11 -0
- package/tw/components/button.rules.css +187 -0
- package/tw/components/feedback.css +11 -0
- package/{dist/tw/components/feedback.css → tw/components/feedback.rules.css} +156 -33
- package/tw/components/form.css +11 -0
- package/{dist/tw/components/form.css → tw/components/form.rules.css} +584 -141
- package/tw/components/index.css +16 -0
- package/tw/components/rules.css +41 -0
- package/tw/components/surface.css +11 -0
- package/tw/components/surface.rules.css +225 -0
- package/tw/components/tooltip.css +11 -0
- package/{dist/tw/components/tooltip.css → tw/components/tooltip.rules.css} +82 -61
- package/{dist/tw → tw}/corner.css +18 -12
- package/{dist/tw → tw}/elevation.css +27 -21
- package/{dist/tw → tw}/index.css +11 -9
- package/tw/index.d.ts +1 -0
- package/tw/intent.css +312 -0
- package/tw/modifiers.css +127 -0
- package/tw/native.css +323 -0
- package/tw/presentation.css +139 -0
- package/tw/reset.css +10 -0
- package/{dist/tw/reset.css → tw/reset.rules.css} +7 -8
- package/tw/size.css +34 -0
- package/tw/surface.css +9 -0
- package/tw/surface.rules.css +212 -0
- package/{dist/tw → tw}/theme.css +93 -29
- package/tw/typography.css +8 -0
- package/{dist/tw/typography.css → tw/typography.rules.css} +0 -3
- package/{dist/tw → tw}/utilities/content.css +248 -108
- package/tw/utilities/index.css +11 -0
- package/tw/utilities/layout.css +210 -0
- package/tw/utilities/rules.css +8 -0
- package/dist/tw/aesthetics/sketch.css +0 -398
- package/dist/tw/components/button.css +0 -139
- package/dist/tw/components/index.css +0 -35
- package/dist/tw/components/surface.css +0 -184
- package/dist/tw/intent.css +0 -229
- package/dist/tw/native.css +0 -203
- package/dist/tw/palette.css +0 -460
- package/dist/tw/presentation.css +0 -68
- package/dist/tw/surface.css +0 -61
- package/dist/tw/utilities/index.css +0 -6
- package/dist/tw/utilities/layout.css +0 -144
- /package/{dist/tw → tw}/aesthetics/index.css +0 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/* The layer map, stated before any import uses a layer -- see `theme.css`.
|
|
2
|
+
Tailwind's utilities are imported into `utilities` the way
|
|
3
|
+
`tailwindcss/index.css` does it, so every component lands there on this
|
|
4
|
+
entrypoint and on `/native` too, exactly where `.` already puts them. Without
|
|
5
|
+
`layer(utilities)` the CLI emitted them unlayered here, and they beat every
|
|
6
|
+
consumer rule on these two entries alone. */
|
|
7
|
+
@layer theme, base, components, utilities;
|
|
8
|
+
|
|
9
|
+
/* The theme first, as `native.css` has it: Tailwind writes the theme's
|
|
10
|
+
variables at the first `@theme` it meets. See docs/internal/model.md
|
|
11
|
+
(Which files import the theme). */
|
|
12
|
+
@import "../theme.css";
|
|
13
|
+
@import "tailwindcss/utilities.css" layer(utilities);
|
|
14
|
+
/* Everything that is not `src/` -- see the note in `index.css`. Keeps a class
|
|
15
|
+
name in a docs code fence from shipping as a real rule in `dist/components.css`. */
|
|
16
|
+
@import "./rules.css";
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/* Every component, with nothing they need to compile: the entry that imports
|
|
2
|
+
this file brings the theme and Tailwind once. `index.css` beside it is that
|
|
3
|
+
entry for `/components`; the complete stylesheet and `/native` are the
|
|
4
|
+
others. See docs/internal/model.md (One route to each utility). */
|
|
5
|
+
@import "../typography.rules.css";
|
|
6
|
+
|
|
7
|
+
/* `hidden` hides. The user agent says so at user-agent origin, which loses to
|
|
8
|
+
any author `display`, and every component sets one. The complete stylesheet
|
|
9
|
+
gets this rule from Tailwind's Preflight; this entry and `/native`, which
|
|
10
|
+
imports it, ship no Preflight, so a hidden `.btn` or `.card` stayed on the
|
|
11
|
+
page. Preflight's own rule, in the same layer, so the three entries agree. */
|
|
12
|
+
@layer base {
|
|
13
|
+
[hidden]:where(:not([hidden="until-found"])) {
|
|
14
|
+
display: none !important;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/* `box` and `surface` once each, then every component's rules: the focused
|
|
19
|
+
entries beside this file each bring their own reference to `box.css`, and
|
|
20
|
+
importing five of them stacked five copies of every `@apply box`. */
|
|
21
|
+
@import "../box.css";
|
|
22
|
+
@import "../surface.rules.css";
|
|
23
|
+
@import "./button.rules.css";
|
|
24
|
+
@import "./feedback.rules.css";
|
|
25
|
+
@import "./form.rules.css";
|
|
26
|
+
@import "./surface.rules.css";
|
|
27
|
+
@import "./tooltip.rules.css";
|
|
28
|
+
|
|
29
|
+
/* The composition utilities -- `box`, `box-hover`, `box-active`,
|
|
30
|
+
`text-control`, `surface`, `input-group` -- are `@utility` rules whose bodies
|
|
31
|
+
the content scan will not emit on its own. `box` and friends appear only as
|
|
32
|
+
`@utility` blocks and `@apply` targets; `text-control`, `surface` and
|
|
33
|
+
`input-group` appear only inside `:is()`/`:where()` argument lists in
|
|
34
|
+
`intent.css` and `form.css`, never as a selector of their own. Safelisting
|
|
35
|
+
all six makes the emission deliberate; the composition-body check in
|
|
36
|
+
`exports.test.ts` fails the build if one is dropped. `text-control` and
|
|
37
|
+
`surface` are also documented as consumer-usable on their own.
|
|
38
|
+
|
|
39
|
+
The list is for the compiled build only. `scripts/build-tw.mjs` strips it
|
|
40
|
+
from the `tw/` copy, so a `/tw` consumer's Tailwind emits just the classes
|
|
41
|
+
it finds in their files rather than every one named here. */
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
@reference "tailwindcss";
|
|
2
|
+
@import "../theme.css";
|
|
3
|
+
@import "../surface.css";
|
|
4
|
+
|
|
5
|
+
/* The focused entry: what the rules in `surface.rules.css` need to compile on their
|
|
6
|
+
own, then the rules. An aggregate entry imports the rules file directly and
|
|
7
|
+
supplies those needs once -- Tailwind stacks a `@utility` each time a file
|
|
8
|
+
that defines it is imported or referenced, so a second route to `box.css`
|
|
9
|
+
doubles every `@apply box`. See docs/internal/model.md (One route to each
|
|
10
|
+
utility). */
|
|
11
|
+
@import "./surface.rules.css";
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/* A ghost, edged container that takes one unit when depth is supplied. */
|
|
2
|
+
@utility card {
|
|
3
|
+
@layer families {
|
|
4
|
+
:where(&:not(.p-xs)) {
|
|
5
|
+
--_m-p-xs: initial;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
:where(&:not(.p-sm)) {
|
|
9
|
+
--_m-p-sm: initial;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
:where(&:not(.p-lg)) {
|
|
13
|
+
--_m-p-lg: initial;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
:where(&:not(.flush)) {
|
|
17
|
+
--_m-flush: initial;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/* The hover flag, raised by `interactive` and `hoverable` below. */
|
|
22
|
+
@layer families {
|
|
23
|
+
:where(&:not(.interactive, .hoverable)) {
|
|
24
|
+
--_m-hover: initial;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@apply surface;
|
|
29
|
+
|
|
30
|
+
/* After the `@apply`, not before: `surface` inlines its own resting geometry
|
|
31
|
+
at that point, so defaults written above it would be overridden by the very
|
|
32
|
+
utility they are meant to specialise. */
|
|
33
|
+
--_d-fill: 0%;
|
|
34
|
+
--_d-fg-on-fill: 0%;
|
|
35
|
+
--_d-border: 100%;
|
|
36
|
+
--_d-elevation: 1;
|
|
37
|
+
|
|
38
|
+
/* The padding steps and `flush`. Each raises a flag (`modifiers.css`) and
|
|
39
|
+
the lines below compute only while theirs is up, so `@apply card p-xs`
|
|
40
|
+
carries the step. `--_scale-pad` is the step `box` scales the corner
|
|
41
|
+
and the depth by; `flush` leaves it alone. */
|
|
42
|
+
--_xs-pad: var(--_m-p-xs) 0.5rem;
|
|
43
|
+
--_sm-pad: var(--_m-p-sm) 0.75rem;
|
|
44
|
+
--_lg-pad: var(--_m-p-lg) 2rem;
|
|
45
|
+
--_flush-pad: var(--_m-flush) 0px;
|
|
46
|
+
--_xs-scale: var(--_m-p-xs) 0.5;
|
|
47
|
+
--_sm-scale: var(--_m-p-sm) 0.75;
|
|
48
|
+
--_lg-scale: var(--_m-p-lg) 1.25;
|
|
49
|
+
--_scale-pad: var(--_lg-scale, var(--_sm-scale, var(--_xs-scale)));
|
|
50
|
+
|
|
51
|
+
padding: var(--_flush-pad, var(--_lg-pad, var(--_sm-pad, var(--_xs-pad, 1.25rem))));
|
|
52
|
+
|
|
53
|
+
/* A quiet neutral tint -- `.soft`, on the card or on a container -- rests
|
|
54
|
+
untinted instead of mixing its 12%: 12% of `--color-text` onto any of
|
|
55
|
+
`--color-background`, `--color-foreground`, or `--color-surface` lands
|
|
56
|
+
within a few units of the others (a near-black ink dominates the result),
|
|
57
|
+
so swapping the ground token alone does not read as quieter. A resting
|
|
58
|
+
neutral `.card.soft` is `--color-foreground` with no ink mixed in -- a
|
|
59
|
+
plain step up from the page that marks a different container without
|
|
60
|
+
drawing attention to it.
|
|
61
|
+
|
|
62
|
+
A named intent keeps its ordinary 12% wash: 12% of an actual hue does not
|
|
63
|
+
read as a slab the way 12% of near-black ink does (`.card.soft.destructive`
|
|
64
|
+
is a gentle `249, 225, 225`), and untinting it would silence it rather than
|
|
65
|
+
quiet it. `.ghost` and `.solid` are not a tint and keep their own plates.
|
|
66
|
+
|
|
67
|
+
Which case applies is `surface`'s `--_quiet`, stepped from the resolved
|
|
68
|
+
fill and the intent's cap rather than keyed on classes on the card, so a
|
|
69
|
+
container's `.soft` renders the plate the card's own `.soft` does. Keyed
|
|
70
|
+
on the card's classes, `.soft > .card` drew the grey slab. `--_fill-cap`
|
|
71
|
+
(box.css's override slot, not `--ui-fill` directly -- see the comment
|
|
72
|
+
there) drops to 0% only when quiet, and the ground steps to the
|
|
73
|
+
foreground only then, through `--_d-surface-ground`, the default
|
|
74
|
+
`surface` reads beneath the public `--ui-surface-ground`, so a consumer's
|
|
75
|
+
override, or glass's ground, wins.
|
|
76
|
+
|
|
77
|
+
Composed with `box-hover`'s formula (`min(100%, resting + 14%)`), the
|
|
78
|
+
quiet rest reveals the intent on hover with no second fill declaration:
|
|
79
|
+
resting at 0% means hover lands at exactly the hover step, 14%, in
|
|
80
|
+
`--intent-hover`, and the ground steps to `--color-surface` at the same
|
|
81
|
+
moment. Scoped to `.interactive` and `.hoverable`, the two classes that
|
|
82
|
+
opt a card into `box-hover`. A named intent rests tinted, so the generic
|
|
83
|
+
formula deepens it on hover (12% to 26%). */
|
|
84
|
+
--_fill-cap: calc(100% - var(--_quiet));
|
|
85
|
+
--_d-surface-ground: color-mix(in oklab, var(--color-foreground) var(--_quiet), var(--color-background));
|
|
86
|
+
|
|
87
|
+
--_hover-ground: var(--_m-hover) color-mix(in oklab, var(--color-surface) var(--_quiet), var(--color-background));
|
|
88
|
+
|
|
89
|
+
/* Behind the query `box-hover` is, so a tapped card keeps its ground. */
|
|
90
|
+
@media (hover: hover) {
|
|
91
|
+
&:hover {
|
|
92
|
+
--_d-surface-ground: var(
|
|
93
|
+
--_hover-ground,
|
|
94
|
+
color-mix(in oklab, var(--color-foreground) var(--_quiet), var(--color-background))
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/* Opt-in, because a card is only sometimes a control. Applications still owe
|
|
100
|
+
it a real interactive element and an accessible name. Hover and press are
|
|
101
|
+
the derived ones every other pressable box gets; there is nothing
|
|
102
|
+
card-specific about either.
|
|
103
|
+
|
|
104
|
+
`.interactive` is the whole opt-in and stays that way; `.hoverable` and
|
|
105
|
+
`.pressable` are its halves, for a card that answers one gesture and not
|
|
106
|
+
the other. A card with its own nested controls takes `.hoverable` for the
|
|
107
|
+
hover warmth without the press-scale that reads as "you activated the
|
|
108
|
+
card" when the click really landed on a nested button. `.hoverable` alone
|
|
109
|
+
does not set the pointer cursor: that travels with being a click target,
|
|
110
|
+
i.e. with `.pressable` / `.interactive`. */
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/* The opt-in itself: utilities, so `@apply card interactive` carries the
|
|
114
|
+
gestures. Each is `box-hover` or `box-active` under the name a card's
|
|
115
|
+
markup uses, and the hover half raises the flag the card's quiet ground
|
|
116
|
+
reads. The pointer is 0-1-0 here, below `box`'s disabled cursor, so a
|
|
117
|
+
disabled interactive card does not invite the click. */
|
|
118
|
+
@utility hoverable {
|
|
119
|
+
@layer families {
|
|
120
|
+
--_m-hover: ;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
@apply box-hover;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
@utility pressable {
|
|
127
|
+
@apply box-active cursor-pointer;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
@utility interactive {
|
|
131
|
+
@layer families {
|
|
132
|
+
--_m-hover: ;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
@apply box-hover box-active cursor-pointer;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/* A panel is the flush, unelevated sibling: sidebars, toolbars, and wells that
|
|
139
|
+
sit flat against the layout rather than floating above it. Soft and edgeless
|
|
140
|
+
is what makes it read as a well without drawing a line to say so. */
|
|
141
|
+
@utility panel {
|
|
142
|
+
@layer families {
|
|
143
|
+
:where(&:not(.p-xs)) {
|
|
144
|
+
--_m-p-xs: initial;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
:where(&:not(.p-sm)) {
|
|
148
|
+
--_m-p-sm: initial;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
:where(&:not(.p-lg)) {
|
|
152
|
+
--_m-p-lg: initial;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
:where(&:not(.flush)) {
|
|
156
|
+
--_m-flush: initial;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
@apply surface;
|
|
161
|
+
|
|
162
|
+
--_d-fill: 12%;
|
|
163
|
+
--_d-fg-on-fill: 0%;
|
|
164
|
+
--_d-border: 0%;
|
|
165
|
+
--_d-elevation: 0;
|
|
166
|
+
|
|
167
|
+
/* The padding steps and `flush`. Each raises a flag (`modifiers.css`) and
|
|
168
|
+
the lines below compute only while theirs is up, so `@apply card p-xs`
|
|
169
|
+
carries the step. `--_scale-pad` is the step `box` scales the corner
|
|
170
|
+
and the depth by; `flush` leaves it alone. */
|
|
171
|
+
--_xs-pad: var(--_m-p-xs) 0.25rem;
|
|
172
|
+
--_sm-pad: var(--_m-p-sm) 0.5rem;
|
|
173
|
+
--_lg-pad: var(--_m-p-lg) 1.5rem;
|
|
174
|
+
--_flush-pad: var(--_m-flush) 0px;
|
|
175
|
+
--_xs-scale: var(--_m-p-xs) 0.5;
|
|
176
|
+
--_sm-scale: var(--_m-p-sm) 0.75;
|
|
177
|
+
--_lg-scale: var(--_m-p-lg) 1.25;
|
|
178
|
+
--_scale-pad: var(--_lg-scale, var(--_sm-scale, var(--_xs-scale)));
|
|
179
|
+
|
|
180
|
+
padding: var(--_flush-pad, var(--_lg-pad, var(--_sm-pad, var(--_xs-pad, 1rem))));
|
|
181
|
+
|
|
182
|
+
/* Neutral panels are the common case -- layout wells, sidebars, toolbars with
|
|
183
|
+
no named intent -- and 12% of `--color-text` (near-black) mixed onto the
|
|
184
|
+
page is far more assertive than 12% of a hue (`217, 217, 217` against a
|
|
185
|
+
`250, 250, 250` page): the same "neutral ink reads louder" effect
|
|
186
|
+
`.card.soft` answers, and the reason `--intent-fill-max` stops neutral's
|
|
187
|
+
fill short everywhere else. So a quiet neutral tint rests untinted on
|
|
188
|
+
`--color-foreground`, through `--_d-surface-ground`, the default
|
|
189
|
+
`.card.soft` rests on, so a bare `.panel` rests at exactly the plate a
|
|
190
|
+
`.card.soft` does, and a consumer's `--ui-surface-ground` or glass's
|
|
191
|
+
translucent ground wins over it: a neutral panel under `.glass` is glass.
|
|
192
|
+
|
|
193
|
+
A named intent keeps its wash: a panel is edgeless by default, so the fill
|
|
194
|
+
is the only channel a `.primary` bulk-actions bar or a `.destructive`
|
|
195
|
+
danger-zone panel has to say what it is (a resting `.panel.destructive` is
|
|
196
|
+
a gentle `249, 225, 225` wash). `.ghost` and `.solid` keep their own
|
|
197
|
+
plates. Which case applies is `surface`'s `--_quiet`, stepped from the
|
|
198
|
+
resolved fill, so a container's `.ghost` or `.solid` renders the panel its
|
|
199
|
+
own would; keyed on the panel's classes, both landed on the quiet plate.
|
|
200
|
+
Permanent rather than hover-revealed: a panel has no interaction state to
|
|
201
|
+
reveal a tint into. */
|
|
202
|
+
--_fill-cap: calc(100% - var(--_quiet));
|
|
203
|
+
--_d-surface-ground: color-mix(in oklab, var(--color-foreground) var(--_quiet), var(--color-background));
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/* A closed `<dialog>` is hidden, and an open one centred, by `surface` itself,
|
|
207
|
+
so every element that applies it -- these three, `.alert`, a consumer's
|
|
208
|
+
`@apply surface` -- gets both (see `surface.css`). That hide is in the
|
|
209
|
+
layer the surface is applied in. For the three containers a consumer
|
|
210
|
+
reaches for as a dialog, it is restated here unlayered: hiding a closed
|
|
211
|
+
dialog is behaviour, so it beats any layered rule whatever its specificity.
|
|
212
|
+
The centring stays a default in `utilities` at zero specificity, so a
|
|
213
|
+
consumer's own margin -- a utility, or unlayered CSS -- still places one.
|
|
214
|
+
|
|
215
|
+
Here rather than in the reset, so every entrypoint that ships `.card` ships
|
|
216
|
+
the fix, `/components` included. */
|
|
217
|
+
dialog:is(.card, .panel, .surface):not([open]) {
|
|
218
|
+
display: none;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/* The popover counterpart, unlayered for the same reason. `.alert` joins the
|
|
222
|
+
list: a toast is the surface most often given `popover`. */
|
|
223
|
+
:is(.card, .panel, .surface, .alert)[popover]:not(:popover-open) {
|
|
224
|
+
display: none;
|
|
225
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
@reference "tailwindcss";
|
|
2
|
+
@import "../theme.css";
|
|
3
|
+
@reference "../surface.css";
|
|
4
|
+
|
|
5
|
+
/* The focused entry: what the rules in `tooltip.rules.css` need to compile on their
|
|
6
|
+
own, then the rules. An aggregate entry imports the rules file directly and
|
|
7
|
+
supplies those needs once -- Tailwind stacks a `@utility` each time a file
|
|
8
|
+
that defines it is imported or referenced, so a second route to `box.css`
|
|
9
|
+
doubles every `@apply box`. See docs/internal/model.md (One route to each
|
|
10
|
+
utility). */
|
|
11
|
+
@import "./tooltip.rules.css";
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
@reference "tailwindcss";
|
|
2
|
-
@import "../theme.css";
|
|
3
|
-
@reference "../box.css";
|
|
4
|
-
@reference "../surface.css";
|
|
5
|
-
|
|
6
1
|
/* The host is a positioning wrapper and nothing else -- it paints no fill, no
|
|
7
2
|
edge, no material of its own. The bubble is a real element beside the trigger
|
|
8
3
|
rather than a pseudo-element, so intent, presentation, aesthetic, and
|
|
@@ -17,40 +12,45 @@
|
|
|
17
12
|
trigger's own `aria-describedby`; wiring that association is the consumer's,
|
|
18
13
|
this package only styles the bubble. See docs/usage/tooltips.md. */
|
|
19
14
|
@utility tooltip {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
--
|
|
29
|
-
--
|
|
30
|
-
--
|
|
15
|
+
/* `--tooltip-gap` and `--tooltip-linger` are public, read with their
|
|
16
|
+
defaults rather than declared, so a value set on any ancestor reaches the
|
|
17
|
+
tooltip. The linger is how long the bubble stays after the pointer leaves
|
|
18
|
+
the trigger: long enough to cross the gap onto the bubble, which keeps it
|
|
19
|
+
open (WCAG 1.4.13). The default is resolved here, so a bubble outside a
|
|
20
|
+
tooltip keeps no delay unless a linger is set above it. The bubble reads
|
|
21
|
+
the public one first, so a value set on the bubble itself, as 0.8
|
|
22
|
+
allowed, still wins. */
|
|
23
|
+
--_tooltip-gap: var(--tooltip-gap, 0.5rem);
|
|
24
|
+
--_tooltip-linger: var(--tooltip-linger, 300ms);
|
|
25
|
+
--_tooltip-top: calc(var(--_tooltip-gap) * -1);
|
|
26
|
+
--_tooltip-right: auto;
|
|
27
|
+
--_tooltip-bottom: auto;
|
|
28
|
+
--_tooltip-left: 50%;
|
|
29
|
+
--_tooltip-origin: bottom;
|
|
30
|
+
--_tooltip-transform: translate(-50%, -100%);
|
|
31
31
|
|
|
32
32
|
@apply relative inline-block;
|
|
33
33
|
|
|
34
34
|
&[data-tooltip-position="bottom"] {
|
|
35
|
-
--
|
|
36
|
-
--
|
|
37
|
-
--
|
|
38
|
-
--
|
|
35
|
+
--_tooltip-top: auto;
|
|
36
|
+
--_tooltip-bottom: calc(var(--_tooltip-gap) * -1);
|
|
37
|
+
--_tooltip-origin: top;
|
|
38
|
+
--_tooltip-transform: translate(-50%, 100%);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
&[data-tooltip-position="left"] {
|
|
42
|
-
--
|
|
43
|
-
--
|
|
44
|
-
--
|
|
45
|
-
--
|
|
42
|
+
--_tooltip-top: 50%;
|
|
43
|
+
--_tooltip-left: calc(var(--_tooltip-gap) * -1);
|
|
44
|
+
--_tooltip-origin: right;
|
|
45
|
+
--_tooltip-transform: translate(-100%, -50%);
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
&[data-tooltip-position="right"] {
|
|
49
|
-
--
|
|
50
|
-
--
|
|
51
|
-
--
|
|
52
|
-
--
|
|
53
|
-
--
|
|
49
|
+
--_tooltip-top: 50%;
|
|
50
|
+
--_tooltip-left: auto;
|
|
51
|
+
--_tooltip-right: calc(var(--_tooltip-gap) * -1);
|
|
52
|
+
--_tooltip-origin: left;
|
|
53
|
+
--_tooltip-transform: translate(100%, -50%);
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
|
|
@@ -64,13 +64,13 @@
|
|
|
64
64
|
/* Hidden rather than merely transparent, so a closed bubble is nothing
|
|
65
65
|
under the pointer, and it lingers before it goes: the host stays hovered
|
|
66
66
|
once the pointer is over the bubble, so crossing the gap in
|
|
67
|
-
`--
|
|
67
|
+
`--_tooltip-linger` keeps it open. Visibility switches at the end of the
|
|
68
68
|
fade, so the bubble is there to land on for the whole of it. */
|
|
69
69
|
visibility: hidden;
|
|
70
70
|
transition-property: opacity, transform, visibility;
|
|
71
71
|
transition-duration: var(--motion-duration-normal);
|
|
72
72
|
transition-timing-function: var(--motion-ease);
|
|
73
|
-
transition-delay: var(--tooltip-linger, 0s);
|
|
73
|
+
transition-delay: var(--tooltip-linger, var(--_tooltip-linger, 0s));
|
|
74
74
|
|
|
75
75
|
/* Filled, over a ground of its own. An intent floods the fill
|
|
76
76
|
(`.tooltip-bubble.primary` is the primary colour); with no intent
|
|
@@ -86,6 +86,10 @@
|
|
|
86
86
|
--_d-elevation: 0;
|
|
87
87
|
--_d-ground: var(--ui-surface-ground, var(--intent-subtle));
|
|
88
88
|
|
|
89
|
+
/* `surface` refuses the silhouette clip because it holds other things. The
|
|
90
|
+
bubble holds a line of text, so it takes the aesthetic's shape back. */
|
|
91
|
+
clip-path: var(--ui-clip, none);
|
|
92
|
+
|
|
89
93
|
/* The bubble's line is a boundary against content nobody chose, so `box`'s
|
|
90
94
|
edge blend is wrong here: at a full fill the line *is* the plate. Restate
|
|
91
95
|
the colour only; how much line comes from `--_edge-amount`, floored below. */
|
|
@@ -93,9 +97,9 @@
|
|
|
93
97
|
|
|
94
98
|
/* Floored, for the same reason the ground is opaque: a cascade must not take
|
|
95
99
|
the boundary from a bubble nobody classed (worst in light, where the plate
|
|
96
|
-
is near-white). The element's own `.edgeless` lowers it -- same
|
|
97
|
-
|
|
98
|
-
--_edge-floor:
|
|
100
|
+
is near-white). The element's own `.edgeless` lowers it -- the same
|
|
101
|
+
`--_own-edge` `text-control` reads. */
|
|
102
|
+
--_edge-floor: var(--_own-edge);
|
|
99
103
|
|
|
100
104
|
/* A bubble is a small transient popover, not a modal, so it takes the
|
|
101
105
|
control corner `box` computes rather than the surface one `surface` hands
|
|
@@ -105,39 +109,52 @@
|
|
|
105
109
|
calc(var(--_corner) * var(--ui-corner-tl, 1)) calc(var(--_corner) * var(--ui-corner-tr, 1))
|
|
106
110
|
calc(var(--_corner) * var(--ui-corner-br, 1)) calc(var(--_corner) * var(--ui-corner-bl, 1))
|
|
107
111
|
);
|
|
108
|
-
left: var(--
|
|
109
|
-
right: var(--
|
|
110
|
-
top: var(--
|
|
111
|
-
bottom: var(--
|
|
112
|
-
transform: var(--
|
|
113
|
-
transform-origin: var(--
|
|
114
|
-
|
|
115
|
-
&.edgeless {
|
|
116
|
-
--_edge-floor: 0%;
|
|
117
|
-
}
|
|
112
|
+
left: var(--_tooltip-left);
|
|
113
|
+
right: var(--_tooltip-right);
|
|
114
|
+
top: var(--_tooltip-top);
|
|
115
|
+
bottom: var(--_tooltip-bottom);
|
|
116
|
+
transform: var(--_tooltip-transform) scale(0);
|
|
117
|
+
transform-origin: var(--_tooltip-origin);
|
|
118
118
|
|
|
119
119
|
/* The bubble appears without growing under reduced motion, for the entries
|
|
120
120
|
without the reset; see `box.css`. */
|
|
121
121
|
@media (prefers-reduced-motion: reduce) {
|
|
122
122
|
transition-duration: 0.01ms;
|
|
123
123
|
}
|
|
124
|
-
}
|
|
125
124
|
|
|
126
|
-
/*
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
125
|
+
/* The no-intent plate, carried so `@apply tooltip-bubble` gets it: the rule
|
|
126
|
+
in `intent.css` names `.tooltip-bubble`, which a consumer's `.my-tip` is
|
|
127
|
+
not, so an applied bubble took `surface`'s neutral reset and drew the
|
|
128
|
+
page's ink at a fifth. In `families` after that reset, which `surface`
|
|
129
|
+
carries at the same zero specificity, so this one wins and an intent
|
|
130
|
+
applied with it still beats both. Never on `.tooltip-bubble` itself,
|
|
131
|
+
which keeps the rule in `components`. */
|
|
132
|
+
@layer families {
|
|
133
|
+
:where(&:not(.tooltip-bubble, .primary, .secondary, .success, .warning, .destructive, .info)) {
|
|
134
|
+
--intent-color: var(--color-tooltip);
|
|
135
|
+
--intent-contrast: var(--color-tooltip-contrast);
|
|
136
|
+
--intent-hover: var(--color-tooltip);
|
|
137
|
+
--intent-strong: var(--color-tooltip-contrast);
|
|
138
|
+
--intent-subtle: var(--color-surface);
|
|
139
|
+
--intent-border: var(--ui-ink, var(--color-border));
|
|
140
|
+
--intent-fill-max: 100%;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/* Shown on hover or focus anywhere in the host, or pinned open with
|
|
145
|
+
`data-state="open"`. `:focus-within` rather than the trigger's own
|
|
146
|
+
`:focus-visible`, the same substitution `.input-group` makes: the bubble
|
|
147
|
+
is a sibling of the trigger, so only the shared ancestor can see both at
|
|
148
|
+
once. The cost is the one `.input-group` accepts -- the bubble also shows
|
|
149
|
+
on a mouse click.
|
|
150
|
+
|
|
151
|
+
In the body, so an applied bubble opens in a `.tooltip` as the class
|
|
152
|
+
does; they win over the resting values above on specificity. */
|
|
153
|
+
.tooltip:hover &,
|
|
154
|
+
.tooltip:focus-within &,
|
|
155
|
+
.tooltip[data-state="open"] & {
|
|
139
156
|
opacity: 1;
|
|
140
|
-
transform: var(--
|
|
157
|
+
transform: var(--_tooltip-transform) scale(1);
|
|
141
158
|
visibility: visible;
|
|
142
159
|
transition-delay: 0s;
|
|
143
160
|
}
|
|
@@ -147,9 +164,9 @@
|
|
|
147
164
|
writes `data-state="closed"` and clears it when the pointer and focus
|
|
148
165
|
leave. Later and as specific as the rule above, so it wins over hover and
|
|
149
166
|
focus alike. */
|
|
150
|
-
.tooltip[data-state="closed"]
|
|
167
|
+
.tooltip[data-state="closed"] & {
|
|
151
168
|
opacity: 0;
|
|
152
|
-
transform: var(--
|
|
169
|
+
transform: var(--_tooltip-transform) scale(0);
|
|
153
170
|
visibility: hidden;
|
|
154
171
|
transition-delay: 0s;
|
|
155
172
|
}
|
|
@@ -176,6 +193,10 @@
|
|
|
176
193
|
--_d-elevation: 0;
|
|
177
194
|
--_d-ground: var(--intent-subtle);
|
|
178
195
|
|
|
196
|
+
/* A ground of its own, so no ink from above passes through, as on `surface`. */
|
|
197
|
+
--_held-ink: var(--_fg-own);
|
|
198
|
+
--_held-on: var(--_own-hold);
|
|
199
|
+
|
|
179
200
|
/* The trigger is best a real `<button>`, which is a `.btn` under `/native`
|
|
180
201
|
and carries the user agent's padding under `/components`; either would
|
|
181
202
|
stretch the chip past its own size. */
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
/*
|
|
2
|
-
|
|
1
|
+
/* Each class here is a `@utility` whose body sits in `utilities.families`: a
|
|
2
|
+
utility, so `@apply` and Tailwind's variants reach it, and in a sublayer, so
|
|
3
|
+
it still loses to every rule written straight into `utilities` -- a
|
|
4
|
+
component's, or a consumer's own utility. See
|
|
3
5
|
docs/internal/model.md#cascade-layers.
|
|
4
6
|
|
|
5
7
|
The corner pattern: which corners take the corner the aesthetic draws. `box`
|
|
@@ -10,17 +12,21 @@
|
|
|
10
12
|
is taken as written and ignores the pattern. See docs/internal/model.md#material-tokens. */
|
|
11
13
|
|
|
12
14
|
/* Top-left and bottom-right. */
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
@utility cut-diagonal {
|
|
16
|
+
@layer families {
|
|
17
|
+
--ui-corner-tl: 1;
|
|
18
|
+
--ui-corner-tr: 0;
|
|
19
|
+
--ui-corner-br: 1;
|
|
20
|
+
--ui-corner-bl: 0;
|
|
21
|
+
}
|
|
18
22
|
}
|
|
19
23
|
|
|
20
24
|
/* Top-right and bottom-left. */
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
@utility cut-diagonal-reverse {
|
|
26
|
+
@layer families {
|
|
27
|
+
--ui-corner-tl: 0;
|
|
28
|
+
--ui-corner-tr: 1;
|
|
29
|
+
--ui-corner-br: 0;
|
|
30
|
+
--ui-corner-bl: 1;
|
|
31
|
+
}
|
|
26
32
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
/*
|
|
2
|
-
|
|
1
|
+
/* Each class here is a `@utility` whose body sits in `utilities.families`: a
|
|
2
|
+
utility, so `@apply` and Tailwind's variants reach it, and in a sublayer, so
|
|
3
|
+
it still loses to every rule written straight into `utilities` -- a
|
|
4
|
+
component's, or a consumer's own utility. See
|
|
3
5
|
docs/internal/model.md#cascade-layers. */
|
|
4
6
|
|
|
5
7
|
/* Elevation is a modifier, not an axis: depth is a per-element decision (raised
|
|
@@ -8,8 +10,8 @@
|
|
|
8
10
|
`.flat` removes a part-based slab or blur without a conditional (complete
|
|
9
11
|
surface shadows like glass remain). See model.md#elevation.
|
|
10
12
|
|
|
11
|
-
`--ui-elevation`, and the plain-page fallback geometry (`--
|
|
12
|
-
`--
|
|
13
|
+
`--ui-elevation`, and the plain-page fallback geometry (`--_elevation-y`,
|
|
14
|
+
`--_elevation-blur`) below, are registered non-inheriting: a class sets them
|
|
13
15
|
on the element it is written on and nothing else picks them up. Inherited, a
|
|
14
16
|
`.floating` dialog's ambient x2 would reach its own unclassed buttons and
|
|
15
17
|
double their shadow with nothing in the markup asking for it. Depth is not
|
|
@@ -35,39 +37,43 @@
|
|
|
35
37
|
inherits: false;
|
|
36
38
|
}
|
|
37
39
|
|
|
38
|
-
@property --
|
|
40
|
+
@property --_elevation-y {
|
|
39
41
|
syntax: "*";
|
|
40
42
|
inherits: false;
|
|
41
43
|
}
|
|
42
44
|
|
|
43
|
-
@property --
|
|
45
|
+
@property --_elevation-blur {
|
|
44
46
|
syntax: "*";
|
|
45
47
|
inherits: false;
|
|
46
48
|
}
|
|
47
49
|
|
|
48
50
|
/* No part-based depth. Complete surface shadow values, such as glass, are not
|
|
49
51
|
reached by the elevation multiplier. */
|
|
50
|
-
|
|
51
|
-
|
|
52
|
+
@utility flat {
|
|
53
|
+
@layer families {
|
|
54
|
+
--ui-elevation: 0;
|
|
55
|
+
}
|
|
52
56
|
}
|
|
53
57
|
|
|
54
|
-
/* The plain-step geometry both rungs multiply
|
|
55
|
-
|
|
58
|
+
/* The plain-step geometry both rungs multiply. Each utility restates it so
|
|
59
|
+
`@apply raised` carries it, so the two copies must stay identical. It is the fallback for a page with no aesthetic in scope; an aesthetic
|
|
56
60
|
that declares its own shadow parts overrides it, and the elevation multiplier
|
|
57
61
|
scales whichever one lands. `.floating` takes its extra depth from the
|
|
58
|
-
multiplier
|
|
59
|
-
.raised,
|
|
60
|
-
.floating {
|
|
61
|
-
--elevation-y: 1px;
|
|
62
|
-
--elevation-blur: 3px;
|
|
63
|
-
}
|
|
64
|
-
|
|
62
|
+
multiplier, not from different parts. */
|
|
65
63
|
/* The aesthetic's depth as authored, said explicitly. */
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
@utility raised {
|
|
65
|
+
@layer families {
|
|
66
|
+
--_elevation-y: 1px;
|
|
67
|
+
--_elevation-blur: 3px;
|
|
68
|
+
--ui-elevation: 1;
|
|
69
|
+
}
|
|
68
70
|
}
|
|
69
71
|
|
|
70
72
|
/* Twice it, for menus and popovers. */
|
|
71
|
-
|
|
72
|
-
|
|
73
|
+
@utility floating {
|
|
74
|
+
@layer families {
|
|
75
|
+
--_elevation-y: 1px;
|
|
76
|
+
--_elevation-blur: 3px;
|
|
77
|
+
--ui-elevation: 2;
|
|
78
|
+
}
|
|
73
79
|
}
|