@crewlethq/icons 0.2.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Crewlet
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,73 @@
1
+ # @crewlethq/icons
2
+
3
+ Crewlet signature icon set, including the illustrated agent variants such as `agent-reading` (crewlet reading a book). SVG sources live in `svg/`. The build compiles each one into a typed React component and re-exports them through a single `<Icon name="..." />` API.
4
+
5
+ ## Use it
6
+
7
+ ```tsx
8
+ import { Icon } from '@crewlethq/icons';
9
+
10
+ <Icon name="AgentReading" size="lg" title="Documentation" />
11
+ ```
12
+
13
+ `size` accepts `'sm' | 'md' | 'lg' | 'xl'`, a number (px), or any CSS length string. `title` makes the icon accessible to screen readers; without it, the icon is marked `aria-hidden`.
14
+
15
+ `name` is typed as the `IconName` union, so TypeScript rejects a name the package does not ship. Plain JavaScript gets no such check, and `<Icon>` renders nothing for an unknown name, so search for a name across the whole project when an icon is renamed. `ICON_NAMES` lists every name in file-name order; treat it as a set and never index it by position, because adding or renaming an icon shifts the order.
16
+
17
+ Each icon is also exported as its own component through the `Icons` namespace (`<Icons.AgentReading />`).
18
+
19
+ ### Raw SVG files
20
+
21
+ The source SVGs ship in the package and are exported as `@crewlethq/icons/svg/*`, for an `<img>`, a favicon or any other surface that needs a file rather than a React component:
22
+
23
+ ```ts
24
+ import markUrl from '@crewlethq/icons/svg/crewlet-icon.svg';
25
+ ```
26
+
27
+ A bundler resolves the import to a URL. Outside a bundler, resolve the same specifier with `import.meta.resolve('@crewlethq/icons/svg/crewlet-icon.svg')` to get the file on disk.
28
+
29
+ ### CrewletFigure
30
+
31
+ `CrewletFigure` renders the Crewlet character as five separately animated body parts:
32
+
33
+ ```tsx
34
+ import { CrewletFigure } from '@crewlethq/icons';
35
+
36
+ <CrewletFigure motion="wave" style={{ fontSize: 96 }} />
37
+ ```
38
+
39
+ | Prop | Type | Default | Purpose |
40
+ | ---- | ---- | ------- | ------- |
41
+ | `motion` | `CrewletMotion`: `'idle' \| 'dance' \| 'wave' \| 'jump' \| 'walk' \| 'spin'` | `'idle'` | The looping motion. |
42
+ | `delay` | number (seconds) | `0` | Phase offset, so several figures do not move in lockstep. |
43
+ | `color` | CSS colour | `'#7c56ff'` | Body fill. |
44
+ | `fillGaps` | boolean | `true` | Backs each joint with body, so a moving limb never uncovers a gap. `false` renders the plain trim, where the pieces meet with visible seams. |
45
+
46
+ The figure is sized in `em` like the icons (set `font-size` or pass `width` and `height`) and is `aria-hidden`; give the surrounding element an accessible name when the figure carries meaning. Every motion stops when the user prefers reduced motion. The geometry lives in `src/crewletParts.ts`.
47
+
48
+ ## Add an icon
49
+
50
+ 1. Drop `<your-icon>.svg` into `svg/`. File names become PascalCase component names (for example, `agent-celebrating.svg` -> `AgentCelebrating`).
51
+ 2. Run `npm run build`.
52
+ 3. The new icon is auto-exported from `@crewlethq/icons` and appears in `ICON_NAMES`.
53
+
54
+ ## Conventions for source SVGs
55
+
56
+ Three families coexist in this package:
57
+
58
+ **Brand artwork**: `crewlet-icon` (the Crewlet mark) and `crewlet-reading` (a full-colour illustration of the Crewlet character reading a newspaper), together with `CrewletFigure`. Filled artwork on its own viewBox; render it as supplied. `crewlet-reading` is a large, detailed illustration (about 670 KB of SVG), so reserve it for hero and empty-state surfaces rather than inline icon slots. The Crewlet name, mark and character are trademarks that the MIT License does not cover; see [TRADEMARKS.md](./TRADEMARKS.md) before using them outside an official Crewlet product.
59
+
60
+ **Feature illustrations** (80x80): `hierarchy`, `human-in-loop` and `company-as-code`. Self-contained artwork with its own gradients and background disc, so it does not inherit `currentColor`. The build prefixes every `id` in a file with that file's name, because inline SVGs share the page's id space; keep gradient and other `id` references inside the file that defines them.
61
+
62
+ **Signature illustrations** (32x32): the crewlet "agent" character in different contexts (`agent-idle`, `agent-working`, `agent-thinking`, `agent-reading`, `agent-greeting`, `agent-success`, `agent-error` and `agent-loading`). The set reads as one character through a shared line style and scale rather than an identical outline: the head and shoulders move, shrink or give way to a torso when the pose needs room for a prop (a book, a desk, a thought bubble). Name new variants `agent-<pose>.svg`.
63
+
64
+ Signature illustrations follow these rules so they recolor from CSS and sit on one visual weight:
65
+ - A `0 0 32 32` viewBox.
66
+ - `stroke="currentColor"` and `fill="none"`.
67
+ - A single 1.6 stroke weight.
68
+ - `stroke-linecap="round"` and `stroke-linejoin="round"`.
69
+ - No hard-coded width or height attributes (the build strips them).
70
+
71
+ ## License
72
+
73
+ MIT. The license text is in [`LICENSE`](./LICENSE), which ships in the package. The license covers copyright only: the Crewlet name, logo and character are trademarks, and [`TRADEMARKS.md`](./TRADEMARKS.md), which also ships in the package, says how they may be used.
package/TRADEMARKS.md ADDED
@@ -0,0 +1,26 @@
1
+ # Trademarks
2
+
3
+ "Crewlet", the Crewlet logo and the Crewlet character (in every pose, illustration, animation and rigged or trimmed variant) are trademarks of Crewlet. The source code and assets in this repository are licensed under the MIT License, and that license covers copyright only: it grants no right to use these trademarks.
4
+
5
+ ## What you may do
6
+
7
+ - Refer to the project by name to describe it truthfully, for example "built with @crewlethq/ui" or "a fork of the Crewlet design system".
8
+ - Use the packages, including the brand files listed below, in an official Crewlet product or in an unmodified build of this repository, such as its Storybook.
9
+
10
+ ## What you may not do
11
+
12
+ - Use the Crewlet name, logo or character in a way that suggests your product is Crewlet, is endorsed by Crewlet, or is an official distribution.
13
+ - Use the logo or the character as the identity of another product, service, company or account, including in a fork. A fork or redistribution that ships a user-facing surface must remove the Crewlet logo and character from it and use a different product name.
14
+
15
+ ## The brand files
16
+
17
+ These files in the repository carry the Crewlet logo or character:
18
+
19
+ - `packages/icons/svg/crewlet-icon.svg`
20
+ - `packages/icons/svg/crewlet-reading.svg`
21
+ - `packages/icons/src/crewletParts.ts`
22
+ - `packages/icons/src/CrewletFigure.tsx`
23
+
24
+ The `CrewletIcon`, `CrewletReading` and `CrewletFigure` components that the `@crewlethq/icons` package builds from them are covered in the same way.
25
+
26
+ For any use this page does not allow, ask the maintainers first by opening an issue in this repository.
@@ -0,0 +1,82 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { SVGProps } from 'react';
3
+
4
+ declare const AgentError: (props: SVGProps<SVGSVGElement>) => react_jsx_runtime.JSX.Element;
5
+
6
+ declare const AgentGreeting: (props: SVGProps<SVGSVGElement>) => react_jsx_runtime.JSX.Element;
7
+
8
+ declare const AgentIdle: (props: SVGProps<SVGSVGElement>) => react_jsx_runtime.JSX.Element;
9
+
10
+ declare const AgentLoading: (props: SVGProps<SVGSVGElement>) => react_jsx_runtime.JSX.Element;
11
+
12
+ declare const AgentReading: (props: SVGProps<SVGSVGElement>) => react_jsx_runtime.JSX.Element;
13
+
14
+ declare const AgentSuccess: (props: SVGProps<SVGSVGElement>) => react_jsx_runtime.JSX.Element;
15
+
16
+ declare const AgentThinking: (props: SVGProps<SVGSVGElement>) => react_jsx_runtime.JSX.Element;
17
+
18
+ declare const AgentWorking: (props: SVGProps<SVGSVGElement>) => react_jsx_runtime.JSX.Element;
19
+
20
+ declare const CompanyAsCode: (props: SVGProps<SVGSVGElement>) => react_jsx_runtime.JSX.Element;
21
+
22
+ declare const CrewletIcon: (props: SVGProps<SVGSVGElement>) => react_jsx_runtime.JSX.Element;
23
+
24
+ declare const CrewletReading: (props: SVGProps<SVGSVGElement>) => react_jsx_runtime.JSX.Element;
25
+
26
+ declare const Hierarchy: (props: SVGProps<SVGSVGElement>) => react_jsx_runtime.JSX.Element;
27
+
28
+ declare const HumanInLoop: (props: SVGProps<SVGSVGElement>) => react_jsx_runtime.JSX.Element;
29
+
30
+ declare const ICON_NAMES: readonly ["AgentError", "AgentGreeting", "AgentIdle", "AgentLoading", "AgentReading", "AgentSuccess", "AgentThinking", "AgentWorking", "CompanyAsCode", "CrewletIcon", "CrewletReading", "Hierarchy", "HumanInLoop"];
31
+ type IconName = (typeof ICON_NAMES)[number];
32
+
33
+ declare const index_AgentError: typeof AgentError;
34
+ declare const index_AgentGreeting: typeof AgentGreeting;
35
+ declare const index_AgentIdle: typeof AgentIdle;
36
+ declare const index_AgentLoading: typeof AgentLoading;
37
+ declare const index_AgentReading: typeof AgentReading;
38
+ declare const index_AgentSuccess: typeof AgentSuccess;
39
+ declare const index_AgentThinking: typeof AgentThinking;
40
+ declare const index_AgentWorking: typeof AgentWorking;
41
+ declare const index_CompanyAsCode: typeof CompanyAsCode;
42
+ declare const index_CrewletIcon: typeof CrewletIcon;
43
+ declare const index_CrewletReading: typeof CrewletReading;
44
+ declare const index_Hierarchy: typeof Hierarchy;
45
+ declare const index_HumanInLoop: typeof HumanInLoop;
46
+ declare const index_ICON_NAMES: typeof ICON_NAMES;
47
+ type index_IconName = IconName;
48
+ declare namespace index {
49
+ export { index_AgentError as AgentError, index_AgentGreeting as AgentGreeting, index_AgentIdle as AgentIdle, index_AgentLoading as AgentLoading, index_AgentReading as AgentReading, index_AgentSuccess as AgentSuccess, index_AgentThinking as AgentThinking, index_AgentWorking as AgentWorking, index_CompanyAsCode as CompanyAsCode, index_CrewletIcon as CrewletIcon, index_CrewletReading as CrewletReading, index_Hierarchy as Hierarchy, index_HumanInLoop as HumanInLoop, index_ICON_NAMES as ICON_NAMES, type index_IconName as IconName };
50
+ }
51
+
52
+ declare const sizes: {
53
+ readonly sm: "16px";
54
+ readonly md: "20px";
55
+ readonly lg: "24px";
56
+ readonly xl: "32px";
57
+ };
58
+ type IconSize = keyof typeof sizes | number | string;
59
+ interface IconProps extends Omit<SVGProps<SVGSVGElement>, 'name' | 'fontSize'> {
60
+ name: IconName;
61
+ size?: IconSize;
62
+ title?: string;
63
+ }
64
+ declare const Icon: ({ name, size, title, style, ...rest }: IconProps) => react_jsx_runtime.JSX.Element | null;
65
+
66
+ type CrewletMotion = 'idle' | 'dance' | 'wave' | 'jump' | 'walk' | 'spin';
67
+ interface CrewletFigureProps extends SVGProps<SVGSVGElement> {
68
+ /** Which looping motion the figure plays. Defaults to a subtle idle. */
69
+ motion?: CrewletMotion;
70
+ /** Phase offset in seconds, so a group of figures does not move in lockstep. */
71
+ delay?: number;
72
+ /** Body fill. Defaults to the crewlet purple; also settable via CSS color. */
73
+ color?: string;
74
+ /**
75
+ * Back the joints so a moving limb reveals body instead of a blank gap.
76
+ * On by default. Set false for the plain trim (pieces meet with visible seams).
77
+ */
78
+ fillGaps?: boolean;
79
+ }
80
+ declare const CrewletFigure: ({ motion, delay, color, fillGaps, style, ...rest }: CrewletFigureProps) => react_jsx_runtime.JSX.Element;
81
+
82
+ export { CrewletFigure, type CrewletFigureProps, type CrewletMotion, ICON_NAMES, Icon, type IconName, type IconProps, type IconSize, index as Icons };