@qeetrix/icons 1.0.7 โ 1.0.8
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 +219 -117
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
-
# Qeetrix Icons
|
|
3
|
+
# ๐จ Qeetrix Icons
|
|
4
4
|
|
|
5
5
|
**The icon and brand logo library for Qeet Group products.**
|
|
6
6
|
|
|
7
|
-
1,863 Lucide icons in round and sharp shapes,
|
|
8
|
-
tree-shakeable, fully typed React 19 components, all from one import.
|
|
7
|
+
1,863 Lucide icons in **round** and **sharp** shapes, **775 filled** variants, and **7,429 brand
|
|
8
|
+
logos**, as tree-shakeable, fully typed React 19 components, all from one import.
|
|
9
9
|
|
|
10
|
+
[](https://www.npmjs.com/package/@qeetrix/icons)
|
|
11
|
+
[](https://github.com/qeetgroup/qeetrix-icons/actions/workflows/ci.yml)
|
|
10
12
|

|
|
11
|
-

|
|
12
14
|

|
|
13
15
|

|
|
14
16
|

|
|
@@ -28,72 +30,103 @@ import { TrashIcon, StarIcon, GithubLogo } from "@qeetrix/icons";
|
|
|
28
30
|
```
|
|
29
31
|
|
|
30
32
|
> [!IMPORTANT]
|
|
31
|
-
> **
|
|
32
|
-
>
|
|
33
|
-
>
|
|
33
|
+
> **Versions 1.0.5 and later are a new library.** They replace the 1.0.0โ1.0.4 catalogue entirely
|
|
34
|
+
> with Lucide-based icons and brand logos. No earlier icon name, prop, type, or import path carries
|
|
35
|
+
> over. If you depend on the old set, pin `@qeetrix/icons@1.0.4` until you migrate.
|
|
34
36
|
|
|
35
37
|
---
|
|
36
38
|
|
|
37
|
-
## Contents
|
|
38
|
-
|
|
39
|
-
- [Why Qeetrix Icons](
|
|
40
|
-
- [At a glance](
|
|
41
|
-
- [Installation](
|
|
42
|
-
- [
|
|
43
|
-
- [
|
|
44
|
-
- [
|
|
45
|
-
- [
|
|
46
|
-
- [
|
|
47
|
-
- [
|
|
48
|
-
- [
|
|
49
|
-
- [
|
|
50
|
-
- [
|
|
51
|
-
- [
|
|
52
|
-
|
|
53
|
-
|
|
39
|
+
## ๐ Contents
|
|
40
|
+
|
|
41
|
+
- [โจ Why Qeetrix Icons](#-why-qeetrix-icons)
|
|
42
|
+
- [๐ At a glance](#-at-a-glance)
|
|
43
|
+
- [๐ฆ Installation](#-installation)
|
|
44
|
+
- [๐ Quick start](#-quick-start)
|
|
45
|
+
- [๐จ Icons](#-icons)
|
|
46
|
+
- [๐ท๏ธ Brand logos](#๏ธ-brand-logos)
|
|
47
|
+
- [๐ Catalogue and search](#-catalogue-and-search)
|
|
48
|
+
- [๐ Coming from lucide-react](#-coming-from-lucide-react)
|
|
49
|
+
- [๐ Design rules](#-design-rules)
|
|
50
|
+
- [๐งช Playground](#-playground)
|
|
51
|
+
- [โก Performance and package size](#-performance-and-package-size)
|
|
52
|
+
- [๐๏ธ How it is built](#๏ธ-how-it-is-built)
|
|
53
|
+
- [โ
Quality](#-quality)
|
|
54
|
+
- [๐ ๏ธ Development](#๏ธ-development)
|
|
55
|
+
- [๐ Documentation](#-documentation)
|
|
56
|
+
- [๐ข Releases](#-releases)
|
|
57
|
+
- [โ๏ธ License](#๏ธ-license)
|
|
58
|
+
|
|
59
|
+
## โจ Why Qeetrix Icons
|
|
54
60
|
|
|
55
61
|
[Lucide](https://lucide.dev) is a superb outline icon set, and [theSVG](https://thesvg.org)
|
|
56
62
|
collects thousands of brand logos. Qeetrix Icons turns them into one consistent, typed library for
|
|
57
63
|
every Qeet product (Qeet ID, Qeet Pay, Qeet Logs, Qeet Notify, Qeet People, Qeet AI) and adds what
|
|
58
64
|
neither provides:
|
|
59
65
|
|
|
60
|
-
- **Filled variants.** Lucide is outline-only.
|
|
66
|
+
- ๐ **Filled variants.** Lucide is outline-only. 775 icons gain a filled drawing for selected,
|
|
61
67
|
active, and favourite states, derived from the outline with Skia path operations and reviewed
|
|
62
|
-
one by one.
|
|
63
|
-
- **A complete sharp style.** Every icon, outline and filled, also comes with square caps,
|
|
68
|
+
one by one, category by category.
|
|
69
|
+
- ๐ท **A complete sharp style.** Every icon, outline and filled, also comes with square caps,
|
|
64
70
|
mitered joins, and squared corners, behind a single `shape` prop.
|
|
65
|
-
- **One API for everything.** Icons and logos share naming, sizing, accessibility defaults, and
|
|
71
|
+
- ๐งฉ **One API for everything.** Icons and logos share naming, sizing, accessibility defaults, and
|
|
66
72
|
typing. A `variant` the icon or logo doesn't have is a compile-time error.
|
|
67
|
-
- **Logos you can trust.** Every logo is embedded byte for byte as published, validated for
|
|
73
|
+
- ๐ก๏ธ **Logos you can trust.** Every logo is embedded byte for byte as published, validated for
|
|
68
74
|
safety, labelled with the background it is drawn for, and carries its own license metadata.
|
|
69
|
-
- **Searchable catalogues.** Tags, categories, Lucide's former names, RTL behaviour, logo
|
|
75
|
+
- ๐ **Searchable catalogues.** Tags, categories, Lucide's former names, RTL behaviour, logo
|
|
70
76
|
collections, colours, and licenses, published as data for docs sites and pickers.
|
|
77
|
+
- ๐ฒ **Zero runtime cost you didn't ask for.** No runtime dependencies, no hooks, no side
|
|
78
|
+
effects: bundlers keep only the icons and logos you import.
|
|
71
79
|
|
|
72
|
-
## At a glance
|
|
80
|
+
## ๐ At a glance
|
|
73
81
|
|
|
74
82
|
| | |
|
|
75
83
|
|:--|:--|
|
|
76
|
-
| **Icons** | 1,863 from Lucide 1.52.0, in 42 categories, with Lucide's names and tags |
|
|
77
|
-
| **Shapes** | `round` (Lucide's drawing, the default) and `sharp`, for every icon |
|
|
78
|
-
| **Variants** | `outline` for every icon; `filled` for
|
|
79
|
-
| **Brand logos** | 7,429 from theSVG 3.3.12: brands, community, auth badges, AWS, Azure, Google Cloud, Kubernetes |
|
|
80
|
-
| **Logo files** | 13,401 variants (default, mono, wordmark, light, dark, colour, โฆ), embedded unmodified |
|
|
81
|
-
| **Grid** | 24 ร 24, 2-unit stroke, 1-unit padding, `currentColor` |
|
|
82
|
-
| **Runtime** | React 19 peer dependency only; no runtime dependencies; no hooks |
|
|
83
|
-
| **Module format** | ESM with TypeScript declarations; every module free of side effects |
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
| ๐จ **Icons** | 1,863 from Lucide 1.52.0, in Lucide's 42 categories, with Lucide's names and tags |
|
|
85
|
+
| ๐ท **Shapes** | `round` (Lucide's drawing, the default) and `sharp`, for every icon |
|
|
86
|
+
| ๐ **Variants** | `outline` for every icon; `filled` for 775, in both shapes |
|
|
87
|
+
| ๐ท๏ธ **Brand logos** | 7,429 from theSVG 3.3.12: brands, community, auth badges, AWS, Azure, Google Cloud, Kubernetes |
|
|
88
|
+
| ๐๏ธ **Logo files** | 13,401 variants (default, mono, wordmark, light, dark, colour, โฆ), embedded unmodified |
|
|
89
|
+
| ๐ **Grid** | 24 ร 24, 2-unit stroke, 1-unit padding, `currentColor` |
|
|
90
|
+
| โ๏ธ **Runtime** | React 19 peer dependency only; no runtime dependencies; no hooks |
|
|
91
|
+
| ๐ฆ **Module format** | ESM with TypeScript declarations; every module free of side effects |
|
|
92
|
+
| โ๏ธ **RTL** | 18 reading-direction concepts flagged `mirror` in the catalogue |
|
|
93
|
+
| โ
**Tests** | 638 tests in 11 suites, including a packed-tarball consumer test |
|
|
94
|
+
|
|
95
|
+
## ๐ฆ Installation
|
|
86
96
|
|
|
87
97
|
```bash
|
|
88
98
|
bun add @qeetrix/icons
|
|
99
|
+
# or: npm install @qeetrix/icons
|
|
89
100
|
```
|
|
90
101
|
|
|
91
102
|
React 19 is the only peer dependency. The package ships compiled ESM with type declarations, so
|
|
92
103
|
it works in Vite, Next.js, TanStack Start, and React Server Components without extra setup.
|
|
93
104
|
|
|
94
|
-
##
|
|
105
|
+
## ๐ Quick start
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
import { BellIcon, SearchIcon, SettingsIcon, StarIcon } from "@qeetrix/icons";
|
|
109
|
+
|
|
110
|
+
export function Toolbar({ starred }: { starred: boolean }) {
|
|
111
|
+
return (
|
|
112
|
+
<nav className="flex items-center gap-3 text-zinc-700">
|
|
113
|
+
<SearchIcon size={20} />
|
|
114
|
+
<BellIcon variant="filled" aria-label="Notifications" />
|
|
115
|
+
<StarIcon variant={starred ? "filled" : "outline"} className="text-amber-500" />
|
|
116
|
+
<SettingsIcon shape="sharp" strokeWidth={1.5} />
|
|
117
|
+
</nav>
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
- ๐จ Icons draw in `currentColor`: they follow the text colour around them.
|
|
123
|
+
- ๐ `size` takes pixels or any CSS length; the default is 24.
|
|
124
|
+
- ๐ท Switch a whole UI to the sharp style by passing `shape="sharp"`, for example from your own
|
|
125
|
+
wrapper or theme.
|
|
126
|
+
|
|
127
|
+
## ๐จ Icons
|
|
95
128
|
|
|
96
|
-
### Shapes and variants
|
|
129
|
+
### ๐ท Shapes and variants
|
|
97
130
|
|
|
98
131
|
Every icon has two shapes, and some icons have two variants. Pick one with two props:
|
|
99
132
|
|
|
@@ -103,10 +136,11 @@ Every icon has two shapes, and some icons have two variants. Pick one with two p
|
|
|
103
136
|
| **`shape="sharp"`** | `<StarIcon shape="sharp" />` | `<StarIcon shape="sharp" variant="filled" />` |
|
|
104
137
|
|
|
105
138
|
Filled drawings exist only where the solid form is clean and meaningful: badges, toggles, nav
|
|
106
|
-
items, devices, media, and many more. Open-line icons such as arrows, chevrons,
|
|
107
|
-
outline-only by
|
|
139
|
+
items, devices, media, files, people, and many more. Open-line icons such as arrows, chevrons,
|
|
140
|
+
and text marks, and icons whose outline is clipped open around a badge, are outline-only by
|
|
141
|
+
design.
|
|
108
142
|
|
|
109
|
-
### Props
|
|
143
|
+
### ๐๏ธ Props
|
|
110
144
|
|
|
111
145
|
Every icon accepts the native `<svg>` props (including `ref`, `className`, `style`, and event
|
|
112
146
|
handlers) plus:
|
|
@@ -119,16 +153,14 @@ handlers) plus:
|
|
|
119
153
|
| `strokeWidth` | `number \| string` | `2` | Overrides the outline stroke (try 1.5 for dense UIs). |
|
|
120
154
|
| `aria-label` | `string` | | Names the icon for assistive technology. |
|
|
121
155
|
|
|
122
|
-
Icons draw in `currentColor`, so they follow the surrounding text colour: set `color` with CSS or
|
|
123
|
-
a utility class.
|
|
124
|
-
|
|
125
156
|
```tsx
|
|
126
157
|
<SearchIcon size={20} className="text-muted" />
|
|
127
158
|
<BellIcon variant="filled" aria-label="Notifications" />
|
|
128
159
|
<SettingsIcon shape="sharp" strokeWidth={1.5} />
|
|
160
|
+
<HeartIcon size="1.25em" style={{ color: "crimson" }} />
|
|
129
161
|
```
|
|
130
162
|
|
|
131
|
-
### Naming
|
|
163
|
+
### ๐ค Naming
|
|
132
164
|
|
|
133
165
|
Each icon is one named export: its Lucide name in PascalCase plus `Icon`. Categories never appear
|
|
134
166
|
in names or import paths.
|
|
@@ -142,13 +174,13 @@ in names or import paths.
|
|
|
142
174
|
Lucide's former names (`trash-2` for `trash`, for example) are listed in the catalogue for search
|
|
143
175
|
and migration, but are not exported.
|
|
144
176
|
|
|
145
|
-
### Type safety
|
|
177
|
+
### ๐งท Type safety
|
|
146
178
|
|
|
147
179
|
`variant` is narrowed per icon, so asking for a drawing that doesn't exist fails at compile time:
|
|
148
180
|
|
|
149
181
|
```tsx
|
|
150
|
-
<StarIcon variant="filled" /> //
|
|
151
|
-
<ArrowLeftIcon variant="filled" /> //
|
|
182
|
+
<StarIcon variant="filled" /> // โ
star has a filled drawing
|
|
183
|
+
<ArrowLeftIcon variant="filled" /> // โ type error: arrow-left is outline-only
|
|
152
184
|
```
|
|
153
185
|
|
|
154
186
|
To accept any icon, for example in a button component, type the prop as
|
|
@@ -167,15 +199,16 @@ function ToolbarButton({ icon: Icon, label }: { icon: ComponentType<IconProps<"o
|
|
|
167
199
|
}
|
|
168
200
|
```
|
|
169
201
|
|
|
170
|
-
### Accessibility and RTL
|
|
202
|
+
### โฟ Accessibility and RTL
|
|
171
203
|
|
|
172
204
|
- Icons are **decorative by default**: `aria-hidden="true"` and `focusable="false"`. A non-empty
|
|
173
205
|
`aria-label` or `aria-labelledby` turns an icon into `role="img"`. Explicit props always win.
|
|
174
206
|
- Each icon's **directionality** is in the catalogue: `mirror` for reading-direction concepts
|
|
175
207
|
such as undo, reply, send, log-in, and indentation, and `preserve` for everything else.
|
|
176
|
-
Physical arrows and chevrons never mirror.
|
|
208
|
+
Physical arrows and chevrons never mirror. The library never flips an icon itself; your RTL
|
|
209
|
+
layer decides. See [docs/rtl.md](docs/rtl.md).
|
|
177
210
|
|
|
178
|
-
## Brand logos
|
|
211
|
+
## ๐ท๏ธ Brand logos
|
|
179
212
|
|
|
180
213
|
```tsx
|
|
181
214
|
import { GithubLogo, SlackLogo, StripeLogo } from "@qeetrix/icons";
|
|
@@ -183,6 +216,7 @@ import { GithubLogo, SlackLogo, StripeLogo } from "@qeetrix/icons";
|
|
|
183
216
|
<GithubLogo /> // the default file, 24 px tall
|
|
184
217
|
<GithubLogo variant="wordmark" height={32} /> // any file the logo has
|
|
185
218
|
<SlackLogo height="2em" aria-label="Slack" /> // CSS lengths work too
|
|
219
|
+
<StripeLogo variant="mono" loading="lazy" /> // native <img> props pass through
|
|
186
220
|
```
|
|
187
221
|
|
|
188
222
|
Each logo renders its **published SVG file, unmodified**, as an `<img>`. Nothing in the artwork is
|
|
@@ -200,7 +234,7 @@ Components.
|
|
|
200
234
|
Other native `<img>` props (`className`, `style`, `loading`, `decoding`, โฆ) pass through. Logos
|
|
201
235
|
keep their brand colours by design, so CSS cannot recolour them.
|
|
202
236
|
|
|
203
|
-
### Names and collections
|
|
237
|
+
### ๐๏ธ Names and collections
|
|
204
238
|
|
|
205
239
|
A logo's name is its slug in PascalCase plus `Logo`: `GithubLogo`, `GoogleCloudLogo`. Slugs that
|
|
206
240
|
start with a digit get a `Brand` prefix (`Brand1passwordLogo`). Icons always end in `Icon` and
|
|
@@ -208,14 +242,14 @@ logos in `Logo`, so the two families never collide.
|
|
|
208
242
|
|
|
209
243
|
| Collection | Logos |
|
|
210
244
|
|:--|--:|
|
|
211
|
-
| Brands | 4,691 |
|
|
212
|
-
| Auth badges | 860 |
|
|
213
|
-
| AWS architecture | 739 |
|
|
214
|
-
| Azure architecture | 626 |
|
|
215
|
-
| Community | 259 |
|
|
216
|
-
| Google Cloud architecture | 214 |
|
|
217
|
-
| Kubernetes architecture | 38 |
|
|
218
|
-
| Unlisted | 2 |
|
|
245
|
+
| ๐ข Brands | 4,691 |
|
|
246
|
+
| ๐ Auth badges | 860 |
|
|
247
|
+
| โ๏ธ AWS architecture | 739 |
|
|
248
|
+
| โ๏ธ Azure architecture | 626 |
|
|
249
|
+
| ๐ฅ Community | 259 |
|
|
250
|
+
| โ๏ธ Google Cloud architecture | 214 |
|
|
251
|
+
| โธ๏ธ Kubernetes architecture | 38 |
|
|
252
|
+
| ๐๏ธ Unlisted | 2 |
|
|
219
253
|
|
|
220
254
|
theSVG's own `light` and `dark` labels are inverted for most logos, so the catalogue records the
|
|
221
255
|
background each file is actually drawn for (`light`, `dark`, or `any`), measured from its colours.
|
|
@@ -228,7 +262,7 @@ background each file is actually drawn for (`light`, `dark`, or `any`), measured
|
|
|
228
262
|
> see [licenses/third-party-logos.md](licenses/third-party-logos.md) and
|
|
229
263
|
> [docs/logos.md](docs/logos.md#licensing-and-trademarks).
|
|
230
264
|
|
|
231
|
-
## Catalogue and search
|
|
265
|
+
## ๐ Catalogue and search
|
|
232
266
|
|
|
233
267
|
Machine-readable catalogues for docs sites, icon pickers, and tooling. They are never needed to
|
|
234
268
|
render, and the package root never imports them.
|
|
@@ -261,7 +295,44 @@ const wordmarks = logoManifest.logos.filter(
|
|
|
261
295
|
| `tags`, `aliases` | `aliases`, `hex` (brand colour) |
|
|
262
296
|
| `directionality` | `license`, `website`, `guidelines`, `source` |
|
|
263
297
|
|
|
264
|
-
##
|
|
298
|
+
## ๐ Coming from lucide-react
|
|
299
|
+
|
|
300
|
+
The artwork is Lucide's, so most screens move over with an import change:
|
|
301
|
+
|
|
302
|
+
| `lucide-react` | `@qeetrix/icons` |
|
|
303
|
+
|:--|:--|
|
|
304
|
+
| `import { Star } from "lucide-react"` | `import { StarIcon } from "@qeetrix/icons"` |
|
|
305
|
+
| `<Star size={20} strokeWidth={1.5} />` | `<StarIcon size={20} strokeWidth={1.5} />` (same props) |
|
|
306
|
+
| `<Star className="text-amber-500" />` | `<StarIcon className="text-amber-500" />` (same `currentColor`) |
|
|
307
|
+
| Outline only | Add `variant="filled"` where a filled drawing exists |
|
|
308
|
+
| Round only | Add `shape="sharp"` for the sharp style |
|
|
309
|
+
| Logos not included | `GithubLogo`, `SlackLogo`, โฆ from the same package |
|
|
310
|
+
|
|
311
|
+
Names follow Lucide 1.52.0, so a few older lucide-react names differ (`Trash2` is `TrashIcon`
|
|
312
|
+
here); the catalogue's `aliases` field maps them. `absoluteStrokeWidth` is not supported.
|
|
313
|
+
|
|
314
|
+
## ๐ Design rules
|
|
315
|
+
|
|
316
|
+
Every derived drawing follows the same rules, so families look alike and nothing surprises you at
|
|
317
|
+
16 px.
|
|
318
|
+
|
|
319
|
+
| | Round filled | Sharp (outline and filled) |
|
|
320
|
+
|:--|:--|:--|
|
|
321
|
+
| ๐ **Footprint** | Same painted extent as the outline | Same drawing, square caps, mitered joins (miter limit 4) |
|
|
322
|
+
| ๐งฑ **Bodies and details** | Bodies solid; details cut as 2-unit negative lines | Small corner roundings become sharp corners; acute tips come to a point |
|
|
323
|
+
| โ๏ธ **Cuts that reach an edge** | Run straight through, so parts separate cleanly (calendar header, file dog-ear, mail flap) | Identical to round: both shapes part the same way |
|
|
324
|
+
| ๐ **Attached parts** | Legs, handles, stands, cords stay joined | Line ends that stop on another stroke are trimmed so no cap pokes out |
|
|
325
|
+
| ๐ช **Layers** | Front parts sit in a 1-unit gap (clipboard clip, copy's front sheet, wheels) | Same roles as round, part for part |
|
|
326
|
+
| ๐ฒ **Border** | Inside Lucide's 1-unit padding | Never crosses it: a corner that would is cut flat, minimally, symmetrically |
|
|
327
|
+
| โช **Dots** | Round holes | UI dots square (ellipsis, bullets, keys, pips); figurative dots round (eyes, spots, drops) |
|
|
328
|
+
| ๐ฟ **Organic shapes** | As the outline | Circles, faces, animals, fruit, hands, and coastlines stay round |
|
|
329
|
+
| ๐ค **Letters** | As the outline | An A's apex stays level with the letters beside it |
|
|
330
|
+
|
|
331
|
+
Where no rule gives a clean result, a reviewed, hand-drawn override takes the derivation's place.
|
|
332
|
+
Full detail: [docs/filled.md](docs/filled.md), [docs/sharp.md](docs/sharp.md), and
|
|
333
|
+
[docs/design.md](docs/design.md).
|
|
334
|
+
|
|
335
|
+
## ๐งช Playground
|
|
265
336
|
|
|
266
337
|
An internal, unpublished playground for browsing and visual review, with separate **Icons** and
|
|
267
338
|
**Logos** pages:
|
|
@@ -270,30 +341,33 @@ An internal, unpublished playground for browsing and visual review, with separat
|
|
|
270
341
|
bun run playground
|
|
271
342
|
```
|
|
272
343
|
|
|
273
|
-
- **Icons:** category sidebar, search across names, tags, and former names, Round/Sharp and
|
|
344
|
+
- ๐จ **Icons:** category sidebar, search across names, tags, and former names, Round/Sharp and
|
|
274
345
|
variant switches, size, stroke, and colour controls, and an inspector with every shape and
|
|
275
346
|
variant, real-size previews, construction grid, light/dark surfaces, RTL preview, and copyable
|
|
276
347
|
JSX.
|
|
277
|
-
- **Logos:** collections, license and variant filters, a light/dark/transparent background
|
|
348
|
+
- ๐ท๏ธ **Logos:** collections, license and variant filters, a light/dark/transparent background
|
|
278
349
|
switch, cards at each logo's true aspect ratio, and an inspector with every file on the
|
|
279
350
|
background it's drawn for, license warnings, and brand links.
|
|
280
|
-
- **Everywhere:** a โK command palette across icons and logos, shareable URLs, keyboard
|
|
351
|
+
- โจ๏ธ **Everywhere:** a โK command palette across icons and logos, shareable URLs, keyboard
|
|
281
352
|
navigation, and light and dark themes.
|
|
282
353
|
|
|
283
|
-
## Performance
|
|
354
|
+
## โก Performance and package size
|
|
284
355
|
|
|
285
|
-
- **Production builds include only what you import.** Every module is free of side effects and
|
|
286
|
-
the root is a list of static re-exports, so bundlers drop every unused icon and logo.
|
|
287
|
-
|
|
356
|
+
- ๐ฒ **Production builds include only what you import.** Every module is free of side effects and
|
|
357
|
+
the root is a list of static re-exports, so bundlers drop every unused icon and logo. Tests
|
|
358
|
+
bundle real consumers to prove it.
|
|
359
|
+
- ๐ฅ **One import, everything included.** Importing `@qeetrix/icons` gives you all icons and logos.
|
|
288
360
|
In Node (server rendering, test runners) the first import therefore loads every module:
|
|
289
361
|
measured cold on a development laptop, about 20 s and 360 MB with the logos, against about
|
|
290
362
|
1.8 s for icons alone. It is paid once per process.
|
|
291
|
-
- **Dev servers** that pre-bundle a dependency's root, such as Vite and Next.js, process the whole
|
|
363
|
+
- ๐ฅ **Dev servers** that pre-bundle a dependency's root, such as Vite and Next.js, process the whole
|
|
292
364
|
package on the first start after installing or upgrading, then reuse their cache.
|
|
293
|
-
- **Per-icon imports** are available when you need the leanest possible module graph:
|
|
365
|
+
- ๐ชถ **Per-icon imports** are available when you need the leanest possible module graph:
|
|
294
366
|
`import { TrashIcon } from "@qeetrix/icons/icons/trash"`.
|
|
367
|
+
- ๐ฆ **Package:** about 10.7 MB packed and 50.7 MB unpacked, almost all of it logo data. Only
|
|
368
|
+
compiled code and licenses ship; no source SVGs.
|
|
295
369
|
|
|
296
|
-
## How it is built
|
|
370
|
+
## ๐๏ธ How it is built
|
|
297
371
|
|
|
298
372
|
Every source file is written by a tool from a pinned upstream release, and everything generated
|
|
299
373
|
is committed, validated in CI, and reproducible.
|
|
@@ -304,6 +378,7 @@ flowchart LR
|
|
|
304
378
|
RO -->|derive:filled| RF["icons/round-filled"]
|
|
305
379
|
RO -->|derive:sharp| SO["icons/sharp-outline"]
|
|
306
380
|
SO -->|derive:sharp| SF["icons/sharp-filled"]
|
|
381
|
+
C["config/derived ยท config/overrides"] -.-> RF & SO & SF
|
|
307
382
|
RO & RF & SO & SF -->|check:icons ยท generate| GI["src/generated/icons"]
|
|
308
383
|
T["theSVG 3.3.12"] -->|sync:brands| B["icons/brand-icons"]
|
|
309
384
|
B -->|check:brands ยท generate:logos| GL["src/generated/logos"]
|
|
@@ -311,22 +386,28 @@ flowchart LR
|
|
|
311
386
|
GL --> P
|
|
312
387
|
```
|
|
313
388
|
|
|
314
|
-
- **Filled drawings** are derived with CanvasKit (Skia) path operations from per-category recipes
|
|
389
|
+
- ๐ **Filled drawings** are derived with CanvasKit (Skia) path operations from per-category recipes
|
|
315
390
|
in [config/derived/](config/derived/README.md): bodies filled to the outline's painted extent,
|
|
316
|
-
details cut as negative lines
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
391
|
+
details cut as negative lines, crossing lines cleared by a gap. See
|
|
392
|
+
[docs/filled.md](docs/filled.md).
|
|
393
|
+
- ๐ท **Sharp drawings** square corner roundings at their tangent intersections, point acute tips,
|
|
394
|
+
and then fit the whole icon: nothing crosses the padding, no cap pokes past the stroke it ends
|
|
395
|
+
on, joined strokes form one corner, and mirror twins get the same cut. See
|
|
321
396
|
[docs/sharp.md](docs/sharp.md).
|
|
322
|
-
- **
|
|
397
|
+
- โ๏ธ **Overrides:** 78 hand-drawn replacements in `config/overrides/` cover the few drawings rules
|
|
398
|
+
cannot get right. Each is stamped with the SHA-256 of the outline it was drawn against, so a
|
|
399
|
+
Lucide upgrade flags it for review instead of silently drifting.
|
|
400
|
+
- ๐ท๏ธ **Logos** are copied byte for byte from a pinned theSVG commit, validated (no scripts, event
|
|
323
401
|
handlers, or external references), and embedded as lossless `data:` URIs. See
|
|
324
402
|
[docs/logos.md](docs/logos.md).
|
|
325
403
|
|
|
326
|
-
### Repository layout
|
|
404
|
+
### ๐๏ธ Repository layout
|
|
327
405
|
|
|
328
406
|
```text
|
|
329
|
-
config/
|
|
407
|
+
config/
|
|
408
|
+
derived/ Per-category tables: filled recipes and roles, keepRound, tipHeight
|
|
409
|
+
overrides/ Hand-drawn, hash-stamped replacements for derived drawings
|
|
410
|
+
lucide.json, brands.json, categories.ts, icon-system.ts, icon-metadata.ts, โฆ
|
|
330
411
|
icons/
|
|
331
412
|
round-outline/ Lucide outlines, unchanged
|
|
332
413
|
round-filled/ Derived filled drawings
|
|
@@ -345,7 +426,23 @@ tests/ Vitest suites, including a packed-tarball consumer test
|
|
|
345
426
|
docs/ Design, API, pipeline, and process documentation
|
|
346
427
|
```
|
|
347
428
|
|
|
348
|
-
##
|
|
429
|
+
## โ
Quality
|
|
430
|
+
|
|
431
|
+
- ๐งพ **Validation:** every source SVG is checked against 24 rules (`QXI-*` codes): structure,
|
|
432
|
+
allowed elements and attributes, paint, the grid, naming, categories, duplicates, and that every
|
|
433
|
+
icon has all its drawings in both shapes. See [docs/validation.md](docs/validation.md).
|
|
434
|
+
- ๐ฒ **Border proof:** a test measures every sharp drawing with CanvasKit and fails if anything
|
|
435
|
+
paints past the padding where the round drawing doesn't. The few curved ends too short to trim
|
|
436
|
+
are listed with their measured overshoot, and none may get worse.
|
|
437
|
+
- ๐ **Reproducibility:** `check:filled`, `check:sharp`, `check:generated`, and `check:logos` fail
|
|
438
|
+
if any derived or generated file differs from what the tools produce.
|
|
439
|
+
- ๐ฆ **Real consumers:** the package test packs the tarball, installs it in a fresh project,
|
|
440
|
+
typechecks strict consumers under `bundler` and `nodenext` resolution, renders icons in both
|
|
441
|
+
shapes, and bundles them to prove tree-shaking.
|
|
442
|
+
- ๐ **Visual review:** every filled and sharp drawing was reviewed by eye at 64, 24, and 16 px,
|
|
443
|
+
category by category. See [docs/visual-qa.md](docs/visual-qa.md).
|
|
444
|
+
|
|
445
|
+
## ๐ ๏ธ Development
|
|
349
446
|
|
|
350
447
|
Bun only (1.3.14), strict TypeScript, ESM, Biome, and Vitest.
|
|
351
448
|
|
|
@@ -356,56 +453,61 @@ bun run lint && bun run typecheck && bun run test
|
|
|
356
453
|
|
|
357
454
|
| Area | Commands |
|
|
358
455
|
|:--|:--|
|
|
359
|
-
| Quality | `lint`, `typecheck`, `test`, `build` |
|
|
360
|
-
| Icons | `sync:lucide [version]`, `derive:filled`, `derive:sharp`, `generate` |
|
|
361
|
-
|
|
|
362
|
-
|
|
|
363
|
-
|
|
|
364
|
-
|
|
|
456
|
+
| โ
Quality | `lint`, `typecheck`, `test`, `build` |
|
|
457
|
+
| ๐จ Icons | `sync:lucide [version]`, `derive:filled`, `derive:sharp`, `generate` |
|
|
458
|
+
| ๐ฏ One category | `derive:filled --category <id>`, `derive:sharp --category <id>` |
|
|
459
|
+
| โ๏ธ Overrides | `stamp:override <file>` |
|
|
460
|
+
| ๐ Icon checks | `check:icons`, `check:filled`, `check:sharp`, `check:generated` |
|
|
461
|
+
| ๐ท๏ธ Logos | `sync:brands [commit]`, `generate:logos` |
|
|
462
|
+
| ๐ Logo checks | `check:brands`, `check:logos` |
|
|
463
|
+
| ๐งช Playground | `playground`, `playground:build` |
|
|
365
464
|
|
|
366
465
|
Ground rules:
|
|
367
466
|
|
|
368
|
-
- **Never hand-edit tool-written files**: `icons/`, `config/lucide.json`, `config/brands.json`,
|
|
467
|
+
- ๐ซ **Never hand-edit tool-written files**: `icons/`, `config/lucide.json`, `config/brands.json`,
|
|
369
468
|
`config/categories.ts`, `src/generated/`, `icon-manifest.json`, or `licenses/third-party-logos.md`.
|
|
370
469
|
Change the inputs and rerun the tool.
|
|
371
|
-
- **`sync:lucide` and `sync:brands` leave the repository consistent**: they re-derive and
|
|
470
|
+
- ๐ **`sync:lucide` and `sync:brands` leave the repository consistent**: they re-derive and
|
|
372
471
|
regenerate everything downstream.
|
|
373
|
-
- **A missing or flawed outline belongs upstream** in Lucide; a filled or sharp result is changed
|
|
472
|
+
- โฌ๏ธ **A missing or flawed outline belongs upstream** in Lucide; a filled or sharp result is changed
|
|
374
473
|
through its category's file in [config/derived/](config/derived/README.md), an override, or the
|
|
375
474
|
sharp rules.
|
|
376
|
-
- **CI and the release gate run** lint, typecheck, tests, every `check:*` command, the build, and
|
|
475
|
+
- ๐ค **CI and the release gate run** lint, typecheck, tests, every `check:*` command, the build, and
|
|
377
476
|
the playground build.
|
|
378
477
|
|
|
379
|
-
## Documentation
|
|
478
|
+
## ๐ Documentation
|
|
380
479
|
|
|
381
480
|
| Guide | |
|
|
382
481
|
|:--|:--|
|
|
383
|
-
| [API](docs/api.md) | Entry points, props, types, the catalogue schema, and versioning |
|
|
384
|
-
| [Design](docs/design.md) | Grid, stroke, padding, and how filled and sharp drawings are formed |
|
|
385
|
-
| [Filled drawings](docs/filled.md) | Roles, inference, recipes, and how to add a filled icon |
|
|
386
|
-
| [Sharp style](docs/sharp.md) | Sharpening rules,
|
|
387
|
-
| [Brand logos](docs/logos.md) | Sync, catalogue, components, licensing, and performance |
|
|
388
|
-
| [Lucide](docs/lucide.md) | What comes from Lucide, syncing, and upgrading |
|
|
389
|
-
| [Naming](docs/naming.md) ยท [Accessibility](docs/accessibility.md) ยท [RTL](docs/rtl.md) | Conventions |
|
|
390
|
-
| [Architecture](docs/architecture.md) ยท [Generation](docs/generation.md) ยท [Validation](docs/validation.md) | How the pipeline works |
|
|
391
|
-
| [Visual QA](docs/visual-qa.md) ยท [Contributing](docs/contributing.md) ยท [Releases](docs/releases.md) | Process |
|
|
482
|
+
| ๐งฉ [API](docs/api.md) | Entry points, props, types, the catalogue schema, and versioning |
|
|
483
|
+
| ๐ [Design](docs/design.md) | Grid, stroke, padding, and how filled and sharp drawings are formed |
|
|
484
|
+
| ๐ [Filled drawings](docs/filled.md) | Roles, inference, recipes, overrides, and how to add a filled icon |
|
|
485
|
+
| ๐ท [Sharp style](docs/sharp.md) | Sharpening rules, fitting, kept-round elements, letter heights |
|
|
486
|
+
| ๐ท๏ธ [Brand logos](docs/logos.md) | Sync, catalogue, components, licensing, and performance |
|
|
487
|
+
| ๐ชถ [Lucide](docs/lucide.md) | What comes from Lucide, syncing, and upgrading |
|
|
488
|
+
| ๐ค [Naming](docs/naming.md) ยท โฟ [Accessibility](docs/accessibility.md) ยท โ๏ธ [RTL](docs/rtl.md) | Conventions |
|
|
489
|
+
| ๐๏ธ [Architecture](docs/architecture.md) ยท โ๏ธ [Generation](docs/generation.md) ยท ๐งพ [Validation](docs/validation.md) | How the pipeline works |
|
|
490
|
+
| ๐ [Visual QA](docs/visual-qa.md) ยท ๐ค [Contributing](docs/contributing.md) ยท ๐ข [Releases](docs/releases.md) | Process |
|
|
392
491
|
|
|
393
492
|
The full index is [docs/README.md](docs/README.md).
|
|
394
493
|
|
|
395
|
-
## Releases
|
|
494
|
+
## ๐ข Releases
|
|
396
495
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
496
|
+
- ๐ท๏ธ **Published on npm** as [`@qeetrix/icons`](https://www.npmjs.com/package/@qeetrix/icons),
|
|
497
|
+
with signed provenance from GitHub Actions, and as a GitHub Release for each version.
|
|
498
|
+
- ๐ข **Versioning:** the Version workflow raises the patch version on every pull request unless
|
|
499
|
+
it is already raised; merging to `main` publishes that version, tags it, and opens the GitHub
|
|
500
|
+
Release. A Rollback workflow moves the `latest` tag back to an earlier version.
|
|
501
|
+
- ๐ **Changes** are recorded in [CHANGELOG.md](CHANGELOG.md). Read
|
|
502
|
+
[docs/releases.md](docs/releases.md) before any release work.
|
|
401
503
|
|
|
402
|
-
## License
|
|
504
|
+
## โ๏ธ License
|
|
403
505
|
|
|
404
|
-
- **Package code:** MIT ยฉ Qeet Group.
|
|
405
|
-
- **Icons:** the artwork, the derived filled and sharp drawings, and the generated icon components
|
|
506
|
+
- ๐ป **Package code:** MIT ยฉ Qeet Group.
|
|
507
|
+
- ๐จ **Icons:** the artwork, the derived filled and sharp drawings, and the generated icon components
|
|
406
508
|
are based on [Lucide](https://lucide.dev), ISC ยฉ Lucide Icons and Contributors. Some Lucide icons
|
|
407
509
|
derive from Feather, MIT ยฉ Cole Bemis.
|
|
408
|
-
- **Brand logos:** each logo keeps its own license (public domain, permissive, attribution,
|
|
510
|
+
- ๐ท๏ธ **Brand logos:** each logo keeps its own license (public domain, permissive, attribution,
|
|
409
511
|
share-alike, no-derivatives, non-commercial, copyleft, or none), listed in
|
|
410
512
|
[licenses/third-party-logos.md](licenses/third-party-logos.md). theSVG's own code is MIT ยฉ
|
|
411
513
|
thesvg.org. Logos are trademarks of their owners, shown for identification only.
|
|
@@ -413,7 +515,7 @@ release work.
|
|
|
413
515
|
`package.json` declares `"license": "SEE LICENSE IN LICENSE"`; the full notices are in
|
|
414
516
|
[LICENSE](LICENSE).
|
|
415
517
|
|
|
416
|
-
### Acknowledgements
|
|
518
|
+
### ๐ Acknowledgements
|
|
417
519
|
|
|
418
520
|
Built on [Lucide](https://lucide.dev) and [Feather](https://feathericons.com) for the icons,
|
|
419
521
|
[theSVG](https://thesvg.org), [Simple Icons](https://simpleicons.org),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qeetrix/icons",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Qeetrix Icons โ Lucide icons in round and sharp shapes with derived filled variants, plus theSVG brand logos, as tree-shakeable React components.",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|