@patternfly/react-docs 7.6.0-prerelease.7 → 7.6.0-prerelease.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +12 -13
- package/patternfly-docs/generated/components/about-modal/react.js +149 -0
- package/patternfly-docs/generated/components/accordion/react.js +262 -0
- package/patternfly-docs/generated/components/action-list/react.js +144 -0
- package/patternfly-docs/generated/components/alert/react-demos.js +56 -0
- package/patternfly-docs/generated/components/alert/react.js +1433 -0
- package/patternfly-docs/generated/components/avatar/react.js +166 -0
- package/patternfly-docs/generated/components/back-to-top/react-demos.js +60 -0
- package/patternfly-docs/generated/components/back-to-top/react.js +77 -0
- package/patternfly-docs/generated/components/backdrop/react.js +64 -0
- package/patternfly-docs/generated/components/background-image/react.js +62 -0
- package/patternfly-docs/generated/components/badge/react.js +97 -0
- package/patternfly-docs/generated/components/banner/react-demos.js +57 -0
- package/patternfly-docs/generated/components/banner/react.js +148 -0
- package/patternfly-docs/generated/components/brand/react.js +142 -0
- package/patternfly-docs/generated/components/breadcrumb/react.js +206 -0
- package/patternfly-docs/generated/components/button/react-demos.js +57 -0
- package/patternfly-docs/generated/components/button/react.js +826 -0
- package/patternfly-docs/generated/components/card/react-demos.js +201 -0
- package/patternfly-docs/generated/components/card/react.js +1015 -0
- package/patternfly-docs/generated/components/charts/area-chart/-Victory.js +1350 -0
- package/patternfly-docs/generated/components/charts/bar-chart/-Victory.js +1334 -0
- package/patternfly-docs/generated/components/charts/box-plot-chart/-Victory.js +1282 -0
- package/patternfly-docs/generated/components/charts/bullet-chart/-Victory.js +848 -0
- package/patternfly-docs/generated/components/charts/colors-for-charts/-Victory.js +192 -0
- package/patternfly-docs/generated/components/charts/donut-chart/-Victory.js +426 -0
- package/patternfly-docs/generated/components/charts/donut-utilization-chart/-Victory.js +804 -0
- package/patternfly-docs/generated/components/charts/legends/-Victory.js +3230 -0
- package/patternfly-docs/generated/components/charts/line-chart/-Victory.js +1178 -0
- package/patternfly-docs/generated/components/charts/line-chart/ECharts.js +525 -0
- package/patternfly-docs/generated/components/charts/patterns/-Victory.js +3382 -0
- package/patternfly-docs/generated/components/charts/pie-chart/-Victory.js +377 -0
- package/patternfly-docs/generated/components/charts/resize-observer/-Victory.js +2475 -0
- package/patternfly-docs/generated/components/charts/sankey-chart/ECharts.js +538 -0
- package/patternfly-docs/generated/components/charts/scatter-chart/-Victory.js +1551 -0
- package/patternfly-docs/generated/components/charts/skeletons/-Victory.js +4115 -0
- package/patternfly-docs/generated/components/charts/sparkline-chart/-Victory.js +955 -0
- package/patternfly-docs/generated/components/charts/stack-chart/-Victory.js +1173 -0
- package/patternfly-docs/generated/components/charts/threshold-chart/-Victory.js +1166 -0
- package/patternfly-docs/generated/components/charts/tooltips/-Victory.js +413 -0
- package/patternfly-docs/generated/components/chip/react-deprecated.js +323 -0
- package/patternfly-docs/generated/components/clipboard-copy/react.js +373 -0
- package/patternfly-docs/generated/components/code-block/react.js +148 -0
- package/patternfly-docs/generated/components/code-editor/react.js +659 -0
- package/patternfly-docs/generated/components/compass/react-demos.js +147 -0
- package/patternfly-docs/generated/components/compass/react.js +440 -0
- package/patternfly-docs/generated/components/content/react.js +248 -0
- package/patternfly-docs/generated/components/data-list/react-demos.js +90 -0
- package/patternfly-docs/generated/components/data-list/react.js +709 -0
- package/patternfly-docs/generated/components/date-and-time/calendar-month/react.js +283 -0
- package/patternfly-docs/generated/components/date-and-time/date-and-time-picker/react-demos.js +64 -0
- package/patternfly-docs/generated/components/date-and-time/date-picker/react-demos.js +83 -0
- package/patternfly-docs/generated/components/date-and-time/date-picker/react.js +395 -0
- package/patternfly-docs/generated/components/date-and-time/time-picker/react.js +241 -0
- package/patternfly-docs/generated/components/description-list/react-demos.js +58 -0
- package/patternfly-docs/generated/components/description-list/react.js +743 -0
- package/patternfly-docs/generated/components/divider/react.js +126 -0
- package/patternfly-docs/generated/components/drag-and-drop/react-demos.js +351 -0
- package/patternfly-docs/generated/components/drag-and-drop/react-deprecated.js +184 -0
- package/patternfly-docs/generated/components/drag-and-drop/react.js +137 -0
- package/patternfly-docs/generated/components/drawer/react.js +598 -0
- package/patternfly-docs/generated/components/dual-list-selector/react-deprecated.js +772 -0
- package/patternfly-docs/generated/components/dual-list-selector/react.js +594 -0
- package/patternfly-docs/generated/components/empty-state/react.js +199 -0
- package/patternfly-docs/generated/components/expandable-section/react-demos.js +65 -0
- package/patternfly-docs/generated/components/expandable-section/react.js +408 -0
- package/patternfly-docs/generated/components/file-upload/multiple-file-upload/react-demos.js +52 -0
- package/patternfly-docs/generated/components/file-upload/multiple-file-upload/react.js +398 -0
- package/patternfly-docs/generated/components/file-upload/simple-file-upload/react.js +749 -0
- package/patternfly-docs/generated/components/forms/checkbox/react.js +222 -0
- package/patternfly-docs/generated/components/forms/form/react.js +1106 -0
- package/patternfly-docs/generated/components/forms/form-select/react.js +208 -0
- package/patternfly-docs/generated/components/forms/radio/react.js +212 -0
- package/patternfly-docs/generated/components/forms/text-area/react.js +160 -0
- package/patternfly-docs/generated/components/forms/text-input/react.js +216 -0
- package/patternfly-docs/generated/components/helper-text/react-demos.js +180 -0
- package/patternfly-docs/generated/components/helper-text/react.js +164 -0
- package/patternfly-docs/generated/components/hero/react.js +88 -0
- package/patternfly-docs/generated/components/hint/react.js +169 -0
- package/patternfly-docs/generated/components/icon/react.js +215 -0
- package/patternfly-docs/generated/components/input-group/react.js +182 -0
- package/patternfly-docs/generated/components/jump-links/react-demos.js +154 -0
- package/patternfly-docs/generated/components/jump-links/react.js +212 -0
- package/patternfly-docs/generated/components/label/react-demos.js +57 -0
- package/patternfly-docs/generated/components/label/react.js +417 -0
- package/patternfly-docs/generated/components/list/react.js +175 -0
- package/patternfly-docs/generated/components/login-page/react.js +587 -0
- package/patternfly-docs/generated/components/masthead/react-demos.js +79 -0
- package/patternfly-docs/generated/components/masthead/react.js +291 -0
- package/patternfly-docs/generated/components/menus/application-launcher/react-demos.js +769 -0
- package/patternfly-docs/generated/components/menus/context-selector/react-demos.js +665 -0
- package/patternfly-docs/generated/components/menus/custom-menus/react-demos.js +187 -0
- package/patternfly-docs/generated/components/menus/dropdown/react-templates.js +163 -0
- package/patternfly-docs/generated/components/menus/dropdown/react.js +998 -0
- package/patternfly-docs/generated/components/menus/menu/react.js +1540 -0
- package/patternfly-docs/generated/components/menus/menu-toggle/react.js +747 -0
- package/patternfly-docs/generated/components/menus/options-menu/react-demos.js +508 -0
- package/patternfly-docs/generated/components/menus/select/react-templates.js +257 -0
- package/patternfly-docs/generated/components/menus/select/react.js +998 -0
- package/patternfly-docs/generated/components/modal/react-deprecated.js +554 -0
- package/patternfly-docs/generated/components/modal/react.js +597 -0
- package/patternfly-docs/generated/components/navigation/react-demos.js +356 -0
- package/patternfly-docs/generated/components/navigation/react.js +409 -0
- package/patternfly-docs/generated/components/notification-badge/react.js +196 -0
- package/patternfly-docs/generated/components/notification-drawer/react-demos.js +107 -0
- package/patternfly-docs/generated/components/notification-drawer/react.js +394 -0
- package/patternfly-docs/generated/components/number-input/react.js +210 -0
- package/patternfly-docs/generated/components/overflow-menu/react.js +274 -0
- package/patternfly-docs/generated/components/page/react-demos.js +149 -0
- package/patternfly-docs/generated/components/page/react.js +1352 -0
- package/patternfly-docs/generated/components/pagination/react.js +492 -0
- package/patternfly-docs/generated/components/panel/react.js +236 -0
- package/patternfly-docs/generated/components/popover/react.js +390 -0
- package/patternfly-docs/generated/components/progress/react-demos.js +59 -0
- package/patternfly-docs/generated/components/progress/react.js +283 -0
- package/patternfly-docs/generated/components/progress-stepper/react-demos.js +45 -0
- package/patternfly-docs/generated/components/progress-stepper/react.js +219 -0
- package/patternfly-docs/generated/components/search-input/react-demos.js +113 -0
- package/patternfly-docs/generated/components/search-input/react.js +263 -0
- package/patternfly-docs/generated/components/sidebar/react.js +236 -0
- package/patternfly-docs/generated/components/simple-list/react.js +200 -0
- package/patternfly-docs/generated/components/skeleton/react-demos.js +44 -0
- package/patternfly-docs/generated/components/skeleton/react.js +122 -0
- package/patternfly-docs/generated/components/skip-to-content/react.js +73 -0
- package/patternfly-docs/generated/components/slider/react.js +309 -0
- package/patternfly-docs/generated/components/spinner/react.js +111 -0
- package/patternfly-docs/generated/components/switch/react.js +163 -0
- package/patternfly-docs/generated/components/table/react-demos.js +355 -0
- package/patternfly-docs/generated/components/table/react-deprecated.js +1350 -0
- package/patternfly-docs/generated/components/table/react.js +3241 -0
- package/patternfly-docs/generated/components/tabs/react-demos.js +108 -0
- package/patternfly-docs/generated/components/tabs/react.js +1359 -0
- package/patternfly-docs/generated/components/text-input-group/react-demos.js +152 -0
- package/patternfly-docs/generated/components/text-input-group/react.js +278 -0
- package/patternfly-docs/generated/components/tile/react-deprecated.js +242 -0
- package/patternfly-docs/generated/components/timestamp/react.js +283 -0
- package/patternfly-docs/generated/components/title/react.js +94 -0
- package/patternfly-docs/generated/components/toggle-group/react.js +299 -0
- package/patternfly-docs/generated/components/toolbar/react-demos.js +66 -0
- package/patternfly-docs/generated/components/toolbar/react.js +932 -0
- package/patternfly-docs/generated/components/tooltip/react.js +241 -0
- package/patternfly-docs/generated/components/tree-view/react.js +429 -0
- package/patternfly-docs/generated/components/truncate/react.js +211 -0
- package/patternfly-docs/generated/components/wizard/react-demos.js +87 -0
- package/patternfly-docs/generated/components/wizard/react-deprecated.js +788 -0
- package/patternfly-docs/generated/components/wizard/react.js +986 -0
- package/patternfly-docs/generated/developer-guides/open-ui-automation/react.js +285 -0
- package/patternfly-docs/generated/foundations-and-styles/layouts/bullseye/react.js +70 -0
- package/patternfly-docs/generated/foundations-and-styles/layouts/flex/react.js +506 -0
- package/patternfly-docs/generated/foundations-and-styles/layouts/gallery/react.js +94 -0
- package/patternfly-docs/generated/foundations-and-styles/layouts/grid/react.js +272 -0
- package/patternfly-docs/generated/foundations-and-styles/layouts/level/react.js +87 -0
- package/patternfly-docs/generated/foundations-and-styles/layouts/split/react.js +124 -0
- package/patternfly-docs/generated/foundations-and-styles/layouts/stack/react.js +112 -0
- package/patternfly-docs/generated/index.js +1769 -0
- package/patternfly-docs/generated/patterns/card-view/react-demos.js +78 -0
- package/patternfly-docs/generated/patterns/filters/react-demos.js +141 -0
- package/patternfly-docs/generated/patterns/password-generator/react-demos.js +51 -0
- package/patternfly-docs/generated/patterns/password-strength/react-demos.js +61 -0
- package/patternfly-docs/generated/patterns/primary-detail/react-demos.js +124 -0
- package/patternfly-docs/generated/patterns/right-to-left/react-demos.js +81 -0
- package/LICENSE +0 -21
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { AutoLinkHeader, Example, Link as PatternflyThemeLink } from '@patternfly/documentation-framework/components';
|
|
3
|
+
import { useEffect, useRef, useState } from 'react';
|
|
4
|
+
import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon';
|
|
5
|
+
import RhMicronsCloseIcon from '@patternfly/react-icons/dist/esm/icons/rh-microns-close-icon';
|
|
6
|
+
const pageData = {
|
|
7
|
+
"id": "Text input group",
|
|
8
|
+
"section": "components",
|
|
9
|
+
"subsection": "",
|
|
10
|
+
"deprecated": false,
|
|
11
|
+
"template": false,
|
|
12
|
+
"beta": false,
|
|
13
|
+
"demo": false,
|
|
14
|
+
"newImplementationLink": false,
|
|
15
|
+
"source": "react-demos",
|
|
16
|
+
"tabName": null,
|
|
17
|
+
"slug": "/components/text-input-group/react-demos",
|
|
18
|
+
"sourceLink": "https://github.com/patternfly/patternfly-react/blob/main/packages/react-core/src/demos/TextInputGroupDemo.md",
|
|
19
|
+
"relPath": "packages/react-core/src/demos/TextInputGroupDemo.md",
|
|
20
|
+
"examples": [
|
|
21
|
+
"Attribute-value filtering",
|
|
22
|
+
"Auto-complete search with typeahead"
|
|
23
|
+
]
|
|
24
|
+
};
|
|
25
|
+
pageData.liveContext = {
|
|
26
|
+
useEffect,
|
|
27
|
+
useRef,
|
|
28
|
+
useState,
|
|
29
|
+
SearchIcon,
|
|
30
|
+
RhMicronsCloseIcon
|
|
31
|
+
};
|
|
32
|
+
pageData.examples = {
|
|
33
|
+
'Attribute-value filtering': props =>
|
|
34
|
+
<Example {...pageData} {...props} {...{"code":"import { useEffect, useRef, useState } from 'react';\nimport {\n TextInputGroup,\n TextInputGroupMain,\n TextInputGroupUtilities,\n Button,\n Menu,\n MenuContent,\n MenuList,\n MenuItem,\n Popper,\n Divider,\n Label,\n LabelGroup\n} from '@patternfly/react-core';\nimport SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon';\nimport RhMicronsCloseIcon from '@patternfly/react-icons/dist/esm/icons/rh-microns-close-icon';\n\nexport const AttributeValueFiltering: React.FunctionComponent = () => {\n const [inputValue, setInputValue] = useState('');\n const [selectedKey, setSelectedKey] = useState('');\n const [menuIsOpen, setMenuIsOpen] = useState(false);\n const [currentChips, setCurrentChips] = useState<string[]>([]);\n\n interface attributeValueData {\n [attribute: string]: string[];\n }\n\n /** key and value data to be shown in the menu */\n const data: attributeValueData = {\n Cluster: ['acmeqe-managed-1', 'local-cluster'],\n Kind: ['Template', 'ReplicationController', 'ReplicaSet', 'Deployment'],\n Label: ['release', 'environment', 'partition'],\n Name: ['backup-1', 'backup-2', 'production-1', 'production-2', 'testing'],\n Namespace: ['default', 'public'],\n Status: ['running', 'idle', 'stopped']\n };\n const keyNames = ['Cluster', 'Kind', 'Label', 'Name', 'Namespace', 'Status'];\n const [menuItemsText, setMenuItemsText] = useState(keyNames);\n const [menuItems, setMenuItems] = useState<React.ReactElement<any>[]>([]);\n\n /** refs used to detect when clicks occur inside vs outside of the textInputGroup and menu popper */\n const menuRef = useRef<HTMLDivElement>(null);\n const textInputGroupRef = useRef<HTMLDivElement>(null);\n\n /** callback for updating the inputValue state in this component so that the input can be controlled */\n const handleInputChange = (_event: React.FormEvent<HTMLInputElement>, value: string) => {\n setInputValue(value);\n };\n\n /** callback for removing a chip from the chip selections */\n const deleteChip = (chipToDelete: string) => {\n const newChips = currentChips.filter((chip) => !Object.is(chip, chipToDelete));\n setCurrentChips(newChips);\n };\n\n /** reset state hooks associated with key selection */\n const clearSelectedKey = () => {\n setInputValue('');\n setSelectedKey('');\n setMenuItemsText(keyNames);\n };\n\n /** callback for clearing all selected chips, the text input, and any selected keys */\n const clearChipsAndInput = () => {\n setCurrentChips([]);\n clearSelectedKey();\n };\n\n useEffect(() => {\n /** in the menu only show items that include the text in the input */\n const filteredMenuItems = menuItemsText\n .filter(\n (item) =>\n !inputValue ||\n item.toLowerCase().includes(\n inputValue\n .toString()\n .slice(selectedKey.length && selectedKey.length + 2)\n .toLowerCase()\n )\n )\n .map((currentValue, index) => (\n <MenuItem key={currentValue} itemId={index}>\n {currentValue}\n </MenuItem>\n ));\n\n /** in the menu show a disabled \"no result\" when all menu items are filtered out */\n if (filteredMenuItems.length === 0) {\n const noResultItem = (\n <MenuItem isDisabled key=\"no result\">\n No results found\n </MenuItem>\n );\n setMenuItems([noResultItem]);\n return;\n }\n\n /** determine the menu heading text based on key selection; or lack thereof */\n const headingItem = (\n <MenuItem isDisabled key=\"heading\">\n {selectedKey.length ? `${selectedKey} values` : 'Attributes'}\n </MenuItem>\n );\n\n const divider = <Divider key=\"divider\" />;\n\n setMenuItems([headingItem, divider, ...filteredMenuItems]);\n }, [inputValue, menuItemsText, selectedKey]);\n\n /** add selected key/value pair as a chip in the chip group */\n const selectValue = (selectedValue: string) => {\n setCurrentChips([...currentChips, `${selectedKey}: ${selectedValue}`]);\n clearSelectedKey();\n };\n\n /** update the input to show the selected key and the menu to show the values associated with that specific key */\n const selectKey = (selectedText: string) => {\n const values = data[selectedText];\n\n if (!values) {\n return;\n }\n\n setInputValue(`${selectedText}: `);\n setSelectedKey(selectedText);\n setMenuItemsText(values);\n };\n\n const handleEnter = () => {\n /** bail if heading + divider + first option are not all present */\n const firstResult = menuItems[2]?.props?.children;\n\n if (!firstResult) {\n return;\n }\n\n /** perform the appropriate action based on key selection state */\n if (selectedKey.length) {\n selectValue(firstResult);\n } else {\n selectKey(firstResult);\n }\n };\n\n /** allow the user to backspace at the selected key name to drop the currently selected key */\n const handleBackspace = () => {\n if (selectedKey.length && inputValue === `${selectedKey}: `) {\n clearSelectedKey();\n }\n };\n\n /** allow the user to select a key by simply typing it and entering a colon, exact (case sensitive) matches only */\n const handleColon = (event: React.KeyboardEvent) => {\n if (!selectedKey.length && keyNames.includes(inputValue)) {\n selectKey(inputValue);\n event.preventDefault();\n }\n };\n\n /** allow the user to focus on the menu and navigate using the arrow keys */\n const handleArrowKey = () => {\n if (menuRef.current) {\n const firstElement = menuRef.current.querySelector<HTMLButtonElement>('li > button:not(:disabled)');\n firstElement && firstElement.focus();\n }\n };\n\n /** enable keyboard only usage */\n const handleTextInputKeyDown = (event: React.KeyboardEvent) => {\n switch (event.key) {\n case 'Enter':\n handleEnter();\n break;\n case 'Escape':\n clearSelectedKey();\n break;\n case 'Backspace':\n handleBackspace();\n break;\n case ':':\n handleColon(event);\n break;\n case 'ArrowUp':\n case 'ArrowDown':\n handleArrowKey();\n break;\n }\n };\n\n /** perform the proper key or value selection when a menu item is selected */\n const onSelect = (event: React.MouseEvent<Element, MouseEvent> | undefined, _itemId: string | number) => {\n const selectedText = (event?.target as HTMLElement | undefined)?.innerText.trim() || '';\n\n if (selectedKey.length) {\n selectValue(selectedText);\n } else {\n selectKey(selectedText);\n }\n event?.stopPropagation();\n textInputGroupRef.current?.querySelector('input')?.focus();\n };\n\n /** close the menu when a click occurs outside of the menu or text input group */\n const handleClick = (event: MouseEvent | undefined) => {\n if (\n menuRef.current &&\n !menuRef.current.contains(event?.target as HTMLElement) &&\n !textInputGroupRef.current?.contains(event?.target as HTMLElement)\n ) {\n setMenuIsOpen(false);\n }\n };\n\n /** show the search icon only when there are no chips to prevent the chips from being displayed behind the icon */\n const showSearchIcon = !currentChips.length;\n\n /** only show the clear button when there is something that can be cleared */\n const showClearButton = !!inputValue || !!currentChips.length;\n\n /** render the utilities component only when a component it contains is being rendered */\n const showUtilities = showClearButton;\n\n const inputGroup = (\n <div ref={textInputGroupRef}>\n <TextInputGroup>\n <TextInputGroupMain\n icon={showSearchIcon && <SearchIcon />}\n value={inputValue}\n onChange={handleInputChange}\n onFocus={() => setMenuIsOpen(true)}\n onKeyDown={handleTextInputKeyDown}\n >\n <LabelGroup>\n {currentChips.map((currentChip) => (\n <Label key={currentChip} variant=\"outline\" onClose={() => deleteChip(currentChip)}>\n {currentChip}\n </Label>\n ))}\n </LabelGroup>\n </TextInputGroupMain>\n {showUtilities && (\n <TextInputGroupUtilities>\n {showClearButton && (\n <Button\n variant=\"plain\"\n onClick={clearChipsAndInput}\n aria-label=\"Clear button and input\"\n icon={<RhMicronsCloseIcon />}\n />\n )}\n </TextInputGroupUtilities>\n )}\n </TextInputGroup>\n </div>\n );\n\n const menu = (\n <div ref={menuRef}>\n <Menu onSelect={onSelect}>\n <MenuContent>\n <MenuList>{menuItems}</MenuList>\n </MenuContent>\n </Menu>\n </div>\n );\n\n return (\n <Popper\n trigger={inputGroup}\n triggerRef={textInputGroupRef}\n popper={menu}\n popperRef={menuRef}\n isVisible={menuIsOpen}\n onDocumentClick={handleClick}\n />\n );\n};\n","title":"Attribute-value filtering","lang":"ts","className":""}}>
|
|
35
|
+
|
|
36
|
+
<p {...{"className":"pf-v6-c-content--p pf-m-editorial ws-p "}}>
|
|
37
|
+
{`This demo showcases the selection of attribute-value pairs based on a predefined set of data.`}
|
|
38
|
+
</p>
|
|
39
|
+
|
|
40
|
+
<p {...{"className":"pf-v6-c-content--p pf-m-editorial ws-p "}}>
|
|
41
|
+
{`Available attributes are shown in a menu when focus is placed on the text input. Once an attribute is selected the values for that attribute will be shown in the menu. When a value is selected for the attribute the pair will be converted into a chip and placed into the chip group. Typing in the text input will filter the entries shown in the menu.`}
|
|
42
|
+
</p>
|
|
43
|
+
|
|
44
|
+
<p {...{"className":"pf-v6-c-content--p pf-m-editorial ws-p "}}>
|
|
45
|
+
{`Attributes and values can both be selected by:`}
|
|
46
|
+
</p>
|
|
47
|
+
|
|
48
|
+
<ul {...{"className":"pf-v6-c-content--ul pf-m-editorial ws-ul "}}>
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
<li {...{"className":"pf-v6-c-content--li pf-m-editorial ws-li "}}>
|
|
53
|
+
{`clicking the entry shown in the menu`}
|
|
54
|
+
</li>
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
<li {...{"className":"pf-v6-c-content--li pf-m-editorial ws-li "}}>
|
|
59
|
+
{`hitting the up or down arrows (while focused on the text input) to switch focus to the menu, navigating the menu using the arrow keys, and hitting `}
|
|
60
|
+
|
|
61
|
+
<code {...{"className":"ws-code "}}>
|
|
62
|
+
{`enter`}
|
|
63
|
+
</code>
|
|
64
|
+
{` on an entry`}
|
|
65
|
+
</li>
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
<li {...{"className":"pf-v6-c-content--li pf-m-editorial ws-li "}}>
|
|
70
|
+
{`hitting `}
|
|
71
|
+
|
|
72
|
+
<code {...{"className":"ws-code "}}>
|
|
73
|
+
{`enter`}
|
|
74
|
+
</code>
|
|
75
|
+
{` (while focused on the text input) to select the first entry shown in the menu at the time`}
|
|
76
|
+
</li>
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
</ul>
|
|
80
|
+
|
|
81
|
+
<p {...{"className":"pf-v6-c-content--p pf-m-editorial ws-p "}}>
|
|
82
|
+
{`Additionally, attributes can be selected by typing the full (case sensitive) name of an attribute, then typing `}
|
|
83
|
+
|
|
84
|
+
<code {...{"className":"ws-code "}}>
|
|
85
|
+
{`:`}
|
|
86
|
+
</code>
|
|
87
|
+
{`.`}
|
|
88
|
+
</p>
|
|
89
|
+
|
|
90
|
+
<p {...{"className":"pf-v6-c-content--p pf-m-editorial ws-p "}}>
|
|
91
|
+
{`Attributes can be deselected (returning you to attribute selection mode) by hitting `}
|
|
92
|
+
|
|
93
|
+
<code {...{"className":"ws-code "}}>
|
|
94
|
+
{`escape`}
|
|
95
|
+
</code>
|
|
96
|
+
{`, or by hitting `}
|
|
97
|
+
|
|
98
|
+
<code {...{"className":"ws-code "}}>
|
|
99
|
+
{`backspace`}
|
|
100
|
+
</code>
|
|
101
|
+
{` when the only text in the text input is the attribute.`}
|
|
102
|
+
</p>
|
|
103
|
+
</Example>,
|
|
104
|
+
'Auto-complete search with typeahead': props =>
|
|
105
|
+
<Example {...pageData} {...props} {...{"code":"import { useEffect, useRef, useState } from 'react';\nimport {\n TextInputGroup,\n TextInputGroupMain,\n TextInputGroupUtilities,\n Button,\n Menu,\n MenuContent,\n MenuList,\n MenuItem,\n Popper,\n Divider,\n Label,\n LabelGroup\n} from '@patternfly/react-core';\nimport SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon';\nimport RhMicronsCloseIcon from '@patternfly/react-icons/dist/esm/icons/rh-microns-close-icon';\n\nexport const AutoCompleteSearch: React.FunctionComponent = () => {\n const [inputValue, setInputValue] = useState('');\n const [menuIsOpen, setMenuIsOpen] = useState(false);\n const [currentChips, setCurrentChips] = useState<string[]>([]);\n const [hint, setHint] = useState('');\n\n /** auto-completing suggestion text items to be shown in the menu */\n const suggestionItems = ['Cluster', 'Kind', 'Label', 'Name', 'Namespace', 'Status'];\n const [menuItems, setMenuItems] = useState<React.ReactElement<any>[]>([]);\n\n /** refs used to detect when clicks occur inside vs outside of the textInputGroup and menu popper */\n const menuRef = useRef<HTMLDivElement>(undefined);\n const textInputGroupRef = useRef<HTMLDivElement>(undefined);\n\n /** callback for updating the inputValue state in this component so that the input can be controlled */\n const handleInputChange = (_event: React.FormEvent<HTMLInputElement>, value: string) => {\n setInputValue(value);\n };\n\n /** callback for removing a chip from the chip selections */\n const deleteChip = (chipToDelete: string) => {\n const newChips = currentChips.filter((chip) => !Object.is(chip, chipToDelete));\n setCurrentChips(newChips);\n };\n\n /** callback for clearing all selected chips and the text input */\n const clearChipsAndInput = () => {\n setCurrentChips([]);\n setInputValue('');\n };\n\n useEffect(() => {\n /** in the menu only show items that include the text in the input */\n const filteredMenuItems = suggestionItems\n .filter((item) => !inputValue || item.toLowerCase().includes(inputValue.toString().toLowerCase()))\n .map((currentValue, index) => (\n <MenuItem key={currentValue} itemId={index}>\n {currentValue}\n </MenuItem>\n ));\n\n /** in the menu show a disabled \"no result\" when all menu items are filtered out */\n if (filteredMenuItems.length === 0) {\n const noResultItem = (\n <MenuItem isDisabled key=\"no result\">\n No results found\n </MenuItem>\n );\n setMenuItems([noResultItem]);\n setHint('');\n return;\n }\n\n /** The hint is set whenever there is only one autocomplete option left. */\n if (filteredMenuItems.length === 1) {\n const hint = filteredMenuItems[0].props.children;\n if (hint.toLowerCase().indexOf(inputValue.toLowerCase())) {\n // the match was found in a place other than the start, so typeahead wouldn't work right\n setHint('');\n } else {\n // use the input for the first part, otherwise case difference could make things look wrong\n setHint(inputValue + hint.substr(inputValue.length));\n }\n } else {\n setHint('');\n }\n\n /** add a heading to the menu */\n const headingItem = (\n <MenuItem isDisabled key=\"heading\">\n Suggestions\n </MenuItem>\n );\n\n const divider = <Divider key=\"divider\" />;\n\n setMenuItems([headingItem, divider, ...filteredMenuItems]);\n }, [inputValue]);\n\n /** add the given string as a chip in the chip group and clear the input */\n const addChip = (newChipText: string) => {\n setCurrentChips([...currentChips, `${newChipText}`]);\n setInputValue('');\n };\n\n /** add the current input value as a chip */\n const handleEnter = () => {\n if (inputValue.length) {\n addChip(inputValue);\n }\n };\n\n const handleTab = () => {\n if (menuItems.length === 3) {\n setInputValue(menuItems[2].props.children);\n }\n setMenuIsOpen(false);\n };\n\n /** close the menu when escape is hit */\n const handleEscape = () => {\n setMenuIsOpen(false);\n };\n\n /** allow the user to focus on the menu and navigate using the arrow keys */\n const handleArrowKey = () => {\n if (menuRef.current) {\n const firstElement = menuRef.current.querySelector<HTMLButtonElement>('li > button:not(:disabled)');\n firstElement && firstElement.focus();\n }\n };\n\n /** reopen the menu if it's closed and any un-designated keys are hit */\n const handleDefault = () => {\n if (!menuIsOpen) {\n setMenuIsOpen(true);\n }\n };\n\n /** enable keyboard only usage while focused on the text input */\n const handleTextInputKeyDown = (event: React.KeyboardEvent) => {\n switch (event.key) {\n case 'Enter':\n handleEnter();\n break;\n case 'Escape':\n handleEscape();\n break;\n case 'Tab':\n handleTab();\n break;\n case 'ArrowUp':\n case 'ArrowDown':\n handleArrowKey();\n break;\n default:\n handleDefault();\n }\n };\n\n /** apply focus to the text input */\n const focusTextInput = () => {\n textInputGroupRef.current.querySelector('input').focus();\n };\n\n /** add the text of the selected item as a new chip */\n const onSelect = (event: React.MouseEvent<Element, MouseEvent>, _itemId: string | number) => {\n const selectedText = (event.target as HTMLElement).innerText;\n addChip(selectedText);\n event.stopPropagation();\n focusTextInput();\n };\n\n /** close the menu when a click occurs outside of the menu or text input group */\n const handleClick = (event: MouseEvent) => {\n if (\n menuRef.current &&\n !menuRef.current.contains(event.target as HTMLElement) &&\n !textInputGroupRef.current.contains(event.target as HTMLElement)\n ) {\n setMenuIsOpen(false);\n }\n };\n\n /** enable keyboard only usage while focused on the menu */\n const handleMenuKeyDown = (event: React.KeyboardEvent) => {\n switch (event.key) {\n case 'Tab':\n case 'Escape':\n event.preventDefault();\n focusTextInput();\n setMenuIsOpen(false);\n break;\n case 'Enter':\n case ' ':\n setTimeout(() => setMenuIsOpen(false), 0);\n break;\n }\n };\n\n /** show the search icon only when there are no chips to prevent the chips from being displayed behind the icon */\n const showSearchIcon = !currentChips.length;\n\n /** only show the clear button when there is something that can be cleared */\n const showClearButton = !!inputValue || !!currentChips.length;\n\n /** render the utilities component only when a component it contains is being rendered */\n const showUtilities = showClearButton;\n\n const inputGroup = (\n <div ref={textInputGroupRef}>\n <TextInputGroup>\n <TextInputGroupMain\n icon={showSearchIcon && <SearchIcon />}\n value={inputValue}\n hint={hint}\n onChange={handleInputChange}\n onFocus={() => setMenuIsOpen(true)}\n onKeyDown={handleTextInputKeyDown}\n placeholder=\"search\"\n aria-label=\"Search input\"\n >\n <LabelGroup>\n {currentChips.map((currentChip) => (\n <Label key={currentChip} variant=\"outline\" onClose={() => deleteChip(currentChip)}>\n {currentChip}\n </Label>\n ))}\n </LabelGroup>\n </TextInputGroupMain>\n {showUtilities && (\n <TextInputGroupUtilities>\n {showClearButton && (\n <Button\n variant=\"plain\"\n onClick={clearChipsAndInput}\n aria-label=\"Clear button for chips and input\"\n icon={<RhMicronsCloseIcon />}\n />\n )}\n </TextInputGroupUtilities>\n )}\n </TextInputGroup>\n </div>\n );\n\n const menu = (\n <div ref={menuRef}>\n <Menu onSelect={onSelect} onKeyDown={handleMenuKeyDown}>\n <MenuContent>\n <MenuList>{menuItems}</MenuList>\n </MenuContent>\n </Menu>\n </div>\n );\n\n return (\n <Popper\n trigger={inputGroup}\n triggerRef={textInputGroupRef}\n popper={menu}\n popperRef={menuRef}\n appendTo={() => textInputGroupRef.current}\n isVisible={menuIsOpen}\n onDocumentClick={handleClick}\n />\n );\n};\n","title":"Auto-complete search with typeahead","lang":"ts","className":""}}>
|
|
106
|
+
|
|
107
|
+
<p {...{"className":"pf-v6-c-content--p pf-m-editorial ws-p "}}>
|
|
108
|
+
{`This demo showcases a search input with suggestions, which filters possible selections based on the text you've entered. Unlike the attribute-value filtering demo, it allows creation of new chip items when the text entered is not available in the list of suggestions.`}
|
|
109
|
+
</p>
|
|
110
|
+
|
|
111
|
+
<p {...{"className":"pf-v6-c-content--p pf-m-editorial ws-p "}}>
|
|
112
|
+
{`The current text in the input can be converted to a chip at any time by hitting `}
|
|
113
|
+
|
|
114
|
+
<code {...{"className":"ws-code "}}>
|
|
115
|
+
{`enter`}
|
|
116
|
+
</code>
|
|
117
|
+
{`. Auto-complete suggestions can be chosen by clicking the corresponding entry in the menu, or by navigating to an entry using the up/down arrow keys and selecting it with `}
|
|
118
|
+
|
|
119
|
+
<code {...{"className":"ws-code "}}>
|
|
120
|
+
{`enter`}
|
|
121
|
+
</code>
|
|
122
|
+
{`.`}
|
|
123
|
+
</p>
|
|
124
|
+
|
|
125
|
+
<p {...{"className":"pf-v6-c-content--p pf-m-editorial ws-p "}}>
|
|
126
|
+
{`Hitting `}
|
|
127
|
+
|
|
128
|
+
<code {...{"className":"ws-code "}}>
|
|
129
|
+
{`escape`}
|
|
130
|
+
</code>
|
|
131
|
+
{` while focused on the input or menu will close the menu, and the menu will reopen when text is entered.`}
|
|
132
|
+
</p>
|
|
133
|
+
|
|
134
|
+
<p {...{"className":"pf-v6-c-content--p pf-m-editorial ws-p "}}>
|
|
135
|
+
{`When only one item remains in the suggestion list, a typeahead hint will show and tab can be used to auto-complete the typing of that item.`}
|
|
136
|
+
</p>
|
|
137
|
+
</Example>
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const Component = () => (
|
|
141
|
+
<React.Fragment>
|
|
142
|
+
<AutoLinkHeader {...{"id":"demos","headingLevel":"h2","className":"ws-title ws-h2"}}>
|
|
143
|
+
{`Demos`}
|
|
144
|
+
</AutoLinkHeader>
|
|
145
|
+
{React.createElement(pageData.examples["Attribute-value filtering"])}
|
|
146
|
+
{React.createElement(pageData.examples["Auto-complete search with typeahead"])}
|
|
147
|
+
</React.Fragment>
|
|
148
|
+
);
|
|
149
|
+
Component.displayName = 'ComponentsTextInputGroupReactDemosDocs';
|
|
150
|
+
Component.pageData = pageData;
|
|
151
|
+
|
|
152
|
+
export default Component;
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { AutoLinkHeader, Example, Link as PatternflyThemeLink } from '@patternfly/documentation-framework/components';
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon';
|
|
5
|
+
import RhMicronsCloseIcon from '@patternfly/react-icons/dist/esm/icons/rh-microns-close-icon';
|
|
6
|
+
const pageData = {
|
|
7
|
+
"id": "Text input group",
|
|
8
|
+
"section": "components",
|
|
9
|
+
"subsection": "",
|
|
10
|
+
"deprecated": false,
|
|
11
|
+
"template": false,
|
|
12
|
+
"beta": false,
|
|
13
|
+
"demo": false,
|
|
14
|
+
"newImplementationLink": false,
|
|
15
|
+
"source": "react",
|
|
16
|
+
"tabName": null,
|
|
17
|
+
"slug": "/components/text-input-group/react",
|
|
18
|
+
"sourceLink": "https://github.com/patternfly/patternfly-react/blob/main/packages/react-core/src/components/TextInputGroup/examples/TextInputGroup.md",
|
|
19
|
+
"relPath": "packages/react-core/src/components/TextInputGroup/examples/TextInputGroup.md",
|
|
20
|
+
"propComponents": [
|
|
21
|
+
{
|
|
22
|
+
"name": "TextInputGroup",
|
|
23
|
+
"description": "",
|
|
24
|
+
"props": [
|
|
25
|
+
{
|
|
26
|
+
"name": "children",
|
|
27
|
+
"type": "React.ReactNode",
|
|
28
|
+
"description": "Content rendered inside the text input group"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"name": "className",
|
|
32
|
+
"type": "string",
|
|
33
|
+
"description": "Additional classes applied to the text input group container"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"name": "isDisabled",
|
|
37
|
+
"type": "boolean",
|
|
38
|
+
"description": "Adds disabled styling and a disabled context value which text input group main hooks into for the input itself"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"name": "isPlain",
|
|
42
|
+
"type": "boolean",
|
|
43
|
+
"description": "Flag to indicate the toggle has no border or background"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"name": "validated",
|
|
47
|
+
"type": "'success' | 'warning' | 'error' | 'default' | ValidatedOptions",
|
|
48
|
+
"description": "Value to indicate if the text input group is modified to show that validation state.\nIf set to success, warning, or error, the group will show that state.\nIf set to default, no validation styling is applied (use to clear a prior validation state)."
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"name": "TextInputGroupMain",
|
|
54
|
+
"description": "",
|
|
55
|
+
"props": [
|
|
56
|
+
{
|
|
57
|
+
"name": "aria-activedescendant",
|
|
58
|
+
"type": "string",
|
|
59
|
+
"description": "The id of the active element. Required if role has a value of \"combobox\", and focus\nshould remain on the input."
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"name": "aria-controls",
|
|
63
|
+
"type": "string",
|
|
64
|
+
"description": "The id of the element(s) controlled by the input. Required if role has a value of \"combobox\"."
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"name": "aria-label",
|
|
68
|
+
"type": "string",
|
|
69
|
+
"description": "Accessibility label for the input"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"name": "children",
|
|
73
|
+
"type": "React.ReactNode",
|
|
74
|
+
"description": "Content rendered inside the text input group main div"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"name": "className",
|
|
78
|
+
"type": "string",
|
|
79
|
+
"description": "Additional classes applied to the text input group main container"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"name": "hint",
|
|
83
|
+
"type": "string",
|
|
84
|
+
"description": "Suggestion that will show up like a placeholder even with text in the input"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"name": "icon",
|
|
88
|
+
"type": "React.ReactNode",
|
|
89
|
+
"description": "Icon to be shown on the left side of the text input group main container"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"name": "inputId",
|
|
93
|
+
"type": "string",
|
|
94
|
+
"description": "The id of the input element"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"name": "inputProps",
|
|
98
|
+
"type": "any",
|
|
99
|
+
"description": "Additional props to spread to the input element."
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"name": "isExpanded",
|
|
103
|
+
"type": "boolean",
|
|
104
|
+
"description": "Flag for whether an associated element controlled by the input is visible. Required if\nrole has a value of \"combobox\"."
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"name": "name",
|
|
108
|
+
"type": "string",
|
|
109
|
+
"description": "Name for the input"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"name": "onBlur",
|
|
113
|
+
"type": "(event?: any) => void",
|
|
114
|
+
"description": "Callback for when focus is lost on the input field"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"name": "onChange",
|
|
118
|
+
"type": "(event: React.FormEvent<HTMLInputElement>, value: string) => void",
|
|
119
|
+
"description": "Callback for when there is a change in the input field"
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"name": "onFocus",
|
|
123
|
+
"type": "(event?: any) => void",
|
|
124
|
+
"description": "Callback for when the input field is focused"
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"name": "placeholder",
|
|
128
|
+
"type": "string",
|
|
129
|
+
"description": "Placeholder value for the input"
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"name": "role",
|
|
133
|
+
"type": "string",
|
|
134
|
+
"description": "Determines the accessible role of the input."
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"name": "type",
|
|
138
|
+
"type": "| 'text'\n| 'date'\n| 'datetime-local'\n| 'email'\n| 'month'\n| 'number'\n| 'password'\n| 'search'\n| 'tel'\n| 'time'\n| 'url'",
|
|
139
|
+
"description": "Type that the input accepts."
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"name": "value",
|
|
143
|
+
"type": "string | number",
|
|
144
|
+
"description": "Value for the input"
|
|
145
|
+
}
|
|
146
|
+
]
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"name": "TextInputGroupUtilities",
|
|
150
|
+
"description": "",
|
|
151
|
+
"props": [
|
|
152
|
+
{
|
|
153
|
+
"name": "children",
|
|
154
|
+
"type": "React.ReactNode",
|
|
155
|
+
"description": "Content rendered inside the text input group utilities div"
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
"name": "className",
|
|
159
|
+
"type": "string",
|
|
160
|
+
"description": "Additional classes applied to the text input group utilities container"
|
|
161
|
+
}
|
|
162
|
+
]
|
|
163
|
+
}
|
|
164
|
+
],
|
|
165
|
+
"cssPrefix": [
|
|
166
|
+
"pf-v6-c-text-input-group"
|
|
167
|
+
],
|
|
168
|
+
"examples": [
|
|
169
|
+
"Basic text input group",
|
|
170
|
+
"Disabled text input group",
|
|
171
|
+
"With icon and utilities",
|
|
172
|
+
"With validation",
|
|
173
|
+
"With filters"
|
|
174
|
+
]
|
|
175
|
+
};
|
|
176
|
+
pageData.liveContext = {
|
|
177
|
+
useState,
|
|
178
|
+
SearchIcon,
|
|
179
|
+
RhMicronsCloseIcon
|
|
180
|
+
};
|
|
181
|
+
pageData.examples = {
|
|
182
|
+
'Basic text input group': props =>
|
|
183
|
+
<Example {...pageData} {...props} {...{"code":"import { useState } from 'react';\nimport { TextInputGroup, TextInputGroupMain } from '@patternfly/react-core';\n\nexport const TextInputGroupBasic: React.FunctionComponent = () => {\n const [value, setValue] = useState('');\n return (\n <TextInputGroup>\n <TextInputGroupMain value={value} onChange={(_event, value) => setValue(value)} />\n </TextInputGroup>\n );\n};\n","title":"Basic text input group","lang":"ts","className":""}}>
|
|
184
|
+
|
|
185
|
+
<p {...{"className":"pf-v6-c-content--p pf-m-editorial ws-p "}}>
|
|
186
|
+
{`A basic text input group updates its contents as users enter text.`}
|
|
187
|
+
</p>
|
|
188
|
+
</Example>,
|
|
189
|
+
'Disabled text input group': props =>
|
|
190
|
+
<Example {...pageData} {...props} {...{"code":"import { TextInputGroup, TextInputGroupMain } from '@patternfly/react-core';\n\nexport const TextInputGroupDisabled: React.FunctionComponent = () => (\n <TextInputGroup isDisabled>\n <TextInputGroupMain value=\"Disabled\" type=\"text\" aria-label=\"Disabled text input group example input\" />\n </TextInputGroup>\n);\n","title":"Disabled text input group","lang":"ts","className":""}}>
|
|
191
|
+
|
|
192
|
+
<p {...{"className":"pf-v6-c-content--p pf-m-editorial ws-p "}}>
|
|
193
|
+
{`To prevent users from making edits to a text input group, you can disable it using `}
|
|
194
|
+
|
|
195
|
+
<code {...{"className":"ws-code "}}>
|
|
196
|
+
{`isDisabled`}
|
|
197
|
+
</code>
|
|
198
|
+
{`.`}
|
|
199
|
+
</p>
|
|
200
|
+
</Example>,
|
|
201
|
+
'With icon and utilities': props =>
|
|
202
|
+
<Example {...pageData} {...props} {...{"code":"import { useState } from 'react';\nimport { TextInputGroup, TextInputGroupMain, TextInputGroupUtilities, Button } from '@patternfly/react-core';\nimport SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon';\nimport RhMicronsCloseIcon from '@patternfly/react-icons/dist/esm/icons/rh-microns-close-icon';\n\nexport const TextInputGroupUtilitiesAndIcon: React.FunctionComponent = () => {\n const [inputValue, setInputValue] = useState('');\n\n /** callback for updating the inputValue state in this component so that the input can be controlled */\n const handleInputChange = (_event: React.FormEvent<HTMLInputElement>, value: string) => {\n setInputValue(value);\n };\n\n /** show the input clearing button only when the input is not empty */\n const showClearButton = !!inputValue;\n\n /** render the utilities component only when a component it contains is being rendered */\n const showUtilities = showClearButton;\n\n /** callback for clearing the text input */\n const clearInput = () => {\n setInputValue('');\n };\n\n return (\n <TextInputGroup>\n <TextInputGroupMain icon={<SearchIcon />} value={inputValue} onChange={handleInputChange} />\n {showUtilities && (\n <TextInputGroupUtilities>\n {showClearButton && (\n <Button\n variant=\"plain\"\n onClick={clearInput}\n aria-label=\"Clear button and input\"\n icon={<RhMicronsCloseIcon />}\n />\n )}\n </TextInputGroupUtilities>\n )}\n </TextInputGroup>\n );\n};\n","title":"With icon and utilities","lang":"ts","className":""}}>
|
|
203
|
+
|
|
204
|
+
<p {...{"className":"pf-v6-c-content--p pf-m-editorial ws-p "}}>
|
|
205
|
+
{`To help users identify the purpose of an input group, you can add an icon. To do this, import your icon and pass it to `}
|
|
206
|
+
|
|
207
|
+
<code {...{"className":"ws-code "}}>
|
|
208
|
+
{`icon`}
|
|
209
|
+
</code>
|
|
210
|
+
{` within `}
|
|
211
|
+
|
|
212
|
+
<code {...{"className":"ws-code "}}>
|
|
213
|
+
{`<TextInputGroupMain>`}
|
|
214
|
+
</code>
|
|
215
|
+
{`.`}
|
|
216
|
+
</p>
|
|
217
|
+
|
|
218
|
+
<p {...{"className":"pf-v6-c-content--p pf-m-editorial ws-p "}}>
|
|
219
|
+
{`You can also add additional actions or utilities via `}
|
|
220
|
+
|
|
221
|
+
<code {...{"className":"ws-code "}}>
|
|
222
|
+
{`<TextInputGroupUtilities>`}
|
|
223
|
+
</code>
|
|
224
|
+
{`. The following example includes a clear button that allows users to remove their previous input.`}
|
|
225
|
+
</p>
|
|
226
|
+
</Example>,
|
|
227
|
+
'With validation': props =>
|
|
228
|
+
<Example {...pageData} {...props} {...{"code":"import { useState } from 'react';\nimport {\n TextInputGroup,\n TextInputGroupMain,\n TextInputGroupUtilities,\n Button,\n ValidatedOptions,\n Flex,\n FlexItem\n} from '@patternfly/react-core';\nimport SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon';\nimport RhMicronsCloseIcon from '@patternfly/react-icons/dist/esm/icons/rh-microns-close-icon';\n\nexport const TextInputGroupWithStatus: React.FunctionComponent = () => {\n const [successValue, setSuccessValue] = useState('Success validation');\n const [warningValue, setWarningValue] = useState('Warning validation with custom non-status icon at start');\n const [errorValue, setErrorValue] = useState('Error validation with custom non-status icon at start and utilities');\n\n /** show the input clearing button only when the input is not empty */\n const showClearButton = !!errorValue;\n\n /** render the utilities component only when a component it contains is being rendered */\n const showUtilities = showClearButton;\n\n /** callback for clearing the text input */\n const clearInput = () => {\n setErrorValue('');\n };\n\n return (\n <Flex direction={{ default: 'column' }} rowGap={{ default: 'rowGapSm' }}>\n <FlexItem>\n <TextInputGroup validated={ValidatedOptions.success}>\n <TextInputGroupMain value={successValue} onChange={(_event, value) => setSuccessValue(value)} />\n </TextInputGroup>\n </FlexItem>\n <FlexItem>\n <TextInputGroup validated={ValidatedOptions.warning}>\n <TextInputGroupMain\n icon={<SearchIcon />}\n value={warningValue}\n onChange={(_event, value) => setWarningValue(value)}\n />\n </TextInputGroup>\n </FlexItem>\n <FlexItem>\n <TextInputGroup validated={ValidatedOptions.error}>\n <TextInputGroupMain\n icon={<SearchIcon />}\n value={errorValue}\n onChange={(_event, value) => setErrorValue(value)}\n />\n {showUtilities && (\n <TextInputGroupUtilities>\n {showClearButton && (\n <Button\n variant=\"plain\"\n onClick={clearInput}\n aria-label=\"Clear button and input\"\n icon={<RhMicronsCloseIcon />}\n />\n )}\n </TextInputGroupUtilities>\n )}\n </TextInputGroup>\n </FlexItem>\n </Flex>\n );\n};\n","title":"With validation","lang":"ts","className":""}}>
|
|
229
|
+
|
|
230
|
+
<p {...{"className":"pf-v6-c-content--p pf-m-editorial ws-p "}}>
|
|
231
|
+
{`You can add a validation status to a `}
|
|
232
|
+
|
|
233
|
+
<code {...{"className":"ws-code "}}>
|
|
234
|
+
{`<TextInputGroup>`}
|
|
235
|
+
</code>
|
|
236
|
+
{` by passing the `}
|
|
237
|
+
|
|
238
|
+
<code {...{"className":"ws-code "}}>
|
|
239
|
+
{`validated`}
|
|
240
|
+
</code>
|
|
241
|
+
{` property with a value of either "success", "warning", or "error".`}
|
|
242
|
+
</p>
|
|
243
|
+
</Example>,
|
|
244
|
+
'With filters': props =>
|
|
245
|
+
<Example {...pageData} {...props} {...{"code":"import { useState } from 'react';\nimport {\n TextInputGroup,\n TextInputGroupMain,\n TextInputGroupUtilities,\n Label,\n LabelGroup,\n Button\n} from '@patternfly/react-core';\nimport SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon';\nimport RhMicronsCloseIcon from '@patternfly/react-icons/dist/esm/icons/rh-microns-close-icon';\n\nexport const TextInputGroupFilters: React.FunctionComponent = () => {\n const [inputValue, setInputValue] = useState('');\n const [currentChips, setCurrentChips] = useState([\n 'chip one',\n 'chip two',\n 'chip three',\n 'chip four',\n 'chip five',\n 'chip six',\n 'chip seven',\n 'chip eight',\n 'chip nine',\n 'chip ten',\n 'chip eleven',\n 'chip twelve',\n 'chip thirteen',\n 'chip fourteen'\n ]);\n\n /** show the search icon only when there are no chips to prevent the chips from being displayed behind the icon */\n const showSearchIcon = !currentChips.length;\n\n /** callback for updating the inputValue state in this component so that the input can be controlled */\n const handleInputChange = (_event: React.FormEvent<HTMLInputElement>, value: string) => {\n setInputValue(value);\n };\n\n /** callback for removing a chip from the chip selections */\n const deleteChip = (chipToDelete: string) => {\n const newChips = currentChips.filter((chip) => !Object.is(chip, chipToDelete));\n setCurrentChips(newChips);\n };\n\n /** show the input/chip clearing button only when either the text input or chip group are not empty */\n const showClearButton = !!inputValue || !!currentChips.length;\n\n /** render the utilities component only when a component it contains is being rendered */\n const showUtilities = showClearButton;\n\n /** callback for clearing all selected chips and the text input */\n const clearChipsAndInput = () => {\n setCurrentChips([]);\n setInputValue('');\n };\n\n return (\n <TextInputGroup>\n <TextInputGroupMain icon={showSearchIcon && <SearchIcon />} value={inputValue} onChange={handleInputChange}>\n <LabelGroup>\n {currentChips.map((currentChip) => (\n <Label key={currentChip} variant=\"outline\" onClose={() => deleteChip(currentChip)}>\n {currentChip}\n </Label>\n ))}\n </LabelGroup>\n </TextInputGroupMain>\n {showUtilities && (\n <TextInputGroupUtilities>\n {showClearButton && (\n <Button\n variant=\"plain\"\n onClick={clearChipsAndInput}\n aria-label=\"Clear button and input\"\n icon={<RhMicronsCloseIcon />}\n />\n )}\n </TextInputGroupUtilities>\n )}\n </TextInputGroup>\n );\n};\n","title":"With filters","lang":"ts","className":""}}>
|
|
246
|
+
|
|
247
|
+
<p {...{"className":"pf-v6-c-content--p pf-m-editorial ws-p "}}>
|
|
248
|
+
{`When a text input group is used within a data view, like a table, you can nest filter labels within the group. To do this, pass a `}
|
|
249
|
+
|
|
250
|
+
<code {...{"className":"ws-code "}}>
|
|
251
|
+
{`<LabelGroup>`}
|
|
252
|
+
</code>
|
|
253
|
+
{` to `}
|
|
254
|
+
|
|
255
|
+
<code {...{"className":"ws-code "}}>
|
|
256
|
+
{`<TextInputGroupMain>`}
|
|
257
|
+
</code>
|
|
258
|
+
{`, with all of the labels that a user has selected. Users can interact with these labels as needed.`}
|
|
259
|
+
</p>
|
|
260
|
+
</Example>
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
const Component = () => (
|
|
264
|
+
<React.Fragment>
|
|
265
|
+
<AutoLinkHeader {...{"id":"examples","headingLevel":"h2","className":"ws-title ws-h2"}}>
|
|
266
|
+
{`Examples`}
|
|
267
|
+
</AutoLinkHeader>
|
|
268
|
+
{React.createElement(pageData.examples["Basic text input group"])}
|
|
269
|
+
{React.createElement(pageData.examples["Disabled text input group"])}
|
|
270
|
+
{React.createElement(pageData.examples["With icon and utilities"])}
|
|
271
|
+
{React.createElement(pageData.examples["With validation"])}
|
|
272
|
+
{React.createElement(pageData.examples["With filters"])}
|
|
273
|
+
</React.Fragment>
|
|
274
|
+
);
|
|
275
|
+
Component.displayName = 'ComponentsTextInputGroupReactDocs';
|
|
276
|
+
Component.pageData = pageData;
|
|
277
|
+
|
|
278
|
+
export default Component;
|