@twentyfirstmedia/ui-core 0.3.1 → 0.5.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/src/icons.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import type { LibraryIconName } from "./icon-library.js";
2
+
1
3
  /** Halo line icon set: 24px grid, 2px round-capped strokes, `currentColor`. Paths from the reference. */
2
4
  export const ICON_PATHS = {
3
5
  thumbUp:
@@ -109,7 +111,46 @@ export const ICON_PATHS = {
109
111
  "M10.67 8.24a3.5 3.5 0 1 1 5.5 2.9L18.67 15.74M8.67 19.24a3.5 3.5 0 0 1-1-6.8M18.67 19.24H11.67M7.67 12.44L11.17 6.74",
110
112
  } as const;
111
113
 
112
- export type IconName = keyof typeof ICON_PATHS;
114
+ /** A name from the kit's own set: always available, no registration needed. */
115
+ export type KitIconName = keyof typeof ICON_PATHS;
116
+
117
+ /**
118
+ * Your own icons: add the names you register to this interface to type them, e.g.
119
+ * `declare module "@twentyfirstmedia/ui-core" { interface CustomIcons { logo: true } }`.
120
+ */
121
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
122
+ export interface CustomIcons {}
123
+
124
+ /** An icon name: the kit's own set, the icon library, or one of your own (`CustomIcons`). */
125
+ export type IconName = KitIconName | LibraryIconName | Extract<keyof CustomIcons, string>;
126
+
127
+ /** A filled drawing on the 24px grid (brand logos): painted with `currentColor`, not stroked. */
128
+ export interface FilledIcon {
129
+ d: string;
130
+ filled: true;
131
+ }
132
+
133
+ /** A drawing for `registerIcons`: a path on the 24px grid, stroked like the kit's icons, or filled. */
134
+ export type IconData = string | FilledIcon;
135
+
136
+ /** Every name of the kit's own set, in set order. */
137
+ export const ICON_NAMES = Object.keys(ICON_PATHS) as KitIconName[];
138
+
139
+ const registered = new Map<string, IconData>();
140
+
141
+ /**
142
+ * Makes icons available by name to `Icon` and every `icon` prop: from the icon library
143
+ * (`@twentyfirstmedia/halo/icons`, `registerIcons({ fingerprint, brandGithub })` or
144
+ * `registerIcons(ICON_LIBRARY)`) or your own drawings on the 24px grid. Call it once, before
145
+ * rendering, in a module both your server and client code import. The kit's own names cannot be
146
+ * replaced.
147
+ */
148
+ export function registerIcons(icons: Readonly<Record<string, IconData>>): void {
149
+ for (const [name, data] of Object.entries(icons))
150
+ if (!(name in ICON_PATHS)) registered.set(name, data);
151
+ }
113
152
 
114
- /** Every icon name, in set order. */
115
- export const ICON_NAMES = Object.keys(ICON_PATHS) as IconName[];
153
+ /** The drawing for a name: the kit's own set first, then registered icons. */
154
+ export function iconData(name: string): IconData | undefined {
155
+ return (ICON_PATHS as Record<string, string>)[name] ?? registered.get(name);
156
+ }
package/src/index.ts CHANGED
@@ -97,6 +97,17 @@ export {
97
97
  type ToastData,
98
98
  type ToastTone,
99
99
  } from "./toast-store.js";
100
- export { ICON_PATHS, ICON_NAMES, type IconName } from "./icons.js";
100
+ export {
101
+ ICON_PATHS,
102
+ ICON_NAMES,
103
+ registerIcons,
104
+ iconData,
105
+ type IconName,
106
+ type KitIconName,
107
+ type IconData,
108
+ type FilledIcon,
109
+ type CustomIcons,
110
+ } from "./icons.js";
111
+ export type { LibraryIconName } from "./icon-library.js";
101
112
  export { Icon, type IconProps } from "./Icon.js";
102
113
  export * from "./components/index.js";