@uncinq/css-components 1.27.4 → 1.29.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 +3 -3
- package/css/components/rating.css +41 -0
- package/css/index.css +1 -0
- package/css/utilities/scrollsnap.css +10 -0
- package/docs/content/_index.md +1 -1
- package/docs/content/rating.md +68 -0
- package/docs/content/surtitle.md +1 -1
- package/docs/overview.md +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
<img width="1280" height="640" alt="share-css-components" src="https://github.com/user-attachments/assets/3d74df8a-e7bf-4ba5-8529-99cfef0bc176" />
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
31 components and 1 utility, written as plain CSS, reading their values from [@uncinq/component-tokens](https://github.com/uncinq/component-tokens) and adding none of their own.
|
|
8
8
|
|
|
9
9
|
## Where this sits
|
|
10
10
|
|
|
@@ -55,7 +55,7 @@ The failure is silent. No error is raised, the page simply stays at its mobile v
|
|
|
55
55
|
| --- | --- |
|
|
56
56
|
| Buttons | `.btn` with colour, size and style variants, plus `btn-close`, `btn-menu`, `btn-search`, `btn-filter`, `btn-share`, `btn-toc`, `btn-toggle-video` |
|
|
57
57
|
| Overlays | `modal`, `drawer`, `dropdown`, and the shared panel skeleton |
|
|
58
|
-
| Content | `alert`, `badge`, `banner`, `card`, `items`, `list`, `media`, `push`, `surtitle` |
|
|
58
|
+
| Content | `alert`, `badge`, `banner`, `card`, `items`, `list`, `media`, `push`, `rating`, `surtitle` |
|
|
59
59
|
| Navigation | `nav`, `nav-title`, `nav-accessibility`, `breadcrumb`, `pagination` |
|
|
60
60
|
| Embeds | `embed`, `video`, `map` |
|
|
61
61
|
| Forms | `form`, `form-check` and the layout helpers |
|
|
@@ -85,7 +85,7 @@ It is also versioned with the code in [`docs/`](docs/), one page per component,
|
|
|
85
85
|
- [Cascade layers](docs/cascade-layers.md) — the two layers, and the `:where()` convention
|
|
86
86
|
- [Buttons](docs/buttons/) — [`.btn`](docs/buttons/btn.md) and the seven specialised buttons
|
|
87
87
|
- [Overlays](docs/overlays/) — [the panel skeleton](docs/overlays/panel.md), [`.modal`](docs/overlays/modal.md), [`.drawer`](docs/overlays/drawer.md), [`.dropdown`](docs/overlays/dropdown.md)
|
|
88
|
-
- [Content](docs/content/) — [`.alert`](docs/content/alert.md), [`.badge`](docs/content/badge.md), [`.banner`](docs/content/banner.md), [`.card`](docs/content/card.md), [`.items`](docs/content/items.md), [`.list`](docs/content/list.md), [`.media`](docs/content/media.md), [`.surtitle`](docs/content/surtitle.md)
|
|
88
|
+
- [Content](docs/content/) — [`.alert`](docs/content/alert.md), [`.badge`](docs/content/badge.md), [`.banner`](docs/content/banner.md), [`.card`](docs/content/card.md), [`.items`](docs/content/items.md), [`.list`](docs/content/list.md), [`.media`](docs/content/media.md), [`.rating`](docs/content/rating.md), [`.surtitle`](docs/content/surtitle.md)
|
|
89
89
|
- [Navigation](docs/navigation/) — [`.nav`](docs/navigation/nav.md), [`.nav-title`](docs/navigation/nav-title.md), [skip links](docs/navigation/nav-accessibility.md), [breadcrumb](docs/navigation/breadcrumb.md), [pagination](docs/navigation/pagination.md)
|
|
90
90
|
- [Embeds](docs/embeds/) — [`.embed`](docs/embeds/embed.md), [`.video`](docs/embeds/video.md), [`.map`](docs/embeds/map.md)
|
|
91
91
|
- [Forms](docs/forms/) — [`.form`](docs/forms/form.md), [`.form-check`](docs/forms/form-check.md)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/* components/rating.css */
|
|
2
|
+
/*
|
|
3
|
+
* .rating — star rating out of 5, fractional values included (4.8).
|
|
4
|
+
*
|
|
5
|
+
* Structure:
|
|
6
|
+
* div.rating
|
|
7
|
+
* span.rating-star (×5, style="--rating-fill: 0–100%")
|
|
8
|
+
* .icon (the theme's star glyph, painted as a mask)
|
|
9
|
+
* span.visually-hidden (e.g. "Rating: 4.8 out of 5")
|
|
10
|
+
*
|
|
11
|
+
* The icon is a mask, so its background is what shows through the glyph.
|
|
12
|
+
* A hard-stop gradient paints each star in the active colour up to its
|
|
13
|
+
* --rating-fill and in the empty colour after it.
|
|
14
|
+
*/
|
|
15
|
+
@layer components {
|
|
16
|
+
.rating {
|
|
17
|
+
--icon-size: var(--rating-size);
|
|
18
|
+
|
|
19
|
+
align-items: center;
|
|
20
|
+
display: flex;
|
|
21
|
+
gap: var(--rating-gap);
|
|
22
|
+
justify-content: var(--rating-justify-content);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.rating-star {
|
|
26
|
+
display: flex;
|
|
27
|
+
|
|
28
|
+
.icon {
|
|
29
|
+
background: linear-gradient(
|
|
30
|
+
to right,
|
|
31
|
+
var(--rating-color-active) var(--rating-fill, 0%),
|
|
32
|
+
var(--rating-color-empty) var(--rating-fill, 0%)
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
/* RTL: stars fill from the right */
|
|
36
|
+
&:dir(rtl) {
|
|
37
|
+
scale: -1 1;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
package/css/index.css
CHANGED
|
@@ -68,6 +68,12 @@
|
|
|
68
68
|
overflow-x: auto;
|
|
69
69
|
overflow-y: hidden;
|
|
70
70
|
padding-inline: var(--container-bleed, var(--gutter));
|
|
71
|
+
/* The row is the containing block of anything absolute inside it.
|
|
72
|
+
overflow only clips what it contains: without this, an absolute
|
|
73
|
+
descendant of an unpositioned item (the .visually-hidden label of a
|
|
74
|
+
.rating, say) anchors to an ancestor outside the row, escapes the clip
|
|
75
|
+
and widens the whole page by the length of the row. */
|
|
76
|
+
position: relative;
|
|
71
77
|
scroll-snap-type: x mandatory;
|
|
72
78
|
|
|
73
79
|
> * {
|
|
@@ -89,6 +95,7 @@
|
|
|
89
95
|
overflow-x: revert-layer;
|
|
90
96
|
overflow-y: revert-layer;
|
|
91
97
|
padding-inline: revert-layer;
|
|
98
|
+
position: revert-layer;
|
|
92
99
|
scroll-snap-type: revert-layer;
|
|
93
100
|
|
|
94
101
|
> * {
|
|
@@ -107,6 +114,7 @@
|
|
|
107
114
|
overflow-x: revert-layer;
|
|
108
115
|
overflow-y: revert-layer;
|
|
109
116
|
padding-inline: revert-layer;
|
|
117
|
+
position: revert-layer;
|
|
110
118
|
scroll-snap-type: revert-layer;
|
|
111
119
|
|
|
112
120
|
> * {
|
|
@@ -125,6 +133,7 @@
|
|
|
125
133
|
overflow-x: revert-layer;
|
|
126
134
|
overflow-y: revert-layer;
|
|
127
135
|
padding-inline: revert-layer;
|
|
136
|
+
position: revert-layer;
|
|
128
137
|
scroll-snap-type: revert-layer;
|
|
129
138
|
|
|
130
139
|
> * {
|
|
@@ -143,6 +152,7 @@
|
|
|
143
152
|
overflow-x: revert-layer;
|
|
144
153
|
overflow-y: revert-layer;
|
|
145
154
|
padding-inline: revert-layer;
|
|
155
|
+
position: revert-layer;
|
|
146
156
|
scroll-snap-type: revert-layer;
|
|
147
157
|
|
|
148
158
|
> * {
|
package/docs/content/_index.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
isIndex: false
|
|
3
3
|
title: Content
|
|
4
|
-
description: Alerts, badges, banners, cards, the items grid, labelled lists, media objects, pushes and surtitles.
|
|
4
|
+
description: Alerts, badges, banners, cards, the items grid, labelled lists, media objects, pushes, star ratings and surtitles.
|
|
5
5
|
weight: 5
|
|
6
6
|
icon: card-text
|
|
7
7
|
---
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
isIndex: false
|
|
3
|
+
title: Rating
|
|
4
|
+
description: A star rating out of 5 with fractional values, how each star is filled through its icon mask, and what the markup has to provide.
|
|
5
|
+
weight: 10
|
|
6
|
+
icon: star-half
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
A star rating out of 5, fractional values included: 4.8 shows four full stars and one filled to 80%.
|
|
10
|
+
|
|
11
|
+
```html
|
|
12
|
+
<div class="rating">
|
|
13
|
+
<span class="rating-star" style="--rating-fill: 100%"><i class="icon icon-star" aria-hidden="true"></i></span>
|
|
14
|
+
<span class="rating-star" style="--rating-fill: 100%"><i class="icon icon-star" aria-hidden="true"></i></span>
|
|
15
|
+
<span class="rating-star" style="--rating-fill: 100%"><i class="icon icon-star" aria-hidden="true"></i></span>
|
|
16
|
+
<span class="rating-star" style="--rating-fill: 100%"><i class="icon icon-star" aria-hidden="true"></i></span>
|
|
17
|
+
<span class="rating-star" style="--rating-fill: 80%"><i class="icon icon-star" aria-hidden="true"></i></span>
|
|
18
|
+
<span class="visually-hidden">Rating: 4.8 out of 5</span>
|
|
19
|
+
</div>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
| Child | Role |
|
|
23
|
+
| --- | --- |
|
|
24
|
+
| `.rating-star` | One star, carrying its own fill in `--rating-fill`, from `0%` to `100%` |
|
|
25
|
+
| `.icon` | The star glyph, rendered by the theme |
|
|
26
|
+
| `.visually-hidden` | The value, read out by screen readers |
|
|
27
|
+
|
|
28
|
+
The fill is computed where the markup is written, not here: star *n* takes `(rating − n + 1) × 100%`, clamped between `0%` and `100%`. A star with no `--rating-fill` is empty.
|
|
29
|
+
|
|
30
|
+
## The fill goes through the mask
|
|
31
|
+
|
|
32
|
+
This package ships no star. The `.icon` is the theme's, and the rating expects it to be a **mask**: an element whose `background` shows through the glyph, as the Hugolify icons render.
|
|
33
|
+
|
|
34
|
+
```css
|
|
35
|
+
.rating-star .icon {
|
|
36
|
+
background: linear-gradient(
|
|
37
|
+
to right,
|
|
38
|
+
var(--rating-color-active) var(--rating-fill, 0%),
|
|
39
|
+
var(--rating-color-empty) var(--rating-fill, 0%)
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Both colour stops sit at the same position, so the gradient is a hard edge, not a blend: the glyph is in the active colour up to its fill and in the empty colour after it. With an outline icon set, such as Lucide, that is the outline which changes colour, not the inside of the star.
|
|
45
|
+
|
|
46
|
+
An icon inlined as an `<svg>` ignores the background and is not filled.
|
|
47
|
+
|
|
48
|
+
Under `:dir(rtl)` the glyph is mirrored, so stars fill from the right.
|
|
49
|
+
|
|
50
|
+
## Size and alignment
|
|
51
|
+
|
|
52
|
+
The rating sets `--icon-size` from `--rating-size`, so the stars follow the rating rather than the font size around them.
|
|
53
|
+
|
|
54
|
+
It is a flex row aligned to the start. `--rating-justify-content` moves it, which is how a centred context, a quote for instance, centres its stars without a modifier:
|
|
55
|
+
|
|
56
|
+
```css
|
|
57
|
+
.quote .rating {
|
|
58
|
+
--rating-justify-content: center;
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`--rating-gap` is `0` by default: the star glyph carries its own inner margin, and a gap would only widen the row.
|
|
63
|
+
|
|
64
|
+
## Accessibility
|
|
65
|
+
|
|
66
|
+
The stars carry no meaning for assistive technology: each `.icon` is `aria-hidden`, and the value is given as text in a `.visually-hidden` span, in words rather than as a fraction.
|
|
67
|
+
|
|
68
|
+
The empty colour defaults to `--color-text-muted` rather than a border colour, so an empty star stays visible on a muted background such as a card.
|
package/docs/content/surtitle.md
CHANGED
package/docs/overview.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
isIndex: false
|
|
3
3
|
title: Overview
|
|
4
|
-
description: The
|
|
4
|
+
description: The 31 components and 1 utility, how to install them, the import order inside the package, and what it deliberately leaves out.
|
|
5
5
|
weight: 1
|
|
6
6
|
icon: book
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
`@uncinq/css-components` is the top of the stack:
|
|
9
|
+
`@uncinq/css-components` is the top of the stack: 31 components and 1 utility, written as plain CSS, reading their values from [@uncinq/component-tokens](../../component-tokens/) and adding no values of their own.
|
|
10
10
|
|
|
11
11
|
```
|
|
12
12
|
@uncinq/design-tokens primitive + semantic values
|
|
@@ -25,7 +25,7 @@ One page per component, grouped into six sections.
|
|
|
25
25
|
| --- | --- |
|
|
26
26
|
| [Buttons](../buttons/) | [`.btn`](../buttons/btn/), [`.btn-close`](../buttons/btn-close/), [`.btn-menu`](../buttons/btn-menu/), [`.btn-search`](../buttons/btn-search/), [`.btn-filter`](../buttons/btn-filter/), [`.btn-share`](../buttons/btn-share/), [`.btn-toc`](../buttons/btn-toc/), [`.btn-toggle-video`](../buttons/btn-toggle-video/) |
|
|
27
27
|
| [Overlays](../overlays/) | [panel](../overlays/panel/), [`.modal`](../overlays/modal/), [`.drawer`](../overlays/drawer/), [`.dropdown`](../overlays/dropdown/) |
|
|
28
|
-
| [Content](../content/) | [`.alert`](../content/alert/), [`.badge`](../content/badge/), [`.banner`](../content/banner/), [`.card`](../content/card/), [`.items`](../content/items/), [`.list`](../content/list/), [`.media`](../content/media/), [`.push`](../content/push/), [`.surtitle`](../content/surtitle/) |
|
|
28
|
+
| [Content](../content/) | [`.alert`](../content/alert/), [`.badge`](../content/badge/), [`.banner`](../content/banner/), [`.card`](../content/card/), [`.items`](../content/items/), [`.list`](../content/list/), [`.media`](../content/media/), [`.push`](../content/push/), [`.rating`](../content/rating/), [`.surtitle`](../content/surtitle/) |
|
|
29
29
|
| [Navigation](../navigation/) | [`.nav`](../navigation/nav/), [`.nav-title`](../navigation/nav-title/), [`.nav-accessibility`](../navigation/nav-accessibility/), [`.breadcrumb-wrapper`](../navigation/breadcrumb/), [`.pagination`](../navigation/pagination/) |
|
|
30
30
|
| [Embeds](../embeds/) | [`.embed`](../embeds/embed/), [`.video`](../embeds/video/), [`.map`](../embeds/map/) |
|
|
31
31
|
| [Forms](../forms/) | [`.form`](../forms/form/), [`.form-check`](../forms/form-check/) |
|