@persona/design-system 0.10.8 → 0.10.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/dist/{Badge-8YzapjWf.mjs → Badge-BCdsVKuj.mjs} +2 -2
- package/dist/{Badge-8YzapjWf.mjs.map → Badge-BCdsVKuj.mjs.map} +1 -1
- package/dist/{Breadcrumbs-Dft2TR4v.mjs → Breadcrumbs-CMf3Uvow.mjs} +4 -4
- package/dist/{Breadcrumbs-Dft2TR4v.mjs.map → Breadcrumbs-CMf3Uvow.mjs.map} +1 -1
- package/dist/Card2.d.mts +2 -2
- package/dist/{CardV2-BRJbRSts.mjs → CardV2-ACI5RIzF.mjs} +5 -5
- package/dist/{CardV2-BRJbRSts.mjs.map → CardV2-ACI5RIzF.mjs.map} +1 -1
- package/dist/{Combobox-DQxaOCLA.mjs → Combobox-Gb_j1dg6.mjs} +5 -5
- package/dist/{Combobox-DQxaOCLA.mjs.map → Combobox-Gb_j1dg6.mjs.map} +1 -1
- package/dist/{CompactBar-D67CdcIo.d.mts → CompactBar-BLZZWtIE.d.mts} +2 -2
- package/dist/CompactBar.d.mts +1 -1
- package/dist/{ControlBar-34th2yt4.d.mts → ControlBar-B3Jn8G0k.d.mts} +5 -4
- package/dist/ControlBar.d.mts +1 -1
- package/dist/{DataTable-BZtzdtVs.d.mts → DataTable-Bf1WDY0z.d.mts} +2 -2
- package/dist/{DataTable-BvA2H9D9.mjs → DataTable-CIZJ1vO8.mjs} +10 -10
- package/dist/{DataTable-BvA2H9D9.mjs.map → DataTable-CIZJ1vO8.mjs.map} +1 -1
- package/dist/DataTable.d.mts +1 -1
- package/dist/{DatePicker-D-_ibUd1.mjs → DatePicker-C9redLBr.mjs} +4 -4
- package/dist/{DatePicker-D-_ibUd1.mjs.map → DatePicker-C9redLBr.mjs.map} +1 -1
- package/dist/{DropdownButton-BiFRlSVD.mjs → DropdownButton-DpLG-cIj.mjs} +3 -3
- package/dist/{DropdownButton-BiFRlSVD.mjs.map → DropdownButton-DpLG-cIj.mjs.map} +1 -1
- package/dist/{DropdownMenu-Q8S-9rXm.mjs → DropdownMenu-c8XK2Lr4.mjs} +2 -2
- package/dist/{DropdownMenu-Q8S-9rXm.mjs.map → DropdownMenu-c8XK2Lr4.mjs.map} +1 -1
- package/dist/{FloatingToolbar-Df90f7Dm.mjs → FloatingToolbar-DLRaE0o7.mjs} +3 -3
- package/dist/{FloatingToolbar-Df90f7Dm.mjs.map → FloatingToolbar-DLRaE0o7.mjs.map} +1 -1
- package/dist/{FormField-BStxmlZT.mjs → FormField-Cf1VMvoa.mjs} +7 -7
- package/dist/{FormField-BStxmlZT.mjs.map → FormField-Cf1VMvoa.mjs.map} +1 -1
- package/dist/{HoverCopyableField-CW7Jxmni.mjs → HoverCopyableField-XHC_n9tp.mjs} +2 -2
- package/dist/{HoverCopyableField-CW7Jxmni.mjs.map → HoverCopyableField-XHC_n9tp.mjs.map} +1 -1
- package/dist/{IconButton-DftINsp7.mjs → IconButton-DxHB2g80.mjs} +2 -2
- package/dist/{IconButton-DftINsp7.mjs.map → IconButton-DxHB2g80.mjs.map} +1 -1
- package/dist/IndexTableLayout.d.mts +3 -3
- package/dist/{Input-DtO3qMnE.mjs → Input-RHXujO9u.mjs} +2 -2
- package/dist/{Input-DtO3qMnE.mjs.map → Input-RHXujO9u.mjs.map} +1 -1
- package/dist/{Link-DKYmdL9t.mjs → Link-D_kCyLYX.mjs} +2 -2
- package/dist/{Link-DKYmdL9t.mjs.map → Link-D_kCyLYX.mjs.map} +1 -1
- package/dist/{ListBox-CDG0EAPg.mjs → ListBox-BZp6exb8.mjs} +6 -6
- package/dist/{ListBox-CDG0EAPg.mjs.map → ListBox-BZp6exb8.mjs.map} +1 -1
- package/dist/{Menu-EIT_MwK6.mjs → Menu-BVn1jh46.mjs} +2 -2
- package/dist/{Menu-EIT_MwK6.mjs.map → Menu-BVn1jh46.mjs.map} +1 -1
- package/dist/{Modal-BGlRX63w.mjs → Modal-De5_bPJ_.mjs} +4 -4
- package/dist/{Modal-BGlRX63w.mjs.map → Modal-De5_bPJ_.mjs.map} +1 -1
- package/dist/PageHeader-7_Hf6rHl.mjs +81 -0
- package/dist/PageHeader-7_Hf6rHl.mjs.map +1 -0
- package/dist/{PageHeader-DRatgscC.d.mts → PageHeader-UPiqJpIF.d.mts} +11 -3
- package/dist/PageHeader.d.mts +1 -1
- package/dist/{Pagination-C8hPOu0l.mjs → Pagination-DMH2IaV0.mjs} +5 -5
- package/dist/{Pagination-C8hPOu0l.mjs.map → Pagination-DMH2IaV0.mjs.map} +1 -1
- package/dist/{Pii-Bvh_kfGN.mjs → Pii-24D_nSRQ.mjs} +2 -2
- package/dist/{Pii-Bvh_kfGN.mjs.map → Pii-24D_nSRQ.mjs.map} +1 -1
- package/dist/{Select-DkUMz4LG.mjs → Select-DOlw_LPR.mjs} +4 -4
- package/dist/{Select-DkUMz4LG.mjs.map → Select-DOlw_LPR.mjs.map} +1 -1
- package/dist/{StatusIndicator-Zf75KK3O.mjs → StatusIndicator-CzRaEFSz.mjs} +2 -2
- package/dist/{StatusIndicator-Zf75KK3O.mjs.map → StatusIndicator-CzRaEFSz.mjs.map} +1 -1
- package/dist/{Sticker-Bi_fezCO.mjs → Sticker-C1_6I08u.mjs} +3 -3
- package/dist/{Sticker-Bi_fezCO.mjs.map → Sticker-C1_6I08u.mjs.map} +1 -1
- package/dist/{TabBar-DpXYsWgS.mjs → TabBar-BCFO38E0.mjs} +3 -3
- package/dist/{TabBar-DpXYsWgS.mjs.map → TabBar-BCFO38E0.mjs.map} +1 -1
- package/dist/{TableBox-BfSF36Gy.mjs → TableBox-DNQsgQ8x.mjs} +4 -4
- package/dist/{TableBox-BfSF36Gy.mjs.map → TableBox-DNQsgQ8x.mjs.map} +1 -1
- package/dist/{TableControls-BZ8RrYOc.mjs → TableControls-BrP_BqnF.mjs} +14 -14
- package/dist/TableControls-BrP_BqnF.mjs.map +1 -0
- package/dist/{TableControls-DT2YpFK8.d.mts → TableControls-ODHrCDJM.d.mts} +2 -2
- package/dist/TableControls.d.mts +1 -1
- package/dist/{TechnicalSticker-B_JlBkXZ.mjs → TechnicalSticker-Cq5jzYKQ.mjs} +2 -2
- package/dist/{TechnicalSticker-B_JlBkXZ.mjs.map → TechnicalSticker-Cq5jzYKQ.mjs.map} +1 -1
- package/dist/components/Accordion/index.mjs +1 -1
- package/dist/components/Attribute/index.mjs +2 -2
- package/dist/components/Badge/index.mjs +1 -1
- package/dist/components/Banner/index.mjs +1 -1
- package/dist/components/BottomPanel/index.mjs +4 -4
- package/dist/components/Breadcrumbs/index.mjs +1 -1
- package/dist/components/Button/index.mjs +1 -1
- package/dist/components/ButtonGroup/index.mjs +1 -1
- package/dist/components/CardV2/index.mjs +1 -1
- package/dist/components/CodeHighlight/index.mjs +1 -1
- package/dist/components/Combobox/index.mjs +1 -1
- package/dist/components/DataTable/TableControls/index.d.mts +3 -3
- package/dist/components/DataTable/TableControls/index.mjs +1 -1
- package/dist/components/DataTable/index.d.mts +1 -1
- package/dist/components/DataTable/index.mjs +1 -1
- package/dist/components/DatePicker/index.mjs +1 -1
- package/dist/components/DropdownButton/index.mjs +1 -1
- package/dist/components/DropdownMenu/index.mjs +1 -1
- package/dist/components/FloatingPanel/index.mjs +2 -2
- package/dist/components/FloatingToolbar/index.mjs +1 -1
- package/dist/components/FormField/index.mjs +1 -1
- package/dist/components/HoverCopyableField/index.mjs +1 -1
- package/dist/components/ImageTile/index.mjs +2 -2
- package/dist/components/Input/index.mjs +1 -1
- package/dist/components/Link/index.mjs +1 -1
- package/dist/components/ListBox/index.mjs +1 -1
- package/dist/components/MaskedInput/index.mjs +1 -1
- package/dist/components/Menu/index.mjs +1 -1
- package/dist/components/Modal/index.mjs +1 -1
- package/dist/components/PageHeader/index.d.mts +1 -1
- package/dist/components/PageHeader/index.mjs +1 -1
- package/dist/components/Pagination/index.mjs +1 -1
- package/dist/components/Pii/index.mjs +1 -1
- package/dist/components/RichTextEditor/index.mjs +4 -4
- package/dist/components/RightPanel/index.mjs +1 -1
- package/dist/components/Select/index.mjs +1 -1
- package/dist/components/SmartTextInput/index.mjs +2 -2
- package/dist/components/StatusIndicator/index.mjs +1 -1
- package/dist/components/Sticker/index.mjs +1 -1
- package/dist/components/TabBar/index.mjs +1 -1
- package/dist/components/TableBox/index.mjs +1 -1
- package/dist/components/TechnicalSticker/index.mjs +1 -1
- package/dist/components/Tile/index.mjs +1 -1
- package/dist/components/Toast/index.mjs +1 -1
- package/dist/components/VersionHistory/index.mjs +4 -4
- package/dist/lib/GlobalStyles.d.mts +19 -2
- package/dist/lib/GlobalStyles.mjs +50 -1
- package/dist/lib/GlobalStyles.mjs.map +1 -1
- package/dist/patterns/CardGrouping/index.mjs +4 -4
- package/dist/patterns/IndexTableLayout/index.mjs +2 -2
- package/dist/patterns/LayoutLoadingShimmer/index.mjs +2 -2
- package/dist/patterns/WizardModal/index.mjs +2 -2
- package/dist/theme.mjs +1 -1
- package/llms.txt +1 -1
- package/package.json +1 -1
- package/dist/PageHeader-DEKTopzU.mjs +0 -75
- package/dist/PageHeader-DEKTopzU.mjs.map +0 -1
- package/dist/TableControls-BZ8RrYOc.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FloatingToolbar-Df90f7Dm.mjs","names":["Input","DropdownMenu"],"sources":["../src/components/FloatingToolbar/FloatingToolbar.tsx"],"sourcesContent":["import { PluginKey } from '@tiptap/pm/state';\nimport type { EditorView } from '@tiptap/pm/view';\nimport { useEditorState, type Editor } from '@tiptap/react';\nimport { BubbleMenu } from '@tiptap/react/menus';\nimport { AnimatePresence, motion } from 'framer-motion';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport styled from 'styled-components';\n\nimport { BorderRadius, Color, Spacing } from '@persona/design-tokens';\nimport {\n BoldIcon,\n CheckIcon,\n GridIcon,\n ItalicIcon,\n LinkIcon,\n ListIcon,\n UnlinkIcon,\n XIcon,\n} from '@persona/icons';\n\nimport { IconButton } from '#src/components/Button';\nimport DropdownMenu from '#src/components/DropdownMenu';\nimport Input from '#src/components/Input';\nimport Stack from '#src/components/Stack';\nimport { Z_INDICES } from '#src/lib/zindex';\nimport { TransitionDuration } from '#src/variables/transitions';\n\n// Core* colors throughout this file are intentional: the bubble toolbar is an\n// always-dark inverse surface floating over the editor, so it must not track\n// the semantic surface theme.\nconst BubbleMenuBar = styled(Stack)`\n padding: ${Spacing[1]} ${Spacing[2]};\n background-color: ${Color.CoreSlate1100};\n border-radius: ${BorderRadius.Lg};\n`;\n\nconst IconContainer = styled(motion.div)`\n display: flex;\n gap: ${Spacing[1]};\n`;\n\nconst InverseIconButton = styled(IconButton)<{ $selected?: boolean }>`\n background-color: ${({ $selected }) => ($selected ? Color.CoreSlate900 : 'transparent')};\n color: ${Color.PrimaryWhite};\n transition: background-color ${TransitionDuration.ExtraFast} ease-out;\n\n &:hover:not(:disabled) {\n background-color: ${Color.CoreSlate800};\n }\n\n &:disabled {\n background-color: transparent;\n opacity: 0.35;\n }\n`;\n\nconst InverseInput = styled(Input)`\n background-color: ${Color.CoreSlate900};\n color: ${Color.PrimaryWhite};\n\n :focus-within {\n border-color: ${Color.CoreBlue700};\n }\n ::placeholder {\n color: ${Color.TextDisabled};\n }\n\n input {\n background-color: ${Color.CoreSlate900};\n color: ${Color.PrimaryWhite};\n }\n`;\n\nconst StyledDropdownItem = styled(DropdownMenu.Item)`\n width: 100%;\n height: 30px;\n font-size: small;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n`;\n\n// Floating UI takes its offset as numbers while the spacing tokens are CSS lengths.\nconst TOOLBAR_GAP = parseInt(Spacing[1]);\n\n// Anchored to the field, the toolbar lines up with the input's left edge; over a\n// selection it sits back a notch so it does not crowd the first selected glyph.\nconst FIELD_OFFSET = { mainAxis: TOOLBAR_GAP, crossAxis: 0 };\nconst SELECTION_OFFSET = { mainAxis: TOOLBAR_GAP, crossAxis: -parseInt(Spacing[2]) };\n\n// The element EditorContent mounts the editor into — the visible field. Tiptap\n// types `options.element` loosely, so fall back to the editable root.\nconst getFieldElement = (editor: Editor): Element =>\n editor.options.element instanceof Element ? editor.options.element : editor.view.dom;\n\n// Schemes we trust as link targets. Anything else (no scheme, or an unsafe one\n// like javascript:/data:/vbscript:) is treated as a bare host and forced onto\n// https, which both preserves host:port input and neutralizes script schemes.\nconst SAFE_LINK_SCHEME = /^(https?|mailto|tel):/i;\nconst URI_SCHEME = /^[a-zA-Z][a-zA-Z0-9+.-]*:/;\n\nexport const ensureProtocol = (url: string): string => {\n const trimmedUrl = url.trim();\n if (!trimmedUrl) {\n return '';\n }\n // Handlebars placeholders (e.g. {{inquiry.id}}) are legitimate link targets in\n // templated messages — the template render produces the final URL, so pass\n // the expression through unvalidated. Only when nothing before the first\n // placeholder looks like an unsafe scheme: javascript:alert(1)//{{x}} would\n // otherwise smuggle a script href past the allowlist. URL parsers strip C0\n // controls, tabs and spaces before reading the scheme, so normalize the\n // prefix the same way first — java\\tscript:...{{x}} must not slip through.\n if (trimmedUrl.includes('{{')) {\n const beforePlaceholder = trimmedUrl\n .slice(0, trimmedUrl.indexOf('{{'))\n // eslint-disable-next-line no-control-regex -- mirrors how URL parsers strip C0/space before reading the scheme\n .replace(/[\\u0000-\\u0020]/g, '');\n if (!URI_SCHEME.test(beforePlaceholder) || SAFE_LINK_SCHEME.test(beforePlaceholder)) {\n return trimmedUrl;\n }\n return '';\n }\n const candidate = SAFE_LINK_SCHEME.test(trimmedUrl) ? trimmedUrl : `https://${trimmedUrl}`;\n // Re-parse so malformed input — including an unsafe scheme that can't survive\n // the https prefix — is dropped instead of applied as a broken href.\n return URL.canParse(candidate) ? candidate : '';\n};\n\ninterface FloatingToolbarProps {\n /** TipTap editor instance to operate on. */\n editor: Editor | null;\n /**\n * Keep the toolbar up the whole time the editor is focused instead of only\n * while text is selected, so the formatting actions are discoverable without\n * knowing to select first.\n */\n showOnFocus?: boolean;\n}\n\n/**\n * Floating bubble toolbar that appears on text selection or inside a table, or —\n * with `showOnFocus` — for as long as the editor is focused.\n * Keyboard shortcut: Cmd/Ctrl+Shift+U opens the link-edit row.\n */\nfunction FloatingToolbar({ editor, showOnFocus = false }: FloatingToolbarProps) {\n const [linkURL, setLinkURL] = useState('');\n const [editingLink, setEditingLink] = useState(false);\n const linkInputRef = useRef<HTMLInputElement>(null);\n const toolbarRef = useRef<HTMLDivElement>(null);\n const savedSelection = useRef<{ from: number; to: number } | null>(null);\n const editingLinkRef = useRef(editingLink);\n const blurTimeout = useRef<ReturnType<typeof setTimeout>>();\n // Lets the toolbar close its own bubble menu plugin via a `hide` meta.\n const [pluginKey] = useState(() => new PluginKey('floatingToolbar'));\n\n useEffect(() => () => clearTimeout(blurTimeout.current), []);\n\n useEffect(() => {\n editingLinkRef.current = editingLink;\n }, [editingLink]);\n\n const restoreSelection = useCallback(() => {\n if (editor && savedSelection.current) {\n const { from, to } = savedSelection.current;\n editor.chain().focus().setTextSelection({ from, to }).run();\n }\n }, [editor]);\n\n const openLinkEditingMode = useCallback(() => {\n if (!editor) {\n return;\n }\n if (!editor.can().chain().toggleLink({ href: 'https://www.google.com' }).run()) {\n return;\n }\n\n const { from, to } = editor.state.selection;\n savedSelection.current = { from, to };\n\n const linkAttr = editor.getAttributes('link');\n if (linkAttr.href) {\n setLinkURL(linkAttr.href);\n }\n\n editor.chain().focus().setTextSelection({ from, to }).run();\n setEditingLink(true);\n\n setTimeout(() => {\n linkInputRef.current?.focus();\n }, 250);\n }, [editor]);\n\n // Cmd/Ctrl+Shift+U → open link mode; Escape inside link mode → cancel.\n useEffect(() => {\n if (!editor) {\n return undefined;\n }\n const dom = editor.view.dom;\n const handler = (event: KeyboardEvent) => {\n if ((event.metaKey || event.ctrlKey) && event.shiftKey && event.key.toLowerCase() === 'u') {\n event.preventDefault();\n openLinkEditingMode();\n return;\n }\n if (event.key === 'Escape' && editingLinkRef.current) {\n event.preventDefault();\n setEditingLink(false);\n setLinkURL('');\n savedSelection.current = null;\n }\n };\n dom.addEventListener('keydown', handler);\n return () => {\n dom.removeEventListener('keydown', handler);\n };\n }, [editor, openLinkEditingMode]);\n\n // Keep selection highlighted while focus is in the link input.\n useEffect(() => {\n if (!editingLink || !editor || !savedSelection.current) {\n return undefined;\n }\n restoreSelection();\n const timeoutId = setTimeout(() => {\n restoreSelection();\n editor.view.dom?.focus();\n }, 0);\n return () => clearTimeout(timeoutId);\n }, [editingLink, restoreSelection, editor]);\n\n // Pressing a toolbar button focuses that button, and the command's own\n // transaction re-runs this check before the chained `.focus()` hands focus\n // back to the editor. Ignoring focus held inside the toolbar therefore tears\n // the bar down for a frame mid-click, taking the pressed button with it.\n const isFocusWithinToolbar = useCallback(\n () => !!toolbarRef.current?.contains(document.activeElement),\n [],\n );\n\n // BubbleMenu dispatches an options-update transaction whenever these props\n // change identity, and editors that re-render per transaction would then\n // loop — so keep them stable across renders.\n const bubbleMenuOptions = useMemo(\n () => ({\n placement: 'top-start' as const,\n offset: showOnFocus ? FIELD_OFFSET : SELECTION_OFFSET,\n }),\n [showOnFocus],\n );\n\n // Sitting above the field rather than the selection: a toolbar that is up\n // for the whole time the field is focused looks jumpy if it chases the\n // caret and hops between selections.\n const getReferencedVirtualElement = useMemo(\n () =>\n showOnFocus && editor\n ? () => ({ getBoundingClientRect: () => getFieldElement(editor).getBoundingClientRect() })\n : undefined,\n [editor, showOnFocus],\n );\n\n const shouldShow = useCallback(\n ({\n editor: e,\n view,\n from,\n to,\n }: {\n editor: Editor;\n view: EditorView;\n from: number;\n to: number;\n }) => {\n if (!e.isEditable) {\n return false;\n }\n if (e.isActive('mention')) {\n return false;\n }\n // The toolbar carries the table-actions dropdown — a collapsed caret\n // inside a table must still show it or row/column controls are\n // unreachable.\n if (e.isActive('table')) {\n return true;\n }\n if (from !== to) {\n return true;\n }\n return showOnFocus && (view.hasFocus() || isFocusWithinToolbar());\n },\n [isFocusWithinToolbar, showOnFocus],\n );\n\n // Self-subscribe: standalone use can't rely on the host's useEditor options (shouldRerenderOnTransaction is off by default in Tiptap 3).\n const editorState = useEditorState({\n editor,\n selector: (snapshot) =>\n snapshot.editor && {\n isBold: snapshot.editor.isActive('bold'),\n canBold: snapshot.editor.can().chain().toggleBold().run(),\n isItalic: snapshot.editor.isActive('italic'),\n canItalic: snapshot.editor.can().chain().toggleItalic().run(),\n isLink: snapshot.editor.isActive('link'),\n isBulletList: snapshot.editor.isActive('bulletList'),\n canLink: snapshot.editor.can().chain().toggleLink({ href: 'https://www.google.com' }).run(),\n isTable: snapshot.editor.isActive('table'),\n canInsertTable: snapshot.editor\n .can()\n .chain()\n .insertTable({ rows: 3, cols: 3, withHeaderRow: true })\n .run(),\n },\n });\n\n if (!editor || !editorState) {\n return null;\n }\n\n // The plugin closes the toolbar off the editor's blur, which cannot fire again\n // once focus has moved in here, so leaving from the toolbar has to close it.\n // Focus only lands on its next target after this event, hence the tick.\n const handleToolbarBlur = () => {\n blurTimeout.current = setTimeout(() => {\n if (editor.isDestroyed || isFocusWithinToolbar() || editor.view.hasFocus()) {\n return;\n }\n editor.view.dispatch(editor.state.tr.setMeta(pluginKey, 'hide'));\n });\n };\n\n return (\n <BubbleMenu\n editor={editor}\n pluginKey={pluginKey}\n options={bubbleMenuOptions}\n getReferencedVirtualElement={getReferencedVirtualElement}\n shouldShow={shouldShow}\n // Floating UI sets no z-index on the portaled menu (Tippy used 9999).\n style={{ zIndex: Z_INDICES.modalElevated }}\n >\n <AnimatePresence>\n <BubbleMenuBar\n ref={toolbarRef}\n role='toolbar'\n aria-label='Text formatting'\n direction='horizontal'\n spacing={Spacing[1]}\n onBlur={handleToolbarBlur}\n >\n {!editingLink ? (\n <IconContainer\n key='main-toolbar'\n layout\n initial={{ x: -10, opacity: 0 }}\n animate={{ x: 0, opacity: 1 }}\n exit={{ x: -10, opacity: 0 }}\n transition={{ duration: 0.2, ease: 'easeOut' }}\n >\n <InverseIconButton\n onClick={() => editor.chain().focus().toggleBulletList().run()}\n $selected={editorState.isBulletList}\n size='sm'\n type='button'\n aria-label='Toggle bullet list'\n data-rte-menu-bar-item\n >\n <ListIcon />\n </InverseIconButton>\n <InverseIconButton\n onClick={() => editor.chain().focus().toggleBold().run()}\n disabled={!editorState.canBold}\n $selected={editorState.isBold}\n size='sm'\n type='button'\n aria-label='Toggle bold'\n data-rte-menu-bar-item\n >\n <BoldIcon />\n </InverseIconButton>\n <InverseIconButton\n onClick={() => editor.chain().focus().toggleItalic().run()}\n $selected={editorState.isItalic}\n disabled={!editorState.canItalic}\n type='button'\n size='sm'\n aria-label='Toggle italic'\n data-rte-menu-bar-item\n >\n <ItalicIcon />\n </InverseIconButton>\n <InverseIconButton\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n openLinkEditingMode();\n }}\n $selected={editorState.isLink}\n disabled={!editorState.canLink}\n size='sm'\n type='button'\n aria-label='Toggle link'\n data-rte-menu-bar-item\n >\n <LinkIcon />\n </InverseIconButton>\n {editorState.isTable ? (\n <DropdownMenu\n contentProps={{\n // @ts-expect-error data attribute on dropdown menu\n 'data-rte-menu-bar-item': 'table-actions-dropdown-menu',\n onCloseAutoFocus: (event) => {\n event.preventDefault();\n editor.commands.focus();\n },\n }}\n trigger={\n <InverseIconButton\n size='sm'\n type='button'\n aria-label='Table actions'\n data-rte-menu-bar-item\n $selected\n >\n <GridIcon />\n </InverseIconButton>\n }\n >\n <StyledDropdownItem\n id='floating-toolbar__tableAddRowAfter'\n variant='basic'\n data-rte-menu-bar-item='table-add-row-after'\n onClick={() => editor.chain().focus().addRowAfter().run()}\n >\n Add row below\n </StyledDropdownItem>\n <StyledDropdownItem\n id='floating-toolbar__tableAddRowBefore'\n variant='basic'\n data-rte-menu-bar-item='table-add-row-before'\n onClick={() => editor.chain().focus().addRowBefore().run()}\n >\n Add row above\n </StyledDropdownItem>\n <StyledDropdownItem\n id='floating-toolbar__tableAddColumnAfter'\n variant='basic'\n data-rte-menu-bar-item='table-add-column-after'\n onClick={() => editor.chain().focus().addColumnAfter().run()}\n >\n Add column right\n </StyledDropdownItem>\n <StyledDropdownItem\n id='floating-toolbar__tableAddColumnBefore'\n variant='basic'\n data-rte-menu-bar-item='table-add-column-before'\n onClick={() => editor.chain().focus().addColumnBefore().run()}\n >\n Add column left\n </StyledDropdownItem>\n <StyledDropdownItem\n id='floating-toolbar__tableDeleteRow'\n variant='basic'\n data-rte-menu-bar-item='table-delete-row'\n onClick={() => editor.chain().focus().deleteRow().run()}\n >\n Delete row\n </StyledDropdownItem>\n <StyledDropdownItem\n id='floating-toolbar__tableDeleteColumn'\n variant='basic'\n data-rte-menu-bar-item='table-delete-column'\n onClick={() => editor.chain().focus().deleteColumn().run()}\n >\n Delete column\n </StyledDropdownItem>\n <StyledDropdownItem\n id='floating-toolbar__tableToggleHeaderRow'\n variant='basic'\n data-rte-menu-bar-item='table-toggle-header-row'\n onClick={() => editor.chain().focus().toggleHeaderRow().run()}\n >\n Toggle header row\n </StyledDropdownItem>\n <StyledDropdownItem\n id='floating-toolbar__tableDelete'\n variant='basic'\n data-rte-menu-bar-item='table-delete'\n onClick={() => editor.chain().focus().deleteTable().run()}\n >\n Delete table\n </StyledDropdownItem>\n </DropdownMenu>\n ) : (\n <InverseIconButton\n onClick={() =>\n editor\n .chain()\n .focus()\n .insertTable({ rows: 3, cols: 3, withHeaderRow: true })\n .run()\n }\n disabled={!editorState.canInsertTable}\n size='sm'\n type='button'\n aria-label='Insert table'\n data-rte-menu-bar-item\n >\n <GridIcon />\n </InverseIconButton>\n )}\n </IconContainer>\n ) : (\n <IconContainer\n key='link-toolbar'\n initial={{ x: -10, opacity: 0 }}\n animate={{ x: 0, opacity: 1 }}\n exit={{ x: -10, opacity: 0 }}\n transition={{ duration: 0.2, ease: 'easeOut' }}\n aria-label='Link toolbar'\n onAnimationComplete={() => {\n if (editor && savedSelection.current) {\n setTimeout(() => {\n restoreSelection();\n linkInputRef.current?.focus();\n }, 10);\n }\n }}\n >\n <InverseInput\n ref={linkInputRef}\n size='sm'\n value={linkURL}\n onChange={(e) => setLinkURL(e.target.value)}\n placeholder='Click to enter URL...'\n aria-label='Link input'\n data-rte-menu-bar-item\n onClick={() => {\n linkInputRef.current?.focus();\n }}\n onFocus={() => {\n if (savedSelection.current && editor) {\n const { from, to } = savedSelection.current;\n editor.chain().setTextSelection({ from, to }).run();\n }\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && linkURL.trim() && editor && savedSelection.current) {\n e.preventDefault();\n e.stopPropagation();\n const { from, to } = savedSelection.current;\n editor\n .chain()\n .focus()\n .setTextSelection({ from, to })\n .setLink({ href: ensureProtocol(linkURL) })\n .run();\n savedSelection.current = null;\n setEditingLink(false);\n setLinkURL('');\n return;\n }\n if (e.key === 'Escape') {\n e.preventDefault();\n e.stopPropagation();\n setEditingLink(false);\n setLinkURL('');\n savedSelection.current = null;\n const { from, to } = editor.state.selection;\n editor.chain().focus().setTextSelection({ from, to }).run();\n }\n }}\n />\n <InverseIconButton\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n if (linkURL) {\n editor.chain().focus().unsetLink().run();\n }\n restoreSelection();\n setLinkURL('');\n savedSelection.current = null;\n setEditingLink(false);\n }}\n size='sm'\n type='button'\n aria-label='Cancel link'\n data-rte-menu-bar-item\n >\n {linkURL && editorState.isLink ? <UnlinkIcon /> : <XIcon />}\n </InverseIconButton>\n <InverseIconButton\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n if (linkURL.trim() && editor && savedSelection.current) {\n const { from, to } = savedSelection.current;\n editor\n .chain()\n .focus()\n .setTextSelection({ from, to })\n .setLink({ href: ensureProtocol(linkURL) })\n .run();\n } else if (editor && savedSelection.current) {\n const { from, to } = savedSelection.current;\n editor.chain().focus().setTextSelection({ from, to }).unsetLink().run();\n }\n savedSelection.current = null;\n setEditingLink(false);\n setLinkURL('');\n }}\n size='sm'\n type='button'\n aria-label='Apply link'\n data-rte-menu-bar-item\n >\n <CheckIcon />\n </InverseIconButton>\n </IconContainer>\n )}\n </BubbleMenuBar>\n </AnimatePresence>\n </BubbleMenu>\n );\n}\n\nexport default FloatingToolbar;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FloatingToolbar-DLRaE0o7.mjs","names":["Input","DropdownMenu"],"sources":["../src/components/FloatingToolbar/FloatingToolbar.tsx"],"sourcesContent":["import { PluginKey } from '@tiptap/pm/state';\nimport type { EditorView } from '@tiptap/pm/view';\nimport { useEditorState, type Editor } from '@tiptap/react';\nimport { BubbleMenu } from '@tiptap/react/menus';\nimport { AnimatePresence, motion } from 'framer-motion';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport styled from 'styled-components';\n\nimport { BorderRadius, Color, Spacing } from '@persona/design-tokens';\nimport {\n BoldIcon,\n CheckIcon,\n GridIcon,\n ItalicIcon,\n LinkIcon,\n ListIcon,\n UnlinkIcon,\n XIcon,\n} from '@persona/icons';\n\nimport { IconButton } from '#src/components/Button';\nimport DropdownMenu from '#src/components/DropdownMenu';\nimport Input from '#src/components/Input';\nimport Stack from '#src/components/Stack';\nimport { Z_INDICES } from '#src/lib/zindex';\nimport { TransitionDuration } from '#src/variables/transitions';\n\n// Core* colors throughout this file are intentional: the bubble toolbar is an\n// always-dark inverse surface floating over the editor, so it must not track\n// the semantic surface theme.\nconst BubbleMenuBar = styled(Stack)`\n padding: ${Spacing[1]} ${Spacing[2]};\n background-color: ${Color.CoreSlate1100};\n border-radius: ${BorderRadius.Lg};\n`;\n\nconst IconContainer = styled(motion.div)`\n display: flex;\n gap: ${Spacing[1]};\n`;\n\nconst InverseIconButton = styled(IconButton)<{ $selected?: boolean }>`\n background-color: ${({ $selected }) => ($selected ? Color.CoreSlate900 : 'transparent')};\n color: ${Color.PrimaryWhite};\n transition: background-color ${TransitionDuration.ExtraFast} ease-out;\n\n &:hover:not(:disabled) {\n background-color: ${Color.CoreSlate800};\n }\n\n &:disabled {\n background-color: transparent;\n opacity: 0.35;\n }\n`;\n\nconst InverseInput = styled(Input)`\n background-color: ${Color.CoreSlate900};\n color: ${Color.PrimaryWhite};\n\n :focus-within {\n border-color: ${Color.CoreBlue700};\n }\n ::placeholder {\n color: ${Color.TextDisabled};\n }\n\n input {\n background-color: ${Color.CoreSlate900};\n color: ${Color.PrimaryWhite};\n }\n`;\n\nconst StyledDropdownItem = styled(DropdownMenu.Item)`\n width: 100%;\n height: 30px;\n font-size: small;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n`;\n\n// Floating UI takes its offset as numbers while the spacing tokens are CSS lengths.\nconst TOOLBAR_GAP = parseInt(Spacing[1]);\n\n// Anchored to the field, the toolbar lines up with the input's left edge; over a\n// selection it sits back a notch so it does not crowd the first selected glyph.\nconst FIELD_OFFSET = { mainAxis: TOOLBAR_GAP, crossAxis: 0 };\nconst SELECTION_OFFSET = { mainAxis: TOOLBAR_GAP, crossAxis: -parseInt(Spacing[2]) };\n\n// The element EditorContent mounts the editor into — the visible field. Tiptap\n// types `options.element` loosely, so fall back to the editable root.\nconst getFieldElement = (editor: Editor): Element =>\n editor.options.element instanceof Element ? editor.options.element : editor.view.dom;\n\n// Schemes we trust as link targets. Anything else (no scheme, or an unsafe one\n// like javascript:/data:/vbscript:) is treated as a bare host and forced onto\n// https, which both preserves host:port input and neutralizes script schemes.\nconst SAFE_LINK_SCHEME = /^(https?|mailto|tel):/i;\nconst URI_SCHEME = /^[a-zA-Z][a-zA-Z0-9+.-]*:/;\n\nexport const ensureProtocol = (url: string): string => {\n const trimmedUrl = url.trim();\n if (!trimmedUrl) {\n return '';\n }\n // Handlebars placeholders (e.g. {{inquiry.id}}) are legitimate link targets in\n // templated messages — the template render produces the final URL, so pass\n // the expression through unvalidated. Only when nothing before the first\n // placeholder looks like an unsafe scheme: javascript:alert(1)//{{x}} would\n // otherwise smuggle a script href past the allowlist. URL parsers strip C0\n // controls, tabs and spaces before reading the scheme, so normalize the\n // prefix the same way first — java\\tscript:...{{x}} must not slip through.\n if (trimmedUrl.includes('{{')) {\n const beforePlaceholder = trimmedUrl\n .slice(0, trimmedUrl.indexOf('{{'))\n // eslint-disable-next-line no-control-regex -- mirrors how URL parsers strip C0/space before reading the scheme\n .replace(/[\\u0000-\\u0020]/g, '');\n if (!URI_SCHEME.test(beforePlaceholder) || SAFE_LINK_SCHEME.test(beforePlaceholder)) {\n return trimmedUrl;\n }\n return '';\n }\n const candidate = SAFE_LINK_SCHEME.test(trimmedUrl) ? trimmedUrl : `https://${trimmedUrl}`;\n // Re-parse so malformed input — including an unsafe scheme that can't survive\n // the https prefix — is dropped instead of applied as a broken href.\n return URL.canParse(candidate) ? candidate : '';\n};\n\ninterface FloatingToolbarProps {\n /** TipTap editor instance to operate on. */\n editor: Editor | null;\n /**\n * Keep the toolbar up the whole time the editor is focused instead of only\n * while text is selected, so the formatting actions are discoverable without\n * knowing to select first.\n */\n showOnFocus?: boolean;\n}\n\n/**\n * Floating bubble toolbar that appears on text selection or inside a table, or —\n * with `showOnFocus` — for as long as the editor is focused.\n * Keyboard shortcut: Cmd/Ctrl+Shift+U opens the link-edit row.\n */\nfunction FloatingToolbar({ editor, showOnFocus = false }: FloatingToolbarProps) {\n const [linkURL, setLinkURL] = useState('');\n const [editingLink, setEditingLink] = useState(false);\n const linkInputRef = useRef<HTMLInputElement>(null);\n const toolbarRef = useRef<HTMLDivElement>(null);\n const savedSelection = useRef<{ from: number; to: number } | null>(null);\n const editingLinkRef = useRef(editingLink);\n const blurTimeout = useRef<ReturnType<typeof setTimeout>>();\n // Lets the toolbar close its own bubble menu plugin via a `hide` meta.\n const [pluginKey] = useState(() => new PluginKey('floatingToolbar'));\n\n useEffect(() => () => clearTimeout(blurTimeout.current), []);\n\n useEffect(() => {\n editingLinkRef.current = editingLink;\n }, [editingLink]);\n\n const restoreSelection = useCallback(() => {\n if (editor && savedSelection.current) {\n const { from, to } = savedSelection.current;\n editor.chain().focus().setTextSelection({ from, to }).run();\n }\n }, [editor]);\n\n const openLinkEditingMode = useCallback(() => {\n if (!editor) {\n return;\n }\n if (!editor.can().chain().toggleLink({ href: 'https://www.google.com' }).run()) {\n return;\n }\n\n const { from, to } = editor.state.selection;\n savedSelection.current = { from, to };\n\n const linkAttr = editor.getAttributes('link');\n if (linkAttr.href) {\n setLinkURL(linkAttr.href);\n }\n\n editor.chain().focus().setTextSelection({ from, to }).run();\n setEditingLink(true);\n\n setTimeout(() => {\n linkInputRef.current?.focus();\n }, 250);\n }, [editor]);\n\n // Cmd/Ctrl+Shift+U → open link mode; Escape inside link mode → cancel.\n useEffect(() => {\n if (!editor) {\n return undefined;\n }\n const dom = editor.view.dom;\n const handler = (event: KeyboardEvent) => {\n if ((event.metaKey || event.ctrlKey) && event.shiftKey && event.key.toLowerCase() === 'u') {\n event.preventDefault();\n openLinkEditingMode();\n return;\n }\n if (event.key === 'Escape' && editingLinkRef.current) {\n event.preventDefault();\n setEditingLink(false);\n setLinkURL('');\n savedSelection.current = null;\n }\n };\n dom.addEventListener('keydown', handler);\n return () => {\n dom.removeEventListener('keydown', handler);\n };\n }, [editor, openLinkEditingMode]);\n\n // Keep selection highlighted while focus is in the link input.\n useEffect(() => {\n if (!editingLink || !editor || !savedSelection.current) {\n return undefined;\n }\n restoreSelection();\n const timeoutId = setTimeout(() => {\n restoreSelection();\n editor.view.dom?.focus();\n }, 0);\n return () => clearTimeout(timeoutId);\n }, [editingLink, restoreSelection, editor]);\n\n // Pressing a toolbar button focuses that button, and the command's own\n // transaction re-runs this check before the chained `.focus()` hands focus\n // back to the editor. Ignoring focus held inside the toolbar therefore tears\n // the bar down for a frame mid-click, taking the pressed button with it.\n const isFocusWithinToolbar = useCallback(\n () => !!toolbarRef.current?.contains(document.activeElement),\n [],\n );\n\n // BubbleMenu dispatches an options-update transaction whenever these props\n // change identity, and editors that re-render per transaction would then\n // loop — so keep them stable across renders.\n const bubbleMenuOptions = useMemo(\n () => ({\n placement: 'top-start' as const,\n offset: showOnFocus ? FIELD_OFFSET : SELECTION_OFFSET,\n }),\n [showOnFocus],\n );\n\n // Sitting above the field rather than the selection: a toolbar that is up\n // for the whole time the field is focused looks jumpy if it chases the\n // caret and hops between selections.\n const getReferencedVirtualElement = useMemo(\n () =>\n showOnFocus && editor\n ? () => ({ getBoundingClientRect: () => getFieldElement(editor).getBoundingClientRect() })\n : undefined,\n [editor, showOnFocus],\n );\n\n const shouldShow = useCallback(\n ({\n editor: e,\n view,\n from,\n to,\n }: {\n editor: Editor;\n view: EditorView;\n from: number;\n to: number;\n }) => {\n if (!e.isEditable) {\n return false;\n }\n if (e.isActive('mention')) {\n return false;\n }\n // The toolbar carries the table-actions dropdown — a collapsed caret\n // inside a table must still show it or row/column controls are\n // unreachable.\n if (e.isActive('table')) {\n return true;\n }\n if (from !== to) {\n return true;\n }\n return showOnFocus && (view.hasFocus() || isFocusWithinToolbar());\n },\n [isFocusWithinToolbar, showOnFocus],\n );\n\n // Self-subscribe: standalone use can't rely on the host's useEditor options (shouldRerenderOnTransaction is off by default in Tiptap 3).\n const editorState = useEditorState({\n editor,\n selector: (snapshot) =>\n snapshot.editor && {\n isBold: snapshot.editor.isActive('bold'),\n canBold: snapshot.editor.can().chain().toggleBold().run(),\n isItalic: snapshot.editor.isActive('italic'),\n canItalic: snapshot.editor.can().chain().toggleItalic().run(),\n isLink: snapshot.editor.isActive('link'),\n isBulletList: snapshot.editor.isActive('bulletList'),\n canLink: snapshot.editor.can().chain().toggleLink({ href: 'https://www.google.com' }).run(),\n isTable: snapshot.editor.isActive('table'),\n canInsertTable: snapshot.editor\n .can()\n .chain()\n .insertTable({ rows: 3, cols: 3, withHeaderRow: true })\n .run(),\n },\n });\n\n if (!editor || !editorState) {\n return null;\n }\n\n // The plugin closes the toolbar off the editor's blur, which cannot fire again\n // once focus has moved in here, so leaving from the toolbar has to close it.\n // Focus only lands on its next target after this event, hence the tick.\n const handleToolbarBlur = () => {\n blurTimeout.current = setTimeout(() => {\n if (editor.isDestroyed || isFocusWithinToolbar() || editor.view.hasFocus()) {\n return;\n }\n editor.view.dispatch(editor.state.tr.setMeta(pluginKey, 'hide'));\n });\n };\n\n return (\n <BubbleMenu\n editor={editor}\n pluginKey={pluginKey}\n options={bubbleMenuOptions}\n getReferencedVirtualElement={getReferencedVirtualElement}\n shouldShow={shouldShow}\n // Floating UI sets no z-index on the portaled menu (Tippy used 9999).\n style={{ zIndex: Z_INDICES.modalElevated }}\n >\n <AnimatePresence>\n <BubbleMenuBar\n ref={toolbarRef}\n role='toolbar'\n aria-label='Text formatting'\n direction='horizontal'\n spacing={Spacing[1]}\n onBlur={handleToolbarBlur}\n >\n {!editingLink ? (\n <IconContainer\n key='main-toolbar'\n layout\n initial={{ x: -10, opacity: 0 }}\n animate={{ x: 0, opacity: 1 }}\n exit={{ x: -10, opacity: 0 }}\n transition={{ duration: 0.2, ease: 'easeOut' }}\n >\n <InverseIconButton\n onClick={() => editor.chain().focus().toggleBulletList().run()}\n $selected={editorState.isBulletList}\n size='sm'\n type='button'\n aria-label='Toggle bullet list'\n data-rte-menu-bar-item\n >\n <ListIcon />\n </InverseIconButton>\n <InverseIconButton\n onClick={() => editor.chain().focus().toggleBold().run()}\n disabled={!editorState.canBold}\n $selected={editorState.isBold}\n size='sm'\n type='button'\n aria-label='Toggle bold'\n data-rte-menu-bar-item\n >\n <BoldIcon />\n </InverseIconButton>\n <InverseIconButton\n onClick={() => editor.chain().focus().toggleItalic().run()}\n $selected={editorState.isItalic}\n disabled={!editorState.canItalic}\n type='button'\n size='sm'\n aria-label='Toggle italic'\n data-rte-menu-bar-item\n >\n <ItalicIcon />\n </InverseIconButton>\n <InverseIconButton\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n openLinkEditingMode();\n }}\n $selected={editorState.isLink}\n disabled={!editorState.canLink}\n size='sm'\n type='button'\n aria-label='Toggle link'\n data-rte-menu-bar-item\n >\n <LinkIcon />\n </InverseIconButton>\n {editorState.isTable ? (\n <DropdownMenu\n contentProps={{\n // @ts-expect-error data attribute on dropdown menu\n 'data-rte-menu-bar-item': 'table-actions-dropdown-menu',\n onCloseAutoFocus: (event) => {\n event.preventDefault();\n editor.commands.focus();\n },\n }}\n trigger={\n <InverseIconButton\n size='sm'\n type='button'\n aria-label='Table actions'\n data-rte-menu-bar-item\n $selected\n >\n <GridIcon />\n </InverseIconButton>\n }\n >\n <StyledDropdownItem\n id='floating-toolbar__tableAddRowAfter'\n variant='basic'\n data-rte-menu-bar-item='table-add-row-after'\n onClick={() => editor.chain().focus().addRowAfter().run()}\n >\n Add row below\n </StyledDropdownItem>\n <StyledDropdownItem\n id='floating-toolbar__tableAddRowBefore'\n variant='basic'\n data-rte-menu-bar-item='table-add-row-before'\n onClick={() => editor.chain().focus().addRowBefore().run()}\n >\n Add row above\n </StyledDropdownItem>\n <StyledDropdownItem\n id='floating-toolbar__tableAddColumnAfter'\n variant='basic'\n data-rte-menu-bar-item='table-add-column-after'\n onClick={() => editor.chain().focus().addColumnAfter().run()}\n >\n Add column right\n </StyledDropdownItem>\n <StyledDropdownItem\n id='floating-toolbar__tableAddColumnBefore'\n variant='basic'\n data-rte-menu-bar-item='table-add-column-before'\n onClick={() => editor.chain().focus().addColumnBefore().run()}\n >\n Add column left\n </StyledDropdownItem>\n <StyledDropdownItem\n id='floating-toolbar__tableDeleteRow'\n variant='basic'\n data-rte-menu-bar-item='table-delete-row'\n onClick={() => editor.chain().focus().deleteRow().run()}\n >\n Delete row\n </StyledDropdownItem>\n <StyledDropdownItem\n id='floating-toolbar__tableDeleteColumn'\n variant='basic'\n data-rte-menu-bar-item='table-delete-column'\n onClick={() => editor.chain().focus().deleteColumn().run()}\n >\n Delete column\n </StyledDropdownItem>\n <StyledDropdownItem\n id='floating-toolbar__tableToggleHeaderRow'\n variant='basic'\n data-rte-menu-bar-item='table-toggle-header-row'\n onClick={() => editor.chain().focus().toggleHeaderRow().run()}\n >\n Toggle header row\n </StyledDropdownItem>\n <StyledDropdownItem\n id='floating-toolbar__tableDelete'\n variant='basic'\n data-rte-menu-bar-item='table-delete'\n onClick={() => editor.chain().focus().deleteTable().run()}\n >\n Delete table\n </StyledDropdownItem>\n </DropdownMenu>\n ) : (\n <InverseIconButton\n onClick={() =>\n editor\n .chain()\n .focus()\n .insertTable({ rows: 3, cols: 3, withHeaderRow: true })\n .run()\n }\n disabled={!editorState.canInsertTable}\n size='sm'\n type='button'\n aria-label='Insert table'\n data-rte-menu-bar-item\n >\n <GridIcon />\n </InverseIconButton>\n )}\n </IconContainer>\n ) : (\n <IconContainer\n key='link-toolbar'\n initial={{ x: -10, opacity: 0 }}\n animate={{ x: 0, opacity: 1 }}\n exit={{ x: -10, opacity: 0 }}\n transition={{ duration: 0.2, ease: 'easeOut' }}\n aria-label='Link toolbar'\n onAnimationComplete={() => {\n if (editor && savedSelection.current) {\n setTimeout(() => {\n restoreSelection();\n linkInputRef.current?.focus();\n }, 10);\n }\n }}\n >\n <InverseInput\n ref={linkInputRef}\n size='sm'\n value={linkURL}\n onChange={(e) => setLinkURL(e.target.value)}\n placeholder='Click to enter URL...'\n aria-label='Link input'\n data-rte-menu-bar-item\n onClick={() => {\n linkInputRef.current?.focus();\n }}\n onFocus={() => {\n if (savedSelection.current && editor) {\n const { from, to } = savedSelection.current;\n editor.chain().setTextSelection({ from, to }).run();\n }\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && linkURL.trim() && editor && savedSelection.current) {\n e.preventDefault();\n e.stopPropagation();\n const { from, to } = savedSelection.current;\n editor\n .chain()\n .focus()\n .setTextSelection({ from, to })\n .setLink({ href: ensureProtocol(linkURL) })\n .run();\n savedSelection.current = null;\n setEditingLink(false);\n setLinkURL('');\n return;\n }\n if (e.key === 'Escape') {\n e.preventDefault();\n e.stopPropagation();\n setEditingLink(false);\n setLinkURL('');\n savedSelection.current = null;\n const { from, to } = editor.state.selection;\n editor.chain().focus().setTextSelection({ from, to }).run();\n }\n }}\n />\n <InverseIconButton\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n if (linkURL) {\n editor.chain().focus().unsetLink().run();\n }\n restoreSelection();\n setLinkURL('');\n savedSelection.current = null;\n setEditingLink(false);\n }}\n size='sm'\n type='button'\n aria-label='Cancel link'\n data-rte-menu-bar-item\n >\n {linkURL && editorState.isLink ? <UnlinkIcon /> : <XIcon />}\n </InverseIconButton>\n <InverseIconButton\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n if (linkURL.trim() && editor && savedSelection.current) {\n const { from, to } = savedSelection.current;\n editor\n .chain()\n .focus()\n .setTextSelection({ from, to })\n .setLink({ href: ensureProtocol(linkURL) })\n .run();\n } else if (editor && savedSelection.current) {\n const { from, to } = savedSelection.current;\n editor.chain().focus().setTextSelection({ from, to }).unsetLink().run();\n }\n savedSelection.current = null;\n setEditingLink(false);\n setLinkURL('');\n }}\n size='sm'\n type='button'\n aria-label='Apply link'\n data-rte-menu-bar-item\n >\n <CheckIcon />\n </InverseIconButton>\n </IconContainer>\n )}\n </BubbleMenuBar>\n </AnimatePresence>\n </BubbleMenu>\n );\n}\n\nexport default FloatingToolbar;\n"],"mappings":"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"}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { t as HStack } from "./Stack-Bzom2BTR.mjs";
|
|
2
|
-
import { t as IconButton } from "./IconButton-
|
|
2
|
+
import { t as IconButton } from "./IconButton-DxHB2g80.mjs";
|
|
3
3
|
import { n as useFormGroup } from "./useFormGroup-DSQkoWLh.mjs";
|
|
4
4
|
import { t as FormControlContext } from "./useFormField-pOVkb5BK.mjs";
|
|
5
5
|
import Input_default from "./components/Input/index.mjs";
|
|
6
|
-
import { n as DropdownMenu_default } from "./DropdownMenu-
|
|
6
|
+
import { n as DropdownMenu_default } from "./DropdownMenu-c8XK2Lr4.mjs";
|
|
7
7
|
import { t as Checkbox } from "./Checkbox-Dr4LMKHV.mjs";
|
|
8
|
-
import { t as Combobox } from "./Combobox-
|
|
9
|
-
import { n as Select } from "./Select-
|
|
8
|
+
import { t as Combobox } from "./Combobox-Gb_j1dg6.mjs";
|
|
9
|
+
import { n as Select } from "./Select-DOlw_LPR.mjs";
|
|
10
10
|
import { a as FormLabel, i as FormInputContainer, n as ErrorText, o as HelperText, r as FormControl, s as WarningText } from "./FormControl-BztNXLn6.mjs";
|
|
11
|
-
import { t as ListBox } from "./ListBox-
|
|
11
|
+
import { t as ListBox } from "./ListBox-BZp6exb8.mjs";
|
|
12
12
|
import { t as RadioGroup } from "./RadioGroup-CMrXmmn4.mjs";
|
|
13
13
|
import { t as SegmentedControl } from "./SegmentedControl-D_DA-MU1.mjs";
|
|
14
14
|
import { t as TextAreaWithStyle } from "./TextArea-Dro-HH8O.mjs";
|
|
15
15
|
import { t as Toggle } from "./Toggle-D9MzTIZs.mjs";
|
|
16
|
-
import { t as TableBox } from "./TableBox-
|
|
16
|
+
import { t as TableBox } from "./TableBox-DNQsgQ8x.mjs";
|
|
17
17
|
import { Children, Fragment, cloneElement, createContext, forwardRef, useContext, useMemo, useRef, useState } from "react";
|
|
18
18
|
import { Spacing } from "@persona/design-tokens";
|
|
19
19
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -483,4 +483,4 @@ TableBoxField.Cell = TableBox.Cell;
|
|
|
483
483
|
//#endregion
|
|
484
484
|
export { CheckboxField as a, SegmentedControlField as c, TextField as d, ToggleField as f, CheckboxGroupField as i, SelectField as l, FormField as m, TableBoxField as n, ComboboxField as o, splitOutFormFieldProps as p, ListBoxField as r, RadioGroupField as s, TABLE_BOX_FIELD_ADD_BUTTON_ARIA_LABEL as t, TextAreaField as u };
|
|
485
485
|
|
|
486
|
-
//# sourceMappingURL=FormField-
|
|
486
|
+
//# sourceMappingURL=FormField-Cf1VMvoa.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormField-BStxmlZT.mjs","names":["Input","TextArea","DropdownMenu","DropdownMenu"],"sources":["../src/components/FormField/FormField.tsx","../src/components/FormField/inputFields.tsx","../src/components/FormField/CheckboxGroupField.tsx","../src/components/FormField/ListBoxField.tsx","../src/components/FormField/TableBoxField.tsx"],"sourcesContent":["import { type ComponentPropsWithRef, forwardRef, type ReactElement, type ReactNode } from 'react';\n\nimport { Spacing } from '@persona/design-tokens';\n\nimport useFormGroup from '#src/components/ConfigFormGroup/useFormGroup';\nimport FormControl, {\n ErrorText,\n type FormControlProps,\n FormInputContainer,\n FormLabel,\n HelperText,\n WarningText,\n} from '#src/components/FormControl';\nimport { HStack } from '#src/components/Stack';\n\nexport interface FormFieldBaseProps {\n /**\n * Renders `<Label>` above input\n */\n label?: ReactNode;\n\n /**\n * ID of the input element. Providing this will automatically link the label to the input.\n */\n inputId?: string;\n\n /** Marks the field as required. The label renders an asterisk; composed fields also forward `required` to their input. */\n required?: boolean;\n\n /**\n * Renders `<HelperText>` below input\n */\n helperText?: ReactNode;\n\n /**\n * Renders `<ErrorText>` below input and helper text.\n */\n errorText?: ReactNode;\n\n /**\n * Renders `<WarningText>` below input and helper text.\n */\n warningText?: ReactNode;\n\n /**\n * Should be an input of some sort\n */\n children?: ReactElement;\n\n labelProps?: ComponentPropsWithRef<typeof FormLabel>;\n helperProps?: ComponentPropsWithRef<typeof HelperText>;\n warningProps?: ComponentPropsWithRef<typeof WarningText>;\n errorProps?: ComponentPropsWithRef<typeof ErrorText>;\n\n /**\n * Whether to render the form field as a config field.\n * This will render the helper text as a tooltip.\n */\n configField?: boolean;\n\n /**\n * Override the width of the input area when `configField` is true.\n * Accepts any valid CSS width value (e.g. `'33%'`, `'66.67%'`).\n * Defaults to `'50%'`.\n */\n configFieldInputWidth?: string;\n\n /**\n * Renders actions to the right of the label.\n */\n rightActions?: ReactNode;\n}\n\nexport interface FormFieldProps extends Omit<FormControlProps, 'children'>, FormFieldBaseProps {}\n\n/**\n * Helper component with preset slots for label, input, and helper texts.\n *\n * Prefer a composed field component, such as `<TextField>`, `<SelectField>`, or\n * `<CheckboxField>`, when one is available for the input type. Use `<FormField>` directly\n * when composing a custom control or layout.\n *\n * ## Usage\n *\n * ```tsx\n * import FormField from '@persona/design-system/components/FormField';\n * ```\n */\nexport const FormField = forwardRef<HTMLDivElement, FormFieldProps>(function FormField(\n {\n label,\n children,\n helperText,\n warningText,\n errorText,\n labelProps,\n helperProps,\n warningProps,\n errorProps,\n configField: configFieldProp,\n configFieldInputWidth,\n rightActions,\n ...props\n }: FormFieldProps,\n ref,\n) {\n const { configField: configFieldFormGroup } = useFormGroup();\n const configField = configFieldProp ?? configFieldFormGroup;\n\n const labelElement = label ? (\n <FormLabel tooltip={configField && helperText ? helperText : undefined} {...labelProps}>\n {label}\n </FormLabel>\n ) : null;\n\n return (\n <FormControl\n hasError={!!errorText}\n hasWarning={!!warningText}\n ref={ref}\n configField={configField}\n hasRightActions={!!rightActions}\n configFieldInputWidth={configFieldInputWidth}\n {...props}\n >\n {rightActions ? (\n <HStack justify='space-between' align='center'>\n {labelElement}\n <HStack spacing={Spacing[1]}>{rightActions}</HStack>\n </HStack>\n ) : (\n labelElement\n )}\n <FormInputContainer>{children}</FormInputContainer>\n {!configField && helperText && <HelperText {...helperProps}>{helperText}</HelperText>}\n {!configField && warningText && <WarningText {...warningProps}>{warningText}</WarningText>}\n {!configField && errorText && <ErrorText {...errorProps}>{errorText}</ErrorText>}\n </FormControl>\n );\n});\n\nexport default FormField;\n","import { uniqueId } from 'lodash-es';\nimport { forwardRef, useMemo } from 'react';\n\nimport Checkbox, { type CheckboxProps } from '#src/components/Checkbox';\nimport Combobox from '#src/components/Combobox';\nimport type { ComboboxMultiSelectProps } from '#src/components/Combobox/ComboboxMultiSelect';\nimport type { ComboboxSingleSelectProps } from '#src/components/Combobox/ComboboxSingleSelect';\nimport FormField, { type FormFieldBaseProps } from '#src/components/FormField/FormField';\nimport Input, { type InputProps } from '#src/components/Input';\nimport RadioGroup, { type RadioGroupProps } from '#src/components/RadioGroup';\nimport SegmentedControl, { type SegmentedControlProps } from '#src/components/SegmentedControl';\nimport Select, { type SelectProps } from '#src/components/Select';\nimport TextArea, { type TextAreaProps } from '#src/components/TextArea';\nimport Toggle, { type ToggleProps } from '#src/components/Toggle';\n\nexport type ImplementsFormField = Omit<FormFieldBaseProps, 'children'>;\n\ntype ExtractFormFieldProps<T extends ImplementsFormField> = Pick<\n T,\n | 'label'\n | 'inputId'\n | 'required'\n | 'helperText'\n | 'errorText'\n | 'warningText'\n | 'labelProps'\n | 'helperProps'\n | 'warningProps'\n | 'errorProps'\n | 'configField'\n | 'configFieldInputWidth'\n | 'rightActions'\n>;\ntype OmitFormFieldProps<T extends ImplementsFormField> = Omit<\n T,\n Exclude<keyof ExtractFormFieldProps<T>, 'required'>\n>;\n\n/**\n * Helper to split out props that are sent to the FormField component from props sent\n * to the underlying input component.\n */\nexport const splitOutFormFieldProps = <T extends ImplementsFormField>(\n props: T,\n): {\n formFieldProps: ExtractFormFieldProps<T>;\n inputProps: OmitFormFieldProps<T>;\n} => {\n const {\n label,\n inputId,\n helperText,\n errorText,\n warningText,\n labelProps,\n helperProps,\n warningProps,\n errorProps,\n configField,\n configFieldInputWidth,\n rightActions,\n ...inputProps\n } = props;\n\n return {\n formFieldProps: {\n label,\n inputId,\n required: props.required,\n helperText,\n errorText,\n warningText,\n labelProps,\n helperProps,\n warningProps,\n errorProps,\n configField,\n configFieldInputWidth,\n rightActions,\n },\n inputProps,\n };\n};\n\nexport interface TextFieldProps extends ImplementsFormField, InputProps {}\n\nexport const TextField = forwardRef<HTMLInputElement, TextFieldProps>(\n function TextField(props, ref) {\n const { formFieldProps, inputProps } = splitOutFormFieldProps(props);\n const { id, ...rest } = inputProps;\n\n return (\n <FormField\n {...formFieldProps}\n labelProps={{ size: props.size, ...formFieldProps.labelProps }}\n inputId={formFieldProps.inputId ?? id}\n >\n <Input {...rest} ref={ref} />\n </FormField>\n );\n },\n);\n\nexport interface TextAreaFieldProps extends ImplementsFormField, TextAreaProps {}\n\nexport const TextAreaField = forwardRef<HTMLTextAreaElement, TextAreaFieldProps>(\n function TextAreaField(props, ref) {\n const { formFieldProps, inputProps } = splitOutFormFieldProps(props);\n const { id, ...rest } = inputProps;\n\n return (\n <FormField\n {...formFieldProps}\n labelProps={{ size: props.size, ...formFieldProps.labelProps }}\n inputId={formFieldProps.inputId ?? id}\n >\n <TextArea {...rest} ref={ref} />\n </FormField>\n );\n },\n);\n\nexport interface SelectFieldProps extends ImplementsFormField, SelectProps {}\n\nexport const SelectField = ({ id, children, ...props }: SelectFieldProps) => {\n const { formFieldProps, inputProps } = splitOutFormFieldProps(props);\n const linkedId = useMemo(\n () => formFieldProps.inputId ?? id ?? uniqueId('pds-form-field-input-fields-select__'),\n [formFieldProps.inputId, id],\n );\n\n return (\n <FormField\n {...formFieldProps}\n inputId={linkedId}\n labelProps={{ htmlFor: linkedId, size: inputProps.size, ...formFieldProps.labelProps }}\n >\n <Select {...inputProps} id={linkedId}>\n {children}\n </Select>\n </FormField>\n );\n};\n\nexport interface RadioGroupFieldProps\n extends Omit<ImplementsFormField, 'configField'>, RadioGroupProps {}\n\nexport const RadioGroupField = ({\n label,\n helperText,\n errorText,\n warningText,\n required,\n children,\n ...props\n}: RadioGroupFieldProps) => {\n return (\n <FormField\n label={label}\n helperText={helperText}\n warningText={warningText}\n errorText={errorText}\n required={required}\n >\n <RadioGroup {...props} aria-required={required}>\n {children}\n </RadioGroup>\n </FormField>\n );\n};\n\nexport interface CheckboxFieldProps extends ImplementsFormField, CheckboxProps {\n checkboxLabel?: CheckboxProps['label'];\n}\n\nexport const CheckboxField = ({\n label,\n helperText,\n errorText,\n warningText,\n checkboxLabel,\n configField,\n labelProps,\n required,\n ...props\n}: CheckboxFieldProps) => {\n return (\n <FormField\n label={label}\n helperText={helperText}\n warningText={warningText}\n errorText={errorText}\n configField={configField}\n labelProps={labelProps}\n required={required}\n >\n <Checkbox label={checkboxLabel} required={required} {...props} />\n </FormField>\n );\n};\n\nexport interface ToggleFieldProps extends ImplementsFormField, ToggleProps {}\n\nexport const ToggleField = forwardRef<HTMLDivElement, ToggleFieldProps>(\n function ToggleField(props, ref) {\n const { formFieldProps, inputProps } = splitOutFormFieldProps(props);\n\n return (\n <FormField\n {...formFieldProps}\n labelProps={{ size: inputProps.size, ...formFieldProps.labelProps }}\n >\n <Toggle {...inputProps} ref={ref} />\n </FormField>\n );\n },\n);\n\nexport interface SegmentedControlFieldProps\n extends ImplementsFormField, Omit<SegmentedControlProps, 'children'> {\n children?: SegmentedControlProps['children'];\n}\n\nexport const SegmentedControlField = forwardRef<HTMLDivElement, SegmentedControlFieldProps>(\n function SegmentedControlField(\n {\n label,\n helperText,\n errorText,\n warningText,\n configField,\n required,\n children,\n labelProps,\n ...props\n },\n ref,\n ) {\n return (\n <FormField\n label={label}\n helperText={helperText}\n warningText={warningText}\n errorText={errorText}\n configField={configField}\n labelProps={labelProps}\n required={required}\n >\n <SegmentedControl fullWidth {...props} aria-required={required} ref={ref}>\n {children}\n </SegmentedControl>\n </FormField>\n );\n },\n);\n\nexport type ComboboxSingleSelectFieldProps<T = string> = ImplementsFormField &\n ComboboxSingleSelectProps<T>;\nexport type ComboboxMultiSelectFieldProps<T = string> = ImplementsFormField &\n ComboboxMultiSelectProps<T>;\n\nexport const ComboboxField = (\n props: ComboboxSingleSelectFieldProps | ComboboxMultiSelectFieldProps,\n) => {\n // `Combobox` registers its own id with the surrounding `FormControl`, which is what links the\n // label to it, so the field only forwards an explicit `inputId` when one is given. Each mode is\n // split separately: `multiple` discriminates the two, and a union split at once loses that.\n if (props.multiple) {\n const { formFieldProps, inputProps } = splitOutFormFieldProps(props);\n\n return (\n <FormField {...formFieldProps}>\n <Combobox {...inputProps} />\n </FormField>\n );\n }\n\n const { formFieldProps, inputProps } = splitOutFormFieldProps(props);\n\n return (\n <FormField {...formFieldProps}>\n <Combobox {...inputProps} />\n </FormField>\n );\n};\n","import {\n Children,\n cloneElement,\n type ComponentPropsWithRef,\n createContext,\n type ReactElement,\n type ReactNode,\n useContext,\n useRef,\n} from 'react';\nimport {\n type AriaCheckboxGroupProps,\n mergeProps,\n useCheckboxGroup,\n useCheckboxGroupItem,\n} from 'react-aria';\nimport innerText from 'react-innertext';\nimport { type CheckboxGroupState, useCheckboxGroupState } from 'react-stately';\n\nimport type { CheckboxProps } from '#src/components/Checkbox';\nimport type Checkbox from '#src/components/Checkbox';\nimport { FormControlContext } from '#src/components/FormControl/useFormField';\nimport FormField from '#src/components/FormField/FormField';\nimport type { ImplementsFormField } from '#src/components/FormField/inputFields';\n\n/* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\nconst CheckboxGroupContext = createContext<CheckboxGroupState>(null);\n\n/** Preserves the parent FormControl context (disabled, hasError, etc.) but clears\n * inputId so each Checkbox inside the group generates its own unique id. */\nconst ClearGroupInputId = ({ children }: { children: ReactNode }) => {\n const parentContext = useContext(FormControlContext);\n return (\n <FormControlContext.Provider value={{ ...parentContext, inputId: undefined }}>\n {children}\n </FormControlContext.Provider>\n );\n};\n\ninterface CheckboxGroupItemProps {\n children: ReactElement<ComponentPropsWithRef<typeof Checkbox>>;\n}\n\nconst CheckboxGroupItem = (props: CheckboxGroupItemProps) => {\n const { children } = props;\n const checkboxProps = children.props;\n\n const state = useContext(CheckboxGroupContext);\n const ref = useRef();\n const { inputProps } = useCheckboxGroupItem(\n /* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\n {\n ...checkboxProps,\n onChange: undefined,\n isDisabled: checkboxProps.disabled,\n isReadOnly: checkboxProps.readOnly,\n isRequired: checkboxProps.required,\n isIndeterminate: checkboxProps.indeterminate,\n value: String(children.props.value),\n 'aria-label': innerText(checkboxProps.label),\n },\n state,\n ref,\n );\n\n return cloneElement(\n children,\n /* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\n mergeProps(inputProps, {\n onChange: checkboxProps.onChange,\n disabled: state.isDisabled || checkboxProps.disabled,\n checked: state.isSelected(String(inputProps.value)),\n ref,\n } as ComponentPropsWithRef<typeof Checkbox>),\n );\n};\n\ninterface CheckboxGroupFieldProps\n extends\n Omit<ImplementsFormField, 'configField'>,\n Omit<\n AriaCheckboxGroupProps,\n 'description' | 'disabled' | 'isReadOnly' | 'isRequired' | 'errorMessage'\n > {\n children?: ReactElement<CheckboxProps>[];\n disabled?: boolean;\n readOnly?: boolean;\n required?: boolean;\n}\n\nconst CheckboxGroupField = ({\n children,\n name,\n onChange,\n disabled,\n readOnly,\n required,\n ...props\n}: CheckboxGroupFieldProps) => {\n const reactAriaProps = {\n ...props,\n description: props.helperText,\n errorMessage: props.errorText,\n onChange,\n name,\n isDisabled: disabled,\n isReadOnly: readOnly,\n isRequired: required,\n };\n const state = useCheckboxGroupState(reactAriaProps);\n const { groupProps, labelProps, descriptionProps, errorMessageProps } = useCheckboxGroup(\n reactAriaProps,\n state,\n );\n\n return (\n <FormField\n labelProps={labelProps}\n helperProps={descriptionProps}\n errorProps={errorMessageProps}\n disabled={disabled}\n required={required}\n {...groupProps}\n {...props}\n >\n <ClearGroupInputId>\n <CheckboxGroupContext.Provider value={state}>\n {Children.map(children, (checkbox) => (\n /* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\n <CheckboxGroupItem>{checkbox}</CheckboxGroupItem>\n ))}\n </CheckboxGroupContext.Provider>\n </ClearGroupInputId>\n </FormField>\n );\n};\n\nexport default CheckboxGroupField;\n","import { type ReactNode, useState } from 'react';\n\nimport { MoreIcon, PlusIcon } from '@persona/icons';\n\nimport { IconButton } from '#src/components/Button';\nimport useFormGroup from '#src/components/ConfigFormGroup/useFormGroup';\nimport DropdownMenu from '#src/components/DropdownMenu';\nimport FormField from '#src/components/FormField/FormField';\nimport type { ImplementsFormField } from '#src/components/FormField/inputFields';\nimport ListBox, { type ListBoxProps } from '#src/components/ListBox';\nimport type { MenuItemProps } from '#src/components/Menu';\n\ninterface ListBoxFieldAction extends Omit<MenuItemProps, 'children'> {\n label: string;\n onClick: (selectedKeys: ListBoxProps<any>['selectedKeys']) => void;\n}\n\ninterface AddDropdownConfig {\n options: ({ label: ReactNode; value: string } & Omit<MenuItemProps, 'children'>)[];\n onSelection: (value: string) => void;\n}\n\ninterface ListBoxFieldProps<T extends object> extends ImplementsFormField, ListBoxProps<T> {\n actions?: ListBoxFieldAction[];\n addDropdownConfig?: AddDropdownConfig;\n /** Disables the add button, e.g. while the list is read-only. */\n addDisabled?: boolean;\n}\n\nconst ListBoxField = <T extends object>({\n label,\n helperText,\n errorText,\n warningText,\n labelProps,\n helperProps,\n errorProps,\n warningProps,\n inputId,\n required,\n onAdd,\n onDelete,\n deleteDisabled,\n configField: configFieldProp,\n size = 'md',\n actions = [],\n addDropdownConfig,\n addDisabled,\n selectedKeys: selectedKeysProp,\n onSelectionChange,\n defaultSelectedKeys,\n ...props\n}: ListBoxFieldProps<T>) => {\n const { configField } = useFormGroup({ configField: configFieldProp });\n const menuActions: ListBoxFieldAction[] = [...actions];\n const [selectedKeysState, setSelectedKeys] = useState(defaultSelectedKeys);\n const selectedKeys = selectedKeysProp ?? selectedKeysState;\n const effectiveSize = configField ? 'sm' : size;\n\n if (onDelete) {\n menuActions.unshift({\n label: 'Delete',\n onClick: () => onDelete(selectedKeys),\n disabled:\n deleteDisabled ||\n selectedKeys == null ||\n (typeof selectedKeys === 'object' && [...selectedKeys].length === 0),\n });\n }\n\n const addButton = (\n <IconButton size='sm' onClick={onAdd} aria-label='Add item to list' disabled={addDisabled}>\n <PlusIcon />\n </IconButton>\n );\n\n return (\n <FormField\n label={label}\n helperText={helperText}\n errorText={errorText}\n warningText={warningText}\n labelProps={labelProps}\n helperProps={helperProps}\n errorProps={errorProps}\n warningProps={warningProps}\n inputId={inputId}\n required={required}\n configField={configField}\n rightActions={\n configField && (\n <>\n {menuActions.length > 0 && (\n <DropdownMenu\n trigger={\n <IconButton aria-label='Actions' size='sm'>\n <MoreIcon />\n </IconButton>\n }\n portal\n >\n {menuActions.map((action) => (\n <DropdownMenu.Item\n key={action.label}\n {...action}\n onClick={() => action.onClick(selectedKeys)}\n size={effectiveSize}\n >\n {action.label}\n </DropdownMenu.Item>\n ))}\n </DropdownMenu>\n )}\n {onAdd && !addDropdownConfig && addButton}\n {addDropdownConfig && (\n <DropdownMenu trigger={addButton} align='start' portal>\n {addDropdownConfig.options.map((option) => (\n <DropdownMenu.Item\n key={option.value}\n {...option}\n onClick={() => addDropdownConfig.onSelection(option.value)}\n size={effectiveSize}\n >\n {option.label}\n </DropdownMenu.Item>\n ))}\n </DropdownMenu>\n )}\n </>\n )\n }\n >\n <ListBox\n id={inputId}\n fullWidth={configField}\n size={effectiveSize}\n deleteDisabled={deleteDisabled}\n // We have to control the keys so we can power the `rightActions`\n selectedKeys={selectedKeys}\n onSelectionChange={(keys) => {\n onSelectionChange?.(keys);\n setSelectedKeys(keys);\n }}\n {...props}\n />\n </FormField>\n );\n};\n\nexport default ListBoxField;\n","import { Fragment, type MouseEvent, type ReactNode, useState } from 'react';\n\nimport { IconButton } from '@persona/design-system/components/Button';\nimport { useFormGroup } from '@persona/design-system/components/ConfigFormGroup';\nimport DropdownMenu from '@persona/design-system/components/DropdownMenu';\nimport type { FormLabelProps } from '@persona/design-system/components/FormControl';\nimport type { MenuItemProps } from '@persona/design-system/components/Menu';\nimport TableBox, { type TableBoxProps } from '@persona/design-system/components/TableBox';\nimport { MoreIcon, PlusIcon } from '@persona/icons';\n\nimport FormField from './FormField';\nimport type { ImplementsFormField } from './inputFields';\n\nexport interface TableBoxFieldAction extends Omit<MenuItemProps, 'children'> {\n label: string;\n onClick: (selectedKey: TableBoxProps['selectedKey']) => void;\n}\n\nexport interface TableBoxFieldActionGroup {\n type: 'group';\n heading: string;\n actions: TableBoxFieldAction[];\n}\n\nexport type TableBoxFieldActionEntry = TableBoxFieldAction | TableBoxFieldActionGroup;\n\n/** Aria-label on TableBoxField's + button. Consumers that style or detect that\n * button (e.g. popover toggle guards) should import this rather than redefining it. */\nexport const TABLE_BOX_FIELD_ADD_BUTTON_ARIA_LABEL = 'Add item to table';\n\nconst isActionGroup = (action: TableBoxFieldActionEntry): action is TableBoxFieldActionGroup =>\n 'type' in action && action.type === 'group';\n\ninterface AddDropdownConfig {\n options: Array<{ label: string; value: string }>;\n onSelection: (value: string) => void;\n}\n\ninterface TableBoxFieldProps<T extends object = object>\n extends ImplementsFormField, Omit<TableBoxProps<T>, 'aria-label' | 'onCreateNewRow'> {\n onAdd?: (e: MouseEvent<HTMLButtonElement>) => void;\n onDelete?: (selectedKey: string | null) => void;\n deleteDisabled?: boolean;\n /** Actions and labeled action groups rendered in order. Empty groups are omitted. */\n actions?: TableBoxFieldActionEntry[];\n addDropdownConfig?: AddDropdownConfig;\n\n /**\n * Callback to create a new row and add it to the rows array\n * Should return the id of the newly created row\n */\n createNewRow?: () => string;\n children?: ReactNode;\n}\n\nconst TableBoxField = <T extends object = object>({\n label,\n helperText,\n errorText,\n warningText,\n labelProps: labelPropsProp,\n helperProps,\n errorProps,\n warningProps,\n inputId,\n required,\n onAdd,\n onDelete,\n deleteDisabled,\n configField: configFieldProp = true,\n actions = [],\n addDropdownConfig,\n selectedKey: selectedKeyProp,\n onSelectionChange,\n defaultSelectedKey,\n selectionMode,\n disabled,\n createNewRow,\n children,\n emptyText = 'No data',\n ...props\n}: TableBoxFieldProps<T>) => {\n const { configField } = useFormGroup({ configField: configFieldProp });\n const menuActions: TableBoxFieldActionEntry[] = [...actions];\n const [selectedKeyState, setSelectedKey] = useState(defaultSelectedKey);\n const selectedKey = selectedKeyProp ?? selectedKeyState;\n const [newRowId, setNewRowId] = useState<string | null>(null);\n const labelProps: FormLabelProps = { size: 'sm', ...labelPropsProp };\n\n const handleCreateNewRow = () => {\n if (createNewRow) {\n setNewRowId(createNewRow());\n }\n };\n\n // Handle add button click\n const handleAddClick = (e: MouseEvent<HTMLButtonElement>) => {\n if (createNewRow) {\n handleCreateNewRow();\n } else if (onAdd) {\n onAdd(e);\n }\n };\n\n if (onDelete) {\n menuActions.unshift({\n label: 'Delete',\n onClick: () => selectedKey && onDelete(selectedKey),\n disabled: deleteDisabled || selectedKey == null,\n });\n }\n const visibleMenuActions = menuActions.filter(\n (action) => !isActionGroup(action) || action.actions.length > 0,\n );\n\n const addButton = (\n <IconButton\n size='sm'\n onClick={handleAddClick}\n aria-label={TABLE_BOX_FIELD_ADD_BUTTON_ARIA_LABEL}\n disabled={disabled}\n >\n <PlusIcon />\n </IconButton>\n );\n\n return (\n <FormField\n label={label}\n helperText={helperText}\n errorText={errorText}\n warningText={warningText}\n labelProps={labelProps}\n helperProps={helperProps}\n errorProps={errorProps}\n warningProps={warningProps}\n inputId={inputId}\n required={required}\n rightActions={\n configField && (\n <>\n {visibleMenuActions.length > 0 && (\n <DropdownMenu\n trigger={\n <IconButton aria-label='Actions' size='sm' disabled={disabled}>\n <MoreIcon />\n </IconButton>\n }\n portal\n >\n {visibleMenuActions.map((entry, entryIndex) => {\n const previousEntry = visibleMenuActions[entryIndex - 1];\n if (isActionGroup(entry)) {\n return (\n <Fragment key={`${entry.heading}-${entryIndex}`}>\n {entryIndex > 0 && <DropdownMenu.Divider />}\n <DropdownMenu.Heading size='sm'>{entry.heading}</DropdownMenu.Heading>\n {entry.actions.map((action) => (\n <DropdownMenu.Item\n key={action.label}\n {...action}\n disabled={disabled || action.disabled}\n onClick={() => action.onClick(selectedKey)}\n size='sm'\n >\n {action.label}\n </DropdownMenu.Item>\n ))}\n </Fragment>\n );\n }\n\n return (\n <Fragment key={`${entry.label}-${entryIndex}`}>\n {previousEntry && isActionGroup(previousEntry) && <DropdownMenu.Divider />}\n <DropdownMenu.Item\n {...entry}\n disabled={disabled || entry.disabled}\n onClick={() => entry.onClick(selectedKey)}\n size='sm'\n >\n {entry.label}\n </DropdownMenu.Item>\n </Fragment>\n );\n })}\n </DropdownMenu>\n )}\n {(onAdd || createNewRow) && !addDropdownConfig && addButton}\n {addDropdownConfig && (\n <DropdownMenu trigger={addButton} portal>\n {addDropdownConfig.options.map((option) => (\n <DropdownMenu.Item\n key={option.value}\n {...option}\n onClick={() => addDropdownConfig.onSelection(option.value)}\n size='sm'\n >\n {option.label}\n </DropdownMenu.Item>\n ))}\n </DropdownMenu>\n )}\n </>\n )\n }\n >\n <TableBox\n aria-label={`${label} table`}\n // We have to control the keys so we can power the `rightActions`\n selectedKey={selectedKey}\n onSelectionChange={(key) => {\n onSelectionChange?.(key);\n setSelectedKey(key);\n }}\n selectionMode={selectionMode}\n newRowId={newRowId}\n onCreateNewRow={createNewRow ? handleCreateNewRow : undefined}\n emptyText={emptyText}\n disabled={disabled}\n {...props}\n >\n {children}\n </TableBox>\n </FormField>\n );\n};\n\n// Attach subcomponents to TableBoxField\nTableBoxField.Row = TableBox.Row;\nTableBoxField.Cell = TableBox.Cell;\n\nexport default TableBoxField;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FormField-Cf1VMvoa.mjs","names":["Input","TextArea","DropdownMenu","DropdownMenu"],"sources":["../src/components/FormField/FormField.tsx","../src/components/FormField/inputFields.tsx","../src/components/FormField/CheckboxGroupField.tsx","../src/components/FormField/ListBoxField.tsx","../src/components/FormField/TableBoxField.tsx"],"sourcesContent":["import { type ComponentPropsWithRef, forwardRef, type ReactElement, type ReactNode } from 'react';\n\nimport { Spacing } from '@persona/design-tokens';\n\nimport useFormGroup from '#src/components/ConfigFormGroup/useFormGroup';\nimport FormControl, {\n ErrorText,\n type FormControlProps,\n FormInputContainer,\n FormLabel,\n HelperText,\n WarningText,\n} from '#src/components/FormControl';\nimport { HStack } from '#src/components/Stack';\n\nexport interface FormFieldBaseProps {\n /**\n * Renders `<Label>` above input\n */\n label?: ReactNode;\n\n /**\n * ID of the input element. Providing this will automatically link the label to the input.\n */\n inputId?: string;\n\n /** Marks the field as required. The label renders an asterisk; composed fields also forward `required` to their input. */\n required?: boolean;\n\n /**\n * Renders `<HelperText>` below input\n */\n helperText?: ReactNode;\n\n /**\n * Renders `<ErrorText>` below input and helper text.\n */\n errorText?: ReactNode;\n\n /**\n * Renders `<WarningText>` below input and helper text.\n */\n warningText?: ReactNode;\n\n /**\n * Should be an input of some sort\n */\n children?: ReactElement;\n\n labelProps?: ComponentPropsWithRef<typeof FormLabel>;\n helperProps?: ComponentPropsWithRef<typeof HelperText>;\n warningProps?: ComponentPropsWithRef<typeof WarningText>;\n errorProps?: ComponentPropsWithRef<typeof ErrorText>;\n\n /**\n * Whether to render the form field as a config field.\n * This will render the helper text as a tooltip.\n */\n configField?: boolean;\n\n /**\n * Override the width of the input area when `configField` is true.\n * Accepts any valid CSS width value (e.g. `'33%'`, `'66.67%'`).\n * Defaults to `'50%'`.\n */\n configFieldInputWidth?: string;\n\n /**\n * Renders actions to the right of the label.\n */\n rightActions?: ReactNode;\n}\n\nexport interface FormFieldProps extends Omit<FormControlProps, 'children'>, FormFieldBaseProps {}\n\n/**\n * Helper component with preset slots for label, input, and helper texts.\n *\n * Prefer a composed field component, such as `<TextField>`, `<SelectField>`, or\n * `<CheckboxField>`, when one is available for the input type. Use `<FormField>` directly\n * when composing a custom control or layout.\n *\n * ## Usage\n *\n * ```tsx\n * import FormField from '@persona/design-system/components/FormField';\n * ```\n */\nexport const FormField = forwardRef<HTMLDivElement, FormFieldProps>(function FormField(\n {\n label,\n children,\n helperText,\n warningText,\n errorText,\n labelProps,\n helperProps,\n warningProps,\n errorProps,\n configField: configFieldProp,\n configFieldInputWidth,\n rightActions,\n ...props\n }: FormFieldProps,\n ref,\n) {\n const { configField: configFieldFormGroup } = useFormGroup();\n const configField = configFieldProp ?? configFieldFormGroup;\n\n const labelElement = label ? (\n <FormLabel tooltip={configField && helperText ? helperText : undefined} {...labelProps}>\n {label}\n </FormLabel>\n ) : null;\n\n return (\n <FormControl\n hasError={!!errorText}\n hasWarning={!!warningText}\n ref={ref}\n configField={configField}\n hasRightActions={!!rightActions}\n configFieldInputWidth={configFieldInputWidth}\n {...props}\n >\n {rightActions ? (\n <HStack justify='space-between' align='center'>\n {labelElement}\n <HStack spacing={Spacing[1]}>{rightActions}</HStack>\n </HStack>\n ) : (\n labelElement\n )}\n <FormInputContainer>{children}</FormInputContainer>\n {!configField && helperText && <HelperText {...helperProps}>{helperText}</HelperText>}\n {!configField && warningText && <WarningText {...warningProps}>{warningText}</WarningText>}\n {!configField && errorText && <ErrorText {...errorProps}>{errorText}</ErrorText>}\n </FormControl>\n );\n});\n\nexport default FormField;\n","import { uniqueId } from 'lodash-es';\nimport { forwardRef, useMemo } from 'react';\n\nimport Checkbox, { type CheckboxProps } from '#src/components/Checkbox';\nimport Combobox from '#src/components/Combobox';\nimport type { ComboboxMultiSelectProps } from '#src/components/Combobox/ComboboxMultiSelect';\nimport type { ComboboxSingleSelectProps } from '#src/components/Combobox/ComboboxSingleSelect';\nimport FormField, { type FormFieldBaseProps } from '#src/components/FormField/FormField';\nimport Input, { type InputProps } from '#src/components/Input';\nimport RadioGroup, { type RadioGroupProps } from '#src/components/RadioGroup';\nimport SegmentedControl, { type SegmentedControlProps } from '#src/components/SegmentedControl';\nimport Select, { type SelectProps } from '#src/components/Select';\nimport TextArea, { type TextAreaProps } from '#src/components/TextArea';\nimport Toggle, { type ToggleProps } from '#src/components/Toggle';\n\nexport type ImplementsFormField = Omit<FormFieldBaseProps, 'children'>;\n\ntype ExtractFormFieldProps<T extends ImplementsFormField> = Pick<\n T,\n | 'label'\n | 'inputId'\n | 'required'\n | 'helperText'\n | 'errorText'\n | 'warningText'\n | 'labelProps'\n | 'helperProps'\n | 'warningProps'\n | 'errorProps'\n | 'configField'\n | 'configFieldInputWidth'\n | 'rightActions'\n>;\ntype OmitFormFieldProps<T extends ImplementsFormField> = Omit<\n T,\n Exclude<keyof ExtractFormFieldProps<T>, 'required'>\n>;\n\n/**\n * Helper to split out props that are sent to the FormField component from props sent\n * to the underlying input component.\n */\nexport const splitOutFormFieldProps = <T extends ImplementsFormField>(\n props: T,\n): {\n formFieldProps: ExtractFormFieldProps<T>;\n inputProps: OmitFormFieldProps<T>;\n} => {\n const {\n label,\n inputId,\n helperText,\n errorText,\n warningText,\n labelProps,\n helperProps,\n warningProps,\n errorProps,\n configField,\n configFieldInputWidth,\n rightActions,\n ...inputProps\n } = props;\n\n return {\n formFieldProps: {\n label,\n inputId,\n required: props.required,\n helperText,\n errorText,\n warningText,\n labelProps,\n helperProps,\n warningProps,\n errorProps,\n configField,\n configFieldInputWidth,\n rightActions,\n },\n inputProps,\n };\n};\n\nexport interface TextFieldProps extends ImplementsFormField, InputProps {}\n\nexport const TextField = forwardRef<HTMLInputElement, TextFieldProps>(\n function TextField(props, ref) {\n const { formFieldProps, inputProps } = splitOutFormFieldProps(props);\n const { id, ...rest } = inputProps;\n\n return (\n <FormField\n {...formFieldProps}\n labelProps={{ size: props.size, ...formFieldProps.labelProps }}\n inputId={formFieldProps.inputId ?? id}\n >\n <Input {...rest} ref={ref} />\n </FormField>\n );\n },\n);\n\nexport interface TextAreaFieldProps extends ImplementsFormField, TextAreaProps {}\n\nexport const TextAreaField = forwardRef<HTMLTextAreaElement, TextAreaFieldProps>(\n function TextAreaField(props, ref) {\n const { formFieldProps, inputProps } = splitOutFormFieldProps(props);\n const { id, ...rest } = inputProps;\n\n return (\n <FormField\n {...formFieldProps}\n labelProps={{ size: props.size, ...formFieldProps.labelProps }}\n inputId={formFieldProps.inputId ?? id}\n >\n <TextArea {...rest} ref={ref} />\n </FormField>\n );\n },\n);\n\nexport interface SelectFieldProps extends ImplementsFormField, SelectProps {}\n\nexport const SelectField = ({ id, children, ...props }: SelectFieldProps) => {\n const { formFieldProps, inputProps } = splitOutFormFieldProps(props);\n const linkedId = useMemo(\n () => formFieldProps.inputId ?? id ?? uniqueId('pds-form-field-input-fields-select__'),\n [formFieldProps.inputId, id],\n );\n\n return (\n <FormField\n {...formFieldProps}\n inputId={linkedId}\n labelProps={{ htmlFor: linkedId, size: inputProps.size, ...formFieldProps.labelProps }}\n >\n <Select {...inputProps} id={linkedId}>\n {children}\n </Select>\n </FormField>\n );\n};\n\nexport interface RadioGroupFieldProps\n extends Omit<ImplementsFormField, 'configField'>, RadioGroupProps {}\n\nexport const RadioGroupField = ({\n label,\n helperText,\n errorText,\n warningText,\n required,\n children,\n ...props\n}: RadioGroupFieldProps) => {\n return (\n <FormField\n label={label}\n helperText={helperText}\n warningText={warningText}\n errorText={errorText}\n required={required}\n >\n <RadioGroup {...props} aria-required={required}>\n {children}\n </RadioGroup>\n </FormField>\n );\n};\n\nexport interface CheckboxFieldProps extends ImplementsFormField, CheckboxProps {\n checkboxLabel?: CheckboxProps['label'];\n}\n\nexport const CheckboxField = ({\n label,\n helperText,\n errorText,\n warningText,\n checkboxLabel,\n configField,\n labelProps,\n required,\n ...props\n}: CheckboxFieldProps) => {\n return (\n <FormField\n label={label}\n helperText={helperText}\n warningText={warningText}\n errorText={errorText}\n configField={configField}\n labelProps={labelProps}\n required={required}\n >\n <Checkbox label={checkboxLabel} required={required} {...props} />\n </FormField>\n );\n};\n\nexport interface ToggleFieldProps extends ImplementsFormField, ToggleProps {}\n\nexport const ToggleField = forwardRef<HTMLDivElement, ToggleFieldProps>(\n function ToggleField(props, ref) {\n const { formFieldProps, inputProps } = splitOutFormFieldProps(props);\n\n return (\n <FormField\n {...formFieldProps}\n labelProps={{ size: inputProps.size, ...formFieldProps.labelProps }}\n >\n <Toggle {...inputProps} ref={ref} />\n </FormField>\n );\n },\n);\n\nexport interface SegmentedControlFieldProps\n extends ImplementsFormField, Omit<SegmentedControlProps, 'children'> {\n children?: SegmentedControlProps['children'];\n}\n\nexport const SegmentedControlField = forwardRef<HTMLDivElement, SegmentedControlFieldProps>(\n function SegmentedControlField(\n {\n label,\n helperText,\n errorText,\n warningText,\n configField,\n required,\n children,\n labelProps,\n ...props\n },\n ref,\n ) {\n return (\n <FormField\n label={label}\n helperText={helperText}\n warningText={warningText}\n errorText={errorText}\n configField={configField}\n labelProps={labelProps}\n required={required}\n >\n <SegmentedControl fullWidth {...props} aria-required={required} ref={ref}>\n {children}\n </SegmentedControl>\n </FormField>\n );\n },\n);\n\nexport type ComboboxSingleSelectFieldProps<T = string> = ImplementsFormField &\n ComboboxSingleSelectProps<T>;\nexport type ComboboxMultiSelectFieldProps<T = string> = ImplementsFormField &\n ComboboxMultiSelectProps<T>;\n\nexport const ComboboxField = (\n props: ComboboxSingleSelectFieldProps | ComboboxMultiSelectFieldProps,\n) => {\n // `Combobox` registers its own id with the surrounding `FormControl`, which is what links the\n // label to it, so the field only forwards an explicit `inputId` when one is given. Each mode is\n // split separately: `multiple` discriminates the two, and a union split at once loses that.\n if (props.multiple) {\n const { formFieldProps, inputProps } = splitOutFormFieldProps(props);\n\n return (\n <FormField {...formFieldProps}>\n <Combobox {...inputProps} />\n </FormField>\n );\n }\n\n const { formFieldProps, inputProps } = splitOutFormFieldProps(props);\n\n return (\n <FormField {...formFieldProps}>\n <Combobox {...inputProps} />\n </FormField>\n );\n};\n","import {\n Children,\n cloneElement,\n type ComponentPropsWithRef,\n createContext,\n type ReactElement,\n type ReactNode,\n useContext,\n useRef,\n} from 'react';\nimport {\n type AriaCheckboxGroupProps,\n mergeProps,\n useCheckboxGroup,\n useCheckboxGroupItem,\n} from 'react-aria';\nimport innerText from 'react-innertext';\nimport { type CheckboxGroupState, useCheckboxGroupState } from 'react-stately';\n\nimport type { CheckboxProps } from '#src/components/Checkbox';\nimport type Checkbox from '#src/components/Checkbox';\nimport { FormControlContext } from '#src/components/FormControl/useFormField';\nimport FormField from '#src/components/FormField/FormField';\nimport type { ImplementsFormField } from '#src/components/FormField/inputFields';\n\n/* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\nconst CheckboxGroupContext = createContext<CheckboxGroupState>(null);\n\n/** Preserves the parent FormControl context (disabled, hasError, etc.) but clears\n * inputId so each Checkbox inside the group generates its own unique id. */\nconst ClearGroupInputId = ({ children }: { children: ReactNode }) => {\n const parentContext = useContext(FormControlContext);\n return (\n <FormControlContext.Provider value={{ ...parentContext, inputId: undefined }}>\n {children}\n </FormControlContext.Provider>\n );\n};\n\ninterface CheckboxGroupItemProps {\n children: ReactElement<ComponentPropsWithRef<typeof Checkbox>>;\n}\n\nconst CheckboxGroupItem = (props: CheckboxGroupItemProps) => {\n const { children } = props;\n const checkboxProps = children.props;\n\n const state = useContext(CheckboxGroupContext);\n const ref = useRef();\n const { inputProps } = useCheckboxGroupItem(\n /* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\n {\n ...checkboxProps,\n onChange: undefined,\n isDisabled: checkboxProps.disabled,\n isReadOnly: checkboxProps.readOnly,\n isRequired: checkboxProps.required,\n isIndeterminate: checkboxProps.indeterminate,\n value: String(children.props.value),\n 'aria-label': innerText(checkboxProps.label),\n },\n state,\n ref,\n );\n\n return cloneElement(\n children,\n /* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\n mergeProps(inputProps, {\n onChange: checkboxProps.onChange,\n disabled: state.isDisabled || checkboxProps.disabled,\n checked: state.isSelected(String(inputProps.value)),\n ref,\n } as ComponentPropsWithRef<typeof Checkbox>),\n );\n};\n\ninterface CheckboxGroupFieldProps\n extends\n Omit<ImplementsFormField, 'configField'>,\n Omit<\n AriaCheckboxGroupProps,\n 'description' | 'disabled' | 'isReadOnly' | 'isRequired' | 'errorMessage'\n > {\n children?: ReactElement<CheckboxProps>[];\n disabled?: boolean;\n readOnly?: boolean;\n required?: boolean;\n}\n\nconst CheckboxGroupField = ({\n children,\n name,\n onChange,\n disabled,\n readOnly,\n required,\n ...props\n}: CheckboxGroupFieldProps) => {\n const reactAriaProps = {\n ...props,\n description: props.helperText,\n errorMessage: props.errorText,\n onChange,\n name,\n isDisabled: disabled,\n isReadOnly: readOnly,\n isRequired: required,\n };\n const state = useCheckboxGroupState(reactAriaProps);\n const { groupProps, labelProps, descriptionProps, errorMessageProps } = useCheckboxGroup(\n reactAriaProps,\n state,\n );\n\n return (\n <FormField\n labelProps={labelProps}\n helperProps={descriptionProps}\n errorProps={errorMessageProps}\n disabled={disabled}\n required={required}\n {...groupProps}\n {...props}\n >\n <ClearGroupInputId>\n <CheckboxGroupContext.Provider value={state}>\n {Children.map(children, (checkbox) => (\n /* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\n <CheckboxGroupItem>{checkbox}</CheckboxGroupItem>\n ))}\n </CheckboxGroupContext.Provider>\n </ClearGroupInputId>\n </FormField>\n );\n};\n\nexport default CheckboxGroupField;\n","import { type ReactNode, useState } from 'react';\n\nimport { MoreIcon, PlusIcon } from '@persona/icons';\n\nimport { IconButton } from '#src/components/Button';\nimport useFormGroup from '#src/components/ConfigFormGroup/useFormGroup';\nimport DropdownMenu from '#src/components/DropdownMenu';\nimport FormField from '#src/components/FormField/FormField';\nimport type { ImplementsFormField } from '#src/components/FormField/inputFields';\nimport ListBox, { type ListBoxProps } from '#src/components/ListBox';\nimport type { MenuItemProps } from '#src/components/Menu';\n\ninterface ListBoxFieldAction extends Omit<MenuItemProps, 'children'> {\n label: string;\n onClick: (selectedKeys: ListBoxProps<any>['selectedKeys']) => void;\n}\n\ninterface AddDropdownConfig {\n options: ({ label: ReactNode; value: string } & Omit<MenuItemProps, 'children'>)[];\n onSelection: (value: string) => void;\n}\n\ninterface ListBoxFieldProps<T extends object> extends ImplementsFormField, ListBoxProps<T> {\n actions?: ListBoxFieldAction[];\n addDropdownConfig?: AddDropdownConfig;\n /** Disables the add button, e.g. while the list is read-only. */\n addDisabled?: boolean;\n}\n\nconst ListBoxField = <T extends object>({\n label,\n helperText,\n errorText,\n warningText,\n labelProps,\n helperProps,\n errorProps,\n warningProps,\n inputId,\n required,\n onAdd,\n onDelete,\n deleteDisabled,\n configField: configFieldProp,\n size = 'md',\n actions = [],\n addDropdownConfig,\n addDisabled,\n selectedKeys: selectedKeysProp,\n onSelectionChange,\n defaultSelectedKeys,\n ...props\n}: ListBoxFieldProps<T>) => {\n const { configField } = useFormGroup({ configField: configFieldProp });\n const menuActions: ListBoxFieldAction[] = [...actions];\n const [selectedKeysState, setSelectedKeys] = useState(defaultSelectedKeys);\n const selectedKeys = selectedKeysProp ?? selectedKeysState;\n const effectiveSize = configField ? 'sm' : size;\n\n if (onDelete) {\n menuActions.unshift({\n label: 'Delete',\n onClick: () => onDelete(selectedKeys),\n disabled:\n deleteDisabled ||\n selectedKeys == null ||\n (typeof selectedKeys === 'object' && [...selectedKeys].length === 0),\n });\n }\n\n const addButton = (\n <IconButton size='sm' onClick={onAdd} aria-label='Add item to list' disabled={addDisabled}>\n <PlusIcon />\n </IconButton>\n );\n\n return (\n <FormField\n label={label}\n helperText={helperText}\n errorText={errorText}\n warningText={warningText}\n labelProps={labelProps}\n helperProps={helperProps}\n errorProps={errorProps}\n warningProps={warningProps}\n inputId={inputId}\n required={required}\n configField={configField}\n rightActions={\n configField && (\n <>\n {menuActions.length > 0 && (\n <DropdownMenu\n trigger={\n <IconButton aria-label='Actions' size='sm'>\n <MoreIcon />\n </IconButton>\n }\n portal\n >\n {menuActions.map((action) => (\n <DropdownMenu.Item\n key={action.label}\n {...action}\n onClick={() => action.onClick(selectedKeys)}\n size={effectiveSize}\n >\n {action.label}\n </DropdownMenu.Item>\n ))}\n </DropdownMenu>\n )}\n {onAdd && !addDropdownConfig && addButton}\n {addDropdownConfig && (\n <DropdownMenu trigger={addButton} align='start' portal>\n {addDropdownConfig.options.map((option) => (\n <DropdownMenu.Item\n key={option.value}\n {...option}\n onClick={() => addDropdownConfig.onSelection(option.value)}\n size={effectiveSize}\n >\n {option.label}\n </DropdownMenu.Item>\n ))}\n </DropdownMenu>\n )}\n </>\n )\n }\n >\n <ListBox\n id={inputId}\n fullWidth={configField}\n size={effectiveSize}\n deleteDisabled={deleteDisabled}\n // We have to control the keys so we can power the `rightActions`\n selectedKeys={selectedKeys}\n onSelectionChange={(keys) => {\n onSelectionChange?.(keys);\n setSelectedKeys(keys);\n }}\n {...props}\n />\n </FormField>\n );\n};\n\nexport default ListBoxField;\n","import { Fragment, type MouseEvent, type ReactNode, useState } from 'react';\n\nimport { IconButton } from '@persona/design-system/components/Button';\nimport { useFormGroup } from '@persona/design-system/components/ConfigFormGroup';\nimport DropdownMenu from '@persona/design-system/components/DropdownMenu';\nimport type { FormLabelProps } from '@persona/design-system/components/FormControl';\nimport type { MenuItemProps } from '@persona/design-system/components/Menu';\nimport TableBox, { type TableBoxProps } from '@persona/design-system/components/TableBox';\nimport { MoreIcon, PlusIcon } from '@persona/icons';\n\nimport FormField from './FormField';\nimport type { ImplementsFormField } from './inputFields';\n\nexport interface TableBoxFieldAction extends Omit<MenuItemProps, 'children'> {\n label: string;\n onClick: (selectedKey: TableBoxProps['selectedKey']) => void;\n}\n\nexport interface TableBoxFieldActionGroup {\n type: 'group';\n heading: string;\n actions: TableBoxFieldAction[];\n}\n\nexport type TableBoxFieldActionEntry = TableBoxFieldAction | TableBoxFieldActionGroup;\n\n/** Aria-label on TableBoxField's + button. Consumers that style or detect that\n * button (e.g. popover toggle guards) should import this rather than redefining it. */\nexport const TABLE_BOX_FIELD_ADD_BUTTON_ARIA_LABEL = 'Add item to table';\n\nconst isActionGroup = (action: TableBoxFieldActionEntry): action is TableBoxFieldActionGroup =>\n 'type' in action && action.type === 'group';\n\ninterface AddDropdownConfig {\n options: Array<{ label: string; value: string }>;\n onSelection: (value: string) => void;\n}\n\ninterface TableBoxFieldProps<T extends object = object>\n extends ImplementsFormField, Omit<TableBoxProps<T>, 'aria-label' | 'onCreateNewRow'> {\n onAdd?: (e: MouseEvent<HTMLButtonElement>) => void;\n onDelete?: (selectedKey: string | null) => void;\n deleteDisabled?: boolean;\n /** Actions and labeled action groups rendered in order. Empty groups are omitted. */\n actions?: TableBoxFieldActionEntry[];\n addDropdownConfig?: AddDropdownConfig;\n\n /**\n * Callback to create a new row and add it to the rows array\n * Should return the id of the newly created row\n */\n createNewRow?: () => string;\n children?: ReactNode;\n}\n\nconst TableBoxField = <T extends object = object>({\n label,\n helperText,\n errorText,\n warningText,\n labelProps: labelPropsProp,\n helperProps,\n errorProps,\n warningProps,\n inputId,\n required,\n onAdd,\n onDelete,\n deleteDisabled,\n configField: configFieldProp = true,\n actions = [],\n addDropdownConfig,\n selectedKey: selectedKeyProp,\n onSelectionChange,\n defaultSelectedKey,\n selectionMode,\n disabled,\n createNewRow,\n children,\n emptyText = 'No data',\n ...props\n}: TableBoxFieldProps<T>) => {\n const { configField } = useFormGroup({ configField: configFieldProp });\n const menuActions: TableBoxFieldActionEntry[] = [...actions];\n const [selectedKeyState, setSelectedKey] = useState(defaultSelectedKey);\n const selectedKey = selectedKeyProp ?? selectedKeyState;\n const [newRowId, setNewRowId] = useState<string | null>(null);\n const labelProps: FormLabelProps = { size: 'sm', ...labelPropsProp };\n\n const handleCreateNewRow = () => {\n if (createNewRow) {\n setNewRowId(createNewRow());\n }\n };\n\n // Handle add button click\n const handleAddClick = (e: MouseEvent<HTMLButtonElement>) => {\n if (createNewRow) {\n handleCreateNewRow();\n } else if (onAdd) {\n onAdd(e);\n }\n };\n\n if (onDelete) {\n menuActions.unshift({\n label: 'Delete',\n onClick: () => selectedKey && onDelete(selectedKey),\n disabled: deleteDisabled || selectedKey == null,\n });\n }\n const visibleMenuActions = menuActions.filter(\n (action) => !isActionGroup(action) || action.actions.length > 0,\n );\n\n const addButton = (\n <IconButton\n size='sm'\n onClick={handleAddClick}\n aria-label={TABLE_BOX_FIELD_ADD_BUTTON_ARIA_LABEL}\n disabled={disabled}\n >\n <PlusIcon />\n </IconButton>\n );\n\n return (\n <FormField\n label={label}\n helperText={helperText}\n errorText={errorText}\n warningText={warningText}\n labelProps={labelProps}\n helperProps={helperProps}\n errorProps={errorProps}\n warningProps={warningProps}\n inputId={inputId}\n required={required}\n rightActions={\n configField && (\n <>\n {visibleMenuActions.length > 0 && (\n <DropdownMenu\n trigger={\n <IconButton aria-label='Actions' size='sm' disabled={disabled}>\n <MoreIcon />\n </IconButton>\n }\n portal\n >\n {visibleMenuActions.map((entry, entryIndex) => {\n const previousEntry = visibleMenuActions[entryIndex - 1];\n if (isActionGroup(entry)) {\n return (\n <Fragment key={`${entry.heading}-${entryIndex}`}>\n {entryIndex > 0 && <DropdownMenu.Divider />}\n <DropdownMenu.Heading size='sm'>{entry.heading}</DropdownMenu.Heading>\n {entry.actions.map((action) => (\n <DropdownMenu.Item\n key={action.label}\n {...action}\n disabled={disabled || action.disabled}\n onClick={() => action.onClick(selectedKey)}\n size='sm'\n >\n {action.label}\n </DropdownMenu.Item>\n ))}\n </Fragment>\n );\n }\n\n return (\n <Fragment key={`${entry.label}-${entryIndex}`}>\n {previousEntry && isActionGroup(previousEntry) && <DropdownMenu.Divider />}\n <DropdownMenu.Item\n {...entry}\n disabled={disabled || entry.disabled}\n onClick={() => entry.onClick(selectedKey)}\n size='sm'\n >\n {entry.label}\n </DropdownMenu.Item>\n </Fragment>\n );\n })}\n </DropdownMenu>\n )}\n {(onAdd || createNewRow) && !addDropdownConfig && addButton}\n {addDropdownConfig && (\n <DropdownMenu trigger={addButton} portal>\n {addDropdownConfig.options.map((option) => (\n <DropdownMenu.Item\n key={option.value}\n {...option}\n onClick={() => addDropdownConfig.onSelection(option.value)}\n size='sm'\n >\n {option.label}\n </DropdownMenu.Item>\n ))}\n </DropdownMenu>\n )}\n </>\n )\n }\n >\n <TableBox\n aria-label={`${label} table`}\n // We have to control the keys so we can power the `rightActions`\n selectedKey={selectedKey}\n onSelectionChange={(key) => {\n onSelectionChange?.(key);\n setSelectedKey(key);\n }}\n selectionMode={selectionMode}\n newRowId={newRowId}\n onCreateNewRow={createNewRow ? handleCreateNewRow : undefined}\n emptyText={emptyText}\n disabled={disabled}\n {...props}\n >\n {children}\n </TableBox>\n </FormField>\n );\n};\n\n// Attach subcomponents to TableBoxField\nTableBoxField.Row = TableBox.Row;\nTableBoxField.Cell = TableBox.Cell;\n\nexport default TableBoxField;\n"],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ import { i as Paragraph } from "./Text-D0vEReED.mjs";
|
|
|
4
4
|
import { t as useToggle } from "./useToggle-1z8JE7Ym.mjs";
|
|
5
5
|
import { fadeIn } from "./variables/keyframes.mjs";
|
|
6
6
|
import "./variables/transitions.mjs";
|
|
7
|
-
import { n as Button } from "./IconButton-
|
|
7
|
+
import { n as Button } from "./IconButton-DxHB2g80.mjs";
|
|
8
8
|
import { s as Popover_default } from "./Popover-DordjYNM.mjs";
|
|
9
9
|
import { Spacing } from "@persona/design-tokens";
|
|
10
10
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -111,4 +111,4 @@ const HoverCopyableField = ({ copyValue, confirmationText = "Copied", onCopySucc
|
|
|
111
111
|
//#endregion
|
|
112
112
|
export { HoverCopyableField as t };
|
|
113
113
|
|
|
114
|
-
//# sourceMappingURL=HoverCopyableField-
|
|
114
|
+
//# sourceMappingURL=HoverCopyableField-XHC_n9tp.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HoverCopyableField-
|
|
1
|
+
{"version":3,"file":"HoverCopyableField-XHC_n9tp.mjs","names":["Card","Popover"],"sources":["../src/components/HoverCopyableField/HoverCopyableField.tsx"],"sourcesContent":["import type { MouseEvent, ReactNode } from 'react';\nimport styled from 'styled-components';\n\nimport { Spacing } from '@persona/design-tokens';\nimport { CopyIcon } from '@persona/icons';\n\nimport Button from '#src/components/Button';\nimport Card from '#src/components/Card';\nimport Popover from '#src/components/Popover';\nimport { Paragraph } from '#src/components/Text';\nimport useToggle from '#src/lib/useToggle';\nimport { fadeIn } from '#src/variables/keyframes';\nimport { TransitionDuration } from '#src/variables/transitions';\n\nexport type CopySuccessDetail = {\n text: string;\n clientX: number;\n clientY: number;\n};\n\nexport type HoverCopyableFieldProps = {\n copyValue: string | undefined;\n confirmationText?: string;\n /**\n * Called after a successful clipboard write. When provided, the Copied\n * popover is skipped so the host can own post-copy UX.\n */\n onCopySuccess?: (detail: CopySuccessDetail) => void;\n children: ReactNode;\n};\n\nconst copyToClipboard = async (text: string): Promise<boolean> => {\n try {\n if ('clipboard' in navigator) {\n await navigator.clipboard.writeText(text);\n return true;\n } else {\n return document.execCommand('copy', true, text);\n }\n } catch {\n return false;\n }\n};\n\nconst clickOrigin = (e: MouseEvent<HTMLButtonElement>): { clientX: number; clientY: number } => {\n const rect = e.currentTarget.getBoundingClientRect();\n const hasPointer = e.clientX !== 0 || e.clientY !== 0;\n return {\n clientX: hasPointer ? e.clientX : rect.left + rect.width / 2,\n clientY: rect.top,\n };\n};\n\nconst CopyableFieldContainer = styled.div`\n display: flex;\n gap: ${Spacing[1]};\n align-items: center;\n`;\n\nconst CopyButton = styled(Button).attrs(() => ({\n type: 'button',\n variant: 'inverse',\n width: 'icon',\n}))<{ isActive: boolean }>`\n height: ${Spacing[5]};\n width: ${Spacing[5]};\n visibility: ${({ isActive }) => (isActive ? 'visible' : 'hidden')};\n animation: ${fadeIn} ${TransitionDuration.Medium} ease-in-out;\n svg {\n width: 14px;\n height: 14px;\n }\n`;\n\nconst StyledCard = styled(Card)`\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n animation: ${fadeIn} ${TransitionDuration.Medium} ease-in-out;\n padding: 6px;\n margin: 0;\n`;\n\nconst HoverCopyableField = ({\n copyValue,\n confirmationText = 'Copied',\n onCopySuccess,\n children,\n}: HoverCopyableFieldProps) => {\n const [copyButtonActive, { enable: showCopyButton, disable: hideCopyButton }] = useToggle(false);\n const [confirmationActive, { enable: showConfirmation, disable: hideConfirmation }] =\n useToggle(false);\n\n const copyTextToClipboard = async (origin: { clientX: number; clientY: number }) => {\n if (copyValue == null) {\n return;\n }\n const copyWasSuccessful = await copyToClipboard(copyValue);\n if (!copyWasSuccessful) {\n return;\n }\n if (onCopySuccess) {\n onCopySuccess({ text: copyValue, ...origin });\n hideCopyButton();\n return;\n }\n showConfirmation();\n setTimeout(() => {\n hideCopyButton();\n hideConfirmation();\n }, 1200);\n };\n\n const copyField = (e: MouseEvent<HTMLButtonElement>) => {\n e.preventDefault();\n e.stopPropagation();\n void copyTextToClipboard(clickOrigin(e));\n };\n\n return copyValue != null && copyValue.trim().length > 0 ? (\n <CopyableFieldContainer onMouseEnter={showCopyButton} onMouseLeave={hideCopyButton}>\n {children}\n <Popover open={confirmationActive}>\n <Popover.Anchor asChild>\n <CopyButton\n id='hover-copyable-field__copy-button'\n isActive={copyButtonActive || confirmationActive}\n onClick={copyField}\n >\n <CopyIcon width={16} height={16} />\n </CopyButton>\n </Popover.Anchor>\n <Popover.Content side='top' align='center' style={{ zIndex: 2 }}>\n <StyledCard elevated>\n <Paragraph>{confirmationText}</Paragraph>\n </StyledCard>\n </Popover.Content>\n </Popover>\n </CopyableFieldContainer>\n ) : null;\n};\n\nexport default HoverCopyableField;\n"],"mappings":";;;;;;;;;;;;AA+BA,MAAM,kBAAkB,OAAO,SAAmC;AAChE,KAAI;AACF,MAAI,eAAe,WAAW;AAC5B,SAAM,UAAU,UAAU,UAAU,KAAK;AACzC,UAAO;QAEP,QAAO,SAAS,YAAY,QAAQ,MAAM,KAAK;SAE3C;AACN,SAAO;;;AAIX,MAAM,eAAe,MAA2E;CAC9F,MAAM,OAAO,EAAE,cAAc,uBAAuB;AAEpD,QAAO;EACL,SAFiB,EAAE,YAAY,KAAK,EAAE,YAAY,IAE5B,EAAE,UAAU,KAAK,OAAO,KAAK,QAAQ;EAC3D,SAAS,KAAK;EACf;;AAGH,MAAM,yBAAyB,OAAO,GAAG;;SAEhC,QAAQ,GAAG;;;AAIpB,MAAM,aAAa,OAAO,OAAO,CAAC,aAAa;CAC7C,MAAM;CACN,SAAS;CACT,OAAO;CACR,EAAE;YACS,QAAQ,GAAG;WACZ,QAAQ,GAAG;iBACL,EAAE,eAAgB,WAAW,YAAY,SAAU;eACrD,OAAO,GAAA,QAA6B;;;;;;AAOnD,MAAM,aAAa,OAAOA,aAAK;;;;;eAKhB,OAAO,GAAA,QAA6B;;;;AAKnD,MAAM,sBAAsB,EAC1B,WACA,mBAAmB,UACnB,eACA,eAC6B;CAC7B,MAAM,CAAC,kBAAkB,EAAE,QAAQ,gBAAgB,SAAS,oBAAoB,UAAU,MAAM;CAChG,MAAM,CAAC,oBAAoB,EAAE,QAAQ,kBAAkB,SAAS,sBAC9D,UAAU,MAAM;CAElB,MAAM,sBAAsB,OAAO,WAAiD;AAClF,MAAI,aAAa,KACf;AAGF,MAAI,CAAC,MAD2B,gBAAgB,UAAU,CAExD;AAEF,MAAI,eAAe;AACjB,iBAAc;IAAE,MAAM;IAAW,GAAG;IAAQ,CAAC;AAC7C,mBAAgB;AAChB;;AAEF,oBAAkB;AAClB,mBAAiB;AACf,mBAAgB;AAChB,qBAAkB;KACjB,KAAK;;CAGV,MAAM,aAAa,MAAqC;AACtD,IAAE,gBAAgB;AAClB,IAAE,iBAAiB;AACd,sBAAoB,YAAY,EAAE,CAAC;;AAG1C,QAAO,aAAa,QAAQ,UAAU,MAAM,CAAC,SAAS,IACpD,qBAAC,wBAAD;EAAwB,cAAc;EAAgB,cAAc;YAApE,CACG,UACD,qBAACC,iBAAD;GAAS,MAAM;aAAf,CACE,oBAACA,gBAAQ,QAAT;IAAgB,SAAA;cACd,oBAAC,YAAD;KACE,IAAG;KACH,UAAU,oBAAoB;KAC9B,SAAS;eAET,oBAAC,UAAD;MAAU,OAAO;MAAI,QAAQ;MAAM,CAAA;KACxB,CAAA;IACE,CAAA,EACjB,oBAACA,gBAAQ,SAAT;IAAiB,MAAK;IAAM,OAAM;IAAS,OAAO,EAAE,QAAQ,GAAG;cAC7D,oBAAC,YAAD;KAAY,UAAA;eACV,oBAAC,WAAD,EAAA,UAAY,kBAA6B,CAAA;KAC9B,CAAA;IACG,CAAA,CACV;KACa;MACvB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as styled, r as css } from "./styledComponentsInterop-Cs5CCPRy.mjs";
|
|
2
|
-
import { n as RouterLink } from "./router-BxmA940v.mjs";
|
|
3
2
|
import { semanticColor, semanticOnly, semanticTokens } from "./lib/semanticColor.mjs";
|
|
3
|
+
import { n as RouterLink } from "./router-BxmA940v.mjs";
|
|
4
4
|
import { paragraphMixins } from "./mixins/text.mjs";
|
|
5
5
|
import { t as useToggle } from "./useToggle-1z8JE7Ym.mjs";
|
|
6
6
|
import { rotate } from "./variables/keyframes.mjs";
|
|
@@ -447,4 +447,4 @@ const IconButton = forwardRef(function IconButton({ size = "xs", ...props }, ref
|
|
|
447
447
|
//#endregion
|
|
448
448
|
export { SuffixIconContainer as a, StyledButton as i, Button as n, buttonPalette as o, ButtonChildren as r, IconButton as t };
|
|
449
449
|
|
|
450
|
-
//# sourceMappingURL=IconButton-
|
|
450
|
+
//# sourceMappingURL=IconButton-DxHB2g80.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IconButton-DftINsp7.mjs","names":["noop"],"sources":["../src/components/Button/palette.ts","../src/components/Button/Button.tsx","../src/components/Button/IconButton.tsx"],"sourcesContent":["import type { Color } from '@persona/design-tokens';\n\nimport { type PdsColor, transparent, withAlpha } from '#src/lib/color';\nimport { semanticTokens } from '#src/lib/semanticColor';\nimport type { PersonaTheme } from '#src/theme';\nimport type { SemanticTokens } from '#src/variables/semantic';\n\nexport type ButtonVariant = 'basic' | 'primary' | 'inverse' | 'danger' | 'text' | 'outline';\n\nexport interface ButtonPalette {\n default: PdsColor;\n hover: Color;\n active: Color;\n disabled: PdsColor;\n text: Color;\n textDisabled: PdsColor;\n /** Set only under semantic theming; legacy leaves disabled icon colour to the stroke rules. */\n iconDisabled?: PdsColor;\n highlightDark: Color;\n}\n\nconst buildSemanticPalettes = (tokens: SemanticTokens): Record<ButtonVariant, ButtonPalette> => {\n const neutral = {\n hover: tokens.ActionNeutralHover,\n active: tokens.ActionNeutralActive,\n text: tokens.FgPrimary,\n textDisabled: tokens.FgDisabled,\n iconDisabled: tokens.FgDisabled,\n highlightDark: tokens.FgDisabled,\n };\n return {\n basic: {\n ...neutral,\n default: tokens.ActionNeutral,\n disabled: withAlpha(tokens.ActionNeutral, tokens.Opacity65),\n },\n text: { ...neutral, default: transparent, disabled: transparent },\n outline: {\n ...neutral,\n default: transparent,\n hover: tokens.ActionOutlineHover,\n active: tokens.ActionOutlineActive,\n disabled: transparent,\n },\n primary: {\n default: tokens.ActionPrimary,\n hover: tokens.ActionPrimaryHover,\n active: tokens.ActionPrimaryActive,\n disabled: tokens.ActionPrimary,\n text: tokens.FgInverse,\n textDisabled: tokens.FgInverse,\n iconDisabled: tokens.FgInverse,\n highlightDark: tokens.FgInverse,\n },\n danger: {\n default: tokens.ActionDanger,\n hover: tokens.ActionDangerHover,\n active: tokens.ActionDangerActive,\n disabled: tokens.ActionDanger,\n text: tokens.FgInverse,\n textDisabled: tokens.FgInverse,\n iconDisabled: tokens.FgInverse,\n highlightDark: tokens.FgInverse,\n },\n inverse: {\n default: tokens.ActionInverse,\n hover: tokens.ActionInverseHover,\n active: tokens.ActionInverseActive,\n disabled: withAlpha(tokens.ActionInverse, tokens.Opacity65),\n text: tokens.FgPrimaryStatic,\n textDisabled: withAlpha(tokens.FgPrimaryStatic, tokens.Opacity65),\n iconDisabled: withAlpha(tokens.FgPrimaryStatic, tokens.Opacity65),\n highlightDark: tokens.ActionNeutralActive,\n },\n };\n};\n\nconst semanticPaletteCache = new WeakMap<SemanticTokens, Record<ButtonVariant, ButtonPalette>>();\n\nconst semanticPalettes = (tokens: SemanticTokens): Record<ButtonVariant, ButtonPalette> => {\n let palettes = semanticPaletteCache.get(tokens);\n if (!palettes) {\n palettes = buildSemanticPalettes(tokens);\n semanticPaletteCache.set(tokens, palettes);\n }\n return palettes;\n};\n\nexport const buttonPalette = (theme: PersonaTheme, variant: ButtonVariant): ButtonPalette => {\n const tokens = semanticTokens(theme);\n return tokens ? semanticPalettes(tokens)[variant] : theme.color.variants[variant];\n};\n","import { isEmpty, isFunction } from 'lodash-es';\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n type HTMLAttributeAnchorTarget,\n type MouseEvent,\n type ReactNode,\n type Ref,\n useCallback,\n} from 'react';\nimport styled, {\n css,\n type DefaultTheme,\n type FlattenInterpolation,\n type ThemeProps,\n} from 'styled-components';\n\nimport { Color, Spacing } from '@persona/design-tokens';\nimport { LoaderIcon } from '@persona/icons';\n\nimport { opacityOf, withAlpha } from '#src/lib/color';\nimport { isDisabled, isHovered, isNotDisabled } from '#src/lib/pseudoClass';\nimport { RouterLink, type To } from '#src/lib/router';\nimport { semanticColor, semanticOnly, semanticTokens } from '#src/lib/semanticColor';\nimport useToggle from '#src/lib/useToggle';\nimport { focusOutlineControlled } from '#src/mixins/focus';\nimport { printMixins } from '#src/mixins/print';\nimport { paragraphMixins } from '#src/mixins/text';\nimport type PseudoClassProps from '#src/types/PseudoClassProps';\nimport { rotate } from '#src/variables/keyframes';\nimport { TransitionDuration } from '#src/variables/transitions';\n\nimport { type ButtonVariant, buttonPalette } from './palette';\n\nconst noop = (): void => undefined;\n\n// TODO(joseph): Bring this fix back to pseudoClass\nconst isActive = ({ active }: PseudoClassProps) => (active ? '' : ':active:enabled');\n\n/* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\nconst sizeStyles: Record<ButtonProps['size'], FlattenInterpolation<ThemeProps<DefaultTheme>>> = {\n md: css`\n ${paragraphMixins.md}\n height: ${({ theme }) => theme.button.height.md};\n padding: ${Spacing[2]};\n svg {\n height: 16px;\n width: 16px;\n }\n `,\n sm: css`\n ${paragraphMixins.sm}\n height: ${({ theme }) => theme.button.height.sm};\n padding: ${Spacing[1]} 6px;\n svg {\n height: 12px;\n width: 12px;\n }\n `,\n};\n\n/* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\nconst widthStyles: Record<ButtonProps['width'], FlattenInterpolation<ThemeProps<DefaultTheme>>> = {\n full: css`\n width: 100%;\n `,\n auto: css`\n width: auto;\n `,\n // TODO: rename this prop to 'element' as a standard unresponsive element width\n button: css`\n width: ${({ theme }) => theme.element.width.md};\n `,\n icon: css<ButtonProps>`\n width: ${({ theme, size }) => {\n /* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\n return theme.button.height[size];\n }};\n padding: 0;\n flex: none;\n `,\n};\n\ninterface ButtonPropsWithTransientProps extends Omit<ButtonProps, 'isPending'> {\n $isPending: boolean;\n $onSecondaryBackground?: boolean;\n}\n\nexport const StyledButton = styled.button.attrs<ButtonPropsWithTransientProps>(({ to, target }) => {\n if (isEmpty(to)) {\n return 'button';\n } else if (typeof to === 'string' && to.startsWith('https://')) {\n return {\n as: 'a',\n href: to,\n target: target ?? '_blank',\n rel: 'noreferrer',\n };\n } else {\n return {\n as: RouterLink,\n };\n }\n})<ButtonPropsWithTransientProps>`\n cursor: pointer;\n border: none;\n box-sizing: border-box;\n white-space: nowrap;\n ${({ theme, variant = 'primary' }) => {\n const palette = buttonPalette(theme, variant);\n const tokens = semanticTokens(theme);\n return css`\n &:disabled {\n background-color: ${palette.disabled};\n color: ${palette.textDisabled};\n ${\n tokens &&\n (variant === 'primary' || variant === 'danger') &&\n css`\n opacity: ${opacityOf(tokens.Opacity65)};\n `\n }\n ${\n palette.iconDisabled &&\n css`\n svg {\n color: ${palette.iconDisabled};\n }\n `\n }\n svg path {\n stroke: ${palette.iconDisabled ?? palette.textDisabled};\n }\n\n /* For backwards compatibility with current coloring scheme (targeting stroke property) */\n svg.pds-icon {\n path {\n stroke: unset;\n }\n\n /* Support icons with stroke */\n path[stroke] {\n stroke: currentColor;\n }\n }\n\n user-select: none;\n }\n `;\n }}\n\n ${({ theme, variant }) =>\n variant === 'outline' &&\n css`\n border: 1px solid ${semanticColor(theme, 'BorderDefault', theme.color.border.input)};\n `}\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n /* To properly position loading spinner */\n position: relative;\n\n border-radius: ${({ theme }) => theme.button.borderRadius};\n\n transition-duration: ${TransitionDuration.Fast};\n transition-property: background-color, color, border-color, width, height;\n\n ${({ size }) => {\n /* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\n return sizeStyles[size];\n }}\n ${({ width }) => {\n /* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\n return widthStyles[width];\n }}\n\n /* Variant styling */\n ${({ theme, variant = 'primary', $isPending, $onSecondaryBackground }) => {\n let palette = buttonPalette(theme, variant);\n\n if (variant === 'basic' && $onSecondaryBackground) {\n const tokens = semanticTokens(theme);\n palette = tokens\n ? {\n ...palette,\n default: tokens.ActionNeutralHover,\n hover: tokens.ActionNeutralActive,\n active: tokens.ActionNeutralActive,\n disabled: withAlpha(tokens.ActionNeutralHover, tokens.Opacity65),\n }\n : {\n ...palette,\n default: Color.CoreSlate300,\n hover: Color.CoreSlate400,\n active: Color.CoreSlate400,\n disabled: Color.CoreSlate100,\n };\n }\n\n return css`\n background-color: ${palette.default};\n color: ${palette.text};\n svg path {\n stroke: ${palette.text};\n }\n\n svg.pds-icon {\n path {\n stroke: unset;\n }\n\n path[stroke] {\n stroke: currentColor;\n }\n }\n\n &${isHovered}${isNotDisabled} {\n background-color: ${palette.hover};\n }\n\n &${isDisabled} {\n cursor: not-allowed;\n }\n\n &${isActive} {\n background-color: ${palette.active};\n }\n\n ${focusOutlineControlled}\n\n ${\n $isPending &&\n css`\n cursor: default;\n background-color: ${palette.active};\n &:disabled {\n background-color: ${buttonPalette(theme, variant).active};\n user-select: none;\n ${semanticOnly(() => 'opacity: 1;')}\n }\n\n svg path {\n stroke: ${palette.highlightDark};\n }\n\n // For backwards compatibility with current coloring scheme (targeting stroke property)\n svg.pds-icon {\n path {\n stroke: unset;\n }\n\n path[stroke] {\n stroke: currentColor;\n }\n }\n `\n }\n `;\n }}\n\n\n ${printMixins.hide}\n`;\n\ntype WithPendingProps = Pick<ButtonProps, 'isPending'>;\n\nconst LoaderContainer = styled.div<WithPendingProps>`\n position: absolute;\n height: 100%;\n width: 100%;\n top: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: opacity 2s;\n opacity: ${({ isPending }) => (isPending ? '1' : '0')};\n`;\n\nconst Loader = styled(LoaderIcon)`\n animation: ${rotate} linear 1s infinite;\n`;\n\nexport const ButtonChildren = styled('div').attrs(({ isPending }: WithPendingProps) => ({\n ['aria-hidden']: isPending,\n}))<WithPendingProps>`\n width: 100%;\n display: flex;\n flex-wrap: nowrap;\n align-items: center;\n justify-content: center;\n transition: opacity ${TransitionDuration.Fast};\n opacity: ${({ isPending }) => (isPending ? '0' : '1')};\n gap: ${Spacing[1]};\n`;\n\nconst PrefixIconContainer = styled.div`\n display: flex;\n align-items: center;\n`;\n\nconst InheritPrefixIconContainer = styled.div`\n display: flex;\n align-items: center;\n\n & svg {\n width: inherit;\n height: inherit;\n }\n`;\n\nexport const SuffixIconContainer = styled(PrefixIconContainer)`\n margin-right: 0;\n flex-grow: 1;\n justify-content: flex-end;\n`;\n\nconst ButtonText = styled.span<{ size: 'md' | 'sm'; width: 'full' | 'auto' | 'button' | 'icon' }>`\n position: relative;\n\n /* Needed to align for browsers that don't support text-box yet\n (which at this time, is firefox, and opera, and a few niche browsers)\n This checks firefox. Otherwise, it will default back to the original\n which is a slightly misaligned button\n */\n\n /* Was trying to use this with @supports not, but genuinely could not figure out why this wouldn't\n work */\n\n line-height: ${({ width }) => (width === 'icon' ? '0' : 'inherit')};\n @-moz-document url-prefix() {\n top: ${({ size }) => (size === 'md' ? '1px' : '0.5px')};\n }\n\n @supports (text-box: cap alphabetic) {\n text-box: ${({ width }) => (width === 'icon' ? 'normal' : 'cap alphabetic')};\n }\n`;\n\ntype MaybePromise =\n | ((e: MouseEvent<HTMLButtonElement>) => void)\n | ((e: MouseEvent<HTMLButtonElement>) => Promise<void>);\n\nexport interface ButtonProps\n extends ComponentPropsWithoutRef<'button'>, Omit<PseudoClassProps, 'checked'> {\n /**\n * Visual style of the button.\n *\n * - `primary` – filled brand colour, for the primary action on a surface.\n * - `basic` – subtle grey fill, for secondary actions.\n * - `outline` – transparent with a border, alternative secondary style.\n * - `text` – no background or border, for tertiary / inline actions.\n * - `inverse` – inverted fill for use on dark/coloured backgrounds.\n * - `danger` – red fill, for destructive actions.\n *\n * @defaultValue 'primary'\n */\n variant?: ButtonVariant;\n /**\n * Shows a loading spinner and disables the button. Also triggers automatically\n * when `onClick` returns a Promise, clearing once the promise settles.\n */\n isPending?: boolean;\n /**\n * Icon rendered to the left of the button label.\n * Import from `@persona/icons`.\n */\n prefixIcon?: ReactNode;\n /**\n * Controls how the prefix icon inherits sizing.\n *\n * - `basic` – icon is rendered inside a fixed-size container.\n * - `inherit` – icon stretches to fill the surrounding element's dimensions.\n *\n * @defaultValue 'basic'\n */\n prefixIconType?: 'basic' | 'inherit';\n\n /**\n * Icon rendered to the right of the button label.\n * Import from `@persona/icons`.\n */\n suffixIcon?: ReactNode;\n\n /**\n * Height and typography scale of the button.\n *\n * @defaultValue 'md'\n */\n size?: 'md' | 'sm';\n\n /**\n * Changes the button into a link.\n * A relative path renders a router-aware link (PDS `RouterProvider` adapter,\n * react-router when present, otherwise a plain `<a>`); an absolute `https://`\n * URL renders an `<a>` that opens in a new tab.\n */\n to?: To;\n\n /**\n * Overrides the target of the link if `to` is provided and is an external link.\n */\n target?: HTMLAttributeAnchorTarget;\n\n /**\n * History state attached to the navigation when `to` is an internal link.\n */\n state?: unknown;\n\n /**\n * Replaces the current history entry instead of pushing, when `to` is an internal link.\n */\n replace?: boolean;\n\n /**\n * Note: we may want to default this to 'button' in the future, but many instances of this Button component\n * in dashboard currently rely on the default 'submit' behavior that occurs when using this in redux-form\n * so we'll have to comb through and manually add the type='submit' prop.\n */\n type?: 'button' | 'reset' | 'submit';\n /**\n * Controls the width of the button.\n *\n * - `full` – stretches to fill its container (`width: 100%`).\n * - `auto` – shrinks to fit its content.\n * - `button` – a fixed medium element width (from design tokens).\n * - `icon` – square, sized to match the button height; use for icon-only buttons.\n *\n * @defaultValue 'full'\n */\n width?: 'full' | 'auto' | 'button' | 'icon';\n onClick?: MaybePromise;\n ref?: Ref<HTMLButtonElement>;\n\n /**\n * In some cases we render a button on a secondary background, which needs an adjustment\n * for certain variants.\n */\n onSecondaryBackground?: boolean;\n}\n\nconst Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n {\n id,\n children,\n prefixIcon,\n suffixIcon,\n disabled,\n isPending,\n type = 'button',\n prefixIconType = 'basic',\n variant = 'primary',\n size = 'md',\n width = 'full',\n onClick,\n onSecondaryBackground,\n to,\n target,\n state,\n replace,\n ...props\n }: ButtonProps,\n ref,\n) {\n const [isResolving, { enable, disable }] = useToggle(false);\n const innerOnClick: MaybePromise = isFunction(onClick) ? onClick : noop;\n const loading = isPending || isResolving;\n const isInternalLink = !isEmpty(to) && !(typeof to === 'string' && to.startsWith('https://'));\n\n const handleClick = useCallback(\n async (e: MouseEvent<HTMLButtonElement>) => {\n if (loading) {\n return;\n }\n\n const maybePromise = innerOnClick(e);\n\n if (maybePromise instanceof Promise) {\n enable();\n try {\n await maybePromise;\n } catch {\n // A failed action should not leave the button pending.\n } finally {\n disable();\n }\n }\n },\n [loading, innerOnClick],\n );\n\n return (\n <StyledButton\n id={id}\n type={type}\n data-test={'button__' + variant}\n variant={variant}\n size={size}\n width={width}\n disabled={disabled || loading}\n $isPending={loading}\n $onSecondaryBackground={onSecondaryBackground}\n to={to}\n target={target}\n {...(isInternalLink ? { state, replace } : {})}\n {...props}\n onClick={handleClick}\n ref={ref}\n >\n {loading && (\n <LoaderContainer isPending={loading}>\n <Loader aria-label={`Loading ${props['aria-label'] || ''}`} />\n </LoaderContainer>\n )}\n <ButtonChildren isPending={loading}>\n {prefixIcon != null && (\n <>\n {prefixIconType === 'basic' && <PrefixIconContainer>{prefixIcon}</PrefixIconContainer>}\n {prefixIconType === 'inherit' && (\n <InheritPrefixIconContainer>{prefixIcon}</InheritPrefixIconContainer>\n )}\n </>\n )}\n {children && (\n <ButtonText width={width} size={size}>\n {children}\n </ButtonText>\n )}\n {suffixIcon != null && <SuffixIconContainer>{suffixIcon}</SuffixIconContainer>}\n </ButtonChildren>\n </StyledButton>\n );\n});\n\nexport default Button;\n","import { forwardRef } from 'react';\nimport styled, { css } from 'styled-components';\n\nimport { BorderRadius } from '@persona/design-tokens';\n\nimport { semanticOnly } from '#src/lib/semanticColor';\n\nimport Button, { type ButtonProps } from './Button';\n\nconst BUTTON_SIZE_MAP = {\n xs: '16px',\n sm: '24px',\n md: '32px',\n};\n\nconst ICON_SIZE_MAP = {\n xs: '12px',\n sm: '16px',\n md: '16px',\n};\n\ntype IconBtnSize = keyof typeof BUTTON_SIZE_MAP;\n\nconst IconBtn = styled(Button).attrs({\n width: 'icon',\n variant: 'basic',\n})`\n background-color: transparent;\n padding: 0;\n border-radius: ${BorderRadius.Md};\n\n ${semanticOnly(\n () => css`\n &:disabled {\n background-color: transparent;\n }\n `,\n )}\n\n ${({ size }) => css`\n height: ${BUTTON_SIZE_MAP[size as IconBtnSize]};\n width: ${BUTTON_SIZE_MAP[size as IconBtnSize]};\n\n svg {\n width: ${ICON_SIZE_MAP[size as IconBtnSize]};\n height: ${ICON_SIZE_MAP[size as IconBtnSize]};\n }\n `}\n`;\n\nexport interface IconButtonProps extends Omit<\n ButtonProps,\n 'width' | 'prefixIcon' | 'prefixIconType' | 'suffixIcon' | 'variant' | 'size'\n> {\n /**\n * `xs` - 16px. `sm` - 24px. `md` - 32px.\n * Pair with a PDS icon in the prescribed size.\n */\n size?: IconBtnSize;\n}\n\n/**\n * Use to render icon-only buttons. Ensure buttons have proper aria properties.\n */\nconst IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(function IconButton(\n { size = 'xs', ...props },\n ref,\n) {\n return <IconBtn size={size as ButtonProps['size']} ref={ref} {...props} />;\n});\n\nexport default IconButton;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"IconButton-DxHB2g80.mjs","names":["noop"],"sources":["../src/components/Button/palette.ts","../src/components/Button/Button.tsx","../src/components/Button/IconButton.tsx"],"sourcesContent":["import type { Color } from '@persona/design-tokens';\n\nimport { type PdsColor, transparent, withAlpha } from '#src/lib/color';\nimport { semanticTokens } from '#src/lib/semanticColor';\nimport type { PersonaTheme } from '#src/theme';\nimport type { SemanticTokens } from '#src/variables/semantic';\n\nexport type ButtonVariant = 'basic' | 'primary' | 'inverse' | 'danger' | 'text' | 'outline';\n\nexport interface ButtonPalette {\n default: PdsColor;\n hover: Color;\n active: Color;\n disabled: PdsColor;\n text: Color;\n textDisabled: PdsColor;\n /** Set only under semantic theming; legacy leaves disabled icon colour to the stroke rules. */\n iconDisabled?: PdsColor;\n highlightDark: Color;\n}\n\nconst buildSemanticPalettes = (tokens: SemanticTokens): Record<ButtonVariant, ButtonPalette> => {\n const neutral = {\n hover: tokens.ActionNeutralHover,\n active: tokens.ActionNeutralActive,\n text: tokens.FgPrimary,\n textDisabled: tokens.FgDisabled,\n iconDisabled: tokens.FgDisabled,\n highlightDark: tokens.FgDisabled,\n };\n return {\n basic: {\n ...neutral,\n default: tokens.ActionNeutral,\n disabled: withAlpha(tokens.ActionNeutral, tokens.Opacity65),\n },\n text: { ...neutral, default: transparent, disabled: transparent },\n outline: {\n ...neutral,\n default: transparent,\n hover: tokens.ActionOutlineHover,\n active: tokens.ActionOutlineActive,\n disabled: transparent,\n },\n primary: {\n default: tokens.ActionPrimary,\n hover: tokens.ActionPrimaryHover,\n active: tokens.ActionPrimaryActive,\n disabled: tokens.ActionPrimary,\n text: tokens.FgInverse,\n textDisabled: tokens.FgInverse,\n iconDisabled: tokens.FgInverse,\n highlightDark: tokens.FgInverse,\n },\n danger: {\n default: tokens.ActionDanger,\n hover: tokens.ActionDangerHover,\n active: tokens.ActionDangerActive,\n disabled: tokens.ActionDanger,\n text: tokens.FgInverse,\n textDisabled: tokens.FgInverse,\n iconDisabled: tokens.FgInverse,\n highlightDark: tokens.FgInverse,\n },\n inverse: {\n default: tokens.ActionInverse,\n hover: tokens.ActionInverseHover,\n active: tokens.ActionInverseActive,\n disabled: withAlpha(tokens.ActionInverse, tokens.Opacity65),\n text: tokens.FgPrimaryStatic,\n textDisabled: withAlpha(tokens.FgPrimaryStatic, tokens.Opacity65),\n iconDisabled: withAlpha(tokens.FgPrimaryStatic, tokens.Opacity65),\n highlightDark: tokens.ActionNeutralActive,\n },\n };\n};\n\nconst semanticPaletteCache = new WeakMap<SemanticTokens, Record<ButtonVariant, ButtonPalette>>();\n\nconst semanticPalettes = (tokens: SemanticTokens): Record<ButtonVariant, ButtonPalette> => {\n let palettes = semanticPaletteCache.get(tokens);\n if (!palettes) {\n palettes = buildSemanticPalettes(tokens);\n semanticPaletteCache.set(tokens, palettes);\n }\n return palettes;\n};\n\nexport const buttonPalette = (theme: PersonaTheme, variant: ButtonVariant): ButtonPalette => {\n const tokens = semanticTokens(theme);\n return tokens ? semanticPalettes(tokens)[variant] : theme.color.variants[variant];\n};\n","import { isEmpty, isFunction } from 'lodash-es';\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n type HTMLAttributeAnchorTarget,\n type MouseEvent,\n type ReactNode,\n type Ref,\n useCallback,\n} from 'react';\nimport styled, {\n css,\n type DefaultTheme,\n type FlattenInterpolation,\n type ThemeProps,\n} from 'styled-components';\n\nimport { Color, Spacing } from '@persona/design-tokens';\nimport { LoaderIcon } from '@persona/icons';\n\nimport { opacityOf, withAlpha } from '#src/lib/color';\nimport { isDisabled, isHovered, isNotDisabled } from '#src/lib/pseudoClass';\nimport { RouterLink, type To } from '#src/lib/router';\nimport { semanticColor, semanticOnly, semanticTokens } from '#src/lib/semanticColor';\nimport useToggle from '#src/lib/useToggle';\nimport { focusOutlineControlled } from '#src/mixins/focus';\nimport { printMixins } from '#src/mixins/print';\nimport { paragraphMixins } from '#src/mixins/text';\nimport type PseudoClassProps from '#src/types/PseudoClassProps';\nimport { rotate } from '#src/variables/keyframes';\nimport { TransitionDuration } from '#src/variables/transitions';\n\nimport { type ButtonVariant, buttonPalette } from './palette';\n\nconst noop = (): void => undefined;\n\n// TODO(joseph): Bring this fix back to pseudoClass\nconst isActive = ({ active }: PseudoClassProps) => (active ? '' : ':active:enabled');\n\n/* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\nconst sizeStyles: Record<ButtonProps['size'], FlattenInterpolation<ThemeProps<DefaultTheme>>> = {\n md: css`\n ${paragraphMixins.md}\n height: ${({ theme }) => theme.button.height.md};\n padding: ${Spacing[2]};\n svg {\n height: 16px;\n width: 16px;\n }\n `,\n sm: css`\n ${paragraphMixins.sm}\n height: ${({ theme }) => theme.button.height.sm};\n padding: ${Spacing[1]} 6px;\n svg {\n height: 12px;\n width: 12px;\n }\n `,\n};\n\n/* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\nconst widthStyles: Record<ButtonProps['width'], FlattenInterpolation<ThemeProps<DefaultTheme>>> = {\n full: css`\n width: 100%;\n `,\n auto: css`\n width: auto;\n `,\n // TODO: rename this prop to 'element' as a standard unresponsive element width\n button: css`\n width: ${({ theme }) => theme.element.width.md};\n `,\n icon: css<ButtonProps>`\n width: ${({ theme, size }) => {\n /* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\n return theme.button.height[size];\n }};\n padding: 0;\n flex: none;\n `,\n};\n\ninterface ButtonPropsWithTransientProps extends Omit<ButtonProps, 'isPending'> {\n $isPending: boolean;\n $onSecondaryBackground?: boolean;\n}\n\nexport const StyledButton = styled.button.attrs<ButtonPropsWithTransientProps>(({ to, target }) => {\n if (isEmpty(to)) {\n return 'button';\n } else if (typeof to === 'string' && to.startsWith('https://')) {\n return {\n as: 'a',\n href: to,\n target: target ?? '_blank',\n rel: 'noreferrer',\n };\n } else {\n return {\n as: RouterLink,\n };\n }\n})<ButtonPropsWithTransientProps>`\n cursor: pointer;\n border: none;\n box-sizing: border-box;\n white-space: nowrap;\n ${({ theme, variant = 'primary' }) => {\n const palette = buttonPalette(theme, variant);\n const tokens = semanticTokens(theme);\n return css`\n &:disabled {\n background-color: ${palette.disabled};\n color: ${palette.textDisabled};\n ${\n tokens &&\n (variant === 'primary' || variant === 'danger') &&\n css`\n opacity: ${opacityOf(tokens.Opacity65)};\n `\n }\n ${\n palette.iconDisabled &&\n css`\n svg {\n color: ${palette.iconDisabled};\n }\n `\n }\n svg path {\n stroke: ${palette.iconDisabled ?? palette.textDisabled};\n }\n\n /* For backwards compatibility with current coloring scheme (targeting stroke property) */\n svg.pds-icon {\n path {\n stroke: unset;\n }\n\n /* Support icons with stroke */\n path[stroke] {\n stroke: currentColor;\n }\n }\n\n user-select: none;\n }\n `;\n }}\n\n ${({ theme, variant }) =>\n variant === 'outline' &&\n css`\n border: 1px solid ${semanticColor(theme, 'BorderDefault', theme.color.border.input)};\n `}\n\n display: flex;\n align-items: center;\n justify-content: center;\n\n /* To properly position loading spinner */\n position: relative;\n\n border-radius: ${({ theme }) => theme.button.borderRadius};\n\n transition-duration: ${TransitionDuration.Fast};\n transition-property: background-color, color, border-color, width, height;\n\n ${({ size }) => {\n /* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\n return sizeStyles[size];\n }}\n ${({ width }) => {\n /* @ts-expect-error [strict-migration] The following line is not strict; please fix! */\n return widthStyles[width];\n }}\n\n /* Variant styling */\n ${({ theme, variant = 'primary', $isPending, $onSecondaryBackground }) => {\n let palette = buttonPalette(theme, variant);\n\n if (variant === 'basic' && $onSecondaryBackground) {\n const tokens = semanticTokens(theme);\n palette = tokens\n ? {\n ...palette,\n default: tokens.ActionNeutralHover,\n hover: tokens.ActionNeutralActive,\n active: tokens.ActionNeutralActive,\n disabled: withAlpha(tokens.ActionNeutralHover, tokens.Opacity65),\n }\n : {\n ...palette,\n default: Color.CoreSlate300,\n hover: Color.CoreSlate400,\n active: Color.CoreSlate400,\n disabled: Color.CoreSlate100,\n };\n }\n\n return css`\n background-color: ${palette.default};\n color: ${palette.text};\n svg path {\n stroke: ${palette.text};\n }\n\n svg.pds-icon {\n path {\n stroke: unset;\n }\n\n path[stroke] {\n stroke: currentColor;\n }\n }\n\n &${isHovered}${isNotDisabled} {\n background-color: ${palette.hover};\n }\n\n &${isDisabled} {\n cursor: not-allowed;\n }\n\n &${isActive} {\n background-color: ${palette.active};\n }\n\n ${focusOutlineControlled}\n\n ${\n $isPending &&\n css`\n cursor: default;\n background-color: ${palette.active};\n &:disabled {\n background-color: ${buttonPalette(theme, variant).active};\n user-select: none;\n ${semanticOnly(() => 'opacity: 1;')}\n }\n\n svg path {\n stroke: ${palette.highlightDark};\n }\n\n // For backwards compatibility with current coloring scheme (targeting stroke property)\n svg.pds-icon {\n path {\n stroke: unset;\n }\n\n path[stroke] {\n stroke: currentColor;\n }\n }\n `\n }\n `;\n }}\n\n\n ${printMixins.hide}\n`;\n\ntype WithPendingProps = Pick<ButtonProps, 'isPending'>;\n\nconst LoaderContainer = styled.div<WithPendingProps>`\n position: absolute;\n height: 100%;\n width: 100%;\n top: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: opacity 2s;\n opacity: ${({ isPending }) => (isPending ? '1' : '0')};\n`;\n\nconst Loader = styled(LoaderIcon)`\n animation: ${rotate} linear 1s infinite;\n`;\n\nexport const ButtonChildren = styled('div').attrs(({ isPending }: WithPendingProps) => ({\n ['aria-hidden']: isPending,\n}))<WithPendingProps>`\n width: 100%;\n display: flex;\n flex-wrap: nowrap;\n align-items: center;\n justify-content: center;\n transition: opacity ${TransitionDuration.Fast};\n opacity: ${({ isPending }) => (isPending ? '0' : '1')};\n gap: ${Spacing[1]};\n`;\n\nconst PrefixIconContainer = styled.div`\n display: flex;\n align-items: center;\n`;\n\nconst InheritPrefixIconContainer = styled.div`\n display: flex;\n align-items: center;\n\n & svg {\n width: inherit;\n height: inherit;\n }\n`;\n\nexport const SuffixIconContainer = styled(PrefixIconContainer)`\n margin-right: 0;\n flex-grow: 1;\n justify-content: flex-end;\n`;\n\nconst ButtonText = styled.span<{ size: 'md' | 'sm'; width: 'full' | 'auto' | 'button' | 'icon' }>`\n position: relative;\n\n /* Needed to align for browsers that don't support text-box yet\n (which at this time, is firefox, and opera, and a few niche browsers)\n This checks firefox. Otherwise, it will default back to the original\n which is a slightly misaligned button\n */\n\n /* Was trying to use this with @supports not, but genuinely could not figure out why this wouldn't\n work */\n\n line-height: ${({ width }) => (width === 'icon' ? '0' : 'inherit')};\n @-moz-document url-prefix() {\n top: ${({ size }) => (size === 'md' ? '1px' : '0.5px')};\n }\n\n @supports (text-box: cap alphabetic) {\n text-box: ${({ width }) => (width === 'icon' ? 'normal' : 'cap alphabetic')};\n }\n`;\n\ntype MaybePromise =\n | ((e: MouseEvent<HTMLButtonElement>) => void)\n | ((e: MouseEvent<HTMLButtonElement>) => Promise<void>);\n\nexport interface ButtonProps\n extends ComponentPropsWithoutRef<'button'>, Omit<PseudoClassProps, 'checked'> {\n /**\n * Visual style of the button.\n *\n * - `primary` – filled brand colour, for the primary action on a surface.\n * - `basic` – subtle grey fill, for secondary actions.\n * - `outline` – transparent with a border, alternative secondary style.\n * - `text` – no background or border, for tertiary / inline actions.\n * - `inverse` – inverted fill for use on dark/coloured backgrounds.\n * - `danger` – red fill, for destructive actions.\n *\n * @defaultValue 'primary'\n */\n variant?: ButtonVariant;\n /**\n * Shows a loading spinner and disables the button. Also triggers automatically\n * when `onClick` returns a Promise, clearing once the promise settles.\n */\n isPending?: boolean;\n /**\n * Icon rendered to the left of the button label.\n * Import from `@persona/icons`.\n */\n prefixIcon?: ReactNode;\n /**\n * Controls how the prefix icon inherits sizing.\n *\n * - `basic` – icon is rendered inside a fixed-size container.\n * - `inherit` – icon stretches to fill the surrounding element's dimensions.\n *\n * @defaultValue 'basic'\n */\n prefixIconType?: 'basic' | 'inherit';\n\n /**\n * Icon rendered to the right of the button label.\n * Import from `@persona/icons`.\n */\n suffixIcon?: ReactNode;\n\n /**\n * Height and typography scale of the button.\n *\n * @defaultValue 'md'\n */\n size?: 'md' | 'sm';\n\n /**\n * Changes the button into a link.\n * A relative path renders a router-aware link (PDS `RouterProvider` adapter,\n * react-router when present, otherwise a plain `<a>`); an absolute `https://`\n * URL renders an `<a>` that opens in a new tab.\n */\n to?: To;\n\n /**\n * Overrides the target of the link if `to` is provided and is an external link.\n */\n target?: HTMLAttributeAnchorTarget;\n\n /**\n * History state attached to the navigation when `to` is an internal link.\n */\n state?: unknown;\n\n /**\n * Replaces the current history entry instead of pushing, when `to` is an internal link.\n */\n replace?: boolean;\n\n /**\n * Note: we may want to default this to 'button' in the future, but many instances of this Button component\n * in dashboard currently rely on the default 'submit' behavior that occurs when using this in redux-form\n * so we'll have to comb through and manually add the type='submit' prop.\n */\n type?: 'button' | 'reset' | 'submit';\n /**\n * Controls the width of the button.\n *\n * - `full` – stretches to fill its container (`width: 100%`).\n * - `auto` – shrinks to fit its content.\n * - `button` – a fixed medium element width (from design tokens).\n * - `icon` – square, sized to match the button height; use for icon-only buttons.\n *\n * @defaultValue 'full'\n */\n width?: 'full' | 'auto' | 'button' | 'icon';\n onClick?: MaybePromise;\n ref?: Ref<HTMLButtonElement>;\n\n /**\n * In some cases we render a button on a secondary background, which needs an adjustment\n * for certain variants.\n */\n onSecondaryBackground?: boolean;\n}\n\nconst Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n {\n id,\n children,\n prefixIcon,\n suffixIcon,\n disabled,\n isPending,\n type = 'button',\n prefixIconType = 'basic',\n variant = 'primary',\n size = 'md',\n width = 'full',\n onClick,\n onSecondaryBackground,\n to,\n target,\n state,\n replace,\n ...props\n }: ButtonProps,\n ref,\n) {\n const [isResolving, { enable, disable }] = useToggle(false);\n const innerOnClick: MaybePromise = isFunction(onClick) ? onClick : noop;\n const loading = isPending || isResolving;\n const isInternalLink = !isEmpty(to) && !(typeof to === 'string' && to.startsWith('https://'));\n\n const handleClick = useCallback(\n async (e: MouseEvent<HTMLButtonElement>) => {\n if (loading) {\n return;\n }\n\n const maybePromise = innerOnClick(e);\n\n if (maybePromise instanceof Promise) {\n enable();\n try {\n await maybePromise;\n } catch {\n // A failed action should not leave the button pending.\n } finally {\n disable();\n }\n }\n },\n [loading, innerOnClick],\n );\n\n return (\n <StyledButton\n id={id}\n type={type}\n data-test={'button__' + variant}\n variant={variant}\n size={size}\n width={width}\n disabled={disabled || loading}\n $isPending={loading}\n $onSecondaryBackground={onSecondaryBackground}\n to={to}\n target={target}\n {...(isInternalLink ? { state, replace } : {})}\n {...props}\n onClick={handleClick}\n ref={ref}\n >\n {loading && (\n <LoaderContainer isPending={loading}>\n <Loader aria-label={`Loading ${props['aria-label'] || ''}`} />\n </LoaderContainer>\n )}\n <ButtonChildren isPending={loading}>\n {prefixIcon != null && (\n <>\n {prefixIconType === 'basic' && <PrefixIconContainer>{prefixIcon}</PrefixIconContainer>}\n {prefixIconType === 'inherit' && (\n <InheritPrefixIconContainer>{prefixIcon}</InheritPrefixIconContainer>\n )}\n </>\n )}\n {children && (\n <ButtonText width={width} size={size}>\n {children}\n </ButtonText>\n )}\n {suffixIcon != null && <SuffixIconContainer>{suffixIcon}</SuffixIconContainer>}\n </ButtonChildren>\n </StyledButton>\n );\n});\n\nexport default Button;\n","import { forwardRef } from 'react';\nimport styled, { css } from 'styled-components';\n\nimport { BorderRadius } from '@persona/design-tokens';\n\nimport { semanticOnly } from '#src/lib/semanticColor';\n\nimport Button, { type ButtonProps } from './Button';\n\nconst BUTTON_SIZE_MAP = {\n xs: '16px',\n sm: '24px',\n md: '32px',\n};\n\nconst ICON_SIZE_MAP = {\n xs: '12px',\n sm: '16px',\n md: '16px',\n};\n\ntype IconBtnSize = keyof typeof BUTTON_SIZE_MAP;\n\nconst IconBtn = styled(Button).attrs({\n width: 'icon',\n variant: 'basic',\n})`\n background-color: transparent;\n padding: 0;\n border-radius: ${BorderRadius.Md};\n\n ${semanticOnly(\n () => css`\n &:disabled {\n background-color: transparent;\n }\n `,\n )}\n\n ${({ size }) => css`\n height: ${BUTTON_SIZE_MAP[size as IconBtnSize]};\n width: ${BUTTON_SIZE_MAP[size as IconBtnSize]};\n\n svg {\n width: ${ICON_SIZE_MAP[size as IconBtnSize]};\n height: ${ICON_SIZE_MAP[size as IconBtnSize]};\n }\n `}\n`;\n\nexport interface IconButtonProps extends Omit<\n ButtonProps,\n 'width' | 'prefixIcon' | 'prefixIconType' | 'suffixIcon' | 'variant' | 'size'\n> {\n /**\n * `xs` - 16px. `sm` - 24px. `md` - 32px.\n * Pair with a PDS icon in the prescribed size.\n */\n size?: IconBtnSize;\n}\n\n/**\n * Use to render icon-only buttons. Ensure buttons have proper aria properties.\n */\nconst IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(function IconButton(\n { size = 'xs', ...props },\n ref,\n) {\n return <IconBtn size={size as ButtonProps['size']} ref={ref} {...props} />;\n});\n\nexport default IconButton;\n"],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { r as BreadcrumbsProps } from "./Breadcrumbs-3MtvzTPi.mjs";
|
|
2
2
|
import { i as BaseFilterConfig, s as FilterConfig } from "./types-BXJ6qAGy.mjs";
|
|
3
|
-
import { r as TableControlsProps } from "./TableControls-
|
|
4
|
-
import { i as DataTableProps } from "./DataTable-
|
|
5
|
-
import { r as PageHeaderProps } from "./PageHeader-
|
|
3
|
+
import { r as TableControlsProps } from "./TableControls-ODHrCDJM.mjs";
|
|
4
|
+
import { i as DataTableProps } from "./DataTable-Bf1WDY0z.mjs";
|
|
5
|
+
import { r as PageHeaderProps } from "./PageHeader-UPiqJpIF.mjs";
|
|
6
6
|
import { UseColumnConfigurationOptions } from "./useColumnConfiguration.mjs";
|
|
7
7
|
import { ReactNode } from "react";
|
|
8
8
|
import * as _$react_jsx_runtime0 from "react/jsx-runtime";
|