From 75f82b3bc7107bc9b7afbb3da8a4e3700c9e2b63 Mon Sep 17 00:00:00 2001 From: Chirag Chhatrala <60499540+chiragchhatrala@users.noreply.github.com> Date: Fri, 3 Jan 2025 20:45:47 +0530 Subject: [PATCH] Refactor form components (#659) * Add Barcode Input Component and Integrate Quagga for Scanning - Introduced a new BarcodeInput component for scanning barcodes using the Quagga library. - Updated package.json and package-lock.json to include Quagga as a dependency. - Enhanced form themes to accommodate the new BarcodeInput component. - Added localization support for barcode scanning actions in English. - Updated blocks_types.json to register the new barcode input type. These changes improve the application's functionality by allowing users to scan barcodes directly within forms, enhancing user experience and data input efficiency. * Update Barcode scanner UI * Barcode decoder as user selection * improve barcode * Refactor form components and update Tailwind configuration - Removed unused box shadow styles from tailwind.config.js. - Enhanced DateInput, FileInput, MatrixInput, RichTextAreaInput, and VSelect components with improved styling and error handling. - Updated theme settings in form-themes.js to include new styles for MatrixInput and other form elements. - Adjusted labels in FieldOptions.vue for clarity. - Improved overall UI consistency and responsiveness across form components. --------- Co-authored-by: Julien Nahum <julien@nahum.net> --- client/components/forms/DateInput.vue | 6 +- client/components/forms/FileInput.vue | 1 + client/components/forms/MatrixInput.vue | 19 ++- .../forms/RichTextAreaInput.client.vue | 24 ++- .../components/forms/components/VSelect.vue | 93 +++++------ .../form-components/FormCustomization.vue | 2 +- .../forms/fields/components/FieldOptions.vue | 2 +- client/lib/forms/themes/form-themes.js | 146 ++++++++++-------- client/tailwind.config.js | 6 +- 9 files changed, 175 insertions(+), 124 deletions(-) diff --git a/client/components/forms/DateInput.vue b/client/components/forms/DateInput.vue index 912c333c6..52156168e 100644 --- a/client/components/forms/DateInput.vue +++ b/client/components/forms/DateInput.vue @@ -59,7 +59,7 @@ </div> </button> - <template #panel="{ close }"> + <template #panel> <DatePicker v-if="props.dateRange" v-model.range="modeledValue" @@ -157,9 +157,11 @@ const inputClasses = computed(() => { classes.push('!cursor-not-allowed !bg-gray-200 dark:!bg-gray-800') } if (input.hasError.value) { - classes.push('!ring-red-500 !ring-2 !border-transparent') } + if (!props.disabled && !input.hasError.value && pickerOpen.value) { + classes.push('ring-2 ring-opacity-100 border-transparent') + } return classes.join(' ') }) diff --git a/client/components/forms/FileInput.vue b/client/components/forms/FileInput.vue index e97d809b5..8615f2215 100644 --- a/client/components/forms/FileInput.vue +++ b/client/components/forms/FileInput.vue @@ -23,6 +23,7 @@ class="flex flex-col w-full items-center justify-center transition-colors duration-40" :class="[ {'!cursor-not-allowed':disabled, 'cursor-pointer':!disabled, + '!bg-gray-200 dark:!bg-gray-800': disabled, [theme.fileInput.inputHover.light + ' dark:'+theme.fileInput.inputHover.dark]: uploadDragoverEvent, ['hover:'+theme.fileInput.inputHover.light +' dark:hover:'+theme.fileInput.inputHover.dark]: !loading}, theme.fileInput.input, diff --git a/client/components/forms/MatrixInput.vue b/client/components/forms/MatrixInput.vue index eea0c2313..bc3368f8c 100644 --- a/client/components/forms/MatrixInput.vue +++ b/client/components/forms/MatrixInput.vue @@ -4,9 +4,11 @@ <slot name="label" /> </template> <div - class="border border-gray-300 overflow-x-auto" + class="border overflow-x-auto" :class="[ theme.default.borderRadius, + theme.MatrixInput.cell, + theme.MatrixInput.table, { '!ring-red-500 !ring-2 !border-transparent': hasError, }, @@ -19,7 +21,8 @@ <td v-for="column in columns" :key="column" - class="ltr:border-l rtl:border-r rtl:!border-l-0 border-gray-300 max-w-24 overflow-hidden" + class="ltr:border-l rtl:border-r rtl:!border-l-0 max-w-24 overflow-hidden" + :class="theme.MatrixInput.cell" > <div class="p-2 w-full flex items-center justify-center text-sm"> {{ column }} @@ -41,10 +44,14 @@ <td v-for="column in columns" :key="row + column" - class="ltr:border-l rtl:border-r rtl:!border-l-0 border-gray-300 hover:!bg-gray-100 dark:hover:!bg-gray-800" - :class="{ - '!cursor-not-allowed !bg-gray-200 dark:!bg-gray-800 hover:!bg-gray-200 dark:hover:!bg-gray-800': disabled, - }" + class="ltr:border-l rtl:border-r rtl:!border-l-0" + :class="[ + theme.MatrixInput.cell, + theme.MatrixInput.cellHover, + { + '!cursor-not-allowed !bg-gray-200 dark:!bg-gray-800 hover:!bg-gray-200 dark:hover:!bg-gray-800': disabled, + }, + ]" > <div v-if="compVal" diff --git a/client/components/forms/RichTextAreaInput.client.vue b/client/components/forms/RichTextAreaInput.client.vue index c7098659a..c85469d2b 100644 --- a/client/components/forms/RichTextAreaInput.client.vue +++ b/client/components/forms/RichTextAreaInput.client.vue @@ -1,5 +1,8 @@ <template> - <InputWrapper v-bind="inputWrapperProps"> + <InputWrapper + v-bind="inputWrapperProps" + wrapper-class="not-draggable" + > <template #label> <slot name="label" /> </template> @@ -10,19 +13,20 @@ { '!ring-red-500 !ring-2 !border-transparent': hasError, '!cursor-not-allowed !bg-gray-200 dark:!bg-gray-800': disabled, + 'focus-within:ring-2 focus-within:ring-opacity-100 focus-within:border-transparent': !hasError && !disabled }, theme.RichTextAreaInput.input, theme.RichTextAreaInput.borderRadius, theme.default.fontSize, ]" :style="{ - '--font-size': theme.default.fontSize + '--font-size': theme.default.fontSize, + ...inputStyle }" > <QuillyEditor :id="id ? id : name" ref="editor" - :key="id+placeholder" v-model="compVal" :options="quillOptions" :disabled="disabled" @@ -37,7 +41,6 @@ <template #error> <slot name="error" /> </template> - <MentionDropdown v-if="enableMentions && mentionState" :state="mentionState" @@ -53,6 +56,7 @@ import InputWrapper from './components/InputWrapper.vue' import QuillyEditor from './components/QuillyEditor.vue' import MentionDropdown from './components/MentionDropdown.vue' import registerMentionExtension from '~/lib/quill/quillMentionExtension.js' + const props = defineProps({ ...inputProps, editorOptions: { @@ -68,7 +72,9 @@ const props = defineProps({ default: () => [] } }) + const emit = defineEmits(['update:modelValue']) + const { compVal, inputStyle, hasError, inputWrapperProps } = useFormInput(props, { emit }) const editor = ref(null) const mentionState = ref(null) @@ -91,6 +97,7 @@ const quillOptions = computed(() => { ] } } + const mergedOptions = { ...defaultOptions, ...props.editorOptions, modules: { ...defaultOptions.modules, ...props.editorOptions.modules } } if (props.enableMentions) { @@ -112,21 +119,26 @@ const quillOptions = computed(() => { border-right: 0px !important; border-left: 0px !important; font-size: var(--font-size); + .ql-editor { min-height: 100px !important; } } + .ql-toolbar { border-top: 0px !important; border-right: 0px !important; border-left: 0px !important; } + .ql-header { @apply rounded-md; } + .ql-editor.ql-blank:before { @apply text-gray-400 dark:text-gray-500 not-italic; } + .ql-snow .ql-toolbar .ql-picker-item.ql-selected, .ql-snow .ql-toolbar .ql-picker-item:hover, .ql-snow .ql-toolbar .ql-picker-label.ql-active, @@ -144,14 +156,16 @@ const quillOptions = computed(() => { @apply text-nt-blue; } } + .ql-mention { padding-top: 0px !important; - margin-top: -5px !important; } .ql-mention::after { content: '@'; font-size: 16px; } + + .rich-editor, .mention-input { span[mention] { @apply inline-flex items-center align-baseline leading-tight text-sm relative bg-blue-100 text-blue-800 border border-blue-200 rounded-md px-1 py-0.5 mx-0.5; diff --git a/client/components/forms/components/VSelect.vue b/client/components/forms/components/VSelect.vue index 3e65b6080..dc851723a 100644 --- a/client/components/forms/components/VSelect.vue +++ b/client/components/forms/components/VSelect.vue @@ -13,7 +13,7 @@ { '!ring-red-500 !ring-2 !border-transparent': hasError, '!cursor-not-allowed !bg-gray-200 dark:!bg-gray-800': disabled, - 'focus-within:ring-2 focus-within:ring-opacity-100 focus-within:border-transparent': !hasError + 'focus-within:ring-2 focus-within:ring-opacity-100 focus-within:border-transparent': !hasError && !disabled }, inputClass ]" @@ -78,9 +78,13 @@ </transition> </div> <div - class="absolute inset-y-0 ltr:right-6 rtl:left-6 w-10 pointer-events-none bg-gradient-to-r from-transparent to-white dark:to-notion-dark-light" + class="absolute inset-y-0 ltr:right-6 rtl:left-6 w-10 pointer-events-none -z-[1]" + :class="[disabled ? 'bg-gradient-to-r from-transparent to-gray-200 dark:to-gray-800' : theme.SelectInput.chevronGradient]" /> - <span class="absolute inset-y-0 ltr:right-0 rtl:left-0 rtl:!right-auto flex items-center ltr:pr-2 rtl:pl-2 rtl:!pr-0 pointer-events-none bg-white"> + <span + class="absolute inset-y-0 ltr:right-0 rtl:left-0 rtl:!right-auto flex items-center ltr:pr-2 rtl:pl-2 rtl:!pr-0 pointer-events-none" + :class="[disabled ? 'bg-gray-200 dark:bg-gray-800' : theme.SelectInput.background]" + > <Icon name="heroicons:chevron-up-down-16-solid" class="h-5 w-5 text-gray-500" @@ -88,7 +92,7 @@ </span> </button> <button - v-if="clearable && showClearButton && !isEmpty" + v-if="clearable && showClearButton && !disabled && !isEmpty" class="hover:bg-gray-50 dark:hover:bg-gray-900 ltr:border-l rtl:!border-l-0 rtl:border-r px-2 flex items-center" :class="[theme.SelectInput.spacing.vertical]" @click.prevent="clear()" @@ -208,47 +212,47 @@ <script> import Collapsible from '~/components/global/transitions/Collapsible.vue' -import CachedDefaultTheme from "~/lib/forms/themes/CachedDefaultTheme.js" import debounce from 'debounce' import Fuse from 'fuse.js' +import CachedDefaultTheme from '~/lib/forms/themes/CachedDefaultTheme.js' export default { name: 'VSelect', - components: {Collapsible}, + components: { Collapsible }, directives: {}, props: { data: Array, - modelValue: {default: null, type: [String, Number, Array, Object]}, - inputClass: {type: String, default: null}, - dropdownClass: {type: String, default: 'w-full'}, - loading: {type: Boolean, default: false}, - required: {type: Boolean, default: false}, - multiple: {type: Boolean, default: false}, - searchable: {type: Boolean, default: false}, - clearable: {type: Boolean, default: false}, - hasError: {type: Boolean, default: false}, - remote: {type: Function, default: null}, - searchKeys: {type: Array, default: () => ['name']}, - optionKey: {type: String, default: 'id'}, - emitKey: {type: String, default: null}, - color: {type: String, default: '#3B82F6'}, - placeholder: {type: String, default: null}, + modelValue: { default: null, type: [String, Number, Array, Object, Boolean] }, + inputClass: { type: String, default: null }, + dropdownClass: { type: String, default: 'w-full' }, + loading: { type: Boolean, default: false }, + required: { type: Boolean, default: false }, + multiple: { type: Boolean, default: false }, + searchable: { type: Boolean, default: false }, + clearable: { type: Boolean, default: false }, + hasError: { type: Boolean, default: false }, + remote: { type: Function, default: null }, + searchKeys: { type: Array, default: () => ['name'] }, + optionKey: { type: String, default: 'id' }, + emitKey: { type: String, default: null }, + color: { type: String, default: '#3B82F6' }, + placeholder: { type: String, default: null }, uppercaseLabels: { type: Boolean, default: true }, showClearButton: { type: Boolean, default: true }, theme: { type: Object, default: () => { - const theme = inject("theme", null) + const theme = inject('theme', null) if (theme) { return theme.value } return CachedDefaultTheme.getInstance() } }, - allowCreation: {type: Boolean, default: false}, - disabled: {type: Boolean, default: false} + allowCreation: { type: Boolean, default: false }, + disabled: { type: Boolean, default: false } }, emits: ['update:modelValue', 'update-options', 'focus', 'blur'], - data() { + data () { return { isOpen: false, searchTerm: '', @@ -257,46 +261,46 @@ export default { } }, computed: { - optionStyle() { + optionStyle () { return { '--bg-form-color': this.color } }, - inputStyle() { + inputStyle () { return { '--tw-ring-color': this.color } }, - debouncedRemote() { + debouncedRemote () { if (this.remote) { return debounce(this.remote, 300) } return null }, - filteredOptions() { + filteredOptions () { if (!this.data) return [] if (!this.searchable || this.remote || this.searchTerm === '') { return this.data } // Fuse search - const fuse = new Fuse(this.data, { - keys: this.searchKeys, - includeScore: true - }) - return fuse.search(this.searchTerm).filter((res) => res.score < 0.5).map((res) => { + const fuzeOptions = { + keys: this.searchKeys + } + const fuse = new Fuse(this.data, fuzeOptions) + return fuse.search(this.searchTerm).map((res) => { return res.item }) }, - isSearchable() { + isSearchable () { return this.searchable || this.remote !== null || this.allowCreation }, - isEmpty() { + isEmpty () { return this.multiple ? !this.modelValue || this.modelValue.length === 0 : !this.modelValue } }, watch: { - searchTerm(val) { + searchTerm (val) { if (!this.debouncedRemote) return if ((this.remote && val) || (val === '' && !this.modelValue) || (val === '' && this.isOpen)) { return this.debouncedRemote(val) @@ -304,13 +308,13 @@ export default { } }, methods: { - onClickAway(event) { + onClickAway (event) { // Check that event target isn't children of dropdown if (this.$refs.select && !this.$refs.select.contains(event.target)) { this.isOpen = false } }, - isSelected(value) { + isSelected (value) { if (!this.modelValue) return false if (this.emitKey && value[this.emitKey]) { @@ -323,16 +327,18 @@ export default { return this.modelValue === value }, onFocus(event) { + if (this.disabled) return this.isFocused = true this.$emit('focus', event) }, onBlur(event) { + if (this.disabled) return this.isFocused = false this.$emit('blur', event) }, - toggleDropdown() { + toggleDropdown () { if (this.disabled) { this.isOpen = false } else { @@ -347,7 +353,7 @@ export default { this.searchTerm = '' } }, - select(value) { + select (value) { if (!this.multiple) { // Close after select this.toggleDropdown() @@ -382,10 +388,10 @@ export default { } } }, - clear() { + clear () { this.$emit('update:modelValue', this.multiple ? [] : null) }, - createOption(newOption) { + createOption (newOption) { if (newOption) { const newItem = { name: newOption, @@ -400,3 +406,4 @@ export default { } } </script> + diff --git a/client/components/open/forms/components/form-components/FormCustomization.vue b/client/components/open/forms/components/form-components/FormCustomization.vue index e920fdea2..2c141d4ec 100644 --- a/client/components/open/forms/components/form-components/FormCustomization.vue +++ b/client/components/open/forms/components/form-components/FormCustomization.vue @@ -11,8 +11,8 @@ class="mt-4" :options="[ { name: 'Default', value: 'default' }, - { name: 'Simple', value: 'simple' }, { name: 'Notion', value: 'notion' }, + { name: 'Simple (no shadows)', value: 'simple' }, ]" :form="form" label="Form Theme" diff --git a/client/components/open/forms/fields/components/FieldOptions.vue b/client/components/open/forms/fields/components/FieldOptions.vue index 3197abee1..9d411c73c 100644 --- a/client/components/open/forms/fields/components/FieldOptions.vue +++ b/client/components/open/forms/fields/components/FieldOptions.vue @@ -231,7 +231,7 @@ :form="field" class="mt-3" name="date_range" - label="End date" + label="Include end date" @update:model-value="onFieldDateRangeChange" /> <toggle-switch-input diff --git a/client/lib/forms/themes/form-themes.js b/client/lib/forms/themes/form-themes.js index 62a1f0cf6..16886bd00 100644 --- a/client/lib/forms/themes/form-themes.js +++ b/client/lib/forms/themes/form-themes.js @@ -1,7 +1,7 @@ /** Input classes for each supported form themes */ -export const themes = { + export const themes = { default: { default: { wrapper: { @@ -9,7 +9,7 @@ export const themes = { md: 'relative my-1.5', lg: 'relative my-1.5', }, - label: 'text-gray-700 dark:text-gray-300 font-medium', + label: 'text-gray-700 dark:text-gray-300 font-semibold', input: 'flex-1 appearance-none border border-gray-300 dark:border-gray-600 w-full bg-white text-gray-700 dark:bg-notion-dark-light dark:text-gray-300 dark:placeholder-gray-500 placeholder-gray-400 shadow-sm focus:outline-none focus:ring-2 focus:border-transparent focus:ring-opacity-100', help: 'text-gray-500', @@ -66,8 +66,30 @@ export const themes = { lg: 'min-h-[28px]' } }, + PhoneInput: { + countrySelectWidth: { + sm: 'w-[100px]', + md: 'w-[120px]', + lg: 'w-[120px]' + }, + flag: { + sm: '!-mt-[14px]', + md: '!-mt-[9px] rounded', + lg: '!-mt-[9px] rounded' + }, + flagSize: { + sm: 'small', + md: 'normal', + lg: 'normal' + }, + maxHeight: { + sm: 'max-h-[20px]', + md: 'max-h-[24px]', + lg: 'max-h-[28px]' + } + }, FlatSelectInput: { - option: 'cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-900 flex items-center space-x-2 border-t first:border-t-0 px-2', + option: 'cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-900 flex items-center gap-x-2 border-t first:border-t-0 px-2', unselectedIcon: 'text-gray-300 dark:text-gray-600', icon: { sm: 'w-4 h-4', @@ -75,40 +97,18 @@ export const themes = { lg: 'w-6 h-6 mx-1' } }, - PhoneInput: { - countrySelectWidth: { - sm: 'w-[100px]', - md: 'w-[120px]', - lg: 'w-[120px]' - }, - flag: { - sm: '!-mt-[14px]', - md: '!-mt-[9px] rounded', - lg: '!-mt-[9px] rounded' - }, - flagSize: { - sm: 'small', - md: 'normal', - lg: 'normal' - }, - maxHeight: { - sm: 'max-h-[20px]', - md: 'max-h-[24px]', - lg: 'max-h-[28px]' - } - }, DateInput: { input: 'flex-1 appearance-none border border-gray-300 dark:border-gray-600 w-full bg-white text-gray-700 dark:bg-notion-dark-light dark:text-gray-300 dark:placeholder-gray-500 placeholder-gray-400 shadow-sm text-base focus:outline-none focus:ring-2 focus:border-transparent focus:ring-opacity-100' }, - CheckboxInput: { + CheckboxInput:{ size: { sm: 'w-4 h-4', md: 'w-5 h-5', lg: 'w-5 h-5' }, }, - SwitchInput: { + SwitchInput:{ containerSize: { sm: 'h-5 w-10 p-0.5', md: 'h-6 w-12 p-1', @@ -125,7 +125,7 @@ export const themes = { lg: 'translate-x-6' } }, - RatingInput: { + RatingInput:{ size: { sm: 'w-6 h-6', md: 'w-8 h-8', @@ -153,6 +153,11 @@ export const themes = { md: 'min-h-40', lg: 'min-h-48' }, + }, + MatrixInput: { + table: 'bg-white dark:bg-notion-dark-light shadow-sm', + cell: 'border-gray-300 dark:border-gray-600', + cellHover: 'hover:bg-gray-50 dark:hover:bg-gray-900' } }, simple: { @@ -219,15 +224,6 @@ export const themes = { lg: 'min-h-[28px]' } }, - FlatSelectInput: { - option: 'cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-900 flex items-center space-x-2 border-t first:border-t-0 px-2', - unselectedIcon: 'text-gray-300 dark:text-gray-600', - icon: { - sm: 'w-4 h-4', - md: 'w-5 h-5', - lg: 'w-6 h-6 mx-1' - } - }, PhoneInput: { countrySelectWidth: { sm: 'w-[100px]', @@ -250,17 +246,26 @@ export const themes = { lg: 'max-h-[28px]' } }, + FlatSelectInput: { + option: 'cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-900 flex items-center space-x-2 border-t first:border-t-0 px-2', + unselectedIcon: 'text-gray-300 dark:text-gray-600', + icon: { + sm: 'w-4 h-4', + md: 'w-5 h-5', + lg: 'w-6 h-6 mx-1' + } + }, DateInput: { input: 'flex-1 appearance-none border border-gray-300 dark:border-gray-600 w-full bg-white text-gray-700 dark:bg-notion-dark-light dark:text-gray-300 placeholder-gray-400 text-base focus:outline-none focus:ring-2 focus:border-transparent focus:ring-opacity-100' }, - CheckboxInput: { + CheckboxInput:{ size: { sm: 'w-4 h-4', md: 'w-5 h-5', lg: 'w-5 h-5' }, }, - SwitchInput: { + SwitchInput:{ containerSize: { sm: 'h-5 w-10', md: 'h-6 w-12', @@ -272,7 +277,7 @@ export const themes = { lg: 'h-4 w-4' }, }, - RatingInput: { + RatingInput:{ size: { sm: 'w-6 h-6', md: 'w-8 h-8', @@ -300,6 +305,11 @@ export const themes = { md: 'min-h-40', lg: 'min-h-48' }, + }, + MatrixInput: { + table: 'bg-white dark:bg-notion-dark-light', + cell: 'border-gray-300 dark:border-gray-600', + cellHover: 'hover:bg-gray-50 dark:hover:bg-gray-900' } }, notion: { @@ -311,7 +321,7 @@ export const themes = { }, label: 'text-gray-900 dark:text-gray-100 mb-1 block mt-4', input: - 'rounded border-transparent flex-1 appearance-none shadow-inner-notion w-full bg-notion-input-background dark:bg-notion-dark-light text-gray-900 dark:text-gray-100 dark:placeholder-gray-500 placeholder-gray-400 focus:outline-none focus:ring-0 focus:border-transparent focus:shadow-focus-notion', + 'rounded border border-notion-input-border dark:border-notion-input-borderDark flex-1 appearance-none w-full bg-notion-input-background dark:bg-notion-dark-light text-gray-900 dark:text-gray-100 dark:placeholder-gray-500 placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-opacity-40 focus:border-transparent', help: 'text-gray-500', spacing: { horizontal: { @@ -337,28 +347,28 @@ export const themes = { } }, ScaleInput: { - button: 'border-transparent flex-1 appearance-none shadow-inner-notion w-full bg-notion-input-background dark:bg-notion-dark-light text-gray-900 dark:text-gray-100 text-center', - unselectedButton: 'bg-notion-input-background dark:bg-notion-dark-light border' + button: 'border border-notion-input-border dark:border-notion-input-borderDark flex-1 appearance-none w-full bg-notion-input-background dark:bg-notion-dark-light text-gray-900 dark:text-gray-100 text-center focus:outline-none focus:ring-2 focus:ring-opacity-40 focus:border-transparent', + unselectedButton: 'bg-notion-input-background dark:bg-notion-dark-light' }, SliderInput: { stepLabel: 'text-gray-700 dark:text-gray-300 text-center text-xs' }, Button: { - body: 'transition ease-in duration-200 text-center font-semibold shadow shadow-inner-notion focus:outline-none focus:ring-2 focus:ring-offset-2 filter hover:brightness-90' + body: 'transition ease-in duration-200 text-center font-semibold border border-notion-input-border dark:border-notion-input-borderDark focus:outline-none focus:ring-2 focus:ring-opacity-40 focus:border-transparent filter hover:brightness-90' }, CodeInput: { - input: 'shadow-inner-notion border-transparent focus:border-transparent overflow-hidden' + input: 'border border-notion-input-border dark:border-notion-input-borderDark focus:outline-none focus:ring-2 focus:ring-opacity-40 focus:border-transparent overflow-hidden' }, RichTextAreaInput: { input: - 'flex-1 appearance-none shadow-inner-notion border-transparent focus:border-transparent w-full text-gray-900 bg-notion-input-background dark:bg-notion-dark-light dark:placeholder-gray-500 placeholder-gray-400 text-base focus:outline-none focus:ring-0 focus:ring-opacity-100 focus:border-transparent focus:ring-0 focus:shadow-focus-notion' + 'flex-1 appearance-none border border-notion-input-border dark:border-notion-input-borderDark w-full bg-notion-input-background dark:bg-notion-dark-light text-gray-900 dark:text-gray-100 dark:placeholder-gray-500 placeholder-gray-400 text-base focus:outline-none focus:ring-2 focus:ring-opacity-40 focus:border-transparent' }, SelectInput: { input: - 'relative w-full border-transparent flex-1 appearance-none shadow-inner-notion w-full text-gray-900 dark:text-gray-100 placeholder-gray-400 dark:placeholder-gray-500 text-base focus:outline-none focus:ring-0 focus:border-transparent focus:shadow-focus-notion', + 'relative w-full border border-notion-input-border dark:border-notion-input-borderDark flex-1 appearance-none w-full text-gray-900 dark:text-gray-100 placeholder-gray-400 dark:placeholder-gray-500 text-base focus:outline-none focus:ring-2 focus:ring-opacity-40 focus:border-transparent', background: 'bg-notion-input-background dark:bg-notion-dark-light', chevronGradient: 'bg-gradient-to-r from-transparent to-notion-input-background dark:to-notion-dark-light', - dropdown: 'border border-gray-300 dark:border-gray-600', + dropdown: 'border border-notion-input-border dark:border-notion-input-borderDark', option: 'rounded', minHeight: { sm: 'min-h-[20px]', @@ -366,15 +376,6 @@ export const themes = { lg: 'min-h-[28px]' } }, - FlatSelectInput: { - option: 'cursor-pointer hover:backdrop-brightness-95 flex items-center space-x-2 border-t border-neutral-300 first:border-t-0 px-2', - unselectedIcon: 'text-neutral-300 dark:text-neutral-600', - icon: { - sm: 'w-4 h-4', - md: 'w-5 h-5', - lg: 'w-6 h-6 mx-1' - } - }, PhoneInput: { countrySelectWidth: { sm: 'w-[100px]', @@ -397,17 +398,26 @@ export const themes = { lg: 'max-h-[28px]' } }, + FlatSelectInput: { + option: 'cursor-pointer hover:backdrop-brightness-95 flex items-center space-x-2 border-t border-neutral-300 first:border-t-0 px-2', + unselectedIcon: 'text-neutral-300 dark:text-neutral-600', + icon: { + sm: 'w-4 h-4', + md: 'w-5 h-5', + lg: 'w-6 h-6 mx-1' + } + }, DateInput: { - input: 'shadow-inner-notion border-transparent focus:border-transparent flex-1 appearance-none w-full bg-notion-input-background dark:bg-notion-dark-light text-gray-900 dark:text-gray-100 placeholder-gray-400 text-base focus:outline-none focus:ring-0 focus:border-transparent focus:shadow-focus-notion p-[1px]' + input: 'border border-notion-input-border dark:border-notion-input-borderDark flex-1 appearance-none w-full bg-notion-input-background dark:bg-notion-dark-light text-gray-900 dark:text-gray-100 placeholder-gray-400 text-base focus:outline-none focus:ring-2 focus:ring-opacity-40 focus:border-transparent' }, - CheckboxInput: { + CheckboxInput:{ size: { sm: 'w-4 h-4', md: 'w-5 h-5', lg: 'w-5 h-5' }, }, - SwitchInput: { + SwitchInput:{ containerSize: { sm: 'h-5 w-10', md: 'h-6 w-12', @@ -418,8 +428,13 @@ export const themes = { md: 'h-4 w-4', lg: 'h-4 w-4' }, + translatedClass: { + sm: 'translate-x-5', + md: 'translate-x-6', + lg: 'translate-x-6' + } }, - RatingInput: { + RatingInput:{ size: { sm: 'w-6 h-6', md: 'w-8 h-8', @@ -428,7 +443,7 @@ export const themes = { }, fileInput: { input: - 'p-4 rounded bg-notion-input-background dark:bg-notion-dark', + 'p-4 rounded border border-dashed border-notion-input-border dark:border-notion-input-borderDark bg-notion-input-background dark:bg-notion-dark-light focus:outline-none focus:ring-2 focus:ring-opacity-40 focus:border-transparent', minHeight: { sm: 'min-h-28', md: 'min-h-40', @@ -439,7 +454,7 @@ export const themes = { dark: 'bg-notion-dark-light' }, uploadedFile: - 'border border-gray-300 dark:border-gray-600 bg-white dark:bg-notion-dark-light rounded shadow-sm max-w-[10rem]' + 'border border-notion-input-border dark:border-notion-input-borderDark bg-white dark:bg-notion-dark-light rounded max-w-[10rem] focus:outline-none focus:ring-2 focus:ring-opacity-40 focus:border-transparent' }, SignatureInput: { minHeight: { @@ -447,6 +462,11 @@ export const themes = { md: 'min-h-40', lg: 'min-h-48' }, + }, + MatrixInput: { + table: 'bg-notion-input-background dark:bg-notion-dark-light', + cell: 'border-notion-input-border dark:border-notion-input-borderDark', + cellHover: 'hover:backdrop-brightness-95' } } } diff --git a/client/tailwind.config.js b/client/tailwind.config.js index db979c79d..b11869a75 100644 --- a/client/tailwind.config.js +++ b/client/tailwind.config.js @@ -56,9 +56,7 @@ module.exports = { 5.5: "1.4rem", }, boxShadow: { - "inner-notion": "#0f0f0f1a 0px 0px 0px 1px inset", - "focus-notion": - "#2eaadcb3 0px 0px 0px 1px inset, #2eaadc66 0px 0px 0px 2px !important", + 'custom-shadow':'0px 25px 75px 0px #5353531A' }, colors: { gray: colors.slate, @@ -78,6 +76,8 @@ module.exports = { backgroundDark: "#272B2C", help: "#37352f99", helpDark: "#fff9", + border: 'rgba(15, 15, 15, 0.1)', + borderDark: 'rgba(255, 255, 255, 0.1)' }, "form-color": "var(--bg-form-color)", },