@primer/components 0.0.0-2021911155316 → 0.0.0-2021911191417
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 +1 -1
- package/dist/browser.esm.js +355 -251
- package/dist/browser.esm.js.map +1 -1
- package/dist/browser.umd.js +422 -318
- package/dist/browser.umd.js.map +1 -1
- package/lib/AnchoredOverlay/AnchoredOverlay.d.ts +2 -1
- package/lib/AnchoredOverlay/AnchoredOverlay.js +11 -3
- package/lib/Autocomplete/Autocomplete.d.ts +37 -0
- package/lib/Autocomplete/Autocomplete.js +68 -0
- package/lib/Autocomplete/AutocompleteContext.d.ts +17 -0
- package/lib/Autocomplete/AutocompleteContext.js +11 -0
- package/lib/Autocomplete/AutocompleteInput.d.ts +9 -0
- package/lib/Autocomplete/AutocompleteInput.js +151 -0
- package/lib/Autocomplete/AutocompleteMenu.d.ts +71 -0
- package/lib/Autocomplete/AutocompleteMenu.js +223 -0
- package/lib/Autocomplete/AutocompleteOverlay.d.ts +20 -0
- package/lib/Autocomplete/AutocompleteOverlay.js +74 -0
- package/lib/Autocomplete/index.d.ts +2 -0
- package/lib/Autocomplete/index.js +15 -0
- package/lib/FilteredActionList/FilteredActionList.js +5 -31
- package/lib/Overlay.d.ts +2 -1
- package/lib/Overlay.js +10 -5
- package/lib/TextInput.d.ts +4 -12
- package/lib/TextInput.js +4 -46
- package/lib/TextInputWithTokens.d.ts +323 -0
- package/lib/TextInputWithTokens.js +244 -0
- package/lib/Token/AvatarToken.d.ts +7 -0
- package/lib/Token/AvatarToken.js +64 -0
- package/lib/Token/IssueLabelToken.d.ts +14 -0
- package/lib/Token/IssueLabelToken.js +144 -0
- package/lib/Token/Token.d.ts +15 -0
- package/lib/Token/Token.js +94 -0
- package/lib/Token/TokenBase.d.ts +31 -0
- package/lib/Token/TokenBase.js +108 -0
- package/lib/Token/_RemoveTokenButton.d.ts +12 -0
- package/lib/Token/_RemoveTokenButton.js +77 -0
- package/lib/Token/_TokenTextContainer.d.ts +3 -0
- package/lib/Token/_TokenTextContainer.js +17 -0
- package/lib/Token/index.d.ts +3 -0
- package/lib/Token/index.js +31 -0
- package/lib/_TextInputWrapper.d.ts +10 -0
- package/lib/_TextInputWrapper.js +51 -0
- package/lib/_UnstyledTextInput.d.ts +2 -0
- package/lib/_UnstyledTextInput.js +20 -0
- package/lib/hooks/useOpenAndCloseFocus.d.ts +2 -1
- package/lib/hooks/useOpenAndCloseFocus.js +7 -2
- package/lib/hooks/useOverlay.d.ts +2 -1
- package/lib/hooks/useOverlay.js +4 -2
- package/lib/index.d.ts +4 -0
- package/lib/index.js +36 -0
- package/lib/utils/scrollIntoViewingArea.d.ts +1 -0
- package/lib/utils/scrollIntoViewingArea.js +39 -0
- package/lib/utils/types/MandateProps.d.ts +3 -0
- package/lib/utils/types/MandateProps.js +1 -0
- package/lib/utils/types/index.d.ts +1 -0
- package/lib/utils/types/index.js +13 -0
- package/lib-esm/AnchoredOverlay/AnchoredOverlay.d.ts +2 -1
- package/lib-esm/AnchoredOverlay/AnchoredOverlay.js +11 -3
- package/lib-esm/Autocomplete/Autocomplete.d.ts +37 -0
- package/lib-esm/Autocomplete/Autocomplete.js +47 -0
- package/lib-esm/Autocomplete/AutocompleteContext.d.ts +17 -0
- package/lib-esm/Autocomplete/AutocompleteContext.js +2 -0
- package/lib-esm/Autocomplete/AutocompleteInput.d.ts +9 -0
- package/lib-esm/Autocomplete/AutocompleteInput.js +132 -0
- package/lib-esm/Autocomplete/AutocompleteMenu.d.ts +71 -0
- package/lib-esm/Autocomplete/AutocompleteMenu.js +204 -0
- package/lib-esm/Autocomplete/AutocompleteOverlay.d.ts +20 -0
- package/lib-esm/Autocomplete/AutocompleteOverlay.js +56 -0
- package/lib-esm/Autocomplete/index.d.ts +2 -0
- package/lib-esm/Autocomplete/index.js +1 -0
- package/lib-esm/FilteredActionList/FilteredActionList.js +3 -31
- package/lib-esm/Overlay.d.ts +2 -1
- package/lib-esm/Overlay.js +8 -5
- package/lib-esm/TextInput.d.ts +4 -12
- package/lib-esm/TextInput.js +4 -37
- package/lib-esm/TextInputWithTokens.d.ts +323 -0
- package/lib-esm/TextInputWithTokens.js +219 -0
- package/lib-esm/Token/AvatarToken.d.ts +7 -0
- package/lib-esm/Token/AvatarToken.js +43 -0
- package/lib-esm/Token/IssueLabelToken.d.ts +14 -0
- package/lib-esm/Token/IssueLabelToken.js +124 -0
- package/lib-esm/Token/Token.d.ts +15 -0
- package/lib-esm/Token/Token.js +73 -0
- package/lib-esm/Token/TokenBase.d.ts +31 -0
- package/lib-esm/Token/TokenBase.js +87 -0
- package/lib-esm/Token/_RemoveTokenButton.d.ts +12 -0
- package/lib-esm/Token/_RemoveTokenButton.js +60 -0
- package/lib-esm/Token/_TokenTextContainer.d.ts +3 -0
- package/lib-esm/Token/_TokenTextContainer.js +6 -0
- package/lib-esm/Token/index.d.ts +3 -0
- package/lib-esm/Token/index.js +3 -0
- package/lib-esm/_TextInputWrapper.d.ts +10 -0
- package/lib-esm/_TextInputWrapper.js +31 -0
- package/lib-esm/_UnstyledTextInput.d.ts +2 -0
- package/lib-esm/_UnstyledTextInput.js +7 -0
- package/lib-esm/hooks/useOpenAndCloseFocus.d.ts +2 -1
- package/lib-esm/hooks/useOpenAndCloseFocus.js +7 -2
- package/lib-esm/hooks/useOverlay.d.ts +2 -1
- package/lib-esm/hooks/useOverlay.js +4 -2
- package/lib-esm/index.d.ts +4 -0
- package/lib-esm/index.js +3 -0
- package/lib-esm/utils/scrollIntoViewingArea.d.ts +1 -0
- package/lib-esm/utils/scrollIntoViewingArea.js +30 -0
- package/lib-esm/utils/types/MandateProps.d.ts +3 -0
- package/lib-esm/utils/types/MandateProps.js +1 -0
- package/lib-esm/utils/types/index.d.ts +1 -0
- package/lib-esm/utils/types/index.js +2 -1
- package/package.json +2 -1
@@ -0,0 +1,124 @@
|
|
1
|
+
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
2
|
+
|
3
|
+
import React, { forwardRef, useMemo } from 'react';
|
4
|
+
import TokenBase, { defaultTokenSize, isTokenInteractive } from './TokenBase';
|
5
|
+
import RemoveTokenButton from './_RemoveTokenButton';
|
6
|
+
import { parseToHsla, parseToRgba } from 'color2k';
|
7
|
+
import { useTheme } from '../ThemeProvider';
|
8
|
+
import TokenTextContainer from './_TokenTextContainer';
|
9
|
+
const tokenBorderWidthPx = 1;
|
10
|
+
const lightModeStyles = {
|
11
|
+
'--lightness-threshold': '0.453',
|
12
|
+
'--border-threshold': '0.96',
|
13
|
+
'--border-alpha': 'max(0, min(calc((var(--perceived-lightness) - var(--border-threshold)) * 100), 1))',
|
14
|
+
background: 'rgb(var(--label-r), var(--label-g), var(--label-b))',
|
15
|
+
color: 'hsl(0, 0%, calc(var(--lightness-switch) * 100%))',
|
16
|
+
borderWidth: tokenBorderWidthPx,
|
17
|
+
borderStyle: 'solid',
|
18
|
+
borderColor: 'hsla(var(--label-h),calc(var(--label-s) * 1%),calc((var(--label-l) - 25) * 1%),var(--border-alpha))'
|
19
|
+
};
|
20
|
+
const darkModeStyles = {
|
21
|
+
'--lightness-threshold': '0.6',
|
22
|
+
'--background-alpha': '0.18',
|
23
|
+
'--border-alpha': '0.3',
|
24
|
+
'--lighten-by': 'calc(((var(--lightness-threshold) - var(--perceived-lightness)) * 100) * var(--lightness-switch))',
|
25
|
+
borderWidth: tokenBorderWidthPx,
|
26
|
+
borderStyle: 'solid',
|
27
|
+
background: 'rgba(var(--label-r), var(--label-g), var(--label-b), var(--background-alpha))',
|
28
|
+
color: 'hsl(var(--label-h), calc(var(--label-s) * 1%), calc((var(--label-l) + var(--lighten-by)) * 1%))',
|
29
|
+
borderColor: 'hsla(var(--label-h), calc(var(--label-s) * 1%),calc((var(--label-l) + var(--lighten-by)) * 1%),var(--border-alpha))'
|
30
|
+
};
|
31
|
+
const IssueLabelToken = /*#__PURE__*/forwardRef((props, forwardedRef) => {
|
32
|
+
const {
|
33
|
+
as,
|
34
|
+
fillColor = '#999',
|
35
|
+
onRemove,
|
36
|
+
id,
|
37
|
+
isSelected,
|
38
|
+
text,
|
39
|
+
size,
|
40
|
+
hideRemoveButton,
|
41
|
+
href,
|
42
|
+
onClick,
|
43
|
+
...rest
|
44
|
+
} = props;
|
45
|
+
const interactiveTokenProps = {
|
46
|
+
as,
|
47
|
+
href,
|
48
|
+
onClick
|
49
|
+
};
|
50
|
+
const {
|
51
|
+
colorScheme
|
52
|
+
} = useTheme();
|
53
|
+
const hasMultipleActionTargets = isTokenInteractive(props) && Boolean(onRemove) && !hideRemoveButton;
|
54
|
+
|
55
|
+
const onRemoveClick = e => {
|
56
|
+
e.stopPropagation();
|
57
|
+
onRemove && onRemove();
|
58
|
+
};
|
59
|
+
|
60
|
+
const labelStyles = useMemo(() => {
|
61
|
+
const [r, g, b] = parseToRgba(fillColor);
|
62
|
+
const [h, s, l] = parseToHsla(fillColor); // label hack taken from https://github.com/github/github/blob/master/app/assets/stylesheets/hacks/hx_primer-labels.scss#L43-L108
|
63
|
+
// this logic should eventually live in primer/components. Also worthy of note is that the dotcom hack code will be moving to primer/css soon.
|
64
|
+
|
65
|
+
return {
|
66
|
+
'--label-r': String(r),
|
67
|
+
'--label-g': String(g),
|
68
|
+
'--label-b': String(b),
|
69
|
+
'--label-h': String(Math.round(h)),
|
70
|
+
'--label-s': String(Math.round(s * 100)),
|
71
|
+
'--label-l': String(Math.round(l * 100)),
|
72
|
+
'--perceived-lightness': 'calc(((var(--label-r) * 0.2126) + (var(--label-g) * 0.7152) + (var(--label-b) * 0.0722)) / 255)',
|
73
|
+
'--lightness-switch': 'max(0, min(calc((var(--perceived-lightness) - var(--lightness-threshold)) * -1000), 1))',
|
74
|
+
paddingRight: hideRemoveButton || !onRemove ? undefined : 0,
|
75
|
+
position: 'relative',
|
76
|
+
...(colorScheme === 'light' ? lightModeStyles : darkModeStyles),
|
77
|
+
...(isSelected ? {
|
78
|
+
background: colorScheme === 'light' ? 'hsl(var(--label-h), calc(var(--label-s) * 1%), calc((var(--label-l) - 5) * 1%))' : darkModeStyles.background,
|
79
|
+
':focus': {
|
80
|
+
outline: 'none'
|
81
|
+
},
|
82
|
+
':after': {
|
83
|
+
content: '""',
|
84
|
+
position: 'absolute',
|
85
|
+
zIndex: 1,
|
86
|
+
top: `-${tokenBorderWidthPx * 2}px`,
|
87
|
+
right: `-${tokenBorderWidthPx * 2}px`,
|
88
|
+
bottom: `-${tokenBorderWidthPx * 2}px`,
|
89
|
+
left: `-${tokenBorderWidthPx * 2}px`,
|
90
|
+
display: 'block',
|
91
|
+
pointerEvents: 'none',
|
92
|
+
boxShadow: `0 0 0 ${tokenBorderWidthPx * 2}px ${colorScheme === 'light' ? 'rgb(var(--label-r), var(--label-g), var(--label-b))' : 'hsl(var(--label-h), calc(var(--label-s) * 1%), calc((var(--label-l) + var(--lighten-by)) * 1%))'}`,
|
93
|
+
borderRadius: '999px'
|
94
|
+
}
|
95
|
+
} : {})
|
96
|
+
};
|
97
|
+
}, [colorScheme, fillColor, isSelected, hideRemoveButton, onRemove]);
|
98
|
+
return /*#__PURE__*/React.createElement(TokenBase, _extends({
|
99
|
+
onRemove: onRemove,
|
100
|
+
id: id === null || id === void 0 ? void 0 : id.toString(),
|
101
|
+
isSelected: isSelected,
|
102
|
+
text: text,
|
103
|
+
size: size,
|
104
|
+
sx: labelStyles
|
105
|
+
}, !hasMultipleActionTargets ? interactiveTokenProps : {}, rest, {
|
106
|
+
ref: forwardedRef
|
107
|
+
}), /*#__PURE__*/React.createElement(TokenTextContainer, hasMultipleActionTargets ? interactiveTokenProps : {}, text), !hideRemoveButton && onRemove ? /*#__PURE__*/React.createElement(RemoveTokenButton, {
|
108
|
+
borderOffset: tokenBorderWidthPx,
|
109
|
+
onClick: onRemoveClick,
|
110
|
+
size: size,
|
111
|
+
"aria-hidden": hasMultipleActionTargets ? 'true' : 'false',
|
112
|
+
isParentInteractive: isTokenInteractive(props),
|
113
|
+
sx: hasMultipleActionTargets ? {
|
114
|
+
position: 'relative',
|
115
|
+
zIndex: '1'
|
116
|
+
} : {}
|
117
|
+
}) : null);
|
118
|
+
});
|
119
|
+
IssueLabelToken.defaultProps = {
|
120
|
+
fillColor: '#999',
|
121
|
+
size: defaultTokenSize
|
122
|
+
};
|
123
|
+
IssueLabelToken.displayName = 'IssueLabelToken';
|
124
|
+
export default IssueLabelToken;
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { SxProp } from '../sx';
|
3
|
+
import { TokenBaseProps } from './TokenBase';
|
4
|
+
export interface TokenProps extends TokenBaseProps {
|
5
|
+
/**
|
6
|
+
* A function that renders a component before the token text
|
7
|
+
*/
|
8
|
+
leadingVisual?: React.ComponentType<any>;
|
9
|
+
/**
|
10
|
+
* Whether the remove button should be rendered in the token
|
11
|
+
*/
|
12
|
+
hideRemoveButton?: boolean;
|
13
|
+
}
|
14
|
+
declare const Token: React.ForwardRefExoticComponent<Pick<TokenProps & SxProp, "sizes" | "color" | "content" | "height" | "translate" | "width" | "hidden" | "children" | "value" | "cite" | "data" | "form" | "label" | "slot" | "span" | "style" | "summary" | "title" | "pattern" | "text" | "list" | "default" | "type" | "name" | "key" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "className" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "id" | "lang" | "placeholder" | "spellCheck" | "tabIndex" | "radioGroup" | "role" | "about" | "datatype" | "inlist" | "prefix" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "start" | "step" | "size" | "wrap" | "open" | "sx" | "max" | "media" | "method" | "min" | "target" | "crossOrigin" | "href" | "classID" | "useMap" | "wmode" | "download" | "hrefLang" | "rel" | "alt" | "coords" | "shape" | "autoPlay" | "controls" | "loop" | "mediaGroup" | "muted" | "playsInline" | "preload" | "src" | "autoFocus" | "disabled" | "formAction" | "formEncType" | "formMethod" | "formNoValidate" | "formTarget" | "dateTime" | "acceptCharset" | "action" | "autoComplete" | "encType" | "noValidate" | "manifest" | "allowFullScreen" | "allowTransparency" | "frameBorder" | "marginHeight" | "marginWidth" | "sandbox" | "scrolling" | "seamless" | "srcDoc" | "srcSet" | "async" | "accept" | "capture" | "checked" | "maxLength" | "minLength" | "multiple" | "readOnly" | "required" | "challenge" | "keyType" | "keyParams" | "htmlFor" | "as" | "integrity" | "charSet" | "httpEquiv" | "high" | "low" | "optimum" | "reversed" | "selected" | "defer" | "nonce" | "scoped" | "cellPadding" | "cellSpacing" | "colSpan" | "headers" | "rowSpan" | "scope" | "cols" | "rows" | "kind" | "srcLang" | "poster" | "leadingVisual" | "onRemove" | "isSelected" | "hideRemoveButton"> & React.RefAttributes<HTMLAnchorElement | HTMLButtonElement | HTMLSpanElement>>;
|
15
|
+
export default Token;
|
@@ -0,0 +1,73 @@
|
|
1
|
+
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
2
|
+
|
3
|
+
import React, { forwardRef } from 'react';
|
4
|
+
import styled, { css } from 'styled-components';
|
5
|
+
import { get } from '../constants';
|
6
|
+
import sx from '../sx';
|
7
|
+
import TokenBase, { defaultTokenSize, isTokenInteractive } from './TokenBase';
|
8
|
+
import RemoveTokenButton from './_RemoveTokenButton';
|
9
|
+
import TokenTextContainer from './_TokenTextContainer';
|
10
|
+
const tokenBorderWidthPx = 1;
|
11
|
+
const DefaultTokenStyled = styled(TokenBase).withConfig({
|
12
|
+
displayName: "Token__DefaultTokenStyled",
|
13
|
+
componentId: "sc-1dg52pw-0"
|
14
|
+
})(["background-color:", ";border-color:", ";border-style:solid;border-width:", "px;color:", ";max-width:100%;padding-right:", ";position:relative;", " ", ""], get('colors.neutral.subtle'), props => props.isSelected ? get('colors.fg.default') : get('colors.border.subtle'), tokenBorderWidthPx, props => props.isSelected ? get('colors.fg.default') : get('colors.fg.muted'), props => !props.hideRemoveButton ? 0 : undefined, sx, props => {
|
15
|
+
if (props.isTokenInteractive) {
|
16
|
+
return css(["&:hover{background-color:", ";box-shadow:", ";color:", ";}"], get('colors.neutral.muted'), get('colors.shadow.medium'), get('colors.fg.default'));
|
17
|
+
}
|
18
|
+
});
|
19
|
+
const LeadingVisualContainer = styled('span').withConfig({
|
20
|
+
displayName: "Token__LeadingVisualContainer",
|
21
|
+
componentId: "sc-1dg52pw-1"
|
22
|
+
})(["flex-shrink:0;line-height:0;"]);
|
23
|
+
const Token = /*#__PURE__*/forwardRef((props, forwardedRef) => {
|
24
|
+
const {
|
25
|
+
as,
|
26
|
+
onRemove,
|
27
|
+
id,
|
28
|
+
leadingVisual: LeadingVisual,
|
29
|
+
text,
|
30
|
+
size,
|
31
|
+
hideRemoveButton,
|
32
|
+
href,
|
33
|
+
onClick,
|
34
|
+
...rest
|
35
|
+
} = props;
|
36
|
+
const hasMultipleActionTargets = isTokenInteractive(props) && Boolean(onRemove) && !hideRemoveButton;
|
37
|
+
|
38
|
+
const onRemoveClick = e => {
|
39
|
+
e.stopPropagation();
|
40
|
+
onRemove && onRemove();
|
41
|
+
};
|
42
|
+
|
43
|
+
const interactiveTokenProps = {
|
44
|
+
as,
|
45
|
+
href,
|
46
|
+
onClick
|
47
|
+
};
|
48
|
+
return /*#__PURE__*/React.createElement(DefaultTokenStyled, _extends({
|
49
|
+
onRemove: onRemove,
|
50
|
+
hideRemoveButton: hideRemoveButton || !onRemove,
|
51
|
+
id: id === null || id === void 0 ? void 0 : id.toString(),
|
52
|
+
text: text,
|
53
|
+
size: size,
|
54
|
+
isTokenInteractive: isTokenInteractive(props)
|
55
|
+
}, !hasMultipleActionTargets ? interactiveTokenProps : {}, rest, {
|
56
|
+
ref: forwardedRef
|
57
|
+
}), LeadingVisual ? /*#__PURE__*/React.createElement(LeadingVisualContainer, null, /*#__PURE__*/React.createElement(LeadingVisual, null)) : null, /*#__PURE__*/React.createElement(TokenTextContainer, hasMultipleActionTargets ? interactiveTokenProps : {}, text), !hideRemoveButton && onRemove ? /*#__PURE__*/React.createElement(RemoveTokenButton, {
|
58
|
+
borderOffset: tokenBorderWidthPx,
|
59
|
+
onClick: onRemoveClick,
|
60
|
+
size: size,
|
61
|
+
isParentInteractive: isTokenInteractive(props),
|
62
|
+
"aria-hidden": hasMultipleActionTargets ? 'true' : 'false',
|
63
|
+
sx: hasMultipleActionTargets ? {
|
64
|
+
position: 'relative',
|
65
|
+
zIndex: '1'
|
66
|
+
} : {}
|
67
|
+
}) : null);
|
68
|
+
});
|
69
|
+
Token.displayName = 'Token';
|
70
|
+
Token.defaultProps = {
|
71
|
+
size: defaultTokenSize
|
72
|
+
};
|
73
|
+
export default Token;
|
@@ -0,0 +1,31 @@
|
|
1
|
+
/// <reference types="react" />
|
2
|
+
import { SxProp } from '../sx';
|
3
|
+
export declare type TokenSizeKeys = 'small' | 'medium' | 'large' | 'extralarge';
|
4
|
+
export declare const tokenSizes: Record<TokenSizeKeys, string>;
|
5
|
+
export declare const defaultTokenSize: TokenSizeKeys;
|
6
|
+
export interface TokenBaseProps extends Omit<React.HTMLProps<HTMLSpanElement | HTMLButtonElement | HTMLAnchorElement>, 'size' | 'id'> {
|
7
|
+
as?: 'button' | 'a' | 'span';
|
8
|
+
/**
|
9
|
+
* The function that gets called when a user clicks the remove button, or keys "Backspace" or "Delete" when focused on the token
|
10
|
+
*/
|
11
|
+
onRemove?: () => void;
|
12
|
+
/**
|
13
|
+
* Whether the token is selected
|
14
|
+
*/
|
15
|
+
isSelected?: boolean;
|
16
|
+
/**
|
17
|
+
* The text label inside the token
|
18
|
+
*/
|
19
|
+
text: string;
|
20
|
+
/**
|
21
|
+
* A unique identifier that can be associated with the token
|
22
|
+
*/
|
23
|
+
id?: number | string;
|
24
|
+
/**
|
25
|
+
* Which size the token will be rendered at
|
26
|
+
*/
|
27
|
+
size?: TokenSizeKeys;
|
28
|
+
}
|
29
|
+
export declare const isTokenInteractive: ({ as, onClick, onFocus, tabIndex }: TokenBaseProps) => boolean;
|
30
|
+
declare const TokenBase: import("styled-components").StyledComponent<"span", any, TokenBaseProps & SxProp, never>;
|
31
|
+
export default TokenBase;
|
@@ -0,0 +1,87 @@
|
|
1
|
+
import styled from 'styled-components';
|
2
|
+
import { variant } from 'styled-system';
|
3
|
+
import { get } from '../constants';
|
4
|
+
import sx from '../sx';
|
5
|
+
export const tokenSizes = {
|
6
|
+
small: '16px',
|
7
|
+
medium: '20px',
|
8
|
+
large: '24px',
|
9
|
+
extralarge: '32px'
|
10
|
+
};
|
11
|
+
export const defaultTokenSize = 'medium';
|
12
|
+
export const isTokenInteractive = ({
|
13
|
+
as = 'span',
|
14
|
+
onClick,
|
15
|
+
onFocus,
|
16
|
+
tabIndex = -1
|
17
|
+
}) => Boolean(onFocus || onClick || tabIndex > -1 || ['a', 'button'].includes(as));
|
18
|
+
const variants = variant({
|
19
|
+
prop: 'size',
|
20
|
+
variants: {
|
21
|
+
small: {
|
22
|
+
fontSize: 0,
|
23
|
+
gap: 1,
|
24
|
+
height: tokenSizes.small,
|
25
|
+
// without setting lineHeight to match height, the "x" appears vertically mis-aligned
|
26
|
+
lineHeight: tokenSizes.small,
|
27
|
+
paddingLeft: 1,
|
28
|
+
paddingRight: 1,
|
29
|
+
// need to explicitly set padding top and bottom to "0" to override default `<button>` element styles
|
30
|
+
// without setting these, the "x" appears vertically mis-aligned
|
31
|
+
paddingTop: 0,
|
32
|
+
paddingBottom: 0
|
33
|
+
},
|
34
|
+
medium: {
|
35
|
+
fontSize: 0,
|
36
|
+
gap: 1,
|
37
|
+
height: tokenSizes.medium,
|
38
|
+
lineHeight: tokenSizes.medium,
|
39
|
+
paddingLeft: 2,
|
40
|
+
paddingRight: 2,
|
41
|
+
paddingTop: 0,
|
42
|
+
paddingBottom: 0
|
43
|
+
},
|
44
|
+
large: {
|
45
|
+
fontSize: 0,
|
46
|
+
gap: 2,
|
47
|
+
height: tokenSizes.large,
|
48
|
+
lineHeight: tokenSizes.large,
|
49
|
+
paddingLeft: 2,
|
50
|
+
paddingRight: 2,
|
51
|
+
paddingTop: 0,
|
52
|
+
paddingBottom: 0
|
53
|
+
},
|
54
|
+
extralarge: {
|
55
|
+
fontSize: 1,
|
56
|
+
gap: 2,
|
57
|
+
height: tokenSizes.extralarge,
|
58
|
+
lineHeight: tokenSizes.extralarge,
|
59
|
+
paddingLeft: 3,
|
60
|
+
paddingRight: 3,
|
61
|
+
paddingTop: 0,
|
62
|
+
paddingBottom: 0
|
63
|
+
}
|
64
|
+
}
|
65
|
+
});
|
66
|
+
const TokenBase = styled.span.attrs(({
|
67
|
+
text,
|
68
|
+
onRemove,
|
69
|
+
onKeyDown
|
70
|
+
}) => ({
|
71
|
+
onKeyDown: event => {
|
72
|
+
onKeyDown && onKeyDown(event);
|
73
|
+
|
74
|
+
if ((event.key === 'Backspace' || event.key === 'Delete') && onRemove) {
|
75
|
+
onRemove();
|
76
|
+
}
|
77
|
+
},
|
78
|
+
'aria-label': onRemove ? `${text}, press backspace or delete to remove` : undefined
|
79
|
+
})).withConfig({
|
80
|
+
displayName: "TokenBase",
|
81
|
+
componentId: "opajvp-0"
|
82
|
+
})(["align-items:center;border-radius:999px;cursor:", ";display:inline-flex;font-weight:", ";text-decoration:none;white-space:nowrap;", " ", ""], props => isTokenInteractive(props) ? 'pointer' : 'auto', get('fontWeights.bold'), variants, sx);
|
83
|
+
TokenBase.defaultProps = {
|
84
|
+
as: 'span',
|
85
|
+
size: defaultTokenSize
|
86
|
+
};
|
87
|
+
export default TokenBase;
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { SxProp } from '../sx';
|
3
|
+
import { ComponentProps } from '../utils/types';
|
4
|
+
import { TokenSizeKeys } from './TokenBase';
|
5
|
+
interface TokenButtonProps {
|
6
|
+
borderOffset?: number;
|
7
|
+
size?: TokenSizeKeys;
|
8
|
+
isParentInteractive?: boolean;
|
9
|
+
}
|
10
|
+
declare const StyledTokenButton: import("styled-components").StyledComponent<"span", any, TokenButtonProps & SxProp, never>;
|
11
|
+
declare const RemoveTokenButton: React.FC<ComponentProps<typeof StyledTokenButton>>;
|
12
|
+
export default RemoveTokenButton;
|
@@ -0,0 +1,60 @@
|
|
1
|
+
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
2
|
+
|
3
|
+
import React from 'react';
|
4
|
+
import { XIcon } from '@primer/octicons-react';
|
5
|
+
import styled from 'styled-components';
|
6
|
+
import { variant } from 'styled-system';
|
7
|
+
import { get } from '../constants';
|
8
|
+
import sx from '../sx';
|
9
|
+
import { tokenSizes, defaultTokenSize } from './TokenBase';
|
10
|
+
const variants = variant({
|
11
|
+
prop: 'size',
|
12
|
+
variants: {
|
13
|
+
small: {
|
14
|
+
height: tokenSizes.small,
|
15
|
+
width: tokenSizes.small
|
16
|
+
},
|
17
|
+
medium: {
|
18
|
+
height: tokenSizes.medium,
|
19
|
+
width: tokenSizes.medium
|
20
|
+
},
|
21
|
+
large: {
|
22
|
+
height: tokenSizes.large,
|
23
|
+
width: tokenSizes.large
|
24
|
+
},
|
25
|
+
extralarge: {
|
26
|
+
height: tokenSizes.extralarge,
|
27
|
+
width: tokenSizes.extralarge
|
28
|
+
}
|
29
|
+
}
|
30
|
+
});
|
31
|
+
|
32
|
+
const getTokenButtonIconSize = size => parseInt(tokenSizes[size || defaultTokenSize], 10) * 0.75;
|
33
|
+
|
34
|
+
const StyledTokenButton = styled.span.withConfig({
|
35
|
+
displayName: "_RemoveTokenButton__StyledTokenButton",
|
36
|
+
componentId: "sc-14lvcw1-0"
|
37
|
+
})(["background-color:transparent;font-family:inherit;color:currentColor;cursor:pointer;display:inline-flex;justify-content:center;align-items:center;user-select:none;appearance:none;text-decoration:none;padding:0;transform:", ";align-self:baseline;border:0;border-radius:999px;&:hover,&:focus{background-color:", ";}&:active{background-color:", ";}", " ", ""], props => `translate(${props.borderOffset}px, -${props.borderOffset}px)`, get('colors.fade.fg10'), get('colors.fade.fg15'), variants, sx);
|
38
|
+
|
39
|
+
const RemoveTokenButton = ({
|
40
|
+
'aria-label': ariaLabel,
|
41
|
+
isParentInteractive,
|
42
|
+
size,
|
43
|
+
...rest
|
44
|
+
}) => {
|
45
|
+
delete rest.children;
|
46
|
+
return /*#__PURE__*/React.createElement(StyledTokenButton, _extends({
|
47
|
+
as: isParentInteractive ? 'span' : 'button',
|
48
|
+
tabIndex: isParentInteractive ? -1 : undefined,
|
49
|
+
"aria-label": !isParentInteractive ? 'Remove token' : ariaLabel,
|
50
|
+
size: size
|
51
|
+
}, rest), /*#__PURE__*/React.createElement(XIcon, {
|
52
|
+
size: getTokenButtonIconSize(size)
|
53
|
+
}));
|
54
|
+
};
|
55
|
+
|
56
|
+
RemoveTokenButton.displayName = "RemoveTokenButton";
|
57
|
+
RemoveTokenButton.defaultProps = {
|
58
|
+
size: defaultTokenSize
|
59
|
+
};
|
60
|
+
export default RemoveTokenButton;
|
@@ -0,0 +1,6 @@
|
|
1
|
+
import styled from 'styled-components';
|
2
|
+
const TokenTextContainer = styled('span').withConfig({
|
3
|
+
displayName: "_TokenTextContainer__TokenTextContainer",
|
4
|
+
componentId: "sc-4t2bev-0"
|
5
|
+
})(["flex-grow:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;background:transparent;border:none;color:inherit;font:inherit;margin:0;overflow:visible;padding:0;width:auto;-webkit-font-smoothing:inherit;-moz-osx-font-smoothing:inherit;-webkit-appearance:none;line-height:1;color:currentColor;text-decoration:none;&:is(a,button,[tabIndex='0']){cursor:pointer;&:after{content:'';position:absolute;left:0;top:0;right:0;bottom:0;}}"]);
|
6
|
+
export default TokenTextContainer;
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import { MaxWidthProps, MinWidthProps, WidthProps } from 'styled-system';
|
2
|
+
import { SxProp } from './sx';
|
3
|
+
declare const TextInputWrapper: import("styled-components").StyledComponent<"span", any, {
|
4
|
+
disabled?: boolean | undefined;
|
5
|
+
hasIcon?: boolean | undefined;
|
6
|
+
block?: boolean | undefined;
|
7
|
+
contrast?: boolean | undefined;
|
8
|
+
variant?: "large" | "small" | undefined;
|
9
|
+
} & WidthProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>, import("csstype").Property.Width<import("styled-system").TLengthStyledSystem>> & MinWidthProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>, import("csstype").Property.MinWidth<import("styled-system").TLengthStyledSystem>> & MaxWidthProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>, import("csstype").Property.MaxWidth<import("styled-system").TLengthStyledSystem>> & SxProp, never>;
|
10
|
+
export default TextInputWrapper;
|
@@ -0,0 +1,31 @@
|
|
1
|
+
import styled, { css } from 'styled-components';
|
2
|
+
import { maxWidth, minWidth, variant, width } from 'styled-system';
|
3
|
+
import { get } from './constants';
|
4
|
+
import sx from './sx';
|
5
|
+
const sizeVariants = variant({
|
6
|
+
variants: {
|
7
|
+
small: {
|
8
|
+
minHeight: '28px',
|
9
|
+
px: 2,
|
10
|
+
py: '3px',
|
11
|
+
fontSize: 0,
|
12
|
+
lineHeight: '20px'
|
13
|
+
},
|
14
|
+
large: {
|
15
|
+
px: 2,
|
16
|
+
py: '10px',
|
17
|
+
fontSize: 3
|
18
|
+
}
|
19
|
+
}
|
20
|
+
});
|
21
|
+
const TextInputWrapper = styled.span.withConfig({
|
22
|
+
displayName: "_TextInputWrapper__TextInputWrapper",
|
23
|
+
componentId: "sc-5vfcis-0"
|
24
|
+
})(["display:inline-flex;align-items:stretch;min-height:34px;font-size:", ";line-height:20px;color:", ";vertical-align:middle;background-repeat:no-repeat;background-position:right 8px center;border:1px solid ", ";border-radius:", ";outline:none;box-shadow:", ";", " .TextInput-icon{align-self:center;color:", ";margin:0 ", ";flex-shrink:0;}&:focus-within{border-color:", ";box-shadow:", ";}", " ", " ", " @media (min-width:", "){font-size:", ";}", " ", " ", " ", " ", ";"], get('fontSizes.1'), get('colors.fg.default'), get('colors.border.default'), get('radii.2'), get('shadows.primer.shadow.inset'), props => {
|
25
|
+
if (props.hasIcon) {
|
26
|
+
return css(["padding:0;"]);
|
27
|
+
} else {
|
28
|
+
return css(["padding:6px 12px;"]);
|
29
|
+
}
|
30
|
+
}, get('colors.fg.muted'), get('space.2'), get('colors.accent.emphasis'), get('shadows.primer.shadow.focus'), props => props.contrast && css(["background-color:", ";"], get('colors.canvas.inset')), props => props.disabled && css(["color:", ";background-color:", ";border-color:", ";"], get('colors.fg.muted'), get('colors.input.disabledBg'), get('colors.border.default')), props => props.block && css(["display:block;width:100%;"]), get('breakpoints.1'), get('fontSizes.1'), width, minWidth, maxWidth, sizeVariants, sx);
|
31
|
+
export default TextInputWrapper;
|
@@ -0,0 +1,7 @@
|
|
1
|
+
import styled from 'styled-components';
|
2
|
+
import sx from './sx';
|
3
|
+
const UnstyledTextInput = styled.input.withConfig({
|
4
|
+
displayName: "_UnstyledTextInput__UnstyledTextInput",
|
5
|
+
componentId: "sc-1jgl33s-0"
|
6
|
+
})(["border:0;font-size:inherit;font-family:inherit;background-color:transparent;-webkit-appearance:none;color:inherit;width:100%;&:focus{outline:0;}", ";"], sx);
|
7
|
+
export default UnstyledTextInput;
|
@@ -3,5 +3,6 @@ export declare type UseOpenAndCloseFocusSettings = {
|
|
3
3
|
initialFocusRef?: React.RefObject<HTMLElement>;
|
4
4
|
containerRef: React.RefObject<HTMLElement>;
|
5
5
|
returnFocusRef: React.RefObject<HTMLElement>;
|
6
|
+
preventFocusOnOpen?: boolean;
|
6
7
|
};
|
7
|
-
export declare function useOpenAndCloseFocus({ initialFocusRef, returnFocusRef, containerRef }: UseOpenAndCloseFocusSettings): void;
|
8
|
+
export declare function useOpenAndCloseFocus({ initialFocusRef, returnFocusRef, containerRef, preventFocusOnOpen }: UseOpenAndCloseFocusSettings): void;
|
@@ -3,9 +3,14 @@ import { iterateFocusableElements } from '../utils/iterateFocusableElements';
|
|
3
3
|
export function useOpenAndCloseFocus({
|
4
4
|
initialFocusRef,
|
5
5
|
returnFocusRef,
|
6
|
-
containerRef
|
6
|
+
containerRef,
|
7
|
+
preventFocusOnOpen
|
7
8
|
}) {
|
8
9
|
useEffect(() => {
|
10
|
+
if (preventFocusOnOpen) {
|
11
|
+
return;
|
12
|
+
}
|
13
|
+
|
9
14
|
const returnRef = returnFocusRef.current;
|
10
15
|
|
11
16
|
if (initialFocusRef && initialFocusRef.current) {
|
@@ -18,5 +23,5 @@ export function useOpenAndCloseFocus({
|
|
18
23
|
return function () {
|
19
24
|
returnRef === null || returnRef === void 0 ? void 0 : returnRef.focus();
|
20
25
|
};
|
21
|
-
}, [initialFocusRef, returnFocusRef, containerRef]);
|
26
|
+
}, [initialFocusRef, returnFocusRef, containerRef, preventFocusOnOpen]);
|
22
27
|
}
|
@@ -7,8 +7,9 @@ export declare type UseOverlaySettings = {
|
|
7
7
|
onEscape: (e: KeyboardEvent) => void;
|
8
8
|
onClickOutside: (e: TouchOrMouseEvent) => void;
|
9
9
|
overlayRef?: React.RefObject<HTMLDivElement>;
|
10
|
+
preventFocusOnOpen?: boolean;
|
10
11
|
};
|
11
12
|
export declare type OverlayReturnProps = {
|
12
13
|
ref: React.RefObject<HTMLDivElement>;
|
13
14
|
};
|
14
|
-
export declare const useOverlay: ({ overlayRef: _overlayRef, returnFocusRef, initialFocusRef, onEscape, ignoreClickRefs, onClickOutside }: UseOverlaySettings) => OverlayReturnProps;
|
15
|
+
export declare const useOverlay: ({ overlayRef: _overlayRef, returnFocusRef, initialFocusRef, onEscape, ignoreClickRefs, onClickOutside, preventFocusOnOpen }: UseOverlaySettings) => OverlayReturnProps;
|
@@ -8,13 +8,15 @@ export const useOverlay = ({
|
|
8
8
|
initialFocusRef,
|
9
9
|
onEscape,
|
10
10
|
ignoreClickRefs,
|
11
|
-
onClickOutside
|
11
|
+
onClickOutside,
|
12
|
+
preventFocusOnOpen
|
12
13
|
}) => {
|
13
14
|
const overlayRef = useProvidedRefOrCreate(_overlayRef);
|
14
15
|
useOpenAndCloseFocus({
|
15
16
|
containerRef: overlayRef,
|
16
17
|
returnFocusRef,
|
17
|
-
initialFocusRef
|
18
|
+
initialFocusRef,
|
19
|
+
preventFocusOnOpen
|
18
20
|
});
|
19
21
|
useOnOutsideClick({
|
20
22
|
containerRef: overlayRef,
|
package/lib-esm/index.d.ts
CHANGED
@@ -24,6 +24,7 @@ export { useConfirm } from './Dialog/ConfirmationDialog';
|
|
24
24
|
export { ActionList } from './ActionList';
|
25
25
|
export { ActionMenu } from './ActionMenu';
|
26
26
|
export type { ActionMenuProps } from './ActionMenu';
|
27
|
+
export { default as Autocomplete } from './Autocomplete';
|
27
28
|
export { default as Avatar } from './Avatar';
|
28
29
|
export type { AvatarProps } from './Avatar';
|
29
30
|
export { default as AvatarPair } from './AvatarPair';
|
@@ -98,10 +99,13 @@ export { default as TabNav } from './TabNav';
|
|
98
99
|
export type { TabNavProps, TabNavLinkProps } from './TabNav';
|
99
100
|
export { default as TextInput } from './TextInput';
|
100
101
|
export type { TextInputProps } from './TextInput';
|
102
|
+
export { default as TextInputWithTokens } from './TextInputWithTokens';
|
103
|
+
export type { TextInputWithTokensProps } from './TextInputWithTokens';
|
101
104
|
export { default as Text } from './Text';
|
102
105
|
export type { TextProps } from './Text';
|
103
106
|
export { default as Timeline } from './Timeline';
|
104
107
|
export type { TimelineProps, TimelineBadgeProps, TimelineBodyProps, TimelineBreakProps, TimelineItemsProps } from './Timeline';
|
108
|
+
export { default as Token, IssueLabelToken, AvatarToken } from './Token';
|
105
109
|
export { default as Tooltip } from './Tooltip';
|
106
110
|
export type { TooltipProps } from './Tooltip';
|
107
111
|
export { default as Truncate } from './Truncate';
|
package/lib-esm/index.js
CHANGED
@@ -19,6 +19,7 @@ export { useConfirm } from './Dialog/ConfirmationDialog'; // Components
|
|
19
19
|
|
20
20
|
export { ActionList } from './ActionList';
|
21
21
|
export { ActionMenu } from './ActionMenu';
|
22
|
+
export { default as Autocomplete } from './Autocomplete';
|
22
23
|
export { default as Avatar } from './Avatar';
|
23
24
|
export { default as AvatarPair } from './AvatarPair';
|
24
25
|
export { default as AvatarStack } from './AvatarStack';
|
@@ -61,8 +62,10 @@ export { default as StyledOcticon } from './StyledOcticon';
|
|
61
62
|
export { default as SubNav } from './SubNav';
|
62
63
|
export { default as TabNav } from './TabNav';
|
63
64
|
export { default as TextInput } from './TextInput';
|
65
|
+
export { default as TextInputWithTokens } from './TextInputWithTokens';
|
64
66
|
export { default as Text } from './Text';
|
65
67
|
export { default as Timeline } from './Timeline';
|
68
|
+
export { default as Token, IssueLabelToken, AvatarToken } from './Token';
|
66
69
|
export { default as Tooltip } from './Tooltip';
|
67
70
|
export { default as Truncate } from './Truncate';
|
68
71
|
export { default as UnderlineNav } from './UnderlineNav';
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare const scrollIntoViewingArea: (child: HTMLElement, container: HTMLElement, direction?: 'horizontal' | 'vertical', startMargin?: number, endMargin?: number, behavior?: ScrollBehavior) => void;
|
@@ -0,0 +1,30 @@
|
|
1
|
+
export const scrollIntoViewingArea = (child, container, direction = 'vertical', startMargin = 8, endMargin = 0, behavior = 'smooth') => {
|
2
|
+
const startSide = direction === 'vertical' ? 'top' : 'left';
|
3
|
+
const endSide = direction === 'vertical' ? 'bottom' : 'right';
|
4
|
+
const scrollSide = direction === 'vertical' ? 'scrollTop' : 'scrollLeft';
|
5
|
+
const {
|
6
|
+
[startSide]: childStart,
|
7
|
+
[endSide]: childEnd
|
8
|
+
} = child.getBoundingClientRect();
|
9
|
+
const {
|
10
|
+
[startSide]: containerStart,
|
11
|
+
[endSide]: containerEnd
|
12
|
+
} = container.getBoundingClientRect();
|
13
|
+
const isChildStartAboveViewingArea = childStart < containerStart + endMargin;
|
14
|
+
const isChildBottomBelowViewingArea = childEnd > containerEnd - startMargin;
|
15
|
+
|
16
|
+
if (isChildStartAboveViewingArea) {
|
17
|
+
const scrollHeightToChildStart = childStart - containerStart + container[scrollSide];
|
18
|
+
container.scrollTo({
|
19
|
+
behavior,
|
20
|
+
[startSide]: scrollHeightToChildStart - endMargin
|
21
|
+
});
|
22
|
+
} else if (isChildBottomBelowViewingArea) {
|
23
|
+
const scrollHeightToChildBottom = childEnd - containerEnd + container[scrollSide];
|
24
|
+
container.scrollTo({
|
25
|
+
behavior,
|
26
|
+
[startSide]: scrollHeightToChildBottom + startMargin
|
27
|
+
});
|
28
|
+
} // either completely in view or outside viewing area on both ends, don't scroll
|
29
|
+
|
30
|
+
};
|