panelui-native 0.80.0 → 0.82.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.
Files changed (92) hide show
  1. package/lib/module/components/bottom-sheet/index.js +90 -17
  2. package/lib/module/components/bottom-sheet/index.js.map +1 -1
  3. package/lib/module/components/button/index.js +13 -0
  4. package/lib/module/components/button/index.js.map +1 -1
  5. package/lib/module/components/button-group/index.js +3 -0
  6. package/lib/module/components/button-group/index.js.map +1 -1
  7. package/lib/module/components/image-generation/dot-field.js +210 -0
  8. package/lib/module/components/image-generation/dot-field.js.map +1 -0
  9. package/lib/module/components/image-generation/index.js +417 -0
  10. package/lib/module/components/image-generation/index.js.map +1 -0
  11. package/lib/module/components/kpi/index.js +2 -4
  12. package/lib/module/components/kpi/index.js.map +1 -1
  13. package/lib/module/components/menu/index.js +8 -16
  14. package/lib/module/components/menu/index.js.map +1 -1
  15. package/lib/module/components/panelside/index.js +340 -33
  16. package/lib/module/components/panelside/index.js.map +1 -1
  17. package/lib/module/components/planner/index.js +446 -32
  18. package/lib/module/components/planner/index.js.map +1 -1
  19. package/lib/module/components/planner/planner-entries.js +36 -0
  20. package/lib/module/components/planner/planner-entries.js.map +1 -1
  21. package/lib/module/components/planner/planner-grid-navigation.js +34 -2
  22. package/lib/module/components/planner/planner-grid-navigation.js.map +1 -1
  23. package/lib/module/components/planner/planner-weeks.js +95 -0
  24. package/lib/module/components/planner/planner-weeks.js.map +1 -0
  25. package/lib/module/components/select/index.js +127 -23
  26. package/lib/module/components/select/index.js.map +1 -1
  27. package/lib/module/components/slide-button/index.js +610 -0
  28. package/lib/module/components/slide-button/index.js.map +1 -0
  29. package/lib/module/components/slide-button/slide-button-track.js +98 -0
  30. package/lib/module/components/slide-button/slide-button-track.js.map +1 -0
  31. package/lib/module/icons/index.js +553 -1934
  32. package/lib/module/icons/index.js.map +1 -1
  33. package/lib/module/index.js +3 -1
  34. package/lib/module/index.js.map +1 -1
  35. package/lib/module/primitives/portal.js +15 -1
  36. package/lib/module/primitives/portal.js.map +1 -1
  37. package/lib/module/utils/date.js +10 -3
  38. package/lib/module/utils/date.js.map +1 -1
  39. package/lib/typescript/src/components/bottom-sheet/index.d.ts.map +1 -1
  40. package/lib/typescript/src/components/button/index.d.ts +12 -0
  41. package/lib/typescript/src/components/button/index.d.ts.map +1 -1
  42. package/lib/typescript/src/components/button-group/index.d.ts +9 -0
  43. package/lib/typescript/src/components/button-group/index.d.ts.map +1 -1
  44. package/lib/typescript/src/components/image-generation/dot-field.d.ts +61 -0
  45. package/lib/typescript/src/components/image-generation/dot-field.d.ts.map +1 -0
  46. package/lib/typescript/src/components/image-generation/index.d.ts +126 -0
  47. package/lib/typescript/src/components/image-generation/index.d.ts.map +1 -0
  48. package/lib/typescript/src/components/kpi/index.d.ts.map +1 -1
  49. package/lib/typescript/src/components/menu/index.d.ts.map +1 -1
  50. package/lib/typescript/src/components/panelside/index.d.ts +194 -10
  51. package/lib/typescript/src/components/panelside/index.d.ts.map +1 -1
  52. package/lib/typescript/src/components/planner/index.d.ts +65 -4
  53. package/lib/typescript/src/components/planner/index.d.ts.map +1 -1
  54. package/lib/typescript/src/components/planner/planner-entries.d.ts +18 -0
  55. package/lib/typescript/src/components/planner/planner-entries.d.ts.map +1 -1
  56. package/lib/typescript/src/components/planner/planner-grid-navigation.d.ts +7 -1
  57. package/lib/typescript/src/components/planner/planner-grid-navigation.d.ts.map +1 -1
  58. package/lib/typescript/src/components/planner/planner-weeks.d.ts +50 -0
  59. package/lib/typescript/src/components/planner/planner-weeks.d.ts.map +1 -0
  60. package/lib/typescript/src/components/select/index.d.ts +75 -2
  61. package/lib/typescript/src/components/select/index.d.ts.map +1 -1
  62. package/lib/typescript/src/components/slide-button/index.d.ts +317 -0
  63. package/lib/typescript/src/components/slide-button/index.d.ts.map +1 -0
  64. package/lib/typescript/src/components/slide-button/slide-button-track.d.ts +70 -0
  65. package/lib/typescript/src/components/slide-button/slide-button-track.d.ts.map +1 -0
  66. package/lib/typescript/src/icons/index.d.ts +136 -189
  67. package/lib/typescript/src/icons/index.d.ts.map +1 -1
  68. package/lib/typescript/src/index.d.ts +5 -3
  69. package/lib/typescript/src/index.d.ts.map +1 -1
  70. package/lib/typescript/src/primitives/portal.d.ts.map +1 -1
  71. package/lib/typescript/src/utils/date.d.ts +1 -1
  72. package/lib/typescript/src/utils/date.d.ts.map +1 -1
  73. package/package.json +3 -2
  74. package/src/components/bottom-sheet/index.tsx +97 -17
  75. package/src/components/button/index.tsx +10 -2
  76. package/src/components/button-group/index.tsx +1 -0
  77. package/src/components/image-generation/dot-field.ts +226 -0
  78. package/src/components/image-generation/index.tsx +488 -0
  79. package/src/components/kpi/index.tsx +2 -4
  80. package/src/components/menu/index.tsx +10 -15
  81. package/src/components/panelside/index.tsx +498 -33
  82. package/src/components/planner/index.tsx +516 -38
  83. package/src/components/planner/planner-entries.ts +33 -0
  84. package/src/components/planner/planner-grid-navigation.ts +37 -2
  85. package/src/components/planner/planner-weeks.ts +90 -0
  86. package/src/components/select/index.tsx +158 -31
  87. package/src/components/slide-button/index.tsx +681 -0
  88. package/src/components/slide-button/slide-button-track.ts +100 -0
  89. package/src/icons/index.tsx +338 -1327
  90. package/src/index.ts +30 -0
  91. package/src/primitives/portal.tsx +15 -1
  92. package/src/utils/date.ts +13 -3
@@ -1,34 +1,139 @@
1
1
  /**
2
2
  * Icon set.
3
3
  *
4
- * Two families live here:
5
- * - Stroked 24×24 icons on Lucide geometry, for chrome such as chevrons and
6
- * the close button.
7
- * - Filled 16×16 status icons for Alert and Toast indicators, which read
8
- * better small than a stroked equivalent would.
4
+ * Every glyph is a 24×24 stroked drawing, sized and coloured by the caller.
5
+ * They exist so the library can draw its own chrome — chevrons, a close
6
+ * button, a check inside a checkbox — without every consumer having to choose
7
+ * an icon package before a Select will render.
9
8
  *
10
- * Every icon resolves its colour in the same order: an explicit `color` prop,
11
- * then the colour inherited from an enclosing `IconColorProvider`, then its
12
- * own fallback. Coloured surfaces such as Button provide the foreground that
13
- * reads against them, so icons follow the theme without callers hardcoding a
14
- * hex — which breaks the moment the theme inverts.
9
+ * ## How a colour is resolved
15
10
  *
16
- * Brand marks (Google, Facebook, Apple) are the exception: they carry their
17
- * own colours and ignore the context.
11
+ * In one order, always: an explicit `color` prop, then the colour inherited
12
+ * from an enclosing `IconColorProvider`, then the icon's own fallback.
13
+ * Coloured surfaces such as Button provide the foreground that reads against
14
+ * them, so an icon dropped into one follows the theme without the caller
15
+ * hardcoding a hex — which is what breaks the moment the theme inverts.
16
+ *
17
+ * ## Weight
18
+ *
19
+ * `strokeWidth` defaults to 2 rather than to the drawing's own 1.5. The set is
20
+ * drawn at 24 and used at 14–20, and a hairline that reads correctly at full
21
+ * size thins to nothing at two thirds of it. A few glyphs carry their own
22
+ * weight because they sit beside something they have to match: the check and
23
+ * the bar inside a checkbox, the grip on a drag handle.
24
+ *
25
+ * ## Mirroring
18
26
  *
19
27
  * A glyph whose *meaning* is a horizontal direction mirrors in a right-to-left
20
- * subtree — the chevrons, the outward arrow, the send plane. Everything else
21
- * is drawn once and left alone, including the vertical arrows, since the
22
- * vertical axis does not mirror, and including asymmetric glyphs that are not
23
- * directions (a magnifier, a pencil, a play triangle).
28
+ * subtree — the two side chevrons, the outward arrow, the send plane. Yoga
29
+ * moves a chevron to the other end of its row but cannot turn the glyph
30
+ * around, so without this an RTL list row ends up with a right-pointing
31
+ * chevron on its left edge, pointing back at the text.
32
+ *
33
+ * Everything else is drawn once and left alone. The vertical axis does not
34
+ * mirror, and an icon that is merely asymmetric — a magnifier, a pencil, a
35
+ * play triangle — means the same thing either way round; flipping it would
36
+ * only be a wrong drawing.
37
+ *
38
+ * A mirroring icon always carries a transform, identity included. Dropping the
39
+ * prop leaves the last matrix the view was given in place, so a glyph mirrored
40
+ * once stays mirrored when the direction flips back — the arrows in an app
41
+ * that can switch direction at runtime end up pointing at the text one toggle
42
+ * in, and never recover.
43
+ *
44
+ * ## The four drawn by hand
45
+ *
46
+ * Google, Facebook and Apple carry their own palettes, and a brand mark
47
+ * repainted to match a surface is no longer the mark. `BadgeCheckIcon` is
48
+ * two-tone by design — a solid badge with a check punched through it in a
49
+ * second colour — and `checkColor` is a public prop that a single-colour
50
+ * outline could only ignore. All four are drawn here rather than mapped.
24
51
  */
