diff --git a/.changeset/short-rice-press.md b/.changeset/short-rice-press.md new file mode 100644 index 0000000000..9a107e3179 --- /dev/null +++ b/.changeset/short-rice-press.md @@ -0,0 +1,5 @@ +--- +"@channel.io/bezier-react": major +--- + +Removed `LegacySegmentedControl` component. Previously deprecated in next-v1.204. This component was removed for reasons of web accessibility, keyboard navigation, and design modernization. Use `SegmentedControl` instead. diff --git a/packages/bezier-react/package.json b/packages/bezier-react/package.json index 93e6b68d70..5f3425238e 100644 --- a/packages/bezier-react/package.json +++ b/packages/bezier-react/package.json @@ -76,7 +76,6 @@ "@rollup/plugin-babel": "^6.0.3", "@rollup/plugin-commonjs": "^25.0.4", "@rollup/plugin-node-resolve": "^15.2.1", - "@rollup/plugin-typescript": "^11.1.3", "@rollup/plugin-url": "^8.0.1", "@storybook/addon-a11y": "^7.4.2", "@storybook/addon-actions": "^7.4.2", @@ -148,7 +147,6 @@ "@radix-ui/react-tooltip": "^1.0.6", "@radix-ui/react-visually-hidden": "^1.0.3", "classnames": "^2.3.2", - "react-resize-detector": "^9.1.0", "react-textarea-autosize": "8.3.4", "ssr-window": "^4.0.2", "uuid": "^9.0.0" diff --git a/packages/bezier-react/src/components/LegacySegmentedControl/LegacySegmentedControl.const.ts b/packages/bezier-react/src/components/LegacySegmentedControl/LegacySegmentedControl.const.ts deleted file mode 100644 index cbfe442a6f..0000000000 --- a/packages/bezier-react/src/components/LegacySegmentedControl/LegacySegmentedControl.const.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { - Typography, - type css, -} from '~/src/foundation' - -import { LegacySegmentedControlSize } from './LegacySegmentedControl.types' - -export const SIZE_TO_HEIGHT: Record = { - [LegacySegmentedControlSize.XS]: 24, - [LegacySegmentedControlSize.S]: 28, - [LegacySegmentedControlSize.M]: 36, - [LegacySegmentedControlSize.L]: 44, -} - -export const SIZE_TO_PADDING: Record = { - [LegacySegmentedControlSize.XS]: 1, - [LegacySegmentedControlSize.S]: 2, - [LegacySegmentedControlSize.M]: 2, - [LegacySegmentedControlSize.L]: 4, -} - -export const DIVIDER_WIDTH = 1 -export const DIVIDER_SIDE_MARGIN = 6 - -export const SIZE_TO_DIVIDER_VERTICAL_MARGIN: Record = { - [LegacySegmentedControlSize.XS]: 1, - [LegacySegmentedControlSize.S]: 2, - [LegacySegmentedControlSize.M]: 2, - [LegacySegmentedControlSize.L]: 4, -} - -export const SIZE_TO_OPTION_TYPOGRAPHY: Record> = { - [LegacySegmentedControlSize.XS]: Typography.Size13, - [LegacySegmentedControlSize.S]: Typography.Size14, - [LegacySegmentedControlSize.M]: Typography.Size14, - [LegacySegmentedControlSize.L]: Typography.Size14, -} diff --git a/packages/bezier-react/src/components/LegacySegmentedControl/LegacySegmentedControl.stories.tsx b/packages/bezier-react/src/components/LegacySegmentedControl/LegacySegmentedControl.stories.tsx deleted file mode 100644 index 0bb4398072..0000000000 --- a/packages/bezier-react/src/components/LegacySegmentedControl/LegacySegmentedControl.stories.tsx +++ /dev/null @@ -1,248 +0,0 @@ -import React, { - useCallback, - useRef, - useState, -} from 'react' - -import { - CancelIcon, - PlusIcon, -} from '@channel.io/bezier-icons' -import { - type Meta, - type StoryFn, -} from '@storybook/react' - -import { styled } from '~/src/foundation' - -import { range } from '~/src/utils/number' -import { isEmpty } from '~/src/utils/type' - -import { Icon } from '~/src/components/Icon' -import { Text } from '~/src/components/Text' - -import LegacySegmentedControl from './LegacySegmentedControl' -import type LegacySegmentedControlProps from './LegacySegmentedControl.types' -import { LegacySegmentedControlSize } from './LegacySegmentedControl.types' - -export default { - component: LegacySegmentedControl, - argTypes: { - width: { - control: { - type: 'text', - }, - }, - size: { - control: { - type: 'radio', - }, - options: [...Object.values(LegacySegmentedControlSize)], - }, - }, -} as Meta - -const Wrapper = styled.div` - display: flex; - flex-direction: column; -` - -const ItemList = styled.div` - display: flex; - margin-top: 20px; - flex-direction: column; -` - -const Item = styled.div` - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - box-sizing: border-box; - height: 38px; - padding: 6px 6px 6px 12px; - background-color: lightpink; - - &:first-child { - border-top-left-radius: 8px; - border-top-right-radius: 8px; - } - - &:last-child { - border-bottom-left-radius: 8px; - border-bottom-right-radius: 8px; - } - - &:not(first-child) { - margin-top: 4px; - } - - &:nth-child(even) { - background-color: skyblue; - } -` - -const InputItem = styled(Item)` - background-color: lightgrey !important; -` - -const CurrentItem = styled.div<{ selected: boolean }>` - display: flex; - flex-direction: row; - justify-content: flex-start; - align-items: center; - width: 30px; - padding: 0 4px; - - ${props => (props.selected ? ` - &::after { - display: block; - content: '👉' - } - ` : '')} -` - -const ItemText = styled(Text)` - flex: 1 0 auto; -` - -const ItemIcon = styled(Icon)<{ disabled?: boolean }>` - cursor: ${props => (!props.disabled ? 'pointer' : 'not-allowed')}; -` - -const Input = styled.input` - margin: 0 8px 0 0; - padding: 0; - flex: 1 0 auto; - border: none; - background-color: transparent; - - &:active, &:focus { - border: none; - outline: none; - } -` - -const PrimaryStory: StoryFn = ({ - size, - width, - selectedOptionIndex, - ...otherProps -}) => ( - - { ['Open', 'Snoozed', 'Closed'] } - -) - -const PlaygroundStory: StoryFn = ({ - size, - width, - ...otherProps -}) => { - const inputWrapper = useRef(null) - - const [items, setItems] = useState(range(0, 5) as any[]) - const [currentIndex, setCurrentIndex] = useState(0) - - const clickRemoveIconHandlerFactory = useCallback((index) => ( - () => { - if (items.length > 1) { - setItems(prev => prev.filter((e, i) => (i !== index))) - setCurrentIndex(Math.min(items.length - 2, currentIndex)) - } - } - ), [ - items, - currentIndex, - ]) - - const handleClickAddIcon = useCallback(() => { - if (inputWrapper.current && inputWrapper.current.value) { - setItems((prev) => [...prev, inputWrapper.current!.value]) - inputWrapper.current.value = '' - } - }, []) - - const handleDownEnter = useCallback((e: React.KeyboardEvent) => { - if (e.key === 'Enter') { - e.stopPropagation() - const value = e.currentTarget.value - if (!isEmpty(value.trim())) { - setItems(prev => [...prev, value]) - e.currentTarget.value = '' - } - } - }, []) - - const handleChangeOption = useCallback((index) => { - setCurrentIndex(index) - }, []) - - return ( - - - { items } - - - - { items.map((item, index, allItems) => ( - - - { item } - - - )) } - - - - - - - - ) -} - -export const Primary = { - render: PrimaryStory, - - args: { - disabled: false, - size: LegacySegmentedControlSize.M, - width: '400px', - selectedOptionIndex: 0, - }, -} - -export const Playground = { - render: PlaygroundStory, - - args: { - disabled: false, - size: LegacySegmentedControlSize.M, - width: '400px', - }, -} diff --git a/packages/bezier-react/src/components/LegacySegmentedControl/LegacySegmentedControl.styled.ts b/packages/bezier-react/src/components/LegacySegmentedControl/LegacySegmentedControl.styled.ts deleted file mode 100644 index b9d30e5753..0000000000 --- a/packages/bezier-react/src/components/LegacySegmentedControl/LegacySegmentedControl.styled.ts +++ /dev/null @@ -1,158 +0,0 @@ -import { - Transition, - css, - styled, -} from '~/src/foundation' - -import disabledOpacity from '~/src/constants/DisabledOpacity' -import type { BezierComponentProps } from '~/src/types/ComponentProps' -import { toLength } from '~/src/utils/style' - -import { - SIZE_TO_DIVIDER_VERTICAL_MARGIN, - SIZE_TO_HEIGHT, - SIZE_TO_PADDING, -} from './LegacySegmentedControl.const' -import { LegacySegmentedControlSize } from './LegacySegmentedControl.types' -import type { LegacySegmentedControlItemProps } from './LegacySegmentedControl.types' - -interface StyledWrapperProps extends BezierComponentProps { - disabled?: boolean - size: LegacySegmentedControlSize - wrapperWidth: number | string -} - -interface StyledOptionItemWrapperProps extends LegacySegmentedControlItemProps { - size: LegacySegmentedControlSize -} - -interface StyledIndicatorProps { - size: LegacySegmentedControlSize -} - -interface StyledDividerProps { - size: LegacySegmentedControlSize - hidden: boolean -} - -const heightStyle = css<{ size: LegacySegmentedControlSize }>` - height: ${({ size }) => SIZE_TO_HEIGHT[size]}px; -` - -const indicatorHeightStyle = css<{ size: LegacySegmentedControlSize }>` - height: ${({ size }) => SIZE_TO_HEIGHT[size] - (SIZE_TO_PADDING[size] * 2)}px; -` - -const verticalPaddingStyle = css<{ size: LegacySegmentedControlSize }>` - padding: ${({ size }) => SIZE_TO_PADDING[size]}px 0; -` - -const wrapperRoundingStyle = css<{ size: LegacySegmentedControlSize }>` - ${({ foundation, size }) => ({ - [LegacySegmentedControlSize.XS]: foundation?.rounding.round6, - [LegacySegmentedControlSize.S]: foundation?.rounding.round8, - [LegacySegmentedControlSize.M]: foundation?.rounding.round8, - [LegacySegmentedControlSize.L]: foundation?.rounding.round12, - })[size]} -` - -const itemRoundingStyle = css<{ size: LegacySegmentedControlSize }>` - ${({ foundation, size }) => ({ - [LegacySegmentedControlSize.XS]: foundation?.rounding.round4, - [LegacySegmentedControlSize.S]: foundation?.rounding.round6, - [LegacySegmentedControlSize.M]: foundation?.rounding.round6, - [LegacySegmentedControlSize.L]: foundation?.rounding.round6, - })[size]} -` - -const indicatorRoundingStyle = css<{ size: LegacySegmentedControlSize }>` - ${({ foundation, size }) => ({ - [LegacySegmentedControlSize.XS]: foundation?.rounding.round4, - [LegacySegmentedControlSize.S]: foundation?.rounding.round6, - [LegacySegmentedControlSize.M]: foundation?.rounding.round6, - [LegacySegmentedControlSize.L]: foundation?.rounding.round8, - })[size]} -` - -export const Wrapper = styled.div` - position: relative; - box-sizing: border-box; - display: inline-flex; - flex-direction: row; - align-items: center; - width: ${({ wrapperWidth }) => toLength(wrapperWidth, '100%')}; - min-width: 50px; - overflow: hidden; - background-color: ${props => props.foundation?.theme?.['bg-black-lighter']}; - ${({ disabled }) => disabled && ` - opacity: ${disabledOpacity}; - `} - ${({ foundation }) => foundation?.transition?.getTransitionsCSS('background-color')}; - - ${heightStyle} - ${wrapperRoundingStyle} - ${verticalPaddingStyle} -` - -export const OptionItemWrapper = styled.div` - position: absolute; - display: flex; - flex-direction: row; - align-items: center; - justify-content: center; - overflow: hidden; - color: ${props => ( - props.active - ? props.foundation?.theme?.['txt-black-darkest'] - : props.foundation?.theme?.['txt-black-dark'] - )}; - cursor: ${props => { - if (props.disabled) { return 'not-allowed' } - if (props.active) { return 'auto' } - return 'pointer' - }}; - ${({ foundation }) => foundation?.transition?.getTransitionsCSS(['background-color', 'color'])}; - user-select: none; - - &:hover { - ${props => ((!props.disabled && !props.active) ? ` - background-color: ${props.foundation?.theme?.['bg-black-lighter']}; - ` : '')} - } - - ${heightStyle} - ${itemRoundingStyle} -` - -export const Indicator = styled.div` - position: absolute; - display: flex; - flex-direction: row; - align-items: center; - justify-content: center; - cursor: default; - ${({ foundation }) => ( - foundation?.transition?.getTransitionsCSS('transform', Transition.TransitionDuration.M) - )}; - will-change: transform; - - ${indicatorHeightStyle} - ${indicatorRoundingStyle} -` - -export const IndicatorBox = styled.div` - ${({ foundation }) => foundation?.elevation?.ev1()}; - width: 100%; - height: 100%; - background-color: ${({ foundation }) => foundation?.theme?.['bg-white-high']}; -` - -export const DividerContainer = styled.div` - position: absolute; - top: ${({ size }) => SIZE_TO_DIVIDER_VERTICAL_MARGIN[size]}px; - bottom: ${({ size }) => SIZE_TO_DIVIDER_VERTICAL_MARGIN[size]}px; - - ${({ hidden }) => hidden && ` - visibility: hidden; - `} -` diff --git a/packages/bezier-react/src/components/LegacySegmentedControl/LegacySegmentedControl.test.tsx b/packages/bezier-react/src/components/LegacySegmentedControl/LegacySegmentedControl.test.tsx deleted file mode 100644 index 02a2324c77..0000000000 --- a/packages/bezier-react/src/components/LegacySegmentedControl/LegacySegmentedControl.test.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import React from 'react' - -import { LightFoundation } from '~/src/foundation' - -import disabledOpacity from '~/src/constants/DisabledOpacity' -import { range } from '~/src/utils/number' -import { render } from '~/src/utils/test' - -import { Text } from '~/src/components/Text' - -import LegacySegmentedControl, { - SEGMENTED_CONTROL_TEST_ID, - segmentedControlOptionItemTestId, -} from './LegacySegmentedControl' -import type LegacySegmentedControlProps from './LegacySegmentedControl.types' -import ResizeObserver from './__mocks__/ResizeObserver' - -describe('LegacySegmentedControl', () => { - const defaultProps: Partial = { - width: 144, - selectedOptionIndex: 1, - children: range(4).map((i) => { i }), - } - - const renderComponent = (props?: Partial) => render( - , - ) - - let oldWindowResizeObserver - - beforeAll(() => { - oldWindowResizeObserver = window.ResizeObserver - window.ResizeObserver = ResizeObserver - }) - - afterAll(() => { - window.ResizeObserver = oldWindowResizeObserver - }) - - it('Snapshot', () => { - const { getByTestId } = renderComponent() - const rendered = getByTestId(SEGMENTED_CONTROL_TEST_ID) - - expect(rendered).toMatchSnapshot() - }) - - it('has active and non-active items with correct style', () => { - const { getByTestId } = renderComponent({ selectedOptionIndex: 1 }) - - const firstItem = getByTestId(segmentedControlOptionItemTestId(0)) - const secondItem = getByTestId(segmentedControlOptionItemTestId(1)) - - expect(firstItem).toHaveStyle(`color: ${LightFoundation.theme['txt-black-dark']};`) - expect(secondItem).toHaveStyle(`color: ${LightFoundation.theme['txt-black-darkest']};`) - }) - - it('should have correct disabled style', () => { - const { getByTestId } = renderComponent({ disabled: true }) - const rendered = getByTestId(SEGMENTED_CONTROL_TEST_ID) - - expect(rendered).toHaveStyle(`opacity: ${disabledOpacity};`) - }) - - it('has active and non-active items with correct style, even if disabled', () => { - const { getByTestId } = renderComponent({ disabled: true, selectedOptionIndex: 1 }) - - const firstItem = getByTestId(segmentedControlOptionItemTestId(0)) - const secondItem = getByTestId(segmentedControlOptionItemTestId(1)) - - expect(firstItem).toHaveStyle(`color: ${LightFoundation.theme['txt-black-dark']};`) - expect(secondItem).toHaveStyle(`color: ${LightFoundation.theme['txt-black-darkest']};`) - }) -}) diff --git a/packages/bezier-react/src/components/LegacySegmentedControl/LegacySegmentedControl.tsx b/packages/bezier-react/src/components/LegacySegmentedControl/LegacySegmentedControl.tsx deleted file mode 100644 index efa342e7b7..0000000000 --- a/packages/bezier-react/src/components/LegacySegmentedControl/LegacySegmentedControl.tsx +++ /dev/null @@ -1,205 +0,0 @@ -import React, { - type Ref, - forwardRef, - useCallback, - useEffect, - useMemo, - useState, -} from 'react' - -import { useResizeDetector } from 'react-resize-detector' -import { v4 as uuid } from 'uuid' - -import useMergeRefs from '~/src/hooks/useMergeRefs' -import { noop } from '~/src/utils/function' -import { range } from '~/src/utils/number' -import { isNumber } from '~/src/utils/type' - -import { Divider } from '~/src/components/Divider' -import useFormFieldProps from '~/src/components/Forms/useFormFieldProps' -import { Text } from '~/src/components/Text' - -import { - DIVIDER_SIDE_MARGIN, - DIVIDER_WIDTH, - SIZE_TO_OPTION_TYPOGRAPHY, - SIZE_TO_PADDING, -} from './LegacySegmentedControl.const' -import type LegacySegmentedControlProps from './LegacySegmentedControl.types' -import { LegacySegmentedControlSize } from './LegacySegmentedControl.types' - -import * as Styled from './LegacySegmentedControl.styled' - -export const SEGMENTED_CONTROL_TEST_ID = 'bezier-react-segmented-control' -const SEGMENTED_CONTROL_OPTION_ITEM_TEST_ID_PREFIX = 'bezier-react-segmented-control-option-item' -export const segmentedControlOptionItemTestId = (index: number) => - [SEGMENTED_CONTROL_OPTION_ITEM_TEST_ID_PREFIX, index.toString()].join('-') - -const itemWidth = (width: number, numItems: number, size: LegacySegmentedControlSize): number => - (width - (2 * SIZE_TO_PADDING[size]) - ((numItems - 1) * DIVIDER_WIDTH)) / Math.max(1, numItems) - -const itemLeft = (width: number, numItems: number, size: LegacySegmentedControlSize) => - (index: number): number => ( - SIZE_TO_PADDING[size] - + (itemWidth(width, numItems, size) * index) - + (DIVIDER_WIDTH * index) - ) - -const dividerLeft = (width: number, numItems: number, size: LegacySegmentedControlSize) => - (index: number): number => ( - SIZE_TO_PADDING[size] - + (itemWidth(width, numItems, size) * index) - + (DIVIDER_WIDTH * (index - 1)) - - DIVIDER_SIDE_MARGIN - ) - -function LegacySegmentedControl( - { - testId = SEGMENTED_CONTROL_TEST_ID, - width = '100%', - size = LegacySegmentedControlSize.M, - /* OptionItemHost props */ - selectedOptionIndex = 0, - onChangeOption = noop, - /* HTMLAttribute props */ - children, - ...rest - }: LegacySegmentedControlProps, - forwardedRef: Ref, -) { - const { - disabled, - ...ownProps - } = useFormFieldProps(rest) - - const [currentIndex, setCurrentIndex] = useState(selectedOptionIndex) - const [wrapperWidth, setWrapperWidth] = useState(0) - - const numItems = useMemo(() => React.Children.count(children), [children]) - - const optionItemWidth = itemWidth(wrapperWidth, numItems, size) - const optionItemLeft = useMemo(() => ( - itemLeft(wrapperWidth, numItems, size) - ), [ - wrapperWidth, - numItems, - size, - ]) - const dividerItemLeft = useMemo(() => ( - dividerLeft(wrapperWidth, numItems, size) - ), [ - wrapperWidth, - numItems, - size, - ]) - - const updateDimensions = useCallback((_width?: number) => { - if (isNumber(_width)) { setWrapperWidth(_width) } - }, []) - - const { ref: resizeDetectorRef } = useResizeDetector({ onResize: updateDimensions }) - - const wrapperRef = useMergeRefs(resizeDetectorRef, forwardedRef) - - useEffect(() => { - if (isNumber(selectedOptionIndex)) { - setCurrentIndex(selectedOptionIndex) - } - }, [selectedOptionIndex]) - - const handleClickOptionItem = useCallback((index: number) => { - setCurrentIndex(index) - onChangeOption(index) - }, [onChangeOption]) - - const renderOption = useCallback((Element: React.ReactNode, index: number) => ( - (disabled ? noop : handleClickOptionItem(index))} - > - - { Element } - - - ), [ - disabled, - size, - currentIndex, - optionItemWidth, - optionItemLeft, - handleClickOptionItem, - ]) - - const Content = useMemo(() => ( - React.Children.map(children, renderOption) - ), [ - children, - renderOption, - ]) - - const Dividers = useMemo(() => ( - range(1, numItems) - .map(index => ( - - )) - ), [ - size, - numItems, - currentIndex, - dividerItemLeft, - ]) - - const IndicatorComponent = useMemo(() => ( - - - - ), [ - size, - currentIndex, - optionItemWidth, - optionItemLeft, - ]) - - return ( - - { IndicatorComponent } - { Content } - { Dividers } - - ) -} - -export default forwardRef(LegacySegmentedControl) diff --git a/packages/bezier-react/src/components/LegacySegmentedControl/LegacySegmentedControl.types.ts b/packages/bezier-react/src/components/LegacySegmentedControl/LegacySegmentedControl.types.ts deleted file mode 100644 index e85a14b6e9..0000000000 --- a/packages/bezier-react/src/components/LegacySegmentedControl/LegacySegmentedControl.types.ts +++ /dev/null @@ -1,43 +0,0 @@ -import type { - BoxSizingUnit, - ExplicitDefaulting, -} from '~/src/types/CSS' -import type { - ActivatableProps, - BezierComponentProps, - ChildrenProps, - OptionItemHostProps, -} from '~/src/types/ComponentProps' - -import type { FormComponentProps } from '~/src/components/Forms/Form.types' - -type SegmentedControlBaseProps = BezierComponentProps & ChildrenProps & FormComponentProps - -type CSSSizingProperty = number | string | ExplicitDefaulting | BoxSizingUnit - -export enum LegacySegmentedControlSize { - XS = 'xs', - S = 's', - M = 'm', - L = 'l', -} - -interface LegacySegmentedControlOptions { - width?: CSSSizingProperty - - /** - * Size variant of this SegmentedControl. - * - * @default SegmentedControlSize.M - */ - size?: LegacySegmentedControlSize -} - -export default interface LegacySegmentedControlProps extends - SegmentedControlBaseProps, - OptionItemHostProps, - LegacySegmentedControlOptions {} - -export interface LegacySegmentedControlItemProps extends - SegmentedControlBaseProps, - Pick {} diff --git a/packages/bezier-react/src/components/LegacySegmentedControl/__mocks__/ResizeObserver.ts b/packages/bezier-react/src/components/LegacySegmentedControl/__mocks__/ResizeObserver.ts deleted file mode 100644 index 16d0043b3b..0000000000 --- a/packages/bezier-react/src/components/LegacySegmentedControl/__mocks__/ResizeObserver.ts +++ /dev/null @@ -1,9 +0,0 @@ -class ResizeObserver { - observe() {} - - unobserve() {} - - disconnect() {} -} - -export default ResizeObserver diff --git a/packages/bezier-react/src/components/LegacySegmentedControl/__snapshots__/LegacySegmentedControl.test.tsx.snap b/packages/bezier-react/src/components/LegacySegmentedControl/__snapshots__/LegacySegmentedControl.test.tsx.snap deleted file mode 100644 index 18c2d997c7..0000000000 --- a/packages/bezier-react/src/components/LegacySegmentedControl/__snapshots__/LegacySegmentedControl.test.tsx.snap +++ /dev/null @@ -1,337 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`LegacySegmentedControl Snapshot 1`] = ` -.c4 { - font-size: 1.4rem; - line-height: 1.8rem; - margin: 0px 0px 0px 0px; - font-style: normal; - font-weight: bold; - color: inherit; - -webkit-transition-delay: 0ms; - transition-delay: 0ms; - -webkit-transition-timing-function: cubic-bezier(.3,0,0,1); - transition-timing-function: cubic-bezier(.3,0,0,1); - -webkit-transition-duration: 150ms; - transition-duration: 150ms; - -webkit-transition-property: color; - transition-property: color; -} - -.c5 { - font-size: 1.5rem; - line-height: 2rem; - -webkit-letter-spacing: -0.1px; - -moz-letter-spacing: -0.1px; - -ms-letter-spacing: -0.1px; - letter-spacing: -0.1px; - margin: 0px 0px 0px 0px; - font-style: normal; - font-weight: normal; - color: inherit; - -webkit-transition-delay: 0ms; - transition-delay: 0ms; - -webkit-transition-timing-function: cubic-bezier(.3,0,0,1); - transition-timing-function: cubic-bezier(.3,0,0,1); - -webkit-transition-duration: 150ms; - transition-duration: 150ms; - -webkit-transition-property: color; - transition-property: color; -} - -.c8 { - overflow: hidden; - border-radius: 1px; - background-color: #00000014; - width: 1px; - height: calc(100% - 12px); - margin: 6px; -} - -.c0 { - position: relative; - box-sizing: border-box; - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - width: 144px; - min-width: 50px; - overflow: hidden; - background-color: #0000000D; - -webkit-transition-delay: 0ms; - transition-delay: 0ms; - -webkit-transition-timing-function: cubic-bezier(.3,0,0,1); - transition-timing-function: cubic-bezier(.3,0,0,1); - -webkit-transition-duration: 150ms; - transition-duration: 150ms; - -webkit-transition-property: background-color; - transition-property: background-color; - height: 36px; - overflow: hidden; - border-radius: 8px; - padding: 2px 0; -} - -.c3 { - position: absolute; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - overflow: hidden; - color: #00000066; - cursor: pointer; - -webkit-transition-delay: 0ms; - transition-delay: 0ms; - -webkit-transition-timing-function: cubic-bezier(.3,0,0,1); - transition-timing-function: cubic-bezier(.3,0,0,1); - -webkit-transition-duration: 150ms; - transition-duration: 150ms; - -webkit-transition-property: background-color,color; - transition-property: background-color,color; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - height: 36px; - overflow: hidden; - border-radius: 6px; -} - -.c3:hover { - background-color: #0000000D; -} - -.c6 { - position: absolute; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - overflow: hidden; - color: #000000D9; - cursor: auto; - -webkit-transition-delay: 0ms; - transition-delay: 0ms; - -webkit-transition-timing-function: cubic-bezier(.3,0,0,1); - transition-timing-function: cubic-bezier(.3,0,0,1); - -webkit-transition-duration: 150ms; - transition-duration: 150ms; - -webkit-transition-property: background-color,color; - transition-property: background-color,color; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - height: 36px; - overflow: hidden; - border-radius: 6px; -} - -.c1 { - position: absolute; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: row; - -ms-flex-direction: row; - flex-direction: row; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - cursor: default; - -webkit-transition-delay: 0ms; - transition-delay: 0ms; - -webkit-transition-timing-function: cubic-bezier(.3,0,0,1); - transition-timing-function: cubic-bezier(.3,0,0,1); - -webkit-transition-duration: 300ms; - transition-duration: 300ms; - -webkit-transition-property: -webkit-transform; - -webkit-transition-property: transform; - transition-property: transform; - will-change: transform; - height: 32px; - overflow: hidden; - border-radius: 6px; -} - -.c2 { - background-color: #FFFFFF; - box-shadow: inset 0 0 2px 0 #FFFFFF1F, 0 0 2px 1px #0000000D, 0 1px 2px #00000014; - width: 100%; - height: 100%; - background-color: #FFFFFF; -} - -.c7 { - position: absolute; - top: 2px; - bottom: 2px; - visibility: hidden; -} - -.c9 { - position: absolute; - top: 2px; - bottom: 2px; -} - -
-
-
-
-
- - - 0 - - -
-
- - - 1 - - -
-
- - - 2 - - -
-
- - - 3 - - -
-