etudes 0.44.0 → 0.45.0
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/lib/Dropdown.d.ts +5 -5
- package/lib/Dropdown.js.map +1 -1
- package/lib/ExtractChildren.d.ts +2 -0
- package/lib/ExtractChildren.js +56 -0
- package/lib/ExtractChildren.js.map +1 -0
- package/lib/Slider.d.ts +9 -5
- package/lib/Slider.js +33 -11
- package/lib/Slider.js.map +1 -1
- package/lib/StepwiseSlider.d.ts +5 -1
- package/lib/StepwiseSlider.js +34 -12
- package/lib/StepwiseSlider.js.map +1 -1
- package/lib/WithTooltip.d.ts +40 -0
- package/lib/WithTooltip.js +179 -0
- package/lib/WithTooltip.js.map +1 -0
- package/package.json +23 -23
package/lib/Dropdown.d.ts
CHANGED
|
@@ -11,15 +11,15 @@ export declare type ButtonCSSProps = Readonly<{
|
|
|
11
11
|
/**
|
|
12
12
|
* Type constraint of the data passed to each item in the component.
|
|
13
13
|
*/
|
|
14
|
-
export declare type DataProps<T = Record<string,
|
|
14
|
+
export declare type DataProps<T = Record<string, any>> = T & {
|
|
15
15
|
label?: string;
|
|
16
16
|
};
|
|
17
17
|
/**
|
|
18
18
|
* Interface defining the props of the item component type to be provided to the
|
|
19
19
|
* component. The data type is generic.
|
|
20
20
|
*/
|
|
21
|
-
export declare type ItemComponentProps<T = Record<string,
|
|
22
|
-
export
|
|
21
|
+
export declare type ItemComponentProps<T = Record<string, any>> = ListItemComponentProps<DataProps<T>>;
|
|
22
|
+
export declare type Props<T = Record<string, any>> = {
|
|
23
23
|
/**
|
|
24
24
|
* Class attribute to the root element.
|
|
25
25
|
*/
|
|
@@ -98,7 +98,7 @@ export interface Props<T = Record<string, never>> {
|
|
|
98
98
|
* Additional CSS to be provided to the dropdown button.
|
|
99
99
|
*/
|
|
100
100
|
buttonCSS?: ExtendedCSSFunction<ButtonCSSProps>;
|
|
101
|
-
}
|
|
101
|
+
};
|
|
102
102
|
export interface State {
|
|
103
103
|
/**
|
|
104
104
|
* Index of the currently selected item. Any value less than 0 indicates that
|
|
@@ -115,7 +115,7 @@ export interface State {
|
|
|
115
115
|
* supports both horizontal and vertical orientations. Provide data and item
|
|
116
116
|
* component type to this component to automatically generate menu items.
|
|
117
117
|
*/
|
|
118
|
-
export default class Dropdown<T = Record<string,
|
|
118
|
+
export default class Dropdown<T = Record<string, any>> extends PureComponent<Props<T>, State> {
|
|
119
119
|
nodeRefs: {
|
|
120
120
|
root: React.RefObject<HTMLDivElement>;
|
|
121
121
|
};
|
package/lib/Dropdown.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dropdown.js","sourceRoot":"/","sources":["Dropdown.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { ComponentType, createRef, PureComponent } from 'react'\nimport { Rect } from 'spase'\nimport styled, { css, CSSProperties } from 'styled-components'\nimport List, { ItemComponentProps as ListItemComponentProps } from './List'\nimport { ExtendedCSSFunction, ExtendedCSSProps, Orientation } from './types'\n\nexport type ButtonCSSProps = Readonly<{\n borderColor: string\n borderThickness: number\n isActive: boolean\n}>\n\n/**\n * Type constraint of the data passed to each item in the component.\n */\nexport type DataProps<T = Record<string, never>> = T & {\n label?: string\n}\n\n/**\n * Interface defining the props of the item component type to be provided to the\n * component. The data type is generic.\n */\nexport type ItemComponentProps<T = Record<string, never>> = ListItemComponentProps<DataProps<T>>\n\nexport interface Props<T = Record<string, never>> {\n /**\n * Class attribute to the root element.\n */\n className?: string\n\n /**\n * Inline style attribute to the element.\n */\n style?: CSSProperties\n\n /**\n * Data of every item in the component. This is used to generate individual\n * menu items. Data type is generic.\n */\n data: DataProps<T>[]\n\n /**\n * Indicates if the component is inverted (i.e. \"dropup\" instead of dropdown).\n * Supports all orientations.\n */\n isInverted?: boolean\n\n /**\n * Indicates if items can be toggled, i.e. they can be deselected if selected\n * again.\n */\n isTogglable?: boolean\n\n /**\n * Thickness of the border (in pixels) of every item and the dropdown button\n * itself. 0 indicates no borders.\n */\n borderThickness?: number\n\n /**\n * The index of the default selected item.\n */\n defaultSelectedItemIndex?: number\n\n /**\n * Length (in pixels) of each item. This does not apply to the dropdown button\n * itself. Length refers to the height in vertical orientation and width in\n * horizontal orientation.\n */\n itemLength?: number\n\n /**\n * Padding (in pixels) of each item.\n */\n itemPadding?: number\n\n /**\n * Maximum number of items that are viside when the component expands. When a\n * value greater than or equal to 0 is specified, only that number of items\n * will be visible at a time, and a scrollbar will appear to scroll to\n * remaining items. Any value less than 0 indicates that all items will be\n * visible when the component expands.\n */\n maxVisibleItems?: number\n\n /**\n * Orientation of the component.\n */\n orientation?: Orientation\n\n /**\n * Color of the border of every item and the dropdown button itself.\n */\n borderColor?: string\n\n /**\n * The label to appear on the dropdown button when no items are selected.\n */\n defaultLabel?: string\n\n /**\n * SVG markup to be put in the dropdown button as the expand icon.\n */\n expandIconSvg?: string\n\n /**\n * React component type to be used for generating items inside the component.\n */\n itemComponentType: ComponentType<ItemComponentProps<T>>\n\n /**\n * Handler invoked whenever the selected index changes.\n */\n onIndexChange?: (index: number) => void\n\n /**\n * Additional CSS to be provided to the dropdown button.\n */\n buttonCSS?: ExtendedCSSFunction<ButtonCSSProps>\n}\n\nexport interface State {\n /**\n * Index of the currently selected item. Any value less than 0 indicates that\n * no item is selected.\n */\n selectedItemIndex: number\n\n /**\n * Indicates if the dropdown menu is collapsed.\n */\n isCollapsed: boolean\n}\n\n/**\n * A dropdown menu component that is invertible (i.e. can \"dropup\" instead) and\n * supports both horizontal and vertical orientations. Provide data and item\n * component type to this component to automatically generate menu items.\n */\nexport default class Dropdown<T = Record<string, never>> extends PureComponent<Props<T>, State> {\n nodeRefs = {\n root: createRef<HTMLDivElement>(),\n }\n\n constructor(props: Props<T>) {\n super(props)\n\n this.state = {\n selectedItemIndex: this.props.defaultSelectedItemIndex ?? -1,\n isCollapsed: true,\n }\n }\n\n get rect(): Rect {\n return Rect.from(this.nodeRefs.root.current) ?? new Rect()\n }\n\n componentDidMount() {\n window.addEventListener('click', this.onClickOutside)\n this.props.onIndexChange?.(this.state.selectedItemIndex)\n }\n\n componentWillUnmount() {\n window.removeEventListener('click', this.onClickOutside)\n }\n\n componentDidUpdate(prevProps: Props<T>, prevState: State) {\n if (prevState.selectedItemIndex !== this.state.selectedItemIndex) {\n this.props.onIndexChange?.(this.state.selectedItemIndex)\n }\n\n if (prevProps.orientation !== this.props.orientation) {\n this.forceUpdate()\n }\n }\n\n render() {\n const borderColor = this.props.borderColor ?? '#000'\n const borderThickness = this.props.borderThickness ?? 1\n const orientation = this.props.orientation ?? 'vertical'\n const itemLength = this.props.itemLength ?? (orientation === 'vertical' ? this.rect.height : this.rect.width)\n const maxVisibleItems = this.props.maxVisibleItems ?? -1\n const isTogglable = this.props.isTogglable ?? true\n const itemPadding = this.props.itemPadding ?? 0\n const numItems = this.props.data.length\n const numVisibleItems = maxVisibleItems < 0 ? numItems : Math.min(numItems, maxVisibleItems)\n const menuLength = (itemLength - borderThickness) * numVisibleItems + itemPadding * (numVisibleItems - 1) + borderThickness\n\n return (\n <StyledRoot\n className={this.props.className}\n orientation={orientation}\n isInverted={this.props.isInverted ?? false}\n ref={this.nodeRefs.root}\n style={this.props.style ?? {}}\n >\n <StyledToggle\n borderColor={borderColor}\n borderThickness={borderThickness}\n extendedCSS={this.props.buttonCSS ?? (() => css``)}\n isActive={!this.state.isCollapsed}\n onClick={() => this.toggle()}\n >\n <label>\n {this.state.selectedItemIndex === -1 ? (this.props.defaultLabel ?? 'Select') : this.props.data[this.state.selectedItemIndex].label}\n </label>\n {this.props.expandIconSvg && <span dangerouslySetInnerHTML={{ __html: this.props.expandIconSvg }}/>}\n </StyledToggle>\n <StyledItemList\n borderColor={borderColor}\n borderThickness={borderThickness}\n data={this.props.data}\n defaultSelectedIndex={this.props.defaultSelectedItemIndex ?? -1}\n isInverted={this.props.isInverted ?? false}\n isTogglable={isTogglable}\n itemComponentType={this.props.itemComponentType as any} // HACK: Generic types cannot be inferred by props, so this is the only way.\n itemPadding={itemPadding}\n onDeselectAt={idx => this.selectItemAt(-1)}\n onSelectAt={idx => this.selectItemAt(idx)}\n orientation={orientation}\n shouldStaySelected={true}\n itemStyle={orientation === 'vertical' ? {\n height: `${itemLength}px`,\n } : {\n width: `${itemLength}px`,\n }}\n style={orientation === 'vertical' ? {\n height: this.state.isCollapsed ? '0px' : `${menuLength}px`,\n overflowY: (maxVisibleItems === -1) ? 'hidden' : (maxVisibleItems < numItems ? 'scroll' : 'hidden'),\n } : {\n width: this.state.isCollapsed ? '0px' : `${menuLength}px`,\n overflowX: (maxVisibleItems === -1) ? 'hidden' : (maxVisibleItems < numItems ? 'scroll' : 'hidden'),\n }}\n />\n </StyledRoot>\n )\n }\n\n /**\n * Indicates if the item at the specified index is selected.\n *\n * @param index - The index of the item.\n *\n * @returns `true` if the item at the specified index is selected, `false`\n * otherwise.\n */\n isItemSelectedAt(index: number) {\n return (this.state.selectedItemIndex === index)\n }\n\n /**\n * Selects the item at the specified index.\n *\n * @param index - The index of the item to select.\n */\n selectItemAt(index: number) {\n this.setState({\n selectedItemIndex: index,\n isCollapsed: true,\n })\n }\n\n /**\n * Expands the menu, revealing its items.\n */\n expand() {\n if (!this.state.isCollapsed) return\n this.setState({ isCollapsed: false })\n }\n\n /**\n * Collapses the menu, concealing its items.\n */\n collapse() {\n if (this.state.isCollapsed) return\n this.setState({ isCollapsed: true })\n }\n\n /**\n * Toggles the visibility of the menu.\n */\n toggle() {\n if (this.state.isCollapsed) {\n this.expand()\n }\n else {\n this.collapse()\n }\n }\n\n /**\n * Handler invoked when click input is detected outside of the root element\n * of the component.\n *\n * @param event - The MouseEvent passed to the handler.\n */\n private onClickOutside = (event: MouseEvent) => {\n if (this.state.isCollapsed) return\n if (!(event.target instanceof Node)) return\n\n let isOutside = true\n let node = event.target\n\n while (node) {\n if (node === this.nodeRefs.root.current) {\n isOutside = false\n break\n }\n\n if (!node.parentNode) break\n\n node = node.parentNode\n }\n\n if (!isOutside) return\n\n this.collapse()\n }\n}\n\nconst StyledItemList = styled(List)<{\n isInverted: boolean\n itemPadding: number\n borderThickness: number\n orientation: Orientation\n}>`\n position: absolute;\n\n ::-webkit-scrollbar {}\n ::-webkit-scrollbar-track {}\n ::-webkit-scrollbar-thumb {}\n ::-webkit-scrollbar-hover {}\n\n ${props => props.orientation === 'vertical' ? css`\n transition: height 100ms ease-out;\n will-change: height;\n\n ${props.isInverted ? css`\n margin-bottom: ${props.itemPadding - props.borderThickness}px;\n bottom: 100%;\n ` : css`\n top: 100%;\n margin-top: ${props.itemPadding - props.borderThickness}px;\n `}\n ` : css`\n transition: width 100ms ease-out;\n will-change: width;\n\n ${props.isInverted ? css`\n margin-right: ${props.itemPadding - props.borderThickness}px;\n right: 100%;\n ` : css`\n left: 100%;\n margin-left: ${props.itemPadding - props.borderThickness}px;\n `}\n `}\n`\n\nconst StyledToggle = styled.button<ButtonCSSProps & ExtendedCSSProps<ButtonCSSProps>>`\n > span {\n height: 15px;\n width: 15px;\n }\n\n > label {\n font-family: inherit;\n font-size: inherit;\n font-weight: inherit;\n letter-spacing: inherit;\n line-height: inherit;\n }\n\n ${props => props.extendedCSS(props)}\n\n align-items: center;\n background: #fff;\n box-sizing: border-box;\n color: #000;\n display: flex;\n flex-direction: row;\n height: 100%;\n justify-content: space-between;\n left: 0;\n margin: 0;\n outline: none;\n padding: 0 10px;\n position: absolute;\n top: 0;\n width: 100%;\n z-index: 1;\n\n ${props => props.borderThickness > 0 && css`\n border: ${props.borderThickness}px solid ${props.borderColor};\n `}\n\n > span {\n box-sizing: border-box;\n display: block;\n transform-origin: center;\n\n svg {\n height: 100%;\n width: auto;\n }\n }\n`\n\nconst StyledRoot = styled.div<{\n isInverted: boolean\n orientation: Orientation\n}>`\n align-items: center;\n box-sizing: border-box;\n display: flex;\n justify-content: flex-start;\n padding: 0;\n overflow: visible;\n position: relative;\n\n ${props => props.orientation === 'vertical' ? css`\n flex-direction: ${props.isInverted ? 'column-reverse' : 'column'};\n height: 50px;\n width: 200px;\n ` : css`\n flex-direction: ${props.isInverted ? 'row-reverse' : 'row'};\n height: 200px;\n width: 50px;\n `}\n`\n"]}
|
|
1
|
+
{"version":3,"file":"Dropdown.js","sourceRoot":"/","sources":["Dropdown.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { ComponentType, createRef, PureComponent } from 'react'\nimport { Rect } from 'spase'\nimport styled, { css, CSSProperties } from 'styled-components'\nimport List, { ItemComponentProps as ListItemComponentProps } from './List'\nimport { ExtendedCSSFunction, ExtendedCSSProps, Orientation } from './types'\n\nexport type ButtonCSSProps = Readonly<{\n borderColor: string\n borderThickness: number\n isActive: boolean\n}>\n\n/**\n * Type constraint of the data passed to each item in the component.\n */\nexport type DataProps<T = Record<string, any>> = T & {\n label?: string\n}\n\n/**\n * Interface defining the props of the item component type to be provided to the\n * component. The data type is generic.\n */\nexport type ItemComponentProps<T = Record<string, any>> = ListItemComponentProps<DataProps<T>>\n\nexport type Props<T = Record<string, any>> = {\n /**\n * Class attribute to the root element.\n */\n className?: string\n\n /**\n * Inline style attribute to the element.\n */\n style?: CSSProperties\n\n /**\n * Data of every item in the component. This is used to generate individual\n * menu items. Data type is generic.\n */\n data: DataProps<T>[]\n\n /**\n * Indicates if the component is inverted (i.e. \"dropup\" instead of dropdown).\n * Supports all orientations.\n */\n isInverted?: boolean\n\n /**\n * Indicates if items can be toggled, i.e. they can be deselected if selected\n * again.\n */\n isTogglable?: boolean\n\n /**\n * Thickness of the border (in pixels) of every item and the dropdown button\n * itself. 0 indicates no borders.\n */\n borderThickness?: number\n\n /**\n * The index of the default selected item.\n */\n defaultSelectedItemIndex?: number\n\n /**\n * Length (in pixels) of each item. This does not apply to the dropdown button\n * itself. Length refers to the height in vertical orientation and width in\n * horizontal orientation.\n */\n itemLength?: number\n\n /**\n * Padding (in pixels) of each item.\n */\n itemPadding?: number\n\n /**\n * Maximum number of items that are viside when the component expands. When a\n * value greater than or equal to 0 is specified, only that number of items\n * will be visible at a time, and a scrollbar will appear to scroll to\n * remaining items. Any value less than 0 indicates that all items will be\n * visible when the component expands.\n */\n maxVisibleItems?: number\n\n /**\n * Orientation of the component.\n */\n orientation?: Orientation\n\n /**\n * Color of the border of every item and the dropdown button itself.\n */\n borderColor?: string\n\n /**\n * The label to appear on the dropdown button when no items are selected.\n */\n defaultLabel?: string\n\n /**\n * SVG markup to be put in the dropdown button as the expand icon.\n */\n expandIconSvg?: string\n\n /**\n * React component type to be used for generating items inside the component.\n */\n itemComponentType: ComponentType<ItemComponentProps<T>>\n\n /**\n * Handler invoked whenever the selected index changes.\n */\n onIndexChange?: (index: number) => void\n\n /**\n * Additional CSS to be provided to the dropdown button.\n */\n buttonCSS?: ExtendedCSSFunction<ButtonCSSProps>\n}\n\nexport interface State {\n /**\n * Index of the currently selected item. Any value less than 0 indicates that\n * no item is selected.\n */\n selectedItemIndex: number\n\n /**\n * Indicates if the dropdown menu is collapsed.\n */\n isCollapsed: boolean\n}\n\n/**\n * A dropdown menu component that is invertible (i.e. can \"dropup\" instead) and\n * supports both horizontal and vertical orientations. Provide data and item\n * component type to this component to automatically generate menu items.\n */\nexport default class Dropdown<T = Record<string, any>> extends PureComponent<Props<T>, State> {\n nodeRefs = {\n root: createRef<HTMLDivElement>(),\n }\n\n constructor(props: Props<T>) {\n super(props)\n\n this.state = {\n selectedItemIndex: this.props.defaultSelectedItemIndex ?? -1,\n isCollapsed: true,\n }\n }\n\n get rect(): Rect {\n return Rect.from(this.nodeRefs.root.current) ?? new Rect()\n }\n\n componentDidMount() {\n window.addEventListener('click', this.onClickOutside)\n this.props.onIndexChange?.(this.state.selectedItemIndex)\n }\n\n componentWillUnmount() {\n window.removeEventListener('click', this.onClickOutside)\n }\n\n componentDidUpdate(prevProps: Props<T>, prevState: State) {\n if (prevState.selectedItemIndex !== this.state.selectedItemIndex) {\n this.props.onIndexChange?.(this.state.selectedItemIndex)\n }\n\n if (prevProps.orientation !== this.props.orientation) {\n this.forceUpdate()\n }\n }\n\n render() {\n const borderColor = this.props.borderColor ?? '#000'\n const borderThickness = this.props.borderThickness ?? 1\n const orientation = this.props.orientation ?? 'vertical'\n const itemLength = this.props.itemLength ?? (orientation === 'vertical' ? this.rect.height : this.rect.width)\n const maxVisibleItems = this.props.maxVisibleItems ?? -1\n const isTogglable = this.props.isTogglable ?? true\n const itemPadding = this.props.itemPadding ?? 0\n const numItems = this.props.data.length\n const numVisibleItems = maxVisibleItems < 0 ? numItems : Math.min(numItems, maxVisibleItems)\n const menuLength = (itemLength - borderThickness) * numVisibleItems + itemPadding * (numVisibleItems - 1) + borderThickness\n\n return (\n <StyledRoot\n className={this.props.className}\n orientation={orientation}\n isInverted={this.props.isInverted ?? false}\n ref={this.nodeRefs.root}\n style={this.props.style ?? {}}\n >\n <StyledToggle\n borderColor={borderColor}\n borderThickness={borderThickness}\n extendedCSS={this.props.buttonCSS ?? (() => css``)}\n isActive={!this.state.isCollapsed}\n onClick={() => this.toggle()}\n >\n <label>\n {this.state.selectedItemIndex === -1 ? (this.props.defaultLabel ?? 'Select') : this.props.data[this.state.selectedItemIndex].label}\n </label>\n {this.props.expandIconSvg && <span dangerouslySetInnerHTML={{ __html: this.props.expandIconSvg }}/>}\n </StyledToggle>\n <StyledItemList\n borderColor={borderColor}\n borderThickness={borderThickness}\n data={this.props.data}\n defaultSelectedIndex={this.props.defaultSelectedItemIndex ?? -1}\n isInverted={this.props.isInverted ?? false}\n isTogglable={isTogglable}\n itemComponentType={this.props.itemComponentType as any} // HACK: Generic types cannot be inferred by props, so this is the only way.\n itemPadding={itemPadding}\n onDeselectAt={idx => this.selectItemAt(-1)}\n onSelectAt={idx => this.selectItemAt(idx)}\n orientation={orientation}\n shouldStaySelected={true}\n itemStyle={orientation === 'vertical' ? {\n height: `${itemLength}px`,\n } : {\n width: `${itemLength}px`,\n }}\n style={orientation === 'vertical' ? {\n height: this.state.isCollapsed ? '0px' : `${menuLength}px`,\n overflowY: (maxVisibleItems === -1) ? 'hidden' : (maxVisibleItems < numItems ? 'scroll' : 'hidden'),\n } : {\n width: this.state.isCollapsed ? '0px' : `${menuLength}px`,\n overflowX: (maxVisibleItems === -1) ? 'hidden' : (maxVisibleItems < numItems ? 'scroll' : 'hidden'),\n }}\n />\n </StyledRoot>\n )\n }\n\n /**\n * Indicates if the item at the specified index is selected.\n *\n * @param index - The index of the item.\n *\n * @returns `true` if the item at the specified index is selected, `false`\n * otherwise.\n */\n isItemSelectedAt(index: number) {\n return (this.state.selectedItemIndex === index)\n }\n\n /**\n * Selects the item at the specified index.\n *\n * @param index - The index of the item to select.\n */\n selectItemAt(index: number) {\n this.setState({\n selectedItemIndex: index,\n isCollapsed: true,\n })\n }\n\n /**\n * Expands the menu, revealing its items.\n */\n expand() {\n if (!this.state.isCollapsed) return\n this.setState({ isCollapsed: false })\n }\n\n /**\n * Collapses the menu, concealing its items.\n */\n collapse() {\n if (this.state.isCollapsed) return\n this.setState({ isCollapsed: true })\n }\n\n /**\n * Toggles the visibility of the menu.\n */\n toggle() {\n if (this.state.isCollapsed) {\n this.expand()\n }\n else {\n this.collapse()\n }\n }\n\n /**\n * Handler invoked when click input is detected outside of the root element\n * of the component.\n *\n * @param event - The MouseEvent passed to the handler.\n */\n private onClickOutside = (event: MouseEvent) => {\n if (this.state.isCollapsed) return\n if (!(event.target instanceof Node)) return\n\n let isOutside = true\n let node = event.target\n\n while (node) {\n if (node === this.nodeRefs.root.current) {\n isOutside = false\n break\n }\n\n if (!node.parentNode) break\n\n node = node.parentNode\n }\n\n if (!isOutside) return\n\n this.collapse()\n }\n}\n\nconst StyledItemList = styled(List)<{\n isInverted: boolean\n itemPadding: number\n borderThickness: number\n orientation: Orientation\n}>`\n position: absolute;\n\n ::-webkit-scrollbar {}\n ::-webkit-scrollbar-track {}\n ::-webkit-scrollbar-thumb {}\n ::-webkit-scrollbar-hover {}\n\n ${props => props.orientation === 'vertical' ? css`\n transition: height 100ms ease-out;\n will-change: height;\n\n ${props.isInverted ? css`\n margin-bottom: ${props.itemPadding - props.borderThickness}px;\n bottom: 100%;\n ` : css`\n top: 100%;\n margin-top: ${props.itemPadding - props.borderThickness}px;\n `}\n ` : css`\n transition: width 100ms ease-out;\n will-change: width;\n\n ${props.isInverted ? css`\n margin-right: ${props.itemPadding - props.borderThickness}px;\n right: 100%;\n ` : css`\n left: 100%;\n margin-left: ${props.itemPadding - props.borderThickness}px;\n `}\n `}\n`\n\nconst StyledToggle = styled.button<ButtonCSSProps & ExtendedCSSProps<ButtonCSSProps>>`\n > span {\n height: 15px;\n width: 15px;\n }\n\n > label {\n font-family: inherit;\n font-size: inherit;\n font-weight: inherit;\n letter-spacing: inherit;\n line-height: inherit;\n }\n\n ${props => props.extendedCSS(props)}\n\n align-items: center;\n background: #fff;\n box-sizing: border-box;\n color: #000;\n display: flex;\n flex-direction: row;\n height: 100%;\n justify-content: space-between;\n left: 0;\n margin: 0;\n outline: none;\n padding: 0 10px;\n position: absolute;\n top: 0;\n width: 100%;\n z-index: 1;\n\n ${props => props.borderThickness > 0 && css`\n border: ${props.borderThickness}px solid ${props.borderColor};\n `}\n\n > span {\n box-sizing: border-box;\n display: block;\n transform-origin: center;\n\n svg {\n height: 100%;\n width: auto;\n }\n }\n`\n\nconst StyledRoot = styled.div<{\n isInverted: boolean\n orientation: Orientation\n}>`\n align-items: center;\n box-sizing: border-box;\n display: flex;\n justify-content: flex-start;\n padding: 0;\n overflow: visible;\n position: relative;\n\n ${props => props.orientation === 'vertical' ? css`\n flex-direction: ${props.isInverted ? 'column-reverse' : 'column'};\n height: 50px;\n width: 200px;\n ` : css`\n flex-direction: ${props.isInverted ? 'row-reverse' : 'row'};\n height: 200px;\n width: 50px;\n `}\n`\n"]}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
26
|
+
if (mod && mod.__esModule) return mod;
|
|
27
|
+
var result = {};
|
|
28
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
29
|
+
__setModuleDefault(result, mod);
|
|
30
|
+
return result;
|
|
31
|
+
};
|
|
32
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
33
|
+
var t = {};
|
|
34
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
35
|
+
t[p] = s[p];
|
|
36
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
37
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
38
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
39
|
+
t[p[i]] = s[p[i]];
|
|
40
|
+
}
|
|
41
|
+
return t;
|
|
42
|
+
};
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
var react_1 = __importStar(require("react"));
|
|
45
|
+
function ExtractChildren(_a) {
|
|
46
|
+
var children = _a.children, props = __rest(_a, ["children"]);
|
|
47
|
+
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
48
|
+
react_1.Children.map(children, function (child) {
|
|
49
|
+
if ((0, react_1.isValidElement)(child))
|
|
50
|
+
return (0, react_1.cloneElement)(child, __assign({}, props));
|
|
51
|
+
return child;
|
|
52
|
+
}),
|
|
53
|
+
")"));
|
|
54
|
+
}
|
|
55
|
+
exports.default = ExtractChildren;
|
|
56
|
+
//# sourceMappingURL=ExtractChildren.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExtractChildren.js","sourceRoot":"/","sources":["ExtractChildren.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6CAAwG;AAExG,SAAwB,eAAe,CAAC,EAAsE;IAApE,IAAA,QAAQ,cAAA,EAAK,KAAK,cAApB,YAAsB,CAAF;IAC1D,OAAO,CACL;QACG,gBAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,UAAA,KAAK;YAC3B,IAAI,IAAA,sBAAc,EAAC,KAAK,CAAC;gBAAE,OAAO,IAAA,oBAAY,EAAC,KAAK,eAAO,KAAK,EAAG,CAAA;YACnE,OAAO,KAAK,CAAA;QACd,CAAC,CAAC;YACD,CACJ,CAAA;AACH,CAAC;AATD,kCASC","sourcesContent":["import React, { Children, cloneElement, HTMLAttributes, isValidElement, PropsWithChildren } from 'react'\n\nexport default function ExtractChildren({ children, ...props }: PropsWithChildren<HTMLAttributes<HTMLElement>>) {\n return (\n <>\n {Children.map(children, child => {\n if (isValidElement(child)) return cloneElement(child, { ...props })\n return child\n })})\n </>\n )\n}\n"]}
|
package/lib/Slider.d.ts
CHANGED
|
@@ -7,6 +7,10 @@ export declare type Props = HTMLAttributes<HTMLDivElement> & {
|
|
|
7
7
|
* being the start.
|
|
8
8
|
*/
|
|
9
9
|
isInverted?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Specifies if the track is clickable to set the position of the knob.
|
|
12
|
+
*/
|
|
13
|
+
isTrackInteractive?: boolean;
|
|
10
14
|
/**
|
|
11
15
|
* Indicates if position change events are dispatched only when dragging ends. When disabled,
|
|
12
16
|
* aforementioned events are fired repeatedly while dragging.
|
|
@@ -61,19 +65,19 @@ export declare type Props = HTMLAttributes<HTMLDivElement> & {
|
|
|
61
65
|
/**
|
|
62
66
|
* Custom CSS provided to the track before the knob.
|
|
63
67
|
*/
|
|
64
|
-
cssStartingTrack?: CSSProp
|
|
68
|
+
cssStartingTrack?: CSSProp;
|
|
65
69
|
/**
|
|
66
70
|
* Custom CSS provided to the track after the knob.
|
|
67
71
|
*/
|
|
68
|
-
cssEndingTrack?: CSSProp
|
|
72
|
+
cssEndingTrack?: CSSProp;
|
|
69
73
|
/**
|
|
70
74
|
* Custom CSS provided to the knob.
|
|
71
75
|
*/
|
|
72
|
-
cssKnob?: CSSProp
|
|
76
|
+
cssKnob?: CSSProp;
|
|
73
77
|
/**
|
|
74
78
|
* Custom CSS provided to the label inside the knob.
|
|
75
79
|
*/
|
|
76
|
-
cssLabel?: CSSProp
|
|
80
|
+
cssLabel?: CSSProp;
|
|
77
81
|
};
|
|
78
82
|
/**
|
|
79
83
|
* A slider component supporting both horizontal and vertical orientations whose sliding position (a
|
|
@@ -83,4 +87,4 @@ export declare type Props = HTMLAttributes<HTMLDivElement> & {
|
|
|
83
87
|
* rules, the width and height of the knob are set via props (`knobWidth` and `knobHeight`,
|
|
84
88
|
* respectively). The size of the knob does not impact the size of the slider.
|
|
85
89
|
*/
|
|
86
|
-
export default function Slider({ isInverted, onlyDispatchesOnDragEnd, trackPadding, knobHeight, knobWidth, orientation, position: externalPosition, labelProvider, onDragEnd, onDragStart, onPositionChange, cssStartingTrack, cssEndingTrack, cssKnob, cssLabel, ...props }: Props): JSX.Element;
|
|
90
|
+
export default function Slider({ isInverted, isTrackInteractive, onlyDispatchesOnDragEnd, trackPadding, knobHeight, knobWidth, orientation, position: externalPosition, labelProvider, onDragEnd, onDragStart, onPositionChange, cssStartingTrack, cssEndingTrack, cssKnob, cssLabel, ...props }: Props): JSX.Element;
|
package/lib/Slider.js
CHANGED
|
@@ -79,7 +79,7 @@ var debug = process.env.NODE_ENV === 'development' ? require('debug')('etudes:sl
|
|
|
79
79
|
* respectively). The size of the knob does not impact the size of the slider.
|
|
80
80
|
*/
|
|
81
81
|
function Slider(_a) {
|
|
82
|
-
var _b = _a.isInverted, isInverted = _b === void 0 ? false : _b, _c = _a.
|
|
82
|
+
var _b = _a.isInverted, isInverted = _b === void 0 ? false : _b, _c = _a.isTrackInteractive, isTrackInteractive = _c === void 0 ? true : _c, _d = _a.onlyDispatchesOnDragEnd, onlyDispatchesOnDragEnd = _d === void 0 ? false : _d, _e = _a.trackPadding, trackPadding = _e === void 0 ? 0 : _e, _f = _a.knobHeight, knobHeight = _f === void 0 ? 30 : _f, _g = _a.knobWidth, knobWidth = _g === void 0 ? 30 : _g, _h = _a.orientation, orientation = _h === void 0 ? 'vertical' : _h, _j = _a.position, externalPosition = _j === void 0 ? 0 : _j, labelProvider = _a.labelProvider, onDragEnd = _a.onDragEnd, onDragStart = _a.onDragStart, onPositionChange = _a.onPositionChange, cssStartingTrack = _a.cssStartingTrack, cssEndingTrack = _a.cssEndingTrack, cssKnob = _a.cssKnob, cssLabel = _a.cssLabel, props = __rest(_a, ["isInverted", "isTrackInteractive", "onlyDispatchesOnDragEnd", "trackPadding", "knobHeight", "knobWidth", "orientation", "position", "labelProvider", "onDragEnd", "onDragStart", "onPositionChange", "cssStartingTrack", "cssEndingTrack", "cssKnob", "cssLabel"]);
|
|
83
83
|
function transform(currentPosition, dx, dy) {
|
|
84
84
|
var _a;
|
|
85
85
|
var rect = (_a = spase_1.Rect.from(rootRef.current)) !== null && _a !== void 0 ? _a : new spase_1.Rect();
|
|
@@ -90,15 +90,36 @@ function Slider(_a) {
|
|
|
90
90
|
var newPosition = isInverted ? 1 - naturalNewPosition : naturalNewPosition;
|
|
91
91
|
return newPosition;
|
|
92
92
|
}
|
|
93
|
+
function onTrackClick(event) {
|
|
94
|
+
var _a;
|
|
95
|
+
if (!isTrackInteractive)
|
|
96
|
+
return;
|
|
97
|
+
var rect = (_a = spase_1.Rect.from(rootRef.current)) !== null && _a !== void 0 ? _a : new spase_1.Rect();
|
|
98
|
+
switch (orientation) {
|
|
99
|
+
case 'horizontal': {
|
|
100
|
+
var position_1 = (event.clientX - rect.left) / rect.width;
|
|
101
|
+
var naturalPosition_1 = isInverted ? 1 - position_1 : position_1;
|
|
102
|
+
setPosition(naturalPosition_1);
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
case 'vertical': {
|
|
106
|
+
var position_2 = (event.clientY - rect.top) / rect.height;
|
|
107
|
+
var naturalPosition_2 = isInverted ? 1 - position_2 : position_2;
|
|
108
|
+
setPosition(naturalPosition_2);
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
93
113
|
var rootRef = (0, react_1.useRef)(null);
|
|
94
114
|
var knobRef = (0, react_1.useRef)(null);
|
|
95
|
-
var
|
|
115
|
+
var _k = (0, useDragEffect_1.default)(knobRef, {
|
|
96
116
|
initialValue: externalPosition,
|
|
97
117
|
transform: transform,
|
|
98
118
|
onDragStart: onDragStart,
|
|
99
119
|
onDragEnd: onDragEnd,
|
|
100
|
-
}),
|
|
120
|
+
}), _l = __read(_k.isDragging, 1), isDragging = _l[0], _m = __read(_k.value, 2), position = _m[0], setPosition = _m[1];
|
|
101
121
|
// debug('Rendering...', 'OK')
|
|
122
|
+
// Natural position is the position after taking `isInverted` into account.
|
|
102
123
|
var naturalPosition = isInverted ? 1 - position : position;
|
|
103
124
|
(0, react_1.useEffect)(function () {
|
|
104
125
|
if (isDragging || externalPosition === position)
|
|
@@ -117,7 +138,7 @@ function Slider(_a) {
|
|
|
117
138
|
onPositionChange === null || onPositionChange === void 0 ? void 0 : onPositionChange(position, true);
|
|
118
139
|
}, [isDragging]);
|
|
119
140
|
return (react_1.default.createElement(StyledRoot, __assign({ ref: rootRef, orientation: orientation }, props),
|
|
120
|
-
react_1.default.createElement(
|
|
141
|
+
react_1.default.createElement(StyledStartingTrack, { orientation: orientation, isClickable: isTrackInteractive, css: cssStartingTrack, onClick: function (event) { return onTrackClick(event); }, style: orientation === 'vertical' ? {
|
|
121
142
|
top: 0,
|
|
122
143
|
height: "calc(".concat(naturalPosition * 100, "% - ").concat(knobHeight * .5, "px - ").concat(trackPadding, "px)"),
|
|
123
144
|
} : {
|
|
@@ -141,7 +162,7 @@ function Slider(_a) {
|
|
|
141
162
|
height: "".concat(knobHeight, "px"),
|
|
142
163
|
width: "".concat(knobWidth, "px"),
|
|
143
164
|
} }, labelProvider && (react_1.default.createElement(StyledLabel, { knobHeight: knobHeight, css: cssLabel }, labelProvider(position))))),
|
|
144
|
-
react_1.default.createElement(
|
|
165
|
+
react_1.default.createElement(StyledEndingTrack, { orientation: orientation, isClickable: isTrackInteractive, css: cssEndingTrack, onClick: function (event) { return onTrackClick(event); }, style: orientation === 'vertical' ? {
|
|
145
166
|
bottom: 0,
|
|
146
167
|
height: "calc(".concat((1 - naturalPosition) * 100, "% - ").concat(knobHeight * .5, "px - ").concat(trackPadding, "px)"),
|
|
147
168
|
} : {
|
|
@@ -150,10 +171,11 @@ function Slider(_a) {
|
|
|
150
171
|
} })));
|
|
151
172
|
}
|
|
152
173
|
exports.default = Slider;
|
|
153
|
-
var
|
|
154
|
-
var
|
|
155
|
-
var
|
|
156
|
-
var
|
|
157
|
-
var
|
|
158
|
-
var
|
|
174
|
+
var StyledStartingTrack = styled_components_1.default.div(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n background: #fff;\n cursor: ", ";\n pointer-events: ", ";\n position: absolute;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n &::after {\n content: '';\n height: 100%;\n min-height: 20px;\n min-width: 20px;\n position: absolute;\n transform: ", ";\n width: 100%;\n }\n\n ", "\n\n ", "\n"], ["\n background: #fff;\n cursor: ", ";\n pointer-events: ", ";\n position: absolute;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n &::after {\n content: '';\n height: 100%;\n min-height: 20px;\n min-width: 20px;\n position: absolute;\n transform: ", ";\n width: 100%;\n }\n\n ", "\n\n ", "\n"])), function (props) { return props.isClickable ? 'pointer' : 'auto'; }, function (props) { return props.isClickable ? 'auto' : 'none'; }, function (props) { return props.orientation === 'horizontal' ? 'translate3d(0, -50%, 0)' : 'translate3d(-50%, 0, 0)'; }, function (props) { return props.orientation === 'vertical' ? (0, styled_components_1.css)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n "], ["\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n "]))) : (0, styled_components_1.css)(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n "], ["\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n "]))); }, function (props) { return props.css; });
|
|
175
|
+
var StyledEndingTrack = styled_components_1.default.div(templateObject_6 || (templateObject_6 = __makeTemplateObject(["\n background: #fff;\n cursor: ", ";\n pointer-events: ", ";;\n position: absolute;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n &::after {\n content: '';\n height: 100%;\n min-height: 20px;\n min-width: 20px;\n position: absolute;\n transform: ", ";\n width: 100%;\n }\n\n ", "\n\n ", "\n"], ["\n background: #fff;\n cursor: ", ";\n pointer-events: ", ";;\n position: absolute;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n &::after {\n content: '';\n height: 100%;\n min-height: 20px;\n min-width: 20px;\n position: absolute;\n transform: ", ";\n width: 100%;\n }\n\n ", "\n\n ", "\n"])), function (props) { return props.isClickable ? 'pointer' : 'auto'; }, function (props) { return props.isClickable ? 'auto' : 'none'; }, function (props) { return props.orientation === 'horizontal' ? 'translate3d(0, -50%, 0)' : 'translate3d(-50%, 0, 0)'; }, function (props) { return props.orientation === 'vertical' ? (0, styled_components_1.css)(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n "], ["\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n "]))) : (0, styled_components_1.css)(templateObject_5 || (templateObject_5 = __makeTemplateObject(["\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n "], ["\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n "]))); }, function (props) { return props.css; });
|
|
176
|
+
var StyledLabel = styled_components_1.default.label(templateObject_7 || (templateObject_7 = __makeTemplateObject(["\n color: #000;\n font-size: ", "px;\n pointer-events: none;\n user-select: none;\n\n ", "\n"], ["\n color: #000;\n font-size: ", "px;\n pointer-events: none;\n user-select: none;\n\n ", "\n"])), function (props) { return props.knobHeight * .5; }, function (props) { return props.css; });
|
|
177
|
+
var StyledKnobContainer = styled_components_1.default.button(templateObject_8 || (templateObject_8 = __makeTemplateObject(["\n position: absolute;\n z-index: 1;\n"], ["\n position: absolute;\n z-index: 1;\n"])));
|
|
178
|
+
var StyledKnob = styled_components_1.default.div(templateObject_9 || (templateObject_9 = __makeTemplateObject(["\n align-items: center;\n background: #fff;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n justify-content: center;\n touch-action: none;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n ", "\n"], ["\n align-items: center;\n background: #fff;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n justify-content: center;\n touch-action: none;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n ", "\n"])), function (props) { return props.css; });
|
|
179
|
+
var StyledRoot = styled_components_1.default.div(templateObject_10 || (templateObject_10 = __makeTemplateObject(["\n box-sizing: border-box;\n display: block;\n height: ", ";\n position: relative;\n width: ", ";\n"], ["\n box-sizing: border-box;\n display: block;\n height: ", ";\n position: relative;\n width: ", ";\n"])), function (props) { return props.orientation === 'vertical' ? '300px' : '4px'; }, function (props) { return props.orientation === 'vertical' ? '4px' : '300px'; });
|
|
180
|
+
var templateObject_1, templateObject_2, templateObject_3, templateObject_4, templateObject_5, templateObject_6, templateObject_7, templateObject_8, templateObject_9, templateObject_10;
|
|
159
181
|
//# sourceMappingURL=Slider.js.map
|
package/lib/Slider.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Slider.js","sourceRoot":"/","sources":["Slider.tsx"],"names":[],"mappings":"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","sourcesContent":["import classNames from 'classnames'\nimport React, { HTMLAttributes, useEffect, useRef } from 'react'\nimport { Rect } from 'spase'\nimport styled, { css, CSSProp } from 'styled-components'\nimport useDragEffect from './hooks/useDragEffect'\n\nconst debug = process.env.NODE_ENV === 'development' ? require('debug')('etudes:slider') : () => {}\n\nexport type Props = HTMLAttributes<HTMLDivElement> & {\n /**\n * By default the position is a value from 0 - 1, 0 being the start of the slider and 1 being the\n * end. Switching on this flag inverts this behavior, where 0 becomes the end of the slider and 1\n * being the start.\n */\n isInverted?: boolean\n\n /**\n * Indicates if position change events are dispatched only when dragging ends. When disabled,\n * aforementioned events are fired repeatedly while dragging.\n */\n onlyDispatchesOnDragEnd?: boolean\n\n /**\n * A function that returns the label to be displayed at a given slider position.\n *\n * @param position - The current slider position.\n *\n * @returns The label.\n */\n labelProvider?: (position: number) => string\n\n /**\n * Padding between the track and the knob in pixels.\n */\n trackPadding?: number\n\n /**\n * Height of the knob in pixels.\n */\n knobHeight?: number\n\n /**\n * Width of the knob in pixels.\n */\n knobWidth?: number\n\n /**\n * Orientation of the slider.\n */\n orientation?: 'horizontal' | 'vertical'\n\n /**\n * The current position.\n */\n position?: number\n\n /**\n * Handler invoked when position changes. This can either be invoked from the `position` prop\n * being changed or from the slider being dragged. Note that if the event is emitted at the end of\n * dragging due to `onlyDispatchesOnDragEnd` set to `true`, the `isDragging` parameter here is\n * still `true`.\n *\n * @param position - The current slider position.\n * @param isDragging - Specifies if the position change is due to dragging.\n */\n onPositionChange?: (position: number, isDragging: boolean) => void\n\n /**\n * Handler invoked when dragging ends.\n */\n onDragEnd?: () => void\n\n /**\n * Handler invoked when dragging begins.\n */\n onDragStart?: () => void\n\n /**\n * Custom CSS provided to the track before the knob.\n */\n cssStartingTrack?: CSSProp<any>\n\n /**\n * Custom CSS provided to the track after the knob.\n */\n cssEndingTrack?: CSSProp<any>\n\n /**\n * Custom CSS provided to the knob.\n */\n cssKnob?: CSSProp<any>\n\n /**\n * Custom CSS provided to the label inside the knob.\n */\n cssLabel?: CSSProp<any>\n}\n\n/**\n * A slider component supporting both horizontal and vertical orientations whose sliding position (a\n * decimal between 0.0 and 1.0, inclusive) can be two-way binded. The component consists of four\n * customizable elements: a draggable knob, a label on the knob, a scroll track before the knob and\n * a scroll track after the knob. While the width and height of the slider is inferred from its CSS\n * rules, the width and height of the knob are set via props (`knobWidth` and `knobHeight`,\n * respectively). The size of the knob does not impact the size of the slider.\n */\nexport default function Slider({\n isInverted = false,\n onlyDispatchesOnDragEnd = false,\n trackPadding = 0,\n knobHeight = 30,\n knobWidth = 30,\n orientation = 'vertical',\n position: externalPosition = 0,\n labelProvider,\n onDragEnd,\n onDragStart,\n onPositionChange,\n cssStartingTrack,\n cssEndingTrack,\n cssKnob,\n cssLabel,\n ...props\n}: Props) {\n function transform(currentPosition: number, dx: number, dy: number): number {\n const rect = Rect.from(rootRef.current) ?? new Rect()\n const naturalPosition = isInverted ? 1 - currentPosition : currentPosition\n const naturalNewPositionX = naturalPosition * rect.width + dx\n const naturalNewPositionY = naturalPosition * rect.height + dy\n const naturalNewPosition = (orientation === 'vertical') ? Math.max(0, Math.min(1, naturalNewPositionY / rect.height)) : Math.max(0, Math.min(1, naturalNewPositionX / rect.width))\n const newPosition = isInverted ? 1 - naturalNewPosition : naturalNewPosition\n return newPosition\n }\n\n const rootRef = useRef<HTMLDivElement>(null)\n const knobRef = useRef<HTMLButtonElement>(null)\n\n const { isDragging: [isDragging], value: [position, setPosition] } = useDragEffect(knobRef, {\n initialValue: externalPosition,\n transform,\n onDragStart,\n onDragEnd,\n })\n\n // debug('Rendering...', 'OK')\n\n const naturalPosition = isInverted ? 1 - position : position\n\n useEffect(() => {\n if (isDragging || externalPosition === position) return\n\n debug('Updating drag effect value from position prop...', 'OK', `prop=${externalPosition}, effect=${position}`)\n\n setPosition(externalPosition)\n }, [externalPosition])\n\n useEffect(() => {\n if (isDragging && onlyDispatchesOnDragEnd) return\n onPositionChange?.(position, isDragging)\n }, [position])\n\n useEffect(() => {\n if (isDragging || !onlyDispatchesOnDragEnd) return\n onPositionChange?.(position, true)\n }, [isDragging])\n\n return (\n <StyledRoot ref={rootRef} orientation={orientation} {...props}>\n <StyledTrack orientation={orientation} css={cssStartingTrack}\n style={orientation === 'vertical' ? {\n top: 0,\n height: `calc(${naturalPosition*100}% - ${knobHeight*.5}px - ${trackPadding}px)`,\n } : {\n left: 0,\n width: `calc(${naturalPosition*100}% - ${knobWidth*.5}px - ${trackPadding}px)`,\n }}\n />\n <StyledKnobContainer ref={knobRef} style={{\n transform: 'translate3d(-50%, -50%, 0)',\n ...(orientation === 'vertical' ? {\n left: '50%',\n top: `${naturalPosition*100}%`,\n transition: isDragging === false ? 'top 100ms ease-out' : 'none',\n } : {\n left: `${naturalPosition*100}%`,\n top: '50%',\n transition: isDragging === false ? 'left 100ms ease-out' : 'none',\n }),\n }}>\n <StyledKnob\n className={classNames({\n 'at-end': isInverted ? (position === 0) : (position === 1),\n 'at-start': isInverted ? (position === 1) : (position === 0),\n 'dragging': isDragging === true,\n })}\n css={cssKnob}\n style={{\n height: `${knobHeight}px`,\n width: `${knobWidth}px`,\n }}\n >\n {labelProvider && (\n <StyledLabel knobHeight={knobHeight} css={cssLabel}>{labelProvider(position)}</StyledLabel>\n )}\n </StyledKnob>\n </StyledKnobContainer>\n <StyledTrack orientation={orientation} css={cssEndingTrack}\n style={orientation === 'vertical' ? {\n bottom: 0,\n height: `calc(${(1 - naturalPosition)*100}% - ${knobHeight*.5}px - ${trackPadding}px)`,\n } : {\n right: 0,\n width: `calc(${(1 - naturalPosition)*100}% - ${knobWidth*.5}px - ${trackPadding}px)`,\n }}\n />\n </StyledRoot>\n )\n}\n\nconst StyledTrack = styled.div<{ orientation: NonNullable<Props['orientation']> }>`\n background: #fff;\n position: absolute;\n\n ${props => props.orientation === 'vertical' ? css`\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n ` : css`\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n `}\n\n ${props => props.css}\n`\n\nconst StyledLabel = styled.label<{ knobHeight: NonNullable<Props['knobHeight']> }>`\n color: #000;\n font-size: ${props => props.knobHeight * .5}px;\n pointer-events: none;\n user-select: none;\n\n ${props => props.css}\n`\n\nconst StyledKnobContainer = styled.button`\n position: absolute;\n z-index: 1;\n`\n\nconst StyledKnob = styled.div`\n align-items: center;\n background: #fff;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n justify-content: center;\n touch-action: none;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n ${props => props.css}\n`\n\nconst StyledRoot = styled.div<{\n orientation: Props['orientation']\n}>`\n box-sizing: border-box;\n display: block;\n height: ${props => props.orientation === 'vertical' ? '300px' : '4px'};\n position: relative;\n width: ${props => props.orientation === 'vertical' ? '4px' : '300px'};\n`\n"]}
|
|
1
|
+
{"version":3,"file":"Slider.js","sourceRoot":"/","sources":["Slider.tsx"],"names":[],"mappings":"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","sourcesContent":["import classNames from 'classnames'\nimport React, { HTMLAttributes, MouseEvent, useEffect, useRef } from 'react'\nimport { Rect } from 'spase'\nimport styled, { css, CSSProp } from 'styled-components'\nimport useDragEffect from './hooks/useDragEffect'\n\nconst debug = process.env.NODE_ENV === 'development' ? require('debug')('etudes:slider') : () => {}\n\nexport type Props = HTMLAttributes<HTMLDivElement> & {\n /**\n * By default the position is a value from 0 - 1, 0 being the start of the slider and 1 being the\n * end. Switching on this flag inverts this behavior, where 0 becomes the end of the slider and 1\n * being the start.\n */\n isInverted?: boolean\n\n /**\n * Specifies if the track is clickable to set the position of the knob.\n */\n isTrackInteractive?: boolean\n\n /**\n * Indicates if position change events are dispatched only when dragging ends. When disabled,\n * aforementioned events are fired repeatedly while dragging.\n */\n onlyDispatchesOnDragEnd?: boolean\n\n /**\n * A function that returns the label to be displayed at a given slider position.\n *\n * @param position - The current slider position.\n *\n * @returns The label.\n */\n labelProvider?: (position: number) => string\n\n /**\n * Padding between the track and the knob in pixels.\n */\n trackPadding?: number\n\n /**\n * Height of the knob in pixels.\n */\n knobHeight?: number\n\n /**\n * Width of the knob in pixels.\n */\n knobWidth?: number\n\n /**\n * Orientation of the slider.\n */\n orientation?: 'horizontal' | 'vertical'\n\n /**\n * The current position.\n */\n position?: number\n\n /**\n * Handler invoked when position changes. This can either be invoked from the `position` prop\n * being changed or from the slider being dragged. Note that if the event is emitted at the end of\n * dragging due to `onlyDispatchesOnDragEnd` set to `true`, the `isDragging` parameter here is\n * still `true`.\n *\n * @param position - The current slider position.\n * @param isDragging - Specifies if the position change is due to dragging.\n */\n onPositionChange?: (position: number, isDragging: boolean) => void\n\n /**\n * Handler invoked when dragging ends.\n */\n onDragEnd?: () => void\n\n /**\n * Handler invoked when dragging begins.\n */\n onDragStart?: () => void\n\n /**\n * Custom CSS provided to the track before the knob.\n */\n cssStartingTrack?: CSSProp\n\n /**\n * Custom CSS provided to the track after the knob.\n */\n cssEndingTrack?: CSSProp\n\n /**\n * Custom CSS provided to the knob.\n */\n cssKnob?: CSSProp\n\n /**\n * Custom CSS provided to the label inside the knob.\n */\n cssLabel?: CSSProp\n}\n\n/**\n * A slider component supporting both horizontal and vertical orientations whose sliding position (a\n * decimal between 0.0 and 1.0, inclusive) can be two-way binded. The component consists of four\n * customizable elements: a draggable knob, a label on the knob, a scroll track before the knob and\n * a scroll track after the knob. While the width and height of the slider is inferred from its CSS\n * rules, the width and height of the knob are set via props (`knobWidth` and `knobHeight`,\n * respectively). The size of the knob does not impact the size of the slider.\n */\nexport default function Slider({\n isInverted = false,\n isTrackInteractive = true,\n onlyDispatchesOnDragEnd = false,\n trackPadding = 0,\n knobHeight = 30,\n knobWidth = 30,\n orientation = 'vertical',\n position: externalPosition = 0,\n labelProvider,\n onDragEnd,\n onDragStart,\n onPositionChange,\n cssStartingTrack,\n cssEndingTrack,\n cssKnob,\n cssLabel,\n ...props\n}: Props) {\n function transform(currentPosition: number, dx: number, dy: number): number {\n const rect = Rect.from(rootRef.current) ?? new Rect()\n const naturalPosition = isInverted ? 1 - currentPosition : currentPosition\n const naturalNewPositionX = naturalPosition * rect.width + dx\n const naturalNewPositionY = naturalPosition * rect.height + dy\n const naturalNewPosition = (orientation === 'vertical') ? Math.max(0, Math.min(1, naturalNewPositionY / rect.height)) : Math.max(0, Math.min(1, naturalNewPositionX / rect.width))\n const newPosition = isInverted ? 1 - naturalNewPosition : naturalNewPosition\n return newPosition\n }\n\n function onTrackClick(event: MouseEvent) {\n if (!isTrackInteractive) return\n\n const rect = Rect.from(rootRef.current) ?? new Rect()\n\n switch (orientation) {\n case 'horizontal': {\n const position = (event.clientX - rect.left) / rect.width\n const naturalPosition = isInverted ? 1 - position : position\n setPosition(naturalPosition)\n break\n }\n case 'vertical': {\n const position = (event.clientY - rect.top) / rect.height\n const naturalPosition = isInverted ? 1 - position : position\n setPosition(naturalPosition)\n break\n }\n }\n }\n\n const rootRef = useRef<HTMLDivElement>(null)\n const knobRef = useRef<HTMLButtonElement>(null)\n\n const { isDragging: [isDragging], value: [position, setPosition] } = useDragEffect(knobRef, {\n initialValue: externalPosition,\n transform,\n onDragStart,\n onDragEnd,\n })\n\n // debug('Rendering...', 'OK')\n\n // Natural position is the position after taking `isInverted` into account.\n const naturalPosition = isInverted ? 1 - position : position\n\n useEffect(() => {\n if (isDragging || externalPosition === position) return\n\n debug('Updating drag effect value from position prop...', 'OK', `prop=${externalPosition}, effect=${position}`)\n\n setPosition(externalPosition)\n }, [externalPosition])\n\n useEffect(() => {\n if (isDragging && onlyDispatchesOnDragEnd) return\n onPositionChange?.(position, isDragging)\n }, [position])\n\n useEffect(() => {\n if (isDragging || !onlyDispatchesOnDragEnd) return\n onPositionChange?.(position, true)\n }, [isDragging])\n\n return (\n <StyledRoot ref={rootRef} orientation={orientation} {...props}>\n <StyledStartingTrack orientation={orientation} isClickable={isTrackInteractive} css={cssStartingTrack} onClick={event => onTrackClick(event)}\n style={orientation === 'vertical' ? {\n top: 0,\n height: `calc(${naturalPosition*100}% - ${knobHeight*.5}px - ${trackPadding}px)`,\n } : {\n left: 0,\n width: `calc(${naturalPosition*100}% - ${knobWidth*.5}px - ${trackPadding}px)`,\n }}\n />\n <StyledKnobContainer ref={knobRef} style={{\n transform: 'translate3d(-50%, -50%, 0)',\n ...(orientation === 'vertical' ? {\n left: '50%',\n top: `${naturalPosition*100}%`,\n transition: isDragging === false ? 'top 100ms ease-out' : 'none',\n } : {\n left: `${naturalPosition*100}%`,\n top: '50%',\n transition: isDragging === false ? 'left 100ms ease-out' : 'none',\n }),\n }}>\n <StyledKnob\n className={classNames({\n 'at-end': isInverted ? (position === 0) : (position === 1),\n 'at-start': isInverted ? (position === 1) : (position === 0),\n 'dragging': isDragging === true,\n })}\n css={cssKnob}\n style={{\n height: `${knobHeight}px`,\n width: `${knobWidth}px`,\n }}\n >\n {labelProvider && (\n <StyledLabel knobHeight={knobHeight} css={cssLabel}>{labelProvider(position)}</StyledLabel>\n )}\n </StyledKnob>\n </StyledKnobContainer>\n <StyledEndingTrack orientation={orientation} isClickable={isTrackInteractive} css={cssEndingTrack} onClick={event => onTrackClick(event)}\n style={orientation === 'vertical' ? {\n bottom: 0,\n height: `calc(${(1 - naturalPosition)*100}% - ${knobHeight*.5}px - ${trackPadding}px)`,\n } : {\n right: 0,\n width: `calc(${(1 - naturalPosition)*100}% - ${knobWidth*.5}px - ${trackPadding}px)`,\n }}\n />\n </StyledRoot>\n )\n}\n\nconst StyledStartingTrack = styled.div<{\n orientation: NonNullable<Props['orientation']>\n isClickable: boolean\n}>`\n background: #fff;\n cursor: ${props => props.isClickable ? 'pointer' : 'auto' };\n pointer-events: ${props => props.isClickable ? 'auto' : 'none' };\n position: absolute;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n &::after {\n content: '';\n height: 100%;\n min-height: 20px;\n min-width: 20px;\n position: absolute;\n transform: ${props => props.orientation === 'horizontal' ? 'translate3d(0, -50%, 0)' : 'translate3d(-50%, 0, 0)'};\n width: 100%;\n }\n\n ${props => props.orientation === 'vertical' ? css`\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n ` : css`\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n `}\n\n ${props => props.css}\n`\n\nconst StyledEndingTrack = styled.div<{\n orientation: NonNullable<Props['orientation']>\n isClickable: boolean\n}>`\n background: #fff;\n cursor: ${props => props.isClickable ? 'pointer' : 'auto' };\n pointer-events: ${props => props.isClickable ? 'auto' : 'none' };;\n position: absolute;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n &::after {\n content: '';\n height: 100%;\n min-height: 20px;\n min-width: 20px;\n position: absolute;\n transform: ${props => props.orientation === 'horizontal' ? 'translate3d(0, -50%, 0)' : 'translate3d(-50%, 0, 0)'};\n width: 100%;\n }\n\n ${props => props.orientation === 'vertical' ? css`\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n ` : css`\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n `}\n\n ${props => props.css}\n`\n\nconst StyledLabel = styled.label<{ knobHeight: NonNullable<Props['knobHeight']> }>`\n color: #000;\n font-size: ${props => props.knobHeight * .5}px;\n pointer-events: none;\n user-select: none;\n\n ${props => props.css}\n`\n\nconst StyledKnobContainer = styled.button`\n position: absolute;\n z-index: 1;\n`\n\nconst StyledKnob = styled.div`\n align-items: center;\n background: #fff;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n justify-content: center;\n touch-action: none;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n ${props => props.css}\n`\n\nconst StyledRoot = styled.div<{\n orientation: Props['orientation']\n}>`\n box-sizing: border-box;\n display: block;\n height: ${props => props.orientation === 'vertical' ? '300px' : '4px'};\n position: relative;\n width: ${props => props.orientation === 'vertical' ? '4px' : '300px'};\n`\n"]}
|
package/lib/StepwiseSlider.d.ts
CHANGED
|
@@ -7,6 +7,10 @@ export declare type Props = HTMLAttributes<HTMLDivElement> & {
|
|
|
7
7
|
* being the start.
|
|
8
8
|
*/
|
|
9
9
|
isInverted?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Specifies if the track is clickable to set the position of the knob.
|
|
12
|
+
*/
|
|
13
|
+
isTrackInteractive?: boolean;
|
|
10
14
|
/**
|
|
11
15
|
* Indicates if position/index change events are dispatched only when dragging ends. When
|
|
12
16
|
* disabled, aforementioned events are fired repeatedly while dragging.
|
|
@@ -113,4 +117,4 @@ export declare function generateSteps(length: number): readonly number[];
|
|
|
113
117
|
* of the slider. While dragging, the slider still emits a position change event, where the position
|
|
114
118
|
* is a decimal ranging between 0.0 and 1.0, inclusive.
|
|
115
119
|
*/
|
|
116
|
-
export default function StepwiseSlider({ id, className, isInverted, onlyDispatchesOnDragEnd, trackPadding, knobHeight, knobWidth, orientation, labelProvider, steps, index: externalIndex, onIndexChange, onPositionChange, onDragEnd, onDragStart, cssStartingTrack, cssEndingTrack, cssKnob, cssLabel, ...props }: Props): JSX.Element;
|
|
120
|
+
export default function StepwiseSlider({ id, className, isInverted, isTrackInteractive, onlyDispatchesOnDragEnd, trackPadding, knobHeight, knobWidth, orientation, labelProvider, steps, index: externalIndex, onIndexChange, onPositionChange, onDragEnd, onDragStart, cssStartingTrack, cssEndingTrack, cssKnob, cssLabel, ...props }: Props): JSX.Element;
|
package/lib/StepwiseSlider.js
CHANGED
|
@@ -141,7 +141,7 @@ function getPositionAt(index, steps) {
|
|
|
141
141
|
* is a decimal ranging between 0.0 and 1.0, inclusive.
|
|
142
142
|
*/
|
|
143
143
|
function StepwiseSlider(_a) {
|
|
144
|
-
var id = _a.id, className = _a.className, _b = _a.isInverted, isInverted = _b === void 0 ? false : _b, _c = _a.
|
|
144
|
+
var id = _a.id, className = _a.className, _b = _a.isInverted, isInverted = _b === void 0 ? false : _b, _c = _a.isTrackInteractive, isTrackInteractive = _c === void 0 ? true : _c, _d = _a.onlyDispatchesOnDragEnd, onlyDispatchesOnDragEnd = _d === void 0 ? false : _d, _e = _a.trackPadding, trackPadding = _e === void 0 ? 0 : _e, _f = _a.knobHeight, knobHeight = _f === void 0 ? 30 : _f, _g = _a.knobWidth, knobWidth = _g === void 0 ? 30 : _g, _h = _a.orientation, orientation = _h === void 0 ? 'vertical' : _h, labelProvider = _a.labelProvider, _j = _a.steps, steps = _j === void 0 ? generateSteps(10) : _j, _k = _a.index, externalIndex = _k === void 0 ? 0 : _k, onIndexChange = _a.onIndexChange, onPositionChange = _a.onPositionChange, onDragEnd = _a.onDragEnd, onDragStart = _a.onDragStart, cssStartingTrack = _a.cssStartingTrack, cssEndingTrack = _a.cssEndingTrack, cssKnob = _a.cssKnob, cssLabel = _a.cssLabel, props = __rest(_a, ["id", "className", "isInverted", "isTrackInteractive", "onlyDispatchesOnDragEnd", "trackPadding", "knobHeight", "knobWidth", "orientation", "labelProvider", "steps", "index", "onIndexChange", "onPositionChange", "onDragEnd", "onDragStart", "cssStartingTrack", "cssEndingTrack", "cssKnob", "cssLabel"]);
|
|
145
145
|
function transform(currentPosition, dx, dy) {
|
|
146
146
|
var _a;
|
|
147
147
|
var rect = (_a = spase_1.Rect.from(rootRef.current)) !== null && _a !== void 0 ? _a : new spase_1.Rect();
|
|
@@ -152,15 +152,36 @@ function StepwiseSlider(_a) {
|
|
|
152
152
|
var newPosition = isInverted ? 1 - naturalNewPosition : naturalNewPosition;
|
|
153
153
|
return newPosition;
|
|
154
154
|
}
|
|
155
|
+
function onTrackClick(event) {
|
|
156
|
+
var _a;
|
|
157
|
+
if (!isTrackInteractive)
|
|
158
|
+
return;
|
|
159
|
+
var rect = (_a = spase_1.Rect.from(rootRef.current)) !== null && _a !== void 0 ? _a : new spase_1.Rect();
|
|
160
|
+
switch (orientation) {
|
|
161
|
+
case 'horizontal': {
|
|
162
|
+
var position_1 = (event.clientX - rect.left) / rect.width;
|
|
163
|
+
var naturalPosition_1 = isInverted ? 1 - position_1 : position_1;
|
|
164
|
+
setPosition(naturalPosition_1);
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
case 'vertical': {
|
|
168
|
+
var position_2 = (event.clientY - rect.top) / rect.height;
|
|
169
|
+
var naturalPosition_2 = isInverted ? 1 - position_2 : position_2;
|
|
170
|
+
setPosition(naturalPosition_2);
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
155
175
|
var rootRef = (0, react_1.useRef)(null);
|
|
156
176
|
var knobRef = (0, react_1.useRef)(null);
|
|
157
|
-
var
|
|
158
|
-
var
|
|
177
|
+
var _l = __read((0, react_1.useState)(externalIndex), 2), index = _l[0], setIndex = _l[1];
|
|
178
|
+
var _m = (0, useDragEffect_1.default)(knobRef, {
|
|
159
179
|
initialValue: getPositionAt(externalIndex, steps),
|
|
160
180
|
transform: transform,
|
|
161
181
|
onDragStart: onDragStart,
|
|
162
182
|
onDragEnd: onDragEnd,
|
|
163
|
-
}),
|
|
183
|
+
}), _o = __read(_m.isDragging, 1), isDragging = _o[0], _p = __read(_m.value, 2), position = _p[0], setPosition = _p[1];
|
|
184
|
+
// Natural position is the position after taking `isInverted` into account.
|
|
164
185
|
var naturalPosition = isInverted ? 1 - position : position;
|
|
165
186
|
(0, react_1.useEffect)(function () {
|
|
166
187
|
if (isDragging)
|
|
@@ -196,7 +217,7 @@ function StepwiseSlider(_a) {
|
|
|
196
217
|
}
|
|
197
218
|
}, [isDragging]);
|
|
198
219
|
return (react_1.default.createElement(StyledRoot, __assign({ ref: rootRef, orientation: orientation }, props),
|
|
199
|
-
react_1.default.createElement(
|
|
220
|
+
react_1.default.createElement(StyledStartingTrack, { orientation: orientation, isClickable: isTrackInteractive, css: cssStartingTrack, onClick: function (event) { return onTrackClick(event); }, style: orientation === 'vertical' ? {
|
|
200
221
|
top: 0,
|
|
201
222
|
height: "calc(".concat(naturalPosition * 100, "% - ").concat(knobHeight * .5, "px - ").concat(trackPadding, "px)"),
|
|
202
223
|
} : {
|
|
@@ -220,7 +241,7 @@ function StepwiseSlider(_a) {
|
|
|
220
241
|
height: "".concat(knobHeight, "px"),
|
|
221
242
|
width: "".concat(knobWidth, "px"),
|
|
222
243
|
} }, steps && labelProvider && (react_1.default.createElement(StyledLabel, { knobHeight: knobHeight, css: cssLabel }, labelProvider(position, getNearestIndexByPosition(position, steps)))))),
|
|
223
|
-
react_1.default.createElement(
|
|
244
|
+
react_1.default.createElement(StyledEndingTrack, { orientation: orientation, isClickable: isTrackInteractive, css: cssEndingTrack, onClick: function (event) { return onTrackClick(event); }, style: orientation === 'vertical' ? {
|
|
224
245
|
bottom: 0,
|
|
225
246
|
height: "calc(".concat((1 - naturalPosition) * 100, "% - ").concat(knobHeight * .5, "px - ").concat(trackPadding, "px)"),
|
|
226
247
|
} : {
|
|
@@ -229,10 +250,11 @@ function StepwiseSlider(_a) {
|
|
|
229
250
|
} })));
|
|
230
251
|
}
|
|
231
252
|
exports.default = StepwiseSlider;
|
|
232
|
-
var
|
|
233
|
-
var
|
|
234
|
-
var
|
|
235
|
-
var
|
|
236
|
-
var
|
|
237
|
-
var
|
|
253
|
+
var StyledStartingTrack = styled_components_1.default.div(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n background: #fff;\n cursor: ", ";\n pointer-events: ", ";\n position: absolute;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n &::after {\n content: '';\n height: 100%;\n min-height: 20px;\n min-width: 20px;\n position: absolute;\n transform: ", ";\n width: 100%;\n }\n\n ", "\n\n ", "\n"], ["\n background: #fff;\n cursor: ", ";\n pointer-events: ", ";\n position: absolute;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n &::after {\n content: '';\n height: 100%;\n min-height: 20px;\n min-width: 20px;\n position: absolute;\n transform: ", ";\n width: 100%;\n }\n\n ", "\n\n ", "\n"])), function (props) { return props.isClickable ? 'pointer' : 'auto'; }, function (props) { return props.isClickable ? 'auto' : 'none'; }, function (props) { return props.orientation === 'horizontal' ? 'translate3d(0, -50%, 0)' : 'translate3d(-50%, 0, 0)'; }, function (props) { return props.orientation === 'vertical' ? (0, styled_components_1.css)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n "], ["\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n "]))) : (0, styled_components_1.css)(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n "], ["\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n "]))); }, function (props) { return props.css; });
|
|
254
|
+
var StyledEndingTrack = styled_components_1.default.div(templateObject_6 || (templateObject_6 = __makeTemplateObject(["\n background: #fff;\n cursor: ", ";\n pointer-events: ", ";\n position: absolute;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n &::after {\n content: '';\n height: 100%;\n min-height: 20px;\n min-width: 20px;\n position: absolute;\n transform: ", ";\n width: 100%;\n }\n\n ", "\n\n ", "\n"], ["\n background: #fff;\n cursor: ", ";\n pointer-events: ", ";\n position: absolute;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n &::after {\n content: '';\n height: 100%;\n min-height: 20px;\n min-width: 20px;\n position: absolute;\n transform: ", ";\n width: 100%;\n }\n\n ", "\n\n ", "\n"])), function (props) { return props.isClickable ? 'pointer' : 'auto'; }, function (props) { return props.isClickable ? 'auto' : 'none'; }, function (props) { return props.orientation === 'horizontal' ? 'translate3d(0, -50%, 0)' : 'translate3d(-50%, 0, 0)'; }, function (props) { return props.orientation === 'vertical' ? (0, styled_components_1.css)(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n "], ["\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n "]))) : (0, styled_components_1.css)(templateObject_5 || (templateObject_5 = __makeTemplateObject(["\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n "], ["\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n "]))); }, function (props) { return props.css; });
|
|
255
|
+
var StyledLabel = styled_components_1.default.label(templateObject_7 || (templateObject_7 = __makeTemplateObject(["\n color: #000;\n font-size: ", "px;\n pointer-events: none;\n user-select: none;\n\n ", "\n"], ["\n color: #000;\n font-size: ", "px;\n pointer-events: none;\n user-select: none;\n\n ", "\n"])), function (props) { return props.knobHeight * .5; }, function (props) { return props.css; });
|
|
256
|
+
var StyledKnobContainer = styled_components_1.default.button(templateObject_8 || (templateObject_8 = __makeTemplateObject(["\n position: absolute;\n z-index: 1;\n"], ["\n position: absolute;\n z-index: 1;\n"])));
|
|
257
|
+
var StyledKnob = styled_components_1.default.div(templateObject_9 || (templateObject_9 = __makeTemplateObject(["\n align-items: center;\n background: #fff;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n justify-content: center;\n opacity: 1;\n touch-action: none;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n ", "\n"], ["\n align-items: center;\n background: #fff;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n justify-content: center;\n opacity: 1;\n touch-action: none;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n ", "\n"])), function (props) { return props.css; });
|
|
258
|
+
var StyledRoot = styled_components_1.default.div(templateObject_10 || (templateObject_10 = __makeTemplateObject(["\n box-sizing: border-box;\n display: block;\n height: ", ";\n position: relative;\n width: ", ";\n"], ["\n box-sizing: border-box;\n display: block;\n height: ", ";\n position: relative;\n width: ", ";\n"])), function (props) { return props.orientation === 'vertical' ? '300px' : '4px'; }, function (props) { return props.orientation === 'vertical' ? '4px' : '300px'; });
|
|
259
|
+
var templateObject_1, templateObject_2, templateObject_3, templateObject_4, templateObject_5, templateObject_6, templateObject_7, templateObject_8, templateObject_9, templateObject_10;
|
|
238
260
|
//# sourceMappingURL=StepwiseSlider.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StepwiseSlider.js","sourceRoot":"/","sources":["StepwiseSlider.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,0DAAmC;AACnC,6CAA0E;AAC1E,+BAA4B;AAC5B,qEAAwD;AACxD,wEAAiD;AAEjD,IAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC,cAAO,CAAC,CAAA;AAgH5G;;;;;;;GAOG;AACH,SAAgB,aAAa,CAAC,MAAc;IAC1C,IAAI,MAAM,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAA;IACrF,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAA;IAEvF,IAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IAEjC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,UAAC,CAAC,EAAE,CAAC;QACvC,IAAM,QAAQ,GAAG,QAAQ,GAAG,CAAC,CAAA;QAC7B,OAAO,QAAQ,CAAA;IACjB,CAAC,CAAC,CAAA;AACJ,CAAC;AAVD,sCAUC;AAED;;;;;;;;GAQG;AACH,SAAS,yBAAyB,CAAC,QAAgB,EAAE,KAAwB;IAC3E,IAAI,KAAK,GAAG,CAAC,CAAC,CAAA;IACd,IAAI,QAAQ,GAAG,GAAG,CAAA;IAElB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;QAC5C,IAAM,IAAI,GAAG,aAAa,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;QAEpC,IAAI,KAAK,CAAC,IAAI,CAAC;YAAE,SAAQ;QAEzB,IAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAA;QAEvC,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,EAAE;YACzC,QAAQ,GAAG,KAAK,CAAA;YAChB,KAAK,GAAG,CAAC,CAAA;SACV;KACF;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,aAAa,CAAC,KAAa,EAAE,KAAwB;IAC5D,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM;QAAE,OAAO,GAAG,CAAA;IACrC,OAAO,KAAK,CAAC,KAAK,CAAC,CAAA;AACrB,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAwB,cAAc,CAAC,EAqB/B;IApBN,IAAA,EAAE,QAAA,EACF,SAAS,eAAA,EACT,kBAAkB,EAAlB,UAAU,mBAAG,KAAK,KAAA,EAClB,+BAA+B,EAA/B,uBAAuB,mBAAG,KAAK,KAAA,EAC/B,oBAAgB,EAAhB,YAAY,mBAAG,CAAC,KAAA,EAChB,kBAAe,EAAf,UAAU,mBAAG,EAAE,KAAA,EACf,iBAAc,EAAd,SAAS,mBAAG,EAAE,KAAA,EACd,mBAAwB,EAAxB,WAAW,mBAAG,UAAU,KAAA,EACxB,aAAa,mBAAA,EACb,aAAyB,EAAzB,KAAK,mBAAG,aAAa,CAAC,EAAE,CAAC,KAAA,EACzB,aAAwB,EAAjB,aAAa,mBAAG,CAAC,KAAA,EACxB,aAAa,mBAAA,EACb,gBAAgB,sBAAA,EAChB,SAAS,eAAA,EACT,WAAW,iBAAA,EACX,gBAAgB,sBAAA,EAChB,cAAc,oBAAA,EACd,OAAO,aAAA,EACP,QAAQ,cAAA,EACL,KAAK,cApB6B,uRAqBtC,CADS;IAER,SAAS,SAAS,CAAC,eAAuB,EAAE,EAAU,EAAE,EAAU;;QAChE,IAAM,IAAI,GAAG,MAAA,YAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,mCAAI,IAAI,YAAI,EAAE,CAAA;QACrD,IAAM,eAAe,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,eAAe,CAAA;QAC1E,IAAM,mBAAmB,GAAG,eAAe,GAAG,IAAI,CAAC,KAAK,GAAG,EAAE,CAAA;QAC7D,IAAM,mBAAmB,GAAG,eAAe,GAAG,IAAI,CAAC,MAAM,GAAG,EAAE,CAAA;QAC9D,IAAM,kBAAkB,GAAG,CAAC,WAAW,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;QAClL,IAAM,WAAW,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,kBAAkB,CAAA;QAC5E,OAAO,WAAW,CAAA;IACpB,CAAC;IAED,IAAM,OAAO,GAAG,IAAA,cAAM,EAAiB,IAAI,CAAC,CAAA;IAC5C,IAAM,OAAO,GAAG,IAAA,cAAM,EAAoB,IAAI,CAAC,CAAA;IAEzC,IAAA,KAAA,OAAoB,IAAA,gBAAQ,EAAC,aAAa,CAAC,IAAA,EAA1C,KAAK,QAAA,EAAE,QAAQ,QAA2B,CAAA;IAE3C,IAAA,KAA+D,IAAA,uBAAa,EAAC,OAAO,EAAE;QAC1F,YAAY,EAAE,aAAa,CAAC,aAAa,EAAE,KAAK,CAAC;QACjD,SAAS,WAAA;QACT,WAAW,aAAA;QACX,SAAS,WAAA;KACV,CAAC,EALM,KAAA,wBAAwB,EAAX,UAAU,QAAA,EAAG,KAAA,mBAA8B,EAAtB,QAAQ,QAAA,EAAE,WAAW,QAK7D,CAAA;IAEF,IAAM,eAAe,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAA;IAE5D,IAAA,iBAAS,EAAC;QACR,IAAI,UAAU;YAAE,OAAM;QAEtB,IAAM,WAAW,GAAG,aAAa,CAAC,aAAa,EAAE,KAAK,CAAC,CAAA;QAEvD,IAAI,QAAQ,KAAK,WAAW,EAAE;YAC5B,KAAK,CAAC,+CAA+C,EAAE,IAAI,EAAE,eAAQ,WAAW,sBAAY,QAAQ,CAAE,CAAC,CAAA;YACvG,WAAW,CAAC,WAAW,CAAC,CAAA;SACzB;QAED,IAAI,aAAa,KAAK,KAAK,EAAE;YAC3B,QAAQ,CAAC,aAAa,CAAC,CAAA;SACxB;IACH,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAA;IAEnB,IAAA,iBAAS,EAAC;QACR,IAAI,UAAU,IAAI,uBAAuB;YAAE,OAAM;QAEjD,gBAAgB,aAAhB,gBAAgB,uBAAhB,gBAAgB,CAAG,QAAQ,EAAE,UAAU,CAAC,CAAA;QAExC,IAAM,QAAQ,GAAG,yBAAyB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;QAC3D,IAAI,KAAK,KAAK,QAAQ;YAAE,QAAQ,CAAC,QAAQ,CAAC,CAAA;IAC5C,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAA;IAEd,IAAA,iBAAS,EAAC;QACR,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAG,KAAK,EAAE,UAAU,CAAC,CAAA;IACpC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;IAEX,IAAA,iBAAS,EAAC;QACR,IAAI,UAAU;YAAE,OAAM;QAEtB,IAAM,YAAY,GAAG,yBAAyB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;QAC/D,IAAM,eAAe,GAAG,aAAa,CAAC,YAAY,EAAE,KAAK,CAAC,CAAA;QAE1D,IAAI,eAAe,KAAK,QAAQ,IAAI,uBAAuB,EAAE;YAC3D,WAAW,CAAC,eAAe,CAAC,CAAA;YAC5B,gBAAgB,aAAhB,gBAAgB,uBAAhB,gBAAgB,CAAG,eAAe,EAAE,IAAI,CAAC,CAAA;SAC1C;IACH,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAA;IAEhB,OAAO,CACL,8BAAC,UAAU,aAAC,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,IAAM,KAAK;QAC3D,8BAAC,WAAW,IAAC,WAAW,EAAE,WAAW,EAAE,GAAG,EAAE,gBAAgB,EAC1D,KAAK,EAAE,WAAW,KAAK,UAAU,CAAC,CAAC,CAAC;gBAClC,GAAG,EAAE,CAAC;gBACN,MAAM,EAAE,eAAQ,eAAe,GAAC,GAAG,iBAAO,UAAU,GAAC,EAAE,kBAAQ,YAAY,QAAK;aACjF,CAAC,CAAC,CAAC;gBACF,IAAI,EAAE,CAAC;gBACP,KAAK,EAAE,eAAQ,eAAe,GAAC,GAAG,iBAAO,SAAS,GAAC,EAAE,kBAAQ,YAAY,QAAK;aAC/E,GACD;QACF,8BAAC,mBAAmB,IAAC,GAAG,EAAE,OAAO,EAAE,KAAK,aACtC,SAAS,EAAE,4BAA4B,IACpC,CAAC,WAAW,KAAK,UAAU,CAAC,CAAC,CAAC;gBAC/B,IAAI,EAAE,KAAK;gBACX,GAAG,EAAE,UAAG,eAAe,GAAC,GAAG,MAAG;gBAC9B,UAAU,EAAE,UAAU,KAAK,KAAK,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,MAAM;aACjE,CAAC,CAAC,CAAC;gBACF,IAAI,EAAE,UAAG,eAAe,GAAC,GAAG,MAAG;gBAC/B,GAAG,EAAE,KAAK;gBACV,UAAU,EAAE,UAAU,KAAK,KAAK,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,MAAM;aAClE,CAAC;YAEF,8BAAC,UAAU,IACT,SAAS,EAAE,IAAA,oBAAU,EAAC;oBACpB,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC;oBAC1D,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC;oBAC5D,UAAU,EAAE,UAAU;iBACvB,CAAC,EACF,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE;oBACL,MAAM,EAAE,UAAG,UAAU,OAAI;oBACzB,KAAK,EAAE,UAAG,SAAS,OAAI;iBACxB,IAEA,KAAK,IAAI,aAAa,IAAI,CACzB,8BAAC,WAAW,IAAC,UAAU,EAAE,UAAU,EAAE,GAAG,EAAE,QAAQ,IAAG,aAAa,CAAC,QAAQ,EAAE,yBAAyB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAe,CACxI,CACU,CACO;QACtB,8BAAC,WAAW,IAAC,WAAW,EAAE,WAAW,EAAE,GAAG,EAAE,cAAc,EACxD,KAAK,EAAE,WAAW,KAAK,UAAU,CAAC,CAAC,CAAC;gBAClC,MAAM,EAAE,CAAC;gBACT,MAAM,EAAE,eAAQ,CAAC,CAAC,GAAG,eAAe,CAAC,GAAC,GAAG,iBAAO,UAAU,GAAC,EAAE,kBAAQ,YAAY,QAAK;aACvF,CAAC,CAAC,CAAC;gBACF,KAAK,EAAE,CAAC;gBACR,KAAK,EAAE,eAAQ,CAAC,CAAC,GAAG,eAAe,CAAC,GAAC,GAAG,iBAAO,SAAS,GAAC,EAAE,kBAAQ,YAAY,QAAK;aACrF,GACD,CACS,CACd,CAAA;AACH,CAAC;AAzID,iCAyIC;AAED,IAAM,WAAW,GAAG,2BAAM,CAAC,GAAG,uIAAoD,oDAI9E,EAUD,QAEC,EAAkB,IACrB,KAbG,UAAA,KAAK,IAAI,OAAA,KAAK,CAAC,WAAW,KAAK,UAAU,CAAC,CAAC,KAAC,uBAAG,8IAAA,0EAKhD,KAAC,CAAC,KAAC,uBAAG,+IAAA,2EAKN,IAAA,EAVU,CAUV,EAEC,UAAA,KAAK,IAAI,OAAA,KAAK,CAAC,GAAG,EAAT,CAAS,CACrB,CAAA;AAED,IAAM,WAAW,GAAG,2BAAM,CAAC,KAAK,sKAAkD,iCAEnE,EAA8B,0DAIzC,EAAkB,IACrB,KALc,UAAA,KAAK,IAAI,OAAA,KAAK,CAAC,UAAU,GAAG,EAAE,EAArB,CAAqB,EAIzC,UAAA,KAAK,IAAI,OAAA,KAAK,CAAC,GAAG,EAAT,CAAS,CACrB,CAAA;AAED,IAAM,mBAAmB,GAAG,2BAAM,CAAC,MAAM,6GAAA,0CAGxC,IAAA,CAAA;AAED,IAAM,UAAU,GAAG,2BAAM,CAAC,GAAG,+YAAA,sUAazB,EAAkB,IACrB,KADG,UAAA,KAAK,IAAI,OAAA,KAAK,CAAC,GAAG,EAAT,CAAS,CACrB,CAAA;AAED,IAAM,UAAU,GAAG,2BAAM,CAAC,GAAG,6KAE3B,4DAGU,EAA2D,qCAE5D,EAA2D,KACrE,KAHW,UAAA,KAAK,IAAI,OAAA,KAAK,CAAC,WAAW,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAlD,CAAkD,EAE5D,UAAA,KAAK,IAAI,OAAA,KAAK,CAAC,WAAW,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAlD,CAAkD,CACrE,CAAA","sourcesContent":["import classNames from 'classnames'\nimport React, { HTMLAttributes, useEffect, useRef, useState } from 'react'\nimport { Rect } from 'spase'\nimport styled, { css, CSSProp } from 'styled-components'\nimport useDragEffect from './hooks/useDragEffect'\n\nconst debug = process.env.NODE_ENV === 'development' ? require('debug')('etudes:stepwise-slider') : () => {}\n\nexport type Props = HTMLAttributes<HTMLDivElement> & {\n /**\n * By default the position is a value from 0 - 1, 0 being the start of the slider and 1 being the\n * end. Switching on this flag inverts this behavior, where 0 becomes the end of the slider and 1\n * being the start.\n */\n isInverted?: boolean\n\n /**\n * Indicates if position/index change events are dispatched only when dragging ends. When\n * disabled, aforementioned events are fired repeatedly while dragging.\n */\n onlyDispatchesOnDragEnd?: boolean\n\n /**\n * A function that returns the label to be displayed at a given slider position and closest step\n * index (if steps are provided).\n *\n * @param position - The current slider position.\n * @param index - The nearest step index (if steps are provided), or -1 if no steps are provided.\n *\n * @returns The label.\n */\n labelProvider?: (position: number, index: number) => string\n\n /**\n * Padding between the track and the knob in pixels.\n */\n trackPadding?: number\n\n /**\n * Height of the knob in pixels.\n */\n knobHeight?: number\n\n /**\n * Width of the knob in pixels.\n */\n knobWidth?: number\n\n /**\n * Orientation of the slider.\n */\n orientation?: 'horizontal' | 'vertical'\n\n /**\n * An array of step descriptors. A step is a position (0 - 1 inclusive) on the track where the\n * knob should snap to if dragging stops near it. Ensure that there are at least two steps: one\n * for the start of the track and one for the end.\n */\n steps?: readonly number[]\n\n /**\n * The current index.\n */\n index?: number\n\n /**\n * Handler invoked when index changes. This can either be invoked from the `index` prop\n * being changed or from the slider being dragged. Note that if the event is emitted at the end of\n * dragging due to `onlyDispatchesOnDragEnd` set to `true`, the `isDragging` parameter here is\n * still `true`. This event is emitted right after `onPositionChange`.\n *\n * @param index - The current slider index.\n * @param isDragging - Specifies if the index change is due to dragging.\n */\n onIndexChange?: (index: number, isDragging: boolean) => void\n\n /**\n * Handler invoked when position changes. This can either be invoked from the `index` prop\n * being changed or from the slider being dragged. Note that if the event is emitted at the end of\n * dragging due to `onlyDispatchesOnDragEnd` set to `true`, the `isDragging` parameter here is\n * still `true`. This event is emitted right before `onIndexChange`.\n *\n * @param position - The current slider position.\n * @param isDragging - Specifies if the position change is due to dragging.\n */\n onPositionChange?: (position: number, isDragging: boolean) => void\n\n /**\n * Handler invoked when dragging ends.\n */\n onDragEnd?: () => void\n\n /**\n * Handler invoked when dragging begins.\n */\n onDragStart?: () => void\n\n /**\n * Custom CSS provided to the track before the knob.\n */\n cssStartingTrack?: CSSProp<any>\n\n /**\n * Custom CSS provided to the track after the knob.\n */\n cssEndingTrack?: CSSProp<any>\n\n /**\n * Custom CSS provided to the knob.\n */\n cssKnob?: CSSProp<any>\n\n /**\n * Custom CSS provided to the label inside the knob.\n */\n cssLabel?: CSSProp<any>\n}\n\n/**\n * Generates a set of steps compatible with this component.\n *\n * @param length - The number of steps. This must be at least 2 because you must include the\n * starting and ending points.\n *\n * @returns An array of steps.\n */\nexport function generateSteps(length: number): readonly number[] {\n if (length <= 1) throw new Error('`length` value must be greater than or equal to 2')\n if (Math.round(length) !== length) throw new Error('`length` value must be an integer')\n\n const interval = 1 / (length - 1)\n\n return Array(length).fill(null).map((v, i) => {\n const position = interval * i\n return position\n })\n}\n\n/**\n * Gets the index of the step of which the specified position is closest to. If for whatever\n * reason the index cannot be computed, -1 is returned.\n *\n * @param position - The position (0 - 1, inclusive).\n * @param steps - The steps.\n *\n * @returns The nearest index.\n */\nfunction getNearestIndexByPosition(position: number, steps: readonly number[]): number {\n let index = -1\n let minDelta = NaN\n\n for (let i = 0, n = steps.length; i < n; i++) {\n const step = getPositionAt(i, steps)\n\n if (isNaN(step)) continue\n\n const delta = Math.abs(position - step)\n\n if (isNaN(minDelta) || (delta < minDelta)) {\n minDelta = delta\n index = i\n }\n }\n\n return index\n}\n\n/**\n * Gets the position by step index. This value ranges between 0 - 1, inclusive.\n *\n * @param index - The step index.\n * @param steps - The steps.\n *\n * @returns The position. If for whatever reason the position cannot be determined, `NaN` is\n * returned.\n */\nfunction getPositionAt(index: number, steps: readonly number[]): number {\n if (index >= steps.length) return NaN\n return steps[index]\n}\n\n/**\n * A \"stepwise\" slider component supporting both horizontal and vertical orientations that\n * automatically snaps to a set of predefined points on the slider when dragged. These points are\n * referred to as \"steps\", indexed by an integer referred to as \"index\". This index can be two-way\n * binded. The component consists of four customizable elements: a draggable knob, a label on the\n * knob, a scroll track before the knob and a scroll track after the knob. While the width and\n * height of the slider is inferred from its CSS rules, the width and height of the knob are set via\n * props (`knobWidth` and `knobHeight`, respectively). The size of the knob does not impact the size\n * of the slider. While dragging, the slider still emits a position change event, where the position\n * is a decimal ranging between 0.0 and 1.0, inclusive.\n */\nexport default function StepwiseSlider({\n id,\n className,\n isInverted = false,\n onlyDispatchesOnDragEnd = false,\n trackPadding = 0,\n knobHeight = 30,\n knobWidth = 30,\n orientation = 'vertical',\n labelProvider,\n steps = generateSteps(10),\n index: externalIndex = 0,\n onIndexChange,\n onPositionChange,\n onDragEnd,\n onDragStart,\n cssStartingTrack,\n cssEndingTrack,\n cssKnob,\n cssLabel,\n ...props\n}: Props) {\n function transform(currentPosition: number, dx: number, dy: number) {\n const rect = Rect.from(rootRef.current) ?? new Rect()\n const naturalPosition = isInverted ? 1 - currentPosition : currentPosition\n const naturalNewPositionX = naturalPosition * rect.width + dx\n const naturalNewPositionY = naturalPosition * rect.height + dy\n const naturalNewPosition = (orientation === 'vertical') ? Math.max(0, Math.min(1, naturalNewPositionY / rect.height)) : Math.max(0, Math.min(1, naturalNewPositionX / rect.width))\n const newPosition = isInverted ? 1 - naturalNewPosition : naturalNewPosition\n return newPosition\n }\n\n const rootRef = useRef<HTMLDivElement>(null)\n const knobRef = useRef<HTMLButtonElement>(null)\n\n const [index, setIndex] = useState(externalIndex)\n\n const { isDragging: [isDragging], value: [position, setPosition] } = useDragEffect(knobRef, {\n initialValue: getPositionAt(externalIndex, steps),\n transform,\n onDragStart,\n onDragEnd,\n })\n\n const naturalPosition = isInverted ? 1 - position : position\n\n useEffect(() => {\n if (isDragging) return\n\n const newPosition = getPositionAt(externalIndex, steps)\n\n if (position !== newPosition) {\n debug('Updating drag effect value from index prop...', 'OK', `prop=${newPosition}, effect=${position}`)\n setPosition(newPosition)\n }\n\n if (externalIndex !== index) {\n setIndex(externalIndex)\n }\n }, [externalIndex])\n\n useEffect(() => {\n if (isDragging && onlyDispatchesOnDragEnd) return\n\n onPositionChange?.(position, isDragging)\n\n const newIndex = getNearestIndexByPosition(position, steps)\n if (index !== newIndex) setIndex(newIndex)\n }, [position])\n\n useEffect(() => {\n onIndexChange?.(index, isDragging)\n }, [index])\n\n useEffect(() => {\n if (isDragging) return\n\n const nearestIndex = getNearestIndexByPosition(position, steps)\n const nearestPosition = getPositionAt(nearestIndex, steps)\n\n if (nearestPosition !== position || onlyDispatchesOnDragEnd) {\n setPosition(nearestPosition)\n onPositionChange?.(nearestPosition, true)\n }\n }, [isDragging])\n\n return (\n <StyledRoot ref={rootRef} orientation={orientation} {...props}>\n <StyledTrack orientation={orientation} css={cssStartingTrack}\n style={orientation === 'vertical' ? {\n top: 0,\n height: `calc(${naturalPosition*100}% - ${knobHeight*.5}px - ${trackPadding}px)`,\n } : {\n left: 0,\n width: `calc(${naturalPosition*100}% - ${knobWidth*.5}px - ${trackPadding}px)`,\n }}\n />\n <StyledKnobContainer ref={knobRef} style={{\n transform: 'translate3d(-50%, -50%, 0)',\n ...(orientation === 'vertical' ? {\n left: '50%',\n top: `${naturalPosition*100}%`,\n transition: isDragging === false ? 'top 100ms ease-out' : 'none',\n } : {\n left: `${naturalPosition*100}%`,\n top: '50%',\n transition: isDragging === false ? 'left 100ms ease-out' : 'none',\n }),\n }}>\n <StyledKnob\n className={classNames({\n 'at-end': isInverted ? (position === 0) : (position === 1),\n 'at-start': isInverted ? (position === 1) : (position === 0),\n 'dragging': isDragging,\n })}\n css={cssKnob}\n style={{\n height: `${knobHeight}px`,\n width: `${knobWidth}px`,\n }}\n >\n {steps && labelProvider && (\n <StyledLabel knobHeight={knobHeight} css={cssLabel}>{labelProvider(position, getNearestIndexByPosition(position, steps))}</StyledLabel>\n )}\n </StyledKnob>\n </StyledKnobContainer>\n <StyledTrack orientation={orientation} css={cssEndingTrack}\n style={orientation === 'vertical' ? {\n bottom: 0,\n height: `calc(${(1 - naturalPosition)*100}% - ${knobHeight*.5}px - ${trackPadding}px)`,\n } : {\n right: 0,\n width: `calc(${(1 - naturalPosition)*100}% - ${knobWidth*.5}px - ${trackPadding}px)`,\n }}\n />\n </StyledRoot>\n )\n}\n\nconst StyledTrack = styled.div<{ orientation: NonNullable<Props['orientation']> }>`\n background: #fff;\n position: absolute;\n\n ${props => props.orientation === 'vertical' ? css`\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n ` : css`\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n `}\n\n ${props => props.css}\n`\n\nconst StyledLabel = styled.label<{ knobHeight: NonNullable<Props['knobHeight']> }>`\n color: #000;\n font-size: ${props => props.knobHeight * .5}px;\n pointer-events: none;\n user-select: none;\n\n ${props => props.css}\n`\n\nconst StyledKnobContainer = styled.button`\n position: absolute;\n z-index: 1;\n`\n\nconst StyledKnob = styled.div`\n align-items: center;\n background: #fff;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n justify-content: center;\n opacity: 1;\n touch-action: none;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n ${props => props.css}\n`\n\nconst StyledRoot = styled.div<{\n orientation: Props['orientation']\n}>`\n box-sizing: border-box;\n display: block;\n height: ${props => props.orientation === 'vertical' ? '300px' : '4px'};\n position: relative;\n width: ${props => props.orientation === 'vertical' ? '4px' : '300px'};\n`\n"]}
|
|
1
|
+
{"version":3,"file":"StepwiseSlider.js","sourceRoot":"/","sources":["StepwiseSlider.tsx"],"names":[],"mappings":"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","sourcesContent":["import classNames from 'classnames'\nimport React, { HTMLAttributes, MouseEvent, useEffect, useRef, useState } from 'react'\nimport { Rect } from 'spase'\nimport styled, { css, CSSProp } from 'styled-components'\nimport useDragEffect from './hooks/useDragEffect'\n\nconst debug = process.env.NODE_ENV === 'development' ? require('debug')('etudes:stepwise-slider') : () => {}\n\nexport type Props = HTMLAttributes<HTMLDivElement> & {\n /**\n * By default the position is a value from 0 - 1, 0 being the start of the slider and 1 being the\n * end. Switching on this flag inverts this behavior, where 0 becomes the end of the slider and 1\n * being the start.\n */\n isInverted?: boolean\n\n /**\n * Specifies if the track is clickable to set the position of the knob.\n */\n isTrackInteractive?: boolean\n\n /**\n * Indicates if position/index change events are dispatched only when dragging ends. When\n * disabled, aforementioned events are fired repeatedly while dragging.\n */\n onlyDispatchesOnDragEnd?: boolean\n\n /**\n * A function that returns the label to be displayed at a given slider position and closest step\n * index (if steps are provided).\n *\n * @param position - The current slider position.\n * @param index - The nearest step index (if steps are provided), or -1 if no steps are provided.\n *\n * @returns The label.\n */\n labelProvider?: (position: number, index: number) => string\n\n /**\n * Padding between the track and the knob in pixels.\n */\n trackPadding?: number\n\n /**\n * Height of the knob in pixels.\n */\n knobHeight?: number\n\n /**\n * Width of the knob in pixels.\n */\n knobWidth?: number\n\n /**\n * Orientation of the slider.\n */\n orientation?: 'horizontal' | 'vertical'\n\n /**\n * An array of step descriptors. A step is a position (0 - 1 inclusive) on the track where the\n * knob should snap to if dragging stops near it. Ensure that there are at least two steps: one\n * for the start of the track and one for the end.\n */\n steps?: readonly number[]\n\n /**\n * The current index.\n */\n index?: number\n\n /**\n * Handler invoked when index changes. This can either be invoked from the `index` prop\n * being changed or from the slider being dragged. Note that if the event is emitted at the end of\n * dragging due to `onlyDispatchesOnDragEnd` set to `true`, the `isDragging` parameter here is\n * still `true`. This event is emitted right after `onPositionChange`.\n *\n * @param index - The current slider index.\n * @param isDragging - Specifies if the index change is due to dragging.\n */\n onIndexChange?: (index: number, isDragging: boolean) => void\n\n /**\n * Handler invoked when position changes. This can either be invoked from the `index` prop\n * being changed or from the slider being dragged. Note that if the event is emitted at the end of\n * dragging due to `onlyDispatchesOnDragEnd` set to `true`, the `isDragging` parameter here is\n * still `true`. This event is emitted right before `onIndexChange`.\n *\n * @param position - The current slider position.\n * @param isDragging - Specifies if the position change is due to dragging.\n */\n onPositionChange?: (position: number, isDragging: boolean) => void\n\n /**\n * Handler invoked when dragging ends.\n */\n onDragEnd?: () => void\n\n /**\n * Handler invoked when dragging begins.\n */\n onDragStart?: () => void\n\n /**\n * Custom CSS provided to the track before the knob.\n */\n cssStartingTrack?: CSSProp<any>\n\n /**\n * Custom CSS provided to the track after the knob.\n */\n cssEndingTrack?: CSSProp<any>\n\n /**\n * Custom CSS provided to the knob.\n */\n cssKnob?: CSSProp<any>\n\n /**\n * Custom CSS provided to the label inside the knob.\n */\n cssLabel?: CSSProp<any>\n}\n\n/**\n * Generates a set of steps compatible with this component.\n *\n * @param length - The number of steps. This must be at least 2 because you must include the\n * starting and ending points.\n *\n * @returns An array of steps.\n */\nexport function generateSteps(length: number): readonly number[] {\n if (length <= 1) throw new Error('`length` value must be greater than or equal to 2')\n if (Math.round(length) !== length) throw new Error('`length` value must be an integer')\n\n const interval = 1 / (length - 1)\n\n return Array(length).fill(null).map((v, i) => {\n const position = interval * i\n return position\n })\n}\n\n/**\n * Gets the index of the step of which the specified position is closest to. If for whatever\n * reason the index cannot be computed, -1 is returned.\n *\n * @param position - The position (0 - 1, inclusive).\n * @param steps - The steps.\n *\n * @returns The nearest index.\n */\nfunction getNearestIndexByPosition(position: number, steps: readonly number[]): number {\n let index = -1\n let minDelta = NaN\n\n for (let i = 0, n = steps.length; i < n; i++) {\n const step = getPositionAt(i, steps)\n\n if (isNaN(step)) continue\n\n const delta = Math.abs(position - step)\n\n if (isNaN(minDelta) || (delta < minDelta)) {\n minDelta = delta\n index = i\n }\n }\n\n return index\n}\n\n/**\n * Gets the position by step index. This value ranges between 0 - 1, inclusive.\n *\n * @param index - The step index.\n * @param steps - The steps.\n *\n * @returns The position. If for whatever reason the position cannot be determined, `NaN` is\n * returned.\n */\nfunction getPositionAt(index: number, steps: readonly number[]): number {\n if (index >= steps.length) return NaN\n return steps[index]\n}\n\n/**\n * A \"stepwise\" slider component supporting both horizontal and vertical orientations that\n * automatically snaps to a set of predefined points on the slider when dragged. These points are\n * referred to as \"steps\", indexed by an integer referred to as \"index\". This index can be two-way\n * binded. The component consists of four customizable elements: a draggable knob, a label on the\n * knob, a scroll track before the knob and a scroll track after the knob. While the width and\n * height of the slider is inferred from its CSS rules, the width and height of the knob are set via\n * props (`knobWidth` and `knobHeight`, respectively). The size of the knob does not impact the size\n * of the slider. While dragging, the slider still emits a position change event, where the position\n * is a decimal ranging between 0.0 and 1.0, inclusive.\n */\nexport default function StepwiseSlider({\n id,\n className,\n isInverted = false,\n isTrackInteractive = true,\n onlyDispatchesOnDragEnd = false,\n trackPadding = 0,\n knobHeight = 30,\n knobWidth = 30,\n orientation = 'vertical',\n labelProvider,\n steps = generateSteps(10),\n index: externalIndex = 0,\n onIndexChange,\n onPositionChange,\n onDragEnd,\n onDragStart,\n cssStartingTrack,\n cssEndingTrack,\n cssKnob,\n cssLabel,\n ...props\n}: Props) {\n function transform(currentPosition: number, dx: number, dy: number) {\n const rect = Rect.from(rootRef.current) ?? new Rect()\n const naturalPosition = isInverted ? 1 - currentPosition : currentPosition\n const naturalNewPositionX = naturalPosition * rect.width + dx\n const naturalNewPositionY = naturalPosition * rect.height + dy\n const naturalNewPosition = (orientation === 'vertical') ? Math.max(0, Math.min(1, naturalNewPositionY / rect.height)) : Math.max(0, Math.min(1, naturalNewPositionX / rect.width))\n const newPosition = isInverted ? 1 - naturalNewPosition : naturalNewPosition\n return newPosition\n }\n\n function onTrackClick(event: MouseEvent) {\n if (!isTrackInteractive) return\n\n const rect = Rect.from(rootRef.current) ?? new Rect()\n\n switch (orientation) {\n case 'horizontal': {\n const position = (event.clientX - rect.left) / rect.width\n const naturalPosition = isInverted ? 1 - position : position\n setPosition(naturalPosition)\n break\n }\n case 'vertical': {\n const position = (event.clientY - rect.top) / rect.height\n const naturalPosition = isInverted ? 1 - position : position\n setPosition(naturalPosition)\n break\n }\n }\n }\n\n const rootRef = useRef<HTMLDivElement>(null)\n const knobRef = useRef<HTMLButtonElement>(null)\n\n const [index, setIndex] = useState(externalIndex)\n\n const { isDragging: [isDragging], value: [position, setPosition] } = useDragEffect(knobRef, {\n initialValue: getPositionAt(externalIndex, steps),\n transform,\n onDragStart,\n onDragEnd,\n })\n\n // Natural position is the position after taking `isInverted` into account.\n const naturalPosition = isInverted ? 1 - position : position\n\n useEffect(() => {\n if (isDragging) return\n\n const newPosition = getPositionAt(externalIndex, steps)\n\n if (position !== newPosition) {\n debug('Updating drag effect value from index prop...', 'OK', `prop=${newPosition}, effect=${position}`)\n setPosition(newPosition)\n }\n\n if (externalIndex !== index) {\n setIndex(externalIndex)\n }\n }, [externalIndex])\n\n useEffect(() => {\n if (isDragging && onlyDispatchesOnDragEnd) return\n\n onPositionChange?.(position, isDragging)\n\n const newIndex = getNearestIndexByPosition(position, steps)\n if (index !== newIndex) setIndex(newIndex)\n }, [position])\n\n useEffect(() => {\n onIndexChange?.(index, isDragging)\n }, [index])\n\n useEffect(() => {\n if (isDragging) return\n\n const nearestIndex = getNearestIndexByPosition(position, steps)\n const nearestPosition = getPositionAt(nearestIndex, steps)\n\n if (nearestPosition !== position || onlyDispatchesOnDragEnd) {\n setPosition(nearestPosition)\n onPositionChange?.(nearestPosition, true)\n }\n }, [isDragging])\n\n return (\n <StyledRoot ref={rootRef} orientation={orientation} {...props}>\n <StyledStartingTrack orientation={orientation} isClickable={isTrackInteractive} css={cssStartingTrack} onClick={event => onTrackClick(event)}\n style={orientation === 'vertical' ? {\n top: 0,\n height: `calc(${naturalPosition*100}% - ${knobHeight*.5}px - ${trackPadding}px)`,\n } : {\n left: 0,\n width: `calc(${naturalPosition*100}% - ${knobWidth*.5}px - ${trackPadding}px)`,\n }}\n />\n <StyledKnobContainer ref={knobRef} style={{\n transform: 'translate3d(-50%, -50%, 0)',\n ...(orientation === 'vertical' ? {\n left: '50%',\n top: `${naturalPosition*100}%`,\n transition: isDragging === false ? 'top 100ms ease-out' : 'none',\n } : {\n left: `${naturalPosition*100}%`,\n top: '50%',\n transition: isDragging === false ? 'left 100ms ease-out' : 'none',\n }),\n }}>\n <StyledKnob\n className={classNames({\n 'at-end': isInverted ? (position === 0) : (position === 1),\n 'at-start': isInverted ? (position === 1) : (position === 0),\n 'dragging': isDragging,\n })}\n css={cssKnob}\n style={{\n height: `${knobHeight}px`,\n width: `${knobWidth}px`,\n }}\n >\n {steps && labelProvider && (\n <StyledLabel knobHeight={knobHeight} css={cssLabel}>{labelProvider(position, getNearestIndexByPosition(position, steps))}</StyledLabel>\n )}\n </StyledKnob>\n </StyledKnobContainer>\n <StyledEndingTrack orientation={orientation} isClickable={isTrackInteractive} css={cssEndingTrack} onClick={event => onTrackClick(event)}\n style={orientation === 'vertical' ? {\n bottom: 0,\n height: `calc(${(1 - naturalPosition)*100}% - ${knobHeight*.5}px - ${trackPadding}px)`,\n } : {\n right: 0,\n width: `calc(${(1 - naturalPosition)*100}% - ${knobWidth*.5}px - ${trackPadding}px)`,\n }}\n />\n </StyledRoot>\n )\n}\n\nconst StyledStartingTrack = styled.div<{\n orientation: NonNullable<Props['orientation']>\n isClickable: boolean\n}>`\n background: #fff;\n cursor: ${props => props.isClickable ? 'pointer' : 'auto' };\n pointer-events: ${props => props.isClickable ? 'auto' : 'none' };\n position: absolute;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n &::after {\n content: '';\n height: 100%;\n min-height: 20px;\n min-width: 20px;\n position: absolute;\n transform: ${props => props.orientation === 'horizontal' ? 'translate3d(0, -50%, 0)' : 'translate3d(-50%, 0, 0)'};\n width: 100%;\n }\n\n ${props => props.orientation === 'vertical' ? css`\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n ` : css`\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n `}\n\n ${props => props.css}\n`\n\nconst StyledEndingTrack = styled.div<{\n orientation: NonNullable<Props['orientation']>\n isClickable: boolean\n}>`\n background: #fff;\n cursor: ${props => props.isClickable ? 'pointer' : 'auto' };\n pointer-events: ${props => props.isClickable ? 'auto' : 'none' };\n position: absolute;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n &::after {\n content: '';\n height: 100%;\n min-height: 20px;\n min-width: 20px;\n position: absolute;\n transform: ${props => props.orientation === 'horizontal' ? 'translate3d(0, -50%, 0)' : 'translate3d(-50%, 0, 0)'};\n width: 100%;\n }\n\n ${props => props.orientation === 'vertical' ? css`\n left: 0;\n margin: 0 auto;\n right: 0;\n width: 100%;\n ` : css`\n bottom: 0;\n height: 100%;\n margin: auto 0;\n top: 0;\n `}\n\n ${props => props.css}\n`\n\nconst StyledLabel = styled.label<{ knobHeight: NonNullable<Props['knobHeight']> }>`\n color: #000;\n font-size: ${props => props.knobHeight * .5}px;\n pointer-events: none;\n user-select: none;\n\n ${props => props.css}\n`\n\nconst StyledKnobContainer = styled.button`\n position: absolute;\n z-index: 1;\n`\n\nconst StyledKnob = styled.div`\n align-items: center;\n background: #fff;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n justify-content: center;\n opacity: 1;\n touch-action: none;\n transition-duration: 100ms;\n transition-property: background, color, opacity, transform;\n transition-timing-function: ease-out;\n\n ${props => props.css}\n`\n\nconst StyledRoot = styled.div<{\n orientation: Props['orientation']\n}>`\n box-sizing: border-box;\n display: block;\n height: ${props => props.orientation === 'vertical' ? '300px' : '4px'};\n position: relative;\n width: ${props => props.orientation === 'vertical' ? '4px' : '300px'};\n`\n"]}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { HTMLAttributes, PropsWithChildren } from 'react';
|
|
2
|
+
import { CSSProp } from 'styled-components';
|
|
3
|
+
declare type Props = PropsWithChildren<HTMLAttributes<HTMLElement>> & {
|
|
4
|
+
/**
|
|
5
|
+
* The height of the arrow. The width (longest edge) of the arrow is always twice its height.
|
|
6
|
+
*/
|
|
7
|
+
arrowHeight?: number;
|
|
8
|
+
/**
|
|
9
|
+
* Color of the dialog background, same format as a CSS color string (i.e. '#000').
|
|
10
|
+
*/
|
|
11
|
+
backgroundColor?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Specifies if the tooltip should be disabled in touch devices (i.e. `html` has class `.touch`).
|
|
14
|
+
*/
|
|
15
|
+
disabledOnTouch?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* The offset (in pixels) between the target element and the tooltip, defaults to zero.
|
|
18
|
+
*/
|
|
19
|
+
offset?: number;
|
|
20
|
+
/**
|
|
21
|
+
* The hint string to display in the tooltip.
|
|
22
|
+
*/
|
|
23
|
+
hint: string;
|
|
24
|
+
/**
|
|
25
|
+
* Color of the dialog text, same format as a CSS color string (i.e. '#000').
|
|
26
|
+
*/
|
|
27
|
+
textColor?: string;
|
|
28
|
+
/**
|
|
29
|
+
* The minimum space (in pixels) between the target element and the edge of the window required to
|
|
30
|
+
* trigger an alignment change, defaults to `100px`.
|
|
31
|
+
*/
|
|
32
|
+
threshold?: number;
|
|
33
|
+
/**
|
|
34
|
+
* Custom CSS provided to the dialog. Not all CSS rules will take effect as they will be
|
|
35
|
+
* overridden by internal rules.
|
|
36
|
+
*/
|
|
37
|
+
cssDialog?: CSSProp<any>;
|
|
38
|
+
};
|
|
39
|
+
export default function WithTooltip({ arrowHeight, backgroundColor, cssDialog, disabledOnTouch, hint, offset, textColor, threshold, ...props }: Props): JSX.Element;
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
|
|
3
|
+
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
|
|
4
|
+
return cooked;
|
|
5
|
+
};
|
|
6
|
+
var __assign = (this && this.__assign) || function () {
|
|
7
|
+
__assign = Object.assign || function(t) {
|
|
8
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
9
|
+
s = arguments[i];
|
|
10
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
11
|
+
t[p] = s[p];
|
|
12
|
+
}
|
|
13
|
+
return t;
|
|
14
|
+
};
|
|
15
|
+
return __assign.apply(this, arguments);
|
|
16
|
+
};
|
|
17
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
20
|
+
}) : (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
o[k2] = m[k];
|
|
23
|
+
}));
|
|
24
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
25
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
26
|
+
}) : function(o, v) {
|
|
27
|
+
o["default"] = v;
|
|
28
|
+
});
|
|
29
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
30
|
+
if (mod && mod.__esModule) return mod;
|
|
31
|
+
var result = {};
|
|
32
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
33
|
+
__setModuleDefault(result, mod);
|
|
34
|
+
return result;
|
|
35
|
+
};
|
|
36
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
37
|
+
var t = {};
|
|
38
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
39
|
+
t[p] = s[p];
|
|
40
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
41
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
42
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
43
|
+
t[p[i]] = s[p[i]];
|
|
44
|
+
}
|
|
45
|
+
return t;
|
|
46
|
+
};
|
|
47
|
+
var __read = (this && this.__read) || function (o, n) {
|
|
48
|
+
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
49
|
+
if (!m) return o;
|
|
50
|
+
var i = m.call(o), r, ar = [], e;
|
|
51
|
+
try {
|
|
52
|
+
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
53
|
+
}
|
|
54
|
+
catch (error) { e = { error: error }; }
|
|
55
|
+
finally {
|
|
56
|
+
try {
|
|
57
|
+
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
58
|
+
}
|
|
59
|
+
finally { if (e) throw e.error; }
|
|
60
|
+
}
|
|
61
|
+
return ar;
|
|
62
|
+
};
|
|
63
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
64
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
65
|
+
};
|
|
66
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
67
|
+
var react_1 = __importStar(require("react"));
|
|
68
|
+
var spase_1 = require("spase");
|
|
69
|
+
var styled_components_1 = __importStar(require("styled-components"));
|
|
70
|
+
var ExtractChildren_1 = __importDefault(require("./ExtractChildren"));
|
|
71
|
+
function WithTooltip(_a) {
|
|
72
|
+
var _b = _a.arrowHeight, arrowHeight = _b === void 0 ? 8 : _b, _c = _a.backgroundColor, backgroundColor = _c === void 0 ? '#000' : _c, cssDialog = _a.cssDialog, _d = _a.disabledOnTouch, disabledOnTouch = _d === void 0 ? true : _d, hint = _a.hint, _e = _a.offset, offset = _e === void 0 ? 5 : _e, _f = _a.textColor, textColor = _f === void 0 ? '#fff' : _f, _g = _a.threshold, threshold = _g === void 0 ? 100 : _g, props = __rest(_a, ["arrowHeight", "backgroundColor", "cssDialog", "disabledOnTouch", "hint", "offset", "textColor", "threshold"]);
|
|
73
|
+
var _h = __read((0, react_1.useState)(new spase_1.Size()), 2), textSize = _h[0], setTextSize = _h[1];
|
|
74
|
+
var _j = __read((0, react_1.useState)('bc'), 2), position = _j[0], setPosition = _j[1];
|
|
75
|
+
function computePosition(target, threshold) {
|
|
76
|
+
var vrect = spase_1.Rect.fromViewport();
|
|
77
|
+
var rect = spase_1.Rect.intersecting(target);
|
|
78
|
+
if (rect) {
|
|
79
|
+
var leftBound = (rect.center.x - vrect.left) < threshold;
|
|
80
|
+
var rightBound = (vrect.center.x - rect.right) < threshold;
|
|
81
|
+
var topBound = (rect.center.y - vrect.top) < threshold;
|
|
82
|
+
var bottomBound = (vrect.center.y - rect.bottom) < threshold;
|
|
83
|
+
if (leftBound && topBound)
|
|
84
|
+
return 'br';
|
|
85
|
+
if (leftBound && bottomBound)
|
|
86
|
+
return 'tr';
|
|
87
|
+
if (rightBound && topBound)
|
|
88
|
+
return 'bl';
|
|
89
|
+
if (rightBound && bottomBound)
|
|
90
|
+
return 'tl';
|
|
91
|
+
if (leftBound)
|
|
92
|
+
return 'cr';
|
|
93
|
+
if (rightBound)
|
|
94
|
+
return 'cl';
|
|
95
|
+
if (bottomBound)
|
|
96
|
+
return 'tc';
|
|
97
|
+
}
|
|
98
|
+
return 'bc';
|
|
99
|
+
}
|
|
100
|
+
function computeTextSize(target) {
|
|
101
|
+
var computedStyle = window.getComputedStyle(target, '::after');
|
|
102
|
+
var div = document.createElement('div');
|
|
103
|
+
div.innerHTML = hint;
|
|
104
|
+
div.style.fontFamily = computedStyle.getPropertyValue('font-family');
|
|
105
|
+
div.style.fontSize = computedStyle.getPropertyValue('font-size');
|
|
106
|
+
div.style.fontStyle = computedStyle.getPropertyValue('font-style');
|
|
107
|
+
div.style.fontVariant = computedStyle.getPropertyValue('font-variant');
|
|
108
|
+
div.style.fontWeight = computedStyle.getPropertyValue('font-weight');
|
|
109
|
+
div.style.height = '30px';
|
|
110
|
+
div.style.left = '0';
|
|
111
|
+
div.style.position = 'absolute';
|
|
112
|
+
div.style.top = '0';
|
|
113
|
+
div.style.visibility = 'hidden';
|
|
114
|
+
div.style.whiteSpace = 'no-wrap';
|
|
115
|
+
document.body.appendChild(div);
|
|
116
|
+
var width = div.clientWidth;
|
|
117
|
+
var height = div.clientHeight;
|
|
118
|
+
document.body.removeChild(div);
|
|
119
|
+
return new spase_1.Size([width, height]);
|
|
120
|
+
}
|
|
121
|
+
function onMouseOver(event) {
|
|
122
|
+
setTextSize(computeTextSize(event.currentTarget));
|
|
123
|
+
setPosition(computePosition(event.currentTarget, threshold));
|
|
124
|
+
}
|
|
125
|
+
return (react_1.default.createElement(StyledRoot, __assign({ position: position, arrowHeight: arrowHeight, backgroundColor: backgroundColor, cssDialog: cssDialog, disabledOnTouch: disabledOnTouch, hint: hint, offset: offset, onMouseOver: function (event) { return onMouseOver(event); }, textColor: textColor, textSize: textSize }, props)));
|
|
126
|
+
}
|
|
127
|
+
exports.default = WithTooltip;
|
|
128
|
+
function _cssDisplacement(position, arrowHeight, offset) {
|
|
129
|
+
switch (position) {
|
|
130
|
+
case 'tl': return (0, styled_components_1.css)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["top: ", "px; left: 100%;"], ["top: ", "px; left: 100%;"])), -arrowHeight);
|
|
131
|
+
case 'tc': return (0, styled_components_1.css)(templateObject_2 || (templateObject_2 = __makeTemplateObject(["top: ", "px; left: 50%;"], ["top: ", "px; left: 50%;"])), -arrowHeight);
|
|
132
|
+
case 'tr': return (0, styled_components_1.css)(templateObject_3 || (templateObject_3 = __makeTemplateObject(["top: ", "px; right: 100%;"], ["top: ", "px; right: 100%;"])), -arrowHeight);
|
|
133
|
+
case 'cl': return (0, styled_components_1.css)(templateObject_4 || (templateObject_4 = __makeTemplateObject(["top: 50%; left: ", "px;"], ["top: 50%; left: ", "px;"])), -arrowHeight);
|
|
134
|
+
case 'cr': return (0, styled_components_1.css)(templateObject_5 || (templateObject_5 = __makeTemplateObject(["top: 50%; right: ", "px;"], ["top: 50%; right: ", "px;"])), -arrowHeight);
|
|
135
|
+
case 'bl': return (0, styled_components_1.css)(templateObject_6 || (templateObject_6 = __makeTemplateObject(["bottom: ", "px; left: 100%;"], ["bottom: ", "px; left: 100%;"])), -arrowHeight);
|
|
136
|
+
case 'bc': return (0, styled_components_1.css)(templateObject_7 || (templateObject_7 = __makeTemplateObject(["bottom: ", "px; left: 50%;"], ["bottom: ", "px; left: 50%;"])), -arrowHeight);
|
|
137
|
+
case 'br': return (0, styled_components_1.css)(templateObject_8 || (templateObject_8 = __makeTemplateObject(["bottom: ", "px; right: 100%;"], ["bottom: ", "px; right: 100%;"])), -arrowHeight);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function _cssDialog(position, arrowHeight, offset) {
|
|
141
|
+
switch (position) {
|
|
142
|
+
case 'tl': return (0, styled_components_1.css)(templateObject_9 || (templateObject_9 = __makeTemplateObject(["transform: translate3d(calc(-100% - ", "px), calc(-100% - ", "px), 0);"], ["transform: translate3d(calc(-100% - ", "px), calc(-100% - ", "px), 0);"])), offset, offset);
|
|
143
|
+
case 'tc': return (0, styled_components_1.css)(templateObject_10 || (templateObject_10 = __makeTemplateObject(["transform: translate3d(-50%, calc(-100% - ", "px), 0);"], ["transform: translate3d(-50%, calc(-100% - ", "px), 0);"])), offset);
|
|
144
|
+
case 'tr': return (0, styled_components_1.css)(templateObject_11 || (templateObject_11 = __makeTemplateObject(["transform: translate3d(calc(100% + ", "px), calc(-100% - ", "px), 0);"], ["transform: translate3d(calc(100% + ", "px), calc(-100% - ", "px), 0);"])), offset, offset);
|
|
145
|
+
case 'cl': return (0, styled_components_1.css)(templateObject_12 || (templateObject_12 = __makeTemplateObject(["transform: translate3d(calc(-100% - ", "px), -50%, 0);"], ["transform: translate3d(calc(-100% - ", "px), -50%, 0);"])), offset);
|
|
146
|
+
case 'cr': return (0, styled_components_1.css)(templateObject_13 || (templateObject_13 = __makeTemplateObject(["transform: translate3d(calc(100% + ", "px), -50%, 0);"], ["transform: translate3d(calc(100% + ", "px), -50%, 0);"])), offset);
|
|
147
|
+
case 'bl': return (0, styled_components_1.css)(templateObject_14 || (templateObject_14 = __makeTemplateObject(["transform: translate3d(calc(-100% - ", "px), calc(100% + ", "px), 0);"], ["transform: translate3d(calc(-100% - ", "px), calc(100% + ", "px), 0);"])), offset, offset);
|
|
148
|
+
case 'bc': return (0, styled_components_1.css)(templateObject_15 || (templateObject_15 = __makeTemplateObject(["transform: translate3d(-50%, calc(100% + ", "px), 0);"], ["transform: translate3d(-50%, calc(100% + ", "px), 0);"])), offset);
|
|
149
|
+
case 'br': return (0, styled_components_1.css)(templateObject_16 || (templateObject_16 = __makeTemplateObject(["transform: translate3d(calc(100% + ", "px), calc(100% + ", "px), 0);"], ["transform: translate3d(calc(100% + ", "px), calc(100% + ", "px), 0);"])), offset, offset);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
function _cssArrow(position, arrowHeight, offset, color) {
|
|
153
|
+
return (0, styled_components_1.css)(templateObject_33 || (templateObject_33 = __makeTemplateObject(["\n ", "\n ", "\n "], ["\n ", "\n ", "\n "])), function () {
|
|
154
|
+
switch (position) {
|
|
155
|
+
case 'tl': return (0, styled_components_1.css)(templateObject_17 || (templateObject_17 = __makeTemplateObject(["border-color: ", " transparent transparent transparent;"], ["border-color: ", " transparent transparent transparent;"])), color);
|
|
156
|
+
case 'tc': return (0, styled_components_1.css)(templateObject_18 || (templateObject_18 = __makeTemplateObject(["border-color: ", " transparent transparent transparent;"], ["border-color: ", " transparent transparent transparent;"])), color);
|
|
157
|
+
case 'tr': return (0, styled_components_1.css)(templateObject_19 || (templateObject_19 = __makeTemplateObject(["border-color: ", " transparent transparent transparent;"], ["border-color: ", " transparent transparent transparent;"])), color);
|
|
158
|
+
case 'cl': return (0, styled_components_1.css)(templateObject_20 || (templateObject_20 = __makeTemplateObject(["border-color: transparent transparent transparent ", ";"], ["border-color: transparent transparent transparent ", ";"])), color);
|
|
159
|
+
case 'cr': return (0, styled_components_1.css)(templateObject_21 || (templateObject_21 = __makeTemplateObject(["border-color: transparent ", " transparent transparent;"], ["border-color: transparent ", " transparent transparent;"])), color);
|
|
160
|
+
case 'bl': return (0, styled_components_1.css)(templateObject_22 || (templateObject_22 = __makeTemplateObject(["border-color: transparent transparent ", " transparent;"], ["border-color: transparent transparent ", " transparent;"])), color);
|
|
161
|
+
case 'bc': return (0, styled_components_1.css)(templateObject_23 || (templateObject_23 = __makeTemplateObject(["border-color: transparent transparent ", " transparent;"], ["border-color: transparent transparent ", " transparent;"])), color);
|
|
162
|
+
case 'br': return (0, styled_components_1.css)(templateObject_24 || (templateObject_24 = __makeTemplateObject(["border-color: transparent transparent ", " transparent;"], ["border-color: transparent transparent ", " transparent;"])), color);
|
|
163
|
+
}
|
|
164
|
+
}, function () {
|
|
165
|
+
switch (position) {
|
|
166
|
+
case 'tl': return (0, styled_components_1.css)(templateObject_25 || (templateObject_25 = __makeTemplateObject(["transform: translate3d(calc(0% - ", "px - ", "px), calc(0% - ", "px), 0);"], ["transform: translate3d(calc(0% - ", "px - ", "px), calc(0% - ", "px), 0);"])), offset, arrowHeight * 3, offset);
|
|
167
|
+
case 'tc': return (0, styled_components_1.css)(templateObject_26 || (templateObject_26 = __makeTemplateObject(["transform: translate3d(-50%, calc(0% - ", "px), 0);"], ["transform: translate3d(-50%, calc(0% - ", "px), 0);"])), offset);
|
|
168
|
+
case 'tr': return (0, styled_components_1.css)(templateObject_27 || (templateObject_27 = __makeTemplateObject(["transform: translate3d(calc(100% + ", "px + ", "px), calc(0% - ", "px), 0);"], ["transform: translate3d(calc(100% + ", "px + ", "px), calc(0% - ", "px), 0);"])), offset, arrowHeight, offset);
|
|
169
|
+
case 'cl': return (0, styled_components_1.css)(templateObject_28 || (templateObject_28 = __makeTemplateObject(["transform: translate3d(calc(0% - ", "px), -50%, 0);"], ["transform: translate3d(calc(0% - ", "px), -50%, 0);"])), offset);
|
|
170
|
+
case 'cr': return (0, styled_components_1.css)(templateObject_29 || (templateObject_29 = __makeTemplateObject(["transform: translate3d(calc(0% + ", "px), -50%, 0);"], ["transform: translate3d(calc(0% + ", "px), -50%, 0);"])), offset);
|
|
171
|
+
case 'bl': return (0, styled_components_1.css)(templateObject_30 || (templateObject_30 = __makeTemplateObject(["transform: translate3d(calc(0% - ", "px - ", "px), calc(0% + ", "px), 0);"], ["transform: translate3d(calc(0% - ", "px - ", "px), calc(0% + ", "px), 0);"])), offset, arrowHeight * 3, offset);
|
|
172
|
+
case 'bc': return (0, styled_components_1.css)(templateObject_31 || (templateObject_31 = __makeTemplateObject(["transform: translate3d(-50%, calc(0% + ", "px), 0);"], ["transform: translate3d(-50%, calc(0% + ", "px), 0);"])), offset);
|
|
173
|
+
case 'br': return (0, styled_components_1.css)(templateObject_32 || (templateObject_32 = __makeTemplateObject(["transform: translate3d(calc(100% + ", "px + ", "px), calc(0% + ", "px), 0);"], ["transform: translate3d(calc(100% + ", "px + ", "px), calc(0% + ", "px), 0);"])), offset, arrowHeight, offset);
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
var StyledRoot = (0, styled_components_1.default)(ExtractChildren_1.default)(templateObject_34 || (templateObject_34 = __makeTemplateObject(["\n cursor: pointer;\n position: relative;\n\n &::before {\n border-style: solid;\n border-width: ", "px;\n content: '';\n height: 0;\n opacity: 0;\n pointer-events: none;\n position: absolute;\n transition: opacity 200ms ease-out;\n width: 0;\n z-index: 10001;\n\n ", "\n ", "\n ", "\n }\n\n &::after {\n box-sizing: content-box;\n font-size: 12px;\n max-width: 240px;\n padding: 10px 14px;\n text-align: left;\n\n ", "\n\n background: ", ";\n color: ", ";\n content: '", "';\n opacity: 0;\n overflow: hidden;\n pointer-events: none;\n position: absolute;\n transform: translate3d(0, 0, 0);\n transition: opacity 200ms ease-out;\n width: ", ";\n z-index: 10000;\n\n ", "\n ", "\n ", "\n }\n\n ", " {\n opacity: 1;\n }\n\n ", " {\n opacity: 1;\n }\n"], ["\n cursor: pointer;\n position: relative;\n\n &::before {\n border-style: solid;\n border-width: ", "px;\n content: '';\n height: 0;\n opacity: 0;\n pointer-events: none;\n position: absolute;\n transition: opacity 200ms ease-out;\n width: 0;\n z-index: 10001;\n\n ", "\n ", "\n ", "\n }\n\n &::after {\n box-sizing: content-box;\n font-size: 12px;\n max-width: 240px;\n padding: 10px 14px;\n text-align: left;\n\n ", "\n\n background: ", ";\n color: ", ";\n content: '", "';\n opacity: 0;\n overflow: hidden;\n pointer-events: none;\n position: absolute;\n transform: translate3d(0, 0, 0);\n transition: opacity 200ms ease-out;\n width: ", ";\n z-index: 10000;\n\n ", "\n ", "\n ", "\n }\n\n ", " {\n opacity: 1;\n }\n\n ", " {\n opacity: 1;\n }\n"])), function (props) { return props.arrowHeight; }, function (props) { return _cssDisplacement(props.position, props.arrowHeight, props.offset); }, function (props) { return _cssArrow(props.position, props.arrowHeight, props.offset, props.backgroundColor); }, function (props) { return props.disabledOnTouch ? 'html.touch & { display: none; }' : ''; }, function (props) { return props.cssDialog; }, function (props) { return props.backgroundColor; }, function (props) { return props.textColor; }, function (props) { return props.hint; }, function (props) { return props.textSize.width > 0 ? props.textSize.width : 'auto'; }, function (props) { return _cssDisplacement(props.position, props.arrowHeight, props.offset); }, function (props) { return _cssDialog(props.position, props.arrowHeight, props.offset); }, function (props) { return props.disabledOnTouch ? 'html.touch & { display: none; }' : ''; }, function (props) { return props.disabledOnTouch ? 'html:not(.touch) &:hover::before' : '&:hover::before'; }, function (props) { return props.disabledOnTouch ? 'html:not(.touch) &:hover::after' : '&:hover::after'; });
|
|
178
|
+
var templateObject_1, templateObject_2, templateObject_3, templateObject_4, templateObject_5, templateObject_6, templateObject_7, templateObject_8, templateObject_9, templateObject_10, templateObject_11, templateObject_12, templateObject_13, templateObject_14, templateObject_15, templateObject_16, templateObject_17, templateObject_18, templateObject_19, templateObject_20, templateObject_21, templateObject_22, templateObject_23, templateObject_24, templateObject_25, templateObject_26, templateObject_27, templateObject_28, templateObject_29, templateObject_30, templateObject_31, templateObject_32, templateObject_33, templateObject_34;
|
|
179
|
+
//# sourceMappingURL=WithTooltip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WithTooltip.js","sourceRoot":"/","sources":["WithTooltip.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { HTMLAttributes, MouseEvent, PropsWithChildren, useState } from 'react'\nimport { Rect, Size } from 'spase'\nimport styled, { css, CSSProp } from 'styled-components'\nimport ExtractChildren from './ExtractChildren'\n\ntype Props = PropsWithChildren<HTMLAttributes<HTMLElement>> & {\n /**\n * The height of the arrow. The width (longest edge) of the arrow is always twice its height.\n */\n arrowHeight?: number\n\n /**\n * Color of the dialog background, same format as a CSS color string (i.e. '#000').\n */\n backgroundColor?: string\n\n /**\n * Specifies if the tooltip should be disabled in touch devices (i.e. `html` has class `.touch`).\n */\n disabledOnTouch?: boolean\n\n /**\n * The offset (in pixels) between the target element and the tooltip, defaults to zero.\n */\n offset?: number\n\n /**\n * The hint string to display in the tooltip.\n */\n hint: string\n\n /**\n * Color of the dialog text, same format as a CSS color string (i.e. '#000').\n */\n textColor?: string\n\n /**\n * The minimum space (in pixels) between the target element and the edge of the window required to\n * trigger an alignment change, defaults to `100px`.\n */\n threshold?: number\n\n /**\n * Custom CSS provided to the dialog. Not all CSS rules will take effect as they will be\n * overridden by internal rules.\n */\n cssDialog?: CSSProp<any>\n}\n\ntype Position = 'tl' | 'tc' | 'tr' | 'cl' | 'cr' | 'bl' | 'bc' | 'br'\n\nexport default function WithTooltip({\n arrowHeight = 8,\n backgroundColor = '#000',\n cssDialog,\n disabledOnTouch = true,\n hint,\n offset = 5,\n textColor = '#fff',\n threshold = 100,\n ...props\n}: Props) {\n const [textSize, setTextSize] = useState<Size>(new Size())\n const [position, setPosition] = useState<Position>('bc')\n\n function computePosition(target: Element, threshold: number): Position {\n const vrect = Rect.fromViewport()\n const rect = Rect.intersecting(target)\n\n if (rect) {\n const leftBound = (rect.center.x - vrect.left) < threshold\n const rightBound = (vrect.center.x - rect.right) < threshold\n const topBound = (rect.center.y - vrect.top) < threshold\n const bottomBound = (vrect.center.y - rect.bottom) < threshold\n\n if (leftBound && topBound) return 'br'\n if (leftBound && bottomBound) return 'tr'\n if (rightBound && topBound) return 'bl'\n if (rightBound && bottomBound) return 'tl'\n if (leftBound) return 'cr'\n if (rightBound) return 'cl'\n if (bottomBound) return 'tc'\n }\n\n return 'bc'\n }\n\n function computeTextSize(target: Element): Size {\n const computedStyle = window.getComputedStyle(target, '::after')\n const div = document.createElement('div')\n div.innerHTML = hint\n div.style.fontFamily = computedStyle.getPropertyValue('font-family')\n div.style.fontSize = computedStyle.getPropertyValue('font-size')\n div.style.fontStyle = computedStyle.getPropertyValue('font-style')\n div.style.fontVariant = computedStyle.getPropertyValue('font-variant')\n div.style.fontWeight = computedStyle.getPropertyValue('font-weight')\n div.style.height = '30px'\n div.style.left = '0'\n div.style.position = 'absolute'\n div.style.top = '0'\n div.style.visibility = 'hidden'\n div.style.whiteSpace = 'no-wrap'\n\n document.body.appendChild(div)\n const width = div.clientWidth\n const height = div.clientHeight\n document.body.removeChild(div)\n\n return new Size([width, height])\n }\n\n function onMouseOver(event: MouseEvent) {\n setTextSize(computeTextSize(event.currentTarget))\n setPosition(computePosition(event.currentTarget, threshold))\n }\n\n return (\n <StyledRoot\n position={position}\n arrowHeight={arrowHeight}\n backgroundColor={backgroundColor}\n cssDialog={cssDialog}\n disabledOnTouch={disabledOnTouch}\n hint={hint}\n offset={offset}\n onMouseOver={event => onMouseOver(event)}\n textColor={textColor}\n textSize={textSize}\n {...props}\n />\n )\n}\n\nfunction _cssDisplacement(position: Position, arrowHeight: number, offset: number): CSSProp {\n switch (position) {\n case 'tl': return css`top: ${-arrowHeight}px; left: 100%;`\n case 'tc': return css`top: ${-arrowHeight}px; left: 50%;`\n case 'tr': return css`top: ${-arrowHeight}px; right: 100%;`\n case 'cl': return css`top: 50%; left: ${-arrowHeight}px;`\n case 'cr': return css`top: 50%; right: ${-arrowHeight}px;`\n case 'bl': return css`bottom: ${-arrowHeight}px; left: 100%;`\n case 'bc': return css`bottom: ${-arrowHeight}px; left: 50%;`\n case 'br': return css`bottom: ${-arrowHeight}px; right: 100%;`\n }\n}\n\nfunction _cssDialog(position: Position, arrowHeight: number, offset: number): CSSProp {\n switch (position) {\n case 'tl': return css`transform: translate3d(calc(-100% - ${offset}px), calc(-100% - ${offset}px), 0);`\n case 'tc': return css`transform: translate3d(-50%, calc(-100% - ${offset}px), 0);`\n case 'tr': return css`transform: translate3d(calc(100% + ${offset}px), calc(-100% - ${offset}px), 0);`\n case 'cl': return css`transform: translate3d(calc(-100% - ${offset}px), -50%, 0);`\n case 'cr': return css`transform: translate3d(calc(100% + ${offset}px), -50%, 0);`\n case 'bl': return css`transform: translate3d(calc(-100% - ${offset}px), calc(100% + ${offset}px), 0);`\n case 'bc': return css`transform: translate3d(-50%, calc(100% + ${offset}px), 0);`\n case 'br': return css`transform: translate3d(calc(100% + ${offset}px), calc(100% + ${offset}px), 0);`\n }\n}\n\nfunction _cssArrow(position: Position, arrowHeight: number, offset: number, color: string): CSSProp {\n return css`\n ${() => {\n switch (position) {\n case 'tl': return css`border-color: ${color} transparent transparent transparent;`\n case 'tc': return css`border-color: ${color} transparent transparent transparent;`\n case 'tr': return css`border-color: ${color} transparent transparent transparent;`\n case 'cl': return css`border-color: transparent transparent transparent ${color};`\n case 'cr': return css`border-color: transparent ${color} transparent transparent;`\n case 'bl': return css`border-color: transparent transparent ${color} transparent;`\n case 'bc': return css`border-color: transparent transparent ${color} transparent;`\n case 'br': return css`border-color: transparent transparent ${color} transparent;`\n }\n }}\n ${() => {\n switch (position) {\n case 'tl': return css`transform: translate3d(calc(0% - ${offset}px - ${arrowHeight*3}px), calc(0% - ${offset}px), 0);`\n case 'tc': return css`transform: translate3d(-50%, calc(0% - ${offset}px), 0);`\n case 'tr': return css`transform: translate3d(calc(100% + ${offset}px + ${arrowHeight}px), calc(0% - ${offset}px), 0);`\n case 'cl': return css`transform: translate3d(calc(0% - ${offset}px), -50%, 0);`\n case 'cr': return css`transform: translate3d(calc(0% + ${offset}px), -50%, 0);`\n case 'bl': return css`transform: translate3d(calc(0% - ${offset}px - ${arrowHeight*3}px), calc(0% + ${offset}px), 0);`\n case 'bc': return css`transform: translate3d(-50%, calc(0% + ${offset}px), 0);`\n case 'br': return css`transform: translate3d(calc(100% + ${offset}px + ${arrowHeight}px), calc(0% + ${offset}px), 0);`\n }\n }}\n `\n}\n\nconst StyledRoot = styled(ExtractChildren)<{\n arrowHeight: number\n backgroundColor: string\n cssDialog?: CSSProp\n disabledOnTouch: boolean\n hint: string\n offset: number\n position: Position\n textColor: string\n textSize: Size\n}>`\n cursor: pointer;\n position: relative;\n\n &::before {\n border-style: solid;\n border-width: ${props => props.arrowHeight}px;\n content: '';\n height: 0;\n opacity: 0;\n pointer-events: none;\n position: absolute;\n transition: opacity 200ms ease-out;\n width: 0;\n z-index: 10001;\n\n ${props => _cssDisplacement(props.position, props.arrowHeight, props.offset)}\n ${props => _cssArrow(props.position, props.arrowHeight, props.offset, props.backgroundColor)}\n ${props => props.disabledOnTouch ? 'html.touch & { display: none; }' : ''}\n }\n\n &::after {\n box-sizing: content-box;\n font-size: 12px;\n max-width: 240px;\n padding: 10px 14px;\n text-align: left;\n\n ${props => props.cssDialog}\n\n background: ${props => props.backgroundColor};\n color: ${props => props.textColor};\n content: '${props => props.hint}';\n opacity: 0;\n overflow: hidden;\n pointer-events: none;\n position: absolute;\n transform: translate3d(0, 0, 0);\n transition: opacity 200ms ease-out;\n width: ${props => props.textSize.width > 0 ? props.textSize.width : 'auto'};\n z-index: 10000;\n\n ${props => _cssDisplacement(props.position, props.arrowHeight, props.offset)}\n ${props => _cssDialog(props.position, props.arrowHeight, props.offset)}\n ${props => props.disabledOnTouch ? 'html.touch & { display: none; }' : ''}\n }\n\n ${props => props.disabledOnTouch ? 'html:not(.touch) &:hover::before' : '&:hover::before'} {\n opacity: 1;\n }\n\n ${props => props.disabledOnTouch ? 'html:not(.touch) &:hover::after' : '&:hover::after'} {\n opacity: 1;\n }\n`\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "etudes",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.45.0",
|
|
4
4
|
"description": "A study of styled React components",
|
|
5
5
|
"main": "lib",
|
|
6
6
|
"scripts": {
|
|
@@ -29,31 +29,31 @@
|
|
|
29
29
|
"lib"
|
|
30
30
|
],
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@babel/core": "^7.16.
|
|
33
|
-
"@babel/plugin-proposal-class-properties": "^7.16.
|
|
34
|
-
"@babel/plugin-proposal-decorators": "^7.16.
|
|
35
|
-
"@babel/plugin-transform-runtime": "^7.16.
|
|
36
|
-
"@babel/preset-env": "^7.16.
|
|
37
|
-
"@babel/preset-react": "^7.16.
|
|
38
|
-
"@babel/preset-typescript": "^7.16.
|
|
39
|
-
"@babel/runtime": "^7.16.
|
|
32
|
+
"@babel/core": "^7.16.7",
|
|
33
|
+
"@babel/plugin-proposal-class-properties": "^7.16.7",
|
|
34
|
+
"@babel/plugin-proposal-decorators": "^7.16.7",
|
|
35
|
+
"@babel/plugin-transform-runtime": "^7.16.8",
|
|
36
|
+
"@babel/preset-env": "^7.16.8",
|
|
37
|
+
"@babel/preset-react": "^7.16.7",
|
|
38
|
+
"@babel/preset-typescript": "^7.16.7",
|
|
39
|
+
"@babel/runtime": "^7.16.7",
|
|
40
40
|
"@types/debug": "^4.1.7",
|
|
41
41
|
"@types/html-webpack-plugin": "^3.2.6",
|
|
42
|
-
"@types/lodash": "^4.14.
|
|
43
|
-
"@types/react": "^17.0.
|
|
42
|
+
"@types/lodash": "^4.14.178",
|
|
43
|
+
"@types/react": "^17.0.38",
|
|
44
44
|
"@types/react-dom": "^17.0.11",
|
|
45
45
|
"@types/react-transition-group": "^4.4.4",
|
|
46
|
-
"@types/styled-components": "^5.1.
|
|
46
|
+
"@types/styled-components": "^5.1.19",
|
|
47
47
|
"@types/webpack": "^5.28.0",
|
|
48
48
|
"@types/webpack-env": "^1.16.3",
|
|
49
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
50
|
-
"@typescript-eslint/parser": "^5.
|
|
49
|
+
"@typescript-eslint/eslint-plugin": "^5.9.1",
|
|
50
|
+
"@typescript-eslint/parser": "^5.9.1",
|
|
51
51
|
"babel-loader": "^8.2.3",
|
|
52
52
|
"babel-plugin-styled-components": "^2.0.2",
|
|
53
|
-
"concurrently": "^
|
|
53
|
+
"concurrently": "^7.0.0",
|
|
54
54
|
"cross-env": "^7.0.3",
|
|
55
55
|
"debug": "^4.3.3",
|
|
56
|
-
"eslint": "^8.
|
|
56
|
+
"eslint": "^8.6.0",
|
|
57
57
|
"file-loader": "^6.2.0",
|
|
58
58
|
"html-webpack-plugin": "^5.5.0",
|
|
59
59
|
"promptu": "^5.3.0",
|
|
@@ -61,18 +61,18 @@
|
|
|
61
61
|
"react": "^17.0.2",
|
|
62
62
|
"react-dom": "^17.0.2",
|
|
63
63
|
"react-is": "^17.0.2",
|
|
64
|
-
"react-router": "^6.
|
|
65
|
-
"react-router-dom": "^6.
|
|
64
|
+
"react-router": "^6.2.1",
|
|
65
|
+
"react-router-dom": "^6.2.1",
|
|
66
66
|
"rimraf": "^3.0.2",
|
|
67
67
|
"styled-components": "^5.3.3",
|
|
68
68
|
"ts-loader": "^9.2.6",
|
|
69
69
|
"ts-node": "^10.4.0",
|
|
70
|
-
"typescript": "^4.5.
|
|
70
|
+
"typescript": "^4.5.4",
|
|
71
71
|
"url-loader": "^4.1.1",
|
|
72
72
|
"wait-on": "^6.0.0",
|
|
73
|
-
"webpack": "^5.
|
|
73
|
+
"webpack": "^5.65.0",
|
|
74
74
|
"webpack-cli": "^4.9.1",
|
|
75
|
-
"webpack-dev-server": "^4.
|
|
75
|
+
"webpack-dev-server": "^4.7.2"
|
|
76
76
|
},
|
|
77
77
|
"dependencies": {
|
|
78
78
|
"classnames": "^2.3.1",
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
"styled-components": "^5.3.3"
|
|
89
89
|
},
|
|
90
90
|
"optionalDependencies": {
|
|
91
|
-
"react-router": "^6.
|
|
92
|
-
"react-router-dom": "^6.
|
|
91
|
+
"react-router": "^6.2.1",
|
|
92
|
+
"react-router-dom": "^6.2.1"
|
|
93
93
|
}
|
|
94
94
|
}
|