Submit
Path:
~
/
/
usr
/
share
/
grafana
/
public
/
app
/
core
/
components
/
NestedFolderPicker
/
File Content:
Trigger.tsx
import { css, cx } from '@emotion/css'; import React, { forwardRef, ReactNode, ButtonHTMLAttributes } from 'react'; import Skeleton from 'react-loading-skeleton'; import { GrafanaTheme2 } from '@grafana/data'; import { Icon, getInputStyles, useTheme2, Text } from '@grafana/ui'; import { focusCss, getFocusStyles, getMouseFocusStyles } from '@grafana/ui/src/themes/mixins'; import { Trans, t } from 'app/core/internationalization'; interface TriggerProps extends ButtonHTMLAttributes<HTMLButtonElement> { isLoading: boolean; handleClearSelection?: (event: React.MouseEvent<SVGElement> | React.KeyboardEvent<SVGElement>) => void; invalid?: boolean; label?: ReactNode; } function Trigger( { handleClearSelection, isLoading, invalid, label, ...rest }: TriggerProps, ref: React.ForwardedRef<HTMLButtonElement> ) { const theme = useTheme2(); const styles = getStyles(theme, invalid); const handleKeyDown = (event: React.KeyboardEvent<SVGElement>) => { if (event.key === 'Enter' || event.key === ' ') { handleClearSelection?.(event); } }; return ( <div className={styles.wrapper}> <div className={styles.inputWrapper}> {label ? ( <div className={styles.prefix}> <Icon name="folder" /> </div> ) : undefined} <button type="button" className={cx(styles.fakeInput, label ? styles.hasPrefix : undefined)} {...rest} ref={ref} > {isLoading ? ( <Skeleton width={100} /> ) : label ? ( <Text truncate>{label}</Text> ) : ( <Text truncate color="secondary"> <Trans i18nKey="browse-dashboards.folder-picker.button-label">Select folder</Trans> </Text> )} {!isLoading && handleClearSelection && ( <Icon role="button" tabIndex={0} aria-label={t('browse-dashboards.folder-picker.clear-selection', 'Clear selection')} className={styles.clearIcon} name="times" onClick={handleClearSelection} onKeyDown={handleKeyDown} /> )} </button> <div className={styles.suffix}> <Icon name="angle-down" /> </div> </div> </div> ); } export default forwardRef(Trigger); const getStyles = (theme: GrafanaTheme2, invalid = false) => { const baseStyles = getInputStyles({ theme, invalid }); return { wrapper: baseStyles.wrapper, inputWrapper: baseStyles.inputWrapper, prefix: css([ baseStyles.prefix, { pointerEvents: 'none', color: theme.colors.text.primary, }, ]), suffix: css([ baseStyles.suffix, { pointerEvents: 'none', }, ]), fakeInput: css([ baseStyles.input, { textAlign: 'left', letterSpacing: 'normal', // We want the focus styles to appear only when tabbing through, not when clicking the button // (and when focus is restored after command palette closes) '&:focus': { outline: 'unset', boxShadow: 'unset', }, '&:focus-visible': css` ${focusCss(theme)} `, alignItems: 'center', display: 'flex', flexWrap: 'nowrap', justifyContent: 'space-between', paddingRight: 28, }, ]), hasPrefix: css({ paddingLeft: 28, }), clearIcon: css({ color: theme.colors.text.secondary, cursor: 'pointer', '&:hover': { color: theme.colors.text.primary, }, '&:focus:not(:focus-visible)': getMouseFocusStyles(theme), '&:focus-visible': getFocusStyles(theme), }), }; };
Submit
FILE
FOLDER
INFO
Name
Size
Permission
Action
NestedFolderList.tsx
8510 bytes
0644
NestedFolderPicker.test.tsx
9463 bytes
0644
NestedFolderPicker.tsx
12199 bytes
0644
Trigger.tsx
3788 bytes
0644
hooks.ts
2779 bytes
0644
N4ST4R_ID | Naxtarrr