@qumra/fanar-native 0.1.2 → 0.1.4
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/lib/components/Surfaces.js +1 -1
- package/lib/icons.d.ts +1 -0
- package/lib/icons.js +57 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/qumra/QumraIcon.js +10 -4
- package/lib/qumra/data.generated.js +168 -24
- package/lib/theme/context.d.ts +2 -1
- package/lib/theme/context.js +3 -3
- package/lib/theme/theme.d.ts +1 -1
- package/lib/theme/theme.js +11 -3
- package/package.json +2 -2
|
@@ -70,7 +70,7 @@ export function StepRow({ icon, title, why, done, action, onPress, style }) {
|
|
|
70
70
|
const inner = (_jsxs(_Fragment, { children: [done ? (_jsx(View, { style: [
|
|
71
71
|
styles.stepIcon,
|
|
72
72
|
{ borderRadius: theme.radius.field, backgroundColor: theme.color.brand },
|
|
73
|
-
], children: _jsx(Check, { size: 17, strokeWidth: 3, color: "#ffffff" }) })) : brand ? (_jsx(QumraIcon, { name: brand, size: 34 })) : (_jsx(View, { style: [
|
|
73
|
+
], children: _jsx(Check, { size: 17, strokeWidth: 3, color: "#ffffff" }) })) : brand ? (_jsx(View, { style: styles.stepIcon, children: _jsx(QumraIcon, { name: brand, size: 34 }) })) : (_jsx(View, { style: [
|
|
74
74
|
styles.stepIcon,
|
|
75
75
|
{ borderRadius: theme.radius.field, backgroundColor: theme.color.soft },
|
|
76
76
|
], children: Lucide ? _jsx(Lucide, { size: 18, strokeWidth: 2, color: theme.color.brand }) : null })), _jsxs(View, { style: styles.rowText, children: [_jsx(Text, { size: 14.5, weight: "extraBold", color: done ? 'muted' : 'ink', align: "start", style: done ? styles.struck : { textAlign: 'left' }, children: title }), why ? (_jsx(Text, { size: 12.5, style: { textAlign: 'left' }, color: "muted", align: "start", leading: "relaxed", lines: 1, children: why })) : null] }), action] }));
|
package/lib/icons.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import * as React from 'react';
|
|
|
2
2
|
import { type StyleProp, type ViewStyle } from 'react-native';
|
|
3
3
|
import { AlertTriangle, ArrowLeft, ArrowRight, BarChart3, Bell, Bot, Check, CheckCheck, ChevronDown, ChevronLeft, ChevronRight, ChevronUp, Copy, ExternalLink, Globe, Home, Info, Lock, Menu, Minus, Plus, Search, Share2, Sparkles, Star, Undo2, X, type LucideIcon } from 'lucide-react-native';
|
|
4
4
|
export type { LucideIcon };
|
|
5
|
+
export declare function uiIconFor(name: string): string | undefined;
|
|
5
6
|
export declare function qumraIconFor(name: string): string | undefined;
|
|
6
7
|
export declare function icon(name: string): LucideIcon;
|
|
7
8
|
export declare function hasIcon(name: string): boolean;
|
package/lib/icons.js
CHANGED
|
@@ -374,6 +374,59 @@ function qumraAs(qumraName) {
|
|
|
374
374
|
wrapped[qumraName] = Wrapped;
|
|
375
375
|
return wrapped[qumraName];
|
|
376
376
|
}
|
|
377
|
+
const stemOf = (name) => name.replace(/-(outline|sharp)$/, '');
|
|
378
|
+
const UI_FOR = {
|
|
379
|
+
add: 'plus', 'add-circle': 'plus', plus: 'plus', 'folder-plus': 'plus', 'package-plus': 'plus',
|
|
380
|
+
'person-add': 'user-plus', remove: 'close', close: 'close', 'close-circle': 'close', x: 'close',
|
|
381
|
+
checkmark: 'check', 'checkmark-circle': 'check', 'checkmark-done': 'check', check: 'check',
|
|
382
|
+
checkbox: 'check', trash: 'trash', 'trash-2': 'trash', create: 'pencil', pencil: 'pencil',
|
|
383
|
+
brush: 'pencil', 'color-wand': 'sparkle', copy: 'copy', save: 'save', download: 'save',
|
|
384
|
+
'cloud-download': 'save', 'cloud-upload': 'publish', print: 'print', send: 'send',
|
|
385
|
+
'share-social': 'share', 'share-2': 'share', search: 'search', filter: 'filter',
|
|
386
|
+
funnel: 'filter', options: 'sliders', sync: 'repeat', reload: 'repeat', refresh: 'reset',
|
|
387
|
+
'refresh-circle': 'reset', scan: 'search', stop: 'stop', 'pause-circle': 'stop', play: 'live',
|
|
388
|
+
'play-circle': 'live', 'log-out': 'logout', exit: 'logout', open: 'external',
|
|
389
|
+
'external-link': 'external', link: 'link', unlink: 'unlink', expand: 'expand',
|
|
390
|
+
contract: 'collapse', resize: 'expand',
|
|
391
|
+
'alert-circle': 'alert', 'alert-triangle': 'alert', warning: 'alert', 'help-circle': 'alert',
|
|
392
|
+
'information-circle': 'alert', 'life-buoy': 'alert', ban: 'ban', 'shield-checkmark': 'shield-check',
|
|
393
|
+
'shield-half': 'shield', 'lock-closed': 'lock', key: 'key', 'finger-print': 'key',
|
|
394
|
+
eye: 'eye', 'eye-off': 'eye-off', star: 'star', crown: 'crown', diamond: 'crown',
|
|
395
|
+
sparkles: 'sparkle', rocket: 'rocket', flash: 'bolt', flame: 'flame', bulb: 'bulb',
|
|
396
|
+
storefront: 'store', business: 'building', cube: 'box', 'package-open': 'box',
|
|
397
|
+
'bag-handle': 'bag', bag: 'bag', cart: 'cart', shoppingcart: 'cart', pricetag: 'tag',
|
|
398
|
+
pricetags: 'tag', gift: 'tag', ticket: 'tag', receipt: 'receipt', card: 'card',
|
|
399
|
+
cash: 'money', payments: 'money', wallet: 'wallet', calculator: 'sigma',
|
|
400
|
+
person: 'user', 'person-circle': 'user', user: 'user', people: 'users', customers: 'users',
|
|
401
|
+
partners: 'users', car: 'truck', barcode: 'hash', keypad: 'hash',
|
|
402
|
+
document: 'file', documents: 'file', 'document-text': 'file', reader: 'file', sheet: 'sheet',
|
|
403
|
+
folder: 'folder', library: 'layers', albums: 'layers', layers: 'layers', book: 'note',
|
|
404
|
+
journal: 'note', chatbubble: 'note', chatbubbles: 'note', text: 'text', 'code-slash': 'code',
|
|
405
|
+
terminal: 'code', image: 'image-plus', images: 'image-plus', camera: 'image-plus',
|
|
406
|
+
'camera-off': 'image-off', videocam: 'film', film: 'film', shapes: 'template',
|
|
407
|
+
'layout-grid': 'grid', grid: 'grid', apps: 'grid', widgets: 'template', list: 'rows',
|
|
408
|
+
'reorder-three': 'rows', 'drag-indicator': 'grip', archive: 'archive',
|
|
409
|
+
'bar-chart': 'chart', 'stats-chart': 'chart', 'pie-chart': 'chart', analytics: 'chart',
|
|
410
|
+
pulse: 'chart', speedometer: 'chart', 'trending-up': 'trend-up', 'trending-down': 'trend-down',
|
|
411
|
+
settings: 'gear', construct: 'gear', build: 'gear', hammer: 'gear', 'color-palette': 'palette',
|
|
412
|
+
globe: 'globe', earth: 'globe', language: 'language', server: 'database', cloud: 'database',
|
|
413
|
+
'cloud-offline': 'database', desktop: 'desktop', laptop: 'desktop', 'phone-portrait': 'mobile',
|
|
414
|
+
'tablet-portrait': 'tablet', radio: 'plug', bot: 'sparkle',
|
|
415
|
+
mail: 'mail', 'mail-open': 'mail', 'mail-unread': 'mail', call: 'phone', phone: 'phone',
|
|
416
|
+
'phone-call': 'phone', headset: 'phone', megaphone: 'megaphone', notifications: 'bell',
|
|
417
|
+
'notifications-off': 'bell', bell: 'bell', time: 'clock', clock: 'clock',
|
|
418
|
+
calendar: 'calendar', 'calendar-clear': 'calendar', location: 'pin', 'map-marker': 'pin',
|
|
419
|
+
map: 'pin', navigate: 'cursor', pin: 'pin', flag: 'thumbtack', menu: 'menu',
|
|
420
|
+
'ellipsis-vertical': 'more', 'ellipsis-horizontal': 'more', more: 'more',
|
|
421
|
+
'swap-vertical': 'sort', sun: 'live', moon: 'live',
|
|
422
|
+
'arrow-back': 'arrow-left', 'arrow-forward': 'arrow-right',
|
|
423
|
+
'arrow-undo': 'undo', 'arrow-redo': 'redo',
|
|
424
|
+
'chevron-down': 'chevron-down', 'chevron-small-down': 'chevron-down', 'chevron-up': 'chevron-up',
|
|
425
|
+
};
|
|
426
|
+
export function uiIconFor(name) {
|
|
427
|
+
const tool = UI_FOR[stemOf(name)];
|
|
428
|
+
return tool ? `ui-${tool}` : undefined;
|
|
429
|
+
}
|
|
377
430
|
export function qumraIconFor(name) {
|
|
378
431
|
return QUMRA_FOR[name];
|
|
379
432
|
}
|
|
@@ -381,10 +434,13 @@ export function icon(name) {
|
|
|
381
434
|
const brand = QUMRA_FOR[name];
|
|
382
435
|
if (brand)
|
|
383
436
|
return qumraAs(brand);
|
|
437
|
+
const tool = uiIconFor(name);
|
|
438
|
+
if (tool)
|
|
439
|
+
return qumraAs(tool);
|
|
384
440
|
return MAP[name] ?? ALIAS[name] ?? Home;
|
|
385
441
|
}
|
|
386
442
|
export function hasIcon(name) {
|
|
387
|
-
return name in QUMRA_FOR || name in MAP || name in ALIAS;
|
|
443
|
+
return name in QUMRA_FOR || !!uiIconFor(name) || name in MAP || name in ALIAS;
|
|
388
444
|
}
|
|
389
445
|
export const ICON_SIZE = {
|
|
390
446
|
xs: 12,
|
package/lib/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export { TONE_SOFT, TONE_SOLID, type Tone, type ToneColors } from './lib/tone';
|
|
|
5
5
|
export { toLatinDigits, toArabicDigits, groupDigits } from './lib/digits';
|
|
6
6
|
export { usePressScale, useEnter, useSkeletonPulse, EASE_OUT, EASE_IN_OUT } from './lib/motion';
|
|
7
7
|
export { hitSlopFor, HIT_SLOP_SM, TOUCH_MIN } from './lib/a11y';
|
|
8
|
-
export { icon, hasIcon, Icon, qumraIconFor, snapIconSize, ICON_SIZE, ICON_STROKE, type LucideIcon, type IconProps, type IconSize, } from './icons';
|
|
8
|
+
export { icon, hasIcon, Icon, qumraIconFor, uiIconFor, snapIconSize, ICON_SIZE, ICON_STROKE, type LucideIcon, type IconProps, type IconSize, } from './icons';
|
|
9
9
|
export { QumraIcon, hasQumraIcon, QUMRA_ICONS, type QumraIconProps, type QumraIconName, type QumraIconSpec, } from './qumra/QumraIcon';
|
|
10
10
|
export { NavIcon, type NavIconProps } from './qumra/NavIcon';
|
|
11
11
|
export { art, hasArt, BRAND, ART, type BrandName, type ArtName } from './art';
|
package/lib/index.js
CHANGED
|
@@ -5,7 +5,7 @@ export { TONE_SOFT, TONE_SOLID } from './lib/tone';
|
|
|
5
5
|
export { toLatinDigits, toArabicDigits, groupDigits } from './lib/digits';
|
|
6
6
|
export { usePressScale, useEnter, useSkeletonPulse, EASE_OUT, EASE_IN_OUT } from './lib/motion';
|
|
7
7
|
export { hitSlopFor, HIT_SLOP_SM, TOUCH_MIN } from './lib/a11y';
|
|
8
|
-
export { icon, hasIcon, Icon, qumraIconFor, snapIconSize, ICON_SIZE, ICON_STROKE, } from './icons';
|
|
8
|
+
export { icon, hasIcon, Icon, qumraIconFor, uiIconFor, snapIconSize, ICON_SIZE, ICON_STROKE, } from './icons';
|
|
9
9
|
export { QumraIcon, hasQumraIcon, QUMRA_ICONS, } from './qumra/QumraIcon';
|
|
10
10
|
export { NavIcon } from './qumra/NavIcon';
|
|
11
11
|
export { art, hasArt, BRAND, ART } from './art';
|
package/lib/qumra/QumraIcon.js
CHANGED
|
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import Svg, { Circle, ClipPath, Defs, Ellipse, G, LinearGradient, Path, RadialGradient, Rect, Stop, Text as SvgText, } from 'react-native-svg';
|
|
4
4
|
import { QUMRA_ICONS } from './data.generated';
|
|
5
|
+
import { useFanar } from '../theme/context';
|
|
5
6
|
const TAGS = {
|
|
6
7
|
svg: Svg,
|
|
7
8
|
g: G,
|
|
@@ -34,7 +35,8 @@ function grayscale(value) {
|
|
|
34
35
|
const c = l.toString(16).padStart(2, '0');
|
|
35
36
|
return `#${c}${c}${c}`;
|
|
36
37
|
}
|
|
37
|
-
|
|
38
|
+
const CURRENT = 'currentColor';
|
|
39
|
+
function build(node, uid, key, tint, current) {
|
|
38
40
|
const [tag, props, kids] = node;
|
|
39
41
|
const Cmp = TAGS[tag];
|
|
40
42
|
if (!Cmp)
|
|
@@ -49,7 +51,9 @@ function build(node, uid, key, tint) {
|
|
|
49
51
|
v = `${v}-${uid}`;
|
|
50
52
|
else if (typeof v === 'string' && v.indexOf('url(#') !== -1)
|
|
51
53
|
v = uniquify(v, uid);
|
|
52
|
-
if (
|
|
54
|
+
if (isPaint(k) && v === CURRENT)
|
|
55
|
+
v = current ?? v;
|
|
56
|
+
if (tint && isPaint(k) && v !== 'none' && v !== CURRENT)
|
|
53
57
|
v = flat ?? grayscale(v);
|
|
54
58
|
p[k] = v;
|
|
55
59
|
}
|
|
@@ -59,7 +63,7 @@ function build(node, uid, key, tint) {
|
|
|
59
63
|
if (p.strokeOpacity !== undefined)
|
|
60
64
|
p.strokeOpacity = '1';
|
|
61
65
|
}
|
|
62
|
-
const children = kids?.map((c, i) => build(c, uid, i, tint)).filter(Boolean);
|
|
66
|
+
const children = kids?.map((c, i) => build(c, uid, i, tint, current)).filter(Boolean);
|
|
63
67
|
return React.createElement(Cmp, { key, ...p }, children?.length ? children : undefined);
|
|
64
68
|
}
|
|
65
69
|
function badge(count) {
|
|
@@ -74,11 +78,13 @@ function badge(count) {
|
|
|
74
78
|
return (_jsxs(G, { children: [_jsx(Rect, { x: x, y: 2.2, width: w, height: 12.4, rx: 6.2, fill: "#E8A94F", stroke: "#F2F7F8", strokeWidth: 1.4 }), _jsx(SvgText, { x: x + w / 2, y: 8.4, dy: fs * 0.35, textAnchor: "middle", fill: "#FFFFFF", fontSize: fs, fontWeight: "700", children: s })] }, "qi-count"));
|
|
75
79
|
}
|
|
76
80
|
export function QumraIcon({ name, size = 32, mono, active, color, count, label, onPress, }) {
|
|
81
|
+
const { theme } = useFanar();
|
|
77
82
|
const spec = QUMRA_ICONS[name];
|
|
78
83
|
const uid = React.useId().replace(/[^a-zA-Z0-9]/g, '');
|
|
79
84
|
const dimmed = !!mono && !active;
|
|
80
85
|
const tint = dimmed ? color ?? 'gray' : undefined;
|
|
81
|
-
const
|
|
86
|
+
const current = color ?? theme.color.ink;
|
|
87
|
+
const children = React.useMemo(() => (spec ? spec.tree.map((n, i) => build(n, uid, i, tint, current)) : []), [spec, uid, tint, current]);
|
|
82
88
|
if (!spec) {
|
|
83
89
|
if (__DEV__)
|
|
84
90
|
console.warn(`[qumra-icons] لا توجد أيقونة بالاسم «${name}»`);
|