@columenlabs/lumen-ui 0.1.192 → 0.1.194

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.
@@ -11,7 +11,7 @@ export declare const viewIcon: (config: {
11
11
  export declare const iconOf: (icon: ViewIcon | null | undefined, fallback: NavIcon) => NavIcon;
12
12
  /** Every lucide icon name, for the icon picker's search: empty until `load` asks for the map and it lands. */
13
13
  export declare function useLucideIconNames(load?: boolean): readonly string[];
14
- /** Any lucide icon by name, loaded on first use (lucide's own DynamicIcon). */
14
+ /** Any lucide icon by name, loaded on first use (all icons in one lazy file). */
15
15
  export declare const lucideIcon: (name: string, fallback?: NavIcon) => NavIcon;
16
16
  /** An emoji drawn where an icon goes. */
17
17
  export declare const emojiIcon: (emoji: string) => NavIcon;
@@ -1,4 +1,4 @@
1
- import { BanknoteIcon, BriefcaseIcon, CalendarIcon, ChartBarIcon, ChartLineIcon, ChartPieIcon, ClockIcon, CoinsIcon, FlameIcon, Grid3x3Icon, LandmarkIcon, LayersIcon, ListTreeIcon, PiggyBankIcon, ReceiptIcon, ShieldIcon, StarIcon, TableIcon, TagIcon, TargetIcon, TrendingDownIcon, TrendingUpIcon, WalletIcon, ZapIcon, } from 'lucide-react';
1
+ import { BanknoteIcon, BriefcaseIcon, CalendarIcon, ChartBarIcon, ChartLineIcon, ChartPieIcon, ClockIcon, CoinsIcon, FlameIcon, Grid3x3Icon, Icon, LandmarkIcon, LayersIcon, ListTreeIcon, PiggyBankIcon, ReceiptIcon, ShieldIcon, StarIcon, TableIcon, TagIcon, TargetIcon, TrendingDownIcon, TrendingUpIcon, WalletIcon, ZapIcon, } from 'lucide-react';
2
2
  import { createElement, useEffect, useState } from 'react';
3
3
  import { cn } from './lib/utils.js';
4
4
  export const VIEW_ICONS = {
@@ -41,15 +41,32 @@ export const iconOf = (icon, fallback) => {
41
41
  if (icon in VIEW_ICONS)
42
42
  return VIEW_ICONS[icon];
43
43
  if (/^[a-z]/.test(icon))
44
- return lucide && !lucide.names.has(icon) ? fallback : lucideIcon(icon, fallback);
44
+ return lucide && !lucide.nodes.has(iconKey(icon)) ? fallback : lucideIcon(icon, fallback);
45
45
  return emojiIcon(icon);
46
46
  };
47
47
  let lucide;
48
48
  let loadingLucide;
49
+ /** A name's lookup key: `arrow-down-0-1`, `arrow-down-01` and `ArrowDown01` are one icon. */
50
+ const iconKey = (name) => name.replace(/-/g, '').toLowerCase();
51
+ /** `ArrowDown01` → `arrow-down-01`, the name the picker shows and saves. */
52
+ const kebab = (pascal) => pascal
53
+ .replace(/([a-z])([A-Z0-9])/g, '$1-$2')
54
+ .replace(/([0-9])([A-Za-z])/g, '$1-$2')
55
+ .replace(/([A-Z])([A-Z][a-z])/g, '$1-$2')
56
+ .toLowerCase();
49
57
  function loadLucide() {
50
58
  if (!loadingLucide)
51
- loadingLucide = import('lucide-react/dynamic').then((m) => {
52
- lucide = { ...m, names: new Set(m.iconNames) };
59
+ loadingLucide = import('lucide').then(({ icons }) => {
60
+ const nodes = new Map();
61
+ const iconNames = [];
62
+ for (const [pascal, node] of Object.entries(icons)) {
63
+ const key = iconKey(pascal);
64
+ if (nodes.has(key))
65
+ continue;
66
+ nodes.set(key, node);
67
+ iconNames.push(kebab(pascal));
68
+ }
69
+ lucide = { iconNames: iconNames.sort(), nodes };
53
70
  return lucide;
54
71
  });
55
72
  return loadingLucide;
@@ -75,9 +92,10 @@ function LucideByName({ name, fallback, className, }) {
75
92
  'aria-hidden': true,
76
93
  className: cn('inline-block size-4 shrink-0', className),
77
94
  });
78
- if (!lucide.names.has(name))
95
+ const node = lucide.nodes.get(iconKey(name));
96
+ if (!node)
79
97
  return fallback ? createElement(fallback, { className }) : null;
80
- return createElement(lucide.DynamicIcon, { name: name, className });
98
+ return createElement(Icon, { iconNode: node, className });
81
99
  }
82
100
  const made = new Map();
83
101
  /** One component per pick, so React keeps it between renders. */
@@ -89,7 +107,7 @@ const once = (key, make) => {
89
107
  }
90
108
  return Icon;
91
109
  };
92
- /** Any lucide icon by name, loaded on first use (lucide's own DynamicIcon). */
110
+ /** Any lucide icon by name, loaded on first use (all icons in one lazy file). */
93
111
  export const lucideIcon = (name, fallback) => once(`lucide:${name}`, () => ({ className }) => createElement(LucideByName, { name, fallback, className }));
94
112
  /** An emoji drawn where an icon goes. */
95
113
  export const emojiIcon = (emoji) => once(`emoji:${emoji}`, () => ({ className }) => createElement('span', {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@columenlabs/lumen-ui",
3
- "version": "0.1.192",
3
+ "version": "0.1.194",
4
4
  "description": "Lumen: shared React components (frame, views, widgets, charts, drawers).",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -49,7 +49,7 @@
49
49
  "@codemirror/lang-javascript": "6.2.5",
50
50
  "@codemirror/lang-json": "6.0.2",
51
51
  "@codemirror/lang-sql": "6.10.0",
52
- "@columenlabs/lumen-ui-types": "0.1.192",
52
+ "@columenlabs/lumen-ui-types": "0.1.194",
53
53
  "@dnd-kit/core": "6.3.1",
54
54
  "@dnd-kit/sortable": "10.0.0",
55
55
  "@dnd-kit/utilities": "3.2.2",
@@ -69,6 +69,7 @@
69
69
  "i18n-iso-countries": "7.14.0",
70
70
  "indicatorts": "^2.2.2",
71
71
  "lightweight-charts": "^5.2.1",
72
+ "lucide": "^1.48.0",
72
73
  "lucide-react": "^1.48.0",
73
74
  "papaparse": "5.5.3",
74
75
  "qrcode.react": "4.2.0",