From 0636c37122f21a83d1aa994f182e56adc418b237 Mon Sep 17 00:00:00 2001 From: Rameshwar Verma <rameshwar.verma@oncehub.com> Date: Fri, 20 Sep 2024 10:57:46 +0530 Subject: [PATCH] move tailwind classes from html to .scss files. --- package-lock.json | 4 +- package.json | 2 +- .../multi-select/multi-select.module.scss | 7 +++ .../components/multi-select/multi-select.tsx | 9 +--- ...{options.tsx => auto-complete-options.tsx} | 12 ++--- .../select/auto-complete.module.scss | 50 +++++++++++++++++++ .../select/auto-complete.stories.tsx | 4 +- src/lib/components/select/auto-complete.tsx | 21 +++----- src/lib/components/select/index.tsx | 2 +- src/lib/components/select/select-options.tsx | 11 ++-- src/lib/components/select/select.module.scss | 47 +++++++++++++++++ src/lib/components/select/select.stories.tsx | 1 - src/lib/components/select/select.tsx | 24 ++++----- 13 files changed, 140 insertions(+), 54 deletions(-) rename src/lib/components/select/{options.tsx => auto-complete-options.tsx} (62%) create mode 100644 src/lib/components/select/auto-complete.module.scss create mode 100644 src/lib/components/select/select.module.scss diff --git a/package-lock.json b/package-lock.json index 8b9b1a2..14eb80b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@oncehub/ui-react", - "version": "1.4.16", + "version": "1.4.17-beta.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@oncehub/ui-react", - "version": "1.4.16", + "version": "1.4.17-beta.1.0", "devDependencies": { "@babel/core": "^7.23.2", "@headlessui/react": "^1.7.17", diff --git a/package.json b/package.json index 86cfa92..98f4935 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@oncehub/ui-react", "private": false, - "version": "1.4.16", + "version": "1.4.17-beta.1.0", "repository": { "type": "git", "url": "https://github.com/scheduleonce/once-ui-react" diff --git a/src/lib/components/multi-select/multi-select.module.scss b/src/lib/components/multi-select/multi-select.module.scss index b70d670..ea98ec4 100644 --- a/src/lib/components/multi-select/multi-select.module.scss +++ b/src/lib/components/multi-select/multi-select.module.scss @@ -51,6 +51,9 @@ } .btnContainer { @apply tw-absolute tw-box-border tw-inset-x-0 tw-flex tw-h-[64px] tw-w-full tw-items-center tw-justify-end tw-border-0 tw-border-t tw-border-solid tw-border-t-[#C8C8C8] tw-px-[18px]; + .hiddenButton{ + @apply tw-absolute tw-left-[-9999px] tw-h-0 tw-w-0 tw-opacity-0; + } } } @@ -61,3 +64,7 @@ background-color: darkgrey; border-radius: 6px; } + +.announcement{ + @apply tw-pointer-events-none tw-h-0 tw-overflow-hidden tw-opacity-0; +} \ No newline at end of file diff --git a/src/lib/components/multi-select/multi-select.tsx b/src/lib/components/multi-select/multi-select.tsx index 3ecce0c..1c578bf 100644 --- a/src/lib/components/multi-select/multi-select.tsx +++ b/src/lib/components/multi-select/multi-select.tsx @@ -349,12 +349,7 @@ export const MultiSelect: React.FC<Props> = ({ </svg> </span> </div> - <div - id="announcement" - aria-live="assertive" - role="alert" - className="tw-pointer-events-none tw-h-0 tw-overflow-hidden tw-opacity-0" - ></div> + <div id="announcement" aria-live="assertive" role="alert" className={styles.announcement}></div> {isMounted ? createPortal( <> @@ -427,7 +422,7 @@ export const MultiSelect: React.FC<Props> = ({ onKeyDown={(event) => { handleKeyDown(event); }} - className="tw-absolute tw-left-[-9999px] tw-h-0 tw-w-0 tw-opacity-0" + className={styles.hiddenButton} /> <Button themeColor={themeColor} diff --git a/src/lib/components/select/options.tsx b/src/lib/components/select/auto-complete-options.tsx similarity index 62% rename from src/lib/components/select/options.tsx rename to src/lib/components/select/auto-complete-options.tsx index 15312b7..f3fbb62 100644 --- a/src/lib/components/select/options.tsx +++ b/src/lib/components/select/auto-complete-options.tsx @@ -1,5 +1,7 @@ import React, { FC, Fragment, forwardRef } from 'react'; import { Combobox, Transition } from '@headlessui/react'; +import styles from './auto-complete.module.scss'; + interface Props { children: any; setQuery: (query: any) => void; @@ -9,14 +11,12 @@ export const AutoCompleteOptions: FC<Props> = ({ children, setQuery }) => { return ( <Transition as={Fragment} - leave="tw-transition tw-ease-in tw-duration-100" - leaveFrom="tw-opacity-100" - leaveTo="tw-opacity-0" + leave={styles.leave} + leaveFrom={styles.leaveFrom} + leaveTo={styles.leaveTo} afterLeave={() => setQuery('')} > - <Combobox.Options className="tw-max-h-[210px] tw-w-full tw-overflow-auto tw-bg-white tw-list-none tw-m-0 tw-px-0 tw-py-[10px] tw-text-base tw-shadow-[0_1px_6px_0_rgba(0,0,0,0.5)] focus:tw-outline-none sm:tw-text-sm [&::-webkit-scrollbar-thumb]:tw-rounded-md [&::-webkit-scrollbar-thumb]:tw-bg-[#a9a9a9] [&::-webkit-scrollbar]:tw-w-[6px]"> - {children} - </Combobox.Options> + <Combobox.Options className={styles.autocompleteOptions}>{children}</Combobox.Options> </Transition> ); }; diff --git a/src/lib/components/select/auto-complete.module.scss b/src/lib/components/select/auto-complete.module.scss new file mode 100644 index 0000000..312cf54 --- /dev/null +++ b/src/lib/components/select/auto-complete.module.scss @@ -0,0 +1,50 @@ +.autocomplete{ + @apply tw-relative; + .autocompleteContainer{ + @apply tw-relative tw-h-10 tw-w-full tw-cursor-default tw-overflow-hidden tw-bg-white tw-text-left tw-text-[#333333]; + &.disable{ + @apply tw-text-[#A7A7A7] + } + &:focus{ + @apply tw-outline-none; + } + &:focus-visible{ + @apply tw-ring-1 tw-ring-[#DFDFDF] tw-ring-offset-2 tw-ring-offset-[#DFDFDF]; + } + .autocompleteInput{ + @apply tw-h-full tw-w-full tw-box-border tw-border-0 tw-border-b-[1px] tw-border-b-[#333333] tw-pb-2 tw-pl-[10px] tw-pr-10 tw-pt-2 tw-text-base tw-leading-5 tw-placeholder-[#666666] tw-shadow-none; + &:focus{ + @apply tw-border-b-2 tw-border-b-[#006bb1] tw-pb-[7px] tw-outline-none tw-ring-[0px]; + } + &:focus-visible{ + @apply tw-ring-[0px]; + } + } + .autocompleteButton{ + @apply tw-absolute tw-inset-y-0 tw-right-0 tw-flex tw-items-center tw-pr-2 tw-bg-transparent tw-border-0; + .chevronDownIcon{ + @apply tw-h-5 tw-w-5 tw-text-[#333333]; + &.disable{ + @apply tw-text-[#A7A7A7]; + } + } + } + } +} + +.leave{ + @apply tw-transition tw-ease-in tw-duration-100; +} +.leaveFrom{ + @apply tw-opacity-100; +} +.leaveTo{ + @apply tw-opacity-0; +} + +.autocompleteOptions{ + @apply tw-max-h-[210px] tw-w-full tw-overflow-auto tw-bg-white tw-list-none tw-m-0 tw-px-0 tw-py-[10px] tw-text-base tw-shadow-[0_1px_6px_0_rgba(0,0,0,0.5)] sm:tw-text-sm [&::-webkit-scrollbar-thumb]:tw-rounded-md [&::-webkit-scrollbar-thumb]:tw-bg-[#a9a9a9] [&::-webkit-scrollbar]:tw-w-[6px]; + &:focus{ + @apply tw-outline-none; + } +} \ No newline at end of file diff --git a/src/lib/components/select/auto-complete.stories.tsx b/src/lib/components/select/auto-complete.stories.tsx index 35a8e1b..6992351 100644 --- a/src/lib/components/select/auto-complete.stories.tsx +++ b/src/lib/components/select/auto-complete.stories.tsx @@ -1,8 +1,8 @@ import type { Meta, StoryObj } from '@storybook/react'; import React from 'react'; import { AutoComplete } from './auto-complete'; -import { AutoCompleteOptions, AutoCompleteOption } from './options'; -import { IOption } from '../../interfaces/select.type'; +import { AutoCompleteOptions, AutoCompleteOption } from './auto-complete-options'; +import { IOption } from './select.types'; const meta: Meta<typeof AutoComplete> = { title: 'Basic/AutoComplete', diff --git a/src/lib/components/select/auto-complete.tsx b/src/lib/components/select/auto-complete.tsx index ac2acb2..65f56a3 100644 --- a/src/lib/components/select/auto-complete.tsx +++ b/src/lib/components/select/auto-complete.tsx @@ -5,6 +5,7 @@ import { ChevronDownIcon } from '@heroicons/react/20/solid'; import luminance from '@oncehub/relative-luminance'; import { ColorsService } from '../colors.service'; import { createPortal } from 'react-dom'; +import styles from './auto-complete.module.scss'; interface Props { children: any; @@ -157,17 +158,12 @@ export const AutoComplete: FC<Props> = ({ return ( <Combobox value={selected} onChange={onSelection} disabled={disable}> {({ open }) => ( - <div className="tw-relative "> - <div - ref={selectRef} - className={`tw-relative tw-h-10 tw-w-full tw-cursor-default tw-overflow-hidden tw-bg-white tw-text-left focus:tw-outline-none focus-visible:tw-ring-1 focus-visible:tw-ring-[#DFDFDF] focus-visible:tw-ring-offset-2 focus-visible:tw-ring-offset-[#DFDFDF] ${ - disable ? 'tw-text-[#A7A7A7]' : 'tw-text-[#333333]' - }`} - > + <div className={styles.autocomplete}> + <div ref={selectRef} className={`${styles.autocompleteContainer} ${disable ? 'disable' : ''}`}> <Combobox.Input ref={inputRef} data-testid={'select-input'} - className="tw-h-full tw-w-full tw-border-0 tw-border-b-[1px] tw-border-b-[#333333] tw-pb-2 tw-pl-[10px] tw-pr-10 tw-pt-2 tw-text-base tw-leading-5 tw-placeholder-[#666666] tw-shadow-none focus:tw-border-b-2 focus:tw-border-b-[#006bb1] focus:tw-pb-[7px] focus:tw-outline-none focus:tw-ring-[0px] focus-visible:tw-ring-[0px]" + className={styles.autocompleteInput} displayValue={displayInputValue} onChange={(event) => { setQuery(event.target.value); @@ -186,15 +182,12 @@ export const AutoComplete: FC<Props> = ({ autoComplete="off" /> <Combobox.Button - className="tw-absolute tw-inset-y-0 tw-right-0 tw-flex tw-items-center tw-pr-2" + className={styles.autocompleteButton} data-testid={'select-button'} ref={inputButton} onClick={getDropdownPosition} > - <ChevronDownIcon - className={`tw-h-5 tw-w-5 ${disable ? 'tw-text-[#A7A7A7]' : 'tw-text-[#333333]'}`} - aria-hidden="true" - /> + <ChevronDownIcon className={`${styles.chevronDownIcon} ${disable ? 'disable' : ''}`} aria-hidden="true" /> </Combobox.Button> </div> {isMounted @@ -211,8 +204,8 @@ export const AutoComplete: FC<Props> = ({ > <div ref={selectDropdownRef} - className="tw-absolute" style={{ + position: 'absolute', opacity: dropdownPosition.left ? 1 : 0, width: selectRef.current ? selectRef.current.clientWidth : 'auto', left: dropdownPosition.left, diff --git a/src/lib/components/select/index.tsx b/src/lib/components/select/index.tsx index 6624d50..b7d1e21 100644 --- a/src/lib/components/select/index.tsx +++ b/src/lib/components/select/index.tsx @@ -1,5 +1,5 @@ export * from './select'; export * from './select-options'; export * from './auto-complete'; -export * from './options'; +export * from './auto-complete-options'; export * from './select.types'; diff --git a/src/lib/components/select/select-options.tsx b/src/lib/components/select/select-options.tsx index 80ac982..c7d0528 100644 --- a/src/lib/components/select/select-options.tsx +++ b/src/lib/components/select/select-options.tsx @@ -1,5 +1,6 @@ import React, { FC, Fragment, forwardRef } from 'react'; import { Listbox, Transition } from '@headlessui/react'; +import styles from './select.module.scss'; interface Props { children: any; setQuery: (query: any) => void; @@ -9,14 +10,12 @@ export const SelectOptions: FC<Props> = ({ children, setQuery }) => { return ( <Transition as={Fragment} - leave="tw-transition tw-ease-in tw-duration-100" - leaveFrom="tw-opacity-100" - leaveTo="tw-opacity-0" + leave={styles.leave} + leaveFrom={styles.leaveFrom} + leaveTo={styles.leaveTo} afterLeave={() => setQuery('')} > - <Listbox.Options className="tw-max-h-[200px] tw-w-full tw-overflow-auto tw-bg-white tw-list-none tw-m-0 tw-px-0 tw-py-[10px] tw-text-base tw-shadow-[0_1px_6px_0_rgba(0,0,0,0.5)] focus:tw-outline-none sm:tw-text-sm [&::-webkit-scrollbar-thumb]:tw-rounded-md [&::-webkit-scrollbar-thumb]:tw-bg-[#a9a9a9] [&::-webkit-scrollbar]:tw-w-[6px]"> - {children} - </Listbox.Options> + <Listbox.Options className={styles.selectOptions}>{children}</Listbox.Options> </Transition> ); }; diff --git a/src/lib/components/select/select.module.scss b/src/lib/components/select/select.module.scss new file mode 100644 index 0000000..fdbb4a3 --- /dev/null +++ b/src/lib/components/select/select.module.scss @@ -0,0 +1,47 @@ +.select { + @apply tw-relative; + .selectContainer { + @apply tw-relative; + .selectButton { + @apply tw-border-solid tw-border-x-0 tw-relative tw-box-border tw-h-10 tw-w-full tw-cursor-pointer tw-border-b tw-border-t tw-border-t-transparent tw-bg-white tw-py-1.5 tw-pl-[10px] tw-pr-8 tw-text-left tw-text-base tw-text-[#333333] tw-border-b-[#333333]; + &:focus { + @apply tw-border-b-2 tw-border-t-2 tw-border-b-[#006bb1] tw-py-[5px] tw-outline-none tw-ring-0; + } + &.open { + @apply tw-border-b-2 tw-border-t-2 tw-border-b-[#006bb1]; + } + .selectValue { + @apply tw-flex tw-items-center; + .seletIcon { + @apply tw-mr-2 tw-h-5 tw-w-5 tw-flex-shrink-0; + } + .selectText { + @apply tw-block tw-truncate; + } + } + .chevronDownIconSpan { + @apply tw-pointer-events-none tw-absolute tw-inset-y-0 tw-right-0 tw-flex tw-items-center tw-pr-2; + .chevronDownIcon { + @apply tw-h-5 tw-w-5 tw-text-[#333333]; + } + } + } + } +} + +.leave { + @apply tw-transition tw-ease-in tw-duration-100; +} +.leaveFrom { + @apply tw-opacity-100; +} +.leaveTo { + @apply tw-opacity-0; +} + +.selectOptions { + @apply tw-max-h-[200px] tw-w-full tw-overflow-auto tw-bg-white tw-list-none tw-m-0 tw-px-0 tw-py-[10px] tw-text-base tw-shadow-[0_1px_6px_0_rgba(0,0,0,0.5)] sm:tw-text-sm [&::-webkit-scrollbar-thumb]:tw-rounded-md [&::-webkit-scrollbar-thumb]:tw-bg-[#a9a9a9] [&::-webkit-scrollbar]:tw-w-[6px]; + &:focus { + @apply tw-outline-none; + } +} diff --git a/src/lib/components/select/select.stories.tsx b/src/lib/components/select/select.stories.tsx index 7681e3c..110028b 100644 --- a/src/lib/components/select/select.stories.tsx +++ b/src/lib/components/select/select.stories.tsx @@ -1,6 +1,5 @@ import type { Meta, StoryObj } from '@storybook/react'; import React from 'react'; - import { Select } from './select'; import { SelectOption, SelectOptions } from './select-options'; import { IOption } from './select.types'; diff --git a/src/lib/components/select/select.tsx b/src/lib/components/select/select.tsx index 285e313..e965805 100644 --- a/src/lib/components/select/select.tsx +++ b/src/lib/components/select/select.tsx @@ -5,6 +5,7 @@ import { ChevronDownIcon } from '@heroicons/react/20/solid'; import luminance from '@oncehub/relative-luminance'; import { ColorsService } from '../colors.service'; import { createPortal } from 'react-dom'; +import styles from './select.module.scss'; interface Props { children: any; selected: IOption | null; @@ -110,8 +111,8 @@ export const Select: FC<Props> = ({ children, selected, onSelect, themeColor }) return ( <Listbox value={selected} onChange={onSelection}> {({ open }) => ( - <div className={'tw-relative'}> - <div className="tw-relative" ref={selectRef}> + <div className={styles.select}> + <div className={styles.selectContainer} ref={selectRef}> <Listbox.Button data-testid={'select-options'} onFocus={handleFocus} @@ -123,21 +124,16 @@ export const Select: FC<Props> = ({ children, selected, onSelect, themeColor }) } }} style={{ borderBottomColor: themeColor && (isFocused || open) ? borderColor : '' }} - className={ - `tw-border-solid tw-border-x-0 tw-relative tw-h-10 tw-w-full tw-cursor-pointer tw-border-b tw-border-t tw-border-t-transparent tw-bg-white tw-py-1.5 tw-pl-[10px] tw-pr-8 tw-text-left tw-text-base tw-text-[#333333] focus:tw-border-b-2 focus:tw-border-t-2 focus:tw-border-b-[#006bb1] focus:tw-py-[5px] focus:tw-outline-none focus:tw-ring-0` + - (open ? ' tw-border-b-2 tw-border-t-2 tw-border-b-[#006bb1]' : ' tw-border-b-[#333333]') - } + className={`${styles.selectButton} ${open ? ' open' : ''}`} > {selected && ( - <span className="tw-flex tw-items-center"> - {selected.avatar && ( - <img src={selected.avatar} alt="" className="tw-mr-2 tw-h-5 tw-w-5 tw-flex-shrink-0" /> - )} - <span className="tw-block tw-truncate">{selected.label}</span> + <span className={styles.selectValue}> + {selected.avatar && <img src={selected.avatar} alt="" className={styles.seletIcon} />} + <span className={styles.selectText}>{selected.label}</span> </span> )} - <span className="tw-pointer-events-none tw-absolute tw-inset-y-0 tw-right-0 tw-flex tw-items-center tw-pr-2"> - <ChevronDownIcon className={'tw-h-5 tw-w-5 tw-text-[#333333]'} aria-hidden="true" /> + <span className={styles.chevronDownIconSpan}> + <ChevronDownIcon className={styles.chevronDownIcon} aria-hidden="true" /> </span> </Listbox.Button> </div> @@ -155,8 +151,8 @@ export const Select: FC<Props> = ({ children, selected, onSelect, themeColor }) > <div ref={selectDropdownRef} - className="tw-absolute" style={{ + position: 'absolute', opacity: dropdownPosition.left ? 1 : 0, width: selectRef.current ? selectRef.current.clientWidth : 'auto', left: dropdownPosition.left,