etudes 0.44.0 → 0.48.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 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, never>> = T & {
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, never>> = ListItemComponentProps<DataProps<T>>;
22
- export interface Props<T = Record<string, never>> {
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, never>> extends PureComponent<Props<T>, State> {
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
  };
@@ -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,2 @@
1
+ import { HTMLAttributes, PropsWithChildren } from 'react';
2
+ export default function ExtractChildren({ children, ...props }: PropsWithChildren<HTMLAttributes<HTMLElement>>): JSX.Element;
@@ -0,0 +1,54 @@
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, react_1.Children.map(children, function (child) {
48
+ if ((0, react_1.isValidElement)(child))
49
+ return (0, react_1.cloneElement)(child, __assign({}, props));
50
+ return child;
51
+ })));
52
+ }
53
+ exports.default = ExtractChildren;
54
+ //# 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,8DACG,gBAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,UAAA,KAAK;QAC3B,IAAI,IAAA,sBAAc,EAAC,KAAK,CAAC;YAAE,OAAO,IAAA,oBAAY,EAAC,KAAK,eAAO,KAAK,EAAG,CAAA;QACnE,OAAO,KAAK,CAAA;IACd,CAAC,CAAC,CACD,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<any>;
68
+ cssStartingTrack?: CSSProp;
65
69
  /**
66
70
  * Custom CSS provided to the track after the knob.
67
71
  */
68
- cssEndingTrack?: CSSProp<any>;
72
+ cssEndingTrack?: CSSProp;
69
73
  /**
70
74
  * Custom CSS provided to the knob.
71
75
  */
72
- cssKnob?: CSSProp<any>;
76
+ cssKnob?: CSSProp;
73
77
  /**
74
78
  * Custom CSS provided to the label inside the knob.
75
79
  */
76
- cssLabel?: CSSProp<any>;
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.onlyDispatchesOnDragEnd, onlyDispatchesOnDragEnd = _c === void 0 ? false : _c, _d = _a.trackPadding, trackPadding = _d === void 0 ? 0 : _d, _e = _a.knobHeight, knobHeight = _e === void 0 ? 30 : _e, _f = _a.knobWidth, knobWidth = _f === void 0 ? 30 : _f, _g = _a.orientation, orientation = _g === void 0 ? 'vertical' : _g, _h = _a.position, externalPosition = _h === void 0 ? 0 : _h, 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", "onlyDispatchesOnDragEnd", "trackPadding", "knobHeight", "knobWidth", "orientation", "position", "labelProvider", "onDragEnd", "onDragStart", "onPositionChange", "cssStartingTrack", "cssEndingTrack", "cssKnob", "cssLabel"]);
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 _j = (0, useDragEffect_1.default)(knobRef, {
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
- }), _k = __read(_j.isDragging, 1), isDragging = _k[0], _l = __read(_j.value, 2), position = _l[0], setPosition = _l[1];
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,12 +138,12 @@ 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(StyledTrack, { orientation: orientation, css: cssStartingTrack, style: orientation === 'vertical' ? {
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
- height: "calc(".concat(naturalPosition * 100, "% - ").concat(knobHeight * .5, "px - ").concat(trackPadding, "px)"),
143
+ height: "calc(".concat(naturalPosition * 100, "% - ").concat(trackPadding <= 0 ? 0 : knobHeight * .5, "px - ").concat(trackPadding, "px)"),
123
144
  } : {
124
145
  left: 0,
125
- width: "calc(".concat(naturalPosition * 100, "% - ").concat(knobWidth * .5, "px - ").concat(trackPadding, "px)"),
146
+ width: "calc(".concat(naturalPosition * 100, "% - ").concat(trackPadding <= 0 ? 0 : knobWidth * .5, "px - ").concat(trackPadding, "px)"),
126
147
  } }),