25
52
  import { createContext, useContext, type ReactNode } from 'react';
26
- import Svg, { Circle, G, Path, type SvgProps } from 'react-native-svg';
53
+ import { HugeiconsIcon, type IconSvgElement } from '@hugeicons/react-native';
54
+ import Svg, { G, Path, type SvgProps } from 'react-native-svg';
27
55
  import { useDirection } from '../hooks/use-direction';
56
+ import HgAlert02Icon from '@hugeicons/core-free-icons/Alert02Icon';
57
+ import HgArrowDown01Icon from '@hugeicons/core-free-icons/ArrowDown01Icon';
58
+ import HgArrowDown02Icon from '@hugeicons/core-free-icons/ArrowDown02Icon';
59
+ import HgArrowLeft01Icon from '@hugeicons/core-free-icons/ArrowLeft01Icon';
60
+ import HgArrowRight01Icon from '@hugeicons/core-free-icons/ArrowRight01Icon';
61
+ import HgArrowUp01Icon from '@hugeicons/core-free-icons/ArrowUp01Icon';
62
+ import HgArrowUp02Icon from '@hugeicons/core-free-icons/ArrowUp02Icon';
63
+ import HgArrowUpRight01Icon from '@hugeicons/core-free-icons/ArrowUpRight01Icon';
64
+ import HgAttachment01Icon from '@hugeicons/core-free-icons/Attachment01Icon';
65
+ import HgAudioWave01Icon from '@hugeicons/core-free-icons/AudioWave01Icon';
66
+ import HgBookmark01Icon from '@hugeicons/core-free-icons/Bookmark01Icon';
67
+ import HgBubbleChatIcon from '@hugeicons/core-free-icons/BubbleChatIcon';
68
+ import HgCalendar03Icon from '@hugeicons/core-free-icons/Calendar03Icon';
69
+ import HgCamera01Icon from '@hugeicons/core-free-icons/Camera01Icon';
70
+ import HgCancel01Icon from '@hugeicons/core-free-icons/Cancel01Icon';
71
+ import HgCheckListIcon from '@hugeicons/core-free-icons/CheckListIcon';
72
+ import HgCheckmarkCircle01Icon from '@hugeicons/core-free-icons/CheckmarkCircle01Icon';
73
+ import HgCircleIcon from '@hugeicons/core-free-icons/CircleIcon';
74
+ import HgClock01Icon from '@hugeicons/core-free-icons/Clock01Icon';
75
+ import HgCodeIcon from '@hugeicons/core-free-icons/CodeIcon';
76
+ import HgCompassIcon from '@hugeicons/core-free-icons/CompassIcon';
77
+ import HgCopy01Icon from '@hugeicons/core-free-icons/Copy01Icon';
78
+ import HgCreditCardIcon from '@hugeicons/core-free-icons/CreditCardIcon';
79
+ import HgCrosshairIcon from '@hugeicons/core-free-icons/CrosshairIcon';
80
+ import HgDelete02Icon from '@hugeicons/core-free-icons/Delete02Icon';
81
+ import HgDownload01Icon from '@hugeicons/core-free-icons/Download01Icon';
82
+ import HgDragDropVerticalIcon from '@hugeicons/core-free-icons/DragDropVerticalIcon';
83
+ import HgEyeIcon from '@hugeicons/core-free-icons/EyeIcon';
84
+ import HgFavouriteIcon from '@hugeicons/core-free-icons/FavouriteIcon';
85
+ import HgFile01Icon from '@hugeicons/core-free-icons/File01Icon';
86
+ import HgFolder01Icon from '@hugeicons/core-free-icons/Folder01Icon';
87
+ import HgFolderOpenIcon from '@hugeicons/core-free-icons/FolderOpenIcon';
88
+ import HgFullScreenIcon from '@hugeicons/core-free-icons/FullScreenIcon';
89
+ import HgGlobeIcon from '@hugeicons/core-free-icons/GlobeIcon';
90
+ import HgHeading01Icon from '@hugeicons/core-free-icons/Heading01Icon';
91
+ import HgImage01Icon from '@hugeicons/core-free-icons/Image01Icon';
92
+ import HgInformationCircleIcon from '@hugeicons/core-free-icons/InformationCircleIcon';
93
+ import HgKeyboardIcon from '@hugeicons/core-free-icons/KeyboardIcon';
94
+ import HgLeftToRightListBulletIcon from '@hugeicons/core-free-icons/LeftToRightListBulletIcon';
95
+ import HgLeftToRightListNumberIcon from '@hugeicons/core-free-icons/LeftToRightListNumberIcon';
96
+ import HgLink01Icon from '@hugeicons/core-free-icons/Link01Icon';
97
+ import HgLockIcon from '@hugeicons/core-free-icons/LockIcon';
98
+ import HgLockOpenIcon from '@hugeicons/core-free-icons/LockOpenIcon';
99
+ import HgMenu01Icon from '@hugeicons/core-free-icons/Menu01Icon';
100
+ import HgMic01Icon from '@hugeicons/core-free-icons/Mic01Icon';
101
+ import HgMinusSignIcon from '@hugeicons/core-free-icons/MinusSignIcon';
102
+ import HgMoonIcon from '@hugeicons/core-free-icons/MoonIcon';
103
+ import HgMoreHorizontalIcon from '@hugeicons/core-free-icons/MoreHorizontalIcon';
104
+ import HgNotification03Icon from '@hugeicons/core-free-icons/Notification03Icon';
105
+ import HgPackageIcon from '@hugeicons/core-free-icons/PackageIcon';
106
+ import HgPauseIcon from '@hugeicons/core-free-icons/PauseIcon';
107
+ import HgPencilEdit01Icon from '@hugeicons/core-free-icons/PencilEdit01Icon';
108
+ import HgPlayIcon from '@hugeicons/core-free-icons/PlayIcon';
109
+ import HgPlusSignIcon from '@hugeicons/core-free-icons/PlusSignIcon';
110
+ import HgPlusSignSquareIcon from '@hugeicons/core-free-icons/PlusSignSquareIcon';
111
+ import HgQuoteDownIcon from '@hugeicons/core-free-icons/QuoteDownIcon';
112
+ import HgReceiptIcon from '@hugeicons/core-free-icons/ReceiptIcon';
113
+ import HgRefreshCcwIcon from '@hugeicons/core-free-icons/RefreshCcwIcon';
114
+ import HgRefreshCwIcon from '@hugeicons/core-free-icons/RefreshCwIcon';
115
+ import HgRepeatIcon from '@hugeicons/core-free-icons/RepeatIcon';
116
+ import HgSearch01Icon from '@hugeicons/core-free-icons/Search01Icon';
117
+ import HgSent02Icon from '@hugeicons/core-free-icons/Sent02Icon';
118
+ import HgSentIcon from '@hugeicons/core-free-icons/SentIcon';
119
+ import HgShare08Icon from '@hugeicons/core-free-icons/Share08Icon';
120
+ import HgShieldAlertIcon from '@hugeicons/core-free-icons/ShieldAlertIcon';
121
+ import HgShieldCheckIcon from '@hugeicons/core-free-icons/ShieldCheckIcon';
122
+ import HgSparklesIcon from '@hugeicons/core-free-icons/SparklesIcon';
123
+ import HgStarIcon from '@hugeicons/core-free-icons/StarIcon';
124
+ import HgSun03Icon from '@hugeicons/core-free-icons/Sun03Icon';
125
+ import HgTextBoldIcon from '@hugeicons/core-free-icons/TextBoldIcon';
126
+ import HgTextItalicIcon from '@hugeicons/core-free-icons/TextItalicIcon';
127
+ import HgTick02Icon from '@hugeicons/core-free-icons/Tick02Icon';
128
+ import HgUnfoldMoreIcon from '@hugeicons/core-free-icons/UnfoldMoreIcon';
28
129
 
29
130
  export interface IconProps extends SvgProps {
131
+ /** Both dimensions — icons are always square. */
30
132
  size?: number;
133
+ /** Overrides the inherited colour and the icon's own fallback. */
31
134
  color?: string;
135
+ /** Line weight. Defaults to 2, or to the glyph's own where it has one. */
136
+ strokeWidth?: number;
32
137
  }
33
138
 
34
139
  /**
@@ -68,378 +173,243 @@ const decorative = {
68
173
  importantForAccessibility: 'no-hide-descendants',
69
174
  } as const;
70
175
 
71
- /* -------------------------------------------------------------------------- */
72
- /* Stroked chrome icons */
73
- /* -------------------------------------------------------------------------- */
176
+ /** The default line weight. See the note on weight above. */
177
+ const STROKE = 2;
74
178
 
