134 lines
4.6 KiB
TypeScript
134 lines
4.6 KiB
TypeScript
// These exports are folds `IconSrc` callbacks — `(filled?: boolean) =>
|
||
// JSX.Element` — that the folds `<Icon>` component invokes as `src(filled)`
|
||
// to populate the inner SVG content. They are NOT React components (they
|
||
// are never mounted via JSX as `<CallMicIcon />`), so the
|
||
// `react/function-component-definition` rule's "use a function
|
||
// declaration" guidance is misapplied here.
|
||
/* eslint-disable react/function-component-definition */
|
||
|
||
// Custom call-control icon set, drawn to match the design-system style
|
||
// captured in `docs/design/new-direct-messages-design/project/shared.jsx`
|
||
// (lines 4-19): 24×24 viewBox, stroke-only (no fill), 1.6px stroke weight
|
||
// for handset/mic/video glyphs, round line joins/caps, currentColor — so
|
||
// the same icons read consistently across the green/red/neutral variant
|
||
// flips of the IncomingCallStrip / CallControl buttons.
|
||
//
|
||
// Folds' `Icon` component owns the outer `<svg>` (viewBox=0 0 24 24,
|
||
// fill=none, sizing class via the `size` prop). An `IconSrc` therefore
|
||
// returns only the inner shapes — same convention as the stock
|
||
// `Icons.*` table (see folds/dist/index.js Icons block).
|
||
//
|
||
// `filled` is intentionally ignored: this is an outline icon family,
|
||
// the muted/active distinction is carried by the diagonal slash plus
|
||
// the button's variant color, not by an alternate filled shape.
|
||
|
||
import React from 'react';
|
||
import { IconSrc } from 'folds';
|
||
|
||
const STROKE = {
|
||
stroke: 'currentColor',
|
||
strokeWidth: 1.6,
|
||
strokeLinecap: 'round' as const,
|
||
strokeLinejoin: 'round' as const,
|
||
fill: 'none',
|
||
};
|
||
|
||
// Slightly heavier than the body strokes so the «muted» indicator
|
||
// reads as a deliberate cancellation rather than ornamentation.
|
||
const SLASH = {
|
||
...STROKE,
|
||
strokeWidth: 2,
|
||
};
|
||
|
||
export const CallMicIcon: IconSrc = () => (
|
||
<>
|
||
<rect x="9" y="3" width="6" height="12" rx="3" {...STROKE} />
|
||
<path d="M5 11a7 7 0 0 0 14 0" {...STROKE} />
|
||
<path d="M12 18v3" {...STROKE} />
|
||
</>
|
||
);
|
||
|
||
export const CallMicMuteIcon: IconSrc = () => (
|
||
<>
|
||
<rect x="9" y="3" width="6" height="12" rx="3" {...STROKE} />
|
||
<path d="M5 11a7 7 0 0 0 14 0" {...STROKE} />
|
||
<path d="M12 18v3" {...STROKE} />
|
||
<path d="M3 3l18 18" {...SLASH} />
|
||
</>
|
||
);
|
||
|
||
export const CallHeadphoneIcon: IconSrc = () => (
|
||
<>
|
||
<path d="M4 14a8 8 0 0 1 16 0" {...STROKE} />
|
||
<path d="M4 14v4a2 2 0 0 0 2 2h2v-7H6a2 2 0 0 0-2 2z" {...STROKE} />
|
||
<path d="M20 14v4a2 2 0 0 1-2 2h-2v-7h2a2 2 0 0 1 2 2z" {...STROKE} />
|
||
</>
|
||
);
|
||
|
||
export const CallHeadphoneMuteIcon: IconSrc = () => (
|
||
<>
|
||
<path d="M4 14a8 8 0 0 1 16 0" {...STROKE} />
|
||
<path d="M4 14v4a2 2 0 0 0 2 2h2v-7H6a2 2 0 0 0-2 2z" {...STROKE} />
|
||
<path d="M20 14v4a2 2 0 0 1-2 2h-2v-7h2a2 2 0 0 1 2 2z" {...STROKE} />
|
||
<path d="M3 3l18 18" {...SLASH} />
|
||
</>
|
||
);
|
||
|
||
export const CallVideoIcon: IconSrc = () => (
|
||
<>
|
||
<rect x="3" y="6" width="13" height="12" rx="2" {...STROKE} />
|
||
<path d="M16 10l5-3v10l-5-3" {...STROKE} />
|
||
</>
|
||
);
|
||
|
||
export const CallVideoMuteIcon: IconSrc = () => (
|
||
<>
|
||
<rect x="3" y="6" width="13" height="12" rx="2" {...STROKE} />
|
||
<path d="M16 10l5-3v10l-5-3" {...STROKE} />
|
||
<path d="M3 3l18 18" {...SLASH} />
|
||
</>
|
||
);
|
||
|
||
export const CallScreenShareIcon: IconSrc = () => (
|
||
<>
|
||
<rect x="3" y="4" width="18" height="13" rx="2" {...STROKE} />
|
||
<path d="M9 21h6M12 17v4" {...STROKE} />
|
||
<path d="M8.5 11l3.5-3.5L15.5 11" {...STROKE} />
|
||
<path d="M12 7.5V14" {...STROKE} />
|
||
</>
|
||
);
|
||
|
||
// Screenshare-off carries the same slash convention as the other muted
|
||
// glyphs so the on/off state has both a shape cue and a variant cue —
|
||
// matters for high-contrast / monochrome modes where the
|
||
// Success-vs-Surface variant flip alone is too subtle.
|
||
export const CallScreenShareMuteIcon: IconSrc = () => (
|
||
<>
|
||
<rect x="3" y="4" width="18" height="13" rx="2" {...STROKE} />
|
||
<path d="M9 21h6M12 17v4" {...STROKE} />
|
||
<path d="M8.5 11l3.5-3.5L15.5 11" {...STROKE} />
|
||
<path d="M12 7.5V14" {...STROKE} />
|
||
<path d="M3 3l18 18" {...SLASH} />
|
||
</>
|
||
);
|
||
|
||
// Classic «pick up» handset, used on the IncomingCallStrip Answer
|
||
// button. Kept upright (no rotation) so it reads as «receive call».
|
||
export const CallPhoneIcon: IconSrc = () => (
|
||
<path
|
||
d="M5 4h4l2 5-3 2a12 12 0 0 0 6 6l2-3 5 2v4a2 2 0 0 1-2 2A17 17 0 0 1 3 6a2 2 0 0 1 2-2z"
|
||
{...STROKE}
|
||
/>
|
||
);
|
||
|
||
// Same handset rotated 135° — universal «hang up / decline» glyph
|
||
// (handset tilted off the cradle). Reused for Decline (IncomingCallStrip)
|
||
// and Hangup (CallControl).
|
||
export const CallPhoneDownIcon: IconSrc = () => (
|
||
<g transform="rotate(135 12 12)">
|
||
<path
|
||
d="M5 4h4l2 5-3 2a12 12 0 0 0 6 6l2-3 5 2v4a2 2 0 0 1-2 2A17 17 0 0 1 3 6a2 2 0 0 1 2-2z"
|
||
{...STROKE}
|
||
/>
|
||
</g>
|
||
);
|