127
148
  react_1.default.createElement(StyledKnobContainer, { ref: knobRef, style: __assign({ transform: 'translate3d(-50%, -50%, 0)' }, (orientation === 'vertical' ? {
128
149
  left: '50%',
@@ -141,19 +162,20 @@ 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(StyledTrack, { orientation: orientation, css: cssEndingTrack, style: orientation === 'vertical' ? {
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
- height: "calc(".concat((1 - naturalPosition) * 100, "% - ").concat(knobHeight * .5, "px - ").concat(trackPadding, "px)"),
167
+ height: "calc(".concat((1 - naturalPosition) * 100, "% - ").concat(trackPadding <= 0 ? 0 : knobHeight * .5, "px - ").concat(trackPadding, "px)"),
147
168
  } : {
148
169
  right: 0,
149
- width: "calc(".concat((1 - naturalPosition) * 100, "% - ").concat(knobWidth * .5, "px - ").concat(trackPadding, "px)"),
170
+ width: "calc(".concat((1 - naturalPosition) * 100, "% - ").concat(trackPadding <= 0 ? 0 : knobWidth * .5, "px - ").concat(trackPadding, "px)"),
150
171
  } })));
151
172
  }
152
173
  exports.default = Slider;
153
- var StyledTrack = styled_components_1.default.div(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n background: #fff;\n position: absolute;\n\n ", "\n\n ", "\n"], ["\n background: #fff;\n position: absolute;\n\n ", "\n\n ", "\n"])), 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; });
154
- var StyledLabel = styled_components_1.default.label(templateObject_4 || (templateObject_4 = __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; });
155
- var StyledKnobContainer = styled_components_1.default.button(templateObject_5 || (templateObject_5 = __makeTemplateObject(["\n position: absolute;\n z-index: 1;\n"], ["\n position: absolute;\n z-index: 1;\n"])));
156
- var StyledKnob = styled_components_1.default.div(templateObject_6 || (templateObject_6 = __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; });
157
- var StyledRoot = styled_components_1.default.div(templateObject_7 || (templateObject_7 = __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'; });
158
- var templateObject_1, templateObject_2, templateObject_3, templateObject_4, templateObject_5, templateObject_6, templateObject_7;
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}% - ${trackPadding <= 0 ? 0 : knobHeight*.5}px - ${trackPadding}px)`,\n } : {\n left: 0,\n width: `calc(${naturalPosition*100}% - ${trackPadding <= 0 ? 0 : 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}% - ${trackPadding <= 0 ? 0 : knobHeight*.5}px - ${trackPadding}px)`,\n } : {\n right: 0,\n width: `calc(${(1 - naturalPosition)*100}% - ${trackPadding <= 0 ? 0 : 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"]}
@@ -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;
@@ -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.onlyDispatchesOnDragEnd, onlyDispatchesOnDragEnd = _c === void 0 ? false : _c, _d = _a.trackPadding, trackPadding = _d === void 0 ? 0 : _d, _e = _a.knobHeight, knobHeight = _e === void 0 ? 30 : _e, _f = _a.knobWidth, knobWidth = _f === void 0 ? 30 : _f, _g = _a.orientation, orientation = _g === void 0 ? 'vertical' : _g, labelProvider = _a.labelProvider, _h = _a.steps, steps = _h === void 0 ? generateSteps(10) : _h, _j = _a.index, externalIndex = _j === void 0 ? 0 : _j, 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", "onlyDispatchesOnDragEnd", "trackPadding", "knobHeight", "knobWidth", "orientation", "labelProvider", "steps", "index", "onIndexChange", "onPositionChange", "onDragEnd", "onDragStart", "cssStartingTrack", "cssEndingTrack", "cssKnob", "cssLabel"]);
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 _k = __read((0, react_1.useState)(externalIndex), 2), index = _k[0], setIndex = _k[1];
158
- var _l = (0, useDragEffect_1.default)(knobRef, {
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
- }), _m = __read(_l.isDragging, 1), isDragging = _m[0], _o = __read(_l.value, 2), position = _o[0], setPosition = _o[1];
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,12 +217,12 @@ 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(StyledTrack, { orientation: orientation, css: cssStartingTrack, style: orientation === 'vertical' ? {
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
- height: "calc(".concat(naturalPosition * 100, "% - ").concat(knobHeight * .5, "px - ").concat(trackPadding, "px)"),
222
+ height: "calc(".concat(naturalPosition * 100, "% - ").concat(trackPadding <= 0 ? 0 : knobHeight * .5, "px - ").concat(trackPadding, "px)"),
202
223
  } : {
203
224
  left: 0,
204
- width: "calc(".concat(naturalPosition * 100, "% - ").concat(knobWidth * .5, "px - ").concat(trackPadding, "px)"),
225
+ width: "calc(".concat(naturalPosition * 100, "% - ").concat(trackPadding <= 0 ? 0 : knobWidth * .5, "px - ").concat(trackPadding, "px)"),
205
226
  } }),
206
227
  react_1.default.createElement(StyledKnobContainer, { ref: knobRef, style: __assign({ transform: 'translate3d(-50%, -50%, 0)' }, (orientation === 'vertical' ? {
207
228
  left: '50%',
@@ -220,19 +241,20 @@ 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(StyledTrack, { orientation: orientation, css: cssEndingTrack, style: orientation === 'vertical' ? {
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
- height: "calc(".concat((1 - naturalPosition) * 100, "% - ").concat(knobHeight * .5, "px - ").concat(trackPadding, "px)"),
246
+ height: "calc(".concat((1 - naturalPosition) * 100, "% - ").concat(trackPadding <= 0 ? 0 : knobHeight * .5, "px - ").concat(trackPadding, "px)"),
226
247
  } : {
227
248
  right: 0,
228
- width: "calc(".concat((1 - naturalPosition) * 100, "% - ").concat(knobWidth * .5, "px - ").concat(trackPadding, "px)"),
249
+ width: "calc(".concat((1 - naturalPosition) * 100, "% - ").concat(trackPadding <= 0 ? 0 : knobWidth * .5, "px - ").concat(trackPadding, "px)"),
229
250
  } })));
230
251
  }
231
252
  exports.default = StepwiseSlider;
232
- var StyledTrack = styled_components_1.default.div(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n background: #fff;\n position: absolute;\n\n ", "\n\n ", "\n"], ["\n background: #fff;\n position: absolute;\n\n ", "\n\n ", "\n"])), 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; });
233
- var StyledLabel = styled_components_1.default.label(templateObject_4 || (templateObject_4 = __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; });
234
- var StyledKnobContainer = styled_components_1.default.button(templateObject_5 || (templateObject_5 = __makeTemplateObject(["\n position: absolute;\n z-index: 1;\n"], ["\n position: absolute;\n z-index: 1;\n"])));
235
- var StyledKnob = styled_components_1.default.div(templateObject_6 || (templateObject_6 = __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; });
236
- var StyledRoot = styled_components_1.default.div(templateObject_7 || (templateObject_7 = __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'; });
237
- var templateObject_1, templateObject_2, templateObject_3, templateObject_4, templateObject_5, templateObject_6, templateObject_7;
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":"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","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}% - ${trackPadding <= 0 ? 0 : knobHeight*.5}px - ${trackPadding}px)`,\n } : {\n left: 0,\n width: `calc(${naturalPosition*100}% - ${trackPadding <= 0 ? 0 : 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}% - ${trackPadding <= 0 ? 0 : knobHeight*.5}px - ${trackPadding}px)`,\n } : {\n right: 0,\n width: `calc(${(1 - naturalPosition)*100}% - ${trackPadding <= 0 ? 0 : 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,44 @@
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 hint string to display in the tooltip.
18
+ */
19
+ hint: string;
20
+ /**
21
+ * Specifies if the arrow is visible.
22
+ */
23
+ isArrowVisible?: boolean;
24
+ /**
25
+ * The offset (in pixels) between the target element and the tooltip, defaults to zero.
26
+ */
27
+ offset?: number;
28
+ /**
29
+ * Color of the dialog text, same format as a CSS color string (i.e. '#000').
30
+ */
31
+ textColor?: string;
32
+ /**
33
+ * The minimum space (in pixels) between the target element and the edge of the window required to
34
+ * trigger an alignment change, defaults to `100px`.
35
+ */
36
+ threshold?: number;
37
+ /**
38
+ * Custom CSS provided to the dialog. Not all CSS rules will take effect as they will be
39
+ * overridden by internal rules.
40
+ */
41
+ cssDialog?: CSSProp<any>;
42
+ };
43
+ export default function WithTooltip({ arrowHeight, backgroundColor, cssDialog, disabledOnTouch, hint, isArrowVisible, offset, textColor, threshold, ...props }: Props): JSX.Element;
44
+ export {};
@@ -0,0 +1,180 @@
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.isArrowVisible, isArrowVisible = _e === void 0 ? true : _e, _f = _a.offset, offset = _f === void 0 ? 5 : _f, _g = _a.textColor, textColor = _g === void 0 ? '#fff' : _g, _h = _a.threshold, threshold = _h === void 0 ? 100 : _h, props = __rest(_a, ["arrowHeight", "backgroundColor", "cssDialog", "disabledOnTouch", "hint", "isArrowVisible", "offset", "textColor", "threshold"]);
73
+ var _j = __read((0, react_1.useState)(new spase_1.Size()), 2), textSize = _j[0], setTextSize = _j[1];
74
+ var _k = __read((0, react_1.useState)('bc'), 2), position = _k[0], setPosition = _k[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.right - rect.center.x) < threshold;
81
+ var topBound = (rect.center.y - vrect.top) < threshold;
82
+ var bottomBound = (vrect.bottom - rect.center.y) < 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
+ // Add 1px as buffer to mitigate precision discrepancies.
117
+ var width = div.clientWidth + 1;
118
+ var height = div.clientHeight + 1;
119
+ document.body.removeChild(div);
120
+ return new spase_1.Size([width, height]);
121
+ }
122
+ function onMouseOver(event) {
123
+ setTextSize(computeTextSize(event.currentTarget));
124
+ setPosition(computePosition(event.currentTarget, threshold));
125
+ }
126
+ return (react_1.default.createElement(StyledRoot, __assign({ arrowHeight: arrowHeight, backgroundColor: backgroundColor, cssDialog: cssDialog, disabledOnTouch: disabledOnTouch, hint: hint, isArrowVisible: isArrowVisible, offset: offset, onMouseOver: function (event) { return onMouseOver(event); }, position: position, textColor: textColor, textSize: textSize }, props)));
127
+ }
128
+ exports.default = WithTooltip;
129
+ function _cssDisplacement(position, arrowHeight, offset) {
130
+ switch (position) {
131
+ case 'tl': return (0, styled_components_1.css)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["top: ", "px; left: 100%;"], ["top: ", "px; left: 100%;"])), -arrowHeight);
132
+ case 'tc': return (0, styled_components_1.css)(templateObject_2 || (templateObject_2 = __makeTemplateObject(["top: ", "px; left: 50%;"], ["top: ", "px; left: 50%;"])), -arrowHeight);
133
+ case 'tr': return (0, styled_components_1.css)(templateObject_3 || (templateObject_3 = __makeTemplateObject(["top: ", "px; right: 100%;"], ["top: ", "px; right: 100%;"])), -arrowHeight);
134
+ case 'cl': return (0, styled_components_1.css)(templateObject_4 || (templateObject_4 = __makeTemplateObject(["top: 50%; left: ", "px;"], ["top: 50%; left: ", "px;"])), -arrowHeight);
135
+ case 'cr': return (0, styled_components_1.css)(templateObject_5 || (templateObject_5 = __makeTemplateObject(["top: 50%; right: ", "px;"], ["top: 50%; right: ", "px;"])), -arrowHeight);
136
+ case 'bl': return (0, styled_components_1.css)(templateObject_6 || (templateObject_6 = __makeTemplateObject(["bottom: ", "px; left: 100%;"], ["bottom: ", "px; left: 100%;"])), -arrowHeight);
137
+ case 'bc': return (0, styled_components_1.css)(templateObject_7 || (templateObject_7 = __makeTemplateObject(["bottom: ", "px; left: 50%;"], ["bottom: ", "px; left: 50%;"])), -arrowHeight);
138
+ case 'br': return (0, styled_components_1.css)(templateObject_8 || (templateObject_8 = __makeTemplateObject(["bottom: ", "px; right: 100%;"], ["bottom: ", "px; right: 100%;"])), -arrowHeight);
139
+ }
140
+ }
141
+ function _cssDialog(position, arrowHeight, offset) {
142
+ switch (position) {
143
+ 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);
144
+ 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);
145
+ 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);
146
+ 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);
147
+ 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);
148
+ 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);
149
+ 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);
150
+ 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);
151
+ }
152
+ }
153
+ function _cssArrow(position, arrowHeight, offset, color) {
154
+ return (0, styled_components_1.css)(templateObject_33 || (templateObject_33 = __makeTemplateObject(["\n ", "\n ", "\n "], ["\n ", "\n ", "\n "])), function () {
155
+ switch (position) {
156
+ case 'tl': return (0, styled_components_1.css)(templateObject_17 || (templateObject_17 = __makeTemplateObject(["border-color: ", " transparent transparent transparent;"], ["border-color: ", " transparent transparent transparent;"])), color);
157
+ case 'tc': return (0, styled_components_1.css)(templateObject_18 || (templateObject_18 = __makeTemplateObject(["border-color: ", " transparent transparent transparent;"], ["border-color: ", " transparent transparent transparent;"])), color);
158
+ case 'tr': return (0, styled_components_1.css)(templateObject_19 || (templateObject_19 = __makeTemplateObject(["border-color: ", " transparent transparent transparent;"], ["border-color: ", " transparent transparent transparent;"])), color);
159
+ case 'cl': return (0, styled_components_1.css)(templateObject_20 || (templateObject_20 = __makeTemplateObject(["border-color: transparent transparent transparent ", ";"], ["border-color: transparent transparent transparent ", ";"])), color);
160
+ case 'cr': return (0, styled_components_1.css)(templateObject_21 || (templateObject_21 = __makeTemplateObject(["border-color: transparent ", " transparent transparent;"], ["border-color: transparent ", " transparent transparent;"])), color);
161
+ case 'bl': return (0, styled_components_1.css)(templateObject_22 || (templateObject_22 = __makeTemplateObject(["border-color: transparent transparent ", " transparent;"], ["border-color: transparent transparent ", " transparent;"])), color);
162
+ case 'bc': return (0, styled_components_1.css)(templateObject_23 || (templateObject_23 = __makeTemplateObject(["border-color: transparent transparent ", " transparent;"], ["border-color: transparent transparent ", " transparent;"])), color);
163
+ case 'br': return (0, styled_components_1.css)(templateObject_24 || (templateObject_24 = __makeTemplateObject(["border-color: transparent transparent ", " transparent;"], ["border-color: transparent transparent ", " transparent;"])), color);
164
+ }
165
+ }, function () {
166
+ switch (position) {
167
+ 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);
168
+ 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);
169
+ 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);
170
+ 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);
171
+ 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);
172
+ 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);
173
+ 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);
174
+ 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);
175
+ }
176
+ });
177
+ }
178
+ var StyledRoot = (0, styled_components_1.default)(ExtractChildren_1.default)(templateObject_35 || (templateObject_35 = __makeTemplateObject(["\n cursor: pointer;\n position: relative;\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 ", "\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.isArrowVisible ? (0, styled_components_1.css)(templateObject_34 || (templateObject_34 = __makeTemplateObject(["\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 &::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 "])), props.arrowHeight, _cssDisplacement(props.position, props.arrowHeight, props.offset), _cssArrow(props.position, props.arrowHeight, props.offset, props.backgroundColor), props.disabledOnTouch ? 'html.touch & { display: none; }' : '') : undefined; }, 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 ? "".concat(props.textSize.width, "px") : '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'; });
179
+ 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, templateObject_35;
180
+ //# 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 hint string to display in the tooltip.\n */\n hint: string\n\n /**\n * Specifies if the arrow is visible.\n */\n isArrowVisible?: 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 * 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 isArrowVisible = true,\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.right - rect.center.x) < threshold\n const topBound = (rect.center.y - vrect.top) < threshold\n const bottomBound = (vrect.bottom - rect.center.y) < 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 // Add 1px as buffer to mitigate precision discrepancies.\n const width = div.clientWidth + 1\n const height = div.clientHeight + 1\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 arrowHeight={arrowHeight}\n backgroundColor={backgroundColor}\n cssDialog={cssDialog}\n disabledOnTouch={disabledOnTouch}\n hint={hint}\n isArrowVisible={isArrowVisible}\n offset={offset}\n onMouseOver={event => onMouseOver(event)}\n position={position}\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 isArrowVisible: boolean\n offset: number\n position: Position\n textColor: string\n textSize: Size\n}>`\n cursor: pointer;\n position: relative;\n\n ${props => props.isArrowVisible ? css`\n &::before {\n border-style: solid;\n border-width: ${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 ${_cssDisplacement(props.position, props.arrowHeight, props.offset)}\n ${_cssArrow(props.position, props.arrowHeight, props.offset, props.backgroundColor)}\n ${props.disabledOnTouch ? 'html.touch & { display: none; }' : ''}\n }\n ` : undefined}\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}px` : '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.44.0",
3
+ "version": "0.48.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.0",
33
- "@babel/plugin-proposal-class-properties": "^7.16.0",
34
- "@babel/plugin-proposal-decorators": "^7.16.4",
35
- "@babel/plugin-transform-runtime": "^7.16.4",
36
- "@babel/preset-env": "^7.16.4",
37
- "@babel/preset-react": "^7.16.0",
38
- "@babel/preset-typescript": "^7.16.0",
39
- "@babel/runtime": "^7.16.3",
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.177",
43
- "@types/react": "^17.0.37",
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.16",
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.5.0",
50
- "@typescript-eslint/parser": "^5.5.0",
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": "^6.4.0",
53
+ "concurrently": "^7.0.0",
54
54
  "cross-env": "^7.0.3",
55
55
  "debug": "^4.3.3",
56
- "eslint": "^8.3.0",
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.0.2",
65
- "react-router-dom": "^6.0.2",
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.2",
70
+ "typescript": "^4.5.4",
71
71
  "url-loader": "^4.1.1",
72
72
  "wait-on": "^6.0.0",
73
- "webpack": "^5.64.4",
73
+ "webpack": "^5.65.0",
74
74
  "webpack-cli": "^4.9.1",
75
- "webpack-dev-server": "^4.6.0"
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.0.2",
92
- "react-router-dom": "^6.0.2"
91
+ "react-router": "^6.2.1",
92
+ "react-router-dom": "^6.2.1"
93
93
  }
94
94
  }