@nice2dev/icons 1.3.6 → 1.3.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/CHANGELOG.md +88 -0
- package/README.md +37 -17
- package/dist/cjs/NiceIconStacker.js +19 -5
- package/dist/cjs/createIcon.js +19 -6
- package/dist/cjs/iconParts.js +24 -2
- package/dist/cjs/iconStack.js +7 -5
- package/dist/cjs/icons/accessibility.js +9 -8
- package/dist/cjs/icons/actions.js +42 -32
- package/dist/cjs/icons/ai.js +12 -11
- package/dist/cjs/icons/brand.js +2 -2
- package/dist/cjs/icons/business.js +37 -29
- package/dist/cjs/icons/devtech.js +17 -15
- package/dist/cjs/icons/ecommerce.js +19 -14
- package/dist/cjs/icons/education.js +30 -25
- package/dist/cjs/icons/files.js +64 -32
- package/dist/cjs/icons/fintech.js +2 -11
- package/dist/cjs/icons/food.js +12 -8
- package/dist/cjs/icons/fun.js +11 -11
- package/dist/cjs/icons/gaming.js +20 -13
- package/dist/cjs/icons/health.js +38 -25
- package/dist/cjs/icons/index.js +1 -0
- package/dist/cjs/icons/input.js +31 -21
- package/dist/cjs/icons/legal.js +11 -11
- package/dist/cjs/icons/media.js +24 -15
- package/dist/cjs/icons/navigation.js +16 -13
- package/dist/cjs/icons/omniverk.js +2 -7
- package/dist/cjs/icons/realestate.js +14 -14
- package/dist/cjs/icons/saas.js +0 -10
- package/dist/cjs/icons/science.js +12 -12
- package/dist/cjs/icons/shapes.js +20 -17
- package/dist/cjs/icons/smarthome.js +0 -11
- package/dist/cjs/icons/social.js +7 -6
- package/dist/cjs/icons/sports.js +5 -6
- package/dist/cjs/icons/sustainability.js +12 -11
- package/dist/cjs/icons/travel.js +13 -13
- package/dist/cjs/icons/ui.js +60 -35
- package/dist/cjs/icons/weather.js +12 -16
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/resolver.js +1 -0
- package/dist/cjs/rsc.js +1 -1
- package/dist/cjs/stacking.js +49 -11
- package/dist/esm/NiceIconStacker.js +22 -8
- package/dist/esm/createIcon.js +20 -7
- package/dist/esm/iconParts.js +24 -3
- package/dist/esm/iconStack.js +7 -5
- package/dist/esm/icons/accessibility.js +9 -8
- package/dist/esm/icons/actions.js +43 -33
- package/dist/esm/icons/ai.js +12 -11
- package/dist/esm/icons/brand.js +2 -2
- package/dist/esm/icons/business.js +38 -30
- package/dist/esm/icons/devtech.js +17 -15
- package/dist/esm/icons/ecommerce.js +19 -14
- package/dist/esm/icons/education.js +30 -25
- package/dist/esm/icons/files.js +65 -33
- package/dist/esm/icons/fintech.js +2 -11
- package/dist/esm/icons/food.js +12 -8
- package/dist/esm/icons/fun.js +11 -11
- package/dist/esm/icons/gaming.js +21 -14
- package/dist/esm/icons/health.js +38 -25
- package/dist/esm/icons/index.js +1 -1
- package/dist/esm/icons/input.js +31 -21
- package/dist/esm/icons/legal.js +12 -12
- package/dist/esm/icons/media.js +25 -16
- package/dist/esm/icons/navigation.js +16 -13
- package/dist/esm/icons/omniverk.js +2 -7
- package/dist/esm/icons/realestate.js +15 -15
- package/dist/esm/icons/saas.js +0 -10
- package/dist/esm/icons/science.js +12 -12
- package/dist/esm/icons/shapes.js +20 -17
- package/dist/esm/icons/smarthome.js +0 -11
- package/dist/esm/icons/social.js +8 -7
- package/dist/esm/icons/sports.js +6 -7
- package/dist/esm/icons/sustainability.js +12 -11
- package/dist/esm/icons/travel.js +14 -14
- package/dist/esm/icons/ui.js +61 -37
- package/dist/esm/icons/weather.js +13 -17
- package/dist/esm/index.js +1 -1
- package/dist/esm/resolver.js +1 -0
- package/dist/esm/rsc.js +1 -1
- package/dist/esm/stacking.js +46 -12
- package/dist/types/createIcon.d.ts +16 -2
- package/dist/types/iconParts.d.ts +8 -2
- package/dist/types/iconStack.d.ts +18 -3
- package/dist/types/icons/index.d.ts +1 -1
- package/dist/types/icons/ui.d.ts +1 -0
- package/dist/types/stacking.d.ts +30 -5
- package/dist/types/types.d.ts +22 -8
- package/package.json +2 -2
package/dist/cjs/stacking.js
CHANGED
|
@@ -16,6 +16,16 @@ function isNtdIconElement(node) {
|
|
|
16
16
|
typeof node.type !== 'string' &&
|
|
17
17
|
Boolean(node.type[NTD_ICON_MARK]));
|
|
18
18
|
}
|
|
19
|
+
/** Set on every component createIcon makes, next to {@link NTD_ICON_MARK}: its {@link PerfectStack}. */
|
|
20
|
+
const PERFECT_STACK = 'perfectStack';
|
|
21
|
+
/** The spot icon component `icon` keeps for stacked icons; `undefined` when it is not an icon. */
|
|
22
|
+
function perfectStackOf(icon) {
|
|
23
|
+
return icon && (typeof icon === 'object' || typeof icon === 'function')
|
|
24
|
+
? icon[PERFECT_STACK]
|
|
25
|
+
: undefined;
|
|
26
|
+
}
|
|
27
|
+
/** A child of the spot's default size and no turn, at the box centre — `'center'`. */
|
|
28
|
+
const BOX_PERFECT_STACK = { rotation: 0, size: 0.6 };
|
|
19
29
|
/** Variants drawn with lines; every other variant is a filled shape. */
|
|
20
30
|
const LINE_VARIANTS = new Set(['outline', 'wireframe']);
|
|
21
31
|
function isFilledVariant(variant) {
|
|
@@ -38,6 +48,13 @@ function stackPlacement(align, size) {
|
|
|
38
48
|
const y = edge.startsWith('top') ? 0 : edge.startsWith('bottom') ? far : mid;
|
|
39
49
|
return half ? [(x + mid) / 2, (y + mid) / 2] : [x, y];
|
|
40
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* `at` moved by `percent` of the parent (`stackOffsetX` / `stackOffsetY`, 1.3.7), in the parent's
|
|
53
|
+
* 24 units. Rounded to a thousandth, so the markup reads 7.2, not 7.199999999999999.
|
|
54
|
+
*/
|
|
55
|
+
function stackOffset(at, percent) {
|
|
56
|
+
return percent ? Math.round(1000 * at + 240 * percent) / 1000 : at;
|
|
57
|
+
}
|
|
41
58
|
/** A corner badge — a full corner; `half-` corners sit inside the parent like its centre. */
|
|
42
59
|
function isCornerBadge(align) {
|
|
43
60
|
return /^(top|bottom)-(left|right)$/.test(align);
|
|
@@ -45,17 +62,25 @@ function isCornerBadge(align) {
|
|
|
45
62
|
/**
|
|
46
63
|
* Font size of text children by length: one character 9, two 7.5, three 6, more 5 (1.3.6 — three
|
|
47
64
|
* quarters of the first sizes, so a number sits inside a star or a circle with room round it).
|
|
65
|
+
* In a spot smaller or larger than the default 0.6 (`perfectStackSize`, 1.3.8) it scales with it.
|
|
48
66
|
*/
|
|
49
|
-
function defaultTextSize(length) {
|
|
50
|
-
|
|
67
|
+
function defaultTextSize(length, spot = BOX_PERFECT_STACK.size) {
|
|
68
|
+
const size = length <= 1 ? 9 : length === 2 ? 7.5 : length === 3 ? 6 : 5;
|
|
69
|
+
return spot === BOX_PERFECT_STACK.size
|
|
70
|
+
? size
|
|
71
|
+
: Math.round((10 * size * spot) / BOX_PERFECT_STACK.size) / 10;
|
|
51
72
|
}
|
|
73
|
+
/** `n` rounded to a thousandth — 7.2 in the markup, not 7.199999999999999. */
|
|
74
|
+
const thousandth = (n) => Math.round(1000 * n) / 1000;
|
|
52
75
|
/** The cutout variant draws its shape at 80% in the tile; its stack follows the shape. */
|
|
53
76
|
const CUTOUT_SHAPE = 'translate(12 12) scale(0.8) translate(-12 -12)';
|
|
54
77
|
/** The gap kept round a corner badge, in the parent's units. */
|
|
55
78
|
const BADGE_GAP = 1;
|
|
56
79
|
/**
|
|
57
|
-
* The children of an icon, drawn into it.
|
|
58
|
-
*
|
|
80
|
+
* The children of an icon, drawn into it. A child without a `stackAlign` goes to the spot the icon
|
|
81
|
+
* keeps for it (`ctx.perfect`: its centre, size and turn), and so does text. Colours given on a
|
|
82
|
+
* child win; otherwise:
|
|
83
|
+
* - content inside — at that spot, centred, at an edge or halfway out — is cut out of a filled parent: an icon child takes
|
|
59
84
|
* the parent's accent as its primary (and the parent's primary as its accent, so its own text
|
|
60
85
|
* and details read), text the accent; on `outline` / `wireframe` it stays in the parent's
|
|
61
86
|
* colours; in a cutout it takes the tile's colour, drawn solid in the cut;
|
|
@@ -75,13 +100,21 @@ function renderStackChildren(children, ctx) {
|
|
|
75
100
|
const text = items
|
|
76
101
|
.filter((c) => typeof c === 'string' || typeof c === 'number')
|
|
77
102
|
.join('');
|
|
103
|
+
const { perfect } = ctx;
|
|
78
104
|
const layers = items.map((child, i) => {
|
|
79
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
105
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
80
106
|
if (isNtdIconElement(child)) {
|
|
81
107
|
const p = child.props;
|
|
82
|
-
const align = (_a = p.stackAlign) !== null && _a !== void 0 ? _a : '
|
|
83
|
-
|
|
84
|
-
const
|
|
108
|
+
const align = (_a = p.stackAlign) !== null && _a !== void 0 ? _a : 'perfect';
|
|
109
|
+
// the parent's own spot (1.3.8): its centre, size and turn, unless the child sets them
|
|
110
|
+
const atSpot = align === 'perfect';
|
|
111
|
+
const size = thousandth(24 * ((_b = p.stackSize) !== null && _b !== void 0 ? _b : (atSpot ? perfect.size : defaultStackSize(align))));
|
|
112
|
+
const [alignX, alignY] = atSpot
|
|
113
|
+
? [thousandth(perfect.x - size / 2), thousandth(perfect.y - size / 2)]
|
|
114
|
+
: stackPlacement(align, size);
|
|
115
|
+
// nudged from the aligned spot (1.3.7) — a share of the parent, so it scales with it
|
|
116
|
+
const x = stackOffset(alignX, p.stackOffsetX);
|
|
117
|
+
const y = stackOffset(alignY, p.stackOffsetY);
|
|
85
118
|
const badge = isCornerBadge(align);
|
|
86
119
|
const icon = React.cloneElement(child, {
|
|
87
120
|
x,
|
|
@@ -95,23 +128,28 @@ function renderStackChildren(children, ctx) {
|
|
|
95
128
|
const cx = x + size / 2;
|
|
96
129
|
const cy = y + size / 2;
|
|
97
130
|
// turned about its own centre (1.3.6) — through a group: a nested <svg> takes no transform
|
|
98
|
-
const
|
|
131
|
+
const rotation = (_g = p.stackRotation) !== null && _g !== void 0 ? _g : (atSpot ? perfect.rotation : 0);
|
|
132
|
+
const turn = rotation ? `rotate(${rotation} ${cx} ${cy})` : undefined;
|
|
99
133
|
if (!badge && !turn) {
|
|
100
134
|
return icon;
|
|
101
135
|
}
|
|
102
|
-
return (jsxRuntime.jsxs("g", { transform: turn, children: [badge && jsxRuntime.jsx("circle", { cx: cx, cy: cy, r: size / 2 + BADGE_GAP, fill: ctx.accentColor }), icon] }, (
|
|
136
|
+
return (jsxRuntime.jsxs("g", { transform: turn, children: [badge && jsxRuntime.jsx("circle", { cx: cx, cy: cy, r: size / 2 + BADGE_GAP, fill: ctx.accentColor }), icon] }, (_h = child.key) !== null && _h !== void 0 ? _h : i));
|
|
103
137
|
}
|
|
104
138
|
return React.isValidElement(child) ? child : null;
|
|
105
139
|
});
|
|
106
|
-
const content = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [layers, text && (jsxRuntime.jsx("text", { x:
|
|
140
|
+
const content = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [layers, text && (jsxRuntime.jsx("text", { x: perfect.x, y: perfect.y, transform: perfect.rotation ? `rotate(${perfect.rotation} ${perfect.x} ${perfect.y})` : undefined, textAnchor: "middle", dominantBaseline: "central", fontSize: (_a = ctx.textSize) !== null && _a !== void 0 ? _a : defaultTextSize(text.length, perfect.size), fontWeight: 700, fill: (_b = ctx.textColor) !== null && _b !== void 0 ? _b : insidePrimary, stroke: "none", children: text }))] }));
|
|
107
141
|
return cutout ? jsxRuntime.jsx("g", { transform: CUTOUT_SHAPE, children: content }) : content;
|
|
108
142
|
}
|
|
109
143
|
|
|
144
|
+
exports.BOX_PERFECT_STACK = BOX_PERFECT_STACK;
|
|
110
145
|
exports.NTD_ICON_MARK = NTD_ICON_MARK;
|
|
146
|
+
exports.PERFECT_STACK = PERFECT_STACK;
|
|
111
147
|
exports.defaultStackSize = defaultStackSize;
|
|
112
148
|
exports.defaultTextSize = defaultTextSize;
|
|
113
149
|
exports.isCornerBadge = isCornerBadge;
|
|
114
150
|
exports.isFilledVariant = isFilledVariant;
|
|
115
151
|
exports.isNtdIconElement = isNtdIconElement;
|
|
152
|
+
exports.perfectStackOf = perfectStackOf;
|
|
116
153
|
exports.renderStackChildren = renderStackChildren;
|
|
154
|
+
exports.stackOffset = stackOffset;
|
|
117
155
|
exports.stackPlacement = stackPlacement;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
1
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import { useNiceTranslation, useControllableState } from '@nice2dev/ui-core';
|
|
3
3
|
import { forwardRef, useRef, useId, useState, useCallback, useMemo, useImperativeHandle } from 'react';
|
|
4
4
|
import { NtdPlus, NtdTrash, NtdCheck, NtdCopy } from './icons/actions.js';
|
|
5
5
|
import { NtdClose } from './icons/navigation.js';
|
|
6
|
-
import { niceIconStackCode, renderIconStack, stackChildrenOf, isValidTextBinding
|
|
7
|
-
import { defaultStackSize, defaultTextSize } from './stacking.js';
|
|
6
|
+
import { niceIconStackCode, renderIconStack, stackParentId, stackChildrenOf, isValidTextBinding } from './iconStack.js';
|
|
7
|
+
import { BOX_PERFECT_STACK, defaultStackSize, defaultTextSize, perfectStackOf } from './stacking.js';
|
|
8
8
|
|
|
9
9
|
const ALIGNS = [
|
|
10
|
+
'perfect',
|
|
10
11
|
'center',
|
|
11
12
|
'top',
|
|
12
13
|
'bottom',
|
|
@@ -66,6 +67,8 @@ function removeLayer(layers, id) {
|
|
|
66
67
|
align: undefined,
|
|
67
68
|
size: undefined,
|
|
68
69
|
rotation: undefined,
|
|
70
|
+
offsetX: undefined,
|
|
71
|
+
offsetY: undefined,
|
|
69
72
|
};
|
|
70
73
|
return [
|
|
71
74
|
newBase,
|
|
@@ -157,19 +160,30 @@ const NiceIconStacker = forwardRef(function NiceIconStacker({ icons, layers: lay
|
|
|
157
160
|
return (jsxs("div", { className: ['nice-icon-stacker', className].filter(Boolean).join(' '), children: [jsxs("div", { className: "nice-icon-stacker__toolbar", children: [jsxs("button", { type: "button", onClick: add, disabled: !current, children: [jsx(NtdPlus, { size: 14 }), " ", addLabel] }), jsxs("button", { type: "button", onClick: clear, disabled: layers.length === 0, children: [jsx(NtdTrash, { size: 14 }), " ", t('iconStacker.clear', 'Clear the stack')] })] }), !base ? (jsx("p", { className: "nice-icon-stacker__empty", children: t('iconStacker.empty', 'The stack is empty. Add an icon to start one.') })) : (jsxs("div", { className: "nice-icon-stacker__body", children: [jsx("div", { className: "nice-icon-stacker__preview", "aria-label": t('iconStacker.preview', 'Preview'), role: "group", children: PREVIEW_SIZES.map((s) => (jsxs("span", { className: "nice-icon-stacker__preview-cell", children: [renderIconStack(layers, icons, {
|
|
158
161
|
baseProps: { ...previewProps, size: s, title: base.icon },
|
|
159
162
|
}), jsxs("small", { children: [s, "px"] })] }, s))) }), jsx("ol", { className: "nice-icon-stacker__layers", "aria-label": t('iconStacker.layers', 'Layers'), children: tree.map(({ layer: l, depth }) => {
|
|
160
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
163
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
161
164
|
const Icon = resolve(l.icon);
|
|
162
165
|
const isBase = l === base;
|
|
163
|
-
const align = (_a = l.align) !== null && _a !== void 0 ? _a : '
|
|
164
|
-
|
|
166
|
+
const align = (_a = l.align) !== null && _a !== void 0 ? _a : 'perfect';
|
|
167
|
+
// the spot the parent keeps for stacked icons (1.3.8): its size and turn are the
|
|
168
|
+
// layer's defaults while it sits there
|
|
169
|
+
const parentId = stackParentId(layers, l);
|
|
170
|
+
const parentLayer = parentId ? layers.find((p) => p.id === parentId) : undefined;
|
|
171
|
+
const spot = (parentLayer && perfectStackOf(resolve(parentLayer.icon))) || BOX_PERFECT_STACK;
|
|
172
|
+
const atSpot = align === 'perfect';
|
|
173
|
+
const share = (_b = l.size) !== null && _b !== void 0 ? _b : (atSpot ? spot.size : defaultStackSize(align));
|
|
174
|
+
const turnDefault = atSpot ? spot.rotation : 0;
|
|
175
|
+
const turn = (_c = l.rotation) !== null && _c !== void 0 ? _c : turnDefault;
|
|
165
176
|
const innermost = stackChildrenOf(layers, l.id).length === 0;
|
|
166
|
-
const textSize = (
|
|
177
|
+
const textSize = (_d = l.textSize) !== null && _d !== void 0 ? _d : defaultTextSize(((_e = l.text) !== null && _e !== void 0 ? _e : '').length || 1, (_f = perfectStackOf(Icon)) === null || _f === void 0 ? void 0 : _f.size);
|
|
167
178
|
const bindingInvalid = !!l.textBinding && !isValidTextBinding(l.textBinding);
|
|
168
179
|
const depthStyle = {
|
|
169
180
|
['--nice-icon-stacker-depth']: String(depth),
|
|
170
181
|
};
|
|
171
182
|
const label = (key, fallback) => t(key, fallback).replace('{icon}', l.icon);
|
|
172
|
-
return (jsxs("li", { className: "nice-icon-stacker__layer", style: depthStyle, children: [jsxs("div", { className: "nice-icon-stacker__layer-row", children: [jsx("input", { type: "radio", name: targetGroup, checked: (target === null || target === void 0 ? void 0 : target.id) === l.id, onChange: () => setSelected(l.id), "aria-label": label('iconStacker.target', 'Add the next icon into {icon}'), title: label('iconStacker.target', 'Add the next icon into {icon}') }), jsx("span", { className: "nice-icon-stacker__layer-icon", children: Icon ? jsx(Icon, { size: 24, variant: l.variant }) : null }), jsxs("span", { className: "nice-icon-stacker__layer-name", children: [l.icon, isBase && (jsx("span", { className: "nice-icon-stacker__badge", children: t('iconStacker.base', 'Base') }))] }), !isBase && (jsxs("label", { className: "nice-icon-stacker__field", children: [jsx("span", { children: t('iconStacker.align', 'Position') }), jsx("select", { value: align, onChange: (e) => update(l.id, { align: e.target.value }), children: ALIGNS.map((a) => (jsx("option", { value: a, children: a }, a))) })] })), !isBase && (jsxs("label", { className: "nice-icon-stacker__field", children: [jsx("span", { children: t('iconStacker.size', 'Size') }), jsx("input", { type: "range", min: 0.2, max: 1, step: 0.05, value: share, onChange: (e) => update(l.id, { size: Number(e.target.value) }) }), jsxs("output", { children: [Math.round(share * 100), "%"] })] })), jsx("button", { type: "button", className: "nice-icon-stacker__remove", onClick: () => remove(l.id), "aria-label": label('iconStacker.remove', 'Remove {icon}'), title: label('iconStacker.remove', 'Remove {icon}'), children: jsx(NtdTrash, { size: 14 }) })] }), jsxs("details", { className: "nice-icon-stacker__more", children: [jsx("summary", { children: t('iconStacker.more', 'More') }), jsxs("div", { className: "nice-icon-stacker__more-body", children: [!isBase && (jsxs(
|
|
183
|
+
return (jsxs("li", { className: "nice-icon-stacker__layer", style: depthStyle, children: [jsxs("div", { className: "nice-icon-stacker__layer-row", children: [jsx("input", { type: "radio", name: targetGroup, checked: (target === null || target === void 0 ? void 0 : target.id) === l.id, onChange: () => setSelected(l.id), "aria-label": label('iconStacker.target', 'Add the next icon into {icon}'), title: label('iconStacker.target', 'Add the next icon into {icon}') }), jsx("span", { className: "nice-icon-stacker__layer-icon", children: Icon ? jsx(Icon, { size: 24, variant: l.variant }) : null }), jsxs("span", { className: "nice-icon-stacker__layer-name", children: [l.icon, isBase && (jsx("span", { className: "nice-icon-stacker__badge", children: t('iconStacker.base', 'Base') }))] }), !isBase && (jsxs("label", { className: "nice-icon-stacker__field", children: [jsx("span", { children: t('iconStacker.align', 'Position') }), jsx("select", { value: align, onChange: (e) => update(l.id, { align: e.target.value }), children: ALIGNS.map((a) => (jsx("option", { value: a, children: a }, a))) })] })), !isBase && (jsxs("label", { className: "nice-icon-stacker__field", children: [jsx("span", { children: t('iconStacker.size', 'Size') }), jsx("input", { type: "range", min: 0.2, max: 1, step: 0.05, value: share, onChange: (e) => update(l.id, { size: Number(e.target.value) }) }), jsxs("output", { children: [Math.round(share * 100), "%"] })] })), jsx("button", { type: "button", className: "nice-icon-stacker__remove", onClick: () => remove(l.id), "aria-label": label('iconStacker.remove', 'Remove {icon}'), title: label('iconStacker.remove', 'Remove {icon}'), children: jsx(NtdTrash, { size: 14 }) })] }), jsxs("details", { className: "nice-icon-stacker__more", children: [jsx("summary", { children: t('iconStacker.more', 'More') }), jsxs("div", { className: "nice-icon-stacker__more-body", children: [!isBase && (jsxs(Fragment, { children: [jsxs("label", { className: "nice-icon-stacker__field", children: [jsx("span", { children: t('iconStacker.rotation', 'Turn') }), jsx("input", { type: "range", min: -180, max: 180, step: 15, value: turn, onChange: (e) => {
|
|
184
|
+
const v = Number(e.target.value);
|
|
185
|
+
update(l.id, { rotation: v === turnDefault ? undefined : v });
|
|
186
|
+
} }), jsxs("output", { children: [turn, "\u00B0"] })] }), jsxs("label", { className: "nice-icon-stacker__field", children: [jsx("span", { children: t('iconStacker.offsetX', 'Shift right') }), jsx("input", { type: "range", min: -50, max: 50, step: 1, value: (_g = l.offsetX) !== null && _g !== void 0 ? _g : 0, onChange: (e) => update(l.id, { offsetX: Number(e.target.value) || undefined }) }), jsxs("output", { children: [(_h = l.offsetX) !== null && _h !== void 0 ? _h : 0, "%"] })] }), jsxs("label", { className: "nice-icon-stacker__field", children: [jsx("span", { children: t('iconStacker.offsetY', 'Shift down') }), jsx("input", { type: "range", min: -50, max: 50, step: 1, value: (_j = l.offsetY) !== null && _j !== void 0 ? _j : 0, onChange: (e) => update(l.id, { offsetY: Number(e.target.value) || undefined }) }), jsxs("output", { children: [(_k = l.offsetY) !== null && _k !== void 0 ? _k : 0, "%"] })] })] })), jsx(ColorField, { label: t('iconStacker.primary', 'Primary'), value: l.primaryColor, onChange: (v) => update(l.id, { primaryColor: v }), autoLabel: autoLabel, resetLabel: resetLabel }), jsx(ColorField, { label: t('iconStacker.secondary', 'Secondary'), value: l.secondaryColor, onChange: (v) => update(l.id, { secondaryColor: v }), autoLabel: autoLabel, resetLabel: resetLabel }), jsx(ColorField, { label: t('iconStacker.accent', 'Accent'), value: l.accentColor, onChange: (v) => update(l.id, { accentColor: v }), autoLabel: autoLabel, resetLabel: resetLabel })] })] }), (innermost || l.text || l.textBinding) && (jsxs("div", { className: "nice-icon-stacker__text", children: [jsxs("label", { className: "nice-icon-stacker__field", children: [jsx("span", { children: t('iconStacker.text', 'Text') }), jsx("input", { type: "text", value: (_l = l.text) !== null && _l !== void 0 ? _l : '', maxLength: 4, onChange: (e) => update(l.id, { text: e.target.value || undefined }) })] }), jsxs("label", { className: "nice-icon-stacker__field", children: [jsx("span", { children: t('iconStacker.textSize', 'Text size') }), jsx("input", { type: "range", min: 3, max: 14, step: 0.5, value: textSize, onChange: (e) => update(l.id, { textSize: Number(e.target.value) }) }), jsx("output", { children: textSize }), l.textSize !== undefined && (jsx("button", { type: "button", className: "nice-icon-stacker__reset", onClick: () => update(l.id, { textSize: undefined }), "aria-label": resetLabel, title: resetLabel, children: jsx(NtdClose, { size: 12 }) }))] }), jsx(ColorField, { label: t('iconStacker.textColor', 'Text colour'), value: l.textColor, onChange: (v) => update(l.id, { textColor: v }), autoLabel: autoLabel, resetLabel: resetLabel }), jsxs("label", { className: "nice-icon-stacker__field", children: [jsx("span", { children: t('iconStacker.bind', 'Bind to') }), jsx("input", { type: "text", value: (_m = l.textBinding) !== null && _m !== void 0 ? _m : '', "aria-invalid": bindingInvalid || undefined, title: t('iconStacker.bindHint', 'The name of the value the text shows, e.g. count — the text above is a sample'), onChange: (e) => update(l.id, { textBinding: e.target.value.trim() || undefined }) })] })] }))] }, l.id));
|
|
173
187
|
}) }), jsxs("div", { className: "nice-icon-stacker__code", children: [jsx("pre", { children: code }), jsxs("button", { type: "button", onClick: copy, children: [copied ? jsx(NtdCheck, { size: 14 }) : jsx(NtdCopy, { size: 14 }), ' ', copied
|
|
174
188
|
? t('iconStacker.copied', 'Copied')
|
|
175
189
|
: t('iconStacker.copy', 'Copy the code')] })] })] }))] }));
|
package/dist/esm/createIcon.js
CHANGED
|
@@ -2,7 +2,7 @@ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
|
2
2
|
import { forwardRef, useId, useSyncExternalStore } from 'react';
|
|
3
3
|
import { sharpenTree, roundTree, wireTree, MINI_SCALE } from './sharpen.js';
|
|
4
4
|
import { generateSmilAnimation } from './smilAnimations.js';
|
|
5
|
-
import { renderStackChildren, NTD_ICON_MARK } from './stacking.js';
|
|
5
|
+
import { BOX_PERFECT_STACK, renderStackChildren, NTD_ICON_MARK, PERFECT_STACK } from './stacking.js';
|
|
6
6
|
import { SEMANTIC_COLOR_VARS, SEMANTIC_COLOR_DEFAULTS, SIZE_MAP, GRADIENT_PRESETS } from './types.js';
|
|
7
7
|
|
|
8
8
|
/* ── Dark mode detection hook ───────────────────────── */
|
|
@@ -113,12 +113,20 @@ function renderCutoutShape(shape, fill, maskId) {
|
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
115
|
function createIcon(options) {
|
|
116
|
+
var _a, _b, _c, _d;
|
|
116
117
|
const { displayName, viewBox = '0 0 24 24', paths, textCenter = BOX_CENTER } = options;
|
|
117
|
-
const
|
|
118
|
+
const solidDuotone = (props) => paths.solid({ ...props, accentColor: props.secondaryColor, accentOpacity: 1 });
|
|
119
|
+
const perfect = {
|
|
120
|
+
x: (_a = options.perfectStackX) !== null && _a !== void 0 ? _a : textCenter[0],
|
|
121
|
+
y: (_b = options.perfectStackY) !== null && _b !== void 0 ? _b : textCenter[1],
|
|
122
|
+
rotation: (_c = options.perfectStackRotation) !== null && _c !== void 0 ? _c : BOX_PERFECT_STACK.rotation,
|
|
123
|
+
size: (_d = options.perfectStackSize) !== null && _d !== void 0 ? _d : BOX_PERFECT_STACK.size,
|
|
124
|
+
};
|
|
125
|
+
const Icon = forwardRef(({ size = 'md', variant = 'solid', cutoutShape = 'rounded-square', color, lightColor, darkColor, primaryColor: propPrimaryColor = 'currentColor', secondaryColor, accentColor, primaryOpacity = 1, secondaryOpacity = 0.4, accentOpacity = 1, strokeWidth = 1, strokeLinecap: propLinecap, strokeLinejoin: propLinejoin, animation, animationDuration, smilAnimation, smilDuration = 1, smilRepeatCount = 'indefinite', smilEasing = 'ease-in-out', smilDelay = 0, gradient, gradientType = 'linear', gradientAngle = 135, gradientAnimation,
|
|
118
126
|
// Transform props
|
|
119
127
|
rotate, flipX, flipY, scale, transition, transformOrigin = 'center center',
|
|
120
128
|
// stacking (1.3.5): the parent icon reads a child's own align / size from its props
|
|
121
|
-
children, stackAlign: _stackAlign, stackSize: _stackSize, stackRotation: _stackRotation, textColor, textSize, title, className, style, ...rest }, ref) => {
|
|
129
|
+
children, stackAlign: _stackAlign, stackSize: _stackSize, stackRotation: _stackRotation, stackOffsetX: _stackOffsetX, stackOffsetY: _stackOffsetY, textColor, textSize, title, className, style, ...rest }, ref) => {
|
|
122
130
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
123
131
|
const resolvedSize = typeof size === 'number' ? size : ((_a = SIZE_MAP[size]) !== null && _a !== void 0 ? _a : 24);
|
|
124
132
|
const gradId = useId();
|
|
@@ -156,10 +164,13 @@ function createIcon(options) {
|
|
|
156
164
|
};
|
|
157
165
|
// Resolve renderer with fallback chain. `wireframe` has no authored layer
|
|
158
166
|
// at all — it is a mechanical re-draw of the full `solid` construction, so
|
|
159
|
-
// it never indexes `paths`.
|
|
167
|
+
// it never indexes `paths`. A duotone left out is the solid with its details
|
|
168
|
+
// in secondary (1.3.8): the body keeps primary, the larger area.
|
|
160
169
|
const renderer = variant === 'wireframe'
|
|
161
170
|
? paths.solid
|
|
162
|
-
:
|
|
171
|
+
: variant === 'duotone' && !paths.duotone
|
|
172
|
+
? solidDuotone
|
|
173
|
+
: ((_g = (_f = (_e = (_d = (_c = (_b = paths[variant]) !== null && _b !== void 0 ? _b : (variant === 'sharp' ? paths.solid : undefined)) !== null && _c !== void 0 ? _c : (variant === 'rounded' ? paths.solid : undefined)) !== null && _d !== void 0 ? _d : (variant === 'mini' ? paths.solid : undefined)) !== null && _e !== void 0 ? _e : (variant === '3d' ? paths.solid : undefined)) !== null && _f !== void 0 ? _f : (variant === 'vivid' ? paths.solid : undefined)) !== null && _g !== void 0 ? _g : paths.solid);
|
|
163
174
|
// 3D variant uses a filter for depth effect
|
|
164
175
|
const is3d = variant === '3d';
|
|
165
176
|
const filterId = useId();
|
|
@@ -234,7 +245,7 @@ function createIcon(options) {
|
|
|
234
245
|
accentColor: resolvedAccent,
|
|
235
246
|
tileColor: gradient ? effectivePrimary : resolvedSecondary,
|
|
236
247
|
strokeWidth,
|
|
237
|
-
|
|
248
|
+
perfect,
|
|
238
249
|
textColor,
|
|
239
250
|
textSize,
|
|
240
251
|
});
|
|
@@ -252,8 +263,10 @@ function createIcon(options) {
|
|
|
252
263
|
}) })] }) })), smilAnimation ? (needsSmilScaleWrapper ? (jsxs("g", { transform: `translate(${center.x}, ${center.y})`, filter: is3d ? `url(#${filterId})` : undefined, children: [jsx("g", { transform: `translate(-${center.x}, -${center.y})`, children: iconContent }), smilAnimationElements] })) : (jsxs("g", { filter: is3d ? `url(#${filterId})` : undefined, children: [iconContent, smilAnimationElements] }))) : is3d ? (jsx("g", { filter: `url(#${filterId})`, children: iconContent })) : (iconContent)] }));
|
|
253
264
|
});
|
|
254
265
|
Icon.displayName = displayName;
|
|
255
|
-
// lets a parent icon tell this one among its children (stacking, 1.3.5)
|
|
266
|
+
// lets a parent icon tell this one among its children (stacking, 1.3.5), and tells the stacker
|
|
267
|
+
// where a child of this one goes by default (1.3.8)
|
|
256
268
|
Icon[NTD_ICON_MARK] = true;
|
|
269
|
+
Icon[PERFECT_STACK] = perfect;
|
|
257
270
|
return Icon;
|
|
258
271
|
}
|
|
259
272
|
|
package/dist/esm/iconParts.js
CHANGED
|
@@ -9,6 +9,19 @@ import { createIcon } from './createIcon.js';
|
|
|
9
9
|
function detailColor({ variant, secondaryColor, accentColor }) {
|
|
10
10
|
return variant === 'cutout' ? accentColor : secondaryColor;
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* A duotone renderer with its two colours swapped, at full strength (1.3.8) — for a duotone that
|
|
14
|
+
* drew its larger area in secondary (a pale body under a primary outline): the body turns
|
|
15
|
+
* primary, the outline and the details secondary.
|
|
16
|
+
*/
|
|
17
|
+
function swapDuotone(render) {
|
|
18
|
+
return (props) => render({
|
|
19
|
+
...props,
|
|
20
|
+
primaryColor: props.secondaryColor,
|
|
21
|
+
secondaryColor: props.primaryColor,
|
|
22
|
+
secondaryOpacity: 1,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
12
25
|
/**
|
|
13
26
|
* `content` drawn only inside `shape` — for accent lines that read as a cut through a shape (a
|
|
14
27
|
* pencil's band, a calendar's header line, an envelope's flap): clipped, they meet the shape's
|
|
@@ -40,6 +53,10 @@ function bellIcon(displayName, ringing) {
|
|
|
40
53
|
const parts = ({ primaryColor, strokeWidth }, detail, rings, ringsOpacity = 1) => (jsxs(Fragment, { children: [jsx("path", { d: BELL, fill: primaryColor }), jsx("path", { d: BELL_CLAPPER, fill: detail }), ringing && (jsx("path", { d: BELL_RINGS, stroke: rings, strokeWidth: strokeWidth, opacity: ringsOpacity }))] }));
|
|
41
54
|
return createIcon({
|
|
42
55
|
displayName,
|
|
56
|
+
// stacked icons and text go into the bell's body, above the clapper (1.3.8)
|
|
57
|
+
perfectStackX: 12,
|
|
58
|
+
perfectStackY: 10.5,
|
|
59
|
+
perfectStackSize: 0.4,
|
|
43
60
|
paths: {
|
|
44
61
|
solid: (props) => parts(props, props.primaryColor, props.primaryColor),
|
|
45
62
|
outline: ({ primaryColor, strokeWidth }) => (jsx("path", { d: `${BELL}${BELL_CLAPPER_LINE}${ringing ? BELL_RINGS : ''}`, stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" })),
|
|
@@ -58,20 +75,24 @@ const PAPER_FOLD_SHARP = 'M12 2v8h8z';
|
|
|
58
75
|
* A paper icon — NtdFile, and every document drawn on the same page (NtdFileText, NtdInvoice,
|
|
59
76
|
* NtdContract, …), so their pages and folds match. The fold is secondary when the page is filled;
|
|
60
77
|
* `text` is the document's writing, a path of strokes kept below the fold (y ≥ 11, x 7–17),
|
|
61
|
-
* drawn in the accent colour on a filled page and in primary on a stroked one.
|
|
78
|
+
* drawn in the accent colour on a filled page (secondary in duotone) and in primary on a stroked one.
|
|
62
79
|
*/
|
|
63
80
|
function paperIcon(displayName, text = '') {
|
|
64
81
|
return createIcon({
|
|
65
82
|
displayName,
|
|
83
|
+
// stacked icons and text go onto the page below the fold (1.3.8), the same on every paper
|
|
84
|
+
perfectStackX: 12,
|
|
85
|
+
perfectStackY: 14,
|
|
86
|
+
perfectStackSize: 0.5,
|
|
66
87
|
paths: {
|
|
67
88
|
solid: ({ primaryColor, secondaryColor, accentColor, accentOpacity }) => (jsxs(Fragment, { children: [jsx("path", { d: PAPER, fill: primaryColor }), jsx("path", { d: PAPER_FOLD, fill: secondaryColor }), text && (jsx("path", { d: text, stroke: accentColor, strokeOpacity: accentOpacity, strokeWidth: "1.5", strokeLinecap: "round", fill: "none" }))] })),
|
|
68
89
|
// square at every corner, the fold included — the derived `sharp` keeps a path's arcs round
|
|
69
90
|
sharp: ({ primaryColor, secondaryColor, accentColor, accentOpacity }) => (jsxs(Fragment, { children: [jsx("path", { d: PAPER_SHARP, fill: primaryColor }), jsx("path", { d: PAPER_FOLD_SHARP, fill: secondaryColor }), text && (jsx("path", { d: text, stroke: accentColor, strokeOpacity: accentOpacity, strokeWidth: "1.5", fill: "none" }))] })),
|
|
70
91
|
outline: ({ primaryColor, strokeWidth }) => (jsx("path", { d: `${PAPER}${PAPER_FOLD_LINE}${text}`, stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" })),
|
|
71
|
-
duotone
|
|
92
|
+
// duotone (1.3.8): createIcon's default — the solid page, its writing in secondary like the fold
|
|
72
93
|
vivid: ({ primaryColor, secondaryColor }) => (jsxs(Fragment, { children: [jsx("path", { d: PAPER, fill: primaryColor }), jsx("path", { d: PAPER, fill: "white", opacity: "0.1" }), jsx("path", { d: PAPER_FOLD, fill: secondaryColor }), text && (jsx("path", { d: text, stroke: "white", strokeOpacity: "0.9", strokeWidth: "1.5", strokeLinecap: "round", fill: "none" }))] })),
|
|
73
94
|
},
|
|
74
95
|
});
|
|
75
96
|
}
|
|
76
97
|
|
|
77
|
-
export { bellIcon, detailColor, paperIcon, within };
|
|
98
|
+
export { bellIcon, detailColor, paperIcon, swapDuotone, within };
|
package/dist/esm/iconStack.js
CHANGED
|
@@ -23,11 +23,13 @@ function niceIconStackCode(layers) {
|
|
|
23
23
|
}
|
|
24
24
|
const bound = layers.filter((l) => isValidTextBinding(l.textBinding));
|
|
25
25
|
const write = (layer, parent, indent) => {
|
|
26
|
-
var _a;
|
|
27
26
|
const attrs = [
|
|
28
|
-
|
|
27
|
+
// the parent's own spot is the default (1.3.8), so only another position is written
|
|
28
|
+
parent && layer.align && layer.align !== 'perfect' ? `stackAlign="${layer.align}"` : '',
|
|
29
29
|
parent && layer.size !== undefined ? `stackSize={${layer.size}}` : '',
|
|
30
|
-
parent && layer.rotation ? `stackRotation={${layer.rotation}}` : '',
|
|
30
|
+
parent && layer.rotation !== undefined ? `stackRotation={${layer.rotation}}` : '',
|
|
31
|
+
parent && layer.offsetX ? `stackOffsetX={${layer.offsetX}}` : '',
|
|
32
|
+
parent && layer.offsetY ? `stackOffsetY={${layer.offsetY}}` : '',
|
|
31
33
|
layer.variant && layer.variant !== (parent === null || parent === void 0 ? void 0 : parent.variant) ? `variant="${layer.variant}"` : '',
|
|
32
34
|
...COLOR_PROPS.map((p) => (layer[p] ? `${p}="${layer[p]}"` : '')),
|
|
33
35
|
layer.textSize !== undefined ? `textSize={${layer.textSize}}` : '',
|
|
@@ -57,7 +59,7 @@ function niceIconStackCode(layers) {
|
|
|
57
59
|
function renderIconStack(layers, icons, { baseProps, values } = {}) {
|
|
58
60
|
const resolve = (name) => (typeof icons === 'function' ? icons(name) : icons[name]);
|
|
59
61
|
const draw = (layer, parent) => {
|
|
60
|
-
var _a
|
|
62
|
+
var _a;
|
|
61
63
|
const Icon = resolve(layer.icon);
|
|
62
64
|
if (!Icon) {
|
|
63
65
|
return null;
|
|
@@ -83,7 +85,7 @@ function renderIconStack(layers, icons, { baseProps, values } = {}) {
|
|
|
83
85
|
inner,
|
|
84
86
|
text));
|
|
85
87
|
}
|
|
86
|
-
return (createElement(Icon, { ...own, key: layer.id, stackAlign:
|
|
88
|
+
return (createElement(Icon, { ...own, key: layer.id, stackAlign: layer.align, stackSize: layer.size, stackRotation: layer.rotation, stackOffsetX: layer.offsetX, stackOffsetY: layer.offsetY, variant: layer.variant !== parent.variant ? layer.variant : undefined },
|
|
87
89
|
inner,
|
|
88
90
|
text));
|
|
89
91
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { createIcon } from '../createIcon.js';
|
|
3
|
+
import { swapDuotone } from '../iconParts.js';
|
|
3
4
|
|
|
4
5
|
/* ────────────────────────────────────────────────────────────────────────────
|
|
5
6
|
UNIVERSAL ACCESS
|
|
@@ -47,7 +48,7 @@ const NtdDeaf = /* @__PURE__ */ createIcon({
|
|
|
47
48
|
paths: {
|
|
48
49
|
solid: ({ primaryColor }) => (jsxs(Fragment, { children: [jsx("path", { d: "M10 5a5 5 0 015 5c0 2-1 3-2 4s-2 2-2 4v2", stroke: primaryColor, strokeWidth: "2", fill: "none", strokeLinecap: "round" }), jsx("path", { d: "M7 8a3 3 0 013-3", stroke: primaryColor, strokeWidth: "2", fill: "none", strokeLinecap: "round" }), jsx("path", { d: "M4 4l16 16", stroke: primaryColor, strokeWidth: "2", strokeLinecap: "round" })] })),
|
|
49
50
|
outline: ({ primaryColor, strokeWidth }) => (jsxs(Fragment, { children: [jsx("path", { d: "M10 5a5 5 0 015 5c0 2-1 3-2 4s-2 2-2 4v2", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none", strokeLinecap: "round" }), jsx("path", { d: "M7 8a3 3 0 013-3", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none", strokeLinecap: "round" }), jsx("path", { d: "M4 4l16 16", stroke: primaryColor, strokeWidth: strokeWidth, strokeLinecap: "round" })] })),
|
|
50
|
-
duotone: ({ primaryColor, secondaryColor, secondaryOpacity, strokeWidth }) => (jsxs(Fragment, { children: [jsx("circle", { cx: "12", cy: "10", r: "6", fill: secondaryColor, opacity: secondaryOpacity }), jsx("path", { d: "M10 5a5 5 0 015 5c0 2-1 3-2 4s-2 2-2 4v2", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none", strokeLinecap: "round" }), jsx("path", { d: "M7 8a3 3 0 013-3", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none", strokeLinecap: "round" }), jsx("path", { d: "M4 4l16 16", stroke: primaryColor, strokeWidth: strokeWidth, strokeLinecap: "round" })] })),
|
|
51
|
+
duotone: swapDuotone(({ primaryColor, secondaryColor, secondaryOpacity, strokeWidth }) => (jsxs(Fragment, { children: [jsx("circle", { cx: "12", cy: "10", r: "6", fill: secondaryColor, opacity: secondaryOpacity }), jsx("path", { d: "M10 5a5 5 0 015 5c0 2-1 3-2 4s-2 2-2 4v2", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none", strokeLinecap: "round" }), jsx("path", { d: "M7 8a3 3 0 013-3", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none", strokeLinecap: "round" }), jsx("path", { d: "M4 4l16 16", stroke: primaryColor, strokeWidth: strokeWidth, strokeLinecap: "round" })] }))),
|
|
51
52
|
vivid: ({ primaryColor, secondaryColor }) => (jsxs(Fragment, { children: [jsx("path", { d: "M10 5a5 5 0 015 5c0 2-1 3-2 4s-2 2-2 4v2", stroke: primaryColor, strokeWidth: "2", fill: "none", strokeLinecap: "round" }), jsx("path", { d: "M7 8a3 3 0 013-3", stroke: secondaryColor, strokeWidth: "1.8", fill: "none", strokeLinecap: "round" }), jsx("path", { d: "M4 4l16 16", stroke: "#3B82F6", strokeWidth: "1.5", strokeLinecap: "round" })] })),
|
|
52
53
|
},
|
|
53
54
|
});
|
|
@@ -56,7 +57,7 @@ const NtdSignLanguage = /* @__PURE__ */ createIcon({
|
|
|
56
57
|
paths: {
|
|
57
58
|
solid: ({ primaryColor }) => (jsx(Fragment, { children: jsx("path", { d: "M8 13V7a2 2 0 014 0v2M12 9V6a2 2 0 014 0v3M16 9V7a2 2 0 014 0v6c0 4-3 7-7 7h-1c-3 0-6-2-6-5v-2a2 2 0 014 0v1", fill: primaryColor }) })),
|
|
58
59
|
outline: ({ primaryColor, strokeWidth }) => (jsx(Fragment, { children: jsx("path", { d: "M8 13V7a2 2 0 014 0v2M12 9V6a2 2 0 014 0v3M16 9V7a2 2 0 014 0v6c0 4-3 7-7 7h-1c-3 0-6-2-6-5v-2a2 2 0 014 0v1", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none", strokeLinecap: "round", strokeLinejoin: "round" }) })),
|
|
59
|
-
duotone: ({ primaryColor, secondaryColor, secondaryOpacity, strokeWidth }) => (jsxs(Fragment, { children: [jsx("path", { d: "M16 9V7a2 2 0 014 0v6c0 4-3 7-7 7h-1c-3 0-6-2-6-5v-2a2 2 0 014 0v1", fill: secondaryColor, opacity: secondaryOpacity }), jsx("path", { d: "M8 13V7a2 2 0 014 0v2M12 9V6a2 2 0 014 0v3M16 9V7a2 2 0 014 0v6c0 4-3 7-7 7h-1c-3 0-6-2-6-5v-2a2 2 0 014 0v1", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none", strokeLinecap: "round", strokeLinejoin: "round" })] })),
|
|
60
|
+
duotone: swapDuotone(({ primaryColor, secondaryColor, secondaryOpacity, strokeWidth }) => (jsxs(Fragment, { children: [jsx("path", { d: "M16 9V7a2 2 0 014 0v6c0 4-3 7-7 7h-1c-3 0-6-2-6-5v-2a2 2 0 014 0v1", fill: secondaryColor, opacity: secondaryOpacity }), jsx("path", { d: "M8 13V7a2 2 0 014 0v2M12 9V6a2 2 0 014 0v3M16 9V7a2 2 0 014 0v6c0 4-3 7-7 7h-1c-3 0-6-2-6-5v-2a2 2 0 014 0v1", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none", strokeLinecap: "round", strokeLinejoin: "round" })] }))),
|
|
60
61
|
vivid: ({ primaryColor, secondaryColor: _secondaryColor }) => (jsxs(Fragment, { children: [jsx("path", { d: "M8 13V7a2 2 0 014 0v2M12 9V6a2 2 0 014 0v3M16 9V7a2 2 0 014 0v6c0 4-3 7-7 7h-1c-3 0-6-2-6-5v-2a2 2 0 014 0v1", fill: primaryColor }), jsx("path", { d: "M8 13V7a2 2 0 014 0v2M12 9V6a2 2 0 014 0v3M16 9V7a2 2 0 014 0v6c0 4-3 7-7 7h-1c-3 0-6-2-6-5v-2a2 2 0 014 0v1", fill: "white", opacity: "0.1" })] })),
|
|
61
62
|
},
|
|
62
63
|
});
|
|
@@ -74,7 +75,7 @@ const NtdAudioDescription = /* @__PURE__ */ createIcon({
|
|
|
74
75
|
paths: {
|
|
75
76
|
solid: ({ primaryColor }) => (jsxs(Fragment, { children: [jsx("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2", fill: primaryColor }), jsx("text", { x: "7", y: "15", fill: "white", fontSize: "8", fontWeight: "bold", fontFamily: "system-ui", children: "AD" })] })),
|
|
76
77
|
outline: ({ primaryColor, strokeWidth }) => (jsxs(Fragment, { children: [jsx("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsx("text", { x: "7", y: "15", fill: primaryColor, fontSize: "8", fontWeight: "bold", fontFamily: "system-ui", children: "AD" })] })),
|
|
77
|
-
duotone: ({ primaryColor, secondaryColor, secondaryOpacity, strokeWidth }) => (jsxs(Fragment, { children: [jsx("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2", fill: secondaryColor, opacity: secondaryOpacity }), jsx("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsx("text", { x: "7", y: "15", fill: primaryColor, fontSize: "8", fontWeight: "bold", fontFamily: "system-ui", children: "AD" })] })),
|
|
78
|
+
duotone: swapDuotone(({ primaryColor, secondaryColor, secondaryOpacity, strokeWidth }) => (jsxs(Fragment, { children: [jsx("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2", fill: secondaryColor, opacity: secondaryOpacity }), jsx("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsx("text", { x: "7", y: "15", fill: primaryColor, fontSize: "8", fontWeight: "bold", fontFamily: "system-ui", children: "AD" })] }))),
|
|
78
79
|
vivid: ({ primaryColor, secondaryColor: _secondaryColor }) => (jsxs(Fragment, { children: [jsx("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2", fill: primaryColor }), jsx("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2", fill: "white", opacity: "0.1" })] })),
|
|
79
80
|
},
|
|
80
81
|
});
|
|
@@ -83,7 +84,7 @@ const NtdClosedCaptions = /* @__PURE__ */ createIcon({
|
|
|
83
84
|
paths: {
|
|
84
85
|
solid: ({ primaryColor }) => (jsxs(Fragment, { children: [jsx("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2", fill: primaryColor }), jsx("text", { x: "6", y: "15", fill: "white", fontSize: "8", fontWeight: "bold", fontFamily: "system-ui", children: "CC" })] })),
|
|
85
86
|
outline: ({ primaryColor, strokeWidth }) => (jsxs(Fragment, { children: [jsx("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsx("text", { x: "6", y: "15", fill: primaryColor, fontSize: "8", fontWeight: "bold", fontFamily: "system-ui", children: "CC" })] })),
|
|
86
|
-
duotone: ({ primaryColor, secondaryColor, secondaryOpacity, strokeWidth }) => (jsxs(Fragment, { children: [jsx("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2", fill: secondaryColor, opacity: secondaryOpacity }), jsx("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsx("text", { x: "6", y: "15", fill: primaryColor, fontSize: "8", fontWeight: "bold", fontFamily: "system-ui", children: "CC" })] })),
|
|
87
|
+
duotone: swapDuotone(({ primaryColor, secondaryColor, secondaryOpacity, strokeWidth }) => (jsxs(Fragment, { children: [jsx("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2", fill: secondaryColor, opacity: secondaryOpacity }), jsx("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsx("text", { x: "6", y: "15", fill: primaryColor, fontSize: "8", fontWeight: "bold", fontFamily: "system-ui", children: "CC" })] }))),
|
|
87
88
|
vivid: ({ primaryColor, secondaryColor: _secondaryColor }) => (jsxs(Fragment, { children: [jsx("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2", fill: primaryColor }), jsx("rect", { x: "2", y: "4", width: "20", height: "16", rx: "2", fill: "white", opacity: "0.1" })] })),
|
|
88
89
|
},
|
|
89
90
|
});
|
|
@@ -95,7 +96,7 @@ const NtdDyslexia = /* @__PURE__ */ createIcon({
|
|
|
95
96
|
paths: {
|
|
96
97
|
solid: ({ primaryColor }) => (jsxs(Fragment, { children: [jsx("rect", { x: "4", y: "2", width: "16", height: "20", rx: "2", fill: primaryColor }), jsx("path", { d: "M8 7h8M8 11h6M8 15h4", stroke: "white", strokeWidth: "2", strokeLinecap: "round" }), jsx("path", { d: "M16 15l-2 2M14 15l2 2", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round" })] })),
|
|
97
98
|
outline: ({ primaryColor, strokeWidth }) => (jsxs(Fragment, { children: [jsx("rect", { x: "4", y: "2", width: "16", height: "20", rx: "2", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsx("path", { d: "M8 7h8M8 11h6M8 15h4", stroke: primaryColor, strokeWidth: strokeWidth, strokeLinecap: "round" }), jsx("path", { d: "M16 15l-2 2M14 15l2 2", stroke: primaryColor, strokeWidth: "1.5", strokeLinecap: "round" })] })),
|
|
98
|
-
duotone: ({ primaryColor, secondaryColor, secondaryOpacity, strokeWidth }) => (jsxs(Fragment, { children: [jsx("rect", { x: "4", y: "2", width: "16", height: "20", rx: "2", fill: secondaryColor, opacity: secondaryOpacity }), jsx("rect", { x: "4", y: "2", width: "16", height: "20", rx: "2", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsx("path", { d: "M8 7h8M8 11h6M8 15h4", stroke: primaryColor, strokeWidth: strokeWidth, strokeLinecap: "round" }), jsx("path", { d: "M16 15l-2 2M14 15l2 2", stroke: primaryColor, strokeWidth: "1.5", strokeLinecap: "round" })] })),
|
|
99
|
+
duotone: swapDuotone(({ primaryColor, secondaryColor, secondaryOpacity, strokeWidth }) => (jsxs(Fragment, { children: [jsx("rect", { x: "4", y: "2", width: "16", height: "20", rx: "2", fill: secondaryColor, opacity: secondaryOpacity }), jsx("rect", { x: "4", y: "2", width: "16", height: "20", rx: "2", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsx("path", { d: "M8 7h8M8 11h6M8 15h4", stroke: primaryColor, strokeWidth: strokeWidth, strokeLinecap: "round" }), jsx("path", { d: "M16 15l-2 2M14 15l2 2", stroke: primaryColor, strokeWidth: "1.5", strokeLinecap: "round" })] }))),
|
|
99
100
|
vivid: ({ primaryColor, secondaryColor: _secondaryColor }) => (jsxs(Fragment, { children: [jsx("rect", { x: "4", y: "2", width: "16", height: "20", rx: "2", fill: primaryColor }), jsx("rect", { x: "4", y: "2", width: "16", height: "20", rx: "2", fill: "white", opacity: "0.1" }), jsx("path", { d: "M8 7h8M8 11h6M8 15h4", stroke: "white", strokeWidth: "1.8", strokeLinecap: "round" }), jsx("path", { d: "M16 15l-2 2M14 15l2 2", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round" })] })),
|
|
100
101
|
},
|
|
101
102
|
});
|
|
@@ -104,7 +105,7 @@ const NtdEasyRead = /* @__PURE__ */ createIcon({
|
|
|
104
105
|
paths: {
|
|
105
106
|
solid: ({ primaryColor }) => (jsxs(Fragment, { children: [jsx("rect", { x: "2", y: "2", width: "20", height: "20", rx: "2", fill: primaryColor }), jsx("path", { d: "M6 8h5v5H6zM13 8h5M13 11h4M6 16h12M6 19h8", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round" })] })),
|
|
106
107
|
outline: ({ primaryColor, strokeWidth }) => (jsxs(Fragment, { children: [jsx("rect", { x: "2", y: "2", width: "20", height: "20", rx: "2", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsx("rect", { x: "6", y: "8", width: "5", height: "5", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsx("path", { d: "M13 8h5M13 11h4M6 16h12M6 19h8", stroke: primaryColor, strokeWidth: strokeWidth, strokeLinecap: "round" })] })),
|
|
107
|
-
duotone: ({ primaryColor, secondaryColor, secondaryOpacity, strokeWidth }) => (jsxs(Fragment, { children: [jsx("rect", { x: "2", y: "2", width: "20", height: "20", rx: "2", fill: secondaryColor, opacity: secondaryOpacity }), jsx("rect", { x: "2", y: "2", width: "20", height: "20", rx: "2", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsx("rect", { x: "6", y: "8", width: "5", height: "5", fill: primaryColor }), jsx("path", { d: "M13 8h5M13 11h4M6 16h12M6 19h8", stroke: primaryColor, strokeWidth: strokeWidth, strokeLinecap: "round" })] })),
|
|
108
|
+
duotone: swapDuotone(({ primaryColor, secondaryColor, secondaryOpacity, strokeWidth }) => (jsxs(Fragment, { children: [jsx("rect", { x: "2", y: "2", width: "20", height: "20", rx: "2", fill: secondaryColor, opacity: secondaryOpacity }), jsx("rect", { x: "2", y: "2", width: "20", height: "20", rx: "2", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsx("rect", { x: "6", y: "8", width: "5", height: "5", fill: primaryColor }), jsx("path", { d: "M13 8h5M13 11h4M6 16h12M6 19h8", stroke: primaryColor, strokeWidth: strokeWidth, strokeLinecap: "round" })] }))),
|
|
108
109
|
vivid: ({ primaryColor, secondaryColor: _secondaryColor }) => (jsxs(Fragment, { children: [jsx("rect", { x: "2", y: "2", width: "20", height: "20", rx: "2", fill: primaryColor }), jsx("rect", { x: "2", y: "2", width: "20", height: "20", rx: "2", fill: "white", opacity: "0.1" }), jsx("path", { d: "M6 8h5v5H6zM13 8h5M13 11h4M6 16h12M6 19h8", stroke: "white", strokeWidth: "1.8", strokeLinecap: "round" })] })),
|
|
109
110
|
},
|
|
110
111
|
});
|
|
@@ -116,7 +117,7 @@ const NtdScreenReader = /* @__PURE__ */ createIcon({
|
|
|
116
117
|
paths: {
|
|
117
118
|
solid: ({ primaryColor }) => (jsxs(Fragment, { children: [jsx("rect", { x: "4", y: "2", width: "16", height: "14", rx: "2", fill: primaryColor }), jsx("path", { d: "M8 18h8M10 18v2M14 18v2M8 20h8", stroke: primaryColor, strokeWidth: "2", strokeLinecap: "round" }), jsx("path", { d: "M8 7h2M8 10h4M8 13h6", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round" }), jsx("circle", { cx: "16", cy: "7", r: "1.5", fill: "white" }), jsx("path", { d: "M14 7c0-1.5 1-2.5 2-2.5s2 1 2 2.5", stroke: "white", strokeWidth: "1", fill: "none" })] })),
|
|
118
119
|
outline: ({ primaryColor, strokeWidth }) => (jsxs(Fragment, { children: [jsx("rect", { x: "4", y: "2", width: "16", height: "14", rx: "2", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsx("path", { d: "M8 18h8M10 18v2M14 18v2M8 20h8", stroke: primaryColor, strokeWidth: strokeWidth, strokeLinecap: "round" }), jsx("path", { d: "M8 7h2M8 10h4M8 13h6", stroke: primaryColor, strokeWidth: strokeWidth, strokeLinecap: "round" }), jsx("circle", { cx: "16", cy: "7", r: "1.5", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsx("path", { d: "M14 7c0-1.5 1-2.5 2-2.5s2 1 2 2.5", stroke: primaryColor, strokeWidth: "1", fill: "none" })] })),
|
|
119
|
-
duotone: ({ primaryColor, secondaryColor, secondaryOpacity, strokeWidth }) => (jsxs(Fragment, { children: [jsx("rect", { x: "4", y: "2", width: "16", height: "14", rx: "2", fill: secondaryColor, opacity: secondaryOpacity }), jsx("rect", { x: "4", y: "2", width: "16", height: "14", rx: "2", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsx("path", { d: "M8 18h8M10 18v2M14 18v2M8 20h8", stroke: primaryColor, strokeWidth: strokeWidth, strokeLinecap: "round" }), jsx("path", { d: "M8 7h2M8 10h4M8 13h6", stroke: primaryColor, strokeWidth: strokeWidth, strokeLinecap: "round" }), jsx("circle", { cx: "16", cy: "7", r: "1.5", fill: primaryColor })] })),
|
|
120
|
+
duotone: swapDuotone(({ primaryColor, secondaryColor, secondaryOpacity, strokeWidth }) => (jsxs(Fragment, { children: [jsx("rect", { x: "4", y: "2", width: "16", height: "14", rx: "2", fill: secondaryColor, opacity: secondaryOpacity }), jsx("rect", { x: "4", y: "2", width: "16", height: "14", rx: "2", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsx("path", { d: "M8 18h8M10 18v2M14 18v2M8 20h8", stroke: primaryColor, strokeWidth: strokeWidth, strokeLinecap: "round" }), jsx("path", { d: "M8 7h2M8 10h4M8 13h6", stroke: primaryColor, strokeWidth: strokeWidth, strokeLinecap: "round" }), jsx("circle", { cx: "16", cy: "7", r: "1.5", fill: primaryColor })] }))),
|
|
120
121
|
vivid: ({ primaryColor, secondaryColor: _secondaryColor }) => (jsxs(Fragment, { children: [jsx("rect", { x: "4", y: "2", width: "16", height: "14", rx: "2", fill: primaryColor }), jsx("rect", { x: "4", y: "2", width: "16", height: "14", rx: "2", fill: "white", opacity: "0.08" }), jsx("circle", { cx: "16", cy: "7", r: "1.5", fill: "white" }), jsx("path", { d: "M8 18h8M10 18v2M14 18v2M8 20h8", stroke: "white", strokeWidth: "1", strokeLinecap: "round" }), jsx("path", { d: "M8 7h2M8 10h4M8 13h6", stroke: "white", strokeWidth: "1", strokeLinecap: "round" }), jsx("path", { d: "M14 7c0-1.5 1-2.5 2-2.5s2 1 2 2.5", stroke: "white", strokeWidth: "1", fill: "none" })] })),
|
|
121
122
|
},
|
|
122
123
|
});
|
|
@@ -134,7 +135,7 @@ const NtdAssistiveTech = /* @__PURE__ */ createIcon({
|
|
|
134
135
|
paths: {
|
|
135
136
|
solid: ({ primaryColor }) => (jsxs(Fragment, { children: [jsx("circle", { cx: "12", cy: "12", r: "10", fill: primaryColor }), jsx("path", { d: "M12 6v2M12 16v2M6 12h2M16 12h2", stroke: "white", strokeWidth: "2", strokeLinecap: "round" }), jsx("circle", { cx: "12", cy: "12", r: "3", fill: "white" })] })),
|
|
136
137
|
outline: ({ primaryColor, strokeWidth }) => (jsxs(Fragment, { children: [jsx("circle", { cx: "12", cy: "12", r: "10", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsx("path", { d: "M12 6v2M12 16v2M6 12h2M16 12h2", stroke: primaryColor, strokeWidth: strokeWidth, strokeLinecap: "round" }), jsx("circle", { cx: "12", cy: "12", r: "3", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" })] })),
|
|
137
|
-
duotone: ({ primaryColor, secondaryColor, secondaryOpacity, strokeWidth }) => (jsxs(Fragment, { children: [jsx("circle", { cx: "12", cy: "12", r: "10", fill: secondaryColor, opacity: secondaryOpacity }), jsx("circle", { cx: "12", cy: "12", r: "10", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsx("path", { d: "M12 6v2M12 16v2M6 12h2M16 12h2", stroke: primaryColor, strokeWidth: strokeWidth, strokeLinecap: "round" }), jsx("circle", { cx: "12", cy: "12", r: "3", fill: primaryColor })] })),
|
|
138
|
+
duotone: swapDuotone(({ primaryColor, secondaryColor, secondaryOpacity, strokeWidth }) => (jsxs(Fragment, { children: [jsx("circle", { cx: "12", cy: "12", r: "10", fill: secondaryColor, opacity: secondaryOpacity }), jsx("circle", { cx: "12", cy: "12", r: "10", stroke: primaryColor, strokeWidth: strokeWidth, fill: "none" }), jsx("path", { d: "M12 6v2M12 16v2M6 12h2M16 12h2", stroke: primaryColor, strokeWidth: strokeWidth, strokeLinecap: "round" }), jsx("circle", { cx: "12", cy: "12", r: "3", fill: primaryColor })] }))),
|
|
138
139
|
vivid: ({ primaryColor, secondaryColor: _secondaryColor }) => (jsxs(Fragment, { children: [jsx("circle", { cx: "12", cy: "12", r: "10", fill: primaryColor }), jsx("circle", { cx: "12", cy: "12", r: "10", fill: "white", opacity: "0.08" }), jsx("circle", { cx: "12", cy: "12", r: "3", fill: "white" }), jsx("path", { d: "M12 6v2M12 16v2M6 12h2M16 12h2", stroke: "white", strokeWidth: "1", strokeLinecap: "round" })] })),
|
|
139
140
|
},
|
|
140
141
|
});
|