@apliteni/apliteni-ui 0.11.4 → 0.12.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/package.json +1 -1
- package/src/assets/icons.js +67 -4
- package/src/components/index.js +16 -2
package/package.json
CHANGED
package/src/assets/icons.js
CHANGED
|
@@ -6,7 +6,29 @@
|
|
|
6
6
|
//
|
|
7
7
|
// Each value is the INNER markup; icon() wraps it in the shared <svg>. Glyphs
|
|
8
8
|
// are grouped by domain — the flat ICONS map is what icon() looks up, and
|
|
9
|
-
// iconCategories drives the Storybook grid.
|
|
9
|
+
// iconCategories drives the Storybook grid.
|
|
10
|
+
//
|
|
11
|
+
// ---- Adding a glyph -------------------------------------------------------
|
|
12
|
+
//
|
|
13
|
+
// NAME it for what it depicts, not for the one place it is used: `trash`, not
|
|
14
|
+
// `deleteWorkspace`. camelCase, and a modifier follows its noun — `circleX`,
|
|
15
|
+
// `eyeOff`, `trendingUp` — so the family sorts together. A name is taken once;
|
|
16
|
+
// a second declaration of one is a gate failure, not a merge conflict.
|
|
17
|
+
//
|
|
18
|
+
// GROUP it by what it depicts, again rather than by caller. `chart` lives in
|
|
19
|
+
// DATA because it draws data, even when a comms panel is what renders it. If
|
|
20
|
+
// two groups both look right, the glyph belongs to the one whose other members
|
|
21
|
+
// it would sit beside in the catalogue. Groups are not tags: exactly one.
|
|
22
|
+
//
|
|
23
|
+
// PROVENANCE: the path comes from Lucide, unmodified, at the 24×24 / 1.7 house
|
|
24
|
+
// stroke — that is what keeps the set looking like one hand. Say which Lucide
|
|
25
|
+
// name it came from in the commit if the two differ. A hand-drawn path needs a
|
|
26
|
+
// reason in the commit message, because the next person cannot tell one from a
|
|
27
|
+
// traced one by looking.
|
|
28
|
+
//
|
|
29
|
+
// The gates: src/assets/icons.test.js holds one-group-per-glyph and the
|
|
30
|
+
// emitter's numbers, and stories/guidelines/iconography.test.js holds the
|
|
31
|
+
// icon-only list below. The written rules are on Guidelines / Iconography.
|
|
10
32
|
|
|
11
33
|
const NAV = {
|
|
12
34
|
chevronDown: '<path d="M6 9l6 6 6-6" stroke-linecap="round" stroke-linejoin="round"/>',
|
|
@@ -101,9 +123,6 @@ const COMMS = {
|
|
|
101
123
|
logout: '<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/>',
|
|
102
124
|
plug: '<path d="M12 22v-5"/><path d="M15 8V2"/><path d="M17 8a1 1 0 0 1 1 1v4a4 4 0 0 1-4 4h-4a4 4 0 0 1-4-4V9a1 1 0 0 1 1-1z"/><path d="M9 8V2"/>',
|
|
103
125
|
sparkle: '<path d="M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z"/><path d="M20 2v4"/><path d="M22 4h-4"/><circle cx="4" cy="20" r="2"/>',
|
|
104
|
-
card: '<rect x="1" y="4" width="22" height="16" rx="2" ry="2"/><line x1="1" y1="10" x2="23" y2="10"/>',
|
|
105
|
-
doc: '<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><polyline points="10 9 9 9 8 9"/>',
|
|
106
|
-
chart: '<line x1="18" y1="20" x2="18" y2="10"/><line x1="12" y1="20" x2="12" y2="4"/><line x1="6" y1="20" x2="6" y2="14"/>',
|
|
107
126
|
};
|
|
108
127
|
|
|
109
128
|
const BRAND = {
|
|
@@ -140,5 +159,49 @@ export const icon = (name, cls = '') =>
|
|
|
140
159
|
|
|
141
160
|
export const iconNames = Object.keys(ICONS);
|
|
142
161
|
|
|
162
|
+
// Which controls may be an icon and nothing else — a closed list, not a
|
|
163
|
+
// judgement call in review.
|
|
164
|
+
//
|
|
165
|
+
// The accessibility half was already held: every glyph is aria-hidden, so
|
|
166
|
+
// button({ iconOnly }) names itself from `label`. That says a nameless icon
|
|
167
|
+
// button cannot ship; it never said when a wordless one SHOULD. This does.
|
|
168
|
+
//
|
|
169
|
+
// A control whose action is on this list may drop its visible text. Everything
|
|
170
|
+
// else carries a label — including glyphs that feel obvious in isolation, like
|
|
171
|
+
// `gear` or `externalLink`, because a reader meets them one at a time and a
|
|
172
|
+
// toolbar is not a legend. Adding an entry is a decision recorded here, which
|
|
173
|
+
// is the point: the alternative rules read well and could not be gated.
|
|
174
|
+
export const iconOnlyAllowed = {
|
|
175
|
+
x: 'close or dismiss',
|
|
176
|
+
copy: 'copy to clipboard',
|
|
177
|
+
moreHorizontal: 'overflow menu',
|
|
178
|
+
moreVertical: 'overflow menu',
|
|
179
|
+
chevronDown: 'expand or collapse',
|
|
180
|
+
chevronUp: 'expand or collapse',
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
// What a glyph means when a component picks it for the reader rather than a
|
|
184
|
+
// caller naming it. Two rules hold the map together:
|
|
185
|
+
//
|
|
186
|
+
// a CIRCLED glyph is a state the system is in — circleCheck, circleX,
|
|
187
|
+
// circleAlert. It is reported to you and you cannot click it.
|
|
188
|
+
// a BARE glyph is an action you can take — x dismisses, check confirms,
|
|
189
|
+
// trash deletes.
|
|
190
|
+
//
|
|
191
|
+
// That split is what a danger toast needed: it used to render the same bare `x`
|
|
192
|
+
// twice, once meaning "this failed" and once meaning "make this go away". The
|
|
193
|
+
// bare x is now reserved for the close button, and status took the circle
|
|
194
|
+
// family the kit was already shipping and never using.
|
|
195
|
+
export const iconMeanings = {
|
|
196
|
+
circleCheck: 'a state: it succeeded',
|
|
197
|
+
circleX: 'a state: it failed',
|
|
198
|
+
circleAlert: 'a state: it needs attention',
|
|
199
|
+
info: 'a state: something worth knowing, no action required',
|
|
200
|
+
bolt: 'a state: it happened, with no verdict attached',
|
|
201
|
+
x: 'an action: close or dismiss this',
|
|
202
|
+
check: 'an action: confirm this',
|
|
203
|
+
trash: 'an action: delete this',
|
|
204
|
+
};
|
|
205
|
+
|
|
143
206
|
export const sun = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/></svg>';
|
|
144
207
|
export const moon = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"/></svg>';
|
package/src/components/index.js
CHANGED
|
@@ -16,6 +16,10 @@ export const esc = (s) => String(s == null ? '' : s).replace(/[&<>"]/g, (c) => (
|
|
|
16
16
|
// stops being decoration and becomes the control's ONLY accessible name. It is
|
|
17
17
|
// mirrored into aria-label + title, and an empty label falls back to the icon
|
|
18
18
|
// name rather than shipping a nameless button.
|
|
19
|
+
//
|
|
20
|
+
// That is the accessibility half, and it is not permission. WHEN a control may
|
|
21
|
+
// go wordless is a closed list — `iconOnlyAllowed` in src/assets/icons.js — and
|
|
22
|
+
// stories/guidelines/iconography.test.js reviews call sites against it.
|
|
19
23
|
export function button({
|
|
20
24
|
label = 'Button', variant = 'secondary', size = 'md', icon: ic, iconSvg, iconRight,
|
|
21
25
|
block = false, disabled = false, busy = false, type = 'button', href, iconOnly = false,
|
|
@@ -217,8 +221,18 @@ export function switchToggle({ checked = false, disabled = false, name, label =
|
|
|
217
221
|
export function callout({ variant, icon: ic = 'info', body } = {}) {
|
|
218
222
|
return `<div class="${cx('ui-callout', variant && `ui-callout--${variant}`)}"><span class="ui-callout__icon">${icon(ic)}</span><div>${body}</div></div>`;
|
|
219
223
|
}
|
|
220
|
-
// Default icon per status — overridable with `icon`.
|
|
221
|
-
|
|
224
|
+
// Default icon per status — overridable with `icon`. The circle family is not
|
|
225
|
+
// decoration: a circled glyph is a STATE the system reports, a bare one is an
|
|
226
|
+
// ACTION you can take (iconMeanings in src/assets/icons.js).
|
|
227
|
+
//
|
|
228
|
+
// This used to read `success: 'check', danger: 'x', warn: 'alert'`, which made
|
|
229
|
+
// a danger toast render the same bare `x` twice — once as the status, meaning
|
|
230
|
+
// "this failed", once as the close button, meaning "make this go away". Status
|
|
231
|
+
// took the circle glyphs the kit already shipped and never used, and the bare
|
|
232
|
+
// `x` now belongs to the close button alone.
|
|
233
|
+
const TOAST_ICON = {
|
|
234
|
+
success: 'circleCheck', danger: 'circleX', warn: 'circleAlert', info: 'info', neutral: 'bolt',
|
|
235
|
+
};
|
|
222
236
|
// A toast carries a status (colour) and a style (surface). Everything visual is
|
|
223
237
|
// token-driven: the status modifier sets --toast-accent/-glow/-on, the style
|
|
224
238
|
// modifier consumes them. `action` adds a trailing button ("Undo"/"Retry"),
|