@apliteni/apliteni-ui 0.24.0 → 0.25.2
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 +21 -1
- package/package.json +1 -1
- package/src/index.css +6 -1
- package/src/styles/base.css +22 -0
- package/src/styles/callout.css +1 -1
- package/src/styles/card.css +7 -0
- package/src/styles/confirm.css +4 -1
- package/src/styles/drawer.css +5 -0
- package/src/styles/dropdown.css +21 -1
- package/src/styles/feedback.css +11 -1
- package/src/styles/layout.css +3 -0
- package/src/styles/topbar.css +17 -0
- package/src/tokens/tokens.css +11 -2
package/README.md
CHANGED
|
@@ -48,7 +48,7 @@ npm install @apliteni/apliteni-ui
|
|
|
48
48
|
## Use it
|
|
49
49
|
|
|
50
50
|
```js
|
|
51
|
-
import '@apliteni/apliteni-ui/css'; // once, at app root (
|
|
51
|
+
import '@apliteni/apliteni-ui/css'; // once, at app root (load the two fonts too — see below)
|
|
52
52
|
import { button, card, topbar, wireTopbar } from '@apliteni/apliteni-ui';
|
|
53
53
|
|
|
54
54
|
el.innerHTML = topbar({ word: 'Strategy', account: { name, email } })
|
|
@@ -56,6 +56,26 @@ el.innerHTML = topbar({ word: 'Strategy', account: { name, email } })
|
|
|
56
56
|
wireTopbar(document); // theme toggle, menus, segmented, copy buttons
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
+
### The two fonts
|
|
60
|
+
|
|
61
|
+
The kit names two families and bundles neither, so the host page loads them. Poppins is
|
|
62
|
+
`--font-display` — headings, brand marks, large readouts. IBM Plex Sans is `--font-sans` —
|
|
63
|
+
tables, fields, paragraphs, chat, which is most of an application. Weights 300-700 in both:
|
|
64
|
+
|
|
65
|
+
```html
|
|
66
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
67
|
+
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&family=IBM+Plex+Sans:wght@300;400;500;600;700&display=swap">
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Load only one of them and the other falls through to the system stack behind it, without
|
|
71
|
+
saying so. Want the old
|
|
72
|
+
single-family look back? Set both roles to the same family in your own stylesheet, after the
|
|
73
|
+
kit's:
|
|
74
|
+
|
|
75
|
+
```css
|
|
76
|
+
:root { --font-sans: var(--font-display); }
|
|
77
|
+
```
|
|
78
|
+
|
|
59
79
|
### Reuse the account page
|
|
60
80
|
|
|
61
81
|
The whole `/account` layout (topbar + sticky sidebar + page body) ships as one
|
package/package.json
CHANGED
package/src/index.css
CHANGED
|
@@ -4,7 +4,12 @@
|
|
|
4
4
|
* addressable — package.json `exports` has no wildcard for ./styles/*, so a deep
|
|
5
5
|
* path into src/styles/ does not resolve. To take one component, read it by name
|
|
6
6
|
* through `apliteni-ui/inline` (`import { topbarCss } from …`).
|
|
7
|
-
* Requires
|
|
7
|
+
* Requires two families, loaded by the host page or the Storybook preview:
|
|
8
|
+
* Poppins (--font-display, headings and brand marks) and IBM Plex Sans
|
|
9
|
+
* (--font-sans, everything else). Weights 300-700 in both. Neither is
|
|
10
|
+
* bundled; a family that never loads falls back to the system stack behind
|
|
11
|
+
* it, in silence.
|
|
12
|
+
* why: docs/specification.md#typefaces
|
|
8
13
|
* ========================================================================== */
|
|
9
14
|
@import "./tokens/brand.generated.css";
|
|
10
15
|
@import "./tokens/tokens.css";
|
package/src/styles/base.css
CHANGED
|
@@ -35,6 +35,28 @@ a {
|
|
|
35
35
|
text-decoration: none;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
/* -- The two typeface roles -----------------------------------------------
|
|
39
|
+
* A heading is the display face, running text is the text face, and the
|
|
40
|
+
* ELEMENT decides which — never the size. A size threshold would change a
|
|
41
|
+
* heading's typeface halfway through a resize, which is the one thing a
|
|
42
|
+
* reader notices. A component that wants a heading tag set in the text face
|
|
43
|
+
* says so on its own rule, which outranks this one at (0,1,0); .ui-drawer__title
|
|
44
|
+
* and .ui-confirm__title are the two that do.
|
|
45
|
+
* why: docs/specification.md#typefaces */
|
|
46
|
+
h1, h2, h3, h4, h5, h6 {
|
|
47
|
+
font-family: var(--font-display);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* The browser default for b/strong is 700, and at the 13px the kit's tables and
|
|
51
|
+
* chat feeds run at, 700 stops reading as emphasis and starts reading as a
|
|
52
|
+
* filled-in shape. The semibold step is the emphasis; the bold step stays
|
|
53
|
+
* available to anything that asks for it by name.
|
|
54
|
+
* why: docs/specification.md#typefaces */
|
|
55
|
+
b,
|
|
56
|
+
strong {
|
|
57
|
+
font-weight: var(--weight-semibold);
|
|
58
|
+
}
|
|
59
|
+
|
|
38
60
|
/* Ambient blurred glow — the deck's signature background depth.
|
|
39
61
|
Place <span class="ui-glow ui-glow--purple"> absolutely inside a positioned
|
|
40
62
|
parent. Two colour variants ship; scale/position with inline styles. */
|
package/src/styles/callout.css
CHANGED
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
.ui-toast__action { flex: none; align-self: center; background: none; border: 0; padding: 4px 9px; border-radius: var(--radius-xs); font: inherit; font-weight: var(--weight-medium); color: var(--toast-action-ink); cursor: pointer; }
|
|
84
84
|
.ui-toast__action:hover { background: color-mix(in srgb, var(--bg) 55%, transparent); }
|
|
85
85
|
|
|
86
|
-
.ui-toast__close { flex: none; align-self: flex-start; background: none; border: 0; color: var(--muted); cursor: pointer; padding: 2px; display: grid; place-items: center; position: relative; }
|
|
86
|
+
.ui-toast__close { flex: none; align-self: flex-start; background: none; border: 0; color: var(--muted); cursor: pointer; padding: 2px; display: grid; place-items: center; position: relative; font: inherit; }
|
|
87
87
|
.ui-toast__close svg { width: 15px; height: 15px; stroke: currentColor; fill: none; stroke-width: 2.5; }
|
|
88
88
|
/* The target, not the ink. WCAG 2.5.8 measures what a pointer can land on, and
|
|
89
89
|
the drawn button is 19x19 — a 15px glyph in 2px of padding. Growing the box
|
package/src/styles/card.css
CHANGED
|
@@ -43,6 +43,13 @@
|
|
|
43
43
|
/* Interactive card (link / button semantics) */
|
|
44
44
|
.ui-card--interactive {
|
|
45
45
|
cursor: pointer;
|
|
46
|
+
/* Written as a <button>, the card would take the browser's frame, centred text
|
|
47
|
+
and `font: 400 13.3333px Arial` — a shorthand, so `font: inherit` and not the
|
|
48
|
+
family longhand. .ui-card already states its own background, and the light
|
|
49
|
+
theme's border rule is (0,3,0) so `border: 0` here cannot reach it. #251 */
|
|
50
|
+
border: 0;
|
|
51
|
+
text-align: left;
|
|
52
|
+
font: inherit;
|
|
46
53
|
transition: transform var(--dur-fast) var(--ease), box-shadow var(--dur-med) var(--ease);
|
|
47
54
|
}
|
|
48
55
|
.ui-card--interactive:hover {
|
package/src/styles/confirm.css
CHANGED
|
@@ -85,7 +85,10 @@
|
|
|
85
85
|
/* -- Slots ----------------------------------------------------------------- */
|
|
86
86
|
/* The question and the answers keep their size; the consequence between them is
|
|
87
87
|
the one that gives, and scrolls — the same split the drawer's header / body /
|
|
88
|
-
footer makes.
|
|
88
|
+
footer makes. The title is an h2 and opts out of the display face base.css
|
|
89
|
+
gives a heading, for the same reason .ui-drawer__title does: at --text-md it
|
|
90
|
+
is the question on a dialog, set at the size the answer beneath it is set at.
|
|
91
|
+
why: docs/specification.md#typefaces */
|
|
89
92
|
.ui-confirm__title {
|
|
90
93
|
margin: 0;
|
|
91
94
|
flex: none;
|
package/src/styles/drawer.css
CHANGED
|
@@ -119,6 +119,10 @@
|
|
|
119
119
|
border-bottom: 1px solid var(--border);
|
|
120
120
|
flex: none;
|
|
121
121
|
}
|
|
122
|
+
/* An h2, and base.css would give it the display face. It opts out: at 15px in a
|
|
123
|
+
panel header it is a label on a piece of UI rather than a heading anybody
|
|
124
|
+
reads, and the display face at that size is exactly what #253 was about.
|
|
125
|
+
why: docs/specification.md#typefaces */
|
|
122
126
|
.ui-drawer__title {
|
|
123
127
|
margin: 0;
|
|
124
128
|
font-family: var(--font-sans);
|
|
@@ -138,6 +142,7 @@
|
|
|
138
142
|
background: transparent;
|
|
139
143
|
border: 1px solid transparent;
|
|
140
144
|
border-radius: var(--radius-sm);
|
|
145
|
+
font: inherit;
|
|
141
146
|
transition:
|
|
142
147
|
color var(--dur-fast) var(--ease),
|
|
143
148
|
background var(--dur-fast) var(--ease),
|
package/src/styles/dropdown.css
CHANGED
|
@@ -45,6 +45,14 @@
|
|
|
45
45
|
the portal's JS, so an upward panel cannot drift from a downward one.
|
|
46
46
|
why: docs/specification.md#the-dropdown-panel */
|
|
47
47
|
--ui-dropdown-gap: 9px;
|
|
48
|
+
/* The panel states its own role rather than inheriting one, because `portal:
|
|
49
|
+
true` moves it onto <body> and an inherited face is then decided by where
|
|
50
|
+
the panel was MOUNTED rather than by what it is. Measured: the same dropdown
|
|
51
|
+
inside a display-face subtree resolved to var(--font-display) in place and
|
|
52
|
+
var(--font-sans) once portalled — a positioning flag changing the typeface.
|
|
53
|
+
A list of item rows is text, so it is the text face in both placements.
|
|
54
|
+
why: docs/specification.md#typefaces */
|
|
55
|
+
font-family: var(--font-sans);
|
|
48
56
|
position: absolute;
|
|
49
57
|
top: calc(100% + var(--ui-dropdown-gap));
|
|
50
58
|
left: 0;
|
|
@@ -94,15 +102,27 @@
|
|
|
94
102
|
}
|
|
95
103
|
.ui-dropdown__panel--portal.is-open { opacity: 1; visibility: visible; transform: translateY(0); }
|
|
96
104
|
|
|
97
|
-
/* Item row — [icon] [main: label + desc] [badge] [tick]
|
|
105
|
+
/* Item row — [icon] [main: label + desc] [badge] [tick]. A row is a <div>, an
|
|
106
|
+
<a href> or a <button>: `is-selected` and __tick below mean a row gets
|
|
107
|
+
chosen, and choosing is a button's job. So the tag's own styling is reset
|
|
108
|
+
here, the way .ui-nav__item resets it, and the three render identically.
|
|
109
|
+
why: docs/specification.md#a-dropdown-row-is-a-div-a-link-or-a-button */
|
|
98
110
|
.ui-dropdown__item {
|
|
99
111
|
display: flex;
|
|
100
112
|
gap: 11px;
|
|
101
113
|
align-items: center;
|
|
114
|
+
width: 100%;
|
|
102
115
|
padding: 9px 12px;
|
|
116
|
+
border: 0;
|
|
103
117
|
border-radius: var(--radius-sm);
|
|
118
|
+
background: none;
|
|
104
119
|
cursor: pointer;
|
|
120
|
+
text-align: left;
|
|
105
121
|
text-decoration: none;
|
|
122
|
+
/* `font`, not `font-family`: the UA writes one shorthand, `font: 400 13.3333px
|
|
123
|
+
Arial`, so answering its family alone leaves the size and the line-height
|
|
124
|
+
standing. The same answer .ui-toast__action gives. */
|
|
125
|
+
font: inherit;
|
|
106
126
|
color: var(--text);
|
|
107
127
|
transition: background var(--dur-fast) var(--ease);
|
|
108
128
|
}
|
package/src/styles/feedback.css
CHANGED
|
@@ -22,6 +22,16 @@
|
|
|
22
22
|
transform: translate(-50%, -100%) translateY(-4px) scale(.82); transform-origin: bottom center;
|
|
23
23
|
display: inline-flex; align-items: center; gap: 9px;
|
|
24
24
|
background: var(--ui-fb-pill-grad); color: var(--accent-contrast);
|
|
25
|
+
/* The pill is a click target the kit renders as a bare <div>, so the consumer who
|
|
26
|
+
needs it from the keyboard writes it as a <button> — which brings a 2px outset
|
|
27
|
+
frame around the gradient, a centred line and `font: 400 13.3333px Arial`. Stated
|
|
28
|
+
here rather than taken from the element. `font` and not `font-family`, because
|
|
29
|
+
Chrome's rule is the shorthand; the three longhands after it keep what the pill
|
|
30
|
+
wants and only the leading comes from the shorthand, which is the 1.62 the pill
|
|
31
|
+
already inherits as a div. `text-align` paints nothing on an inline-flex box
|
|
32
|
+
either way and is declared because leaving it to the element is the dependency
|
|
33
|
+
this refuses. why: #251 */
|
|
34
|
+
border: 0; text-align: center; font: inherit;
|
|
25
35
|
font-family: var(--font-sans); font-size: 13px; font-weight: var(--weight-semibold); letter-spacing: .01em;
|
|
26
36
|
padding: 9px 17px 9px 15px; border-radius: 999px; cursor: pointer; white-space: nowrap; overflow: hidden;
|
|
27
37
|
box-shadow: 0 10px 26px var(--ui-fb-pill-glow),
|
|
@@ -68,7 +78,7 @@
|
|
|
68
78
|
.ui-fbc__head { display: flex; align-items: center; gap: 12px; padding: 17px 20px 0; }
|
|
69
79
|
.ui-fbc__chip { display: inline-flex; align-items: center; gap: 8px; color: var(--accent); font-size: 13px; font-weight: var(--weight-semibold); letter-spacing: .01em; white-space: nowrap; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
|
|
70
80
|
.ui-fbc__chip svg { width: 14px; height: 14px; flex: none; opacity: .85; stroke-width: 2.7; }
|
|
71
|
-
.ui-fbc__x { margin-left: auto; background: var(--surface-2); color: var(--dim); border: 0; width: 28px; height: 28px; border-radius: 8px; cursor: pointer; display: grid; place-items: center; flex: none; }
|
|
81
|
+
.ui-fbc__x { margin-left: auto; background: var(--surface-2); color: var(--dim); border: 0; width: 28px; height: 28px; border-radius: 8px; cursor: pointer; display: grid; place-items: center; flex: none; font: inherit; }
|
|
72
82
|
.ui-fbc__x:hover { color: var(--strong); }
|
|
73
83
|
.ui-fbc__x svg { width: 14px; height: 14px; stroke-width: 2.7; }
|
|
74
84
|
.ui-fbc__quote { margin: 14px 20px 0; background: var(--surface-2); border-radius: 12px; padding: 12px 15px; display: flex; gap: 11px; }
|
package/src/styles/layout.css
CHANGED
|
@@ -55,6 +55,9 @@
|
|
|
55
55
|
gap: var(--space-2);
|
|
56
56
|
padding: 2px 6px;
|
|
57
57
|
text-decoration: none;
|
|
58
|
+
/* display: brand — the rail's lockup is the same mark topbar.css sets, and the
|
|
59
|
+
two have to be the same face or the shell reads as two products. */
|
|
60
|
+
font-family: var(--font-display);
|
|
58
61
|
font-weight: var(--weight-semibold);
|
|
59
62
|
letter-spacing: var(--tracking-tight);
|
|
60
63
|
}
|
package/src/styles/topbar.css
CHANGED
|
@@ -30,6 +30,10 @@
|
|
|
30
30
|
display: inline-flex;
|
|
31
31
|
align-items: center;
|
|
32
32
|
gap: 9px;
|
|
33
|
+
/* display: brand — a wordmark is the mark, not text. It is two words beside a
|
|
34
|
+
glyph and it is what the product is recognised by, so it keeps the display
|
|
35
|
+
face at every size it is set at, including the 13px below. */
|
|
36
|
+
font-family: var(--font-display);
|
|
33
37
|
font-weight: 600;
|
|
34
38
|
color: var(--strong);
|
|
35
39
|
text-decoration: none;
|
|
@@ -75,6 +79,7 @@
|
|
|
75
79
|
color: var(--text);
|
|
76
80
|
border: 1px solid var(--border);
|
|
77
81
|
border-radius: 10px;
|
|
82
|
+
font: inherit;
|
|
78
83
|
transition:
|
|
79
84
|
transform var(--dur-fast) var(--ease),
|
|
80
85
|
background var(--dur-fast) var(--ease),
|
|
@@ -142,6 +147,17 @@
|
|
|
142
147
|
padding: 10px 13px;
|
|
143
148
|
border-radius: 10px;
|
|
144
149
|
cursor: pointer;
|
|
150
|
+
/* What a browser paints on a <button> before any author rule runs. A consumer
|
|
151
|
+
reaches for <button> whenever the row has to work from the keyboard, so the
|
|
152
|
+
row states these rather than taking them from the element. `font` and not
|
|
153
|
+
`font-family`: Chrome's rule is the shorthand `font: 400 13.3333px Arial`,
|
|
154
|
+
and answering the family alone leaves a row 2.25px shorter in type 1.17px
|
|
155
|
+
smaller. Any font longhand a rule keeps goes after it. why: #251 */
|
|
156
|
+
width: 100%;
|
|
157
|
+
background: none;
|
|
158
|
+
border: 0;
|
|
159
|
+
text-align: left;
|
|
160
|
+
font: inherit;
|
|
145
161
|
transition: background var(--dur-fast) var(--ease);
|
|
146
162
|
}
|
|
147
163
|
.vopt:hover { background: var(--surface); }
|
|
@@ -174,6 +190,7 @@
|
|
|
174
190
|
border: 1px solid var(--border);
|
|
175
191
|
background: linear-gradient(145deg, var(--accent-strong), var(--purple));
|
|
176
192
|
color: var(--accent-contrast);
|
|
193
|
+
font: inherit;
|
|
177
194
|
font-weight: 600;
|
|
178
195
|
font-size: 12.5px;
|
|
179
196
|
display: grid;
|
package/src/tokens/tokens.css
CHANGED
|
@@ -42,8 +42,17 @@
|
|
|
42
42
|
--container: 1120px;
|
|
43
43
|
--measure: 860px;
|
|
44
44
|
|
|
45
|
-
/* -- Typography ---------------------------------------------------------
|
|
46
|
-
|
|
45
|
+
/* -- Typography ---------------------------------------------------------
|
|
46
|
+
* Two roles, not one family. --font-display is the brand voice — headings,
|
|
47
|
+
* brand lockups, large readouts — and --font-sans is what an application is
|
|
48
|
+
* actually made of: tables, fields, paragraphs, chat. Poppins is a geometric
|
|
49
|
+
* display grotesque and holds its character at heading sizes; at 13-14px it
|
|
50
|
+
* smears, worst of all in Cyrillic, which is where the kit spends most of its
|
|
51
|
+
* pixels. IBM Plex Sans is humanist and narrower, and its Cyrillic was drawn
|
|
52
|
+
* by the same team as its Latin.
|
|
53
|
+
* why: docs/specification.md#typefaces */
|
|
54
|
+
--font-display: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
55
|
+
--font-sans: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
47
56
|
--font-mono: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
|
|
48
57
|
|
|
49
58
|
--text-xs: 11px;
|