75
- export function CheckIcon({ size = 14, color, ...props }: IconProps) {
76
- const resolved = useResolvedColor(color, '#fff');
77
- return (
78
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
79
- <Path
80
- d="M20 6 9 17l-5-5"
81
- stroke={resolved}
82
- strokeWidth={3}
83
- strokeLinecap="round"
84
- strokeLinejoin="round"
85
- />
86
- </Svg>
87
- );
179
+ interface IconDefaults {
180
+ /** Both dimensions at the size this glyph is normally drawn. */
181
+ size: number;
182
+ /** The colour used when neither a prop nor a provider supplies one. */
183
+ color: string;
184
+ /** Overrides `STROKE` for a glyph that has to match something beside it. */
185
+ strokeWidth?: number;
186
+ /** Whether the glyph's meaning is a horizontal direction. */
187
+ flip?: boolean;
188
+ /** Whether the glyph is a toggle that can be solid. See `ToggleIconProps`. */
189
+ fillable?: boolean;
88
190
  }
89
191
 
90
192
  /**
91
- * A single bar. Its weight is a prop because it has two jobs: it is the
92
- * indeterminate mark inside a checkbox, where it has to carry the same weight
93
- * as the check it stands in for, and it is the decrement half of a stepper,
94
- * where it has to match the plus beside it. Those are different weights, and a
95
- * bar that is heavier than the + it pairs with reads as a different glyph.
193
+ * Builds one icon from a glyph and the defaults it is normally drawn with.
194
+ *
195
+ * A factory rather than seventy near-identical components: what varies between
196
+ * them is data, and what does not — the colour order, the weight default, the
197
+ * mirror, the fill toggle, the prop passthrough — is worth having in exactly
198
+ * one place, where a fix reaches the whole set at once.
96
199
  */
97
- export function MinusIcon({ size = 14, color, strokeWidth = 3, ...props }: IconProps) {
98
- const resolved = useResolvedColor(color, '#fff');
99
- return (
100
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
101
- <Path
102
- d="M5 12h14"
103
- stroke={resolved}
104
- strokeWidth={strokeWidth}
105
- strokeLinecap="round"
106
- strokeLinejoin="round"
107
- />
108
- </Svg>
109
- );
110
- }
111
-
112
- export function ChevronUpIcon({ size = 16, color, ...props }: IconProps) {
113
- const resolved = useResolvedColor(color, '#737373');
114
- return (
115
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
116
- <Path
117
- d="m18 15-6-6-6 6"
118
- stroke={resolved}
119
- strokeWidth={2}
120
- strokeLinecap="round"
121
- strokeLinejoin="round"
122
- />
123
- </Svg>
124
- );
125
- }
126
-
127
- export function CalendarIcon({ size = 16, color, ...props }: IconProps) {
128
- const resolved = useResolvedColor(color, '#737373');
129
- return (
130
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
131
- <Path
132
- d="M8 2v4M16 2v4M3 10h18M5 4h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2Z"
133
- stroke={resolved}
134
- strokeWidth={2}
135
- strokeLinecap="round"
136
- strokeLinejoin="round"
137
- />
138
- </Svg>
139
- );
140
- }
141
-
142
- /** A clock face reading ten past ten — the hour, a time field, a schedule. */
143
- export function ClockIcon({ size = 16, color, ...props }: IconProps) {
144
- const resolved = useResolvedColor(color, '#737373');
145
- return (
146
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
147
- <Circle
148
- cx={12}
149
- cy={12}
150
- r={9}
151
- stroke={resolved}
152
- strokeWidth={2}
153
- strokeLinecap="round"
154
- strokeLinejoin="round"
155
- />
156
- <Path
157
- d="M12 7v5l3.5 2"
158
- stroke={resolved}
159
- strokeWidth={2}
160
- strokeLinecap="round"
161
- strokeLinejoin="round"
162
- />
163
- </Svg>
164
- );
165
- }
166
-
167
- /** A keyboard — swapping a gesture-driven control for typed entry. */
168
- export function KeyboardIcon({ size = 16, color, ...props }: IconProps) {
169
- const resolved = useResolvedColor(color, '#737373');
170
- return (
171
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
172
- <Path
173
- d="M4 5h16a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1Z"
174
- stroke={resolved}
175
- strokeWidth={2}
176
- strokeLinejoin="round"
177
- />
178
- <Path
179
- d="M7 9h.01M11 9h.01M15 9h.01M7 12h.01M11 12h.01M15 12h.01M8 15h8"
180
- stroke={resolved}
181
- strokeWidth={2}
182
- strokeLinecap="round"
183
- strokeLinejoin="round"
184
- />
185
- </Svg>
186
- );
187
- }
188
-
189
- export function BookmarkIcon({
190
- size = 16,
191
- color,
192
- filled,
193
- ...props
194
- }: IconProps & { filled?: boolean }) {
195
- const resolved = useResolvedColor(color, '#737373');
196
- return (
197
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
198
- <Path
199
- d="m19 21-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2Z"
200
- fill={filled ? resolved : 'none'}
201
- stroke={resolved}
202
- strokeWidth={2}
203
- strokeLinecap="round"
204
- strokeLinejoin="round"
205
- />
206
- </Svg>
207
- );
200
+ function icon(glyph: IconSvgElement, defaults: IconDefaults) {
201
+ function Icon({
202
+ size = defaults.size,
203
+ color,
204
+ strokeWidth,
205
+ filled,
206
+ style,
207
+ ...props
208
+ }: ToggleIconProps) {
209
+ const resolved = useResolvedColor(color, defaults.color);
210
+ const rtl = useDirection() === 'rtl';
211
+ return (
212
+ <HugeiconsIcon
213
+ icon={glyph}
214
+ size={size}
215
+ color={resolved}
216
+ strokeWidth={strokeWidth ?? defaults.strokeWidth ?? STROKE}
217
+ fill={defaults.fillable && filled ? resolved : 'none'}
218
+ style={defaults.flip ? [{ transform: [{ scaleX: rtl ? -1 : 1 }] }, style] : style}
219
+ {...props}
220
+ />
221
+ );
222
+ }
223
+
224
+ return Icon;
208
225
  }
209
226
 
210
- export function ChevronDownIcon({ size = 16, color, ...props }: IconProps) {
211
- const resolved = useResolvedColor(color, '#737373');
212
- return (
213
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
214
- <Path
215
- d="m6 9 6 6 6-6"
216
- stroke={resolved}
217
- strokeWidth={2}
218
- strokeLinecap="round"
219
- strokeLinejoin="round"
220
- />
221
- </Svg>
222
- );
223
- }
227
+ /* -------------------------------------------------------------------------- */
228
+ /* Chrome */
229
+ /* -------------------------------------------------------------------------- */
224
230
 
225
- /**
226
- * Mirrors a directional glyph in a right-to-left subtree.
227
- *
228
- * Yoga moves a chevron to the other end of its row, but it cannot turn the
229
- * glyph around — so an RTL list row ends up with a right-pointing chevron on
230
- * its left edge, pointing back at the text. These arrows mean "onward" and
231
- * "back", and which way that is depends on which way you read.
232
- *
233
- * Only for glyphs whose meaning *is* a direction. An icon that happens to be
234
- * asymmetric — a pencil, a magnifier — means the same thing either way round,
235
- * and flipping it is just a wrong drawing. The vertical axis never mirrors, so
236
- * the up and down glyphs stay as they are drawn.
237
- *
238
- * Left-to-right gets an identity transform rather than no transform at all.
239
- * Dropping the prop leaves the last matrix the view was given in place, so a
240
- * glyph mirrored once stays mirrored when the direction flips back — the
241
- * arrows in an app that can switch direction at runtime end up pointing at the
242
- * text one toggle in, and never recover.
243
- */
244
- const IDENTITY = 'translate(0 0)';
245
- const MIRROR = 'scale(-1 1) translate(-24 0)';
231
+ export const ChevronUpIcon = icon(HgArrowUp01Icon, { size: 16, color: '#737373' });
232
+ export const ChevronDownIcon = icon(HgArrowDown01Icon, { size: 16, color: '#737373' });
233
+ export const ChevronLeftIcon = icon(HgArrowLeft01Icon, {
234
+ size: 16,
235
+ color: '#737373',
236
+ flip: true,
237
+ });
238
+ export const ChevronRightIcon = icon(HgArrowRight01Icon, {
239
+ size: 16,
240
+ color: '#737373',
241
+ flip: true,
242
+ });
243
+ export const ChevronsUpDownIcon = icon(HgUnfoldMoreIcon, { size: 16, color: '#737373' });
244
+ export const EllipsisIcon = icon(HgMoreHorizontalIcon, { size: 16, color: '#737373' });
245
+ export const MenuIcon = icon(HgMenu01Icon, { size: 20, color: '#737373' });
246
+ export const XIcon = icon(HgCancel01Icon, { size: 16, color: '#737373' });
247
+ export const SearchIcon = icon(HgSearch01Icon, { size: 16, color: '#737373' });
248
+ export const ArrowUpRightIcon = icon(HgArrowUpRight01Icon, {
249
+ size: 20,
250
+ color: '#fff',
251
+ flip: true,
252
+ });
253
+ export const PlusIcon = icon(HgPlusSignIcon, { size: 16, color: '#737373' });
254
+ export const MinusIcon = icon(HgMinusSignIcon, { size: 14, color: '#fff', strokeWidth: 3 });
255
+ export const CheckIcon = icon(HgTick02Icon, { size: 14, color: '#fff', strokeWidth: 3 });
256
+ export const CircleIcon = icon(HgCircleIcon, { size: 16, color: '#737373', fillable: true });
257
+ export const GripVerticalIcon = icon(HgDragDropVerticalIcon, {
258
+ size: 16,
259
+ color: '#737373',
260
+ strokeWidth: 2.5,
261
+ });
262
+ export const MaximizeIcon = icon(HgFullScreenIcon, { size: 16, color: '#737373' });
246
263
 
247
- function useFlip(): { transform: string } {
248
- return { transform: useDirection() === 'rtl' ? MIRROR : IDENTITY };
249
- }
264
+ /* -------------------------------------------------------------------------- */
265
+ /* Status */
266
+ /* -------------------------------------------------------------------------- */
250
267
 
251
- export function ChevronLeftIcon({ size = 16, color, ...props }: IconProps) {
252
- const resolved = useResolvedColor(color, '#737373');
253
- const flip = useFlip();
254
- return (
255
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
256
- <Path
257
- d="m15 18-6-6 6-6"
258
- stroke={resolved}
259
- strokeWidth={2}
260
- strokeLinecap="round"
261
- strokeLinejoin="round"
262
- {...flip}
263
- />
264
- </Svg>
265
- );
266
- }
268
+ export const InfoIcon = icon(HgInformationCircleIcon, { size: 20, color: 'currentColor' });
269
+ export const CheckCircleIcon = icon(HgCheckmarkCircle01Icon, {
270
+ size: 20,
271
+ color: 'currentColor',
272
+ });
273
+ export const AlertTriangleIcon = icon(HgAlert02Icon, { size: 20, color: 'currentColor' });
274
+ export const ShieldAlertIcon = icon(HgShieldAlertIcon, { size: 16, color: '#737373' });
275
+ export const ShieldCheckIcon = icon(HgShieldCheckIcon, { size: 16, color: '#737373' });
276
+ export const BellIcon = icon(HgNotification03Icon, { size: 16, color: '#737373' });
267
277
 
268
- export function ChevronRightIcon({ size = 16, color, ...props }: IconProps) {
269
- const resolved = useResolvedColor(color, '#737373');
270
- const flip = useFlip();
271
- return (
272
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
273
- <Path
274
- d="m9 18 6-6-6-6"
275
- stroke={resolved}
276
- strokeWidth={2}
277
- strokeLinecap="round"
278
- strokeLinejoin="round"
279
- {...flip}
280
- />
281
- </Svg>
282
- );
283
- }
278
+ /* -------------------------------------------------------------------------- */
279
+ /* Time and place */
280
+ /* -------------------------------------------------------------------------- */
284
281
 
285
- export function EllipsisIcon({ size = 16, color, ...props }: IconProps) {
286
- const resolved = useResolvedColor(color, '#737373');
287
- return (
288
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
289
- <Circle cx={5} cy={12} r={1.6} fill={resolved} />
290
- <Circle cx={12} cy={12} r={1.6} fill={resolved} />
291
- <Circle cx={19} cy={12} r={1.6} fill={resolved} />
292
- </Svg>
293
- );
294
- }
282
+ export const CalendarIcon = icon(HgCalendar03Icon, { size: 16, color: '#737373' });
283
+ export const ClockIcon = icon(HgClock01Icon, { size: 16, color: '#737373' });
284
+ export const GlobeIcon = icon(HgGlobeIcon, { size: 16, color: '#737373' });
285
+ export const CompassIcon = icon(HgCompassIcon, { size: 16, color: '#737373' });
286
+ export const CrosshairIcon = icon(HgCrosshairIcon, { size: 16, color: '#737373' });
295
287
 
296
- export function MenuIcon({ size = 20, color, ...props }: IconProps) {
297
- const resolved = useResolvedColor(color, '#737373');
298
- return (
299
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
300
- <Path
301
- d="M4 6h16M4 12h16M4 18h16"
302
- stroke={resolved}
303
- strokeWidth={2}
304
- strokeLinecap="round"
305
- />
306
- </Svg>
307
- );
308
- }
288
+ /* -------------------------------------------------------------------------- */
289
+ /* Text and editing */
290
+ /* -------------------------------------------------------------------------- */
309
291
 
310
- export function XIcon({ size = 16, color, ...props }: IconProps) {
311
- const resolved = useResolvedColor(color, '#737373');
312
- return (
313
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
314
- <Path
315
- d="M18 6 6 18M6 6l12 12"
316
- stroke={resolved}
317
- strokeWidth={2}
318
- strokeLinecap="round"
319
- strokeLinejoin="round"
320
- />
321
- </Svg>
322
- );
323
- }
292
+ export const BoldIcon = icon(HgTextBoldIcon, { size: 16, color: '#737373' });
293
+ export const ItalicIcon = icon(HgTextItalicIcon, { size: 16, color: '#737373' });
294
+ export const HeadingIcon = icon(HgHeading01Icon, { size: 16, color: '#737373' });
295
+ export const ListIcon = icon(HgLeftToRightListBulletIcon, { size: 16, color: '#737373' });
296
+ export const ListOrderedIcon = icon(HgLeftToRightListNumberIcon, {
297
+ size: 16,
298
+ color: '#737373',
299
+ });
300
+ export const ListChecksIcon = icon(HgCheckListIcon, { size: 16, color: '#737373' });
301
+ export const QuoteIcon = icon(HgQuoteDownIcon, { size: 16, color: '#737373' });
302
+ export const CodeIcon = icon(HgCodeIcon, { size: 16, color: '#737373' });
303
+ export const PencilIcon = icon(HgPencilEdit01Icon, { size: 16, color: '#737373' });
304
+ export const KeyboardIcon = icon(HgKeyboardIcon, { size: 16, color: '#737373' });
324
305
 
325
- export function SearchIcon({ size = 16, color, ...props }: IconProps) {
326
- const resolved = useResolvedColor(color, '#737373');
327
- return (
328
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
329
- <Circle cx={11} cy={11} r={8} stroke={resolved} strokeWidth={2} />
330
- <Path
331
- d="m21 21-4.3-4.3"
332
- stroke={resolved}
333
- strokeWidth={2}
334
- strokeLinecap="round"
335
- strokeLinejoin="round"
336
- />
337
- </Svg>
338
- );
339
- }
306
+ /* -------------------------------------------------------------------------- */
307
+ /* Files and media */
308
+ /* -------------------------------------------------------------------------- */
340
309
 
341
- export function ArrowUpRightIcon({ size = 20, color, ...props }: IconProps) {
342
- const resolved = useResolvedColor(color, '#fff');
343
- const flip = useFlip();
344
- return (
345
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
346
- <Path
347
- d="M7 17 17 7M8 7h9v9"
348
- stroke={resolved}
349
- strokeWidth={2}
350
- strokeLinecap="round"
351
- strokeLinejoin="round"
352
- {...flip}
353
- />
354
- </Svg>
355
- );
356
- }
310
+ export const FileIcon = icon(HgFile01Icon, { size: 16, color: '#737373' });
311
+ export const FolderIcon = icon(HgFolder01Icon, { size: 16, color: '#737373' });
312
+ export const FolderOpenIcon = icon(HgFolderOpenIcon, { size: 16, color: '#737373' });
313
+ export const ImageIcon = icon(HgImage01Icon, { size: 16, color: '#737373' });
314
+ export const PaperclipIcon = icon(HgAttachment01Icon, { size: 16, color: '#737373' });
315
+ export const CameraIcon = icon(HgCamera01Icon, { size: 16, color: '#737373' });
316
+ export const MicIcon = icon(HgMic01Icon, { size: 16, color: '#737373' });
317
+ export const AudioLinesIcon = icon(HgAudioWave01Icon, { size: 16, color: '#737373' });
318
+ export const PlayIcon = icon(HgPlayIcon, { size: 16, color: '#737373' });
319
+ export const PauseIcon = icon(HgPauseIcon, { size: 16, color: '#737373', strokeWidth: 1.5 });
320
+ export const DownloadIcon = icon(HgDownload01Icon, { size: 16, color: '#737373' });
321
+ export const PackageIcon = icon(HgPackageIcon, { size: 16, color: '#737373' });
357
322
 
358
- export function SunIcon({ size = 18, color, ...props }: IconProps) {
359
- const resolved = useResolvedColor(color, '#f5f5f5');
360
- return (
361
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
362
- <Circle cx={12} cy={12} r={4} stroke={resolved} strokeWidth={2} />
363
- <Path
364
- d="M12 2v2m0 16v2M4.93 4.93l1.41 1.41m11.32 11.32 1.41 1.41M2 12h2m16 0h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"
365
- stroke={resolved}
366
- strokeWidth={2}
367
- strokeLinecap="round"
368
- />
369
- </Svg>
370
- );
371
- }
323
+ /* -------------------------------------------------------------------------- */
324
+ /* Actions */
325
+ /* -------------------------------------------------------------------------- */
372
326
 
373
- export function MoonIcon({ size = 18, color, ...props }: IconProps) {
374
- const resolved = useResolvedColor(color, '#262626');
375
- return (
376
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
377
- <Path
378
- d="M21 12.79A9 9 0 1 1 11.21 3a7 7 0 0 0 9.79 9.79"
379
- stroke={resolved}
380
- strokeWidth={2}
381
- strokeLinecap="round"
382
- strokeLinejoin="round"
383
- />
384
- </Svg>
385
- );
386
- }
327
+ export const CopyIcon = icon(HgCopy01Icon, { size: 16, color: '#737373' });
328
+ export const LinkIcon = icon(HgLink01Icon, { size: 16, color: '#737373' });
329
+ export const ShareNodesIcon = icon(HgShare08Icon, { size: 16, color: '#737373' });
330
+ export const SendIcon = icon(HgSentIcon, { size: 16, color: '#737373', flip: true });
331
+ export const SendArrowIcon = icon(HgSent02Icon, {
332
+ size: 16,
333
+ color: '#737373',
334
+ strokeWidth: 2.5,
335
+ });
336
+ export const TrashIcon = icon(HgDelete02Icon, { size: 16, color: '#737373' });
337
+ export const RotateCcwIcon = icon(HgRefreshCcwIcon, { size: 16, color: '#737373' });
338
+ export const RotateCwIcon = icon(HgRefreshCwIcon, { size: 16, color: '#737373' });
339
+ export const RepeatIcon = icon(HgRepeatIcon, { size: 16, color: '#737373' });
340
+ export const PlusSquareIcon = icon(HgPlusSignSquareIcon, { size: 16, color: '#737373' });
341
+ export const EyeIcon = icon(HgEyeIcon, { size: 16, color: '#737373' });
342
+ export const LockIcon = icon(HgLockIcon, { size: 16, color: '#737373' });
343
+ export const UnlockIcon = icon(HgLockOpenIcon, { size: 16, color: '#737373' });
387
344
 
388
345
  /* -------------------------------------------------------------------------- */
389
- /* Filled status icons (Alert / Toast indicators) */
346
+ /* Marks and moods */
390
347
  /* -------------------------------------------------------------------------- */
391
348
 
392
- /** Info circle. Used for `default`, `info` and `destructive` status. */
393
- export function InfoIcon({ size = 20, color, ...props }: IconProps) {
394
- const resolved = useResolvedColor(color, 'currentColor');
395
- return (
396
- <Svg width={size} height={size} viewBox="0 0 16 16" fill={resolved} {...decorative} {...props}>
397
- <Path
398
- d="M8 13.5a5.5 5.5 0 1 0 0-11a5.5 5.5 0 0 0 0 11M8 15A7 7 0 1 0 8 1a7 7 0 0 0 0 14m1-9.5a1 1 0 1 1-2 0a1 1 0 0 1 2 0m-.25 3a.75.75 0 0 0-1.5 0V11a.75.75 0 0 0 1.5 0z"
399
- fillRule="evenodd"
400
- clipRule="evenodd"
401
- />
402
- </Svg>
403
- );
404
- }
349
+ export const StarIcon = icon(HgStarIcon, {
350
+ size: 20,
351
+ color: '#737373',
352
+ strokeWidth: 1.6,
353
+ fillable: true,
354
+ });
355
+ export const HeartIcon = icon(HgFavouriteIcon, {
356
+ size: 16,
357
+ color: '#737373',
358
+ fillable: true,
359
+ });
360
+ export const BookmarkIcon = icon(HgBookmark01Icon, {
361
+ size: 16,
362
+ color: '#737373',
363
+ fillable: true,
364
+ });
365
+ export const SparklesIcon = icon(HgSparklesIcon, { size: 16, color: '#737373' });
366
+ export const MessageCircleIcon = icon(HgBubbleChatIcon, {
367
+ size: 16,
368
+ color: '#737373',
369
+ fillable: true,
370
+ });
371
+ export const CardIcon = icon(HgCreditCardIcon, { size: 16, color: '#737373' });
372
+ export const ReceiptIcon = icon(HgReceiptIcon, { size: 16, color: '#737373' });
373
+ export const SunIcon = icon(HgSun03Icon, { size: 18, color: '#f5f5f5' });
374
+ export const MoonIcon = icon(HgMoonIcon, { size: 18, color: '#262626' });
405
375
 
406
- /** Check circle. Used for `success` status. */
407
- export function CheckCircleIcon({ size = 20, color, ...props }: IconProps) {
408
- const resolved = useResolvedColor(color, 'currentColor');
409
- return (
410
- <Svg width={size} height={size} viewBox="0 0 16 16" fill={resolved} {...decorative} {...props}>
411
- <Path
412
- d="M13.5 8a5.5 5.5 0 1 1-11 0a5.5 5.5 0 0 1 11 0M15 8A7 7 0 1 1 1 8a7 7 0 0 1 14 0m-3.9-1.55a.75.75 0 1 0-1.2-.9L7.419 8.858L6.03 7.47a.75.75 0 0 0-1.06 1.06l2 2a.75.75 0 0 0 1.13-.08z"
413
- fillRule="evenodd"
414
- clipRule="evenodd"
415
- />
416
- </Svg>
417
- );
418
- }
376
+ /* -------------------------------------------------------------------------- */
377
+ /* A post's toggles */
378
+ /* -------------------------------------------------------------------------- */
419
379
 
420
- /** Warning triangle. Used for `warning` status. */
421
- export function AlertTriangleIcon({ size = 20, color, ...props }: IconProps) {
422
- const resolved = useResolvedColor(color, 'currentColor');
423
- return (
424
- <Svg width={size} height={size} viewBox="0 0 16 16" fill={resolved} {...decorative} {...props}>
425
- <Path
426
- d="M7.134 2.994L2.217 11.5a1 1 0 0 0 .866 1.5h9.834a1 1 0 0 0 .866-1.5L8.866 2.993a1 1 0 0 0-1.732 0m3.03-.75c-.962-1.665-3.366-1.665-4.329 0L.918 10.749c-.963 1.666.24 3.751 2.165 3.751h9.834c1.925 0 3.128-2.085 2.164-3.751zM8 5a.75.75 0 0 1 .75.75v2a.75.75 0 0 1-1.5 0v-2A.75.75 0 0 1 8 5m1 5.75a1 1 0 1 1-2 0a1 1 0 0 1 2 0"
427
- fillRule="evenodd"
428
- clipRule="evenodd"
429
- />
430
- </Svg>
431
- );
432
- }
380
+ export const ArrowUpIcon = icon(HgArrowUp02Icon, {
381
+ size: 16,
382
+ color: '#737373',
383
+ fillable: true,
384
+ });
385
+ export const ArrowDownIcon = icon(HgArrowDown02Icon, {
386
+ size: 16,
387
+ color: '#737373',
388
+ fillable: true,
389
+ });
433
390
 
434
391
  /* -------------------------------------------------------------------------- */
435
- /* Brand marks */
392
+ /* Drawn by hand */
436
393
  /* -------------------------------------------------------------------------- */
437
394
 
438
- /*
439
- * These keep their official colours and so opt out of the icon colour
440
- * context — recolouring a brand mark to match a button is a trademark
441
- * problem, not a theming one.
395
+ /**
396
+ * The icons a post's action row is made of.
397
+ *
398
+ * These are the only ones in the set that take `filled`, and it is not a
399
+ * stylistic choice: a like, a save and a vote are toggles, and the outline and
400
+ * the solid are the two states of one control. Drawn as two different icons
401
+ * they would swap shape under the finger; drawn as one that fills, the shape
402
+ * stays put and only the inside changes.
442
403
  */
404
+ export interface ToggleIconProps extends IconProps {
405
+ /** Solid rather than outlined — the on state of a like, a save, a vote. */
406
+ filled?: boolean;
407
+ }
408
+
409
+ export interface BadgeCheckIconProps extends IconProps {
410
+ /** The tick's colour when the rosette is solid. Defaults to white. */
411
+ checkColor?: string;
412
+ }
443
413
 
444
414
  /** Google "G", in the four official brand colours. */
445
415
  export function GoogleIcon({ size = 18, ...props }: Omit<IconProps, 'color'>) {
@@ -467,6 +437,8 @@ export function GoogleIcon({ size = 18, ...props }: Omit<IconProps, 'color'>) {
467
437
  );
468
438
  }
469
439
 
440
+ /** Facebook "f" mark. */
441
+
470
442
  /** Facebook "f" mark. */
471
443
  export function FacebookIcon({ size = 18, ...props }: Omit<IconProps, 'color'>) {
472
444
  return (
@@ -479,6 +451,12 @@ export function FacebookIcon({ size = 18, ...props }: Omit<IconProps, 'color'>)
479
451
  );
480
452
  }
481
453
 
454
+ /**
455
+ * Apple mark. Monochrome by design, so unlike the other brand marks it does
456
+ * follow the icon colour context — Apple's guidelines require it to match the
457
+ * button's text colour.
458
+ */
459
+
482
460
  /**
483
461
  * Apple mark. Monochrome by design, so unlike the other brand marks it does
484
462
  * follow the icon colour context — Apple's guidelines require it to match the
@@ -500,973 +478,6 @@ export function AppleIcon({ size = 18, color, ...props }: IconProps) {
500
478
  /* Event icons (Timeline and other status surfaces) */
501
479
  /* -------------------------------------------------------------------------- */
502
480
 
503
- export function PlusSquareIcon({ size = 16, color, ...props }: IconProps) {
504
- const resolved = useResolvedColor(color, '#737373');
505
- return (
506
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
507
- <Path
508
- d="M4 6a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2zM12 8v8M8 12h8"
509
- stroke={resolved}
510
- strokeWidth={2}
511
- strokeLinecap="round"
512
- strokeLinejoin="round"
513
- />
514
- </Svg>
515
- );
516
- }
517
-
518
- /** Three connected nodes — a branch, a share, a fan-out. */
519
- export function ShareNodesIcon({ size = 16, color, ...props }: IconProps) {
520
- const resolved = useResolvedColor(color, '#737373');
521
- return (
522
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
523
- <Circle cx={18} cy={5} r={2.5} stroke={resolved} strokeWidth={2} />
524
- <Circle cx={6} cy={12} r={2.5} stroke={resolved} strokeWidth={2} />
525
- <Circle cx={18} cy={19} r={2.5} stroke={resolved} strokeWidth={2} />
526
- <Path
527
- d="m8.6 10.7 6.8-4M8.6 13.3l6.8 4"
528
- stroke={resolved}
529
- strokeWidth={2}
530
- strokeLinecap="round"
531
- />
532
- </Svg>
533
- );
534
- }
535
-
536
- /** Shield with an exclamation — a tripped guardrail. */
537
- export function ShieldAlertIcon({ size = 16, color, ...props }: IconProps) {
538
- const resolved = useResolvedColor(color, '#737373');
539
- return (
540
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
541
- <Path
542
- d="M12 2.5 4.5 5.5v6c0 4.6 3.2 8.6 7.5 10 4.3-1.4 7.5-5.4 7.5-10v-6z"
543
- stroke={resolved}
544
- strokeWidth={2}
545
- strokeLinejoin="round"
546
- />
547
- <Path d="M12 8v4" stroke={resolved} strokeWidth={2} strokeLinecap="round" />
548
- <Circle cx={12} cy={15.5} r={1} fill={resolved} />
549
- </Svg>
550
- );
551
- }
552
-
553
- /** Shield with a check — a passed verification. */
554
- export function ShieldCheckIcon({ size = 16, color, ...props }: IconProps) {
555
- const resolved = useResolvedColor(color, '#737373');
556
- return (
557
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
558
- <Path
559
- d="M12 2.5 4.5 5.5v6c0 4.6 3.2 8.6 7.5 10 4.3-1.4 7.5-5.4 7.5-10v-6z"
560
- stroke={resolved}
561
- strokeWidth={2}
562
- strokeLinejoin="round"
563
- />
564
- <Path
565
- d="m9 12 2 2 4-4"
566
- stroke={resolved}
567
- strokeWidth={2}
568
- strokeLinecap="round"
569
- strokeLinejoin="round"
570
- />
571
- </Svg>
572
- );
573
- }
574
-
575
- export function BellIcon({ size = 16, color, ...props }: IconProps) {
576
- const resolved = useResolvedColor(color, '#737373');
577
- return (
578
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
579
- <Path
580
- d="M18 8a6 6 0 1 0-12 0c0 7-3 9-3 9h18s-3-2-3-9M13.7 21a2 2 0 0 1-3.4 0"
581
- stroke={resolved}
582
- strokeWidth={2}
583
- strokeLinecap="round"
584
- strokeLinejoin="round"
585
- />
586
- </Svg>
587
- );
588
- }
589
-
590
- export function PackageIcon({ size = 16, color, ...props }: IconProps) {
591
- const resolved = useResolvedColor(color, '#737373');
592
- return (
593
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
594
- <Path
595
- d="m12 2.5 8 4.5v10l-8 4.5-8-4.5V7zM4 7l8 4.5L20 7M12 11.5V21"
596
- stroke={resolved}
597
- strokeWidth={2}
598
- strokeLinecap="round"
599
- strokeLinejoin="round"
600
- />
601
- </Svg>
602
- );
603
- }
604
-
605
- export function CardIcon({ size = 16, color, ...props }: IconProps) {
606
- const resolved = useResolvedColor(color, '#737373');
607
- return (
608
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
609
- <Path
610
- d="M3 7a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2zM3 10h18"
611
- stroke={resolved}
612
- strokeWidth={2}
613
- strokeLinecap="round"
614
- strokeLinejoin="round"
615
- />
616
- </Svg>
617
- );
618
- }
619
-
620
- export function ReceiptIcon({ size = 16, color, ...props }: IconProps) {
621
- const resolved = useResolvedColor(color, '#737373');
622
- return (
623
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
624
- <Path
625
- d="M5 3h14v18l-2.3-1.6L14.4 21l-2.4-1.6L9.6 21l-2.3-1.6L5 21zM9 8h6M9 12h6"
626
- stroke={resolved}
627
- strokeWidth={2}
628
- strokeLinecap="round"
629
- strokeLinejoin="round"
630
- />
631
- </Svg>
632
- );
633
- }
634
-
635
- /** Paper plane — sent, submitted, approved-and-forwarded. */
636
- export function SendIcon({ size = 16, color, ...props }: IconProps) {
637
- const resolved = useResolvedColor(color, '#737373');
638
- const flip = useFlip();
639
- return (
640
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
641
- <Path
642
- d="M21.5 2.5 2.5 10l7.5 3 3 7.5z"
643
- stroke={resolved}
644
- strokeWidth={2}
645
- strokeLinejoin="round"
646
- {...flip}
647
- />
648
- </Svg>
649
- );
650
- }
651
-
652
- /** Document with a folded corner — a file attachment. */
653
- export function FileIcon({ size = 16, color, ...props }: IconProps) {
654
- const resolved = useResolvedColor(color, '#737373');
655
- return (
656
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
657
- <Path
658
- d="M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8zM14 3v5h5"
659
- stroke={resolved}
660
- strokeWidth={2}
661
- strokeLinecap="round"
662
- strokeLinejoin="round"
663
- />
664
- </Svg>
665
- );
666
- }
667
-
668
- /* ------------------------------------------------------------------ *
669
- * Text formatting. Drawn as the letterforms and marks an editor's
670
- * toolbar uses, rather than as pictures of them — a B that is a bold B
671
- * is read before it is recognised.
672
- * ------------------------------------------------------------------ */
673
-
674
- /** Bold — the two-bowled B. */
675
- export function BoldIcon({ size = 16, color, ...props }: IconProps) {
676
- const resolved = useResolvedColor(color, '#737373');
677
- return (
678
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
679
- <Path
680
- d="M6 4h8a4 4 0 0 1 0 8H6zM6 12h9a4 4 0 0 1 0 8H6z"
681
- stroke={resolved}
682
- strokeWidth={2}
683
- strokeLinecap="round"
684
- strokeLinejoin="round"
685
- />
686
- </Svg>
687
- );
688
- }
689
-
690
- /** Italic — a slanted stroke between its serifs. */
691
- export function ItalicIcon({ size = 16, color, ...props }: IconProps) {
692
- const resolved = useResolvedColor(color, '#737373');
693
- return (
694
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
695
- <Path
696
- d="M19 4h-9M14 20H5M15 4 9 20"
697
- stroke={resolved}
698
- strokeWidth={2}
699
- strokeLinecap="round"
700
- strokeLinejoin="round"
701
- />
702
- </Svg>
703
- );
704
- }
705
-
706
- /** Heading — the crossbar H. */
707
- export function HeadingIcon({ size = 16, color, ...props }: IconProps) {
708
- const resolved = useResolvedColor(color, '#737373');
709
- return (
710
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
711
- <Path
712
- d="M6 12h12M6 20V4M18 20V4"
713
- stroke={resolved}
714
- strokeWidth={2}
715
- strokeLinecap="round"
716
- strokeLinejoin="round"
717
- />
718
- </Svg>
719
- );
720
- }
721
-
722
- /** Bulleted list — three rules, each behind a dot. */
723
- export function ListIcon({ size = 16, color, ...props }: IconProps) {
724
- const resolved = useResolvedColor(color, '#737373');
725
- return (
726
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
727
- <Path
728
- d="M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01"
729
- stroke={resolved}
730
- strokeWidth={2}
731
- strokeLinecap="round"
732
- strokeLinejoin="round"
733
- />
734
- </Svg>
735
- );
736
- }
737
-
738
- /** Numbered list — the same rules, counted. */
739
- export function ListOrderedIcon({ size = 16, color, ...props }: IconProps) {
740
- const resolved = useResolvedColor(color, '#737373');
741
- return (
742
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
743
- <Path
744
- d="M10 6h11M10 12h11M10 18h11M4 4h1v4M4 8h2M6 15a1.5 1.5 0 1 0-2-1.4M4 17l2-2M4 17h2"
745
- stroke={resolved}
746
- strokeWidth={2}
747
- strokeLinecap="round"
748
- strokeLinejoin="round"
749
- />
750
- </Svg>
751
- );
752
- }
753
-
754
- /** Block quote — the rule a quoted passage is set behind. */
755
- export function QuoteIcon({ size = 16, color, ...props }: IconProps) {
756
- const resolved = useResolvedColor(color, '#737373');
757
- return (
758
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
759
- <Path
760
- d="M4 5v14M9 7h11M9 12h11M9 17h7"
761
- stroke={resolved}
762
- strokeWidth={2}
763
- strokeLinecap="round"
764
- strokeLinejoin="round"
765
- />
766
- </Svg>
767
- );
768
- }
769
-
770
- /** Code — the pair of angle brackets. */
771
- export function CodeIcon({ size = 16, color, ...props }: IconProps) {
772
- const resolved = useResolvedColor(color, '#737373');
773
- return (
774
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
775
- <Path
776
- d="m8 18-6-6 6-6M16 6l6 6-6 6"
777
- stroke={resolved}
778
- strokeWidth={2}
779
- strokeLinecap="round"
780
- strokeLinejoin="round"
781
- />
782
- </Svg>
783
- );
784
- }
785
-
786
- /** Closed folder with a tab — a branch nobody has opened yet. */
787
- export function FolderIcon({ size = 16, color, ...props }: IconProps) {
788
- const resolved = useResolvedColor(color, '#737373');
789
- return (
790
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
791
- <Path
792
- d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2z"
793
- stroke={resolved}
794
- strokeWidth={2}
795
- strokeLinecap="round"
796
- strokeLinejoin="round"
797
- />
798
- </Svg>
799
- );
800
- }
801
-
802
- /**
803
- * Folder tipped open, its front face sheared to the side — the same branch
804
- * once it is expanded. Drawn as a separate glyph rather than a rotation of
805
- * `FolderIcon`, because a folder that opens by spinning reads as a mistake.
806
- */
807
- export function FolderOpenIcon({ size = 16, color, ...props }: IconProps) {
808
- const resolved = useResolvedColor(color, '#737373');
809
- return (
810
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
811
- <Path
812
- d="M6 14l1.45-2.9A2 2 0 0 1 9.24 10H22a2 2 0 0 1 1.94 2.5l-1.55 6a2 2 0 0 1-1.94 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.93a2 2 0 0 1 1.66.9l.82 1.2a2 2 0 0 0 1.66.9H18a2 2 0 0 1 2 2v2"
813
- stroke={resolved}
814
- strokeWidth={2}
815
- strokeLinecap="round"
816
- strokeLinejoin="round"
817
- />
818
- </Svg>
819
- );
820
- }
821
-
822
- /** Framed picture with a sun and a corner peak — an image attachment. */
823
- export function ImageIcon({ size = 16, color, ...props }: IconProps) {
824
- const resolved = useResolvedColor(color, '#737373');
825
- return (
826
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
827
- <Path
828
- d="M4 4h16v16H4z M8.5 10a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zM20 15l-4.5-4.5L6 20"
829
- stroke={resolved}
830
- strokeWidth={2}
831
- strokeLinecap="round"
832
- strokeLinejoin="round"
833
- />
834
- </Svg>
835
- );
836
- }
837
-
838
- /** A paperclip — attaching a file to a composer. */
839
- export function PaperclipIcon({ size = 16, color, ...props }: IconProps) {
840
- const resolved = useResolvedColor(color, '#737373');
841
- return (
842
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
843
- <Path
844
- d="M21 8.5 11.3 18.2a4 4 0 0 1-5.6-5.6l9-9a2.5 2.5 0 0 1 3.6 3.6l-9 9a1 1 0 0 1-1.5-1.5l8.3-8.3"
845
- stroke={resolved}
846
- strokeWidth={2}
847
- strokeLinecap="round"
848
- strokeLinejoin="round"
849
- />
850
- </Svg>
851
- );
852
- }
853
-
854
- /** A capsule on a stand — a microphone, for anything voice. */
855
- /** A voice waveform — dictation, voice mode, a recording that has a shape. */
856
- export function AudioLinesIcon({ size = 16, color, ...props }: IconProps) {
857
- const resolved = useResolvedColor(color, '#737373');
858
- return (
859
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
860
- <Path
861
- d="M2 10v3M6 6v11M10 3v18M14 8v7M18 5v13M22 10v3"
862
- stroke={resolved}
863
- strokeWidth={2}
864
- strokeLinecap="round"
865
- strokeLinejoin="round"
866
- />
867
- </Svg>
868
- );
869
- }
870
-
871
- export function MicIcon({ size = 16, color, ...props }: IconProps) {
872
- const resolved = useResolvedColor(color, '#737373');
873
- return (
874
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
875
- <Path
876
- d="M12 3a3 3 0 0 0-3 3v6a3 3 0 0 0 6 0V6a3 3 0 0 0-3-3zM5 11v1a7 7 0 0 0 14 0v-1M12 19v3"
877
- stroke={resolved}
878
- strokeWidth={2}
879
- strokeLinecap="round"
880
- strokeLinejoin="round"
881
- />
882
- </Svg>
883
- );
884
- }
885
-
886
- /** A filled triangle — start playback. */
887
- export function PlayIcon({ size = 16, color, ...props }: IconProps) {
888
- const resolved = useResolvedColor(color, '#737373');
889
- return (
890
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
891
- <Path d="M7 4.5v15l13-7.5z" fill={resolved} stroke={resolved} strokeWidth={2} strokeLinejoin="round" />
892
- </Svg>
893
- );
894
- }
895
-
896
- /** Two filled bars — hold playback where it is. */
897
- export function PauseIcon({ size = 16, color, ...props }: IconProps) {
898
- const resolved = useResolvedColor(color, '#737373');
899
- return (
900
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
901
- <Path d="M8 5h2v14H8zM14 5h2v14h-2z" fill={resolved} stroke={resolved} strokeWidth={1.5} strokeLinejoin="round" />
902
- </Svg>
903
- );
904
- }
905
-
906
- /**
907
- * A five-pointed star — the mark of a Rating. `filled` paints the interior;
908
- * left hollow it is the outline of an unearned star. Both share the same
909
- * geometry, so a filled star clipped over an empty one lines up to the pixel.
910
- */
911
- export function StarIcon({
912
- size = 20,
913
- color,
914
- filled = false,
915
- ...props
916
- }: IconProps & { filled?: boolean }) {
917
- const resolved = useResolvedColor(color, '#737373');
918
- return (
919
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
920
- <Path
921
- d="M12 2.5l2.9 5.88 6.49.94-4.7 4.58 1.11 6.46L12 17.82 6.2 20.86l1.11-6.46-4.7-4.58 6.49-.94z"
922
- fill={filled ? resolved : 'none'}
923
- stroke={resolved}
924
- strokeWidth={1.6}
925
- strokeLinejoin="round"
926
- strokeLinecap="round"
927
- />
928
- </Svg>
929
- );
930
- }
931
-
932
- /** A pencil at an angle — draw, sign, edit by hand. */
933
- export function PencilIcon({ size = 16, color, ...props }: IconProps) {
934
- const resolved = useResolvedColor(color, '#737373');
935
- return (
936
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
937
- <Path
938
- d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4z"
939
- stroke={resolved}
940
- strokeWidth={2}
941
- strokeLinecap="round"
942
- strokeLinejoin="round"
943
- />
944
- </Svg>
945
- );
946
- }
947
-
948
- /** An arrow curling anticlockwise — undo, reset, start over. */
949
- export function RotateCcwIcon({ size = 16, color, ...props }: IconProps) {
950
- const resolved = useResolvedColor(color, '#737373');
951
- return (
952
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
953
- <Path
954
- d="M3 12a9 9 0 1 0 2.64-6.36L3 8"
955
- stroke={resolved}
956
- strokeWidth={2}
957
- strokeLinecap="round"
958
- strokeLinejoin="round"
959
- />
960
- <Path
961
- d="M3 3v5h5"
962
- stroke={resolved}
963
- strokeWidth={2}
964
- strokeLinecap="round"
965
- strokeLinejoin="round"
966
- />
967
- </Svg>
968
- );
969
- }
970
-
971
- /** An arrow curling clockwise — redo, put back what was undone. */
972
- export function RotateCwIcon({ size = 16, color, ...props }: IconProps) {
973
- const resolved = useResolvedColor(color, '#737373');
974
- return (
975
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
976
- <Path
977
- d="M21 12a9 9 0 1 1-2.64-6.36L21 8"
978
- stroke={resolved}
979
- strokeWidth={2}
980
- strokeLinecap="round"
981
- strokeLinejoin="round"
982
- />
983
- <Path
984
- d="M21 3v5h-5"
985
- stroke={resolved}
986
- strokeWidth={2}
987
- strokeLinecap="round"
988
- strokeLinejoin="round"
989
- />
990
- </Svg>
991
- );
992
- }
993
-
994
- /** A bin — discard what is there. */
995
- export function TrashIcon({ size = 16, color, ...props }: IconProps) {
996
- const resolved = useResolvedColor(color, '#737373');
997
- return (
998
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
999
- <Path
1000
- d="M4 7h16M10 4h4M6 7l1 13h10l1-13"
1001
- stroke={resolved}
1002
- strokeWidth={2}
1003
- strokeLinecap="round"
1004
- strokeLinejoin="round"
1005
- />
1006
- </Svg>
1007
- );
1008
- }
1009
-
1010
- /**
1011
- * Two columns of dots — the grip on a row that can be dragged somewhere else.
1012
- *
1013
- * Dots rather than the stacked rules of a menu glyph, and two columns rather
1014
- * than one: the pattern has to read as a surface to take hold of from either
1015
- * side, and a single column reads as a divider instead.
1016
- */
1017
- export function GripVerticalIcon({ size = 16, color, ...props }: IconProps) {
1018
- const resolved = useResolvedColor(color, '#737373');
1019
- return (
1020
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
1021
- <Path
1022
- d="M9 5h.01M9 12h.01M9 19h.01M15 5h.01M15 12h.01M15 19h.01"
1023
- stroke={resolved}
1024
- strokeWidth={2.5}
1025
- strokeLinecap="round"
1026
- strokeLinejoin="round"
1027
- />
1028
- </Svg>
1029
- );
1030
- }
1031
-
1032
- /** An arrow into a tray — save the thing to a file. */
1033
- export function DownloadIcon({ size = 16, color, ...props }: IconProps) {
1034
- const resolved = useResolvedColor(color, '#737373');
1035
- return (
1036
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
1037
- <Path
1038
- d="M12 3v12m0 0 4-4m-4 4-4-4M4 19h16"
1039
- stroke={resolved}
1040
- strokeWidth={2}
1041
- strokeLinecap="round"
1042
- strokeLinejoin="round"
1043
- />
1044
- </Svg>
1045
- );
1046
- }
1047
-
1048
- /** A cross of two strokes — zoom in, add. Pairs with MinusIcon. */
1049
- export function PlusIcon({ size = 16, color, ...props }: IconProps) {
1050
- const resolved = useResolvedColor(color, '#737373');
1051
- return (
1052
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
1053
- <Path
1054
- d="M12 5v14M5 12h14"
1055
- stroke={resolved}
1056
- strokeWidth={2}
1057
- strokeLinecap="round"
1058
- />
1059
- </Svg>
1060
- );
1061
- }
1062
-
1063
- /** Four corners pushing outward — fit everything into view. */
1064
- export function MaximizeIcon({ size = 16, color, ...props }: IconProps) {
1065
- const resolved = useResolvedColor(color, '#737373');
1066
- return (
1067
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
1068
- <Path
1069
- d="M8 3H3v5M16 3h5v5M8 21H3v-5M16 21h5v-5"
1070
- stroke={resolved}
1071
- strokeWidth={2}
1072
- strokeLinecap="round"
1073
- strokeLinejoin="round"
1074
- />
1075
- </Svg>
1076
- );
1077
- }
1078
-
1079
- /** Crosshairs on a centre dot — put me where I actually am. */
1080
- export function CrosshairIcon({ size = 16, color, ...props }: IconProps) {
1081
- const resolved = useResolvedColor(color, '#737373');
1082
- return (
1083
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
1084
- <Circle cx={12} cy={12} r={7} stroke={resolved} strokeWidth={2} />
1085
- <Path
1086
- d="M12 2v3M12 19v3M2 12h3M19 12h3"
1087
- stroke={resolved}
1088
- strokeWidth={2}
1089
- strokeLinecap="round"
1090
- />
1091
- <Circle cx={12} cy={12} r={1.5} fill={resolved} />
1092
- </Svg>
1093
- );
1094
- }
1095
-
1096
- /** A compass needle — which way is north. */
1097
- export function GlobeIcon({ size = 16, color, ...props }: IconProps) {
1098
- const resolved = useResolvedColor(color, '#737373');
1099
- return (
1100
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
1101
- <Circle
1102
- cx={12}
1103
- cy={12}
1104
- r={10}
1105
- stroke={resolved}
1106
- strokeWidth={2}
1107
- strokeLinecap="round"
1108
- strokeLinejoin="round"
1109
- />
1110
- <Path
1111
- d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20M2 12h20"
1112
- stroke={resolved}
1113
- strokeWidth={2}
1114
- strokeLinecap="round"
1115
- strokeLinejoin="round"
1116
- />
1117
- </Svg>
1118
- );
1119
- }
1120
-
1121
- export function CameraIcon({ size = 16, color, ...props }: IconProps) {
1122
- const resolved = useResolvedColor(color, '#737373');
1123
- return (
1124
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
1125
- <Path
1126
- d="M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z"
1127
- stroke={resolved}
1128
- strokeWidth={2}
1129
- strokeLinecap="round"
1130
- strokeLinejoin="round"
1131
- />
1132
- <Circle
1133
- cx={12}
1134
- cy={13}
1135
- r={3}
1136
- stroke={resolved}
1137
- strokeWidth={2}
1138
- strokeLinecap="round"
1139
- strokeLinejoin="round"
1140
- />
1141
- </Svg>
1142
- );
1143
- }
1144
-
1145
- /**
1146
- * The glyph on a control that opens a list of values — a stacked pair, because
1147
- * one chevron promises a direction the control does not travel in.
1148
- */
1149
- export function ChevronsUpDownIcon({ size = 16, color, ...props }: IconProps) {
1150
- const resolved = useResolvedColor(color, '#737373');
1151
- return (
1152
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
1153
- <Path
1154
- d="m7 15 5 5 5-5M7 9l5-5 5 5"
1155
- stroke={resolved}
1156
- strokeWidth={2}
1157
- strokeLinecap="round"
1158
- strokeLinejoin="round"
1159
- />
1160
- </Svg>
1161
- );
1162
- }
1163
-
1164
- export function CompassIcon({ size = 16, color, ...props }: IconProps) {
1165
- const resolved = useResolvedColor(color, '#737373');
1166
- return (
1167
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
1168
- <Circle cx={12} cy={12} r={9} stroke={resolved} strokeWidth={2} />
1169
- <Path
1170
- d="M15.5 8.5l-2 5-5 2 2-5 5-2z"
1171
- stroke={resolved}
1172
- strokeWidth={2}
1173
- strokeLinejoin="round"
1174
- />
1175
- </Svg>
1176
- );
1177
- }
1178
-
1179
- /** A closed padlock — the thing behind it cannot be moved. */
1180
- export function LockIcon({ size = 16, color, ...props }: IconProps) {
1181
- const resolved = useResolvedColor(color, '#737373');
1182
- return (
1183
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
1184
- <Path
1185
- d="M5 11h14v10H5z"
1186
- stroke={resolved}
1187
- strokeWidth={2}
1188
- strokeLinejoin="round"
1189
- />
1190
- <Path
1191
- d="M8 11V7a4 4 0 0 1 8 0v4"
1192
- stroke={resolved}
1193
- strokeWidth={2}
1194
- strokeLinecap="round"
1195
- />
1196
- </Svg>
1197
- );
1198
- }
1199
-
1200
- /** The same padlock with its shackle swung open — freely movable. */
1201
- export function UnlockIcon({ size = 16, color, ...props }: IconProps) {
1202
- const resolved = useResolvedColor(color, '#737373');
1203
- return (
1204
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
1205
- <Path
1206
- d="M5 11h14v10H5z"
1207
- stroke={resolved}
1208
- strokeWidth={2}
1209
- strokeLinejoin="round"
1210
- />
1211
- <Path
1212
- d="M8 11V7a4 4 0 0 1 7.5-2"
1213
- stroke={resolved}
1214
- strokeWidth={2}
1215
- strokeLinecap="round"
1216
- />
1217
- </Svg>
1218
- );
1219
- }
1220
-
1221
- /**
1222
- * Four-pointed sparkles. The mark for a model doing something on your behalf —
1223
- * a reasoning step, a generated plan — where a gear or a brain reads as
1224
- * machinery rather than as assistance.
1225
- */
1226
- export function SparklesIcon({ size = 16, color, ...props }: IconProps) {
1227
- const resolved = useResolvedColor(color, '#737373');
1228
- return (
1229
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
1230
- <Path
1231
- d="M11 3 12.6 8.4 18 10l-5.4 1.6L11 17l-1.6-5.4L4 10l5.4-1.6z"
1232
- stroke={resolved}
1233
- strokeWidth={2}
1234
- strokeLinejoin="round"
1235
- />
1236
- <Path
1237
- d="M18 15.5 18.7 18l2.3.7-2.3.7-.7 2.3-.7-2.3-2.3-.7 2.3-.7z"
1238
- stroke={resolved}
1239
- strokeWidth={1.6}
1240
- strokeLinejoin="round"
1241
- />
1242
- </Svg>
1243
- );
1244
- }
1245
-
1246
- /** Two stacked sheets — the copy action, paired with CheckIcon once it has run. */
1247
- export function CopyIcon({ size = 16, color, ...props }: IconProps) {
1248
- const resolved = useResolvedColor(color, '#737373');
1249
- return (
1250
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
1251
- <Path
1252
- d="M9 9h10v12H9z"
1253
- stroke={resolved}
1254
- strokeWidth={2}
1255
- strokeLinejoin="round"
1256
- />
1257
- <Path
1258
- d="M15 5H5v12h2"
1259
- stroke={resolved}
1260
- strokeWidth={2}
1261
- strokeLinecap="round"
1262
- strokeLinejoin="round"
1263
- />
1264
- </Svg>
1265
- );
1266
- }
1267
-
1268
- /** Two links of a chain, for a row that opens somewhere outside the app. */
1269
- export function LinkIcon({ size = 16, color, ...props }: IconProps) {
1270
- const resolved = useResolvedColor(color, '#737373');
1271
- return (
1272
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
1273
- <Path
1274
- d="M10 13a5 5 0 0 0 7.5.5l3-3a5 5 0 0 0-7-7l-1.7 1.7"
1275
- stroke={resolved}
1276
- strokeWidth={2}
1277
- strokeLinecap="round"
1278
- strokeLinejoin="round"
1279
- />
1280
- <Path
1281
- d="M14 11a5 5 0 0 0-7.5-.5l-3 3a5 5 0 0 0 7 7l1.7-1.7"
1282
- stroke={resolved}
1283
- strokeWidth={2}
1284
- strokeLinecap="round"
1285
- strokeLinejoin="round"
1286
- />
1287
- </Svg>
1288
- );
1289
- }
1290
-
1291
- /** A list with its items ticked off — a plan, or a run of steps. */
1292
- export function ListChecksIcon({ size = 16, color, ...props }: IconProps) {
1293
- const resolved = useResolvedColor(color, '#737373');
1294
- return (
1295
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
1296
- <Path
1297
- d="m3 6 1.8 1.8L8 4.5M3 16l1.8 1.8L8 14.5"
1298
- stroke={resolved}
1299
- strokeWidth={2}
1300
- strokeLinecap="round"
1301
- strokeLinejoin="round"
1302
- />
1303
- <Path
1304
- d="M12 6.5h9M12 17.5h9"
1305
- stroke={resolved}
1306
- strokeWidth={2}
1307
- strokeLinecap="round"
1308
- />
1309
- </Svg>
1310
- );
1311
- }
1312
-
1313
- /** A hollow ring, for a step that has not started. */
1314
- export function CircleIcon({ size = 16, color, ...props }: IconProps) {
1315
- const resolved = useResolvedColor(color, '#737373');
1316
- return (
1317
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
1318
- <Circle cx={12} cy={12} r={8} stroke={resolved} strokeWidth={2} />
1319
- </Svg>
1320
- );
1321
- }
1322
-
1323
- /* -------------------------------------------------------------------------- */
1324
- /* Social */
1325
- /* -------------------------------------------------------------------------- */
1326
-
1327
- /**
1328
- * The icons a post's action row is made of.
1329
- *
1330
- * These are the only ones in the set that take `filled`, and it is not a
1331
- * stylistic choice: a like, a save and a vote are toggles, and the outline and
1332
- * the solid are the two states of one control. Drawn as two different icons
1333
- * they would swap shape under the finger; drawn as one that fills, the shape
1334
- * stays put and only the inside changes.
1335
- */
1336
- export interface ToggleIconProps extends IconProps {
1337
- /** Solid rather than outlined — the on state of a like, a save, a vote. */
1338
- filled?: boolean;
1339
- }
1340
-
1341
- /** Upvote. Filled once the vote is cast. */
1342
- /**
1343
- * A plain up arrow, drawn symmetrically about the centre of its box so it sits
1344
- * dead centre in a circular button.
1345
- *
1346
- * Distinct from `ArrowUpIcon`, which is the heavy solid arrow a vote control
1347
- * wants, and from `SendIcon`, which is a paper plane. This is the one a
1348
- * composer's send button uses.
1349
- */
1350
- export function SendArrowIcon({ size = 16, color, ...props }: IconProps) {
1351
- const resolved = useResolvedColor(color, '#737373');
1352
- return (
1353
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
1354
- <Path
1355
- d="m5 12 7-7 7 7M12 19V5"
1356
- stroke={resolved}
1357
- strokeWidth={2.5}
1358
- strokeLinecap="round"
1359
- strokeLinejoin="round"
1360
- />
1361
- </Svg>
1362
- );
1363
- }
1364
-
1365
- export function ArrowUpIcon({ size = 16, color, filled, ...props }: ToggleIconProps) {
1366
- const resolved = useResolvedColor(color, '#737373');
1367
- return (
1368
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
1369
- <Path
1370
- d="M9 18v-6H5l7-7 7 7h-4v6z"
1371
- fill={filled ? resolved : 'none'}
1372
- stroke={resolved}
1373
- strokeWidth={2}
1374
- strokeLinecap="round"
1375
- strokeLinejoin="round"
1376
- />
1377
- </Svg>
1378
- );
1379
- }
1380
-
1381
- /** Downvote. The same arrow, turned over. */
1382
- export function ArrowDownIcon({ size = 16, color, filled, ...props }: ToggleIconProps) {
1383
- const resolved = useResolvedColor(color, '#737373');
1384
- return (
1385
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
1386
- <Path
1387
- d="M9 6v6H5l7 7 7-7h-4V6z"
1388
- fill={filled ? resolved : 'none'}
1389
- stroke={resolved}
1390
- strokeWidth={2}
1391
- strokeLinecap="round"
1392
- strokeLinejoin="round"
1393
- />
1394
- </Svg>
1395
- );
1396
- }
1397
-
1398
- /** A like. */
1399
- export function HeartIcon({ size = 16, color, filled, ...props }: ToggleIconProps) {
1400
- const resolved = useResolvedColor(color, '#737373');
1401
- return (
1402
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
1403
- <Path
1404
- d="M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z"
1405
- fill={filled ? resolved : 'none'}
1406
- stroke={resolved}
1407
- strokeWidth={2}
1408
- strokeLinecap="round"
1409
- strokeLinejoin="round"
1410
- />
1411
- </Svg>
1412
- );
1413
- }
1414
-
1415
- /** A reply, or the count of them. */
1416
- export function MessageCircleIcon({ size = 16, color, filled, ...props }: ToggleIconProps) {
1417
- const resolved = useResolvedColor(color, '#737373');
1418
- return (
1419
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
1420
- <Path
1421
- d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"
1422
- fill={filled ? resolved : 'none'}
1423
- stroke={resolved}
1424
- strokeWidth={2}
1425
- strokeLinecap="round"
1426
- strokeLinejoin="round"
1427
- />
1428
- </Svg>
1429
- );
1430
- }
1431
-
1432
- /** Views — how many times a thing has been seen rather than acted on. */
1433
- export function EyeIcon({ size = 16, color, ...props }: IconProps) {
1434
- const resolved = useResolvedColor(color, '#737373');
1435
- return (
1436
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
1437
- <Path
1438
- d="M2.06 12.35a1 1 0 0 1 0-.7 10.75 10.75 0 0 1 19.88 0 1 1 0 0 1 0 .7 10.75 10.75 0 0 1-19.88 0"
1439
- stroke={resolved}
1440
- strokeWidth={2}
1441
- strokeLinecap="round"
1442
- strokeLinejoin="round"
1443
- />
1444
- <Circle cx={12} cy={12} r={3} stroke={resolved} strokeWidth={2} />
1445
- </Svg>
1446
- );
1447
- }
1448
-
1449
- /** A repost — the same thing sent round again. */
1450
- export function RepeatIcon({ size = 16, color, ...props }: IconProps) {
1451
- const resolved = useResolvedColor(color, '#737373');
1452
- return (
1453
- <Svg width={size} height={size} viewBox="0 0 24 24" fill="none" {...props}>
1454
- <Path
1455
- d="m2 9 3-3 3 3M5 6v10a2 2 0 0 0 2 2h6M22 15l-3 3-3-3M19 18V8a2 2 0 0 0-2-2h-6"
1456
- stroke={resolved}
1457
- strokeWidth={2}
1458
- strokeLinecap="round"
1459
- strokeLinejoin="round"
1460
- />
1461
- </Svg>
1462
- );
1463
- }
1464
-
1465
- export interface BadgeCheckIconProps extends IconProps {
1466
- /** The tick's colour when the rosette is solid. Defaults to white. */
1467
- checkColor?: string;
1468
- }
1469
-
1470
481
  /**
1471
482
  * The verified rosette.
1472
483
  *