@mattermost/compass-ui 0.1.0-alpha.13 → 0.1.0-alpha.15
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/dist/components/action-button/ActionButton.cjs +1 -1
- package/dist/components/action-button/ActionButton.cjs.map +1 -1
- package/dist/components/action-button/ActionButton.css +1 -1
- package/dist/components/action-button/ActionButton.d.ts +41 -5
- package/dist/components/action-button/ActionButton.d.ts.map +1 -1
- package/dist/components/action-button/ActionButton.js +68 -35
- package/dist/components/action-button/ActionButton.js.map +1 -1
- package/dist/components/action-button/ActionButton.module.scss.cjs +1 -1
- package/dist/components/action-button/ActionButton.module.scss.js +6 -5
- package/dist/components/action-button/ActionButton.module.scss.js.map +1 -1
- package/dist/components/action-button/index.d.ts +1 -1
- package/dist/components/action-button/index.d.ts.map +1 -1
- package/dist/components/button/Button.cjs +1 -1
- package/dist/components/button/Button.cjs.map +1 -1
- package/dist/components/button/Button.css +1 -1
- package/dist/components/button/Button.d.ts +37 -6
- package/dist/components/button/Button.d.ts.map +1 -1
- package/dist/components/button/Button.js +106 -44
- package/dist/components/button/Button.js.map +1 -1
- package/dist/components/button/Button.module.scss.cjs +1 -1
- package/dist/components/button/Button.module.scss.js +16 -15
- package/dist/components/button/Button.module.scss.js.map +1 -1
- package/dist/components/button/index.d.ts +1 -1
- package/dist/components/button/index.d.ts.map +1 -1
- package/dist/components/channel-sidebar-item/ChannelSidebarItem.cjs +1 -1
- package/dist/components/channel-sidebar-item/ChannelSidebarItem.cjs.map +1 -1
- package/dist/components/channel-sidebar-item/ChannelSidebarItem.d.ts.map +1 -1
- package/dist/components/channel-sidebar-item/ChannelSidebarItem.js +32 -31
- package/dist/components/channel-sidebar-item/ChannelSidebarItem.js.map +1 -1
- package/dist/components/checkbox/Checkbox.css +1 -1
- package/dist/components/checkbox/Checkbox.module.scss.cjs +1 -1
- package/dist/components/checkbox/Checkbox.module.scss.js +10 -10
- package/dist/components/icon-button/IconButton.cjs +1 -1
- package/dist/components/icon-button/IconButton.cjs.map +1 -1
- package/dist/components/icon-button/IconButton.css +1 -1
- package/dist/components/icon-button/IconButton.d.ts +48 -7
- package/dist/components/icon-button/IconButton.d.ts.map +1 -1
- package/dist/components/icon-button/IconButton.js +136 -62
- package/dist/components/icon-button/IconButton.js.map +1 -1
- package/dist/components/icon-button/IconButton.module.scss.cjs +1 -1
- package/dist/components/icon-button/IconButton.module.scss.js +16 -15
- package/dist/components/icon-button/IconButton.module.scss.js.map +1 -1
- package/dist/components/icon-button/index.d.ts +1 -1
- package/dist/components/icon-button/index.d.ts.map +1 -1
- package/dist/components/modal/Modal.cjs +1 -1
- package/dist/components/modal/Modal.cjs.map +1 -1
- package/dist/components/modal/Modal.css +1 -1
- package/dist/components/modal/Modal.d.ts +25 -3
- package/dist/components/modal/Modal.d.ts.map +1 -1
- package/dist/components/modal/Modal.js +105 -68
- package/dist/components/modal/Modal.js.map +1 -1
- package/dist/components/modal/Modal.module.scss.cjs +1 -1
- package/dist/components/modal/Modal.module.scss.js +14 -12
- package/dist/components/modal/Modal.module.scss.js.map +1 -1
- package/dist/components/modal-header/ModalHeader.css +1 -1
- package/dist/components/modal-header/ModalHeader.module.scss.cjs +1 -1
- package/dist/components/modal-header/ModalHeader.module.scss.js +15 -15
- package/dist/components/popover-menu/PopoverMenu.cjs +1 -1
- package/dist/components/popover-menu/PopoverMenu.cjs.map +1 -1
- package/dist/components/popover-menu/PopoverMenu.css +1 -1
- package/dist/components/popover-menu/PopoverMenu.d.ts +9 -1
- package/dist/components/popover-menu/PopoverMenu.d.ts.map +1 -1
- package/dist/components/popover-menu/PopoverMenu.js +39 -28
- package/dist/components/popover-menu/PopoverMenu.js.map +1 -1
- package/dist/components/popover-menu/PopoverMenu.module.scss.cjs +1 -1
- package/dist/components/popover-menu/PopoverMenu.module.scss.js +12 -10
- package/dist/components/popover-menu/PopoverMenu.module.scss.js.map +1 -1
- package/dist/components/radio/Radio.css +1 -1
- package/dist/components/radio/Radio.module.scss.cjs +1 -1
- package/dist/components/radio/Radio.module.scss.js +14 -14
- package/dist/components/right-sidebar-header/RightSidebarHeader.cjs +1 -1
- package/dist/components/right-sidebar-header/RightSidebarHeader.cjs.map +1 -1
- package/dist/components/right-sidebar-header/RightSidebarHeader.d.ts +5 -1
- package/dist/components/right-sidebar-header/RightSidebarHeader.d.ts.map +1 -1
- package/dist/components/right-sidebar-header/RightSidebarHeader.js +60 -48
- package/dist/components/right-sidebar-header/RightSidebarHeader.js.map +1 -1
- package/dist/components/switch/Switch.css +1 -1
- package/dist/components/switch/Switch.module.scss.cjs +1 -1
- package/dist/components/switch/Switch.module.scss.js +11 -11
- package/dist/components/tabs/Tabs.cjs +1 -1
- package/dist/components/tabs/Tabs.cjs.map +1 -1
- package/dist/components/tabs/Tabs.css +1 -1
- package/dist/components/tabs/Tabs.d.ts +4 -1
- package/dist/components/tabs/Tabs.d.ts.map +1 -1
- package/dist/components/tabs/Tabs.js +41 -35
- package/dist/components/tabs/Tabs.js.map +1 -1
- package/dist/components/tabs/Tabs.module.scss.cjs +1 -1
- package/dist/components/tabs/Tabs.module.scss.js +13 -12
- package/dist/components/tabs/Tabs.module.scss.js.map +1 -1
- package/dist/components/tabs/index.d.ts +1 -1
- package/dist/components/tabs/index.d.ts.map +1 -1
- package/dist/hooks/use-modal-focus.cjs +2 -0
- package/dist/hooks/use-modal-focus.cjs.map +1 -0
- package/dist/hooks/use-modal-focus.d.ts +26 -0
- package/dist/hooks/use-modal-focus.d.ts.map +1 -0
- package/dist/hooks/use-modal-focus.js +91 -0
- package/dist/hooks/use-modal-focus.js.map +1 -0
- package/dist/hooks/use-popover-transition.cjs +1 -1
- package/dist/hooks/use-popover-transition.cjs.map +1 -1
- package/dist/hooks/use-popover-transition.d.ts +6 -4
- package/dist/hooks/use-popover-transition.d.ts.map +1 -1
- package/dist/hooks/use-popover-transition.js +19 -15
- package/dist/hooks/use-popover-transition.js.map +1 -1
- package/dist/utils/duration.cjs +2 -0
- package/dist/utils/duration.cjs.map +1 -0
- package/dist/utils/duration.d.ts +8 -0
- package/dist/utils/duration.d.ts.map +1 -0
- package/dist/utils/duration.js +11 -0
- package/dist/utils/duration.js.map +1 -0
- package/dist/utils/slot.cjs +2 -0
- package/dist/utils/slot.cjs.map +1 -0
- package/dist/utils/slot.d.ts +46 -0
- package/dist/utils/slot.d.ts.map +1 -0
- package/dist/utils/slot.js +88 -0
- package/dist/utils/slot.js.map +1 -0
- package/package.json +5 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChannelSidebarItem.js","sources":["../../../src/components/channel-sidebar-item/ChannelSidebarItem.tsx"],"sourcesContent":["import type { MouseEvent, ReactNode } from 'react';\nimport GlobeIcon from '@mattermost/compass-icons/components/globe';\nimport LockOutlineIcon from '@mattermost/compass-icons/components/lock-outline';\nimport MessageTextOutlineIcon from '@mattermost/compass-icons/components/message-text-outline';\nimport SendOutlineIcon from '@mattermost/compass-icons/components/send-outline';\nimport ChartLineIcon from '@mattermost/compass-icons/components/chart-line';\nimport CircleMultipleOutlineIcon from '@mattermost/compass-icons/components/circle-multiple-outline';\nimport PhoneInTalkIcon from '@mattermost/compass-icons/components/phone-in-talk';\nimport DotsVerticalIcon from '@mattermost/compass-icons/components/dots-vertical';\nimport DialpadIcon from '@mattermost/compass-icons/components/dialpad';\nimport UserAvatar from '@/components/user-avatar/UserAvatar';\nimport MentionBadge from '@/components/mention-badge/MentionBadge';\nimport IconButton from '@/components/icon-button/IconButton';\nimport styles from './ChannelSidebarItem.module.scss';\n\nexport type ChannelSidebarItemLeadingVisual =\n | 'public'\n | 'private'\n | 'group-message'\n | 'direct-message'\n | 'drafts'\n | 'insights'\n | 'threads'\n | 'dial-pad';\n\nexport type ChannelSidebarItemStatus = 'read' | 'unread' | 'mention';\n\nexport interface ChannelSidebarItemProps {\n className?: string;\n /** Channel or user display name. Accepts translated nodes. */\n name: ReactNode;\n /**\n * Text-only row (e.g. System Console navigation): no channel glyph or\n * overflow menu; name aligns with channel sidebar label padding.\n */\n hideLeadingVisual?: boolean;\n /** Leading visual type. Default: Public. Ignored when `hideLeadingVisual`. */\n leadingVisual?: ChannelSidebarItemLeadingVisual;\n /** Read/unread/mention state. Default: Read. */\n status?: ChannelSidebarItemStatus;\n /** Highlighted as the currently active item. */\n active?: boolean;\n /** Muted channel — reduces visual prominence. */\n muted?: boolean;\n /** Shows a call-in-progress indicator on the right. */\n callActive?: boolean;\n /** Shows the shared-channel icon after the name. */\n sharedChannel?: boolean;\n /** Mention count shown in the badge when status='mention'. */\n mentionCount?: number;\n /** Member count shown in the group icon when leadingVisual='group-message'. */\n memberCount?: number;\n /** Avatar image URL for leadingVisual='direct-message'. */\n avatarSrc?: string;\n /** Avatar alt text for leadingVisual='direct-message'. */\n avatarAlt?: string;\n /** Shows status badge on the avatar when leadingVisual='direct-message'. */\n showAvatarStatus?: boolean;\n /** Custom status emoji shown after the name for leadingVisual='direct-message'. */\n customStatusEmoji?: string;\n onClick?: () => void;\n /** Overflow menu (kebab). Sibling of the channel control so it is keyboard-reachable. */\n onMenuClick?: (event: MouseEvent<HTMLButtonElement>) => void;\n /** Visually hidden mention hint. Default: `{count} mention(s)`. */\n formatMentionLabel?: (count: number) => ReactNode;\n /** Visually hidden unread hint. Default: \"unread\". */\n unreadLabel?: ReactNode;\n /** Accessible name for the overflow menu button. Default: \"Channel options\". */\n menuLabel?: string;\n}\n\nconst defaultFormatMentions = (count: number) =>\n `${count} mention${count === 1 ? '' : 's'}`;\n\nfunction LeadingVisualContent({\n leadingVisual,\n memberCount,\n avatarSrc,\n showAvatarStatus,\n}: {\n leadingVisual: ChannelSidebarItemLeadingVisual;\n memberCount: number | undefined;\n avatarSrc: string | undefined;\n showAvatarStatus: boolean | undefined;\n}) {\n switch (leadingVisual) {\n case 'private':\n return <LockOutlineIcon size={16} />;\n case 'group-message':\n return (\n <div className={styles['channel-sidebar-item__group-icon']}>\n {memberCount ?? 2}\n </div>\n );\n case 'direct-message':\n return (\n <UserAvatar\n src={avatarSrc ?? ''}\n alt=\"\"\n size=\"20\"\n status={!!showAvatarStatus}\n />\n );\n case 'drafts':\n return <SendOutlineIcon size={16} />;\n case 'insights':\n return <ChartLineIcon size={16} />;\n case 'threads':\n return <MessageTextOutlineIcon size={16} />;\n case 'dial-pad':\n return <DialpadIcon size={16} />;\n case 'public':\n default:\n return <GlobeIcon size={16} />;\n }\n}\n\n/**\n * The Channel Sidebar Item is the row people use to move between channels, DMs, and group\n * messages. It compresses a lot of state — channel type, unread, mention count, mute,\n * in-call — into a single, scannable line.\n */\nexport default function ChannelSidebarItem({\n className,\n name,\n hideLeadingVisual = false,\n leadingVisual = 'public',\n status = 'read',\n active = false,\n muted = false,\n callActive = false,\n sharedChannel = false,\n mentionCount,\n memberCount,\n avatarSrc,\n showAvatarStatus = false,\n customStatusEmoji,\n onClick,\n onMenuClick,\n formatMentionLabel = defaultFormatMentions,\n unreadLabel = 'unread',\n menuLabel = 'Channel options',\n}: ChannelSidebarItemProps) {\n const isDM = !hideLeadingVisual && leadingVisual === 'direct-message';\n const isDrafts = !hideLeadingVisual && leadingVisual === 'drafts';\n const effectiveStatus = isDrafts && status === 'unread' ? 'read' : status;\n const hasMentionBadge = effectiveStatus === 'mention';\n const isChannelOrDM =\n !hideLeadingVisual &&\n ['public', 'private', 'group-message', 'direct-message'].includes(\n leadingVisual,\n );\n\n const rootClass = [\n styles['channel-sidebar-item'],\n hideLeadingVisual ? styles['channel-sidebar-item--text-only'] : '',\n active ? styles['channel-sidebar-item--active'] : '',\n muted ? styles['channel-sidebar-item--muted'] : '',\n styles[`channel-sidebar-item--status-${effectiveStatus.toLowerCase()}`],\n isDrafts ? styles['channel-sidebar-item--drafts'] : '',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const iconContainerClass = [\n styles['channel-sidebar-item__icon-container'],\n isDM ? styles['channel-sidebar-item__icon-container--dm'] : '',\n ]\n .filter(Boolean)\n .join(' ');\n\n const rightClass = styles['channel-sidebar-item__right'];\n\n const statusHint =\n effectiveStatus === 'mention'\n ? formatMentionLabel(mentionCount ?? 1)\n : effectiveStatus === 'unread'\n ? unreadLabel\n : undefined;\n\n return (\n <div className={rootClass}>\n {active && (\n <div className={styles['channel-sidebar-item__active-border']} />\n )}\n <button\n type=\"button\"\n className={styles['channel-sidebar-item__left']}\n onClick={onClick}\n aria-current={active ? true : undefined}\n >\n {!hideLeadingVisual && (\n <div className={iconContainerClass} aria-hidden>\n <LeadingVisualContent\n leadingVisual={leadingVisual}\n memberCount={memberCount}\n avatarSrc={avatarSrc}\n showAvatarStatus={showAvatarStatus}\n />\n </div>\n )}\n <div className={styles['channel-sidebar-item__content']}>\n <span className={styles['channel-sidebar-item__name']}>{name}</span>\n {statusHint && (\n <span className={styles['channel-sidebar-item__status-hint']}>\n {statusHint}\n </span>\n )}\n {sharedChannel && (\n <span\n className={styles['channel-sidebar-item__shared-icon']}\n aria-hidden\n >\n <CircleMultipleOutlineIcon size={12} />\n </span>\n )}\n {isDM && customStatusEmoji && (\n <span\n className={styles['channel-sidebar-item__custom-status']}\n aria-hidden\n >\n {customStatusEmoji}\n </span>\n )}\n </div>\n </button>\n <div className={rightClass}>\n {callActive && (\n <div className={styles['channel-sidebar-item__call']} aria-hidden>\n <PhoneInTalkIcon size={12} />\n </div>\n )}\n {hasMentionBadge && (\n <span\n className={styles['channel-sidebar-item__mention-badge']}\n aria-hidden\n >\n <MentionBadge\n count={mentionCount ?? 1}\n location=\"sidebar\"\n size=\"medium\"\n />\n </span>\n )}\n {isChannelOrDM && (\n <span className={styles['channel-sidebar-item__menu-button']}>\n <IconButton\n className={styles['channel-sidebar-item__menu-icon']}\n size=\"x-small\"\n style=\"inverted\"\n icon={<DotsVerticalIcon size={12} />}\n aria-label={menuLabel}\n onClick={(e) => {\n e.stopPropagation();\n onMenuClick?.(e);\n }}\n />\n </span>\n )}\n </div>\n </div>\n );\n}\n"],"names":["defaultFormatMentions","count","LeadingVisualContent","leadingVisual","memberCount","avatarSrc","showAvatarStatus","jsx","LockOutlineIcon","styles","UserAvatar","SendOutlineIcon","ChartLineIcon","MessageTextOutlineIcon","DialpadIcon","GlobeIcon","ChannelSidebarItem","className","name","hideLeadingVisual","status","active","muted","callActive","sharedChannel","mentionCount","customStatusEmoji","onClick","onMenuClick","formatMentionLabel","unreadLabel","menuLabel","isDM","isDrafts","effectiveStatus","hasMentionBadge","isChannelOrDM","rootClass","iconContainerClass","rightClass","statusHint","jsxs","CircleMultipleOutlineIcon","PhoneInTalkIcon","MentionBadge","IconButton","DotsVerticalIcon","e"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ChannelSidebarItem.js","sources":["../../../src/components/channel-sidebar-item/ChannelSidebarItem.tsx"],"sourcesContent":["import type { MouseEvent, ReactNode } from 'react';\nimport GlobeIcon from '@mattermost/compass-icons/components/globe';\nimport LockOutlineIcon from '@mattermost/compass-icons/components/lock-outline';\nimport MessageTextOutlineIcon from '@mattermost/compass-icons/components/message-text-outline';\nimport SendOutlineIcon from '@mattermost/compass-icons/components/send-outline';\nimport ChartLineIcon from '@mattermost/compass-icons/components/chart-line';\nimport CircleMultipleOutlineIcon from '@mattermost/compass-icons/components/circle-multiple-outline';\nimport PhoneInTalkIcon from '@mattermost/compass-icons/components/phone-in-talk';\nimport DotsVerticalIcon from '@mattermost/compass-icons/components/dots-vertical';\nimport DialpadIcon from '@mattermost/compass-icons/components/dialpad';\nimport UserAvatar from '@/components/user-avatar/UserAvatar';\nimport MentionBadge from '@/components/mention-badge/MentionBadge';\nimport Icon from '@/components/icon/Icon';\nimport IconButton from '@/components/icon-button/IconButton';\nimport styles from './ChannelSidebarItem.module.scss';\n\nexport type ChannelSidebarItemLeadingVisual =\n | 'public'\n | 'private'\n | 'group-message'\n | 'direct-message'\n | 'drafts'\n | 'insights'\n | 'threads'\n | 'dial-pad';\n\nexport type ChannelSidebarItemStatus = 'read' | 'unread' | 'mention';\n\nexport interface ChannelSidebarItemProps {\n className?: string;\n /** Channel or user display name. Accepts translated nodes. */\n name: ReactNode;\n /**\n * Text-only row (e.g. System Console navigation): no channel glyph or\n * overflow menu; name aligns with channel sidebar label padding.\n */\n hideLeadingVisual?: boolean;\n /** Leading visual type. Default: Public. Ignored when `hideLeadingVisual`. */\n leadingVisual?: ChannelSidebarItemLeadingVisual;\n /** Read/unread/mention state. Default: Read. */\n status?: ChannelSidebarItemStatus;\n /** Highlighted as the currently active item. */\n active?: boolean;\n /** Muted channel — reduces visual prominence. */\n muted?: boolean;\n /** Shows a call-in-progress indicator on the right. */\n callActive?: boolean;\n /** Shows the shared-channel icon after the name. */\n sharedChannel?: boolean;\n /** Mention count shown in the badge when status='mention'. */\n mentionCount?: number;\n /** Member count shown in the group icon when leadingVisual='group-message'. */\n memberCount?: number;\n /** Avatar image URL for leadingVisual='direct-message'. */\n avatarSrc?: string;\n /** Avatar alt text for leadingVisual='direct-message'. */\n avatarAlt?: string;\n /** Shows status badge on the avatar when leadingVisual='direct-message'. */\n showAvatarStatus?: boolean;\n /** Custom status emoji shown after the name for leadingVisual='direct-message'. */\n customStatusEmoji?: string;\n onClick?: () => void;\n /** Overflow menu (kebab). Sibling of the channel control so it is keyboard-reachable. */\n onMenuClick?: (event: MouseEvent<HTMLButtonElement>) => void;\n /** Visually hidden mention hint. Default: `{count} mention(s)`. */\n formatMentionLabel?: (count: number) => ReactNode;\n /** Visually hidden unread hint. Default: \"unread\". */\n unreadLabel?: ReactNode;\n /** Accessible name for the overflow menu button. Default: \"Channel options\". */\n menuLabel?: string;\n}\n\nconst defaultFormatMentions = (count: number) =>\n `${count} mention${count === 1 ? '' : 's'}`;\n\nfunction LeadingVisualContent({\n leadingVisual,\n memberCount,\n avatarSrc,\n showAvatarStatus,\n}: {\n leadingVisual: ChannelSidebarItemLeadingVisual;\n memberCount: number | undefined;\n avatarSrc: string | undefined;\n showAvatarStatus: boolean | undefined;\n}) {\n switch (leadingVisual) {\n case 'private':\n return <LockOutlineIcon size={16} />;\n case 'group-message':\n return (\n <div className={styles['channel-sidebar-item__group-icon']}>\n {memberCount ?? 2}\n </div>\n );\n case 'direct-message':\n return (\n <UserAvatar\n src={avatarSrc ?? ''}\n alt=\"\"\n size=\"20\"\n status={!!showAvatarStatus}\n />\n );\n case 'drafts':\n return <SendOutlineIcon size={16} />;\n case 'insights':\n return <ChartLineIcon size={16} />;\n case 'threads':\n return <MessageTextOutlineIcon size={16} />;\n case 'dial-pad':\n return <DialpadIcon size={16} />;\n case 'public':\n default:\n return <GlobeIcon size={16} />;\n }\n}\n\n/**\n * The Channel Sidebar Item is the row people use to move between channels, DMs, and group\n * messages. It compresses a lot of state — channel type, unread, mention count, mute,\n * in-call — into a single, scannable line.\n */\nexport default function ChannelSidebarItem({\n className,\n name,\n hideLeadingVisual = false,\n leadingVisual = 'public',\n status = 'read',\n active = false,\n muted = false,\n callActive = false,\n sharedChannel = false,\n mentionCount,\n memberCount,\n avatarSrc,\n showAvatarStatus = false,\n customStatusEmoji,\n onClick,\n onMenuClick,\n formatMentionLabel = defaultFormatMentions,\n unreadLabel = 'unread',\n menuLabel = 'Channel options',\n}: ChannelSidebarItemProps) {\n const isDM = !hideLeadingVisual && leadingVisual === 'direct-message';\n const isDrafts = !hideLeadingVisual && leadingVisual === 'drafts';\n const effectiveStatus = isDrafts && status === 'unread' ? 'read' : status;\n const hasMentionBadge = effectiveStatus === 'mention';\n const isChannelOrDM =\n !hideLeadingVisual &&\n ['public', 'private', 'group-message', 'direct-message'].includes(\n leadingVisual,\n );\n\n const rootClass = [\n styles['channel-sidebar-item'],\n hideLeadingVisual ? styles['channel-sidebar-item--text-only'] : '',\n active ? styles['channel-sidebar-item--active'] : '',\n muted ? styles['channel-sidebar-item--muted'] : '',\n styles[`channel-sidebar-item--status-${effectiveStatus.toLowerCase()}`],\n isDrafts ? styles['channel-sidebar-item--drafts'] : '',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const iconContainerClass = [\n styles['channel-sidebar-item__icon-container'],\n isDM ? styles['channel-sidebar-item__icon-container--dm'] : '',\n ]\n .filter(Boolean)\n .join(' ');\n\n const rightClass = styles['channel-sidebar-item__right'];\n\n const statusHint =\n effectiveStatus === 'mention'\n ? formatMentionLabel(mentionCount ?? 1)\n : effectiveStatus === 'unread'\n ? unreadLabel\n : undefined;\n\n return (\n <div className={rootClass}>\n {active && (\n <div className={styles['channel-sidebar-item__active-border']} />\n )}\n <button\n type=\"button\"\n className={styles['channel-sidebar-item__left']}\n onClick={onClick}\n aria-current={active ? true : undefined}\n >\n {!hideLeadingVisual && (\n <div className={iconContainerClass} aria-hidden>\n <LeadingVisualContent\n leadingVisual={leadingVisual}\n memberCount={memberCount}\n avatarSrc={avatarSrc}\n showAvatarStatus={showAvatarStatus}\n />\n </div>\n )}\n <div className={styles['channel-sidebar-item__content']}>\n <span className={styles['channel-sidebar-item__name']}>{name}</span>\n {statusHint && (\n <span className={styles['channel-sidebar-item__status-hint']}>\n {statusHint}\n </span>\n )}\n {sharedChannel && (\n <span\n className={styles['channel-sidebar-item__shared-icon']}\n aria-hidden\n >\n <CircleMultipleOutlineIcon size={12} />\n </span>\n )}\n {isDM && customStatusEmoji && (\n <span\n className={styles['channel-sidebar-item__custom-status']}\n aria-hidden\n >\n {customStatusEmoji}\n </span>\n )}\n </div>\n </button>\n <div className={rightClass}>\n {callActive && (\n <div className={styles['channel-sidebar-item__call']} aria-hidden>\n <PhoneInTalkIcon size={12} />\n </div>\n )}\n {hasMentionBadge && (\n <span\n className={styles['channel-sidebar-item__mention-badge']}\n aria-hidden\n >\n <MentionBadge\n count={mentionCount ?? 1}\n location=\"sidebar\"\n size=\"medium\"\n />\n </span>\n )}\n {isChannelOrDM && (\n <span className={styles['channel-sidebar-item__menu-button']}>\n <IconButton\n className={styles['channel-sidebar-item__menu-icon']}\n size=\"x-small\"\n style=\"inverted\"\n icon={<Icon glyph={<DotsVerticalIcon />} />}\n aria-label={menuLabel}\n onClick={(e) => {\n e.stopPropagation();\n onMenuClick?.(e);\n }}\n />\n </span>\n )}\n </div>\n </div>\n );\n}\n"],"names":["defaultFormatMentions","count","LeadingVisualContent","leadingVisual","memberCount","avatarSrc","showAvatarStatus","jsx","LockOutlineIcon","styles","UserAvatar","SendOutlineIcon","ChartLineIcon","MessageTextOutlineIcon","DialpadIcon","GlobeIcon","ChannelSidebarItem","className","name","hideLeadingVisual","status","active","muted","callActive","sharedChannel","mentionCount","customStatusEmoji","onClick","onMenuClick","formatMentionLabel","unreadLabel","menuLabel","isDM","isDrafts","effectiveStatus","hasMentionBadge","isChannelOrDM","rootClass","iconContainerClass","rightClass","statusHint","jsxs","CircleMultipleOutlineIcon","PhoneInTalkIcon","MentionBadge","IconButton","Icon","DotsVerticalIcon","e"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@keyframes _checkbox-icon-
|
|
1
|
+
@keyframes _checkbox-icon-enter_1rll8_1{0%{transform:scale(.5)}to{transform:scale(1)}}._checkbox_1rll8_10{position:relative;display:flex;align-items:flex-start;width:100%;gap:var(--spacing-s);font-family:var(--font-family-body);font-weight:var(--font-weight-regular);color:var(--center-channel-color);cursor:pointer;-webkit-user-select:none;user-select:none}._checkbox_1rll8_10:has(._checkbox__input_1rll8_22:disabled){cursor:not-allowed;color:rgba(var(--center-channel-color-rgb),.56)}._checkbox__input_1rll8_22{position:absolute;left:0;top:0;margin:0;padding:0;opacity:0;overflow:hidden;white-space:nowrap;border:0;cursor:inherit}._checkbox__input_1rll8_22:focus-visible{outline:none}._checkbox__box_1rll8_41{position:relative;flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;background-color:var(--center-channel-bg);border:1px solid rgba(var(--center-channel-color-rgb),.24);transition:background-color var(--duration-quick) var(--ease-transition),border-color var(--duration-quick) var(--ease-transition),box-shadow var(--duration-quick) var(--ease-transition)}._checkbox__input_1rll8_22:focus-visible~._checkbox__box_1rll8_41{box-shadow:0 0 0 2px rgba(var(--button-bg-rgb),.56)}._checkbox_1rll8_10:has(._checkbox__input_1rll8_22:not(:disabled)):hover ._checkbox__box_1rll8_41{border-color:rgba(var(--center-channel-color-rgb),.32)}._checkbox__input_1rll8_22:disabled~._checkbox__box_1rll8_41{background-color:var(--center-channel-bg);border-color:rgba(var(--center-channel-color-rgb),.16)}._checkbox__input_1rll8_22:checked~._checkbox__box_1rll8_41,._checkbox--indeterminate_1rll8_62 ._checkbox__box_1rll8_41{background-color:var(--button-bg);border-color:var(--button-bg)}._checkbox__input_1rll8_22:checked~._checkbox__box_1rll8_41 ._checkbox__icon_1rll8_66,._checkbox--indeterminate_1rll8_62 ._checkbox__box_1rll8_41 ._checkbox__icon_1rll8_66{color:var(--button-color)}._checkbox_1rll8_10:has(._checkbox__input_1rll8_22:not(:disabled)):hover ._checkbox__input_1rll8_22:checked~._checkbox__box_1rll8_41,._checkbox_1rll8_10:has(._checkbox__input_1rll8_22:not(:disabled)):hover._checkbox--indeterminate_1rll8_62 ._checkbox__box_1rll8_41{background-color:var(--button-bg);border-color:var(--button-bg)}._checkbox__input_1rll8_22:focus-visible:checked~._checkbox__box_1rll8_41,._checkbox--indeterminate_1rll8_62 ._checkbox__input_1rll8_22:focus-visible~._checkbox__box_1rll8_41{border-color:var(--button-bg);box-shadow:0 0 0 2px rgba(var(--button-bg-rgb),.56)}._checkbox__input_1rll8_22:disabled:checked~._checkbox__box_1rll8_41,._checkbox--indeterminate_1rll8_62 ._checkbox__input_1rll8_22:disabled~._checkbox__box_1rll8_41{background-color:rgba(var(--center-channel-color-rgb),.32);border-color:transparent}._checkbox__input_1rll8_22:disabled:checked~._checkbox__box_1rll8_41 ._checkbox__icon_1rll8_66,._checkbox--indeterminate_1rll8_62 ._checkbox__input_1rll8_22:disabled~._checkbox__box_1rll8_41 ._checkbox__icon_1rll8_66{color:var(--button-color)}._checkbox--invalid_1rll8_84 ._checkbox__box_1rll8_41{border-color:rgba(var(--error-text-color-rgb),.5)}._checkbox--invalid_1rll8_84 ._checkbox__input_1rll8_22:checked~._checkbox__box_1rll8_41,._checkbox--invalid_1rll8_84._checkbox--indeterminate_1rll8_62 ._checkbox__box_1rll8_41{background-color:var(--error-text);border-color:var(--error-text)}._checkbox--invalid_1rll8_84 ._checkbox__input_1rll8_22:checked~._checkbox__box_1rll8_41 ._checkbox__icon_1rll8_66,._checkbox--invalid_1rll8_84._checkbox--indeterminate_1rll8_62 ._checkbox__box_1rll8_41 ._checkbox__icon_1rll8_66{color:var(--button-color)}._checkbox_1rll8_10:has(._checkbox__input_1rll8_22:not(:disabled)):hover._checkbox--invalid_1rll8_84 ._checkbox__input_1rll8_22:checked~._checkbox__box_1rll8_41,._checkbox_1rll8_10:has(._checkbox__input_1rll8_22:not(:disabled)):hover._checkbox--invalid_1rll8_84._checkbox--indeterminate_1rll8_62 ._checkbox__box_1rll8_41{background-color:var(--error-text);border-color:var(--error-text)}._checkbox--invalid_1rll8_84 ._checkbox__input_1rll8_22:focus-visible~._checkbox__box_1rll8_41{box-shadow:0 0 0 2px var(--error-text)}._checkbox--invalid_1rll8_84 ._checkbox__input_1rll8_22:focus-visible:checked~._checkbox__box_1rll8_41,._checkbox--invalid_1rll8_84._checkbox--indeterminate_1rll8_62 ._checkbox__input_1rll8_22:focus-visible~._checkbox__box_1rll8_41{border-color:rgba(var(--button-color-rgb),.24);box-shadow:0 0 0 2px var(--error-text)}._checkbox_1rll8_10:has(._checkbox__input_1rll8_22:not(:disabled)):hover._checkbox--invalid_1rll8_84 ._checkbox__input_1rll8_22:not(:checked)~._checkbox__box_1rll8_41{border-color:var(--error-text)}._checkbox__icon_1rll8_66{display:inline-flex;align-items:center;justify-content:center;color:var(--button-color);pointer-events:none;transform-origin:center;animation:_checkbox-icon-enter_1rll8_1 var(--duration-quick) var(--ease-entrance) forwards}._checkbox__label_1rll8_117{line-height:1}._checkbox--size-small_1rll8_120 ._checkbox__input_1rll8_22{width:var(--icon-size-12);height:var(--icon-size-12);margin-top:calc((var(--line-height-75) - var(--icon-size-12)) / 2)}._checkbox--size-small_1rll8_120 ._checkbox__box_1rll8_41{width:var(--icon-size-12);height:var(--icon-size-12);border-radius:var(--radius-xs);margin-top:calc((var(--line-height-75) - var(--icon-size-12)) / 2)}._checkbox--size-small_1rll8_120 ._checkbox__label_1rll8_117{font-size:var(--font-size-75);line-height:var(--line-height-75)}._checkbox--size-medium_1rll8_135 ._checkbox__input_1rll8_22{width:var(--icon-size-16);height:var(--icon-size-16);margin-top:calc((var(--line-height-100) - var(--icon-size-16)) / 2)}._checkbox--size-medium_1rll8_135 ._checkbox__box_1rll8_41{width:var(--icon-size-16);height:var(--icon-size-16);border-radius:var(--radius-xs);margin-top:calc((var(--line-height-100) - var(--icon-size-16)) / 2)}._checkbox--size-medium_1rll8_135 ._checkbox__label_1rll8_117{font-size:var(--font-size-100);line-height:var(--line-height-100)}._checkbox--size-large_1rll8_150 ._checkbox__input_1rll8_22{width:var(--icon-size-20);height:var(--icon-size-20);margin-top:calc((var(--line-height-200) - var(--icon-size-20)) / 2)}._checkbox--size-large_1rll8_150 ._checkbox__box_1rll8_41{width:var(--icon-size-20);height:var(--icon-size-20);border-radius:var(--radius-s);margin-top:calc((var(--line-height-200) - var(--icon-size-20)) / 2)}._checkbox--size-large_1rll8_150 ._checkbox__label_1rll8_117{font-size:var(--font-size-200);line-height:var(--line-height-200)}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});require('./Checkbox.css');const c="
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});require('./Checkbox.css');const c="_checkbox_1rll8_10",e="_checkbox__input_1rll8_22",_="_checkbox__box_1rll8_41",o="_checkbox__icon_1rll8_66",l="_checkbox__label_1rll8_117",b={checkbox:c,checkbox__input:e,checkbox__box:_,"checkbox--indeterminate":"_checkbox--indeterminate_1rll8_62",checkbox__icon:o,"checkbox--invalid":"_checkbox--invalid_1rll8_84","checkbox-icon-enter":"_checkbox-icon-enter_1rll8_1",checkbox__label:l,"checkbox--size-small":"_checkbox--size-small_1rll8_120","checkbox--size-medium":"_checkbox--size-medium_1rll8_135","checkbox--size-large":"_checkbox--size-large_1rll8_150"};exports.checkbox=c;exports.checkbox__box=_;exports.checkbox__icon=o;exports.checkbox__input=e;exports.checkbox__label=l;exports.default=b;
|
|
2
2
|
//# sourceMappingURL=Checkbox.module.scss.cjs.map
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import './Checkbox.css';const c = "
|
|
1
|
+
import './Checkbox.css';const c = "_checkbox_1rll8_10", _ = "_checkbox__input_1rll8_22", e = "_checkbox__box_1rll8_41", o = "_checkbox__icon_1rll8_66", l = "_checkbox__label_1rll8_117", b = {
|
|
2
2
|
checkbox: c,
|
|
3
3
|
checkbox__input: _,
|
|
4
4
|
checkbox__box: e,
|
|
5
|
-
"checkbox--indeterminate": "_checkbox--
|
|
5
|
+
"checkbox--indeterminate": "_checkbox--indeterminate_1rll8_62",
|
|
6
6
|
checkbox__icon: o,
|
|
7
|
-
"checkbox--invalid": "_checkbox--
|
|
8
|
-
"checkbox-icon-enter": "_checkbox-icon-
|
|
9
|
-
checkbox__label:
|
|
10
|
-
"checkbox--size-small": "_checkbox--size-
|
|
11
|
-
"checkbox--size-medium": "_checkbox--size-
|
|
12
|
-
"checkbox--size-large": "_checkbox--size-
|
|
7
|
+
"checkbox--invalid": "_checkbox--invalid_1rll8_84",
|
|
8
|
+
"checkbox-icon-enter": "_checkbox-icon-enter_1rll8_1",
|
|
9
|
+
checkbox__label: l,
|
|
10
|
+
"checkbox--size-small": "_checkbox--size-small_1rll8_120",
|
|
11
|
+
"checkbox--size-medium": "_checkbox--size-medium_1rll8_135",
|
|
12
|
+
"checkbox--size-large": "_checkbox--size-large_1rll8_150"
|
|
13
13
|
};
|
|
14
14
|
export {
|
|
15
15
|
c as checkbox,
|
|
16
16
|
e as checkbox__box,
|
|
17
17
|
o as checkbox__icon,
|
|
18
18
|
_ as checkbox__input,
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
l as checkbox__label,
|
|
20
|
+
b as default
|
|
21
21
|
};
|
|
22
22
|
//# sourceMappingURL=Checkbox.module.scss.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const t=require("react/jsx-runtime"),V=require("react"),x=require("../icon/Icon.cjs"),j=require("../spinner/Spinner.cjs"),W=require("../../utils/slot.cjs"),X=require("../../utils/string.cjs"),e=require("./IconButton.module.scss.cjs"),b={"x-small":"12",small:"16",medium:"20",large:"24"};function I({className:m="",count:a,destructive:i=!1,padding:o="default",rounded:l=!1,size:n="medium",style:u="default",active:c=!1,toggled:s}){return[e.default["icon-button"],e.default[`icon-button--size-${X.toKebab(n)}`],o==="compact"?e.default["icon-button--padding-compact"]:"",u==="inverted"?e.default["icon-button--style-inverted"]:"",i?e.default["icon-button--destructive"]:"",l?e.default["icon-button--rounded"]:"",s?e.default["icon-button--toggled"]:"",c?e.default["icon-button--active"]:"",a!==void 0?e.default["icon-button--has-count"]:"",m].filter(Boolean).join(" ")}const B=V.forwardRef(function(a,i){if(a.asChild){const{active:h=!1,className:E="",count:f,destructive:L=!1,icon:M,loading:d=!1,padding:U="default",rounded:Z=!1,size:N="medium",style:C="default",unreadBadge:A=!1,disabled:F,children:K,"aria-label":$,asChild:ee,...k}=a,G=I({className:E,count:f,destructive:L,padding:U,rounded:Z,size:N,style:C,active:h}),p=b[N],H=!!(F||d),J=f!==void 0,Q=t.jsxs(t.Fragment,{children:[t.jsxs("span",{className:e.default["icon-button__icon-slot"],"aria-hidden":!0,children:[d?t.jsx(j.default,{size:p,inverted:C==="inverted"}):t.jsx(x.IconSlotContext.Provider,{value:{size:p},children:M}),A&&!d&&t.jsx("span",{className:e.default["icon-button__unread-badge"]})]}),J&&t.jsx("span",{className:e.default["icon-button__count"],children:f})]});return W.renderAsChild({child:K,props:{...k,className:G,"aria-label":$,"data-active":h?"true":void 0,...d?{"aria-busy":!0}:null},ref:i,content:Q,disabled:H,disabledClassName:e.default["icon-button--disabled"],warnOnChildContent:!0})}const{active:o=!1,className:l="",count:n,destructive:u=!1,icon:c,loading:s=!1,padding:z="default",rounded:S=!1,size:v="medium",style:g="default",toggled:r,unreadBadge:y=!1,disabled:O,type:q="button","aria-label":T,asChild:Y,...R}=a,P=I({className:l,count:n,destructive:u,padding:z,rounded:S,size:v,style:g,active:o,toggled:r}),_=b[v],w=!!(O||s),D=n!==void 0;return t.jsxs("button",{ref:i,className:P,type:q,disabled:w,"aria-label":T,"aria-pressed":r===void 0?void 0:r,"data-active":o?"true":void 0,...R,children:[t.jsxs("span",{className:e.default["icon-button__icon-slot"],"aria-hidden":!0,children:[s?t.jsx(j.default,{size:_,inverted:g==="inverted"}):t.jsx(x.IconSlotContext.Provider,{value:{size:_},children:c}),y&&!s&&t.jsx("span",{className:e.default["icon-button__unread-badge"]})]}),D&&t.jsx("span",{className:e.default["icon-button__count"],children:n})]})});B.displayName="IconButton";exports.ICON_BUTTON_ICON_SIZES=b;exports.default=B;
|
|
2
2
|
//# sourceMappingURL=IconButton.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IconButton.cjs","sources":["../../../src/components/icon-button/IconButton.tsx"],"sourcesContent":["import { forwardRef, type ButtonHTMLAttributes, type ReactNode } from 'react';\nimport { IconSlotContext } from '@/components/icon/Icon';\nimport Spinner from '@/components/spinner/Spinner';\nimport { toKebab } from '@/utils/string';\nimport styles from './IconButton.module.scss';\n\nexport type IconButtonSize = 'x-small' | 'small' | 'medium' | 'large';\n\n/** Figma \"Style\": Default (light context) | Inverted (dark context). */\nexport type IconButtonStyle = 'default' | 'inverted';\n\nexport type IconButtonPadding = 'default' | 'compact';\n\nexport interface IconButtonProps extends Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n 'style'\n> {\n /** When true, forces the subtler pressed/active visual (lighter than toggled). */\n active?: boolean;\n /** Optional CSS class name. */\n className?: string;\n /** Numeric count shown inline after the icon. Figma: Count. */\n count?: number;\n /** When true, uses destructive (danger) styling. Figma: Destructive. */\n destructive?: boolean;\n /** Icon to show. Pass `<Icon glyph={<YourIcon />} />` — IconButton provides the correct size via context; no `size` prop needed on the Icon. */\n icon: ReactNode;\n /** When true, shows a Spinner in place of the icon and disables the button. */\n loading?: boolean;\n /** Padding variant. Figma: Padding = Default | Compact. */\n padding?: IconButtonPadding;\n /** When true, uses full border radius (pill). Figma: Rounded = On. */\n rounded?: boolean;\n /** Size variant. Figma: Size. Default: Medium. */\n size?: IconButtonSize;\n /** Default | Inverted. Figma: Style (for light vs dark backgrounds). */\n style?: IconButtonStyle;\n /** When true, shows toggled/selected state. Figma: Toggled = On. When omitted, the control is not a toggle. */\n toggled?: boolean;\n /** When true, shows a small unread dot over the icon. Figma: Unread Badge. */\n unreadBadge?: boolean;\n}\n\n/**\n * @deprecated No longer needed — IconButton sets the icon size via context.\n * Pass `<Icon glyph={<YourIcon />} />` without a size prop.\n */\nexport const ICON_BUTTON_ICON_SIZES: Record<\n IconButtonSize,\n '12' | '16' | '20' | '24'\n> = {\n 'x-small': '12',\n small: '16',\n medium: '20',\n large: '24',\n};\n\n/**\n * Icon Buttons are compact, label-free actions for tight surfaces — channel headers, message\n * hover actions, modal dismissals, toolbar slots. They lean on the icon to communicate\n * intent, so every Icon Button must pair with a tooltip or `aria-label` that makes the\n * action explicit.\n */\nconst IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(\n function IconButton(\n {\n active = false,\n className = '',\n count,\n destructive = false,\n icon,\n loading = false,\n padding = 'default',\n rounded = false,\n size = 'medium',\n style = 'default',\n toggled,\n unreadBadge = false,\n disabled,\n type = 'button',\n 'aria-label': ariaLabel,\n ...rest\n },\n ref,\n ) {\n const sizeClass = styles[`icon-button--size-${toKebab(size)}`];\n const paddingClass =\n padding === 'compact' ? styles['icon-button--padding-compact'] : '';\n const styleClass =\n style === 'inverted' ? styles['icon-button--style-inverted'] : '';\n const destructiveClass = destructive\n ? styles['icon-button--destructive']\n : '';\n const roundedClass = rounded ? styles['icon-button--rounded'] : '';\n const toggledClass = toggled ? styles['icon-button--toggled'] : '';\n const activeClass = active ? styles['icon-button--active'] : '';\n const hasCount = count !== undefined;\n const hasCountClass = hasCount ? styles['icon-button--has-count'] : '';\n\n const rootClass = [\n styles['icon-button'],\n sizeClass,\n paddingClass,\n styleClass,\n destructiveClass,\n roundedClass,\n toggledClass,\n activeClass,\n hasCountClass,\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const spinnerSize = ICON_BUTTON_ICON_SIZES[size];\n\n return (\n <button\n ref={ref}\n className={rootClass}\n type={type}\n disabled={disabled || loading}\n aria-label={ariaLabel}\n aria-pressed={toggled === undefined ? undefined : toggled}\n data-active={active ? 'true' : undefined}\n {...rest}\n >\n <span className={styles['icon-button__icon-slot']} aria-hidden>\n {loading ? (\n <Spinner size={spinnerSize} inverted={style === 'inverted'} />\n ) : (\n <IconSlotContext.Provider value={{ size: spinnerSize }}>\n {icon}\n </IconSlotContext.Provider>\n )}\n {unreadBadge && !loading && (\n <span className={styles['icon-button__unread-badge']} />\n )}\n </span>\n {hasCount && (\n <span className={styles['icon-button__count']}>{count}</span>\n )}\n </button>\n );\n },\n);\n\nIconButton.displayName = 'IconButton';\n\nexport default IconButton;\n"],"names":["ICON_BUTTON_ICON_SIZES","IconButton","forwardRef","active","className","count","destructive","icon","loading","padding","rounded","size","style","toggled","unreadBadge","disabled","type","ariaLabel","rest","ref","sizeClass","styles","toKebab","paddingClass","styleClass","destructiveClass","roundedClass","toggledClass","activeClass","hasCount","hasCountClass","rootClass","spinnerSize","jsxs","Spinner","jsx","IconSlotContext"],"mappings":"oTA+CaA,EAGT,CACF,UAAW,KACX,MAAO,KACP,OAAQ,KACR,MAAO,IACT,EAQMC,EAAaC,EAAAA,WACjB,SACE,CACE,OAAAC,EAAS,GACT,UAAAC,EAAY,GACZ,MAAAC,EACA,YAAAC,EAAc,GACd,KAAAC,EACA,QAAAC,EAAU,GACV,QAAAC,EAAU,UACV,QAAAC,EAAU,GACV,KAAAC,EAAO,SACP,MAAAC,EAAQ,UACR,QAAAC,EACA,YAAAC,EAAc,GACd,SAAAC,EACA,KAAAC,EAAO,SACP,aAAcC,EACd,GAAGC,CAAA,EAELC,EACA,CACA,MAAMC,EAAYC,EAAAA,QAAO,qBAAqBC,EAAAA,QAAQX,CAAI,CAAC,EAAE,EACvDY,EACJd,IAAY,UAAYY,EAAAA,QAAO,8BAA8B,EAAI,GAC7DG,EACJZ,IAAU,WAAaS,EAAAA,QAAO,6BAA6B,EAAI,GAC3DI,EAAmBnB,EACrBe,UAAO,0BAA0B,EACjC,GACEK,EAAehB,EAAUW,UAAO,sBAAsB,EAAI,GAC1DM,EAAed,EAAUQ,UAAO,sBAAsB,EAAI,GAC1DO,EAAczB,EAASkB,UAAO,qBAAqB,EAAI,GACvDQ,EAAWxB,IAAU,OACrByB,EAAgBD,EAAWR,UAAO,wBAAwB,EAAI,GAE9DU,EAAY,CAChBV,EAAAA,QAAO,aAAa,EACpBD,EACAG,EACAC,EACAC,EACAC,EACAC,EACAC,EACAE,EACA1B,CAAA,EAEC,OAAO,OAAO,EACd,KAAK,GAAG,EAEL4B,EAAchC,EAAuBW,CAAI,EAE/C,OACEsB,EAAAA,KAAC,SAAA,CACC,IAAAd,EACA,UAAWY,EACX,KAAAf,EACA,SAAUD,GAAYP,EACtB,aAAYS,EACZ,eAAcJ,IAAY,OAAY,OAAYA,EAClD,cAAaV,EAAS,OAAS,OAC9B,GAAGe,EAEJ,SAAA,CAAAe,OAAC,QAAK,UAAWZ,EAAAA,QAAO,wBAAwB,EAAG,cAAW,GAC3D,SAAA,CAAAb,QACE0B,EAAAA,QAAA,CAAQ,KAAMF,EAAa,SAAUpB,IAAU,WAAY,EAE5DuB,EAAAA,IAACC,kBAAgB,SAAhB,CAAyB,MAAO,CAAE,KAAMJ,CAAA,EACtC,SAAAzB,EACH,EAEDO,GAAe,CAACN,GACf2B,MAAC,QAAK,UAAWd,EAAAA,QAAO,2BAA2B,CAAA,CAAG,CAAA,EAE1D,EACCQ,GACCM,EAAAA,IAAC,OAAA,CAAK,UAAWd,EAAAA,QAAO,oBAAoB,EAAI,SAAAhB,CAAA,CAAM,CAAA,CAAA,CAAA,CAI9D,CACF,EAEAJ,EAAW,YAAc"}
|
|
1
|
+
{"version":3,"file":"IconButton.cjs","sources":["../../../src/components/icon-button/IconButton.tsx"],"sourcesContent":["import {\n forwardRef,\n type ButtonHTMLAttributes,\n type HTMLAttributes,\n type ReactElement,\n type ReactNode,\n type Ref,\n type RefAttributes,\n} from 'react';\nimport { IconSlotContext } from '@/components/icon/Icon';\nimport Spinner from '@/components/spinner/Spinner';\nimport { renderAsChild } from '@/utils/slot';\nimport { toKebab } from '@/utils/string';\nimport styles from './IconButton.module.scss';\n\nexport type IconButtonSize = 'x-small' | 'small' | 'medium' | 'large';\n\n/** Figma \"Style\": Default (light context) | Inverted (dark context). */\nexport type IconButtonStyle = 'default' | 'inverted';\n\nexport type IconButtonPadding = 'default' | 'compact';\n\ninterface IconButtonOwnProps {\n /** When true, forces the subtler pressed/active visual (lighter than toggled). */\n active?: boolean;\n /** Optional CSS class name. */\n className?: string;\n /** Numeric count shown inline after the icon. Figma: Count. */\n count?: number;\n /** When true, uses destructive (danger) styling. Figma: Destructive. */\n destructive?: boolean;\n /** Icon to show. Pass `<Icon glyph={<YourIcon />} />` — IconButton provides the correct size via context; no `size` prop needed on the Icon. */\n icon: ReactNode;\n /** When true, shows a Spinner in place of the icon and disables the button (or blocks navigation when `asChild`). */\n loading?: boolean;\n /** Padding variant. Figma: Padding = Default | Compact. */\n padding?: IconButtonPadding;\n /** When true, uses full border radius (pill). Figma: Rounded = On. */\n rounded?: boolean;\n /** Size variant. Figma: Size. Default: Medium. */\n size?: IconButtonSize;\n /** Default | Inverted. Figma: Style (for light vs dark backgrounds). Replaces the HTML `style` attribute. */\n style?: IconButtonStyle;\n /** When true, shows a small unread dot over the icon. Figma: Unread Badge. */\n unreadBadge?: boolean;\n /**\n * When true, disables the control. On a native `<button>`, sets the `disabled`\n * attribute. With `asChild`, sets `aria-disabled`, applies disabled styles, and\n * blocks click / middle-click navigation (the link stays focusable).\n */\n disabled?: boolean;\n}\n\nexport interface IconButtonProps\n extends\n IconButtonOwnProps,\n Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'style'> {\n /**\n * When true, merges IconButton props onto the single child element instead of\n * rendering a `<button>`. Use with `<a>` or a router `Link`. Default: false.\n */\n asChild?: false;\n /**\n * When true, shows toggled/selected state. Figma: Toggled = On. When omitted,\n * the control is not a toggle. Only applies to the native `<button>` (maps to\n * `aria-pressed`); not available with `asChild`.\n */\n toggled?: boolean;\n}\n\nexport interface IconButtonAsChildProps\n extends\n IconButtonOwnProps,\n Omit<HTMLAttributes<HTMLElement>, 'children' | 'color' | 'style'> {\n /**\n * Merges IconButton props onto the single child element instead of rendering a\n * `<button>`. The child's own props (`href`, `to`, `target`, …) stay on the\n * child. Do not pass `type` or `toggled` — they are not available on links.\n * Pass an empty child; IconButton supplies the icon anatomy.\n */\n asChild: true;\n /** Single empty element to render as the IconButton (e.g. `<a href=\"…\" />`). */\n children: ReactElement;\n /**\n * Accessible name for the icon-only link. Required with `asChild`. An\n * `aria-label` on the child also satisfies this (child props win).\n */\n 'aria-label': string;\n}\n\n/**\n * @deprecated No longer needed — IconButton sets the icon size via context.\n * Pass `<Icon glyph={<YourIcon />} />` without a size prop.\n */\nexport const ICON_BUTTON_ICON_SIZES: Record<\n IconButtonSize,\n '12' | '16' | '20' | '24'\n> = {\n 'x-small': '12',\n small: '16',\n medium: '20',\n large: '24',\n};\n\ntype IconButtonComponent = {\n (\n props: IconButtonAsChildProps & RefAttributes<HTMLElement>,\n ): ReactElement | null;\n (\n props: IconButtonProps & RefAttributes<HTMLButtonElement>,\n ): ReactElement | null;\n displayName?: string;\n};\n\nfunction buildRootClass({\n className = '',\n count,\n destructive = false,\n padding = 'default',\n rounded = false,\n size = 'medium',\n style = 'default',\n active = false,\n toggled,\n}: {\n className?: string;\n count?: number;\n destructive?: boolean;\n padding?: IconButtonPadding;\n rounded?: boolean;\n size?: IconButtonSize;\n style?: IconButtonStyle;\n active?: boolean;\n toggled?: boolean;\n}): string {\n return [\n styles['icon-button'],\n styles[`icon-button--size-${toKebab(size)}`],\n padding === 'compact' ? styles['icon-button--padding-compact'] : '',\n style === 'inverted' ? styles['icon-button--style-inverted'] : '',\n destructive ? styles['icon-button--destructive'] : '',\n rounded ? styles['icon-button--rounded'] : '',\n toggled ? styles['icon-button--toggled'] : '',\n active ? styles['icon-button--active'] : '',\n count !== undefined ? styles['icon-button--has-count'] : '',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n}\n\n/**\n * Icon Buttons are compact, label-free actions for tight surfaces — channel headers, message\n * hover actions, modal dismissals, toolbar slots. They lean on the icon to communicate\n * intent, so every Icon Button must pair with a tooltip or `aria-label` that makes the\n * action explicit.\n *\n * Pass `asChild` with a single empty `<a>` or router `Link` child to render a navigational\n * icon control with Icon Button styling (no nested `<button>`).\n */\nconst IconButton = forwardRef(function IconButton(\n props: IconButtonProps | IconButtonAsChildProps,\n ref: Ref<HTMLButtonElement | HTMLElement>,\n) {\n if (props.asChild) {\n const {\n active = false,\n className = '',\n count,\n destructive = false,\n icon,\n loading = false,\n padding = 'default',\n rounded = false,\n size = 'medium',\n style = 'default',\n unreadBadge = false,\n disabled,\n children,\n 'aria-label': ariaLabel,\n asChild,\n ...rest\n } = props;\n void asChild;\n\n const rootClass = buildRootClass({\n className,\n count,\n destructive,\n padding,\n rounded,\n size,\n style,\n active,\n });\n const spinnerSize = ICON_BUTTON_ICON_SIZES[size];\n const isDisabled = Boolean(disabled || loading);\n const hasCount = count !== undefined;\n\n const anatomy = (\n <>\n <span className={styles['icon-button__icon-slot']} aria-hidden>\n {loading ? (\n <Spinner size={spinnerSize} inverted={style === 'inverted'} />\n ) : (\n <IconSlotContext.Provider value={{ size: spinnerSize }}>\n {icon}\n </IconSlotContext.Provider>\n )}\n {unreadBadge && !loading && (\n <span className={styles['icon-button__unread-badge']} />\n )}\n </span>\n {hasCount && (\n <span className={styles['icon-button__count']}>{count}</span>\n )}\n </>\n );\n\n return renderAsChild({\n child: children,\n props: {\n ...rest,\n className: rootClass,\n 'aria-label': ariaLabel,\n 'data-active': active ? 'true' : undefined,\n ...(loading ? { 'aria-busy': true } : null),\n },\n ref,\n content: anatomy,\n disabled: isDisabled,\n disabledClassName: styles['icon-button--disabled'],\n warnOnChildContent: true,\n });\n }\n\n const {\n active = false,\n className = '',\n count,\n destructive = false,\n icon,\n loading = false,\n padding = 'default',\n rounded = false,\n size = 'medium',\n style = 'default',\n toggled,\n unreadBadge = false,\n disabled,\n type = 'button',\n 'aria-label': ariaLabel,\n asChild,\n ...rest\n } = props;\n void asChild;\n\n const rootClass = buildRootClass({\n className,\n count,\n destructive,\n padding,\n rounded,\n size,\n style,\n active,\n toggled,\n });\n const spinnerSize = ICON_BUTTON_ICON_SIZES[size];\n const isDisabled = Boolean(disabled || loading);\n const hasCount = count !== undefined;\n\n return (\n <button\n ref={ref as Ref<HTMLButtonElement>}\n className={rootClass}\n type={type}\n disabled={isDisabled}\n aria-label={ariaLabel}\n aria-pressed={toggled === undefined ? undefined : toggled}\n data-active={active ? 'true' : undefined}\n {...rest}\n >\n <span className={styles['icon-button__icon-slot']} aria-hidden>\n {loading ? (\n <Spinner size={spinnerSize} inverted={style === 'inverted'} />\n ) : (\n <IconSlotContext.Provider value={{ size: spinnerSize }}>\n {icon}\n </IconSlotContext.Provider>\n )}\n {unreadBadge && !loading && (\n <span className={styles['icon-button__unread-badge']} />\n )}\n </span>\n {hasCount && (\n <span className={styles['icon-button__count']}>{count}</span>\n )}\n </button>\n );\n}) as IconButtonComponent;\n\nIconButton.displayName = 'IconButton';\n\nexport default IconButton;\n"],"names":["ICON_BUTTON_ICON_SIZES","buildRootClass","className","count","destructive","padding","rounded","size","style","active","toggled","styles","toKebab","IconButton","forwardRef","props","ref","icon","loading","unreadBadge","disabled","children","ariaLabel","asChild","rest","rootClass","spinnerSize","isDisabled","hasCount","anatomy","jsxs","Fragment","jsx","Spinner","IconSlotContext","renderAsChild","type"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
._icon-
|
|
1
|
+
._icon-button_13ryy_2{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;font-family:var(--font-family-body);border-radius:var(--radius-s);border:0;cursor:pointer;text-decoration:none;transition:background-color var(--duration-quick) var(--ease-transition),color var(--duration-quick) var(--ease-transition),outline-color var(--duration-quick) var(--ease-transition),outline-offset var(--duration-quick) var(--ease-transition);background-color:transparent;--icon-button-fg: rgba(var(--center-channel-color-rgb), .64);color:var(--icon-button-fg);outline:2px solid color-mix(in srgb,var(--focus-ring-color) 0%,transparent);outline-offset:0}._icon-button_13ryy_2:any-link,._icon-button_13ryy_2:hover,._icon-button_13ryy_2:focus,._icon-button_13ryy_2:active,._icon-button_13ryy_2:visited{color:var(--icon-button-fg);text-decoration:none}._icon-button_13ryy_2:focus-visible{outline-color:var(--focus-ring-color);outline-offset:3px}._icon-button_13ryy_2:is(:disabled,._icon-button--disabled_13ryy_27){cursor:not-allowed;opacity:.5}._icon-button_13ryy_2:hover:not(:disabled,._icon-button--disabled_13ryy_27):not(:active):not(._icon-button--active_13ryy_31):not(._icon-button--toggled_13ryy_31){background-color:rgba(var(--center-channel-color-rgb),.08);--icon-button-fg: rgba(var(--center-channel-color-rgb), .75);color:rgba(var(--center-channel-color-rgb),.75)}._icon-button_13ryy_2:active:not(:disabled,._icon-button--disabled_13ryy_27):not(._icon-button--toggled_13ryy_31){background-color:rgba(var(--button-bg-rgb),.08);--icon-button-fg: var(--link-color);color:var(--link-color)}._icon-button__icon-slot_13ryy_41{position:relative;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}._icon-button__unread-badge_13ryy_48{position:absolute;top:-1px;right:-1px;width:6px;height:6px;border-radius:var(--radius-pill);background-color:var(--sidebar-text-active-border);box-shadow:0 0 0 2px var(--center-channel-bg);pointer-events:none}._icon-button__count_13ryy_59{font-weight:var(--font-weight-semibold);color:inherit}._icon-button--size-x-small_13ryy_63{width:24px;height:24px;padding:var(--spacing-xxs)}._icon-button--size-x-small_13ryy_63 ._icon-button__count_13ryy_59{font-size:var(--font-size-75);line-height:12px}._icon-button--size-x-small_13ryy_63._icon-button--padding-compact_13ryy_72{width:20px;height:20px;padding:var(--spacing-xxxs)}._icon-button--size-small_13ryy_77{width:32px;height:32px;padding:var(--spacing-xs)}._icon-button--size-small_13ryy_77 ._icon-button__count_13ryy_59{font-size:var(--font-size-100);line-height:14px}._icon-button--size-small_13ryy_77._icon-button--padding-compact_13ryy_72{width:28px;height:28px;padding:var(--spacing-xxs)}._icon-button--size-medium_13ryy_91{width:40px;height:40px;padding:var(--spacing-s)}._icon-button--size-medium_13ryy_91 ._icon-button__count_13ryy_59{font-size:var(--font-size-200);line-height:16px}._icon-button--size-medium_13ryy_91._icon-button--padding-compact_13ryy_72{width:36px;height:36px;padding:var(--spacing-xs)}._icon-button--size-large_13ryy_105{width:48px;height:48px;padding:var(--spacing-m)}._icon-button--size-large_13ryy_105 ._icon-button__count_13ryy_59{font-size:var(--font-size-300);line-height:18px}._icon-button--size-large_13ryy_105._icon-button--padding-compact_13ryy_72{width:44px;height:44px;padding:var(--spacing-s)}._icon-button--has-count_13ryy_119{width:auto;gap:var(--spacing-xxxs)}._icon-button--rounded_13ryy_123{border-radius:var(--radius-pill)}._icon-button--active_13ryy_31:not(:disabled,._icon-button--disabled_13ryy_27){background-color:rgba(var(--button-bg-rgb),.08);--icon-button-fg: var(--link-color);color:var(--link-color)}._icon-button--active_13ryy_31:not(:disabled,._icon-button--disabled_13ryy_27):hover:not(:disabled,._icon-button--disabled_13ryy_27):not(:active){background-color:rgba(var(--button-bg-rgb),.12);--icon-button-fg: var(--link-color);color:var(--link-color)}._icon-button--active_13ryy_31:not(:disabled,._icon-button--disabled_13ryy_27):active:not(:disabled,._icon-button--disabled_13ryy_27){background-color:rgba(var(--button-bg-rgb),.16);--icon-button-fg: var(--link-color);color:var(--link-color)}._icon-button--toggled_13ryy_31{background-color:var(--button-bg);--icon-button-fg: var(--button-color);color:var(--button-color)}._icon-button--toggled_13ryy_31:hover:not(:disabled,._icon-button--disabled_13ryy_27):not(:active){background-color:color-mix(in srgb,black 8%,var(--button-bg));--icon-button-fg: var(--button-color);color:var(--button-color)}._icon-button--toggled_13ryy_31:active:not(:disabled,._icon-button--disabled_13ryy_27){background-color:color-mix(in srgb,black 16%,var(--button-bg));--icon-button-fg: var(--button-color);color:var(--button-color)}._icon-button--toggled_13ryy_31 ._icon-button__unread-badge_13ryy_48{box-shadow:0 0 0 2px var(--button-bg)}._icon-button--style-inverted_13ryy_159{background-color:transparent;--icon-button-fg: rgba(var(--sidebar-text-rgb), .64);color:rgba(var(--sidebar-text-rgb),.64)}._icon-button--style-inverted_13ryy_159 ._icon-button__unread-badge_13ryy_48{box-shadow:0 0 0 2px var(--sidebar-header-bg)}._icon-button--style-inverted_13ryy_159:hover:not(:disabled,._icon-button--disabled_13ryy_27):not(:active):not(._icon-button--toggled_13ryy_31):not(._icon-button--active_13ryy_31){background-color:rgba(var(--sidebar-text-rgb),.08);--icon-button-fg: var(--sidebar-text);color:var(--sidebar-text)}._icon-button--style-inverted_13ryy_159:active:not(:disabled,._icon-button--disabled_13ryy_27):not(._icon-button--toggled_13ryy_31){background-color:rgba(var(--sidebar-text-rgb),.16);--icon-button-fg: var(--sidebar-text);color:var(--sidebar-text)}._icon-button--style-inverted_13ryy_159._icon-button--active_13ryy_31:not(:disabled,._icon-button--disabled_13ryy_27){background-color:rgba(var(--sidebar-text-rgb),.16);--icon-button-fg: var(--sidebar-text);color:var(--sidebar-text)}._icon-button--style-inverted_13ryy_159._icon-button--active_13ryy_31:not(:disabled,._icon-button--disabled_13ryy_27):hover:not(:disabled,._icon-button--disabled_13ryy_27):not(:active){background-color:rgba(var(--sidebar-text-rgb),.2);--icon-button-fg: var(--sidebar-text);color:var(--sidebar-text)}._icon-button--style-inverted_13ryy_159._icon-button--active_13ryy_31:not(:disabled,._icon-button--disabled_13ryy_27):active:not(:disabled,._icon-button--disabled_13ryy_27){background-color:rgba(var(--sidebar-text-rgb),.24);--icon-button-fg: var(--sidebar-text);color:var(--sidebar-text)}._icon-button--style-inverted_13ryy_159._icon-button--toggled_13ryy_31{background-color:var(--sidebar-text);--icon-button-fg: var(--sidebar-bg);color:var(--sidebar-bg)}._icon-button--style-inverted_13ryy_159._icon-button--toggled_13ryy_31:hover:not(:disabled,._icon-button--disabled_13ryy_27):not(:active){background-color:rgba(var(--sidebar-text-rgb),.92);--icon-button-fg: var(--sidebar-bg);color:var(--sidebar-bg)}._icon-button--style-inverted_13ryy_159._icon-button--toggled_13ryy_31:active:not(:disabled,._icon-button--disabled_13ryy_27){background-color:rgba(var(--sidebar-text-rgb),.88);--icon-button-fg: var(--sidebar-bg);color:var(--sidebar-bg)}._icon-button--style-inverted_13ryy_159._icon-button--toggled_13ryy_31 ._icon-button__unread-badge_13ryy_48{box-shadow:0 0 0 2px var(--sidebar-text)}._icon-button--style-inverted_13ryy_159._icon-button--destructive_13ryy_210{--focus-ring-color: var(--error-text, var(--color-danger));background-color:transparent;--icon-button-fg: var(--error-text, var(--color-danger));color:var(--error-text, var(--color-danger))}._icon-button--style-inverted_13ryy_159._icon-button--destructive_13ryy_210:hover:not(:disabled,._icon-button--disabled_13ryy_27):not(:active){background-color:rgba(var(--error-text-color-rgb, var(--color-danger-rgb)),.08);--icon-button-fg: var(--error-text, var(--color-danger));color:var(--error-text, var(--color-danger))}._icon-button--style-inverted_13ryy_159._icon-button--destructive_13ryy_210:active:not(:disabled,._icon-button--disabled_13ryy_27):not(._icon-button--toggled_13ryy_31){background-color:rgba(var(--error-text-color-rgb, var(--color-danger-rgb)),.16);--icon-button-fg: var(--error-text, var(--color-danger));color:var(--error-text, var(--color-danger))}._icon-button--destructive_13ryy_210{--focus-ring-color: var(--error-text, var(--color-danger));background-color:transparent;--icon-button-fg: var(--error-text, var(--color-danger));color:var(--error-text, var(--color-danger))}._icon-button--destructive_13ryy_210:hover:not(:disabled,._icon-button--disabled_13ryy_27):not(:active){background-color:rgba(var(--error-text-color-rgb, var(--color-danger-rgb)),.08);--icon-button-fg: var(--error-text, var(--color-danger));color:var(--error-text, var(--color-danger))}._icon-button--destructive_13ryy_210:active:not(:disabled,._icon-button--disabled_13ryy_27):not(._icon-button--toggled_13ryy_31){background-color:rgba(var(--error-text-color-rgb, var(--color-danger-rgb)),.16);--icon-button-fg: var(--error-text, var(--color-danger));color:var(--error-text, var(--color-danger))}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { ButtonHTMLAttributes, ReactNode } from 'react';
|
|
1
|
+
import { ButtonHTMLAttributes, HTMLAttributes, ReactElement, ReactNode, RefAttributes } from 'react';
|
|
2
2
|
export type IconButtonSize = 'x-small' | 'small' | 'medium' | 'large';
|
|
3
3
|
/** Figma "Style": Default (light context) | Inverted (dark context). */
|
|
4
4
|
export type IconButtonStyle = 'default' | 'inverted';
|
|
5
5
|
export type IconButtonPadding = 'default' | 'compact';
|
|
6
|
-
|
|
6
|
+
interface IconButtonOwnProps {
|
|
7
7
|
/** When true, forces the subtler pressed/active visual (lighter than toggled). */
|
|
8
8
|
active?: boolean;
|
|
9
9
|
/** Optional CSS class name. */
|
|
@@ -14,7 +14,7 @@ export interface IconButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonEle
|
|
|
14
14
|
destructive?: boolean;
|
|
15
15
|
/** Icon to show. Pass `<Icon glyph={<YourIcon />} />` — IconButton provides the correct size via context; no `size` prop needed on the Icon. */
|
|
16
16
|
icon: ReactNode;
|
|
17
|
-
/** When true, shows a Spinner in place of the icon and disables the button. */
|
|
17
|
+
/** When true, shows a Spinner in place of the icon and disables the button (or blocks navigation when `asChild`). */
|
|
18
18
|
loading?: boolean;
|
|
19
19
|
/** Padding variant. Figma: Padding = Default | Compact. */
|
|
20
20
|
padding?: IconButtonPadding;
|
|
@@ -22,24 +22,65 @@ export interface IconButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonEle
|
|
|
22
22
|
rounded?: boolean;
|
|
23
23
|
/** Size variant. Figma: Size. Default: Medium. */
|
|
24
24
|
size?: IconButtonSize;
|
|
25
|
-
/** Default | Inverted. Figma: Style (for light vs dark backgrounds). */
|
|
25
|
+
/** Default | Inverted. Figma: Style (for light vs dark backgrounds). Replaces the HTML `style` attribute. */
|
|
26
26
|
style?: IconButtonStyle;
|
|
27
|
-
/** When true, shows toggled/selected state. Figma: Toggled = On. When omitted, the control is not a toggle. */
|
|
28
|
-
toggled?: boolean;
|
|
29
27
|
/** When true, shows a small unread dot over the icon. Figma: Unread Badge. */
|
|
30
28
|
unreadBadge?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* When true, disables the control. On a native `<button>`, sets the `disabled`
|
|
31
|
+
* attribute. With `asChild`, sets `aria-disabled`, applies disabled styles, and
|
|
32
|
+
* blocks click / middle-click navigation (the link stays focusable).
|
|
33
|
+
*/
|
|
34
|
+
disabled?: boolean;
|
|
35
|
+
}
|
|
36
|
+
export interface IconButtonProps extends IconButtonOwnProps, Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'style'> {
|
|
37
|
+
/**
|
|
38
|
+
* When true, merges IconButton props onto the single child element instead of
|
|
39
|
+
* rendering a `<button>`. Use with `<a>` or a router `Link`. Default: false.
|
|
40
|
+
*/
|
|
41
|
+
asChild?: false;
|
|
42
|
+
/**
|
|
43
|
+
* When true, shows toggled/selected state. Figma: Toggled = On. When omitted,
|
|
44
|
+
* the control is not a toggle. Only applies to the native `<button>` (maps to
|
|
45
|
+
* `aria-pressed`); not available with `asChild`.
|
|
46
|
+
*/
|
|
47
|
+
toggled?: boolean;
|
|
48
|
+
}
|
|
49
|
+
export interface IconButtonAsChildProps extends IconButtonOwnProps, Omit<HTMLAttributes<HTMLElement>, 'children' | 'color' | 'style'> {
|
|
50
|
+
/**
|
|
51
|
+
* Merges IconButton props onto the single child element instead of rendering a
|
|
52
|
+
* `<button>`. The child's own props (`href`, `to`, `target`, …) stay on the
|
|
53
|
+
* child. Do not pass `type` or `toggled` — they are not available on links.
|
|
54
|
+
* Pass an empty child; IconButton supplies the icon anatomy.
|
|
55
|
+
*/
|
|
56
|
+
asChild: true;
|
|
57
|
+
/** Single empty element to render as the IconButton (e.g. `<a href="…" />`). */
|
|
58
|
+
children: ReactElement;
|
|
59
|
+
/**
|
|
60
|
+
* Accessible name for the icon-only link. Required with `asChild`. An
|
|
61
|
+
* `aria-label` on the child also satisfies this (child props win).
|
|
62
|
+
*/
|
|
63
|
+
'aria-label': string;
|
|
31
64
|
}
|
|
32
65
|
/**
|
|
33
66
|
* @deprecated No longer needed — IconButton sets the icon size via context.
|
|
34
67
|
* Pass `<Icon glyph={<YourIcon />} />` without a size prop.
|
|
35
68
|
*/
|
|
36
69
|
export declare const ICON_BUTTON_ICON_SIZES: Record<IconButtonSize, '12' | '16' | '20' | '24'>;
|
|
70
|
+
type IconButtonComponent = {
|
|
71
|
+
(props: IconButtonAsChildProps & RefAttributes<HTMLElement>): ReactElement | null;
|
|
72
|
+
(props: IconButtonProps & RefAttributes<HTMLButtonElement>): ReactElement | null;
|
|
73
|
+
displayName?: string;
|
|
74
|
+
};
|
|
37
75
|
/**
|
|
38
76
|
* Icon Buttons are compact, label-free actions for tight surfaces — channel headers, message
|
|
39
77
|
* hover actions, modal dismissals, toolbar slots. They lean on the icon to communicate
|
|
40
78
|
* intent, so every Icon Button must pair with a tooltip or `aria-label` that makes the
|
|
41
79
|
* action explicit.
|
|
80
|
+
*
|
|
81
|
+
* Pass `asChild` with a single empty `<a>` or router `Link` child to render a navigational
|
|
82
|
+
* icon control with Icon Button styling (no nested `<button>`).
|
|
42
83
|
*/
|
|
43
|
-
declare const IconButton:
|
|
84
|
+
declare const IconButton: IconButtonComponent;
|
|
44
85
|
export default IconButton;
|
|
45
86
|
//# sourceMappingURL=IconButton.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IconButton.d.ts","sourceRoot":"","sources":["../../../src/components/icon-button/IconButton.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"IconButton.d.ts","sourceRoot":"","sources":["../../../src/components/icon-button/IconButton.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,SAAS,EAEd,KAAK,aAAa,EACnB,MAAM,OAAO,CAAC;AAOf,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEtE,wEAAwE;AACxE,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,UAAU,CAAC;AAErD,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,SAAS,CAAC;AAEtD,UAAU,kBAAkB;IAC1B,kFAAkF;IAClF,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,+BAA+B;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,gJAAgJ;IAChJ,IAAI,EAAE,SAAS,CAAC;IAChB,qHAAqH;IACrH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,sEAAsE;IACtE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kDAAkD;IAClD,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,6GAA6G;IAC7G,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,eACf,SACE,kBAAkB,EAClB,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IACxD;;;OAGG;IACH,OAAO,CAAC,EAAE,KAAK,CAAC;IAChB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,sBACf,SACE,kBAAkB,EAClB,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,UAAU,GAAG,OAAO,GAAG,OAAO,CAAC;IACnE;;;;;OAKG;IACH,OAAO,EAAE,IAAI,CAAC;IACd,gFAAgF;IAChF,QAAQ,EAAE,YAAY,CAAC;IACvB;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,CACzC,cAAc,EACd,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAM1B,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,CACE,KAAK,EAAE,sBAAsB,GAAG,aAAa,CAAC,WAAW,CAAC,GACzD,YAAY,GAAG,IAAI,CAAC;IACvB,CACE,KAAK,EAAE,eAAe,GAAG,aAAa,CAAC,iBAAiB,CAAC,GACxD,YAAY,GAAG,IAAI,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAuCF;;;;;;;;GAQG;AACH,QAAA,MAAM,UAAU,EA4IV,mBAAmB,CAAC;AAI1B,eAAe,UAAU,CAAC"}
|
|
@@ -1,70 +1,144 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import { forwardRef as
|
|
3
|
-
import { IconSlotContext as
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
|
|
1
|
+
import { jsxs as l, Fragment as V, jsx as a } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as W } from "react";
|
|
3
|
+
import { IconSlotContext as z } from "../icon/Icon.js";
|
|
4
|
+
import y from "../spinner/Spinner.js";
|
|
5
|
+
import { renderAsChild as X } from "../../utils/slot.js";
|
|
6
|
+
import { toKebab as Y } from "../../utils/string.js";
|
|
7
|
+
import e from "./IconButton.module.scss.js";
|
|
8
|
+
const B = {
|
|
8
9
|
"x-small": "12",
|
|
9
10
|
small: "16",
|
|
10
11
|
medium: "20",
|
|
11
12
|
large: "24"
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
g,
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
13
|
+
};
|
|
14
|
+
function I({
|
|
15
|
+
className: f = "",
|
|
16
|
+
count: t,
|
|
17
|
+
destructive: o = !1,
|
|
18
|
+
padding: s = "default",
|
|
19
|
+
rounded: c = !1,
|
|
20
|
+
size: n = "medium",
|
|
21
|
+
style: r = "default",
|
|
22
|
+
active: u = !1,
|
|
23
|
+
toggled: i
|
|
24
|
+
}) {
|
|
25
|
+
return [
|
|
26
|
+
e["icon-button"],
|
|
27
|
+
e[`icon-button--size-${Y(n)}`],
|
|
28
|
+
s === "compact" ? e["icon-button--padding-compact"] : "",
|
|
29
|
+
r === "inverted" ? e["icon-button--style-inverted"] : "",
|
|
30
|
+
o ? e["icon-button--destructive"] : "",
|
|
31
|
+
c ? e["icon-button--rounded"] : "",
|
|
32
|
+
i ? e["icon-button--toggled"] : "",
|
|
33
|
+
u ? e["icon-button--active"] : "",
|
|
34
|
+
t !== void 0 ? e["icon-button--has-count"] : "",
|
|
35
|
+
f
|
|
36
|
+
].filter(Boolean).join(" ");
|
|
37
|
+
}
|
|
38
|
+
const ee = W(function(t, o) {
|
|
39
|
+
if (t.asChild) {
|
|
40
|
+
const {
|
|
41
|
+
active: g = !1,
|
|
42
|
+
className: A = "",
|
|
43
|
+
count: b,
|
|
44
|
+
destructive: E = !1,
|
|
45
|
+
icon: F,
|
|
46
|
+
loading: d = !1,
|
|
47
|
+
padding: K = "default",
|
|
48
|
+
rounded: U = !1,
|
|
49
|
+
size: N = "medium",
|
|
50
|
+
style: C = "default",
|
|
51
|
+
unreadBadge: Z = !1,
|
|
52
|
+
disabled: $,
|
|
53
|
+
children: k,
|
|
54
|
+
"aria-label": q,
|
|
55
|
+
asChild: te,
|
|
56
|
+
...G
|
|
57
|
+
} = t, H = I({
|
|
58
|
+
className: A,
|
|
59
|
+
count: b,
|
|
60
|
+
destructive: E,
|
|
61
|
+
padding: K,
|
|
62
|
+
rounded: U,
|
|
63
|
+
size: N,
|
|
64
|
+
style: C,
|
|
65
|
+
active: g
|
|
66
|
+
}), _ = B[N], J = !!($ || d), M = b !== void 0, Q = /* @__PURE__ */ l(V, { children: [
|
|
67
|
+
/* @__PURE__ */ l("span", { className: e["icon-button__icon-slot"], "aria-hidden": !0, children: [
|
|
68
|
+
d ? /* @__PURE__ */ a(y, { size: _, inverted: C === "inverted" }) : /* @__PURE__ */ a(z.Provider, { value: { size: _ }, children: F }),
|
|
69
|
+
Z && !d && /* @__PURE__ */ a("span", { className: e["icon-button__unread-badge"] })
|
|
70
|
+
] }),
|
|
71
|
+
M && /* @__PURE__ */ a("span", { className: e["icon-button__count"], children: b })
|
|
72
|
+
] });
|
|
73
|
+
return X({
|
|
74
|
+
child: k,
|
|
75
|
+
props: {
|
|
76
|
+
...G,
|
|
77
|
+
className: H,
|
|
78
|
+
"aria-label": q,
|
|
79
|
+
"data-active": g ? "true" : void 0,
|
|
80
|
+
...d ? { "aria-busy": !0 } : null
|
|
81
|
+
},
|
|
82
|
+
ref: o,
|
|
83
|
+
content: Q,
|
|
84
|
+
disabled: J,
|
|
85
|
+
disabledClassName: e["icon-button--disabled"],
|
|
86
|
+
warnOnChildContent: !0
|
|
87
|
+
});
|
|
63
88
|
}
|
|
64
|
-
|
|
65
|
-
|
|
89
|
+
const {
|
|
90
|
+
active: s = !1,
|
|
91
|
+
className: c = "",
|
|
92
|
+
count: n,
|
|
93
|
+
destructive: r = !1,
|
|
94
|
+
icon: u,
|
|
95
|
+
loading: i = !1,
|
|
96
|
+
padding: S = "default",
|
|
97
|
+
rounded: x = !1,
|
|
98
|
+
size: v = "medium",
|
|
99
|
+
style: p = "default",
|
|
100
|
+
toggled: m,
|
|
101
|
+
unreadBadge: O = !1,
|
|
102
|
+
disabled: j,
|
|
103
|
+
type: w = "button",
|
|
104
|
+
"aria-label": D,
|
|
105
|
+
asChild: ae,
|
|
106
|
+
...L
|
|
107
|
+
} = t, P = I({
|
|
108
|
+
className: c,
|
|
109
|
+
count: n,
|
|
110
|
+
destructive: r,
|
|
111
|
+
padding: S,
|
|
112
|
+
rounded: x,
|
|
113
|
+
size: v,
|
|
114
|
+
style: p,
|
|
115
|
+
active: s,
|
|
116
|
+
toggled: m
|
|
117
|
+
}), h = B[v], R = !!(j || i), T = n !== void 0;
|
|
118
|
+
return /* @__PURE__ */ l(
|
|
119
|
+
"button",
|
|
120
|
+
{
|
|
121
|
+
ref: o,
|
|
122
|
+
className: P,
|
|
123
|
+
type: w,
|
|
124
|
+
disabled: R,
|
|
125
|
+
"aria-label": D,
|
|
126
|
+
"aria-pressed": m === void 0 ? void 0 : m,
|
|
127
|
+
"data-active": s ? "true" : void 0,
|
|
128
|
+
...L,
|
|
129
|
+
children: [
|
|
130
|
+
/* @__PURE__ */ l("span", { className: e["icon-button__icon-slot"], "aria-hidden": !0, children: [
|
|
131
|
+
i ? /* @__PURE__ */ a(y, { size: h, inverted: p === "inverted" }) : /* @__PURE__ */ a(z.Provider, { value: { size: h }, children: u }),
|
|
132
|
+
O && !i && /* @__PURE__ */ a("span", { className: e["icon-button__unread-badge"] })
|
|
133
|
+
] }),
|
|
134
|
+
T && /* @__PURE__ */ a("span", { className: e["icon-button__count"], children: n })
|
|
135
|
+
]
|
|
136
|
+
}
|
|
137
|
+
);
|
|
138
|
+
});
|
|
139
|
+
ee.displayName = "IconButton";
|
|
66
140
|
export {
|
|
67
|
-
|
|
68
|
-
|
|
141
|
+
B as ICON_BUTTON_ICON_SIZES,
|
|
142
|
+
ee as default
|
|
69
143
|
};
|
|
70
144
|
//# sourceMappingURL=IconButton.js.map
|